Branch data Line data Source code
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 : : #include <test/util/setup_common.h> 6 : : #include <common/run_command.h> 7 : : #include <univalue.h> 8 : : 9 : : #ifdef ENABLE_EXTERNAL_SIGNER 10 : : #include <boost/process.hpp> 11 : : #endif // ENABLE_EXTERNAL_SIGNER 12 : : 13 : : #include <boost/test/unit_test.hpp> 14 : : 15 : 0 : BOOST_FIXTURE_TEST_SUITE(system_tests, BasicTestingSetup) 16 : : 17 : : // At least one test is required (in case ENABLE_EXTERNAL_SIGNER is not defined). 18 : : // Workaround for https://github.com/bitcoin/bitcoin/issues/19128 19 : 0 : BOOST_AUTO_TEST_CASE(dummy) 20 : : { 21 : 0 : BOOST_CHECK(true); 22 : 0 : } 23 : : 24 : : #ifdef ENABLE_EXTERNAL_SIGNER 25 : : 26 : 0 : BOOST_AUTO_TEST_CASE(run_command) 27 : : { 28 : : #ifdef WIN32 29 : : // https://www.winehq.org/pipermail/wine-devel/2008-September/069387.html 30 : : auto hntdll = GetModuleHandleA("ntdll.dll"); 31 : : assert(hntdll); 32 : : const bool wine_runtime = GetProcAddress(hntdll, "wine_get_version"); 33 : : #endif 34 : : 35 : : { 36 : 0 : const UniValue result = RunCommandParseJSON(""); 37 : 0 : BOOST_CHECK(result.isNull()); 38 : 0 : } 39 : : { 40 : : #ifdef WIN32 41 : : const UniValue result = RunCommandParseJSON("cmd.exe /c echo {\"success\": true}"); 42 : : #else 43 : 0 : const UniValue result = RunCommandParseJSON("echo \"{\"success\": true}\""); 44 : : #endif 45 : 0 : BOOST_CHECK(result.isObject()); 46 : 0 : const UniValue& success = result.find_value("success"); 47 : 0 : BOOST_CHECK(!success.isNull()); 48 : 0 : BOOST_CHECK_EQUAL(success.get_bool(), true); 49 : 0 : } 50 : : { 51 : : // An invalid command is handled by Boost 52 : : #ifdef WIN32 53 : 0 : const int expected_error{wine_runtime ? 6 : 2}; 54 : : #else 55 : 0 : const int expected_error{2}; 56 : : #endif 57 : 0 : BOOST_CHECK_EXCEPTION(RunCommandParseJSON("invalid_command"), boost::process::process_error, [&](const boost::process::process_error& e) { 58 : : BOOST_CHECK(std::string(e.what()).find("RunCommandParseJSON error:") == std::string::npos); 59 : : BOOST_CHECK_EQUAL(e.code().value(), expected_error); 60 : : return true; 61 : : }); 62 : : } 63 : : { 64 : : // Return non-zero exit code, no output to stderr 65 : : #ifdef WIN32 66 : : const std::string command{"cmd.exe /c exit 1"}; 67 : : #else 68 : 0 : const std::string command{"false"}; 69 : : #endif 70 : 0 : BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) { 71 : : const std::string what{e.what()}; 72 : : BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned 1: \n", command)) != std::string::npos); 73 : : return true; 74 : 0 : }); 75 : 0 : } 76 : : { 77 : : // Return non-zero exit code, with error message for stderr 78 : : #ifdef WIN32 79 : : const std::string command{"cmd.exe /c dir nosuchfile"}; 80 : : const std::string expected{wine_runtime ? "File not found." : "File Not Found"}; 81 : : #else 82 : 0 : const std::string command{"ls nosuchfile"}; 83 : 0 : const std::string expected{"No such file or directory"}; 84 : : #endif 85 : 0 : BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) { 86 : : const std::string what(e.what()); 87 : : BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned", command)) != std::string::npos); 88 : : BOOST_CHECK(what.find(expected) != std::string::npos); 89 : : return true; 90 : : }); 91 : 0 : } 92 : : { 93 : 0 : BOOST_REQUIRE_THROW(RunCommandParseJSON("echo \"{\""), std::runtime_error); // Unable to parse JSON 94 : : } 95 : : // Test std::in, except for Windows 96 : : #ifndef WIN32 97 : : { 98 : 0 : const UniValue result = RunCommandParseJSON("cat", "{\"success\": true}"); 99 : 0 : BOOST_CHECK(result.isObject()); 100 : 0 : const UniValue& success = result.find_value("success"); 101 : 0 : BOOST_CHECK(!success.isNull()); 102 : 0 : BOOST_CHECK_EQUAL(success.get_bool(), true); 103 : 0 : } 104 : : #endif 105 : 0 : } 106 : : #endif // ENABLE_EXTERNAL_SIGNER 107 : : 108 : 0 : BOOST_AUTO_TEST_SUITE_END()