0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-05 14:06:27 -05:00

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
```
This commit is contained in:
Vasil Dimov 2021-10-08 18:11:40 +02:00
parent c561f2f06e
commit 92a0f7e58d
No known key found for this signature in database
GPG key ID: 54DF06F64B55CBBF
7 changed files with 56 additions and 12 deletions

View file

@ -19,6 +19,8 @@ using namespace std::chrono_literals;
const std::function<void(const std::string&)> G_TEST_LOG_FUN{}; const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS{};
namespace { namespace {
void GenerateTemplateResults(const std::vector<ankerl::nanobench::Result>& benchmarkResults, const std::string& filename, const char* tpl) void GenerateTemplateResults(const std::vector<ankerl::nanobench::Result>& benchmarkResults, const std::string& filename, const char* tpl)

View file

@ -22,6 +22,7 @@
#include <QApplication> #include <QApplication>
#include <QObject> #include <QObject>
#include <QTest> #include <QTest>
#include <functional>
#if defined(QT_STATICPLUGIN) #if defined(QT_STATICPLUGIN)
#include <QtPlugin> #include <QtPlugin>
@ -43,6 +44,8 @@ using node::NodeContext;
const std::function<void(const std::string&)> G_TEST_LOG_FUN{}; const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS{};
// This is all you need to run all the tests // This is all you need to run all the tests
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {

View file

@ -33,19 +33,31 @@ the `src/qt/test/test_main.cpp` file.
### Running individual tests ### Running individual tests
`test_bitcoin` has some built-in command-line arguments; for `test_bitcoin` accepts the command line arguments from the boost framework.
example, to run just the `getarg_tests` verbosely: For example, to run just the `getarg_tests` suite of tests:
test_bitcoin --log_level=all --run_test=getarg_tests -- DEBUG_LOG_OUT ```bash
test_bitcoin --log_level=all --run_test=getarg_tests
```
`log_level` controls the verbosity of the test framework, which logs when a `log_level` controls the verbosity of the test framework, which logs when a
test case is entered, for example. The `DEBUG_LOG_OUT` after the two dashes test case is entered, for example. `test_bitcoin` also accepts the command
redirects the debug log, which would normally go to a file in the test datadir line arguments accepted by `bitcoind`. Use `--` to separate both types of
arguments:
```bash
test_bitcoin --log_level=all --run_test=getarg_tests -- -printtoconsole=1
```
The `-printtoconsole=1` after the two dashes redirects the debug log, which
would normally go to a file in the test datadir
(`BasicTestingSetup::m_path_root`), to the standard terminal output. (`BasicTestingSetup::m_path_root`), to the standard terminal output.
... or to run just the doubledash test: ... or to run just the doubledash test:
test_bitcoin --run_test=getarg_tests/doubledash ```bash
test_bitcoin --run_test=getarg_tests/doubledash
```
Run `test_bitcoin --help` for the full list. Run `test_bitcoin --help` for the full list.
@ -68,7 +80,7 @@ on failure. For running individual tests verbosely, refer to the section
To write to logs from unit tests you need to use specific message methods To write to logs from unit tests you need to use specific message methods
provided by Boost. The simplest is `BOOST_TEST_MESSAGE`. provided by Boost. The simplest is `BOOST_TEST_MESSAGE`.
For debugging you can launch the `test_bitcoin` executable with `gdb`or `lldb` and For debugging you can launch the `test_bitcoin` executable with `gdb` or `lldb` and
start debugging, just like you would with any other program: start debugging, just like you would with any other program:
```bash ```bash
@ -95,7 +107,7 @@ Running the tests and hitting a segmentation fault should now produce a file cal
`/proc/sys/kernel/core_pattern`). `/proc/sys/kernel/core_pattern`).
You can then explore the core dump using You can then explore the core dump using
``` bash ```bash
gdb src/test/test_bitcoin core gdb src/test/test_bitcoin core
(gbd) bt # produce a backtrace for where a segfault occurred (gbd) bt # produce a backtrace for where a segfault occurred

View file

@ -12,6 +12,7 @@
#include <cstdint> #include <cstdint>
#include <exception> #include <exception>
#include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unistd.h> #include <unistd.h>
@ -19,6 +20,8 @@
const std::function<void(const std::string&)> G_TEST_LOG_FUN{}; const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS{};
std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>>& FuzzTargets() std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>>& FuzzTargets()
{ {
static std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>> g_fuzz_targets; static std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>> g_fuzz_targets;

View file

@ -11,6 +11,7 @@
#include <test/util/setup_common.h> #include <test/util/setup_common.h>
#include <functional>
#include <iostream> #include <iostream>
/** Redirect debug log to unit_test.log files */ /** 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
if (!should_log) return; if (!should_log) return;
std::cout << s; std::cout << s;
}; };
/**
* Retrieve the command line arguments from boost.
* Allows usage like:
* `test_bitcoin --run_test="net_tests/cnode_listen_port" -- -checkaddrman=1 -printtoconsole=1`
* which would return `["-checkaddrman=1", "-printtoconsole=1"]`.
*/
const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS = []() {
std::vector<const char*> args;
for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) {
args.push_back(boost::unit_test::framework::master_test_suite().argv[i]);
}
return args;
};

View file

@ -42,6 +42,7 @@
#include <walletinitinterface.h> #include <walletinitinterface.h>
#include <functional> #include <functional>
#include <stdexcept>
using node::BlockAssembler; using node::BlockAssembler;
using node::CalculateCacheSizes; using node::CalculateCacheSizes;
@ -88,7 +89,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
m_args{} m_args{}
{ {
m_node.args = &gArgs; m_node.args = &gArgs;
const std::vector<const char*> arguments = Cat( std::vector<const char*> arguments = Cat(
{ {
"dummy", "dummy",
"-printtoconsole=0", "-printtoconsole=0",
@ -100,6 +101,9 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
"-debugexclude=leveldb", "-debugexclude=leveldb",
}, },
extra_args); extra_args);
if (G_TEST_COMMAND_LINE_ARGUMENTS) {
arguments = Cat(arguments, G_TEST_COMMAND_LINE_ARGUMENTS());
}
util::ThreadRename("test"); util::ThreadRename("test");
fs::create_directories(m_path_root); fs::create_directories(m_path_root);
m_args.ForceSetArg("-datadir", fs::PathToString(m_path_root)); m_args.ForceSetArg("-datadir", fs::PathToString(m_path_root));
@ -108,9 +112,10 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
{ {
SetupServerArgs(*m_node.args); SetupServerArgs(*m_node.args);
std::string error; std::string error;
const bool success{m_node.args->ParseParameters(arguments.size(), arguments.data(), error)}; if (!m_node.args->ParseParameters(arguments.size(), arguments.data(), error)) {
assert(success); m_node.args->ClearArgs();
assert(error.empty()); throw std::runtime_error{error};
}
} }
SelectParams(chainName); SelectParams(chainName);
SeedInsecureRand(); SeedInsecureRand();

View file

@ -19,12 +19,16 @@
#include <util/string.h> #include <util/string.h>
#include <util/vector.h> #include <util/vector.h>
#include <functional>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
/** This is connected to the logger. Can be used to redirect logs to any other log */ /** This is connected to the logger. Can be used to redirect logs to any other log */
extern const std::function<void(const std::string&)> G_TEST_LOG_FUN; extern const std::function<void(const std::string&)> G_TEST_LOG_FUN;
/** Retrieve the command line arguments. */
extern const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS;
// Enable BOOST_CHECK_EQUAL for enum class types // Enable BOOST_CHECK_EQUAL for enum class types
namespace std { namespace std {
template <typename T> template <typename T>