Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2019-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.4//6#include <common/run_command.h>7#include <test/util/common.h>8#include <test/util/setup_common.h>9#include <univalue.h>10#include <util/string.h>12#include <cstdlib>13#include <iostream>14#include <string_view>16#include <util/subprocess.h>18#include <boost/test/unit_test.hpp>20#include <string>22namespace {23// When set in the environment, test_bitcoin acts as a mock subprocess for the24// run_command test below instead of running unit tests.25constexpr const char* MOCK_PROCESS_ENV = "BITCOIN_TEST_MOCK_PROCESS";27const bool g_maybe_run_mock_dispatcher_before_main{[]() {28const char* name = std::getenv(MOCK_PROCESS_ENV);29if (!name) return false;30const std::string_view n{name};31if (n == "valid_json") {32std::cout << R"({"success": true})" << std::endl;33std::_Exit(EXIT_SUCCESS);34}35if (n == "nonzeroexit_nooutput") {36std::_Exit(EXIT_FAILURE);37}38if (n == "nonzeroexit_stderroutput") {39std::cerr << "err" << std::endl;40std::_Exit(EXIT_FAILURE);41}42if (n == "invalid_json") {43std::cout << "{" << std::endl;44std::_Exit(EXIT_SUCCESS);45}46if (n == "pass_stdin_to_stdout") {47std::string s;48std::getline(std::cin, s);49std::cout << s << std::endl;50std::_Exit(EXIT_SUCCESS);51}52std::cerr << "Unknown mock process: " << n << std::endl;53std::_Exit(EXIT_FAILURE);54}()};55} // namespace57BOOST_FIXTURE_TEST_SUITE(system_tests, BasicTestingSetup)59static std::vector<std::string> mock_executable(const std::string& name)60{61#if defined(WIN32)62_putenv_s(MOCK_PROCESS_ENV, name.c_str());63#else64setenv(MOCK_PROCESS_ENV, name.c_str(), /*overwrite=*/1);65#endif66return {boost::unit_test::framework::master_test_suite().argv[0]};67}69BOOST_AUTO_TEST_CASE(run_command)70{71{72const UniValue result = RunCommandParseJSON({});73BOOST_CHECK(result.isNull());74}75{76const UniValue result = RunCommandParseJSON(mock_executable("valid_json"));77BOOST_CHECK(result.isObject());78const UniValue& success = result.find_value("success");79BOOST_CHECK(!success.isNull());80BOOST_CHECK_EQUAL(success.get_bool(), true);81}82{83// An invalid command is handled by cpp-subprocess84#ifdef WIN3285const std::string expected{"CreateProcess failed: "};86#else87const std::string expected{"execve failed: "};88#endif89BOOST_CHECK_EXCEPTION(RunCommandParseJSON({"invalid_command"}), subprocess::CalledProcessError, HasReason(expected));90}91{92// Return non-zero exit code, no output to stderr93const std::vector<std::string> command = mock_executable("nonzeroexit_nooutput");94BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) {95const std::string what{e.what()};96BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned %d: \n", util::Join(command, " "), EXIT_FAILURE)) != std::string::npos);97return true;98});99}100{101// Return non-zero exit code, with error message for stderr102const std::vector<std::string> command = mock_executable("nonzeroexit_stderroutput");103const std::string expected{"err"};104BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) {105const std::string what(e.what());106BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned %s: %s", util::Join(command, " "), EXIT_FAILURE, "err")) != std::string::npos);107BOOST_CHECK(what.find(expected) != std::string::npos);108return true;109});110}111{112// Unable to parse JSON113BOOST_CHECK_EXCEPTION(RunCommandParseJSON(mock_executable("invalid_json")), std::runtime_error, HasReason("Unable to parse JSON: {"));114}115{116// Test stdin117const UniValue result = RunCommandParseJSON(mock_executable("pass_stdin_to_stdout"), "{\"success\": true}");118BOOST_CHECK(result.isObject());119const UniValue& success = result.find_value("success");120BOOST_CHECK(!success.isNull());121BOOST_CHECK_EQUAL(success.get_bool(), true);122}123}125BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.