Bitcoin Core
32.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
test
system_tests.cpp
Go to the documentation of this file.
1
// Copyright (c) 2019-present 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 <
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
>
11
12
#include <cstdlib>
13
#include <iostream>
14
#include <string_view>
15
16
#include <
util/subprocess.h
>
17
18
#include <boost/test/unit_test.hpp>
19
20
#include <string>
21
22
namespace
{
23
// When set in the environment, test_bitcoin acts as a mock subprocess for the
24
// run_command test below instead of running unit tests.
25
constexpr
const
char
* MOCK_PROCESS_ENV =
"BITCOIN_TEST_MOCK_PROCESS"
;
26
27
const
bool
g_maybe_run_mock_dispatcher_before_main{[]() {
28
const
char
* name = std::getenv(MOCK_PROCESS_ENV);
29
if
(!name)
return
false
;
30
const
std::string_view n{name};
31
if
(n ==
"valid_json"
) {
32
std::cout << R
"({"success": true})" << std::endl;
33
std::_Exit(
EXIT_SUCCESS
);
34
}
35
if
(n ==
"nonzeroexit_nooutput"
) {
36
std::_Exit(EXIT_FAILURE);
37
}
38
if
(n ==
"nonzeroexit_stderroutput"
) {
39
std::cerr <<
"err"
<< std::endl;
40
std::_Exit(EXIT_FAILURE);
41
}
42
if
(n ==
"invalid_json"
) {
43
std::cout <<
"{"
<< std::endl;
44
std::_Exit(
EXIT_SUCCESS
);
45
}
46
if
(n ==
"pass_stdin_to_stdout"
) {
47
std::string
s
;
48
std::getline(std::cin, s);
49
std::cout <<
s
<< std::endl;
50
std::_Exit(
EXIT_SUCCESS
);
51
}
52
std::cerr <<
"Unknown mock process: "
<< n << std::endl;
53
std::_Exit(EXIT_FAILURE);
54
}()};
55
}
// namespace
56
57
BOOST_FIXTURE_TEST_SUITE
(system_tests,
BasicTestingSetup
)
58
59
static
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
#else
64
setenv(MOCK_PROCESS_ENV, name.c_str(),
/*overwrite=*/
1);
65
#endif
66
return
{boost::unit_test::framework::master_test_suite().argv[0]};
67
}
68
69
BOOST_AUTO_TEST_CASE
(run_command)
70
{
71
{
72
const
UniValue
result =
RunCommandParseJSON
({});
73
BOOST_CHECK
(result.
isNull
());
74
}
75
{
76
const
UniValue
result =
RunCommandParseJSON
(
mock_executable
(
"valid_json"
));
77
BOOST_CHECK
(result.
isObject
());
78
const
UniValue
& success = result.
find_value
(
"success"
);
79
BOOST_CHECK
(!success.
isNull
());
80
BOOST_CHECK_EQUAL
(success.
get_bool
(),
true
);
81
}
82
{
83
// An invalid command is handled by cpp-subprocess
84
#ifdef WIN32
85
const
std::string expected{
"CreateProcess failed: "
};
86
#else
87
const
std::string expected{
"execve failed: "
};
88
#endif
89
BOOST_CHECK_EXCEPTION
(
RunCommandParseJSON
({
"invalid_command"
}),
subprocess::CalledProcessError
,
HasReason
(expected));
90
}
91
{
92
// Return non-zero exit code, no output to stderr
93
const
std::vector<std::string>
command
=
mock_executable
(
"nonzeroexit_nooutput"
);
94
BOOST_CHECK_EXCEPTION
(
RunCommandParseJSON
(
command
), std::runtime_error, [&](
const
std::runtime_error& e) {
95
const
std::string what{e.what()};
96
BOOST_CHECK
(what.find(
strprintf
(
"RunCommandParseJSON error: process(%s) returned %d: \n"
,
util::Join
(
command
,
" "
), EXIT_FAILURE)) != std::string::npos);
97
return
true
;
98
});
99
}
100
{
101
// Return non-zero exit code, with error message for stderr
102
const
std::vector<std::string>
command
=
mock_executable
(
"nonzeroexit_stderroutput"
);
103
const
std::string expected{
"err"
};
104
BOOST_CHECK_EXCEPTION
(
RunCommandParseJSON
(
command
), std::runtime_error, [&](
const
std::runtime_error& e) {
105
const
std::string what(e.what());
106
BOOST_CHECK
(what.find(
strprintf
(
"RunCommandParseJSON error: process(%s) returned %s: %s"
,
util::Join
(
command
,
" "
), EXIT_FAILURE,
"err"
)) != std::string::npos);
107
BOOST_CHECK
(what.find(expected) != std::string::npos);
108
return
true
;
109
});
110
}
111
{
112
// Unable to parse JSON
113
BOOST_CHECK_EXCEPTION
(
RunCommandParseJSON
(
mock_executable
(
"invalid_json"
)), std::runtime_error,
HasReason
(
"Unable to parse JSON: {"
));
114
}
115
{
116
// Test stdin
117
const
UniValue
result =
RunCommandParseJSON
(
mock_executable
(
"pass_stdin_to_stdout"
),
"{\"success\": true}"
);
118
BOOST_CHECK
(result.
isObject
());
119
const
UniValue
& success = result.
find_value
(
"success"
);
120
BOOST_CHECK
(!success.
isNull
());
121
BOOST_CHECK_EQUAL
(success.
get_bool
(),
true
);
122
}
123
}
124
125
BOOST_AUTO_TEST_SUITE_END
()
EXIT_SUCCESS
return EXIT_SUCCESS
Definition
bitcoin-wallet.cpp:133
command
const auto command
Definition
bitcoin-wallet.cpp:119
HasReason::HasReason
HasReason(std::string_view reason)
Definition
common.h:21
UniValue
Definition
univalue.h:22
UniValue::find_value
const UniValue & find_value(std::string_view key) const
Definition
univalue.cpp:232
UniValue::isNull
bool isNull() const
Definition
univalue.h:81
UniValue::get_bool
bool get_bool() const
Definition
univalue_get.cpp:59
UniValue::isObject
bool isObject() const
Definition
univalue.h:88
subprocess::CalledProcessError
Definition
subprocess.h:134
BOOST_FIXTURE_TEST_SUITE
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EXCEPTION
BOOST_CHECK_EXCEPTION(req.LoadBody(reader), std::runtime_error, HasReason{"Cannot parse Content-Length value"})
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(ipc_tests)
Definition
ipc_tests.cpp:202
std
Definition
transaction.h:420
test_vectors_musig2_generate.s
tuple s
Definition
test_vectors_musig2_generate.py:72
util::Join
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
Definition
string.h:209
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition
object.cpp:17
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition
object.cpp:16
RunCommandParseJSON
UniValue RunCommandParseJSON(const std::vector< std::string > &cmd_args, const std::string &str_std_in)
Execute a command which returns JSON, and parse the result.
Definition
run_command.cpp:16
run_command.h
setup_common.h
string.h
BasicTestingSetup
Basic testing setup.
Definition
setup_common.h:58
subprocess.h
mock_executable
static std::vector< std::string > mock_executable(const std::string &name)
Definition
system_tests.cpp:59
common.h
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition
tinyformat.h:1172
univalue.h
Generated on
for Bitcoin Core by
1.18.0