diff --git a/plugins/trace_api_plugin/trace_api_plugin.cpp b/plugins/trace_api_plugin/trace_api_plugin.cpp index 6eee7a93f4..8a412f8b27 100644 --- a/plugins/trace_api_plugin/trace_api_plugin.cpp +++ b/plugins/trace_api_plugin/trace_api_plugin.cpp @@ -202,6 +202,9 @@ struct trace_api_rpc_plugin_impl : public std::enable_shared_from_this data_handler = std::make_shared([](const exception_with_context& e){ log_exception(e, fc::log_level::debug); + if (std::get<0>(e)) { // rethrow so caller is notified of error + std::rethrow_exception(std::get<0>(e)); + } }); if( options.count("trace-rpc-abi") ) { diff --git a/tests/TestHarness/testUtils.py b/tests/TestHarness/testUtils.py index b232a93eb3..c386953c4c 100644 --- a/tests/TestHarness/testUtils.py +++ b/tests/TestHarness/testUtils.py @@ -218,7 +218,7 @@ def checkDelayedOutput(popen, cmd, ignoreError=False): Utils.checkOutputFileWrite(start, cmd, output, error) if popen.returncode != 0 and not ignoreError: raise subprocess.CalledProcessError(returncode=popen.returncode, cmd=cmd, output=output, stderr=error) - return output.decode("utf-8") + return output.decode("utf-8") if popen.returncode == 0 else error.decode("utf-8") @staticmethod def errorExit(msg="", raw=False, errorCode=1): @@ -317,13 +317,13 @@ def runCmdArrReturnJson(cmdArr, trace=False, silentErrors=True): return Utils.toJson(retStr) @staticmethod - def runCmdReturnStr(cmd, trace=False): + def runCmdReturnStr(cmd, trace=False, ignoreError=False): cmdArr=shlex.split(cmd) - return Utils.runCmdArrReturnStr(cmdArr) + return Utils.runCmdArrReturnStr(cmdArr, ignoreError=ignoreError) @staticmethod - def runCmdArrReturnStr(cmdArr, trace=False): - retStr=Utils.checkOutput(cmdArr) + def runCmdArrReturnStr(cmdArr, trace=False, ignoreError=False): + retStr=Utils.checkOutput(cmdArr, ignoreError=ignoreError) if trace: Utils.Print ("RAW > %s" % (retStr)) return retStr diff --git a/tests/plugin_http_api_test.py b/tests/plugin_http_api_test.py index 33755e482f..c903173ff6 100755 --- a/tests/plugin_http_api_test.py +++ b/tests/plugin_http_api_test.py @@ -1406,6 +1406,22 @@ def test_TraceApi(self) : self.assertEqual(ret_json["code"], 404) self.assertEqual(ret_json["error"]["code"], 0) + # get_transaction_trace with empty parameter + command = "get_transaction_trace" + ret_json = self.nodeos.processUrllibRequest(resource, command) + self.assertEqual(ret_json["code"], 400) + # get_transaction_trace with empty content parameter + ret_json = self.nodeos.processUrllibRequest(resource, command, self.empty_content_dict) + self.assertEqual(ret_json["code"], 400) + # get_transaction_trace with invalid parameter + ret_json = self.nodeos.processUrllibRequest(resource, command, self.http_post_invalid_param) + self.assertEqual(ret_json["code"], 400) + # get_transaction_trace with syntactically correct id parameter, but random id, so should return 404 (not found) + payload = {"id":"f6e325a524e0d75c2275e7d9c2d9e065a38760c29b1d0471a75ccde650ef26d6"} + ret_json = self.nodeos.processUrllibRequest(resource, command, payload) + self.assertEqual(ret_json["code"], 404) + self.assertEqual(ret_json["error"]["code"], 0) + # test all db_size api def test_DbSizeApi(self) : resource = "db_size" diff --git a/tests/trace_plugin_test.py b/tests/trace_plugin_test.py index 6fb0376413..1bfe110c60 100755 --- a/tests/trace_plugin_test.py +++ b/tests/trace_plugin_test.py @@ -5,6 +5,7 @@ import time import unittest import os +import signal from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr, CORE_SYMBOL, createAccountKeys @@ -20,7 +21,7 @@ class TraceApiPluginTest(unittest.TestCase): def startEnv(self) : account_names = ["alice", "bob", "charlie"] abs_path = os.path.abspath(os.getcwd() + '/unittests/contracts/eosio.token/eosio.token.abi') - traceNodeosArgs = " --trace-rpc-abi eosio.token=" + abs_path + traceNodeosArgs = " --verbose-http-errors --trace-rpc-abi eosio.token=" + abs_path self.cluster.launch(totalNodes=2, extraNodeosArgs=traceNodeosArgs) self.walletMgr.launch() testWalletName="testwallet" @@ -95,6 +96,20 @@ def test_TraceApi(self) : global testSuccessful testSuccessful = True + # relaunch with no time allocated for http response & abi-serializer + node.kill(signal.SIGTERM) + isRelaunchSuccess = node.relaunch(timeout=10, addSwapFlags={"--http-max-response-time-ms": "0", "--abi-serializer-max-time-ms": "0"}) + self.assertTrue(isRelaunchSuccess) + + # Verify get block_trace still works even with no time for http-max-response-time-ms and no time for bi-serializer-max-time-ms + cmdDesc="get block_trace" + cmd=" --print-response %s %d" % (cmdDesc, blockNum) + cmd="%s %s %s" % (Utils.EosClientPath, node.eosClientArgs(), cmd) + result=Utils.runCmdReturnStr(cmd, ignoreError=True) + + Utils.Print(f"{cmdDesc} returned: {result}") + self.assertIn("test transfer a->b", result) + @classmethod def setUpClass(self): self.startEnv(self)