system_tests.cpp raw

   1  // Copyright (c) 2019-2022 The Limenka 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 <limenka-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  #ifdef WIN32
  29          const UniValue result = RunCommandParseJSON("cmd.exe /c echo {\"success\": true}");
  30  #else
  31          const UniValue result = RunCommandParseJSON("echo {\"success\": true}");
  32  #endif
  33          BOOST_CHECK(result.isObject());
  34          const UniValue& success = result.find_value("success");
  35          BOOST_CHECK(!success.isNull());
  36          BOOST_CHECK_EQUAL(success.get_bool(), true);
  37      }
  38      {
  39          // An invalid command is handled by cpp-subprocess
  40  #ifdef WIN32
  41          const std::string expected{"CreateProcess failed: "};
  42  #else
  43          const std::string expected{"execve failed: "};
  44  #endif
  45          BOOST_CHECK_EXCEPTION(RunCommandParseJSON("invalid_command"), subprocess::CalledProcessError, HasReason(expected));
  46      }
  47      {
  48          // Return non-zero exit code, no output to stderr
  49  #ifdef WIN32
  50          const std::string command{"cmd.exe /c exit 1"};
  51  #else
  52          const std::string command{"false"};
  53  #endif
  54          BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) {
  55              const std::string what{e.what()};
  56              BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned 1: \n", command)) != std::string::npos);
  57              return true;
  58          });
  59      }
  60      {
  61          // Return non-zero exit code, with error message for stderr
  62  #ifdef WIN32
  63          const std::string command{"cmd.exe /c \"echo err 1>&2 && exit 1\""};
  64  #else
  65          const std::string command{"sh -c 'echo err 1>&2 && false'"};
  66  #endif
  67          const std::string expected{"err"};
  68          BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) {
  69              const std::string what(e.what());
  70              BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned", command)) != std::string::npos);
  71              BOOST_CHECK(what.find(expected) != std::string::npos);
  72              return true;
  73          });
  74      }
  75      {
  76          // Unable to parse JSON
  77  #ifdef WIN32
  78          const std::string command{"cmd.exe /c echo {"};
  79  #else
  80          const std::string command{"echo {"};
  81  #endif
  82          BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, HasReason("Unable to parse JSON: {"));
  83      }
  84  #ifndef WIN32
  85      {
  86          // Test stdin
  87          const UniValue result = RunCommandParseJSON("cat", "{\"success\": true}");
  88          BOOST_CHECK(result.isObject());
  89          const UniValue& success = result.find_value("success");
  90          BOOST_CHECK(!success.isNull());
  91          BOOST_CHECK_EQUAL(success.get_bool(), true);
  92      }
  93  #endif
  94  }
  95  #endif // ENABLE_EXTERNAL_SIGNER
  96  
  97  BOOST_AUTO_TEST_SUITE_END()
  98