From 945438d035f7068ef9d6daf60638f4beeb518c93 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 26 Sep 2023 16:30:29 -0500 Subject: [PATCH 1/5] Add a more time consuming read-only trx --- tests/PerformanceHarness/CMakeLists.txt | 1 + .../readOnlySlowTrxData.json | 14 ++++++ .../payloadless/payloadless.abi | 10 ++++ .../payloadless/payloadless.cpp | 43 ++++++++++++++++++ .../payloadless/payloadless.hpp | 3 ++ .../payloadless/payloadless.wasm | Bin 862 -> 2824 bytes 6 files changed, 71 insertions(+) create mode 100644 tests/PerformanceHarness/readOnlySlowTrxData.json diff --git a/tests/PerformanceHarness/CMakeLists.txt b/tests/PerformanceHarness/CMakeLists.txt index f5a7711e3f..cba9f6282e 100644 --- a/tests/PerformanceHarness/CMakeLists.txt +++ b/tests/PerformanceHarness/CMakeLists.txt @@ -5,6 +5,7 @@ configure_file(genesis.json . COPYONLY) configure_file(cpuTrxData.json . COPYONLY) configure_file(ramTrxData.json . COPYONLY) configure_file(readOnlyTrxData.json . COPYONLY) +configure_file(readOnlySlowTrxData.json . COPYONLY) configure_file(userTrxDataTransfer.json . COPYONLY) configure_file(userTrxDataNewAccount.json . COPYONLY) diff --git a/tests/PerformanceHarness/readOnlySlowTrxData.json b/tests/PerformanceHarness/readOnlySlowTrxData.json new file mode 100644 index 0000000000..ec6a61fd96 --- /dev/null +++ b/tests/PerformanceHarness/readOnlySlowTrxData.json @@ -0,0 +1,14 @@ +{ + "initAccounts": ["payloadless"], + "abiFile": "unittests/test-contracts/payloadless/payloadless.abi", + "apiEndpoint": "/v1/chain/send_read_only_transaction", + "actions": [ + { + "actionName": "doitslow", + "actionData": { + }, + "actionAuthAcct": "payloadless", + "authorization": {} + } + ] +} diff --git a/unittests/test-contracts/payloadless/payloadless.abi b/unittests/test-contracts/payloadless/payloadless.abi index ad6c695ea6..aafa35c171 100644 --- a/unittests/test-contracts/payloadless/payloadless.abi +++ b/unittests/test-contracts/payloadless/payloadless.abi @@ -7,6 +7,11 @@ "name": "doit", "base": "", "fields": [] + }, + { + "name": "doitslow", + "base": "", + "fields": [] } ], "actions": [ @@ -14,6 +19,11 @@ "name": "doit", "type": "doit", "ricardian_contract": "" + }, + { + "name": "doitslow", + "type": "doitslow", + "ricardian_contract": "" } ], "tables": [], diff --git a/unittests/test-contracts/payloadless/payloadless.cpp b/unittests/test-contracts/payloadless/payloadless.cpp index 16637efa2b..4c4fcfbf68 100644 --- a/unittests/test-contracts/payloadless/payloadless.cpp +++ b/unittests/test-contracts/payloadless/payloadless.cpp @@ -5,3 +5,46 @@ using namespace eosio; void payloadless::doit() { print("Im a payloadless action"); } + +constexpr size_t cpu_prime_max = 15375u; + +bool is_prime(int p) { + if (p == 2) { + return true; + } else if (p <= 1 || p % 2 == 0) { + return false; + } + + bool prime = true; + const int to = sqrt(p); + int i; + for (i = 3; i <= to; i += 2) { + if (!((prime = bool(p)) % i)) break; + } + return prime; +} + +bool is_mersenne_prime(int p) { + if (p == 2) return true; + + const long long unsigned m_p = (1LLU << p) - 1; + long long unsigned s = 4; + int i; + for (i = 3; i <= p; i++) { + s = (s * s - 2) % m_p; + } + return bool(s == 0); +} + + +void payloadless::doitslow() { + print("Im a payloadless slow action"); + + for (size_t p = 2; p <= cpu_prime_max; p += 1) { + if (is_prime(p) && is_mersenne_prime(p)) { + // We need to keep an eye on this to make sure it doesn't get optimized out. So far so good. + //eosio::print_f(" %u", p); + } + } +} + diff --git a/unittests/test-contracts/payloadless/payloadless.hpp b/unittests/test-contracts/payloadless/payloadless.hpp index 945a0d7417..0fea87a29b 100644 --- a/unittests/test-contracts/payloadless/payloadless.hpp +++ b/unittests/test-contracts/payloadless/payloadless.hpp @@ -8,4 +8,7 @@ class [[eosio::contract]] payloadless : public eosio::contract { [[eosio::action]] void doit(); + + [[eosio::action]] + void doitslow(); }; diff --git a/unittests/test-contracts/payloadless/payloadless.wasm b/unittests/test-contracts/payloadless/payloadless.wasm index 7b0ae321539be6cdf84a30ddf2d34449e9f451ae..dc91259462d70f80d797daf22f65c9d27759025d 100755 GIT binary patch literal 2824 zcmbtWOOG2x5U%c-@vCiiHjfP?Kzb%1hXV(^TF-QKeP307HLe

9E<}l8&o@1AGocSC#>7iCc=?Y|Wh)8=M8PW$6dl%{c#5jUPm9Q8VuJ2~1c(>UwAHX3(_ z-8Z8CUS|>|(Qcf@Ns8O0i4Pb_@_k=OlI#_?y}dM_U*7$eB*$8t{X?EM z|NPtaUsueBJxRI$-7i1|3Q932w{-RrEw?%eE!!@zkj+g0RXwW zT-p#t{<`?4#o4^R;7H)BkZsHBw?nSL^RPP2FK1gwT++vqZmkK)ZU+u;!<#F*fE}(L z;!~YUCppt%ST3{`e;1n@SWwLQz@)Wg=S~3g^bDLpAmfb;0DYV!bkE^HwR{oOBqSIb9rP~Fr8VSv4o?+$ z9Cc72<)8rOw5z};ZJ=)f{SpvFcEA%hu4dtCB^-Ec+;JP{S~$0a1CNb+!p3n6$4fZy z*to}S9J6pJ_ajBMFyOIq$1EJgek7uApk3u#yMML|bYw2csa)vZmmK-$VJe`>y0Oki|Mg^g# zHPk{6mzr+LHJuY0I*e>88z2<2u8w4ScYmN0f9MSEY|D4F!wlAwS#syv*8yRkiiA04 zfa#&KhH0YcG{4c7r2JW^<=Vt5w_a<9j--KF8>q=Nq)mP;A1i()>17Sqjdq~@CDUm! zoiS^Z$rKbf?~;!*I%1Qt#VG_Bh5&8yCXfi)Jk6=#ULvS8F%)g#dZR5GIs`rM+-nO? z;sWwMMIqNC)n}oLVPz_T!Qq~VGOqtvz_loPD4LXqA%6x(#@cs|3-uY&LB(KtpK-j4 zT=`#Y-)XiNDgU$sJW_frLjYItmvlM@^U(8K$A$C`JpbIfg@*upXrAik142n55K Date: Wed, 27 Sep 2023 08:24:21 -0500 Subject: [PATCH 2/5] Move logging template to TestHarness and remove gelf config --- programs/nodeos/CMakeLists.txt | 1 - tests/TestHarness/CMakeLists.txt | 1 + tests/TestHarness/logging-template.json | 150 ++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 tests/TestHarness/logging-template.json diff --git a/programs/nodeos/CMakeLists.txt b/programs/nodeos/CMakeLists.txt index 493c9e3a43..49b43670b4 100644 --- a/programs/nodeos/CMakeLists.txt +++ b/programs/nodeos/CMakeLists.txt @@ -5,7 +5,6 @@ if( UNIX AND NOT APPLE ) endif() configure_file(config.hpp.in config.hpp ESCAPE_QUOTES) -configure_file(logging.json ${CMAKE_BINARY_DIR}/tests/TestHarness/logging-template.json) target_include_directories(${NODE_EXECUTABLE_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/tests/TestHarness/CMakeLists.txt b/tests/TestHarness/CMakeLists.txt index 1e00fbf567..82da444a6e 100644 --- a/tests/TestHarness/CMakeLists.txt +++ b/tests/TestHarness/CMakeLists.txt @@ -14,3 +14,4 @@ configure_file(logging.py . COPYONLY) configure_file(depresolver.py . COPYONLY) configure_file(launcher.py . COPYONLY) configure_file(accounts.py . COPYONLY) +configure_file(logging-template.json . COPYONLY) diff --git a/tests/TestHarness/logging-template.json b/tests/TestHarness/logging-template.json new file mode 100644 index 0000000000..fff1143346 --- /dev/null +++ b/tests/TestHarness/logging-template.json @@ -0,0 +1,150 @@ +{ + "includes": [], + "appenders": [{ + "name": "stderr", + "type": "console", + "args": { + "format": " : ] ", + "stream": "std_error", + "level_colors": [{ + "level": "debug", + "color": "green" + },{ + "level": "warn", + "color": "brown" + },{ + "level": "error", + "color": "red" + } + ], + "flush": true + }, + "enabled": true + },{ + "name": "stdout", + "type": "console", + "args": { + "stream": "std_out", + "level_colors": [{ + "level": "debug", + "color": "green" + },{ + "level": "warn", + "color": "brown" + },{ + "level": "error", + "color": "red" + } + ], + "flush": true + }, + "enabled": true + } + ], + "loggers": [{ + "name": "default", + "level": "debug", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "net_plugin_impl", + "level": "info", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "http_plugin", + "level": "debug", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "producer_plugin", + "level": "debug", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "transaction_success_tracing", + "level": "debug", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "transaction_failure_tracing", + "level": "debug", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "trace_api", + "level": "debug", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "transaction_trace_success", + "level": "info", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "transaction_trace_failure", + "level": "info", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "transient_trx_success_tracing", + "level": "debug", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "transient_trx_failure_tracing", + "level": "debug", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "state_history", + "level": "info", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + },{ + "name": "transaction", + "level": "info", + "enabled": true, + "additivity": false, + "appenders": [ + "stderr" + ] + } + ] +} From 9d55f8f464f8c39c21f8e57ad3c1ad9782d05489 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 27 Sep 2023 09:15:10 -0500 Subject: [PATCH 3/5] Add in a slower read-only trx --- tests/read_only_trx_test.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/read_only_trx_test.py b/tests/read_only_trx_test.py index 91f92a8a0b..4af2f35d90 100755 --- a/tests/read_only_trx_test.py +++ b/tests/read_only_trx_test.py @@ -204,6 +204,9 @@ def sendTransaction(account, action, data, auth=[], opts=None): def sendReadOnlyPayloadless(): return sendTransaction('payloadless', action='doit', data={}, auth=[], opts='--read') +def sendReadOnlySlowPayloadless(): + return sendTransaction('payloadless', action='doitslow', data={}, auth=[], opts='--read') + # Send read-only trxs from mutltiple threads to bump load def sendReadOnlyTrxOnThread(startId, numTrxs): Print("start sendReadOnlyTrxOnThread") @@ -219,6 +222,10 @@ def sendReadOnlyTrxOnThread(startId, numTrxs): results = sendReadOnlyPayloadless() assert(results[0]) assert(results[1]['processed']['action_traces'][0]['console'] == "Im a payloadless action") + + results = sendReadOnlySlowPayloadless() + assert(results[0]) + assert(results[1]['processed']['action_traces'][0]['console'] == "Im a payloadless slow action") except Exception as e: Print("Exception in sendReadOnlyTrxOnThread: ", e) errorInThread = True From 82be47122256a99adae4620e77a562b88044e7bf Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 27 Sep 2023 11:04:47 -0500 Subject: [PATCH 4/5] Fix is_prime to not always return true. Verify that doitslow action runs for at least 100us --- tests/read_only_trx_test.py | 1 + unittests/test-contracts/payloadless/payloadless.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/read_only_trx_test.py b/tests/read_only_trx_test.py index 4af2f35d90..7b6a555bc5 100755 --- a/tests/read_only_trx_test.py +++ b/tests/read_only_trx_test.py @@ -226,6 +226,7 @@ def sendReadOnlyTrxOnThread(startId, numTrxs): results = sendReadOnlySlowPayloadless() assert(results[0]) assert(results[1]['processed']['action_traces'][0]['console'] == "Im a payloadless slow action") + assert(int(results[1]['processed']['elapsed']) > 100) except Exception as e: Print("Exception in sendReadOnlyTrxOnThread: ", e) errorInThread = True diff --git a/unittests/test-contracts/payloadless/payloadless.cpp b/unittests/test-contracts/payloadless/payloadless.cpp index 4c4fcfbf68..46566c3215 100644 --- a/unittests/test-contracts/payloadless/payloadless.cpp +++ b/unittests/test-contracts/payloadless/payloadless.cpp @@ -17,9 +17,11 @@ bool is_prime(int p) { bool prime = true; const int to = sqrt(p); - int i; - for (i = 3; i <= to; i += 2) { - if (!((prime = bool(p)) % i)) break; + for (int i = 3; i <= to; i += 2) { + if (p % i == 0) { + prime = false; + break; + } } return prime; } From 4d3f0908208ff69d19a7928a85ce279c33066510 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 27 Sep 2023 11:25:34 -0500 Subject: [PATCH 5/5] Use the doitslow trx action for testing perf harness --- tests/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ed884355da..b73809254d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -274,7 +274,7 @@ set_property(TEST gelf_test PROPERTY LABELS nonparallelizable_tests) add_test(NAME performance_test_bp COMMAND tests/PerformanceHarnessScenarioRunner.py findMax testBpOpMode --max-tps-to-test 50 --test-iteration-min-step 10 --test-iteration-duration-sec 10 --final-iterations-duration-sec 10 --calc-chain-threads lmax overrideBasicTestConfig -v --tps-limit-per-generator 25 --chain-state-db-size-mb 200 ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME performance_test_api COMMAND tests/PerformanceHarnessScenarioRunner.py findMax testApiOpMode --max-tps-to-test 50 --test-iteration-min-step 10 --test-iteration-duration-sec 10 --final-iterations-duration-sec 10 --calc-chain-threads lmax overrideBasicTestConfig -v --tps-limit-per-generator 25 --chain-state-db-size-mb 200 ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -add_test(NAME performance_test_read_only_trxs COMMAND tests/PerformanceHarnessScenarioRunner.py findMax testApiOpMode --max-tps-to-test 50 --test-iteration-min-step 10 --test-iteration-duration-sec 10 --final-iterations-duration-sec 10 overrideBasicTestConfig -v --tps-limit-per-generator 25 --api-nodes-read-only-threads 2 --read-only-write-window-time-us 1000 --read-only-read-window-time-us 165000 --account-name "payloadless" --abi-file payloadless.abi --wasm-file payloadless.wasm --contract-dir unittests/test-contracts/payloadless --user-trx-data-file tests/PerformanceHarness/readOnlyTrxData.json --chain-state-db-size-mb 200 ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +add_test(NAME performance_test_read_only_trxs COMMAND tests/PerformanceHarnessScenarioRunner.py findMax testApiOpMode --max-tps-to-test 50 --test-iteration-min-step 10 --test-iteration-duration-sec 10 --final-iterations-duration-sec 10 overrideBasicTestConfig -v --tps-limit-per-generator 25 --api-nodes-read-only-threads 2 --read-only-write-window-time-us 1000 --read-only-read-window-time-us 165000 --account-name "payloadless" --abi-file payloadless.abi --wasm-file payloadless.wasm --contract-dir unittests/test-contracts/payloadless --user-trx-data-file tests/PerformanceHarness/readOnlySlowTrxData.json --chain-state-db-size-mb 200 ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME performance_test_cpu_trx_spec COMMAND tests/PerformanceHarnessScenarioRunner.py findMax testBpOpMode --max-tps-to-test 50 --test-iteration-min-step 10 --test-iteration-duration-sec 10 --final-iterations-duration-sec 10 overrideBasicTestConfig -v --tps-limit-per-generator 25 --chain-state-db-size-mb 200 --account-name "c" --abi-file eosmechanics.abi --wasm-file eosmechanics.wasm --contract-dir unittests/contracts/eosio.mechanics --user-trx-data-file tests/PerformanceHarness/cpuTrxData.json ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME performance_test_basic_p2p COMMAND tests/PerformanceHarnessScenarioRunner.py singleTest -v --producer-nodes 1 --validation-nodes 1 --target-tps 20 --tps-limit-per-generator 10 --test-duration-sec 5 --chain-state-db-size-mb 200 ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME performance_test_basic_http COMMAND tests/PerformanceHarnessScenarioRunner.py singleTest -v --endpoint-mode http --producer-nodes 1 --validation-nodes 1 --api-nodes 1 --target-tps 10 --tps-limit-per-generator 10 --test-duration-sec 5 --chain-state-db-size-mb 200 ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) @@ -282,7 +282,7 @@ add_test(NAME performance_test_basic_transfer_trx_spec COMMAND tests/Performance add_test(NAME performance_test_basic_new_acct_trx_spec COMMAND tests/PerformanceHarnessScenarioRunner.py singleTest -v --producer-nodes 1 --validation-nodes 1 --target-tps 20 --tps-limit-per-generator 10 --test-duration-sec 5 --chain-state-db-size-mb 200 --user-trx-data-file tests/PerformanceHarness/userTrxDataNewAccount.json ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME performance_test_basic_cpu_trx_spec COMMAND tests/PerformanceHarnessScenarioRunner.py singleTest -v --producer-nodes 1 --validation-nodes 1 --target-tps 20 --tps-limit-per-generator 10 --test-duration-sec 5 --chain-state-db-size-mb 200 --account-name "c" --abi-file eosmechanics.abi --wasm-file eosmechanics.wasm --contract-dir unittests/contracts/eosio.mechanics --user-trx-data-file tests/PerformanceHarness/cpuTrxData.json ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME performance_test_basic_ram_trx_spec COMMAND tests/PerformanceHarnessScenarioRunner.py singleTest -v --producer-nodes 1 --validation-nodes 1 --target-tps 20 --tps-limit-per-generator 10 --test-duration-sec 5 --chain-state-db-size-mb 200 --account-name "r" --abi-file eosmechanics.abi --wasm-file eosmechanics.wasm --contract-dir unittests/contracts/eosio.mechanics --user-trx-data-file tests/PerformanceHarness/ramTrxData.json ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -add_test(NAME performance_test_basic_read_only_trxs COMMAND tests/PerformanceHarnessScenarioRunner.py singleTest -v --endpoint-mode http --producer-nodes 1 --validation-nodes 1 --api-nodes 1 --api-nodes-read-only-threads 2 --read-only-write-window-time-us 1000 --read-only-read-window-time-us 165000 --target-tps 20 --tps-limit-per-generator 10 --test-duration-sec 5 --chain-state-db-size-mb 200 --account-name "payloadless" --abi-file payloadless.abi --wasm-file payloadless.wasm --contract-dir unittests/test-contracts/payloadless --user-trx-data-file tests/PerformanceHarness/readOnlyTrxData.json ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +add_test(NAME performance_test_basic_read_only_trxs COMMAND tests/PerformanceHarnessScenarioRunner.py singleTest -v --endpoint-mode http --producer-nodes 1 --validation-nodes 1 --api-nodes 1 --api-nodes-read-only-threads 2 --read-only-write-window-time-us 1000 --read-only-read-window-time-us 165000 --target-tps 20 --tps-limit-per-generator 10 --test-duration-sec 5 --chain-state-db-size-mb 200 --account-name "payloadless" --abi-file payloadless.abi --wasm-file payloadless.wasm --contract-dir unittests/test-contracts/payloadless --user-trx-data-file tests/PerformanceHarness/readOnlySlowTrxData.json ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) set_property(TEST performance_test_bp PROPERTY LABELS long_running_tests) set_property(TEST performance_test_api PROPERTY LABELS long_running_tests) set_property(TEST performance_test_read_only_trxs PROPERTY LABELS long_running_tests)