Skip to content

Commit 92a0f7e

Browse files
committed
test: parse the command line arguments in unit tests
Retrieve the command line arguments from boost and pass them to `BasicTestingSetup` so that we gain extra flexibility of passing any config options on the test command line, e.g.: ``` test_bitcoin -- -printtoconsole=1 -checkaddrman=5 ```
1 parent c561f2f commit 92a0f7e

File tree

7 files changed

+56
-12
lines changed

7 files changed

+56
-12
lines changed

src/bench/bench.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ using namespace std::chrono_literals;
1919

2020
const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
2121

22+
const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS{};
23+
2224
namespace {
2325

2426
void GenerateTemplateResults(const std::vector<ankerl::nanobench::Result>& benchmarkResults, const std::string& filename, const char* tpl)

src/qt/test/test_main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <QApplication>
2323
#include <QObject>
2424
#include <QTest>
25+
#include <functional>
2526

2627
#if defined(QT_STATICPLUGIN)
2728
#include <QtPlugin>
@@ -43,6 +44,8 @@ using node::NodeContext;
4344

4445
const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
4546

47+
const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS{};
48+
4649
// This is all you need to run all the tests
4750
int main(int argc, char* argv[])
4851
{

src/test/README.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,31 @@ the `src/qt/test/test_main.cpp` file.
3333

3434
### Running individual tests
3535

36-
`test_bitcoin` has some built-in command-line arguments; for
37-
example, to run just the `getarg_tests` verbosely:
36+
`test_bitcoin` accepts the command line arguments from the boost framework.
37+
For example, to run just the `getarg_tests` suite of tests:
3838

39-
test_bitcoin --log_level=all --run_test=getarg_tests -- DEBUG_LOG_OUT
39+
```bash
40+
test_bitcoin --log_level=all --run_test=getarg_tests
41+
```
4042

4143
`log_level` controls the verbosity of the test framework, which logs when a
42-
test case is entered, for example. The `DEBUG_LOG_OUT` after the two dashes
43-
redirects the debug log, which would normally go to a file in the test datadir
44+
test case is entered, for example. `test_bitcoin` also accepts the command
45+
line arguments accepted by `bitcoind`. Use `--` to separate both types of
46+
arguments:
47+
48+
```bash
49+
test_bitcoin --log_level=all --run_test=getarg_tests -- -printtoconsole=1
50+
```
51+
52+
The `-printtoconsole=1` after the two dashes redirects the debug log, which
53+
would normally go to a file in the test datadir
4454
(`BasicTestingSetup::m_path_root`), to the standard terminal output.
4555

4656
... or to run just the doubledash test:
4757

48-
test_bitcoin --run_test=getarg_tests/doubledash
58+
```bash
59+
test_bitcoin --run_test=getarg_tests/doubledash
60+
```
4961

5062
Run `test_bitcoin --help` for the full list.
5163

@@ -68,7 +80,7 @@ on failure. For running individual tests verbosely, refer to the section
6880
To write to logs from unit tests you need to use specific message methods
6981
provided by Boost. The simplest is `BOOST_TEST_MESSAGE`.
7082

71-
For debugging you can launch the `test_bitcoin` executable with `gdb`or `lldb` and
83+
For debugging you can launch the `test_bitcoin` executable with `gdb` or `lldb` and
7284
start debugging, just like you would with any other program:
7385

7486
```bash
@@ -95,7 +107,7 @@ Running the tests and hitting a segmentation fault should now produce a file cal
95107
`/proc/sys/kernel/core_pattern`).
96108

97109
You can then explore the core dump using
98-
``` bash
110+
```bash
99111
gdb src/test/test_bitcoin core
100112

101113
(gbd) bt # produce a backtrace for where a segfault occurred

src/test/fuzz/fuzz.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212

1313
#include <cstdint>
1414
#include <exception>
15+
#include <functional>
1516
#include <memory>
1617
#include <string>
1718
#include <unistd.h>
1819
#include <vector>
1920

2021
const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
2122

23+
const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS{};
24+
2225
std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>>& FuzzTargets()
2326
{
2427
static std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>> g_fuzz_targets;

src/test/main.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <test/util/setup_common.h>
1313

14+
#include <functional>
1415
#include <iostream>
1516

1617
/** Redirect debug log to unit_test.log files */
@@ -24,3 +25,17 @@ const std::function<void(const std::string&)> G_TEST_LOG_FUN = [](const std::str
2425
if (!should_log) return;
2526
std::cout << s;
2627
};
28+
29+
/**
30+
* Retrieve the command line arguments from boost.
31+
* Allows usage like:
32+
* `test_bitcoin --run_test="net_tests/cnode_listen_port" -- -checkaddrman=1 -printtoconsole=1`
33+
* which would return `["-checkaddrman=1", "-printtoconsole=1"]`.
34+
*/
35+
const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS = []() {
36+
std::vector<const char*> args;
37+
for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) {
38+
args.push_back(boost::unit_test::framework::master_test_suite().argv[i]);
39+
}
40+
return args;
41+
};

src/test/util/setup_common.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <walletinitinterface.h>
4343

4444
#include <functional>
45+
#include <stdexcept>
4546

4647
using node::BlockAssembler;
4748
using node::CalculateCacheSizes;
@@ -88,7 +89,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
8889
m_args{}
8990
{
9091
m_node.args = &gArgs;
91-
const std::vector<const char*> arguments = Cat(
92+
std::vector<const char*> arguments = Cat(
9293
{
9394
"dummy",
9495
"-printtoconsole=0",
@@ -100,6 +101,9 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
100101
"-debugexclude=leveldb",
101102
},
102103
extra_args);
104+
if (G_TEST_COMMAND_LINE_ARGUMENTS) {
105+
arguments = Cat(arguments, G_TEST_COMMAND_LINE_ARGUMENTS());
106+
}
103107
util::ThreadRename("test");
104108
fs::create_directories(m_path_root);
105109
m_args.ForceSetArg("-datadir", fs::PathToString(m_path_root));
@@ -108,9 +112,10 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
108112
{
109113
SetupServerArgs(*m_node.args);
110114
std::string error;
111-
const bool success{m_node.args->ParseParameters(arguments.size(), arguments.data(), error)};
112-
assert(success);
113-
assert(error.empty());
115+
if (!m_node.args->ParseParameters(arguments.size(), arguments.data(), error)) {
116+
m_node.args->ClearArgs();
117+
throw std::runtime_error{error};
118+
}
114119
}
115120
SelectParams(chainName);
116121
SeedInsecureRand();

src/test/util/setup_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@
1919
#include <util/string.h>
2020
#include <util/vector.h>
2121

22+
#include <functional>
2223
#include <type_traits>
2324
#include <vector>
2425

2526
/** This is connected to the logger. Can be used to redirect logs to any other log */
2627
extern const std::function<void(const std::string&)> G_TEST_LOG_FUN;
2728

29+
/** Retrieve the command line arguments. */
30+
extern const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS;
31+
2832
// Enable BOOST_CHECK_EQUAL for enum class types
2933
namespace std {
3034
template <typename T>

0 commit comments

Comments
 (0)