Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cli help command for the perf project #1757

Merged
merged 13 commits into from
Oct 29, 2020
8 changes: 7 additions & 1 deletion priv/perf/apps/load_test/lib/test_runner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ defmodule LoadTest.TestRunner do
alias LoadTest.TestRunner.Config

def run() do
{runner_module, config, property} = Config.parse()
case Config.parse() do
{:ok, {runner_module, config, property}} -> run_test(runner_module, config, property)
:ok -> :ok
end
end

defp run_test(runner_module, config, property) do
result = Chaperon.run_load_test(runner_module, print_results: true, config: config)

# / 1 is to convert result to float (mean is float, percentiles are integers)[O
Expand Down
39 changes: 24 additions & 15 deletions priv/perf/apps/load_test/lib/test_runner/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ defmodule LoadTest.TestRunner.Config do
Command line args parser for TestRunner.
"""
alias ExPlasma.Encoding
alias LoadTest.TestRunner.Help

@tests %{
"deposits" => LoadTest.Runner.Deposits,
Expand All @@ -39,27 +40,33 @@ defmodule LoadTest.TestRunner.Config do
}

def parse() do
[test, rate, period, property] =
case System.argv() do
[test, rate, period] ->
[test, rate, period, :mean]
case System.argv() do
[test, rate, period] ->
{:ok, config(test, rate, period, :mean)}

[test, rate, period, percentile] ->
percentile = parse_percentile(percentile)
[test, rate, period, percentile]
end
[test, rate, period, percentile] ->
percentile = parse_percentile(percentile)
{:ok, config(test, rate, period, percentile)}

rate_int = String.to_integer(rate)
period_int = String.to_integer(period)
["help"] ->
Help.help()

config = config(test, rate_int, period_int)
["help", "env"] ->
Help.help("env")

runner_module = Map.fetch!(@tests, test)
["help", name] ->
Help.help(name)

{runner_module, config, property}
:ok
end
end

defp config(test, rate_int, period_int) do
defp config(test, rate, period, property) do
rate_int = String.to_integer(rate)
period_int = String.to_integer(period)

runner_module = Map.fetch!(@tests, test)

# Chaperon's SpreadAsyns (https://github.com/polleverywhere/chaperon/blob/13cc4a2d2a7baacddf20c46397064b5e42a48d97/lib/chaperon/action/spread_async.ex)
# spawns a separate process for each execution. VM may fail if too many processes are spawned
if rate_int * period_int > 200_000, do: raise("too many processes")
Expand All @@ -71,11 +78,13 @@ defmodule LoadTest.TestRunner.Config do

chain_config = read_config!(test)

%{
config = %{
run_config: run_config,
chain_config: chain_config,
timeout: :infinity
}

{runner_module, config, property}
end

defp read_config!(test) do
Expand Down
144 changes: 144 additions & 0 deletions priv/perf/apps/load_test/lib/test_runner/help.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule LoadTest.TestRunner.Help do
@moduledoc """
Shows help info for TestRunner.
"""

require Logger

@help """

`LoadTest.TestRunner` accepts three required parameters:

1. Test name (`utxos` or `deposits`)
2. Rate in tests per second
3. Period in seconds

For example, if you want to run `deposits` with 5 tests / second rate over 20 seconds, you
should run the following command:

```
mix run -e "LoadTest.TestRunner.run()" -- deposits 5 20
```

To modify tests values use `TEST_CONFIG_PATH`. It should contain a path to json file containing
test values:

```
TEST_CONFIG_PATH=./my_file mix run -e "LoadTest.TestRunner.run()" -- deposits 1 5
```

To see which values can be overridden, use

```
mix run -e "LoadTest.TestRunner.run()" -- help test_name
```

To see env variable, use:

```
mix run -e "LoadTest.TestRunner.run()" -- help env
```
"""

@help_test %{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

"deposits" => """

A single iteration of this test consists of the following steps:

1. It creates two accounts: the depositor and the receiver.
2. It funds depositor with the specified amount (`initial_amount`) on the rootchain.
3. It creates deposit (`deposited_amount`) with gas price `gas_price` for the depositor account on the childchain and
checks balances on the rootchain and the childchain after this deposit.
4. The depositor account sends the specifed amount (`transferred_amount`) on the childchain to the receiver
and checks its balance on the childchain.

Overridable parameters are:

- token. default value is "0x0000000000000000000000000000000000000000"
- initial_amount. default value is 500_000_000_000_000_000
- deposited_amount default value is 200_000_000_000_000_000
- transferred_amount. default value is 100_000_000_000_000_000
- gas_price. default value is 2_000_000_000
""",
"utxos" => """

A single iteration of this test consists of the following steps:

1.1 Two accounts are created - the sender and the receiver

2.1 The sender account is funded with `initial_amount` `token`
2.2 The balance on the childchain of the sender is validated using WatcherInfoAPI.Api.Account.account_get_balance API.
2.3 Utxos of the sender are validated using WatcherInfoAPI.Api.Account.account_get_utxos API

3.1 The sender sends all his tokens to the receiver with fee `fee`
3.2 The balance on the childchain of the sender is validated
3.3 The balance on the childchain of the receiver is validated
3.4 Utxos of the sender are validated
3.5 Utxos of the receiver are validated

Overridable parameters are:

- initial_balance. default value is 760
- token. default value is "0x0000000000000000000000000000000000000000"
- fee. default value is 75
"""
}

@env """

ETHEREUM_RPC_URL - Ethereum Json RPC url. Default value is http://localhost:8545
RETRY_SLEEP - Sleeping period used when polling data. Default value is 1000 (ms)
CHILD_CHAIN_URL - Childcahin url. Default value is http://localhost:9656
WATCHER_SECURITY_URL - Watcher security url. Default value is http://localhost:7434
WATCHER_INFO_URL - Watcehr info url. Default value is http://localhost:7534
LOAD_TEST_FAUCET_PRIVATE_KEY - Faucet private key. Default value is 0xd885a307e35738f773d8c9c63c7a3f3977819274638d04aaf934a1e1158513ce
CONTRACT_ADDRESS_ETH_VAULT - Eth vault contact address
CONTRACT_ADDRESS_PAYMENT_EXIT_GAME - Payment exit game contract address
CHILD_BLOCK_INTERVAL - Block generation interval. Default value is 1000 (ms)
CONTRACT_ADDRESS_PLASMA_FRAMEWORK - Plasma framework contract address
CONTRACT_ADDRESS_ERC20_VAULT - Erc 20 vault contract address
FEE_AMOUNT - Fee amount used by faucet when funding accounts. Default value is 75
DEPOSIT_FINALITY_MARGIN - Number of comfirmation for a deposit. Default value is 10
"""

def help do
IO.puts(@help)
end

def help("env") do
IO.puts(@env)
end

def help(test_name) do
case @help_test[test_name] do
nil ->
tests =
@help_test
|> Map.keys()
|> Enum.join(", ")

IO.puts("""

Documentation for `#{test_name}` is not found. Available tests are #{tests}.

""")

doc ->
IO.puts(doc)
end
end
end