system_tests.cpp
1 // Copyright (c) 2019-2022 The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 // 5 6 #if defined(HAVE_CONFIG_H) 7 #include <config/bitcoin-config.h> 8 #endif 9 #include <test/util/setup_common.h> 10 #include <common/run_command.h> 11 #include <univalue.h> 12 13 #ifdef ENABLE_EXTERNAL_SIGNER 14 #include <boost/process.hpp> 15 #endif // ENABLE_EXTERNAL_SIGNER 16 17 #include <boost/test/unit_test.hpp> 18 19 BOOST_FIXTURE_TEST_SUITE(system_tests, BasicTestingSetup) 20 21 // At least one test is required (in case ENABLE_EXTERNAL_SIGNER is not defined). 22 // Workaround for https://github.com/bitcoin/bitcoin/issues/19128 23 BOOST_AUTO_TEST_CASE(dummy) 24 { 25 BOOST_CHECK(true); 26 } 27 28 #ifdef ENABLE_EXTERNAL_SIGNER 29 30 BOOST_AUTO_TEST_CASE(run_command) 31 { 32 { 33 const UniValue result = RunCommandParseJSON(""); 34 BOOST_CHECK(result.isNull()); 35 } 36 { 37 const UniValue result = RunCommandParseJSON("echo \"{\"success\": true}\""); 38 BOOST_CHECK(result.isObject()); 39 const UniValue& success = result.find_value("success"); 40 BOOST_CHECK(!success.isNull()); 41 BOOST_CHECK_EQUAL(success.get_bool(), true); 42 } 43 { 44 // An invalid command is handled by Boost 45 const int expected_error{2}; 46 BOOST_CHECK_EXCEPTION(RunCommandParseJSON("invalid_command"), boost::process::process_error, [&](const boost::process::process_error& e) { 47 BOOST_CHECK(std::string(e.what()).find("RunCommandParseJSON error:") == std::string::npos); 48 BOOST_CHECK_EQUAL(e.code().value(), expected_error); 49 return true; 50 }); 51 } 52 { 53 // Return non-zero exit code, no output to stderr 54 const std::string command{"false"}; 55 BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) { 56 const std::string what{e.what()}; 57 BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned 1: \n", command)) != std::string::npos); 58 return true; 59 }); 60 } 61 { 62 // Return non-zero exit code, with error message for stderr 63 const std::string command{"ls nosuchfile"}; 64 const std::string expected{"No such file or directory"}; 65 BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) { 66 const std::string what(e.what()); 67 BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned", command)) != std::string::npos); 68 BOOST_CHECK(what.find(expected) != std::string::npos); 69 return true; 70 }); 71 } 72 { 73 // Unable to parse JSON 74 const std::string command{"echo {"}; 75 BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, HasReason("Unable to parse JSON: {")); 76 } 77 // Test std::in 78 { 79 const UniValue result = RunCommandParseJSON("cat", "{\"success\": true}"); 80 BOOST_CHECK(result.isObject()); 81 const UniValue& success = result.find_value("success"); 82 BOOST_CHECK(!success.isNull()); 83 BOOST_CHECK_EQUAL(success.get_bool(), true); 84 } 85 } 86 #endif // ENABLE_EXTERNAL_SIGNER 87 88 BOOST_AUTO_TEST_SUITE_END()