/ src / test / system_tests.cpp
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  #include <bitcoin-build-config.h> // IWYU pragma: keep
 7  #include <test/util/setup_common.h>
 8  #include <common/run_command.h>
 9  #include <univalue.h>
10  
11  #ifdef ENABLE_EXTERNAL_SIGNER
12  #include <util/subprocess.h>
13  #endif // ENABLE_EXTERNAL_SIGNER
14  
15  #include <boost/test/unit_test.hpp>
16  
17  BOOST_FIXTURE_TEST_SUITE(system_tests, BasicTestingSetup)
18  
19  #ifdef ENABLE_EXTERNAL_SIGNER
20  
21  BOOST_AUTO_TEST_CASE(run_command)
22  {
23      {
24          const UniValue result = RunCommandParseJSON("");
25          BOOST_CHECK(result.isNull());
26      }
27      {
28          const UniValue result = RunCommandParseJSON("echo {\"success\": true}");
29          BOOST_CHECK(result.isObject());
30          const UniValue& success = result.find_value("success");
31          BOOST_CHECK(!success.isNull());
32          BOOST_CHECK_EQUAL(success.get_bool(), true);
33      }
34      {
35          // An invalid command is handled by cpp-subprocess
36          const std::string expected{"execve failed: "};
37          BOOST_CHECK_EXCEPTION(RunCommandParseJSON("invalid_command"), subprocess::CalledProcessError, HasReason(expected));
38      }
39      {
40          // Return non-zero exit code, no output to stderr
41          const std::string command{"false"};
42          BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) {
43              const std::string what{e.what()};
44              BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned 1: \n", command)) != std::string::npos);
45              return true;
46          });
47      }
48      {
49          // Return non-zero exit code, with error message for stderr
50          const std::string command{"sh -c 'echo err 1>&2 && false'"};
51          const std::string expected{"err"};
52          BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) {
53              const std::string what(e.what());
54              BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned", command)) != std::string::npos);
55              BOOST_CHECK(what.find(expected) != std::string::npos);
56              return true;
57          });
58      }
59      {
60          // Unable to parse JSON
61          const std::string command{"echo {"};
62          BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, HasReason("Unable to parse JSON: {"));
63      }
64      // Test std::in
65      {
66          const UniValue result = RunCommandParseJSON("cat", "{\"success\": true}");
67          BOOST_CHECK(result.isObject());
68          const UniValue& success = result.find_value("success");
69          BOOST_CHECK(!success.isNull());
70          BOOST_CHECK_EQUAL(success.get_bool(), true);
71      }
72  }
73  #endif // ENABLE_EXTERNAL_SIGNER
74  
75  BOOST_AUTO_TEST_SUITE_END()