Branch data Line data Source code
1 : : // Copyright (c) 2011-2022 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 : : #include <common/args.h>
6 : : #include <sync.h>
7 : : #include <test/util/logging.h>
8 : : #include <test/util/setup_common.h>
9 : : #include <test/util/str.h>
10 : : #include <univalue.h>
11 : : #include <util/chaintype.h>
12 : : #include <util/fs.h>
13 : : #include <util/strencodings.h>
14 : :
15 : : #include <array>
16 : : #include <optional>
17 : : #include <cstdint>
18 : : #include <cstring>
19 : : #include <vector>
20 : :
21 : : #include <boost/test/unit_test.hpp>
22 : :
23 : : using util::ToString;
24 : :
25 : : BOOST_FIXTURE_TEST_SUITE(argsman_tests, BasicTestingSetup)
26 : :
27 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_datadir)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
28 : : {
29 : : // Use local args variable instead of m_args to avoid making assumptions about test setup
30 : 1 : ArgsManager args;
31 [ + - + - : 3 : args.ForceSetArg("-datadir", fs::PathToString(m_path_root));
+ - ]
32 : :
33 [ + - ]: 1 : const fs::path dd_norm = args.GetDataDirBase();
34 : :
35 [ + - + - : 4 : args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/");
+ - + - ]
36 [ + - ]: 1 : args.ClearPathCache();
37 [ + - + - : 1 : BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
+ - ]
38 : :
39 [ + - + - : 4 : args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.");
+ - + - ]
40 [ + - ]: 1 : args.ClearPathCache();
41 [ + - + - : 1 : BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
+ - ]
42 : :
43 [ + - + - : 4 : args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/./");
+ - + - ]
44 [ + - ]: 1 : args.ClearPathCache();
45 [ + - + - : 1 : BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
+ - ]
46 : :
47 [ + - + - : 4 : args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.//");
+ - + - ]
48 [ + - ]: 1 : args.ClearPathCache();
49 [ + - + - : 2 : BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
+ - ]
50 : 1 : }
51 : :
52 : 0 : struct TestArgsManager : public ArgsManager
53 : : {
54 : 48913 : TestArgsManager() { m_network_only_args.clear(); }
55 : 13 : void ReadConfigString(const std::string str_config)
56 : : {
57 : 13 : std::istringstream streamConfig(str_config);
58 : 13 : {
59 [ + - ]: 13 : LOCK(cs_args);
60 : 13 : m_settings.ro_config.clear();
61 [ + - ]: 13 : m_config_sections.clear();
62 : 13 : }
63 [ + - ]: 13 : std::string error;
64 [ + - + - : 26 : BOOST_REQUIRE(ReadConfigStream(streamConfig, "", error));
+ - + - ]
65 : 13 : }
66 : 23747 : void SetNetworkOnlyArg(const std::string arg)
67 : : {
68 : 23747 : LOCK(cs_args);
69 [ + - ]: 23747 : m_network_only_args.insert(arg);
70 : 23747 : }
71 : 53 : void SetupArgs(const std::vector<std::pair<std::string, unsigned int>>& args)
72 : : {
73 [ + + ]: 126 : for (const auto& arg : args) {
74 [ + - ]: 146 : AddArg(arg.first, "", arg.second, OptionsCategory::OPTIONS);
75 : : }
76 : 53 : }
77 : : using ArgsManager::GetSetting;
78 : : using ArgsManager::GetSettingsList;
79 : : using ArgsManager::ReadConfigStream;
80 : : using ArgsManager::cs_args;
81 : : using ArgsManager::m_network;
82 : : using ArgsManager::m_settings;
83 : : };
84 : :
85 : : //! Test GetSetting and GetArg type coercion, negation, and default value handling.
86 : 2 : class CheckValueTest : public TestChain100Setup
87 : : {
88 : : public:
89 : 13 : struct Expect {
90 : : common::SettingsValue setting;
91 : : bool default_string = false;
92 : : bool default_int = false;
93 : : bool default_bool = false;
94 : : const char* string_value = nullptr;
95 : : std::optional<int64_t> int_value;
96 : : std::optional<bool> bool_value;
97 : : std::optional<std::vector<std::string>> list_value;
98 : : const char* error = nullptr;
99 : :
100 : 13 : explicit Expect(common::SettingsValue s) : setting(std::move(s)) {}
101 : 1 : Expect& DefaultString() { default_string = true; return *this; }
102 : 1 : Expect& DefaultInt() { default_int = true; return *this; }
103 : 1 : Expect& DefaultBool() { default_bool = true; return *this; }
104 : 12 : Expect& String(const char* s) { string_value = s; return *this; }
105 : 12 : Expect& Int(int64_t i) { int_value = i; return *this; }
106 [ + - + - : 12 : Expect& Bool(bool b) { bool_value = b; return *this; }
+ - + - +
- + - + -
+ - ]
107 : 13 : Expect& List(std::vector<std::string> m) { list_value = std::move(m); return *this; }
108 : : Expect& Error(const char* e) { error = e; return *this; }
109 : : };
110 : :
111 : 13 : void CheckValue(unsigned int flags, const char* arg, const Expect& expect)
112 : : {
113 : 13 : TestArgsManager test;
114 [ + - + + : 26 : test.SetupArgs({{"-value", flags}});
- - ]
115 : 13 : const char* argv[] = {"ignored", arg};
116 [ + + ]: 13 : std::string error;
117 [ + + + - ]: 14 : bool success = test.ParseParameters(arg ? 2 : 1, argv, error);
118 : :
119 [ + - + - : 13 : BOOST_CHECK_EQUAL(test.GetSetting("-value").write(), expect.setting.write());
+ - + - +
- + - ]
120 [ + - + - ]: 13 : auto settings_list = test.GetSettingsList("-value");
121 [ + + + + ]: 13 : if (expect.setting.isNull() || expect.setting.isFalse()) {
122 [ + - + - ]: 5 : BOOST_CHECK_EQUAL(settings_list.size(), 0U);
123 : : } else {
124 [ + - + - ]: 8 : BOOST_CHECK_EQUAL(settings_list.size(), 1U);
125 [ + - + - : 8 : BOOST_CHECK_EQUAL(settings_list[0].write(), expect.setting.write());
+ - + - ]
126 : : }
127 : :
128 [ - + ]: 13 : if (expect.error) {
129 [ # # # # : 0 : BOOST_CHECK(!success);
# # ]
130 [ # # # # ]: 0 : BOOST_CHECK_NE(error.find(expect.error), std::string::npos);
131 : : } else {
132 [ + - + - : 26 : BOOST_CHECK(success);
+ - ]
133 [ + - + - ]: 13 : BOOST_CHECK_EQUAL(error, "");
134 : : }
135 : :
136 [ + + ]: 13 : if (expect.default_string) {
137 [ + - + - : 1 : BOOST_CHECK_EQUAL(test.GetArg("-value", "zzzzz"), "zzzzz");
+ - + - +
- ]
138 [ + - ]: 12 : } else if (expect.string_value) {
139 [ + - + - : 12 : BOOST_CHECK_EQUAL(test.GetArg("-value", "zzzzz"), expect.string_value);
+ - + - +
- ]
140 : : } else {
141 [ # # # # ]: 0 : BOOST_CHECK(!success);
142 : : }
143 : :
144 [ + + ]: 13 : if (expect.default_int) {
145 [ + - + - : 1 : BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), 99999);
+ - + - ]
146 [ + - ]: 12 : } else if (expect.int_value) {
147 [ + - + - : 12 : BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), *expect.int_value);
+ - + - ]
148 : : } else {
149 [ # # # # ]: 0 : BOOST_CHECK(!success);
150 : : }
151 : :
152 [ + + ]: 13 : if (expect.default_bool) {
153 [ + - + - : 1 : BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), false);
+ - + - ]
154 [ + - + - : 1 : BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), true);
+ - + - ]
155 [ + - ]: 12 : } else if (expect.bool_value) {
156 [ + - + - : 12 : BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), *expect.bool_value);
+ - + - ]
157 [ + - + - : 12 : BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), *expect.bool_value);
+ - + - ]
158 : : } else {
159 [ # # # # ]: 0 : BOOST_CHECK(!success);
160 : : }
161 : :
162 [ + - ]: 13 : if (expect.list_value) {
163 [ + - + - ]: 13 : auto l = test.GetArgs("-value");
164 [ + - + - : 26 : BOOST_CHECK_EQUAL_COLLECTIONS(l.begin(), l.end(), expect.list_value->begin(), expect.list_value->end());
+ - ]
165 : 13 : } else {
166 [ # # # # ]: 0 : BOOST_CHECK(!success);
167 : : }
168 [ + - + - ]: 26 : }
169 : : };
170 : :
171 [ + - + - : 7 : BOOST_FIXTURE_TEST_CASE(util_CheckValue, CheckValueTest)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
172 : : {
173 : 1 : using M = ArgsManager;
174 : :
175 [ + - ]: 2 : CheckValue(M::ALLOW_ANY, nullptr, Expect{{}}.DefaultString().DefaultInt().DefaultBool().List({}));
176 [ + - ]: 2 : CheckValue(M::ALLOW_ANY, "-novalue", Expect{false}.String("0").Int(0).Bool(false).List({}));
177 [ + - ]: 2 : CheckValue(M::ALLOW_ANY, "-novalue=", Expect{false}.String("0").Int(0).Bool(false).List({}));
178 [ + - + - ]: 3 : CheckValue(M::ALLOW_ANY, "-novalue=0", Expect{true}.String("1").Int(1).Bool(true).List({"1"}));
179 [ + - ]: 2 : CheckValue(M::ALLOW_ANY, "-novalue=1", Expect{false}.String("0").Int(0).Bool(false).List({}));
180 [ + - ]: 2 : CheckValue(M::ALLOW_ANY, "-novalue=2", Expect{false}.String("0").Int(0).Bool(false).List({}));
181 [ + - + - ]: 3 : CheckValue(M::ALLOW_ANY, "-novalue=abc", Expect{true}.String("1").Int(1).Bool(true).List({"1"}));
182 [ + - + - ]: 3 : CheckValue(M::ALLOW_ANY, "-value", Expect{""}.String("").Int(0).Bool(true).List({""}));
183 [ + - + - ]: 3 : CheckValue(M::ALLOW_ANY, "-value=", Expect{""}.String("").Int(0).Bool(true).List({""}));
184 [ + - + - ]: 3 : CheckValue(M::ALLOW_ANY, "-value=0", Expect{"0"}.String("0").Int(0).Bool(false).List({"0"}));
185 [ + - + - ]: 3 : CheckValue(M::ALLOW_ANY, "-value=1", Expect{"1"}.String("1").Int(1).Bool(true).List({"1"}));
186 [ + - + - ]: 3 : CheckValue(M::ALLOW_ANY, "-value=2", Expect{"2"}.String("2").Int(2).Bool(true).List({"2"}));
187 [ + - + - ]: 3 : CheckValue(M::ALLOW_ANY, "-value=abc", Expect{"abc"}.String("abc").Int(0).Bool(false).List({"abc"}));
188 : 1 : }
189 : :
190 : : struct NoIncludeConfTest {
191 : 3 : std::string Parse(const char* arg)
192 : : {
193 : 3 : TestArgsManager test;
194 [ + - + - : 9 : test.SetupArgs({{"-includeconf", ArgsManager::ALLOW_ANY}});
+ + - - ]
195 : 3 : std::array argv{"ignored", arg};
196 [ + - ]: 3 : std::string error;
197 [ + - ]: 3 : (void)test.ParseParameters(argv.size(), argv.data(), error);
198 : 3 : return error;
199 [ + - ]: 6 : }
200 : : };
201 : :
202 [ + - + - : 7 : BOOST_FIXTURE_TEST_CASE(util_NoIncludeConf, NoIncludeConfTest)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
203 : : {
204 [ + - ]: 1 : BOOST_CHECK_EQUAL(Parse("-noincludeconf"), "");
205 [ + - ]: 1 : BOOST_CHECK_EQUAL(Parse("-includeconf"), "-includeconf cannot be used from commandline; -includeconf=\"\"");
206 [ + - ]: 1 : BOOST_CHECK_EQUAL(Parse("-includeconf=file"), "-includeconf cannot be used from commandline; -includeconf=\"file\"");
207 : 1 : }
208 : :
209 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_ParseParameters)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
210 : : {
211 : 1 : TestArgsManager testArgs;
212 : 1 : const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);
213 : 1 : const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);
214 : 1 : const auto ccc = std::make_pair("-ccc", ArgsManager::ALLOW_ANY);
215 : 1 : const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);
216 : :
217 : 1 : const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"};
218 : :
219 [ + - ]: 1 : std::string error;
220 [ + - ]: 1 : LOCK(testArgs.cs_args);
221 [ + - + + : 5 : testArgs.SetupArgs({a, b, ccc, d});
- - ]
222 [ + - + - : 2 : BOOST_CHECK(testArgs.ParseParameters(0, argv_test, error));
+ - + - ]
223 [ + - + - : 2 : BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
- + + - +
- ]
224 : :
225 [ + - + - : 2 : BOOST_CHECK(testArgs.ParseParameters(1, argv_test, error));
+ - + - ]
226 [ + - + - : 2 : BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
- + + - +
- ]
227 : :
228 [ + - + - : 2 : BOOST_CHECK(testArgs.ParseParameters(7, argv_test, error));
+ - + - ]
229 : : // expectation: -ignored is ignored (program name argument),
230 : : // -a, -b and -ccc end up in map, -d ignored because it is after
231 : : // a non-option argument (non-GNU option parsing)
232 [ + - + - : 2 : BOOST_CHECK(testArgs.m_settings.command_line_options.size() == 3 && testArgs.m_settings.ro_config.empty());
- + + - +
- ]
233 [ + - + - : 7 : BOOST_CHECK(testArgs.IsArgSet("-a") && testArgs.IsArgSet("-b") && testArgs.IsArgSet("-ccc")
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- - + + -
+ - + - +
- + - + -
- - - - -
- - - -
- ]
234 : : && !testArgs.IsArgSet("f") && !testArgs.IsArgSet("-d"));
235 [ + - + - : 7 : BOOST_CHECK(testArgs.m_settings.command_line_options.count("a") && testArgs.m_settings.command_line_options.count("b") && testArgs.m_settings.command_line_options.count("ccc")
+ - + - +
- + - + -
+ - + - +
- - + + -
+ - + - +
- + - + -
- - - - -
- - - -
- ]
236 : : && !testArgs.m_settings.command_line_options.count("f") && !testArgs.m_settings.command_line_options.count("d"));
237 : :
238 [ + - + - : 2 : BOOST_CHECK(testArgs.m_settings.command_line_options["a"].size() == 1);
+ - + - +
- ]
239 [ + - + - : 2 : BOOST_CHECK(testArgs.m_settings.command_line_options["a"].front().get_str() == "");
+ - + - +
- + - ]
240 [ + - + - : 2 : BOOST_CHECK(testArgs.m_settings.command_line_options["ccc"].size() == 2);
+ - + - +
- ]
241 [ + - + - : 2 : BOOST_CHECK(testArgs.m_settings.command_line_options["ccc"].front().get_str() == "argument");
+ - + - +
- + - ]
242 [ + - + - : 2 : BOOST_CHECK(testArgs.m_settings.command_line_options["ccc"].back().get_str() == "multiple");
+ - + - +
- + - ]
243 [ + - + - : 2 : BOOST_CHECK(testArgs.GetArgs("-ccc").size() == 2);
+ - + - +
- ]
244 [ + - + - : 2 : }
+ - + - +
- - - ]
245 : :
246 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_ParseInvalidParameters)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
247 : : {
248 : 1 : TestArgsManager test;
249 [ + - + - : 3 : test.SetupArgs({{"-registered", ArgsManager::ALLOW_ANY}});
+ + - - ]
250 : :
251 : 1 : const char* argv[] = {"ignored", "-registered"};
252 [ + - ]: 1 : std::string error;
253 [ + - + - : 2 : BOOST_CHECK(test.ParseParameters(2, argv, error));
+ - + - ]
254 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(error, "");
255 : :
256 : 1 : argv[1] = "-unregistered";
257 [ + - + - : 2 : BOOST_CHECK(!test.ParseParameters(2, argv, error));
+ - + - ]
258 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(error, "Invalid parameter -unregistered");
259 : :
260 : : // Make sure registered parameters prefixed with a chain type trigger errors.
261 : : // (Previously, they were accepted and ignored.)
262 : 1 : argv[1] = "-test.registered";
263 [ + - + - : 2 : BOOST_CHECK(!test.ParseParameters(2, argv, error));
+ - + - ]
264 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(error, "Invalid parameter -test.registered");
265 [ + - ]: 2 : }
266 : :
267 : 31 : static void TestParse(const std::string& str, bool expected_bool, int64_t expected_int)
268 : : {
269 : 31 : TestArgsManager test;
270 [ + - + - : 93 : test.SetupArgs({{"-value", ArgsManager::ALLOW_ANY}});
+ + - - ]
271 [ + - ]: 31 : std::string arg = "-value=" + str;
272 [ + - ]: 31 : const char* argv[] = {"ignored", arg.c_str()};
273 [ + - ]: 31 : std::string error;
274 [ + - + - : 62 : BOOST_CHECK(test.ParseParameters(2, argv, error));
+ - + - ]
275 [ + - + - : 31 : BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), expected_bool);
+ - + - ]
276 [ + - + - : 31 : BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), expected_bool);
+ - + - ]
277 [ + - + - : 31 : BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99998), expected_int);
+ - + - ]
278 [ + - + - : 31 : BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), expected_int);
+ - + - ]
279 [ + - ]: 62 : }
280 : :
281 : : // Test bool and int parsing.
282 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_ArgParsing)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
283 : : {
284 : : // Some of these cases could be ambiguous or surprising to users, and might
285 : : // be worth triggering errors or warnings in the future. But for now basic
286 : : // test coverage is useful to avoid breaking backwards compatibility
287 : : // unintentionally.
288 [ + - ]: 1 : TestParse("", true, 0);
289 [ + - ]: 1 : TestParse(" ", false, 0);
290 [ + - ]: 1 : TestParse("0", false, 0);
291 [ + - ]: 1 : TestParse("0 ", false, 0);
292 [ + - ]: 1 : TestParse(" 0", false, 0);
293 [ + - ]: 1 : TestParse("+0", false, 0);
294 [ + - ]: 1 : TestParse("-0", false, 0);
295 [ + - ]: 1 : TestParse("5", true, 5);
296 [ + - ]: 1 : TestParse("5 ", true, 5);
297 [ + - ]: 1 : TestParse(" 5", true, 5);
298 [ + - ]: 1 : TestParse("+5", true, 5);
299 [ + - ]: 1 : TestParse("-5", true, -5);
300 [ + - ]: 1 : TestParse("0 5", false, 0);
301 [ + - ]: 1 : TestParse("5 0", true, 5);
302 [ + - ]: 1 : TestParse("050", true, 50);
303 [ + - ]: 1 : TestParse("0.", false, 0);
304 [ + - ]: 1 : TestParse("5.", true, 5);
305 [ + - ]: 1 : TestParse("0.0", false, 0);
306 [ + - ]: 1 : TestParse("0.5", false, 0);
307 [ + - ]: 1 : TestParse("5.0", true, 5);
308 [ + - ]: 1 : TestParse("5.5", true, 5);
309 [ + - ]: 1 : TestParse("x", false, 0);
310 [ + - ]: 1 : TestParse("x0", false, 0);
311 [ + - ]: 1 : TestParse("x5", false, 0);
312 [ + - ]: 1 : TestParse("0x", false, 0);
313 [ + - ]: 1 : TestParse("5x", true, 5);
314 [ + - ]: 1 : TestParse("0x5", false, 0);
315 [ + - ]: 1 : TestParse("false", false, 0);
316 [ + - ]: 1 : TestParse("true", false, 0);
317 [ + - ]: 1 : TestParse("yes", false, 0);
318 [ + - ]: 1 : TestParse("no", false, 0);
319 : 1 : }
320 : :
321 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_GetBoolArg)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
322 : : {
323 : 1 : TestArgsManager testArgs;
324 : 1 : const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);
325 : 1 : const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);
326 : 1 : const auto c = std::make_pair("-c", ArgsManager::ALLOW_ANY);
327 : 1 : const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);
328 : 1 : const auto e = std::make_pair("-e", ArgsManager::ALLOW_ANY);
329 : 1 : const auto f = std::make_pair("-f", ArgsManager::ALLOW_ANY);
330 : :
331 : 1 : const char *argv_test[] = {
332 : : "ignored", "-a", "-nob", "-c=0", "-d=1", "-e=false", "-f=true"};
333 [ + - ]: 1 : std::string error;
334 [ + - ]: 1 : LOCK(testArgs.cs_args);
335 [ + - + + : 7 : testArgs.SetupArgs({a, b, c, d, e, f});
- - ]
336 [ + - + - : 2 : BOOST_CHECK(testArgs.ParseParameters(7, argv_test, error));
+ - ]
337 : :
338 : : // Each letter should be set.
339 [ + + ]: 8 : for (const char opt : "abcdef")
340 [ + - + - : 14 : BOOST_CHECK(testArgs.IsArgSet({'-', opt}) || !opt);
+ - + + -
+ + - -
- ]
341 : :
342 : : // Nothing else should be in the map
343 [ + - + - : 2 : BOOST_CHECK(testArgs.m_settings.command_line_options.size() == 6 &&
- + + - +
- ]
344 : : testArgs.m_settings.ro_config.empty());
345 : :
346 : : // The -no prefix should get stripped on the way in.
347 [ + - + - : 2 : BOOST_CHECK(!testArgs.IsArgSet("-nob"));
+ - + - +
- ]
348 : :
349 : : // The -b option is flagged as negated, and nothing else is
350 [ + - + - : 2 : BOOST_CHECK(testArgs.IsArgNegated("-b"));
+ - + - +
- ]
351 [ + - + - : 2 : BOOST_CHECK(!testArgs.IsArgNegated("-a"));
+ - + - +
- ]
352 : :
353 : : // Check expected values.
354 [ + - + - : 2 : BOOST_CHECK(testArgs.GetBoolArg("-a", false) == true);
+ - + - +
- ]
355 [ + - + - : 2 : BOOST_CHECK(testArgs.GetBoolArg("-b", true) == false);
+ - + - +
- ]
356 [ + - + - : 2 : BOOST_CHECK(testArgs.GetBoolArg("-c", true) == false);
+ - + - +
- ]
357 [ + - + - : 2 : BOOST_CHECK(testArgs.GetBoolArg("-d", false) == true);
+ - + - +
- ]
358 [ + - + - : 2 : BOOST_CHECK(testArgs.GetBoolArg("-e", true) == false);
+ - + - +
- ]
359 [ + - + - : 2 : BOOST_CHECK(testArgs.GetBoolArg("-f", true) == false);
+ - + - +
- ]
360 [ + - + - : 2 : }
+ - + - +
- + - + -
- - ]
361 : :
362 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
363 : : {
364 : : // Test some awful edge cases that hopefully no user will ever exercise.
365 : 1 : TestArgsManager testArgs;
366 : :
367 : : // Params test
368 : 1 : const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY);
369 : 1 : const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY);
370 : 1 : const char *argv_test[] = {"ignored", "-nofoo", "-foo", "-nobar=0"};
371 [ + - + + : 3 : testArgs.SetupArgs({foo, bar});
- - ]
372 [ + - ]: 1 : std::string error;
373 [ + - + - : 2 : BOOST_CHECK(testArgs.ParseParameters(4, argv_test, error));
+ - + - ]
374 : :
375 : : // This was passed twice, second one overrides the negative setting.
376 [ + - + - : 2 : BOOST_CHECK(!testArgs.IsArgNegated("-foo"));
+ - + - +
- ]
377 [ + - + - : 2 : BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "");
+ - + - +
- + - ]
378 : :
379 : : // A double negative is a positive, and not marked as negated.
380 [ + - + - : 2 : BOOST_CHECK(!testArgs.IsArgNegated("-bar"));
+ - + - +
- ]
381 [ + - + - : 2 : BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "1");
+ - + - +
- + - ]
382 : :
383 : : // Config test
384 : 1 : const char *conf_test = "nofoo=1\nfoo=1\nnobar=0\n";
385 [ + - + - : 2 : BOOST_CHECK(testArgs.ParseParameters(1, argv_test, error));
+ - + - ]
386 [ + - + - ]: 1 : testArgs.ReadConfigString(conf_test);
387 : :
388 : : // This was passed twice, second one overrides the negative setting,
389 : : // and the value.
390 [ + - + - : 2 : BOOST_CHECK(!testArgs.IsArgNegated("-foo"));
+ - + - +
- ]
391 [ + - + - : 2 : BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "1");
+ - + - +
- + - ]
392 : :
393 : : // A double negative is a positive, and does not count as negated.
394 [ + - + - : 2 : BOOST_CHECK(!testArgs.IsArgNegated("-bar"));
+ - + - +
- ]
395 [ + - + - : 2 : BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "1");
+ - + - +
- + - ]
396 : :
397 : : // Combined test
398 : 1 : const char *combo_test_args[] = {"ignored", "-nofoo", "-bar"};
399 : 1 : const char *combo_test_conf = "foo=1\nnobar=1\n";
400 [ + - + - : 2 : BOOST_CHECK(testArgs.ParseParameters(3, combo_test_args, error));
+ - + - ]
401 [ + - + - ]: 1 : testArgs.ReadConfigString(combo_test_conf);
402 : :
403 : : // Command line overrides, but doesn't erase old setting
404 [ + - + - : 2 : BOOST_CHECK(testArgs.IsArgNegated("-foo"));
+ - + - +
- ]
405 [ + - + - : 2 : BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "0");
+ - + - +
- + - ]
406 [ + - + - : 2 : BOOST_CHECK(testArgs.GetArgs("-foo").size() == 0);
+ - + - +
- ]
407 : :
408 : : // Command line overrides, but doesn't erase old setting
409 [ + - + - : 2 : BOOST_CHECK(!testArgs.IsArgNegated("-bar"));
+ - + - +
- ]
410 [ + - + - : 2 : BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "");
+ - + - +
- + - ]
411 [ + - + - : 4 : BOOST_CHECK(testArgs.GetArgs("-bar").size() == 1
+ - + - +
- + - - +
+ - + - +
- - - - -
- - - - ]
412 : : && testArgs.GetArgs("-bar").front() == "");
413 [ + - + - : 2 : }
+ - - - ]
414 : :
415 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
416 : : {
417 : 1 : const char *str_config =
418 : : "a=\n"
419 : : "b=1\n"
420 : : "ccc=argument\n"
421 : : "ccc=multiple\n"
422 : : "d=e\n"
423 : : "nofff=1\n"
424 : : "noggg=0\n"
425 : : "h=1\n"
426 : : "noh=1\n"
427 : : "noi=1\n"
428 : : "i=1\n"
429 : : "sec1.ccc=extend1\n"
430 : : "\n"
431 : : "[sec1]\n"
432 : : "ccc=extend2\n"
433 : : "d=eee\n"
434 : : "h=1\n"
435 : : "[sec2]\n"
436 : : "ccc=extend3\n"
437 : : "iii=2\n";
438 : :
439 : 1 : TestArgsManager test_args;
440 [ + - ]: 1 : LOCK(test_args.cs_args);
441 : 1 : const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);
442 : 1 : const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);
443 : 1 : const auto ccc = std::make_pair("-ccc", ArgsManager::ALLOW_ANY);
444 : 1 : const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);
445 : 1 : const auto e = std::make_pair("-e", ArgsManager::ALLOW_ANY);
446 : 1 : const auto fff = std::make_pair("-fff", ArgsManager::ALLOW_ANY);
447 : 1 : const auto ggg = std::make_pair("-ggg", ArgsManager::ALLOW_ANY);
448 : 1 : const auto h = std::make_pair("-h", ArgsManager::ALLOW_ANY);
449 : 1 : const auto i = std::make_pair("-i", ArgsManager::ALLOW_ANY);
450 : 1 : const auto iii = std::make_pair("-iii", ArgsManager::ALLOW_ANY);
451 [ + - + + : 11 : test_args.SetupArgs({a, b, ccc, d, e, fff, ggg, h, i, iii});
- - ]
452 : :
453 [ + - + - ]: 1 : test_args.ReadConfigString(str_config);
454 : : // expectation: a, b, ccc, d, fff, ggg, h, i end up in map
455 : : // so do sec1.ccc, sec1.d, sec1.h, sec2.ccc, sec2.iii
456 : :
457 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.command_line_options.empty());
+ - ]
458 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config.size() == 3);
+ - ]
459 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config[""].size() == 8);
+ - + - +
- ]
460 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config["sec1"].size() == 3);
+ - + - +
- ]
461 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config["sec2"].size() == 2);
+ - + - +
- ]
462 : :
463 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config[""].count("a"));
+ - + - +
- + - ]
464 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config[""].count("b"));
+ - + - +
- + - ]
465 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config[""].count("ccc"));
+ - + - +
- + - ]
466 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config[""].count("d"));
+ - + - +
- + - ]
467 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config[""].count("fff"));
+ - + - +
- + - ]
468 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config[""].count("ggg"));
+ - + - +
- + - ]
469 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config[""].count("h"));
+ - + - +
- + - ]
470 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config[""].count("i"));
+ - + - +
- + - ]
471 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config["sec1"].count("ccc"));
+ - + - +
- + - ]
472 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config["sec1"].count("h"));
+ - + - +
- + - ]
473 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config["sec2"].count("ccc"));
+ - + - +
- + - ]
474 [ + - + - : 2 : BOOST_CHECK(test_args.m_settings.ro_config["sec2"].count("iii"));
+ - + - +
- + - ]
475 : :
476 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgSet("-a"));
+ - + - +
- ]
477 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgSet("-b"));
+ - + - +
- ]
478 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgSet("-ccc"));
+ - + - +
- ]
479 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgSet("-d"));
+ - + - +
- ]
480 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgSet("-fff"));
+ - + - +
- ]
481 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgSet("-ggg"));
+ - + - +
- ]
482 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgSet("-h"));
+ - + - +
- ]
483 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgSet("-i"));
+ - + - +
- ]
484 [ + - + - : 2 : BOOST_CHECK(!test_args.IsArgSet("-zzz"));
+ - + - +
- ]
485 [ + - + - : 2 : BOOST_CHECK(!test_args.IsArgSet("-iii"));
+ - + - +
- ]
486 : :
487 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-a", "xxx"), "");
+ - + - +
- ]
488 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-b", "xxx"), "1");
+ - + - +
- ]
489 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-ccc", "xxx"), "argument");
+ - + - +
- ]
490 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-d", "xxx"), "e");
+ - + - +
- ]
491 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-fff", "xxx"), "0");
+ - + - +
- ]
492 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-ggg", "xxx"), "1");
+ - + - +
- ]
493 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-h", "xxx"), "0");
+ - + - +
- ]
494 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-i", "xxx"), "1");
+ - + - +
- ]
495 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-zzz", "xxx"), "xxx");
+ - + - +
- ]
496 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-iii", "xxx"), "xxx");
+ - + - +
- ]
497 : :
498 [ + + ]: 3 : for (const bool def : {false, true}) {
499 [ + - + - : 4 : BOOST_CHECK(test_args.GetBoolArg("-a", def));
+ - + - +
- ]
500 [ + - + - : 4 : BOOST_CHECK(test_args.GetBoolArg("-b", def));
+ - + - +
- ]
501 [ + - + - : 4 : BOOST_CHECK(!test_args.GetBoolArg("-ccc", def));
+ - + - +
- ]
502 [ + - + - : 4 : BOOST_CHECK(!test_args.GetBoolArg("-d", def));
+ - + - +
- ]
503 [ + - + - : 4 : BOOST_CHECK(!test_args.GetBoolArg("-fff", def));
+ - + - +
- ]
504 [ + - + - : 4 : BOOST_CHECK(test_args.GetBoolArg("-ggg", def));
+ - + - +
- ]
505 [ + - + - : 4 : BOOST_CHECK(!test_args.GetBoolArg("-h", def));
+ - + - +
- ]
506 [ + - + - : 4 : BOOST_CHECK(test_args.GetBoolArg("-i", def));
+ - + - +
- ]
507 [ + - + - : 4 : BOOST_CHECK(test_args.GetBoolArg("-zzz", def) == def);
+ - + - +
- ]
508 [ + - + - : 4 : BOOST_CHECK(test_args.GetBoolArg("-iii", def) == def);
+ - + - ]
509 : : }
510 : :
511 [ + - + - : 4 : BOOST_CHECK(test_args.GetArgs("-a").size() == 1
+ - + - +
- + - - +
+ - + - +
- + - - -
- - - - -
- ]
512 : : && test_args.GetArgs("-a").front() == "");
513 [ + - + - : 4 : BOOST_CHECK(test_args.GetArgs("-b").size() == 1
+ - + - +
- + - - +
+ - + - +
- + - - -
- - - - -
- ]
514 : : && test_args.GetArgs("-b").front() == "1");
515 [ + - + - : 5 : BOOST_CHECK(test_args.GetArgs("-ccc").size() == 2
+ - + - +
- + - + -
+ - + - -
+ + - + -
+ - + - +
- + - - -
- - - - -
- - - -
- ]
516 : : && test_args.GetArgs("-ccc").front() == "argument"
517 : : && test_args.GetArgs("-ccc").back() == "multiple");
518 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-fff").size() == 0);
+ - + - +
- ]
519 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-nofff").size() == 0);
+ - + - +
- ]
520 [ + - + - : 4 : BOOST_CHECK(test_args.GetArgs("-ggg").size() == 1
+ - + - +
- + - - +
+ - + - +
- + - - -
- - - - -
- ]
521 : : && test_args.GetArgs("-ggg").front() == "1");
522 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-noggg").size() == 0);
+ - + - +
- ]
523 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-h").size() == 0);
+ - + - +
- ]
524 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-noh").size() == 0);
+ - + - +
- ]
525 [ + - + - : 4 : BOOST_CHECK(test_args.GetArgs("-i").size() == 1
+ - + - +
- + - - +
+ - + - +
- + - - -
- - - - -
- ]
526 : : && test_args.GetArgs("-i").front() == "1");
527 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-noi").size() == 0);
+ - + - +
- ]
528 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-zzz").size() == 0);
+ - + - +
- ]
529 : :
530 [ + - + - : 2 : BOOST_CHECK(!test_args.IsArgNegated("-a"));
+ - + - +
- ]
531 [ + - + - : 2 : BOOST_CHECK(!test_args.IsArgNegated("-b"));
+ - + - +
- ]
532 [ + - + - : 2 : BOOST_CHECK(!test_args.IsArgNegated("-ccc"));
+ - + - +
- ]
533 [ + - + - : 2 : BOOST_CHECK(!test_args.IsArgNegated("-d"));
+ - + - +
- ]
534 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgNegated("-fff"));
+ - + - +
- ]
535 [ + - + - : 2 : BOOST_CHECK(!test_args.IsArgNegated("-ggg"));
+ - + - +
- ]
536 [ + - + - : 2 : BOOST_CHECK(test_args.IsArgNegated("-h")); // last setting takes precedence
+ - + - +
- ]
537 [ + - + - : 2 : BOOST_CHECK(!test_args.IsArgNegated("-i")); // last setting takes precedence
+ - + - +
- ]
538 [ + - + - : 2 : BOOST_CHECK(!test_args.IsArgNegated("-zzz"));
+ - + - +
- ]
539 : :
540 : : // Test sections work
541 [ + - + - ]: 1 : test_args.SelectConfigNetwork("sec1");
542 : :
543 : : // same as original
544 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-a", "xxx"), "");
+ - + - +
- ]
545 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-b", "xxx"), "1");
+ - + - +
- ]
546 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-fff", "xxx"), "0");
+ - + - +
- ]
547 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-ggg", "xxx"), "1");
+ - + - +
- ]
548 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-zzz", "xxx"), "xxx");
+ - + - +
- ]
549 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetArg("-iii", "xxx"), "xxx");
+ - + - +
- ]
550 : : // d is overridden
551 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-d", "xxx") == "eee");
+ - + - +
- + - ]
552 : : // section-specific setting
553 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-h", "xxx") == "1");
+ - + - +
- + - ]
554 : : // section takes priority for multiple values
555 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-ccc", "xxx") == "extend1");
+ - + - +
- + - ]
556 : : // check multiple values works
557 [ + - ]: 1 : const std::vector<std::string> sec1_ccc_expected = {"extend1","extend2","argument","multiple"};
558 [ + - + - ]: 1 : const auto& sec1_ccc_res = test_args.GetArgs("-ccc");
559 [ + - + - : 2 : BOOST_CHECK_EQUAL_COLLECTIONS(sec1_ccc_res.begin(), sec1_ccc_res.end(), sec1_ccc_expected.begin(), sec1_ccc_expected.end());
+ - + - ]
560 : :
561 [ + - + - ]: 1 : test_args.SelectConfigNetwork("sec2");
562 : :
563 : : // same as original
564 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-a", "xxx") == "");
+ - + - +
- + - ]
565 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-b", "xxx") == "1");
+ - + - +
- + - ]
566 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-d", "xxx") == "e");
+ - + - +
- + - ]
567 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-fff", "xxx") == "0");
+ - + - +
- + - ]
568 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-ggg", "xxx") == "1");
+ - + - +
- + - ]
569 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-zzz", "xxx") == "xxx");
+ - + - +
- + - ]
570 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-h", "xxx") == "0");
+ - + - +
- + - ]
571 : : // section-specific setting
572 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-iii", "xxx") == "2");
+ - + - +
- + - ]
573 : : // section takes priority for multiple values
574 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-ccc", "xxx") == "extend3");
+ - + - +
- + - ]
575 : : // check multiple values works
576 [ + - ]: 1 : const std::vector<std::string> sec2_ccc_expected = {"extend3","argument","multiple"};
577 [ + - + - ]: 1 : const auto& sec2_ccc_res = test_args.GetArgs("-ccc");
578 [ + - + - : 2 : BOOST_CHECK_EQUAL_COLLECTIONS(sec2_ccc_res.begin(), sec2_ccc_res.end(), sec2_ccc_expected.begin(), sec2_ccc_expected.end());
+ - + - ]
579 : :
580 : : // Test section only options
581 : :
582 [ + - + - ]: 1 : test_args.SetNetworkOnlyArg("-d");
583 [ + - + - ]: 1 : test_args.SetNetworkOnlyArg("-ccc");
584 [ + - + - ]: 1 : test_args.SetNetworkOnlyArg("-h");
585 : :
586 [ + - + - ]: 1 : test_args.SelectConfigNetwork(ChainTypeToString(ChainType::MAIN));
587 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-d", "xxx") == "e");
+ - + - +
- + - ]
588 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-ccc").size() == 2);
+ - + - +
- ]
589 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-h", "xxx") == "0");
+ - + - +
- + - ]
590 : :
591 [ + - + - ]: 1 : test_args.SelectConfigNetwork("sec1");
592 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-d", "xxx") == "eee");
+ - + - +
- + - ]
593 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-d").size() == 1);
+ - + - +
- ]
594 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-ccc").size() == 2);
+ - + - +
- ]
595 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-h", "xxx") == "1");
+ - + - +
- + - ]
596 : :
597 [ + - + - ]: 1 : test_args.SelectConfigNetwork("sec2");
598 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-d", "xxx") == "xxx");
+ - + - +
- + - ]
599 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-d").size() == 0);
+ - + - +
- ]
600 [ + - + - : 2 : BOOST_CHECK(test_args.GetArgs("-ccc").size() == 1);
+ - + - +
- ]
601 [ + - + - : 2 : BOOST_CHECK(test_args.GetArg("-h", "xxx") == "0");
+ - + - +
- ]
602 [ + - + - : 3 : }
+ - + - +
- + - + -
+ - + - +
- + - + -
- - ]
603 : :
604 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_GetArg)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
605 : : {
606 : 1 : TestArgsManager testArgs;
607 [ + - ]: 1 : LOCK(testArgs.cs_args);
608 : 1 : testArgs.m_settings.command_line_options.clear();
609 [ + - + - : 3 : testArgs.m_settings.command_line_options["strtest1"] = {"string..."};
+ - + + -
- ]
610 : : // strtest2 undefined on purpose
611 [ + - + - : 3 : testArgs.m_settings.command_line_options["inttest1"] = {"12345"};
+ - + + -
- ]
612 [ + - + - : 3 : testArgs.m_settings.command_line_options["inttest2"] = {"81985529216486895"};
+ - + + -
- ]
613 : : // inttest3 undefined on purpose
614 [ + - + - : 3 : testArgs.m_settings.command_line_options["booltest1"] = {""};
+ - + + -
- ]
615 : : // booltest2 undefined on purpose
616 [ + - + - : 3 : testArgs.m_settings.command_line_options["booltest3"] = {"0"};
+ - + + -
- ]
617 [ + - + - : 3 : testArgs.m_settings.command_line_options["booltest4"] = {"1"};
+ - + + -
- ]
618 : :
619 : : // priorities
620 [ + - + - : 4 : testArgs.m_settings.command_line_options["pritest1"] = {"a", "b"};
+ - + + -
- ]
621 [ + - + - : 4 : testArgs.m_settings.ro_config[""]["pritest2"] = {"a", "b"};
+ - + - +
- + + -
- ]
622 [ + - + - : 3 : testArgs.m_settings.command_line_options["pritest3"] = {"a"};
+ - + + -
- ]
623 [ + - + - : 3 : testArgs.m_settings.ro_config[""]["pritest3"] = {"b"};
+ - + - +
- + + -
- ]
624 [ + - + - : 4 : testArgs.m_settings.command_line_options["pritest4"] = {"a","b"};
+ - + + -
- ]
625 [ + - + - : 4 : testArgs.m_settings.ro_config[""]["pritest4"] = {"c","d"};
+ - + - +
- + + -
- ]
626 : :
627 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetArg("strtest1", "default"), "string...");
+ - + - +
- ]
628 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetArg("strtest2", "default"), "default");
+ - + - +
- ]
629 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetIntArg("inttest1", -1), 12345);
+ - + - ]
630 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetIntArg("inttest2", -1), 81985529216486895LL);
+ - + - ]
631 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetIntArg("inttest3", -1), -1);
+ - + - ]
632 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest1", false), true);
+ - + - ]
633 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest2", false), false);
+ - + - ]
634 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest3", false), false);
+ - + - ]
635 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest4", false), true);
+ - + - ]
636 : :
637 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetArg("pritest1", "default"), "b");
+ - + - +
- ]
638 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetArg("pritest2", "default"), "a");
+ - + - +
- ]
639 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetArg("pritest3", "default"), "a");
+ - + - +
- ]
640 [ + - + - : 1 : BOOST_CHECK_EQUAL(testArgs.GetArg("pritest4", "default"), "b");
+ - + - +
- + - ]
641 [ + - + - : 13 : }
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - - -
- - - - -
- ]
642 : :
643 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_GetChainTypeString)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
644 : : {
645 : 1 : TestArgsManager test_args;
646 : 1 : const auto testnet = std::make_pair("-testnet", ArgsManager::ALLOW_ANY);
647 : 1 : const auto testnet4 = std::make_pair("-testnet4", ArgsManager::ALLOW_ANY);
648 : 1 : const auto regtest = std::make_pair("-regtest", ArgsManager::ALLOW_ANY);
649 [ + - + + : 4 : test_args.SetupArgs({testnet, testnet4, regtest});
- - ]
650 : :
651 : 1 : const char* argv_testnet[] = {"cmd", "-testnet"};
652 : 1 : const char* argv_testnet4[] = {"cmd", "-testnet4"};
653 : 1 : const char* argv_regtest[] = {"cmd", "-regtest"};
654 : 1 : const char* argv_test_no_reg[] = {"cmd", "-testnet", "-noregtest"};
655 : 1 : const char* argv_both[] = {"cmd", "-testnet", "-regtest"};
656 : :
657 : : // equivalent to "-testnet"
658 : : // regtest in testnet section is ignored
659 : 1 : const char* testnetconf = "testnet=1\nregtest=0\n[test]\nregtest=1";
660 [ + - ]: 1 : std::string error;
661 : :
662 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(0, argv_testnet, error));
+ - + - ]
663 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "main");
+ - ]
664 : :
665 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
+ - + - ]
666 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
+ - ]
667 : :
668 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(0, argv_testnet4, error));
+ - + - ]
669 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "main");
+ - ]
670 : :
671 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(2, argv_testnet4, error));
+ - + - ]
672 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "testnet4");
+ - ]
673 : :
674 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
+ - + - ]
675 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "regtest");
+ - ]
676 : :
677 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(3, argv_test_no_reg, error));
+ - + - ]
678 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
+ - ]
679 : :
680 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(3, argv_both, error));
+ - + - ]
681 [ + - - + : 2 : BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
- - - - -
+ + - +
- ]
682 : :
683 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(0, argv_testnet, error));
+ - + - ]
684 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
685 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
+ - ]
686 : :
687 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
+ - + - ]
688 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
689 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
+ - ]
690 : :
691 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
+ - + - ]
692 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
693 [ + - - + : 2 : BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
- - - - -
+ + - +
- ]
694 : :
695 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(3, argv_test_no_reg, error));
+ - + - ]
696 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
697 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
+ - ]
698 : :
699 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(3, argv_both, error));
+ - + - ]
700 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
701 [ + - - + : 2 : BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
- - - - -
+ + - +
- ]
702 : :
703 : : // check setting the network to test (and thus making
704 : : // [test] regtest=1 potentially relevant) doesn't break things
705 [ + - + - ]: 1 : test_args.SelectConfigNetwork("test");
706 : :
707 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(0, argv_testnet, error));
+ - + - ]
708 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
709 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
+ - ]
710 : :
711 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
+ - + - ]
712 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
713 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
+ - ]
714 : :
715 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
+ - + - ]
716 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
717 [ + - - + : 2 : BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
- - - - -
+ + - +
- ]
718 : :
719 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(2, argv_test_no_reg, error));
+ - + - ]
720 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
721 [ + - + - : 1 : BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
+ - ]
722 : :
723 [ + - + - : 2 : BOOST_CHECK(test_args.ParseParameters(3, argv_both, error));
+ - + - ]
724 [ + - + - ]: 1 : test_args.ReadConfigString(testnetconf);
725 [ + - - + : 2 : BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
- - - - -
+ + - +
- ]
726 [ + - + - : 2 : }
+ - + - -
- ]
727 : :
728 : : // Test different ways settings can be merged, and verify results. This test can
729 : : // be used to confirm that updates to settings code don't change behavior
730 : : // unintentionally.
731 : : //
732 : : // The test covers:
733 : : //
734 : : // - Combining different setting actions. Possible actions are: configuring a
735 : : // setting, negating a setting (adding "-no" prefix), and configuring/negating
736 : : // settings in a network section (adding "main." or "test." prefixes).
737 : : //
738 : : // - Combining settings from command line arguments and a config file.
739 : : //
740 : : // - Combining SoftSet and ForceSet calls.
741 : : //
742 : : // - Testing "main" and "test" network values to make sure settings from network
743 : : // sections are applied and to check for mainnet-specific behaviors like
744 : : // inheriting settings from the default section.
745 : : //
746 : : // - Testing network-specific settings like "-wallet", that may be ignored
747 : : // outside a network section, and non-network specific settings like "-server"
748 : : // that aren't sensitive to the network.
749 : : //
750 : 2 : struct ArgsMergeTestingSetup : public BasicTestingSetup {
751 : : //! Max number of actions to sequence together. Can decrease this when
752 : : //! debugging to make test results easier to understand.
753 : : static constexpr int MAX_ACTIONS = 3;
754 : :
755 : : enum Action { NONE, SET, NEGATE, SECTION_SET, SECTION_NEGATE };
756 : : using ActionList = Action[MAX_ACTIONS];
757 : :
758 : : //! Enumerate all possible test configurations.
759 : : template <typename Fn>
760 : 1 : void ForEachMergeSetup(Fn&& fn)
761 : : {
762 : 1 : ActionList arg_actions = {};
763 : : // command_line_options do not have sections. Only iterate over SET and NEGATE
764 : 1 : ForEachNoDup(arg_actions, SET, NEGATE, [&] {
765 : 7 : ActionList conf_actions = {};
766 : 378 : ForEachNoDup(conf_actions, SET, SECTION_NEGATE, [&] {
767 [ + + ]: 1113 : for (bool soft_set : {false, true}) {
768 [ + + ]: 2226 : for (bool force_set : {false, true}) {
769 [ + - + - : 14840 : for (const std::string& section : {ChainTypeToString(ChainType::MAIN), ChainTypeToString(ChainType::TESTNET), ChainTypeToString(ChainType::TESTNET4), ChainTypeToString(ChainType::SIGNET)}) {
+ - + - +
+ + + - -
- - ]
770 [ + - + - : 59360 : for (const std::string& network : {ChainTypeToString(ChainType::MAIN), ChainTypeToString(ChainType::TESTNET), ChainTypeToString(ChainType::TESTNET4), ChainTypeToString(ChainType::SIGNET)}) {
+ - + - +
+ + + - -
- - ]
771 [ + + ]: 71232 : for (bool net_specific : {false, true}) {
772 [ - + ]: 47488 : fn(arg_actions, conf_actions, soft_set, force_set, section, network, net_specific);
773 : : }
774 : : }
775 : : }
776 : : }
777 : : }
778 : : });
779 : : });
780 : 1 : }
781 : :
782 : : //! Translate actions into a list of <key>=<value> setting strings.
783 : 94976 : std::vector<std::string> GetValues(const ActionList& actions,
784 : : const std::string& section,
785 : : const std::string& name,
786 : : const std::string& value_prefix)
787 : : {
788 : 94976 : std::vector<std::string> values;
789 : 94976 : int suffix = 0;
790 [ + + ]: 298240 : for (Action action : actions) {
791 [ + + ]: 252416 : if (action == NONE) break;
792 [ + + ]: 203264 : std::string prefix;
793 [ + + + - ]: 203264 : if (action == SECTION_SET || action == SECTION_NEGATE) prefix = section + ".";
794 [ + + ]: 203264 : if (action == SET || action == SECTION_SET) {
795 [ + + ]: 304896 : for (int i = 0; i < 2; ++i) {
796 [ + - + - : 609792 : values.push_back(prefix + name + "=" + value_prefix + ToString(++suffix));
+ - + - ]
797 : : }
798 : : }
799 [ + + ]: 203264 : if (action == NEGATE || action == SECTION_NEGATE) {
800 [ + - + - : 203264 : values.push_back(prefix + "no" + name + "=1");
+ - ]
801 : : }
802 : 203264 : }
803 : 94976 : return values;
804 : 0 : }
805 : : };
806 : :
807 : : // Regression test covering different ways config settings can be merged. The
808 : : // test parses and merges settings, representing the results as strings that get
809 : : // compared against an expected hash. To debug, the result strings can be dumped
810 : : // to a file (see comments below).
811 [ + - + - : 7 : BOOST_FIXTURE_TEST_CASE(util_ArgsMerge, ArgsMergeTestingSetup)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
812 : : {
813 : 1 : CHash256 out_sha;
814 : 1 : FILE* out_file = nullptr;
815 [ - + ]: 1 : if (const char* out_path = getenv("ARGS_MERGE_TEST_OUT")) {
816 [ # # ]: 0 : out_file = fsbridge::fopen(out_path, "w");
817 [ # # # # ]: 0 : if (!out_file) throw std::system_error(errno, std::generic_category(), "fopen failed");
818 : : }
819 : :
820 : 47489 : ForEachMergeSetup([&](const ActionList& arg_actions, const ActionList& conf_actions, bool soft_set, bool force_set,
821 : : const std::string& section, const std::string& network, bool net_specific) {
822 : 47488 : TestArgsManager parser;
823 [ + - ]: 47488 : LOCK(parser.cs_args);
824 : :
825 [ + - ]: 47488 : std::string desc = "net=";
826 [ + - ]: 47488 : desc += network;
827 [ + - ]: 47488 : parser.m_network = network;
828 : :
829 [ + + + - : 71232 : const std::string& name = net_specific ? "wallet" : "server";
+ - ]
830 [ + - ]: 47488 : const std::string key = "-" + name;
831 [ + - ]: 47488 : parser.AddArg(key, name, ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
832 [ + + + - : 71232 : if (net_specific) parser.SetNetworkOnlyArg(key);
+ - ]
833 : :
834 [ + - + - ]: 47488 : auto args = GetValues(arg_actions, section, name, "a");
835 [ + - ]: 47488 : std::vector<const char*> argv = {"ignored"};
836 [ + + ]: 169600 : for (auto& arg : args) {
837 [ + - ]: 122112 : arg.insert(0, "-");
838 [ + - ]: 122112 : desc += " ";
839 [ + - ]: 122112 : desc += arg;
840 [ + - ]: 122112 : argv.push_back(arg.c_str());
841 : : }
842 [ + - ]: 47488 : std::string error;
843 [ + - + - : 94976 : BOOST_CHECK(parser.ParseParameters(argv.size(), argv.data(), error));
+ - + - ]
844 [ + - + - ]: 47488 : BOOST_CHECK_EQUAL(error, "");
845 : :
846 [ + - ]: 47488 : std::string conf;
847 [ + - + - : 230272 : for (auto& conf_val : GetValues(conf_actions, section, name, "c")) {
+ + ]
848 [ + - ]: 182784 : desc += " ";
849 [ + - ]: 182784 : desc += conf_val;
850 [ + - ]: 182784 : conf += conf_val;
851 [ + - ]: 182784 : conf += "\n";
852 : 47488 : }
853 [ + - ]: 47488 : std::istringstream conf_stream(conf);
854 [ + - + - : 94976 : BOOST_CHECK(parser.ReadConfigStream(conf_stream, "filepath", error));
+ - + - +
- ]
855 [ + - + - ]: 47488 : BOOST_CHECK_EQUAL(error, "");
856 : :
857 [ + + ]: 47488 : if (soft_set) {
858 [ + - ]: 23744 : desc += " soft";
859 [ + - + - ]: 23744 : parser.SoftSetArg(key, "soft1");
860 [ + - + - ]: 47488 : parser.SoftSetArg(key, "soft2");
861 : : }
862 : :
863 [ + + ]: 47488 : if (force_set) {
864 [ + - ]: 23744 : desc += " force";
865 [ + - + - ]: 23744 : parser.ForceSetArg(key, "force1");
866 [ + - + - ]: 47488 : parser.ForceSetArg(key, "force2");
867 : : }
868 : :
869 [ + - ]: 47488 : desc += " || ";
870 : :
871 [ + - + + ]: 47488 : if (!parser.IsArgSet(key)) {
872 [ + - ]: 392 : desc += "unset";
873 [ + - + - : 784 : BOOST_CHECK(!parser.IsArgNegated(key));
+ - + - ]
874 [ + - + - : 392 : BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "default");
+ - + - ]
875 [ + - + - : 784 : BOOST_CHECK(parser.GetArgs(key).empty());
+ - ]
876 [ + - + + ]: 47096 : } else if (parser.IsArgNegated(key)) {
877 [ + - ]: 11696 : desc += "negated";
878 [ + - + - : 11696 : BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "0");
+ - + - ]
879 [ + - + - : 23392 : BOOST_CHECK(parser.GetArgs(key).empty());
+ - ]
880 : : } else {
881 [ + - + - ]: 70800 : desc += parser.GetArg(key, "default");
882 [ + - ]: 35400 : desc += " |";
883 [ + - + + ]: 110468 : for (const auto& arg : parser.GetArgs(key)) {
884 [ + - ]: 75068 : desc += " ";
885 [ + - ]: 150136 : desc += arg;
886 : 35400 : }
887 : : }
888 : :
889 [ + - ]: 47488 : std::set<std::string> ignored = parser.GetUnsuitableSectionOnlyArgs();
890 [ + + ]: 47488 : if (!ignored.empty()) {
891 [ + - ]: 1752 : desc += " | ignored";
892 [ + + ]: 3504 : for (const auto& arg : ignored) {
893 [ + - ]: 1752 : desc += " ";
894 [ + - ]: 3504 : desc += arg;
895 : : }
896 : : }
897 : :
898 [ + - ]: 47488 : desc += "\n";
899 : :
900 [ + - ]: 47488 : out_sha.Write(MakeUCharSpan(desc));
901 [ - + ]: 47488 : if (out_file) {
902 [ # # # # : 0 : BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
# # ]
903 : : }
904 [ + - ]: 94976 : });
905 : :
906 [ - + ]: 1 : if (out_file) {
907 [ # # # # ]: 0 : if (fclose(out_file)) throw std::system_error(errno, std::generic_category(), "fclose failed");
908 : 0 : out_file = nullptr;
909 : : }
910 : :
911 : 1 : unsigned char out_sha_bytes[CSHA256::OUTPUT_SIZE];
912 : 1 : out_sha.Finalize(out_sha_bytes);
913 : 1 : std::string out_sha_hex = HexStr(out_sha_bytes);
914 : :
915 : : // If check below fails, should manually dump the results with:
916 : : //
917 : : // ARGS_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=argsman_tests/util_ArgsMerge
918 : : //
919 : : // And verify diff against previous results to make sure the changes are expected.
920 : : //
921 : : // Results file is formatted like:
922 : : //
923 : : // <input> || <IsArgSet/IsArgNegated/GetArg output> | <GetArgs output> | <GetUnsuitable output>
924 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(out_sha_hex, "f1ee5ab094cc43d16a6086fa7f2c10389e0f99902616b31bbf29189972ad1473");
925 : 1 : }
926 : :
927 : : // Similar test as above, but for ArgsManager::GetChainTypeString function.
928 : 2 : struct ChainMergeTestingSetup : public BasicTestingSetup {
929 : : static constexpr int MAX_ACTIONS = 2;
930 : :
931 : : enum Action { NONE, ENABLE_TEST, DISABLE_TEST, NEGATE_TEST, ENABLE_REG, DISABLE_REG, NEGATE_REG };
932 : : using ActionList = Action[MAX_ACTIONS];
933 : :
934 : : //! Enumerate all possible test configurations.
935 : : template <typename Fn>
936 : 1 : void ForEachMergeSetup(Fn&& fn)
937 : : {
938 : 1 : ActionList arg_actions = {};
939 : 1 : ForEachNoDup(arg_actions, ENABLE_TEST, NEGATE_REG, [&] {
940 : 37 : ActionList conf_actions = {};
941 : 1406 : ForEachNoDup(conf_actions, ENABLE_TEST, NEGATE_REG, [&] { fn(arg_actions, conf_actions); });
942 : : });
943 : 1 : }
944 : : };
945 : :
946 [ + - + - : 7 : BOOST_FIXTURE_TEST_CASE(util_ChainMerge, ChainMergeTestingSetup)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
947 : : {
948 : 1 : CHash256 out_sha;
949 : 1 : FILE* out_file = nullptr;
950 [ - + ]: 1 : if (const char* out_path = getenv("CHAIN_MERGE_TEST_OUT")) {
951 [ # # ]: 0 : out_file = fsbridge::fopen(out_path, "w");
952 [ # # # # ]: 0 : if (!out_file) throw std::system_error(errno, std::generic_category(), "fopen failed");
953 : : }
954 : :
955 : 1370 : ForEachMergeSetup([&](const ActionList& arg_actions, const ActionList& conf_actions) {
956 : 1369 : TestArgsManager parser;
957 [ + - ]: 1369 : LOCK(parser.cs_args);
958 [ + - + - : 2738 : parser.AddArg("-regtest", "regtest", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ - ]
959 [ + - + - : 2738 : parser.AddArg("-testnet", "testnet", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ - ]
960 : :
961 [ + + + + : 5402 : auto arg = [](Action action) { return action == ENABLE_TEST ? "-testnet=1" :
+ + + ]
962 : : action == DISABLE_TEST ? "-testnet=0" :
963 : : action == NEGATE_TEST ? "-notestnet=1" :
964 : : action == ENABLE_REG ? "-regtest=1" :
965 : : action == DISABLE_REG ? "-regtest=0" :
966 : 5402 : action == NEGATE_REG ? "-noregtest=1" : nullptr; };
967 : :
968 [ + - ]: 1369 : std::string desc;
969 [ + - ]: 1369 : std::vector<const char*> argv = {"ignored"};
970 [ + + ]: 3811 : for (Action action : arg_actions) {
971 : 2701 : const char* argstr = arg(action);
972 [ + + ]: 2701 : if (!argstr) break;
973 [ + - ]: 2442 : argv.push_back(argstr);
974 [ + - ]: 2442 : desc += " ";
975 [ + - ]: 2442 : desc += argv.back();
976 : : }
977 [ + - ]: 1369 : std::string error;
978 [ + - + - : 2738 : BOOST_CHECK(parser.ParseParameters(argv.size(), argv.data(), error));
+ - + - ]
979 [ + - + - ]: 1369 : BOOST_CHECK_EQUAL(error, "");
980 : :
981 : 1369 : std::string conf;
982 [ + + ]: 3811 : for (Action action : conf_actions) {
983 : 2701 : const char* argstr = arg(action);
984 [ + + ]: 2701 : if (!argstr) break;
985 [ + - ]: 2442 : desc += " ";
986 [ + - ]: 2442 : desc += argstr + 1;
987 [ + - ]: 2442 : conf += argstr + 1;
988 [ + - ]: 2442 : conf += "\n";
989 : : }
990 [ + - ]: 1369 : std::istringstream conf_stream(conf);
991 [ + - + - : 2738 : BOOST_CHECK(parser.ReadConfigStream(conf_stream, "filepath", error));
+ - + - +
- ]
992 [ + - + - ]: 1369 : BOOST_CHECK_EQUAL(error, "");
993 : :
994 [ + - ]: 1369 : desc += " || ";
995 : 1369 : try {
996 [ + + ]: 2556 : desc += parser.GetChainTypeString();
997 [ - + ]: 182 : } catch (const std::runtime_error& e) {
998 [ + - ]: 182 : desc += "error: ";
999 [ + - ]: 182 : desc += e.what();
1000 : 182 : }
1001 [ + - ]: 1369 : desc += "\n";
1002 : :
1003 [ + - ]: 1369 : out_sha.Write(MakeUCharSpan(desc));
1004 [ - + ]: 1369 : if (out_file) {
1005 [ # # # # : 0 : BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
# # ]
1006 : : }
1007 [ + - ]: 2738 : });
1008 : :
1009 [ - + ]: 1 : if (out_file) {
1010 [ # # # # ]: 0 : if (fclose(out_file)) throw std::system_error(errno, std::generic_category(), "fclose failed");
1011 : 0 : out_file = nullptr;
1012 : : }
1013 : :
1014 : 1 : unsigned char out_sha_bytes[CSHA256::OUTPUT_SIZE];
1015 : 1 : out_sha.Finalize(out_sha_bytes);
1016 : 1 : std::string out_sha_hex = HexStr(out_sha_bytes);
1017 : :
1018 : : // If check below fails, should manually dump the results with:
1019 : : //
1020 : : // CHAIN_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=argsman_tests/util_ChainMerge
1021 : : //
1022 : : // And verify diff against previous results to make sure the changes are expected.
1023 : : //
1024 : : // Results file is formatted like:
1025 : : //
1026 : : // <input> || <output>
1027 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(out_sha_hex, "9e60306e1363528bbc19a47f22bcede88e5d6815212f18ec8e6cdc4638dddab4");
1028 : 1 : }
1029 : :
1030 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(util_ReadWriteSettings)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
1031 : : {
1032 : : // Test writing setting.
1033 : 1 : TestArgsManager args1;
1034 [ + - + - : 3 : args1.ForceSetArg("-datadir", fs::PathToString(m_path_root));
+ - ]
1035 [ + - + - ]: 2 : args1.LockSettings([&](common::Settings& settings) { settings.rw_settings["name"] = "value"; });
1036 [ + - ]: 1 : args1.WriteSettingsFile();
1037 : :
1038 : : // Test reading setting.
1039 [ + - ]: 1 : TestArgsManager args2;
1040 [ + - + - : 3 : args2.ForceSetArg("-datadir", fs::PathToString(m_path_root));
+ - ]
1041 [ + - ]: 1 : args2.ReadSettingsFile();
1042 [ + - + - : 2 : args2.LockSettings([&](common::Settings& settings) { BOOST_CHECK_EQUAL(settings.rw_settings["name"].get_str(), "value"); });
+ - ]
1043 : :
1044 : : // Test error logging, and remove previously written setting.
1045 : 1 : {
1046 [ + - + - ]: 2 : ASSERT_DEBUG_LOG("Failed renaming settings file");
1047 [ + - + - : 3 : fs::remove(args1.GetDataDirBase() / "settings.json");
+ - ]
1048 [ + - + - : 3 : fs::create_directory(args1.GetDataDirBase() / "settings.json");
+ - ]
1049 [ + - ]: 1 : args2.WriteSettingsFile();
1050 [ + - + - : 3 : fs::remove(args1.GetDataDirBase() / "settings.json");
+ - ]
1051 : 1 : }
1052 : 1 : }
1053 : :
1054 : : BOOST_AUTO_TEST_SUITE_END()
|