Line data Source code
1 : // Copyright (c) 2019 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 <util/system.h> 7 : #include <univalue.h> 8 : 9 : #ifdef HAVE_BOOST_PROCESS 10 : #include <boost/process.hpp> 11 : #endif // HAVE_BOOST_PROCESS 12 : 13 : #include <boost/test/unit_test.hpp> 14 : 15 89 : BOOST_FIXTURE_TEST_SUITE(system_tests, BasicTestingSetup) 16 : 17 : // At least one test is required (in case HAVE_BOOST_PROCESS is not defined). 18 : // Workaround for https://github.com/bitcoin/bitcoin/issues/19128 19 95 : BOOST_AUTO_TEST_CASE(dummy) 20 : { 21 1 : BOOST_CHECK(true); 22 1 : } 23 : 24 : #ifdef HAVE_BOOST_PROCESS 25 : 26 : bool checkMessage(const std::runtime_error& ex) 27 : { 28 : // On Linux & Mac: "No such file or directory" 29 : // On Windows: "The system cannot find the file specified." 30 : const std::string what(ex.what()); 31 : BOOST_CHECK(what.find("file") != std::string::npos); 32 : return true; 33 : } 34 : 35 : bool checkMessageFalse(const std::runtime_error& ex) 36 : { 37 : BOOST_CHECK_EQUAL(ex.what(), std::string("RunCommandParseJSON error: process(false) returned 1: \n")); 38 : return true; 39 : } 40 : 41 : bool checkMessageStdErr(const std::runtime_error& ex) 42 : { 43 : const std::string what(ex.what()); 44 : BOOST_CHECK(what.find("RunCommandParseJSON error:") != std::string::npos); 45 : return checkMessage(ex); 46 : } 47 : 48 : BOOST_AUTO_TEST_CASE(run_command) 49 : { 50 : { 51 : const UniValue result = RunCommandParseJSON(""); 52 : BOOST_CHECK(result.isNull()); 53 : } 54 : { 55 : #ifdef WIN32 56 : // Windows requires single quotes to prevent escaping double quotes from the JSON... 57 : const UniValue result = RunCommandParseJSON("echo '{\"success\": true}'"); 58 : #else 59 : // ... but Linux and macOS echo a single quote if it's used 60 : const UniValue result = RunCommandParseJSON("echo \"{\"success\": true}\""); 61 : #endif 62 : BOOST_CHECK(result.isObject()); 63 : const UniValue& success = find_value(result, "success"); 64 : BOOST_CHECK(!success.isNull()); 65 : BOOST_CHECK_EQUAL(success.getBool(), true); 66 : } 67 : { 68 : // An invalid command is handled by Boost 69 : BOOST_CHECK_EXCEPTION(RunCommandParseJSON("invalid_command"), boost::process::process_error, checkMessage); // Command failed 70 : } 71 : { 72 : // Return non-zero exit code, no output to stderr 73 : BOOST_CHECK_EXCEPTION(RunCommandParseJSON("false"), std::runtime_error, checkMessageFalse); 74 : } 75 : { 76 : // Return non-zero exit code, with error message for stderr 77 : BOOST_CHECK_EXCEPTION(RunCommandParseJSON("ls nosuchfile"), std::runtime_error, checkMessageStdErr); 78 : } 79 : { 80 : BOOST_REQUIRE_THROW(RunCommandParseJSON("echo \"{\""), std::runtime_error); // Unable to parse JSON 81 : } 82 : // Test std::in, except for Windows 83 : #ifndef WIN32 84 : { 85 : const UniValue result = RunCommandParseJSON("cat", "{\"success\": true}"); 86 : BOOST_CHECK(result.isObject()); 87 : const UniValue& success = find_value(result, "success"); 88 : BOOST_CHECK(!success.isNull()); 89 : BOOST_CHECK_EQUAL(success.getBool(), true); 90 : } 91 : #endif 92 : } 93 : #endif // HAVE_BOOST_PROCESS 94 : 95 89 : BOOST_AUTO_TEST_SUITE_END()