21#include <boost/test/unit_test.hpp>
58 void SetupArgs(
const std::vector<std::pair<std::string, unsigned int>>&
args)
60 for (
const auto& arg :
args) {
99 const char* argv[] = {
"ignored", arg};
105 if (
expect.setting.isNull() ||
expect.setting.isFalse()) {
114 BOOST_CHECK_NE(error.find(
expect.error), std::string::npos);
120 if (
expect.default_string) {
122 }
else if (
expect.string_value) {
130 }
else if (
expect.int_value) {
136 if (
expect.default_bool) {
139 }
else if (
expect.bool_value) {
147 auto l = test.
GetArgs(
"-value");
148 BOOST_CHECK_EQUAL_COLLECTIONS(l.begin(), l.end(),
expect.list_value->begin(),
expect.list_value->end());
159 CheckValue(M::ALLOW_ANY,
nullptr, Expect{{}}.DefaultString().DefaultInt().DefaultBool().List({}));
160 CheckValue(M::ALLOW_ANY,
"-novalue", Expect{
false}.String(
"0").Int(0).Bool(
false).List({}));
161 CheckValue(M::ALLOW_ANY,
"-novalue=", Expect{
false}.String(
"0").Int(0).Bool(
false).List({}));
162 CheckValue(M::ALLOW_ANY,
"-novalue=0", Expect{
true}.String(
"1").Int(1).Bool(
true).List({
"1"}));
163 CheckValue(M::ALLOW_ANY,
"-novalue=1", Expect{
false}.String(
"0").Int(0).Bool(
false).List({}));
164 CheckValue(M::ALLOW_ANY,
"-novalue=2", Expect{
false}.String(
"0").Int(0).Bool(
false).List({}));
165 CheckValue(M::ALLOW_ANY,
"-novalue=abc", Expect{
true}.String(
"1").Int(1).Bool(
true).List({
"1"}));
166 CheckValue(M::ALLOW_ANY,
"-value", Expect{
""}.String(
"").Int(0).Bool(
true).List({
""}));
167 CheckValue(M::ALLOW_ANY,
"-value=", Expect{
""}.String(
"").Int(0).Bool(
true).List({
""}));
168 CheckValue(M::ALLOW_ANY,
"-value=0", Expect{
"0"}.String(
"0").Int(0).Bool(
false).List({
"0"}));
169 CheckValue(M::ALLOW_ANY,
"-value=1", Expect{
"1"}.String(
"1").Int(1).Bool(
true).List({
"1"}));
170 CheckValue(M::ALLOW_ANY,
"-value=2", Expect{
"2"}.String(
"2").Int(2).Bool(
true).List({
"2"}));
171 CheckValue(M::ALLOW_ANY,
"-value=abc", Expect{
"abc"}.String(
"abc").Int(0).Bool(
false).List({
"abc"}));
179 std::array argv{
"ignored", arg};
189 BOOST_CHECK_EQUAL(
Parse(
"-includeconf"),
"-includeconf cannot be used from commandline; -includeconf=\"\"");
190 BOOST_CHECK_EQUAL(
Parse(
"-includeconf=file"),
"-includeconf cannot be used from commandline; -includeconf=\"file\"");
201 const char *argv_test[] = {
"-ignored",
"-a",
"-b",
"-ccc=argument",
"-ccc=multiple",
"f",
"-d=e"};
207 BOOST_CHECK(
s.command_line_options.empty() &&
s.ro_config.empty());
212 BOOST_CHECK(
s.command_line_options.empty() &&
s.ro_config.empty());
222 BOOST_CHECK(
s.command_line_options.size() == 3 &&
s.ro_config.empty());
223 BOOST_CHECK(
s.command_line_options.contains(
"a") &&
s.command_line_options.contains(
"b") &&
s.command_line_options.contains(
"ccc")
224 && !
s.command_line_options.contains(
"f") && !
s.command_line_options.contains(
"d"));
226 BOOST_CHECK(
s.command_line_options.at(
"a").size() == 1);
227 BOOST_CHECK(
s.command_line_options.at(
"a").front().get_str() ==
"");
228 BOOST_CHECK(
s.command_line_options.at(
"ccc").size() == 2);
229 BOOST_CHECK(
s.command_line_options.at(
"ccc").front().get_str() ==
"argument");
230 BOOST_CHECK(
s.command_line_options.at(
"ccc").back().get_str() ==
"multiple");
240 const char* argv[] = {
"ignored",
"-registered"};
245 argv[1] =
"-unregistered";
251 argv[1] =
"-test.registered";
256static void TestParse(
const std::string& str,
bool expected_bool, int64_t expected_int)
260 std::string arg =
"-value=" + str;
261 const char* argv[] = {
"ignored", arg.c_str()};
320 const char *argv_test[] = {
321 "ignored",
"-a",
"-nob",
"-c=0",
"-d=1",
"-e=false",
"-f=true"};
327 for (
const char opt :
"abcdef")
332 BOOST_CHECK(
s.command_line_options.size() == 6 &&
s.ro_config.empty());
359 const char *argv_test[] = {
"ignored",
"-nofoo",
"-foo",
"-nobar=0"};
373 const char *conf_test =
"nofoo=1\nfoo=1\nnobar=0\n";
387 const char *combo_test_args[] = {
"ignored",
"-nofoo",
"-bar"};
388 const char *combo_test_conf =
"foo=1\nnobar=1\n";
401 && testArgs.
GetArgs(
"-bar").front() ==
"");
406 const char *str_config =
439 test_args.
SetupArgs({a, b, ccc, d, e, fff, ggg, h, i, iii});
488 for (
const bool def : {
false,
true}) {
502 && test_args.
GetArgs(
"-a").front() ==
"");
504 && test_args.
GetArgs(
"-b").front() ==
"1");
506 && test_args.
GetArgs(
"-ccc").front() ==
"argument"
507 && test_args.
GetArgs(
"-ccc").back() ==
"multiple");
511 && test_args.
GetArgs(
"-ggg").front() ==
"1");
516 && test_args.
GetArgs(
"-i").front() ==
"1");
547 const std::vector<std::string> sec1_ccc_expected = {
"extend1",
"extend2",
"argument",
"multiple"};
548 const auto& sec1_ccc_res = test_args.
GetArgs(
"-ccc");
549 BOOST_CHECK_EQUAL_COLLECTIONS(sec1_ccc_res.begin(), sec1_ccc_res.end(), sec1_ccc_expected.begin(), sec1_ccc_expected.end());
566 const std::vector<std::string> sec2_ccc_expected = {
"extend3",
"argument",
"multiple"};
567 const auto& sec2_ccc_res = test_args.
GetArgs(
"-ccc");
568 BOOST_CHECK_EQUAL_COLLECTIONS(sec2_ccc_res.begin(), sec2_ccc_res.end(), sec2_ccc_expected.begin(), sec2_ccc_expected.end());
576 test_args.
SetupArgs({a, b, ccc2, d2, e, fff, ggg, h2, i, iii});
601 s.command_line_options.clear();
602 s.command_line_options[
"strtest1"] = {
"string..."};
604 s.command_line_options[
"inttest1"] = {
"12345"};
605 s.command_line_options[
"inttest2"] = {
"81985529216486895"};
607 s.command_line_options[
"booltest1"] = {
""};
609 s.command_line_options[
"booltest3"] = {
"0"};
610 s.command_line_options[
"booltest4"] = {
"1"};
613 s.command_line_options[
"pritest1"] = {
"a",
"b"};
614 s.ro_config[
""][
"pritest2"] = {
"a",
"b"};
615 s.command_line_options[
"pritest3"] = {
"a"};
616 s.ro_config[
""][
"pritest3"] = {
"b"};
617 s.command_line_options[
"pritest4"] = {
"a",
"b"};
618 s.ro_config[
""][
"pritest4"] = {
"c",
"d"};
643 test_args.
SetupArgs({testnet, testnet4, regtest});
645 const char* argv_testnet4[] = {
"cmd",
"-testnet4"};
646 const char* argv_regtest[] = {
"cmd",
"-regtest"};
647 const char* argv_test_no_reg[] = {
"cmd",
"-testnet4",
"-noregtest"};
648 const char* argv_both[] = {
"cmd",
"-testnet4",
"-regtest"};
651 const char* testnetconf =
"testnet4=1\nregtest=0\n[testnet4]\nregtest=1";
748 template <
typename Fn>
756 for (
bool soft_set : {
false,
true}) {
757 for (
bool force_set : {
false,
true}) {
760 for (
bool net_specific : {
false,
true}) {
761 fn(arg_actions, conf_actions, soft_set, force_set, section, network, net_specific);
773 const std::string& section,
774 const std::string&
name,
775 const std::string& value_prefix)
777 std::vector<std::string>
values;
779 for (
Action action : actions) {
780 if (action ==
NONE)
break;
784 for (
int i = 0; i < 2; ++i) {
803 FILE* out_file =
nullptr;
804 if (
const char* out_path = getenv(
"ARGS_MERGE_TEST_OUT")) {
806 if (!out_file)
throw std::system_error(errno, std::generic_category(),
"fopen failed");
809 ForEachMergeSetup([&](
const ActionList& arg_actions,
const ActionList& conf_actions,
bool soft_set,
bool force_set,
810 const std::string& section,
const std::string& network,
bool net_specific) {
813 std::string desc =
"net=";
817 const std::string&
name = net_specific ?
"wallet" :
"server";
818 const std::string key =
"-" +
name;
823 auto args = GetValues(arg_actions, section,
name,
"a");
824 std::vector<const char*> argv = {
"ignored"};
825 for (
auto& arg :
args) {
829 argv.push_back(arg.c_str());
836 for (
auto& conf_val : GetValues(conf_actions, section,
name,
"c")) {
842 std::istringstream conf_stream(conf);
870 desc += parser.
GetArg(key,
"default");
872 for (
const auto& arg : parser.
GetArgs(key)) {
879 if (!ignored.empty()) {
880 desc +=
" | ignored";
881 for (
const auto& arg : ignored) {
891 BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
896 if (fclose(out_file))
throw std::system_error(errno, std::generic_category(),
"fclose failed");
902 std::string out_sha_hex =
HexStr(out_sha_bytes);
913 BOOST_CHECK_EQUAL(out_sha_hex,
"f1ee5ab094cc43d16a6086fa7f2c10389e0f99902616b31bbf29189972ad1473");
924 template <
typename Fn>
938 FILE* out_file =
nullptr;
939 if (
const char* out_path = getenv(
"CHAIN_MERGE_TEST_OUT")) {
941 if (!out_file)
throw std::system_error(errno, std::generic_category(),
"fopen failed");
944 ForEachMergeSetup([&](
const ActionList& arg_actions,
const ActionList& conf_actions) {
949 auto arg = [](Action action) {
return action == ENABLE_TEST ?
"-testnet4=1" :
950 action == DISABLE_TEST ?
"-testnet4=0" :
951 action == NEGATE_TEST ?
"-notestnet4=1" :
952 action == ENABLE_REG ?
"-regtest=1" :
953 action == DISABLE_REG ?
"-regtest=0" :
954 action == NEGATE_REG ?
"-noregtest=1" :
nullptr; };
957 std::vector<const char*> argv = {
"ignored"};
958 for (Action action : arg_actions) {
959 const char* argstr = arg(action);
961 argv.push_back(argstr);
970 for (Action action : conf_actions) {
971 const char* argstr = arg(action);
978 std::istringstream conf_stream(conf);
985 }
catch (
const std::runtime_error& e) {
993 BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
998 if (fclose(out_file))
throw std::system_error(errno, std::generic_category(),
"fclose failed");
1004 std::string out_sha_hex =
HexStr(out_sha_bytes);
1015 BOOST_CHECK_EQUAL(out_sha_hex,
"c0e33aab0c74e040ddcee9edad59e8148d8e1cacb3cccd9ea1a1f485cb6bad21");
BOOST_FIXTURE_TEST_CASE(util_CheckValue, CheckValueTest)
static void TestParse(const std::string &str, bool expected_bool, int64_t expected_int)
BOOST_AUTO_TEST_CASE(util_datadir)
std::string ChainTypeToString(ChainType chain)
bool ParseParameters(int argc, const char *const argv[], std::string &error) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
std::vector< common::SettingsValue > GetSettingsList(const std::string &arg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get list of setting values.
std::vector< std::string > GetArgs(const std::string &strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Return a vector of strings of the given argument.
@ ALLOW_ANY
disable validation
common::SettingsValue GetSetting(const std::string &arg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get setting value.
bool ReadConfigString(const std::string &str_config) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
fs::path GetDataDirBase() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get data directory path.
bool SoftSetArg(const std::string &strArg, const std::string &strValue) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Set an argument if it doesn't already have a value.
std::set< std::string > GetUnsuitableSectionOnlyArgs() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Log warnings for options in m_section_only_args when they are specified in the default section but no...
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Add argument.
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Write settings file or backup settings file.
void LockSettings(Fn &&fn) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Access settings with lock held.
void ClearPathCache() EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Clear cached directory paths.
void ForceSetArg(const std::string &strArg, const std::string &strValue) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Return string argument or default value.
std::string GetChainTypeString() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Returns the appropriate chain type string from the program arguments.
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Read settings file.
void ClearArgs() EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Clear available arguments.
bool IsArgSet(const std::string &strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Return true if the given argument has been manually set.
bool IsArgNegated(const std::string &strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Return true if the argument was originally passed as a negated option, i.e.
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
bool GetBoolArg(const std::string &strArg, bool fDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Return boolean argument or default value.
void SelectConfigNetwork(const std::string &network) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Select the network in use.
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
void Finalize(std::span< unsigned char > output)
CHash256 & Write(std::span< const unsigned char > input)
static const size_t OUTPUT_SIZE
Test GetSetting and GetArg type coercion, negation, and default value handling.
void CheckValue(unsigned int flags, const char *arg, const Expect &expect)
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
static UniValue Parse(std::string_view raw, ParamFormat format=ParamFormat::JSON)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
static std::string PathToString(const path &path)
Convert path object to a byte string.
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
FILE * fopen(const fs::path &p, const char *mode)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
#define BOOST_CHECK_THROW(stmt, excMatch)
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
constexpr auto MakeUCharSpan(const V &v) -> decltype(UCharSpanCast(std::span{v}))
Like the std::span constructor, but for (const) unsigned char member types only.
void ForEachNoDup(CharType(&string)[StringLength], CharType min_char, CharType max_char, Fn &&fn)
Iterate over string values and call function for each string without successive duplicate characters.
void ForEachMergeSetup(Fn &&fn)
Enumerate all possible test configurations.
static constexpr int MAX_ACTIONS
Max number of actions to sequence together.
std::vector< std::string > GetValues(const ActionList &actions, const std::string §ion, const std::string &name, const std::string &value_prefix)
Translate actions into a list of <key>=setting strings.
Action[MAX_ACTIONS] ActionList
void ForEachMergeSetup(Fn &&fn)
Enumerate all possible test configurations.
Action[MAX_ACTIONS] ActionList
static constexpr int MAX_ACTIONS
Expect(common::SettingsValue s)
Expect & List(std::vector< std::string > m)
Expect & String(const char *s)
std::optional< int64_t > int_value
std::optional< std::vector< std::string > > list_value
Expect & Error(const char *e)
common::SettingsValue setting
std::optional< bool > bool_value
const char * string_value
std::string Parse(const char *arg)
void ReadConfigString(const std::string &str_config)
void SetupArgs(const std::vector< std::pair< std::string, unsigned int > > &args)
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
#define ASSERT_DEBUG_LOG(message)