Bitcoin Core 22.99.0
P2P Digital Currency
util_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2020 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 <util/system.h>
6
7#include <clientversion.h>
8#include <hash.h> // For Hash()
9#include <key.h> // For CKey
10#include <sync.h>
11#include <test/util/logging.h>
13#include <test/util/str.h>
14#include <uint256.h>
15#include <util/getuniquepath.h>
16#include <util/message.h> // For MessageSign(), MessageVerify(), MESSAGE_MAGIC
17#include <util/moneystr.h>
18#include <util/spanparsing.h>
19#include <util/strencodings.h>
20#include <util/string.h>
21#include <util/time.h>
22#include <util/vector.h>
23
24#include <array>
25#include <optional>
26#include <stdint.h>
27#include <string.h>
28#include <thread>
29#include <univalue.h>
30#include <utility>
31#include <vector>
32#ifndef WIN32
33#include <signal.h>
34#include <sys/types.h>
35#include <sys/wait.h>
36#endif
37
38#include <boost/test/unit_test.hpp>
39
40using namespace std::literals;
41static const std::string STRING_WITH_EMBEDDED_NULL_CHAR{"1"s "\0" "1"s};
42
43/* defined in logging.cpp */
44namespace BCLog {
45 std::string LogEscapeMessage(const std::string& str);
46}
47
49
51{
52 // Use local args variable instead of m_args to avoid making assumptions about test setup
53 ArgsManager args;
54 args.ForceSetArg("-datadir", fs::PathToString(m_path_root));
55
56 const fs::path dd_norm = args.GetDataDirBase();
57
58 args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/");
59 args.ClearPathCache();
60 BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
61
62 args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.");
63 args.ClearPathCache();
64 BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
65
66 args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/./");
67 args.ClearPathCache();
68 BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
69
70 args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.//");
71 args.ClearPathCache();
72 BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
73}
74
76{
77 // Check that Assert can forward
78 const std::unique_ptr<int> p_two = Assert(std::make_unique<int>(2));
79 // Check that Assert works on lvalues and rvalues
80 const int two = *Assert(p_two);
81 Assert(two == 2);
82 Assert(true);
83 // Check that Assume can be used as unary expression
84 const bool result{Assume(two == 2)};
85 Assert(result);
86}
87
88BOOST_AUTO_TEST_CASE(util_criticalsection)
89{
91
92 do {
93 LOCK(cs);
94 break;
95
96 BOOST_ERROR("break was swallowed!");
97 } while(0);
98
99 do {
100 TRY_LOCK(cs, lockTest);
101 if (lockTest) {
102 BOOST_CHECK(true); // Needed to suppress "Test case [...] did not check any assertions"
103 break;
104 }
105
106 BOOST_ERROR("break was swallowed!");
107 } while(0);
108}
109
110static const unsigned char ParseHex_expected[65] = {
111 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
112 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
113 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12,
114 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
115 0x5f
116};
118{
119 std::vector<unsigned char> result;
120 std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
121 // Basic test vector
122 result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
123 BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
124
125 // Spaces between bytes must be supported
126 result = ParseHex("12 34 56 78");
127 BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
128
129 // Leading space must be supported (used in BerkeleyEnvironment::Salvage)
130 result = ParseHex(" 89 34 56 78");
131 BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
132
133 // Stop parsing at invalid value
134 result = ParseHex("1234 invalid 1234");
135 BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34);
136}
137
139{
142 "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
143
148 "");
149
152 "");
153
154 std::vector<unsigned char> ParseHex_vec(ParseHex_expected, ParseHex_expected + 5);
155
157 HexStr(ParseHex_vec),
158 "04678afdb0"
159 );
160}
161
163{
164 // Normal version
165 BOOST_CHECK_EQUAL(Join({}, ", "), "");
166 BOOST_CHECK_EQUAL(Join({"foo"}, ", "), "foo");
167 BOOST_CHECK_EQUAL(Join({"foo", "bar"}, ", "), "foo, bar");
168
169 // Version with unary operator
170 const auto op_upper = [](const std::string& s) { return ToUpper(s); };
171 BOOST_CHECK_EQUAL(Join<std::string>({}, ", ", op_upper), "");
172 BOOST_CHECK_EQUAL(Join<std::string>({"foo"}, ", ", op_upper), "FOO");
173 BOOST_CHECK_EQUAL(Join<std::string>({"foo", "bar"}, ", ", op_upper), "FOO, BAR");
174}
175
176BOOST_AUTO_TEST_CASE(util_TrimString)
177{
178 BOOST_CHECK_EQUAL(TrimString(" foo bar "), "foo bar");
179 BOOST_CHECK_EQUAL(TrimString("\t \n \n \f\n\r\t\v\tfoo \n \f\n\r\t\v\tbar\t \n \f\n\r\t\v\t\n "), "foo \n \f\n\r\t\v\tbar");
180 BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n "), "foo \n\tbar");
181 BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n ", "fobar"), "\t \n foo \n\tbar\t \n ");
182 BOOST_CHECK_EQUAL(TrimString("foo bar"), "foo bar");
183 BOOST_CHECK_EQUAL(TrimString("foo bar", "fobar"), " ");
184 BOOST_CHECK_EQUAL(TrimString(std::string("\0 foo \0 ", 8)), std::string("\0 foo \0", 7));
185 BOOST_CHECK_EQUAL(TrimString(std::string(" foo ", 5)), std::string("foo", 3));
186 BOOST_CHECK_EQUAL(TrimString(std::string("\t\t\0\0\n\n", 6)), std::string("\0\0", 2));
187 BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6)), std::string("\x05\x04\x03\x02\x01\x00", 6));
188 BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01", 5)), std::string("\0", 1));
189 BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01\x00", 6)), "");
190}
191
192BOOST_AUTO_TEST_CASE(util_FormatParseISO8601DateTime)
193{
194 BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z");
195 BOOST_CHECK_EQUAL(FormatISO8601DateTime(0), "1970-01-01T00:00:00Z");
196
197 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:00Z"), 0);
198 BOOST_CHECK_EQUAL(ParseISO8601DateTime("1960-01-01T00:00:00Z"), 0);
199 BOOST_CHECK_EQUAL(ParseISO8601DateTime("2011-09-30T23:36:17Z"), 1317425777);
200
201 auto time = GetTimeSeconds();
203}
204
205BOOST_AUTO_TEST_CASE(util_FormatISO8601Date)
206{
207 BOOST_CHECK_EQUAL(FormatISO8601Date(1317425777), "2011-09-30");
208}
209
211{
212 TestArgsManager() { m_network_only_args.clear(); }
213 void ReadConfigString(const std::string str_config)
214 {
215 std::istringstream streamConfig(str_config);
216 {
217 LOCK(cs_args);
218 m_settings.ro_config.clear();
219 m_config_sections.clear();
220 }
221 std::string error;
222 BOOST_REQUIRE(ReadConfigStream(streamConfig, "", error));
223 }
224 void SetNetworkOnlyArg(const std::string arg)
225 {
226 LOCK(cs_args);
227 m_network_only_args.insert(arg);
228 }
229 void SetupArgs(const std::vector<std::pair<std::string, unsigned int>>& args)
230 {
231 for (const auto& arg : args) {
232 AddArg(arg.first, "", arg.second, OptionsCategory::OPTIONS);
233 }
234 }
239 using ArgsManager::m_network;
240 using ArgsManager::m_settings;
241};
242
245{
246public:
247 struct Expect {
249 bool default_string = false;
250 bool default_int = false;
251 bool default_bool = false;
252 const char* string_value = nullptr;
253 std::optional<int64_t> int_value;
254 std::optional<bool> bool_value;
255 std::optional<std::vector<std::string>> list_value;
256 const char* error = nullptr;
257
258 explicit Expect(util::SettingsValue s) : setting(std::move(s)) {}
259 Expect& DefaultString() { default_string = true; return *this; }
260 Expect& DefaultInt() { default_int = true; return *this; }
261 Expect& DefaultBool() { default_bool = true; return *this; }
262 Expect& String(const char* s) { string_value = s; return *this; }
263 Expect& Int(int64_t i) { int_value = i; return *this; }
264 Expect& Bool(bool b) { bool_value = b; return *this; }
265 Expect& List(std::vector<std::string> m) { list_value = std::move(m); return *this; }
266 Expect& Error(const char* e) { error = e; return *this; }
267 };
268
269 void CheckValue(unsigned int flags, const char* arg, const Expect& expect)
270 {
271 TestArgsManager test;
272 test.SetupArgs({{"-value", flags}});
273 const char* argv[] = {"ignored", arg};
274 std::string error;
275 bool success = test.ParseParameters(arg ? 2 : 1, (char**)argv, error);
276
277 BOOST_CHECK_EQUAL(test.GetSetting("-value").write(), expect.setting.write());
278 auto settings_list = test.GetSettingsList("-value");
279 if (expect.setting.isNull() || expect.setting.isFalse()) {
280 BOOST_CHECK_EQUAL(settings_list.size(), 0U);
281 } else {
282 BOOST_CHECK_EQUAL(settings_list.size(), 1U);
283 BOOST_CHECK_EQUAL(settings_list[0].write(), expect.setting.write());
284 }
285
286 if (expect.error) {
287 BOOST_CHECK(!success);
288 BOOST_CHECK_NE(error.find(expect.error), std::string::npos);
289 } else {
290 BOOST_CHECK(success);
292 }
293
294 if (expect.default_string) {
295 BOOST_CHECK_EQUAL(test.GetArg("-value", "zzzzz"), "zzzzz");
296 } else if (expect.string_value) {
297 BOOST_CHECK_EQUAL(test.GetArg("-value", "zzzzz"), expect.string_value);
298 } else {
299 BOOST_CHECK(!success);
300 }
301
302 if (expect.default_int) {
303 BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), 99999);
304 } else if (expect.int_value) {
305 BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), *expect.int_value);
306 } else {
307 BOOST_CHECK(!success);
308 }
309
310 if (expect.default_bool) {
311 BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), false);
312 BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), true);
313 } else if (expect.bool_value) {
314 BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), *expect.bool_value);
315 BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), *expect.bool_value);
316 } else {
317 BOOST_CHECK(!success);
318 }
319
320 if (expect.list_value) {
321 auto l = test.GetArgs("-value");
322 BOOST_CHECK_EQUAL_COLLECTIONS(l.begin(), l.end(), expect.list_value->begin(), expect.list_value->end());
323 } else {
324 BOOST_CHECK(!success);
325 }
326 }
327};
328
330{
331 using M = ArgsManager;
332
333 CheckValue(M::ALLOW_ANY, nullptr, Expect{{}}.DefaultString().DefaultInt().DefaultBool().List({}));
334 CheckValue(M::ALLOW_ANY, "-novalue", Expect{false}.String("0").Int(0).Bool(false).List({}));
335 CheckValue(M::ALLOW_ANY, "-novalue=", Expect{false}.String("0").Int(0).Bool(false).List({}));
336 CheckValue(M::ALLOW_ANY, "-novalue=0", Expect{true}.String("1").Int(1).Bool(true).List({"1"}));
337 CheckValue(M::ALLOW_ANY, "-novalue=1", Expect{false}.String("0").Int(0).Bool(false).List({}));
338 CheckValue(M::ALLOW_ANY, "-novalue=2", Expect{false}.String("0").Int(0).Bool(false).List({}));
339 CheckValue(M::ALLOW_ANY, "-novalue=abc", Expect{true}.String("1").Int(1).Bool(true).List({"1"}));
340 CheckValue(M::ALLOW_ANY, "-value", Expect{""}.String("").Int(0).Bool(true).List({""}));
341 CheckValue(M::ALLOW_ANY, "-value=", Expect{""}.String("").Int(0).Bool(true).List({""}));
342 CheckValue(M::ALLOW_ANY, "-value=0", Expect{"0"}.String("0").Int(0).Bool(false).List({"0"}));
343 CheckValue(M::ALLOW_ANY, "-value=1", Expect{"1"}.String("1").Int(1).Bool(true).List({"1"}));
344 CheckValue(M::ALLOW_ANY, "-value=2", Expect{"2"}.String("2").Int(2).Bool(true).List({"2"}));
345 CheckValue(M::ALLOW_ANY, "-value=abc", Expect{"abc"}.String("abc").Int(0).Bool(false).List({"abc"}));
346}
347
349 std::string Parse(const char* arg)
350 {
351 TestArgsManager test;
352 test.SetupArgs({{"-includeconf", ArgsManager::ALLOW_ANY}});
353 std::array argv{"ignored", arg};
354 std::string error;
355 (void)test.ParseParameters(argv.size(), argv.data(), error);
356 return error;
357 }
358};
359
361{
362 BOOST_CHECK_EQUAL(Parse("-noincludeconf"), "");
363 BOOST_CHECK_EQUAL(Parse("-includeconf"), "-includeconf cannot be used from commandline; -includeconf=\"\"");
364 BOOST_CHECK_EQUAL(Parse("-includeconf=file"), "-includeconf cannot be used from commandline; -includeconf=\"file\"");
365}
366
367BOOST_AUTO_TEST_CASE(util_ParseParameters)
368{
369 TestArgsManager testArgs;
370 const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);
371 const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);
372 const auto ccc = std::make_pair("-ccc", ArgsManager::ALLOW_ANY);
373 const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);
374
375 const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"};
376
377 std::string error;
378 LOCK(testArgs.cs_args);
379 testArgs.SetupArgs({a, b, ccc, d});
380 BOOST_CHECK(testArgs.ParseParameters(0, (char**)argv_test, error));
381 BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
382
383 BOOST_CHECK(testArgs.ParseParameters(1, (char**)argv_test, error));
384 BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
385
386 BOOST_CHECK(testArgs.ParseParameters(7, (char**)argv_test, error));
387 // expectation: -ignored is ignored (program name argument),
388 // -a, -b and -ccc end up in map, -d ignored because it is after
389 // a non-option argument (non-GNU option parsing)
390 BOOST_CHECK(testArgs.m_settings.command_line_options.size() == 3 && testArgs.m_settings.ro_config.empty());
391 BOOST_CHECK(testArgs.IsArgSet("-a") && testArgs.IsArgSet("-b") && testArgs.IsArgSet("-ccc")
392 && !testArgs.IsArgSet("f") && !testArgs.IsArgSet("-d"));
393 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")
394 && !testArgs.m_settings.command_line_options.count("f") && !testArgs.m_settings.command_line_options.count("d"));
395
396 BOOST_CHECK(testArgs.m_settings.command_line_options["a"].size() == 1);
397 BOOST_CHECK(testArgs.m_settings.command_line_options["a"].front().get_str() == "");
398 BOOST_CHECK(testArgs.m_settings.command_line_options["ccc"].size() == 2);
399 BOOST_CHECK(testArgs.m_settings.command_line_options["ccc"].front().get_str() == "argument");
400 BOOST_CHECK(testArgs.m_settings.command_line_options["ccc"].back().get_str() == "multiple");
401 BOOST_CHECK(testArgs.GetArgs("-ccc").size() == 2);
402}
403
404BOOST_AUTO_TEST_CASE(util_ParseInvalidParameters)
405{
406 TestArgsManager test;
407 test.SetupArgs({{"-registered", ArgsManager::ALLOW_ANY}});
408
409 const char* argv[] = {"ignored", "-registered"};
410 std::string error;
411 BOOST_CHECK(test.ParseParameters(2, (char**)argv, error));
413
414 argv[1] = "-unregistered";
415 BOOST_CHECK(!test.ParseParameters(2, (char**)argv, error));
416 BOOST_CHECK_EQUAL(error, "Invalid parameter -unregistered");
417
418 // Make sure registered parameters prefixed with a chain name trigger errors.
419 // (Previously, they were accepted and ignored.)
420 argv[1] = "-test.registered";
421 BOOST_CHECK(!test.ParseParameters(2, (char**)argv, error));
422 BOOST_CHECK_EQUAL(error, "Invalid parameter -test.registered");
423}
424
425static void TestParse(const std::string& str, bool expected_bool, int64_t expected_int)
426{
427 TestArgsManager test;
428 test.SetupArgs({{"-value", ArgsManager::ALLOW_ANY}});
429 std::string arg = "-value=" + str;
430 const char* argv[] = {"ignored", arg.c_str()};
431 std::string error;
432 BOOST_CHECK(test.ParseParameters(2, (char**)argv, error));
433 BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), expected_bool);
434 BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), expected_bool);
435 BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99998), expected_int);
436 BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), expected_int);
437}
438
439// Test bool and int parsing.
440BOOST_AUTO_TEST_CASE(util_ArgParsing)
441{
442 // Some of these cases could be ambiguous or surprising to users, and might
443 // be worth triggering errors or warnings in the future. But for now basic
444 // test coverage is useful to avoid breaking backwards compatibility
445 // unintentionally.
446 TestParse("", true, 0);
447 TestParse(" ", false, 0);
448 TestParse("0", false, 0);
449 TestParse("0 ", false, 0);
450 TestParse(" 0", false, 0);
451 TestParse("+0", false, 0);
452 TestParse("-0", false, 0);
453 TestParse("5", true, 5);
454 TestParse("5 ", true, 5);
455 TestParse(" 5", true, 5);
456 TestParse("+5", true, 5);
457 TestParse("-5", true, -5);
458 TestParse("0 5", false, 0);
459 TestParse("5 0", true, 5);
460 TestParse("050", true, 50);
461 TestParse("0.", false, 0);
462 TestParse("5.", true, 5);
463 TestParse("0.0", false, 0);
464 TestParse("0.5", false, 0);
465 TestParse("5.0", true, 5);
466 TestParse("5.5", true, 5);
467 TestParse("x", false, 0);
468 TestParse("x0", false, 0);
469 TestParse("x5", false, 0);
470 TestParse("0x", false, 0);
471 TestParse("5x", true, 5);
472 TestParse("0x5", false, 0);
473 TestParse("false", false, 0);
474 TestParse("true", false, 0);
475 TestParse("yes", false, 0);
476 TestParse("no", false, 0);
477}
478
479BOOST_AUTO_TEST_CASE(util_GetBoolArg)
480{
481 TestArgsManager testArgs;
482 const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);
483 const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);
484 const auto c = std::make_pair("-c", ArgsManager::ALLOW_ANY);
485 const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);
486 const auto e = std::make_pair("-e", ArgsManager::ALLOW_ANY);
487 const auto f = std::make_pair("-f", ArgsManager::ALLOW_ANY);
488
489 const char *argv_test[] = {
490 "ignored", "-a", "-nob", "-c=0", "-d=1", "-e=false", "-f=true"};
491 std::string error;
492 LOCK(testArgs.cs_args);
493 testArgs.SetupArgs({a, b, c, d, e, f});
494 BOOST_CHECK(testArgs.ParseParameters(7, (char**)argv_test, error));
495
496 // Each letter should be set.
497 for (const char opt : "abcdef")
498 BOOST_CHECK(testArgs.IsArgSet({'-', opt}) || !opt);
499
500 // Nothing else should be in the map
501 BOOST_CHECK(testArgs.m_settings.command_line_options.size() == 6 &&
502 testArgs.m_settings.ro_config.empty());
503
504 // The -no prefix should get stripped on the way in.
505 BOOST_CHECK(!testArgs.IsArgSet("-nob"));
506
507 // The -b option is flagged as negated, and nothing else is
508 BOOST_CHECK(testArgs.IsArgNegated("-b"));
509 BOOST_CHECK(!testArgs.IsArgNegated("-a"));
510
511 // Check expected values.
512 BOOST_CHECK(testArgs.GetBoolArg("-a", false) == true);
513 BOOST_CHECK(testArgs.GetBoolArg("-b", true) == false);
514 BOOST_CHECK(testArgs.GetBoolArg("-c", true) == false);
515 BOOST_CHECK(testArgs.GetBoolArg("-d", false) == true);
516 BOOST_CHECK(testArgs.GetBoolArg("-e", true) == false);
517 BOOST_CHECK(testArgs.GetBoolArg("-f", true) == false);
518}
519
520BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)
521{
522 // Test some awful edge cases that hopefully no user will ever exercise.
523 TestArgsManager testArgs;
524
525 // Params test
526 const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY);
527 const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY);
528 const char *argv_test[] = {"ignored", "-nofoo", "-foo", "-nobar=0"};
529 testArgs.SetupArgs({foo, bar});
530 std::string error;
531 BOOST_CHECK(testArgs.ParseParameters(4, (char**)argv_test, error));
532
533 // This was passed twice, second one overrides the negative setting.
534 BOOST_CHECK(!testArgs.IsArgNegated("-foo"));
535 BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "");
536
537 // A double negative is a positive, and not marked as negated.
538 BOOST_CHECK(!testArgs.IsArgNegated("-bar"));
539 BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "1");
540
541 // Config test
542 const char *conf_test = "nofoo=1\nfoo=1\nnobar=0\n";
543 BOOST_CHECK(testArgs.ParseParameters(1, (char**)argv_test, error));
544 testArgs.ReadConfigString(conf_test);
545
546 // This was passed twice, second one overrides the negative setting,
547 // and the value.
548 BOOST_CHECK(!testArgs.IsArgNegated("-foo"));
549 BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "1");
550
551 // A double negative is a positive, and does not count as negated.
552 BOOST_CHECK(!testArgs.IsArgNegated("-bar"));
553 BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "1");
554
555 // Combined test
556 const char *combo_test_args[] = {"ignored", "-nofoo", "-bar"};
557 const char *combo_test_conf = "foo=1\nnobar=1\n";
558 BOOST_CHECK(testArgs.ParseParameters(3, (char**)combo_test_args, error));
559 testArgs.ReadConfigString(combo_test_conf);
560
561 // Command line overrides, but doesn't erase old setting
562 BOOST_CHECK(testArgs.IsArgNegated("-foo"));
563 BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "0");
564 BOOST_CHECK(testArgs.GetArgs("-foo").size() == 0);
565
566 // Command line overrides, but doesn't erase old setting
567 BOOST_CHECK(!testArgs.IsArgNegated("-bar"));
568 BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "");
569 BOOST_CHECK(testArgs.GetArgs("-bar").size() == 1
570 && testArgs.GetArgs("-bar").front() == "");
571}
572
573BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
574{
575 const char *str_config =
576 "a=\n"
577 "b=1\n"
578 "ccc=argument\n"
579 "ccc=multiple\n"
580 "d=e\n"
581 "nofff=1\n"
582 "noggg=0\n"
583 "h=1\n"
584 "noh=1\n"
585 "noi=1\n"
586 "i=1\n"
587 "sec1.ccc=extend1\n"
588 "\n"
589 "[sec1]\n"
590 "ccc=extend2\n"
591 "d=eee\n"
592 "h=1\n"
593 "[sec2]\n"
594 "ccc=extend3\n"
595 "iii=2\n";
596
597 TestArgsManager test_args;
598 LOCK(test_args.cs_args);
599 const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);
600 const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);
601 const auto ccc = std::make_pair("-ccc", ArgsManager::ALLOW_ANY);
602 const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);
603 const auto e = std::make_pair("-e", ArgsManager::ALLOW_ANY);
604 const auto fff = std::make_pair("-fff", ArgsManager::ALLOW_ANY);
605 const auto ggg = std::make_pair("-ggg", ArgsManager::ALLOW_ANY);
606 const auto h = std::make_pair("-h", ArgsManager::ALLOW_ANY);
607 const auto i = std::make_pair("-i", ArgsManager::ALLOW_ANY);
608 const auto iii = std::make_pair("-iii", ArgsManager::ALLOW_ANY);
609 test_args.SetupArgs({a, b, ccc, d, e, fff, ggg, h, i, iii});
610
611 test_args.ReadConfigString(str_config);
612 // expectation: a, b, ccc, d, fff, ggg, h, i end up in map
613 // so do sec1.ccc, sec1.d, sec1.h, sec2.ccc, sec2.iii
614
615 BOOST_CHECK(test_args.m_settings.command_line_options.empty());
616 BOOST_CHECK(test_args.m_settings.ro_config.size() == 3);
617 BOOST_CHECK(test_args.m_settings.ro_config[""].size() == 8);
618 BOOST_CHECK(test_args.m_settings.ro_config["sec1"].size() == 3);
619 BOOST_CHECK(test_args.m_settings.ro_config["sec2"].size() == 2);
620
621 BOOST_CHECK(test_args.m_settings.ro_config[""].count("a"));
622 BOOST_CHECK(test_args.m_settings.ro_config[""].count("b"));
623 BOOST_CHECK(test_args.m_settings.ro_config[""].count("ccc"));
624 BOOST_CHECK(test_args.m_settings.ro_config[""].count("d"));
625 BOOST_CHECK(test_args.m_settings.ro_config[""].count("fff"));
626 BOOST_CHECK(test_args.m_settings.ro_config[""].count("ggg"));
627 BOOST_CHECK(test_args.m_settings.ro_config[""].count("h"));
628 BOOST_CHECK(test_args.m_settings.ro_config[""].count("i"));
629 BOOST_CHECK(test_args.m_settings.ro_config["sec1"].count("ccc"));
630 BOOST_CHECK(test_args.m_settings.ro_config["sec1"].count("h"));
631 BOOST_CHECK(test_args.m_settings.ro_config["sec2"].count("ccc"));
632 BOOST_CHECK(test_args.m_settings.ro_config["sec2"].count("iii"));
633
634 BOOST_CHECK(test_args.IsArgSet("-a"));
635 BOOST_CHECK(test_args.IsArgSet("-b"));
636 BOOST_CHECK(test_args.IsArgSet("-ccc"));
637 BOOST_CHECK(test_args.IsArgSet("-d"));
638 BOOST_CHECK(test_args.IsArgSet("-fff"));
639 BOOST_CHECK(test_args.IsArgSet("-ggg"));
640 BOOST_CHECK(test_args.IsArgSet("-h"));
641 BOOST_CHECK(test_args.IsArgSet("-i"));
642 BOOST_CHECK(!test_args.IsArgSet("-zzz"));
643 BOOST_CHECK(!test_args.IsArgSet("-iii"));
644
645 BOOST_CHECK_EQUAL(test_args.GetArg("-a", "xxx"), "");
646 BOOST_CHECK_EQUAL(test_args.GetArg("-b", "xxx"), "1");
647 BOOST_CHECK_EQUAL(test_args.GetArg("-ccc", "xxx"), "argument");
648 BOOST_CHECK_EQUAL(test_args.GetArg("-d", "xxx"), "e");
649 BOOST_CHECK_EQUAL(test_args.GetArg("-fff", "xxx"), "0");
650 BOOST_CHECK_EQUAL(test_args.GetArg("-ggg", "xxx"), "1");
651 BOOST_CHECK_EQUAL(test_args.GetArg("-h", "xxx"), "0");
652 BOOST_CHECK_EQUAL(test_args.GetArg("-i", "xxx"), "1");
653 BOOST_CHECK_EQUAL(test_args.GetArg("-zzz", "xxx"), "xxx");
654 BOOST_CHECK_EQUAL(test_args.GetArg("-iii", "xxx"), "xxx");
655
656 for (const bool def : {false, true}) {
657 BOOST_CHECK(test_args.GetBoolArg("-a", def));
658 BOOST_CHECK(test_args.GetBoolArg("-b", def));
659 BOOST_CHECK(!test_args.GetBoolArg("-ccc", def));
660 BOOST_CHECK(!test_args.GetBoolArg("-d", def));
661 BOOST_CHECK(!test_args.GetBoolArg("-fff", def));
662 BOOST_CHECK(test_args.GetBoolArg("-ggg", def));
663 BOOST_CHECK(!test_args.GetBoolArg("-h", def));
664 BOOST_CHECK(test_args.GetBoolArg("-i", def));
665 BOOST_CHECK(test_args.GetBoolArg("-zzz", def) == def);
666 BOOST_CHECK(test_args.GetBoolArg("-iii", def) == def);
667 }
668
669 BOOST_CHECK(test_args.GetArgs("-a").size() == 1
670 && test_args.GetArgs("-a").front() == "");
671 BOOST_CHECK(test_args.GetArgs("-b").size() == 1
672 && test_args.GetArgs("-b").front() == "1");
673 BOOST_CHECK(test_args.GetArgs("-ccc").size() == 2
674 && test_args.GetArgs("-ccc").front() == "argument"
675 && test_args.GetArgs("-ccc").back() == "multiple");
676 BOOST_CHECK(test_args.GetArgs("-fff").size() == 0);
677 BOOST_CHECK(test_args.GetArgs("-nofff").size() == 0);
678 BOOST_CHECK(test_args.GetArgs("-ggg").size() == 1
679 && test_args.GetArgs("-ggg").front() == "1");
680 BOOST_CHECK(test_args.GetArgs("-noggg").size() == 0);
681 BOOST_CHECK(test_args.GetArgs("-h").size() == 0);
682 BOOST_CHECK(test_args.GetArgs("-noh").size() == 0);
683 BOOST_CHECK(test_args.GetArgs("-i").size() == 1
684 && test_args.GetArgs("-i").front() == "1");
685 BOOST_CHECK(test_args.GetArgs("-noi").size() == 0);
686 BOOST_CHECK(test_args.GetArgs("-zzz").size() == 0);
687
688 BOOST_CHECK(!test_args.IsArgNegated("-a"));
689 BOOST_CHECK(!test_args.IsArgNegated("-b"));
690 BOOST_CHECK(!test_args.IsArgNegated("-ccc"));
691 BOOST_CHECK(!test_args.IsArgNegated("-d"));
692 BOOST_CHECK(test_args.IsArgNegated("-fff"));
693 BOOST_CHECK(!test_args.IsArgNegated("-ggg"));
694 BOOST_CHECK(test_args.IsArgNegated("-h")); // last setting takes precedence
695 BOOST_CHECK(!test_args.IsArgNegated("-i")); // last setting takes precedence
696 BOOST_CHECK(!test_args.IsArgNegated("-zzz"));
697
698 // Test sections work
699 test_args.SelectConfigNetwork("sec1");
700
701 // same as original
702 BOOST_CHECK_EQUAL(test_args.GetArg("-a", "xxx"), "");
703 BOOST_CHECK_EQUAL(test_args.GetArg("-b", "xxx"), "1");
704 BOOST_CHECK_EQUAL(test_args.GetArg("-fff", "xxx"), "0");
705 BOOST_CHECK_EQUAL(test_args.GetArg("-ggg", "xxx"), "1");
706 BOOST_CHECK_EQUAL(test_args.GetArg("-zzz", "xxx"), "xxx");
707 BOOST_CHECK_EQUAL(test_args.GetArg("-iii", "xxx"), "xxx");
708 // d is overridden
709 BOOST_CHECK(test_args.GetArg("-d", "xxx") == "eee");
710 // section-specific setting
711 BOOST_CHECK(test_args.GetArg("-h", "xxx") == "1");
712 // section takes priority for multiple values
713 BOOST_CHECK(test_args.GetArg("-ccc", "xxx") == "extend1");
714 // check multiple values works
715 const std::vector<std::string> sec1_ccc_expected = {"extend1","extend2","argument","multiple"};
716 const auto& sec1_ccc_res = test_args.GetArgs("-ccc");
717 BOOST_CHECK_EQUAL_COLLECTIONS(sec1_ccc_res.begin(), sec1_ccc_res.end(), sec1_ccc_expected.begin(), sec1_ccc_expected.end());
718
719 test_args.SelectConfigNetwork("sec2");
720
721 // same as original
722 BOOST_CHECK(test_args.GetArg("-a", "xxx") == "");
723 BOOST_CHECK(test_args.GetArg("-b", "xxx") == "1");
724 BOOST_CHECK(test_args.GetArg("-d", "xxx") == "e");
725 BOOST_CHECK(test_args.GetArg("-fff", "xxx") == "0");
726 BOOST_CHECK(test_args.GetArg("-ggg", "xxx") == "1");
727 BOOST_CHECK(test_args.GetArg("-zzz", "xxx") == "xxx");
728 BOOST_CHECK(test_args.GetArg("-h", "xxx") == "0");
729 // section-specific setting
730 BOOST_CHECK(test_args.GetArg("-iii", "xxx") == "2");
731 // section takes priority for multiple values
732 BOOST_CHECK(test_args.GetArg("-ccc", "xxx") == "extend3");
733 // check multiple values works
734 const std::vector<std::string> sec2_ccc_expected = {"extend3","argument","multiple"};
735 const auto& sec2_ccc_res = test_args.GetArgs("-ccc");
736 BOOST_CHECK_EQUAL_COLLECTIONS(sec2_ccc_res.begin(), sec2_ccc_res.end(), sec2_ccc_expected.begin(), sec2_ccc_expected.end());
737
738 // Test section only options
739
740 test_args.SetNetworkOnlyArg("-d");
741 test_args.SetNetworkOnlyArg("-ccc");
742 test_args.SetNetworkOnlyArg("-h");
743
745 BOOST_CHECK(test_args.GetArg("-d", "xxx") == "e");
746 BOOST_CHECK(test_args.GetArgs("-ccc").size() == 2);
747 BOOST_CHECK(test_args.GetArg("-h", "xxx") == "0");
748
749 test_args.SelectConfigNetwork("sec1");
750 BOOST_CHECK(test_args.GetArg("-d", "xxx") == "eee");
751 BOOST_CHECK(test_args.GetArgs("-d").size() == 1);
752 BOOST_CHECK(test_args.GetArgs("-ccc").size() == 2);
753 BOOST_CHECK(test_args.GetArg("-h", "xxx") == "1");
754
755 test_args.SelectConfigNetwork("sec2");
756 BOOST_CHECK(test_args.GetArg("-d", "xxx") == "xxx");
757 BOOST_CHECK(test_args.GetArgs("-d").size() == 0);
758 BOOST_CHECK(test_args.GetArgs("-ccc").size() == 1);
759 BOOST_CHECK(test_args.GetArg("-h", "xxx") == "0");
760}
761
763{
764 TestArgsManager testArgs;
765 LOCK(testArgs.cs_args);
766 testArgs.m_settings.command_line_options.clear();
767 testArgs.m_settings.command_line_options["strtest1"] = {"string..."};
768 // strtest2 undefined on purpose
769 testArgs.m_settings.command_line_options["inttest1"] = {"12345"};
770 testArgs.m_settings.command_line_options["inttest2"] = {"81985529216486895"};
771 // inttest3 undefined on purpose
772 testArgs.m_settings.command_line_options["booltest1"] = {""};
773 // booltest2 undefined on purpose
774 testArgs.m_settings.command_line_options["booltest3"] = {"0"};
775 testArgs.m_settings.command_line_options["booltest4"] = {"1"};
776
777 // priorities
778 testArgs.m_settings.command_line_options["pritest1"] = {"a", "b"};
779 testArgs.m_settings.ro_config[""]["pritest2"] = {"a", "b"};
780 testArgs.m_settings.command_line_options["pritest3"] = {"a"};
781 testArgs.m_settings.ro_config[""]["pritest3"] = {"b"};
782 testArgs.m_settings.command_line_options["pritest4"] = {"a","b"};
783 testArgs.m_settings.ro_config[""]["pritest4"] = {"c","d"};
784
785 BOOST_CHECK_EQUAL(testArgs.GetArg("strtest1", "default"), "string...");
786 BOOST_CHECK_EQUAL(testArgs.GetArg("strtest2", "default"), "default");
787 BOOST_CHECK_EQUAL(testArgs.GetIntArg("inttest1", -1), 12345);
788 BOOST_CHECK_EQUAL(testArgs.GetIntArg("inttest2", -1), 81985529216486895LL);
789 BOOST_CHECK_EQUAL(testArgs.GetIntArg("inttest3", -1), -1);
790 BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest1", false), true);
791 BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest2", false), false);
792 BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest3", false), false);
793 BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest4", false), true);
794
795 BOOST_CHECK_EQUAL(testArgs.GetArg("pritest1", "default"), "b");
796 BOOST_CHECK_EQUAL(testArgs.GetArg("pritest2", "default"), "a");
797 BOOST_CHECK_EQUAL(testArgs.GetArg("pritest3", "default"), "a");
798 BOOST_CHECK_EQUAL(testArgs.GetArg("pritest4", "default"), "b");
799}
800
801BOOST_AUTO_TEST_CASE(util_GetChainName)
802{
803 TestArgsManager test_args;
804 const auto testnet = std::make_pair("-testnet", ArgsManager::ALLOW_ANY);
805 const auto regtest = std::make_pair("-regtest", ArgsManager::ALLOW_ANY);
806 test_args.SetupArgs({testnet, regtest});
807
808 const char* argv_testnet[] = {"cmd", "-testnet"};
809 const char* argv_regtest[] = {"cmd", "-regtest"};
810 const char* argv_test_no_reg[] = {"cmd", "-testnet", "-noregtest"};
811 const char* argv_both[] = {"cmd", "-testnet", "-regtest"};
812
813 // equivalent to "-testnet"
814 // regtest in testnet section is ignored
815 const char* testnetconf = "testnet=1\nregtest=0\n[test]\nregtest=1";
816 std::string error;
817
818 BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
819 BOOST_CHECK_EQUAL(test_args.GetChainName(), "main");
820
821 BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
822 BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
823
824 BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
825 BOOST_CHECK_EQUAL(test_args.GetChainName(), "regtest");
826
827 BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_test_no_reg, error));
828 BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
829
830 BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
831 BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
832
833 BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
834 test_args.ReadConfigString(testnetconf);
835 BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
836
837 BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
838 test_args.ReadConfigString(testnetconf);
839 BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
840
841 BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
842 test_args.ReadConfigString(testnetconf);
843 BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
844
845 BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_test_no_reg, error));
846 test_args.ReadConfigString(testnetconf);
847 BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
848
849 BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
850 test_args.ReadConfigString(testnetconf);
851 BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
852
853 // check setting the network to test (and thus making
854 // [test] regtest=1 potentially relevant) doesn't break things
855 test_args.SelectConfigNetwork("test");
856
857 BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
858 test_args.ReadConfigString(testnetconf);
859 BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
860
861 BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
862 test_args.ReadConfigString(testnetconf);
863 BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
864
865 BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
866 test_args.ReadConfigString(testnetconf);
867 BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
868
869 BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_test_no_reg, error));
870 test_args.ReadConfigString(testnetconf);
871 BOOST_CHECK_EQUAL(test_args.GetChainName(), "test");
872
873 BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
874 test_args.ReadConfigString(testnetconf);
875 BOOST_CHECK_THROW(test_args.GetChainName(), std::runtime_error);
876}
877
878// Test different ways settings can be merged, and verify results. This test can
879// be used to confirm that updates to settings code don't change behavior
880// unintentionally.
881//
882// The test covers:
883//
884// - Combining different setting actions. Possible actions are: configuring a
885// setting, negating a setting (adding "-no" prefix), and configuring/negating
886// settings in a network section (adding "main." or "test." prefixes).
887//
888// - Combining settings from command line arguments and a config file.
889//
890// - Combining SoftSet and ForceSet calls.
891//
892// - Testing "main" and "test" network values to make sure settings from network
893// sections are applied and to check for mainnet-specific behaviors like
894// inheriting settings from the default section.
895//
896// - Testing network-specific settings like "-wallet", that may be ignored
897// outside a network section, and non-network specific settings like "-server"
898// that aren't sensitive to the network.
899//
903 static constexpr int MAX_ACTIONS = 3;
904
907
909 template <typename Fn>
910 void ForEachMergeSetup(Fn&& fn)
911 {
912 ActionList arg_actions = {};
913 // command_line_options do not have sections. Only iterate over SET and NEGATE
914 ForEachNoDup(arg_actions, SET, NEGATE, [&] {
915 ActionList conf_actions = {};
916 ForEachNoDup(conf_actions, SET, SECTION_NEGATE, [&] {
917 for (bool soft_set : {false, true}) {
918 for (bool force_set : {false, true}) {
919 for (const std::string& section : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET}) {
920 for (const std::string& network : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET}) {
921 for (bool net_specific : {false, true}) {
922 fn(arg_actions, conf_actions, soft_set, force_set, section, network, net_specific);
923 }
924 }
925 }
926 }
927 }
928 });
929 });
930 }
931
933 std::vector<std::string> GetValues(const ActionList& actions,
934 const std::string& section,
935 const std::string& name,
936 const std::string& value_prefix)
937 {
938 std::vector<std::string> values;
939 int suffix = 0;
940 for (Action action : actions) {
941 if (action == NONE) break;
942 std::string prefix;
943 if (action == SECTION_SET || action == SECTION_NEGATE) prefix = section + ".";
944 if (action == SET || action == SECTION_SET) {
945 for (int i = 0; i < 2; ++i) {
946 values.push_back(prefix + name + "=" + value_prefix + ToString(++suffix));
947 }
948 }
949 if (action == NEGATE || action == SECTION_NEGATE) {
950 values.push_back(prefix + "no" + name + "=1");
951 }
952 }
953 return values;
954 }
955};
956
957// Regression test covering different ways config settings can be merged. The
958// test parses and merges settings, representing the results as strings that get
959// compared against an expected hash. To debug, the result strings can be dumped
960// to a file (see comments below).
962{
963 CHash256 out_sha;
964 FILE* out_file = nullptr;
965 if (const char* out_path = getenv("ARGS_MERGE_TEST_OUT")) {
966 out_file = fsbridge::fopen(out_path, "w");
967 if (!out_file) throw std::system_error(errno, std::generic_category(), "fopen failed");
968 }
969
970 ForEachMergeSetup([&](const ActionList& arg_actions, const ActionList& conf_actions, bool soft_set, bool force_set,
971 const std::string& section, const std::string& network, bool net_specific) {
972 TestArgsManager parser;
973 LOCK(parser.cs_args);
974
975 std::string desc = "net=";
976 desc += network;
977 parser.m_network = network;
978
979 const std::string& name = net_specific ? "wallet" : "server";
980 const std::string key = "-" + name;
982 if (net_specific) parser.SetNetworkOnlyArg(key);
983
984 auto args = GetValues(arg_actions, section, name, "a");
985 std::vector<const char*> argv = {"ignored"};
986 for (auto& arg : args) {
987 arg.insert(0, "-");
988 desc += " ";
989 desc += arg;
990 argv.push_back(arg.c_str());
991 }
992 std::string error;
993 BOOST_CHECK(parser.ParseParameters(argv.size(), argv.data(), error));
995
996 std::string conf;
997 for (auto& conf_val : GetValues(conf_actions, section, name, "c")) {
998 desc += " ";
999 desc += conf_val;
1000 conf += conf_val;
1001 conf += "\n";
1002 }
1003 std::istringstream conf_stream(conf);
1004 BOOST_CHECK(parser.ReadConfigStream(conf_stream, "filepath", error));
1006
1007 if (soft_set) {
1008 desc += " soft";
1009 parser.SoftSetArg(key, "soft1");
1010 parser.SoftSetArg(key, "soft2");
1011 }
1012
1013 if (force_set) {
1014 desc += " force";
1015 parser.ForceSetArg(key, "force1");
1016 parser.ForceSetArg(key, "force2");
1017 }
1018
1019 desc += " || ";
1020
1021 if (!parser.IsArgSet(key)) {
1022 desc += "unset";
1023 BOOST_CHECK(!parser.IsArgNegated(key));
1024 BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "default");
1025 BOOST_CHECK(parser.GetArgs(key).empty());
1026 } else if (parser.IsArgNegated(key)) {
1027 desc += "negated";
1028 BOOST_CHECK_EQUAL(parser.GetArg(key, "default"), "0");
1029 BOOST_CHECK(parser.GetArgs(key).empty());
1030 } else {
1031 desc += parser.GetArg(key, "default");
1032 desc += " |";
1033 for (const auto& arg : parser.GetArgs(key)) {
1034 desc += " ";
1035 desc += arg;
1036 }
1037 }
1038
1039 std::set<std::string> ignored = parser.GetUnsuitableSectionOnlyArgs();
1040 if (!ignored.empty()) {
1041 desc += " | ignored";
1042 for (const auto& arg : ignored) {
1043 desc += " ";
1044 desc += arg;
1045 }
1046 }
1047
1048 desc += "\n";
1049
1050 out_sha.Write(MakeUCharSpan(desc));
1051 if (out_file) {
1052 BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
1053 }
1054 });
1055
1056 if (out_file) {
1057 if (fclose(out_file)) throw std::system_error(errno, std::generic_category(), "fclose failed");
1058 out_file = nullptr;
1059 }
1060
1061 unsigned char out_sha_bytes[CSHA256::OUTPUT_SIZE];
1062 out_sha.Finalize(out_sha_bytes);
1063 std::string out_sha_hex = HexStr(out_sha_bytes);
1064
1065 // If check below fails, should manually dump the results with:
1066 //
1067 // ARGS_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=util_tests/util_ArgsMerge
1068 //
1069 // And verify diff against previous results to make sure the changes are expected.
1070 //
1071 // Results file is formatted like:
1072 //
1073 // <input> || <IsArgSet/IsArgNegated/GetArg output> | <GetArgs output> | <GetUnsuitable output>
1074 BOOST_CHECK_EQUAL(out_sha_hex, "d1e436c1cd510d0ec44d5205d4b4e3bee6387d316e0075c58206cb16603f3d82");
1075}
1076
1077// Similar test as above, but for ArgsManager::GetChainName function.
1079 static constexpr int MAX_ACTIONS = 2;
1080
1083
1085 template <typename Fn>
1086 void ForEachMergeSetup(Fn&& fn)
1087 {
1088 ActionList arg_actions = {};
1089 ForEachNoDup(arg_actions, ENABLE_TEST, NEGATE_REG, [&] {
1090 ActionList conf_actions = {};
1091 ForEachNoDup(conf_actions, ENABLE_TEST, NEGATE_REG, [&] { fn(arg_actions, conf_actions); });
1092 });
1093 }
1094};
1095
1097{
1098 CHash256 out_sha;
1099 FILE* out_file = nullptr;
1100 if (const char* out_path = getenv("CHAIN_MERGE_TEST_OUT")) {
1101 out_file = fsbridge::fopen(out_path, "w");
1102 if (!out_file) throw std::system_error(errno, std::generic_category(), "fopen failed");
1103 }
1104
1105 ForEachMergeSetup([&](const ActionList& arg_actions, const ActionList& conf_actions) {
1106 TestArgsManager parser;
1107 LOCK(parser.cs_args);
1108 parser.AddArg("-regtest", "regtest", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
1109 parser.AddArg("-testnet", "testnet", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
1110
1111 auto arg = [](Action action) { return action == ENABLE_TEST ? "-testnet=1" :
1112 action == DISABLE_TEST ? "-testnet=0" :
1113 action == NEGATE_TEST ? "-notestnet=1" :
1114 action == ENABLE_REG ? "-regtest=1" :
1115 action == DISABLE_REG ? "-regtest=0" :
1116 action == NEGATE_REG ? "-noregtest=1" : nullptr; };
1117
1118 std::string desc;
1119 std::vector<const char*> argv = {"ignored"};
1120 for (Action action : arg_actions) {
1121 const char* argstr = arg(action);
1122 if (!argstr) break;
1123 argv.push_back(argstr);
1124 desc += " ";
1125 desc += argv.back();
1126 }
1127 std::string error;
1128 BOOST_CHECK(parser.ParseParameters(argv.size(), argv.data(), error));
1130
1131 std::string conf;
1132 for (Action action : conf_actions) {
1133 const char* argstr = arg(action);
1134 if (!argstr) break;
1135 desc += " ";
1136 desc += argstr + 1;
1137 conf += argstr + 1;
1138 conf += "\n";
1139 }
1140 std::istringstream conf_stream(conf);
1141 BOOST_CHECK(parser.ReadConfigStream(conf_stream, "filepath", error));
1143
1144 desc += " || ";
1145 try {
1146 desc += parser.GetChainName();
1147 } catch (const std::runtime_error& e) {
1148 desc += "error: ";
1149 desc += e.what();
1150 }
1151 desc += "\n";
1152
1153 out_sha.Write(MakeUCharSpan(desc));
1154 if (out_file) {
1155 BOOST_REQUIRE(fwrite(desc.data(), 1, desc.size(), out_file) == desc.size());
1156 }
1157 });
1158
1159 if (out_file) {
1160 if (fclose(out_file)) throw std::system_error(errno, std::generic_category(), "fclose failed");
1161 out_file = nullptr;
1162 }
1163
1164 unsigned char out_sha_bytes[CSHA256::OUTPUT_SIZE];
1165 out_sha.Finalize(out_sha_bytes);
1166 std::string out_sha_hex = HexStr(out_sha_bytes);
1167
1168 // If check below fails, should manually dump the results with:
1169 //
1170 // CHAIN_MERGE_TEST_OUT=results.txt ./test_bitcoin --run_test=util_tests/util_ChainMerge
1171 //
1172 // And verify diff against previous results to make sure the changes are expected.
1173 //
1174 // Results file is formatted like:
1175 //
1176 // <input> || <output>
1177 BOOST_CHECK_EQUAL(out_sha_hex, "f263493e300023b6509963887444c41386f44b63bc30047eb8402e8c1144854c");
1178}
1179
1180BOOST_AUTO_TEST_CASE(util_ReadWriteSettings)
1181{
1182 // Test writing setting.
1183 TestArgsManager args1;
1184 args1.ForceSetArg("-datadir", fs::PathToString(m_path_root));
1185 args1.LockSettings([&](util::Settings& settings) { settings.rw_settings["name"] = "value"; });
1186 args1.WriteSettingsFile();
1187
1188 // Test reading setting.
1189 TestArgsManager args2;
1190 args2.ForceSetArg("-datadir", fs::PathToString(m_path_root));
1191 args2.ReadSettingsFile();
1192 args2.LockSettings([&](util::Settings& settings) { BOOST_CHECK_EQUAL(settings.rw_settings["name"].get_str(), "value"); });
1193
1194 // Test error logging, and remove previously written setting.
1195 {
1196 ASSERT_DEBUG_LOG("Failed renaming settings file");
1197 fs::remove(args1.GetDataDirBase() / "settings.json");
1198 fs::create_directory(args1.GetDataDirBase() / "settings.json");
1199 args2.WriteSettingsFile();
1200 fs::remove(args1.GetDataDirBase() / "settings.json");
1201 }
1202}
1203
1204BOOST_AUTO_TEST_CASE(util_FormatMoney)
1205{
1206 BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
1207 BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789");
1209
1210 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00");
1211 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00");
1212 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00");
1213 BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00");
1214 BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00");
1215 BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00");
1216 BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00");
1217 BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00");
1219 BOOST_CHECK_EQUAL(FormatMoney(COIN/10), "0.10");
1220 BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01");
1221 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001");
1222 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001");
1223 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001");
1224 BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001");
1225 BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001");
1226 BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001");
1227
1228 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max()), "92233720368.54775807");
1229 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 1), "92233720368.54775806");
1230 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 2), "92233720368.54775805");
1231 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 3), "92233720368.54775804");
1232 // ...
1233 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 3), "-92233720368.54775805");
1234 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 2), "-92233720368.54775806");
1235 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 1), "-92233720368.54775807");
1236 BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min()), "-92233720368.54775808");
1237}
1238
1239BOOST_AUTO_TEST_CASE(util_ParseMoney)
1240{
1241 BOOST_CHECK_EQUAL(ParseMoney("0.0").value(), 0);
1242 BOOST_CHECK_EQUAL(ParseMoney(".").value(), 0);
1243 BOOST_CHECK_EQUAL(ParseMoney("0.").value(), 0);
1244 BOOST_CHECK_EQUAL(ParseMoney(".0").value(), 0);
1245 BOOST_CHECK_EQUAL(ParseMoney(".6789").value(), 6789'0000);
1246 BOOST_CHECK_EQUAL(ParseMoney("12345.").value(), COIN * 12345);
1247
1248 BOOST_CHECK_EQUAL(ParseMoney("12345.6789").value(), (COIN/10000)*123456789);
1249
1250 BOOST_CHECK_EQUAL(ParseMoney("10000000.00").value(), COIN*10000000);
1251 BOOST_CHECK_EQUAL(ParseMoney("1000000.00").value(), COIN*1000000);
1252 BOOST_CHECK_EQUAL(ParseMoney("100000.00").value(), COIN*100000);
1253 BOOST_CHECK_EQUAL(ParseMoney("10000.00").value(), COIN*10000);
1254 BOOST_CHECK_EQUAL(ParseMoney("1000.00").value(), COIN*1000);
1255 BOOST_CHECK_EQUAL(ParseMoney("100.00").value(), COIN*100);
1256 BOOST_CHECK_EQUAL(ParseMoney("10.00").value(), COIN*10);
1257 BOOST_CHECK_EQUAL(ParseMoney("1.00").value(), COIN);
1258 BOOST_CHECK_EQUAL(ParseMoney("1").value(), COIN);
1259 BOOST_CHECK_EQUAL(ParseMoney(" 1").value(), COIN);
1260 BOOST_CHECK_EQUAL(ParseMoney("1 ").value(), COIN);
1261 BOOST_CHECK_EQUAL(ParseMoney(" 1 ").value(), COIN);
1262 BOOST_CHECK_EQUAL(ParseMoney("0.1").value(), COIN/10);
1263 BOOST_CHECK_EQUAL(ParseMoney("0.01").value(), COIN/100);
1264 BOOST_CHECK_EQUAL(ParseMoney("0.001").value(), COIN/1000);
1265 BOOST_CHECK_EQUAL(ParseMoney("0.0001").value(), COIN/10000);
1266 BOOST_CHECK_EQUAL(ParseMoney("0.00001").value(), COIN/100000);
1267 BOOST_CHECK_EQUAL(ParseMoney("0.000001").value(), COIN/1000000);
1268 BOOST_CHECK_EQUAL(ParseMoney("0.0000001").value(), COIN/10000000);
1269 BOOST_CHECK_EQUAL(ParseMoney("0.00000001").value(), COIN/100000000);
1270 BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001 ").value(), COIN/100000000);
1271 BOOST_CHECK_EQUAL(ParseMoney("0.00000001 ").value(), COIN/100000000);
1272 BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001").value(), COIN/100000000);
1273
1274 // Parsing amount that can not be represented should fail
1275 BOOST_CHECK(!ParseMoney("100000000.00"));
1276 BOOST_CHECK(!ParseMoney("0.000000001"));
1277
1278 // Parsing empty string should fail
1279 BOOST_CHECK(!ParseMoney(""));
1280 BOOST_CHECK(!ParseMoney(" "));
1281 BOOST_CHECK(!ParseMoney(" "));
1282
1283 // Parsing two numbers should fail
1284 BOOST_CHECK(!ParseMoney(".."));
1285 BOOST_CHECK(!ParseMoney("0..0"));
1286 BOOST_CHECK(!ParseMoney("1 2"));
1287 BOOST_CHECK(!ParseMoney(" 1 2 "));
1288 BOOST_CHECK(!ParseMoney(" 1.2 3 "));
1289 BOOST_CHECK(!ParseMoney(" 1 2.3 "));
1290
1291 // Embedded whitespace should fail
1292 BOOST_CHECK(!ParseMoney(" -1 .2 "));
1293 BOOST_CHECK(!ParseMoney(" 1 .2 "));
1294 BOOST_CHECK(!ParseMoney(" +1 .2 "));
1295
1296 // Attempted 63 bit overflow should fail
1297 BOOST_CHECK(!ParseMoney("92233720368.54775808"));
1298
1299 // Parsing negative amounts must fail
1300 BOOST_CHECK(!ParseMoney("-1"));
1301
1302 // Parsing strings with embedded NUL characters should fail
1303 BOOST_CHECK(!ParseMoney("\0-1"s));
1305 BOOST_CHECK(!ParseMoney("1\0"s));
1306}
1307
1309{
1310 BOOST_CHECK(IsHex("00"));
1311 BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
1312 BOOST_CHECK(IsHex("ff"));
1313 BOOST_CHECK(IsHex("FF"));
1314
1315 BOOST_CHECK(!IsHex(""));
1316 BOOST_CHECK(!IsHex("0"));
1317 BOOST_CHECK(!IsHex("a"));
1318 BOOST_CHECK(!IsHex("eleven"));
1319 BOOST_CHECK(!IsHex("00xx00"));
1320 BOOST_CHECK(!IsHex("0x0000"));
1321}
1322
1323BOOST_AUTO_TEST_CASE(util_IsHexNumber)
1324{
1325 BOOST_CHECK(IsHexNumber("0x0"));
1327 BOOST_CHECK(IsHexNumber("0x10"));
1328 BOOST_CHECK(IsHexNumber("10"));
1329 BOOST_CHECK(IsHexNumber("0xff"));
1330 BOOST_CHECK(IsHexNumber("ff"));
1331 BOOST_CHECK(IsHexNumber("0xFfa"));
1332 BOOST_CHECK(IsHexNumber("Ffa"));
1333 BOOST_CHECK(IsHexNumber("0x00112233445566778899aabbccddeeffAABBCCDDEEFF"));
1334 BOOST_CHECK(IsHexNumber("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
1335
1336 BOOST_CHECK(!IsHexNumber("")); // empty string not allowed
1337 BOOST_CHECK(!IsHexNumber("0x")); // empty string after prefix not allowed
1338 BOOST_CHECK(!IsHexNumber("0x0 ")); // no spaces at end,
1339 BOOST_CHECK(!IsHexNumber(" 0x0")); // or beginning,
1340 BOOST_CHECK(!IsHexNumber("0x 0")); // or middle,
1341 BOOST_CHECK(!IsHexNumber(" ")); // etc.
1342 BOOST_CHECK(!IsHexNumber("0x0ga")); // invalid character
1343 BOOST_CHECK(!IsHexNumber("x0")); // broken prefix
1344 BOOST_CHECK(!IsHexNumber("0x0x00")); // two prefixes not allowed
1345
1346}
1347
1348BOOST_AUTO_TEST_CASE(util_seed_insecure_rand)
1349{
1351 for (int mod=2;mod<11;mod++)
1352 {
1353 int mask = 1;
1354 // Really rough binomial confidence approximation.
1355 int err = 30*10000./mod*sqrt((1./mod*(1-1./mod))/10000.);
1356 //mask is 2^ceil(log2(mod))-1
1357 while(mask<mod-1)mask=(mask<<1)+1;
1358
1359 int count = 0;
1360 //How often does it get a zero from the uniform range [0,mod)?
1361 for (int i = 0; i < 10000; i++) {
1362 uint32_t rval;
1363 do{
1364 rval=InsecureRand32()&mask;
1365 }while(rval>=(uint32_t)mod);
1366 count += rval==0;
1367 }
1368 BOOST_CHECK(count<=10000/mod+err);
1369 BOOST_CHECK(count>=10000/mod-err);
1370 }
1371}
1372
1373BOOST_AUTO_TEST_CASE(util_TimingResistantEqual)
1374{
1375 BOOST_CHECK(TimingResistantEqual(std::string(""), std::string("")));
1376 BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("")));
1377 BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc")));
1378 BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa")));
1379 BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a")));
1380 BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc")));
1381 BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba")));
1382}
1383
1384/* Test strprintf formatting directives.
1385 * Put a string before and after to ensure sanity of element sizes on stack. */
1386#define B "check_prefix"
1387#define E "check_postfix"
1388BOOST_AUTO_TEST_CASE(strprintf_numbers)
1389{
1390 int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
1391 uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
1392 BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
1393 BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
1394 BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
1395
1396 size_t st = 12345678; /* unsigned size_t test value */
1397 ssize_t sst = -12345678; /* signed size_t test value */
1398 BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
1399 BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
1400 BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
1401
1402 ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
1403 ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
1404 BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
1405 BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
1406 BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
1407}
1408#undef B
1409#undef E
1410
1411/* Check for mingw/wine issue #3494
1412 * Remove this test before time.ctime(0xffffffff) == 'Sun Feb 7 07:28:15 2106'
1413 */
1415{
1416 BOOST_CHECK((GetTime() & ~0xFFFFFFFFLL) == 0);
1417}
1418
1419BOOST_AUTO_TEST_CASE(util_time_GetTime)
1420{
1421 SetMockTime(111);
1422 // Check that mock time does not change after a sleep
1423 for (const auto& num_sleep : {0, 1}) {
1424 UninterruptibleSleep(std::chrono::milliseconds{num_sleep});
1425 BOOST_CHECK_EQUAL(111, GetTime()); // Deprecated time getter
1426 BOOST_CHECK_EQUAL(111, GetTime<std::chrono::seconds>().count());
1427 BOOST_CHECK_EQUAL(111000, GetTime<std::chrono::milliseconds>().count());
1428 BOOST_CHECK_EQUAL(111000000, GetTime<std::chrono::microseconds>().count());
1429 }
1430
1431 SetMockTime(0);
1432 // Check that system time changes after a sleep
1433 const auto ms_0 = GetTime<std::chrono::milliseconds>();
1434 const auto us_0 = GetTime<std::chrono::microseconds>();
1435 UninterruptibleSleep(std::chrono::milliseconds{1});
1436 BOOST_CHECK(ms_0 < GetTime<std::chrono::milliseconds>());
1437 BOOST_CHECK(us_0 < GetTime<std::chrono::microseconds>());
1438}
1439
1441{
1442 BOOST_CHECK_EQUAL(IsDigit('0'), true);
1443 BOOST_CHECK_EQUAL(IsDigit('1'), true);
1444 BOOST_CHECK_EQUAL(IsDigit('8'), true);
1445 BOOST_CHECK_EQUAL(IsDigit('9'), true);
1446
1447 BOOST_CHECK_EQUAL(IsDigit('0' - 1), false);
1448 BOOST_CHECK_EQUAL(IsDigit('9' + 1), false);
1449 BOOST_CHECK_EQUAL(IsDigit(0), false);
1450 BOOST_CHECK_EQUAL(IsDigit(1), false);
1451 BOOST_CHECK_EQUAL(IsDigit(8), false);
1452 BOOST_CHECK_EQUAL(IsDigit(9), false);
1453}
1454
1455BOOST_AUTO_TEST_CASE(test_ParseInt32)
1456{
1457 int32_t n;
1458 // Valid values
1459 BOOST_CHECK(ParseInt32("1234", nullptr));
1460 BOOST_CHECK(ParseInt32("0", &n) && n == 0);
1461 BOOST_CHECK(ParseInt32("1234", &n) && n == 1234);
1462 BOOST_CHECK(ParseInt32("01234", &n) && n == 1234); // no octal
1463 BOOST_CHECK(ParseInt32("2147483647", &n) && n == 2147483647);
1464 BOOST_CHECK(ParseInt32("-2147483648", &n) && n == (-2147483647 - 1)); // (-2147483647 - 1) equals INT_MIN
1465 BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234);
1466 BOOST_CHECK(ParseInt32("00000000000000001234", &n) && n == 1234);
1467 BOOST_CHECK(ParseInt32("-00000000000000001234", &n) && n == -1234);
1468 BOOST_CHECK(ParseInt32("00000000000000000000", &n) && n == 0);
1469 BOOST_CHECK(ParseInt32("-00000000000000000000", &n) && n == 0);
1470 // Invalid values
1471 BOOST_CHECK(!ParseInt32("", &n));
1472 BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside
1473 BOOST_CHECK(!ParseInt32("1 ", &n));
1474 BOOST_CHECK(!ParseInt32("++1", &n));
1475 BOOST_CHECK(!ParseInt32("+-1", &n));
1476 BOOST_CHECK(!ParseInt32("-+1", &n));
1477 BOOST_CHECK(!ParseInt32("--1", &n));
1478 BOOST_CHECK(!ParseInt32("1a", &n));
1479 BOOST_CHECK(!ParseInt32("aap", &n));
1480 BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
1482 // Overflow and underflow
1483 BOOST_CHECK(!ParseInt32("-2147483649", nullptr));
1484 BOOST_CHECK(!ParseInt32("2147483648", nullptr));
1485 BOOST_CHECK(!ParseInt32("-32482348723847471234", nullptr));
1486 BOOST_CHECK(!ParseInt32("32482348723847471234", nullptr));
1487}
1488
1489template <typename T>
1491{
1493 BOOST_CHECK(!ToIntegral<T>(" 1"));
1494 BOOST_CHECK(!ToIntegral<T>("1 "));
1495 BOOST_CHECK(!ToIntegral<T>("1a"));
1496 BOOST_CHECK(!ToIntegral<T>("1.1"));
1497 BOOST_CHECK(!ToIntegral<T>("1.9"));
1498 BOOST_CHECK(!ToIntegral<T>("+01.9"));
1499 BOOST_CHECK(!ToIntegral<T>("-"));
1500 BOOST_CHECK(!ToIntegral<T>("+"));
1501 BOOST_CHECK(!ToIntegral<T>(" -1"));
1502 BOOST_CHECK(!ToIntegral<T>("-1 "));
1503 BOOST_CHECK(!ToIntegral<T>(" -1 "));
1504 BOOST_CHECK(!ToIntegral<T>("+1"));
1505 BOOST_CHECK(!ToIntegral<T>(" +1"));
1506 BOOST_CHECK(!ToIntegral<T>(" +1 "));
1507 BOOST_CHECK(!ToIntegral<T>("+-1"));
1508 BOOST_CHECK(!ToIntegral<T>("-+1"));
1509 BOOST_CHECK(!ToIntegral<T>("++1"));
1510 BOOST_CHECK(!ToIntegral<T>("--1"));
1511 BOOST_CHECK(!ToIntegral<T>(""));
1512 BOOST_CHECK(!ToIntegral<T>("aap"));
1513 BOOST_CHECK(!ToIntegral<T>("0x1"));
1514 BOOST_CHECK(!ToIntegral<T>("-32482348723847471234"));
1515 BOOST_CHECK(!ToIntegral<T>("32482348723847471234"));
1516}
1517
1518BOOST_AUTO_TEST_CASE(test_ToIntegral)
1519{
1520 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("1234").value(), 1'234);
1521 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("0").value(), 0);
1522 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("01234").value(), 1'234);
1523 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000001234").value(), 1'234);
1524 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000001234").value(), -1'234);
1525 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("00000000000000000000").value(), 0);
1526 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-00000000000000000000").value(), 0);
1527 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1234").value(), -1'234);
1528 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-1").value(), -1);
1529
1530 RunToIntegralTests<uint64_t>();
1531 RunToIntegralTests<int64_t>();
1532 RunToIntegralTests<uint32_t>();
1533 RunToIntegralTests<int32_t>();
1534 RunToIntegralTests<uint16_t>();
1535 RunToIntegralTests<int16_t>();
1536 RunToIntegralTests<uint8_t>();
1537 RunToIntegralTests<int8_t>();
1538
1539 BOOST_CHECK(!ToIntegral<int64_t>("-9223372036854775809"));
1540 BOOST_CHECK_EQUAL(ToIntegral<int64_t>("-9223372036854775808").value(), -9'223'372'036'854'775'807LL - 1LL);
1541 BOOST_CHECK_EQUAL(ToIntegral<int64_t>("9223372036854775807").value(), 9'223'372'036'854'775'807);
1542 BOOST_CHECK(!ToIntegral<int64_t>("9223372036854775808"));
1543
1544 BOOST_CHECK(!ToIntegral<uint64_t>("-1"));
1545 BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("0").value(), 0U);
1546 BOOST_CHECK_EQUAL(ToIntegral<uint64_t>("18446744073709551615").value(), 18'446'744'073'709'551'615ULL);
1547 BOOST_CHECK(!ToIntegral<uint64_t>("18446744073709551616"));
1548
1549 BOOST_CHECK(!ToIntegral<int32_t>("-2147483649"));
1550 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("-2147483648").value(), -2'147'483'648LL);
1551 BOOST_CHECK_EQUAL(ToIntegral<int32_t>("2147483647").value(), 2'147'483'647);
1552 BOOST_CHECK(!ToIntegral<int32_t>("2147483648"));
1553
1554 BOOST_CHECK(!ToIntegral<uint32_t>("-1"));
1555 BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("0").value(), 0U);
1556 BOOST_CHECK_EQUAL(ToIntegral<uint32_t>("4294967295").value(), 4'294'967'295U);
1557 BOOST_CHECK(!ToIntegral<uint32_t>("4294967296"));
1558
1559 BOOST_CHECK(!ToIntegral<int16_t>("-32769"));
1560 BOOST_CHECK_EQUAL(ToIntegral<int16_t>("-32768").value(), -32'768);
1561 BOOST_CHECK_EQUAL(ToIntegral<int16_t>("32767").value(), 32'767);
1562 BOOST_CHECK(!ToIntegral<int16_t>("32768"));
1563
1564 BOOST_CHECK(!ToIntegral<uint16_t>("-1"));
1565 BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("0").value(), 0U);
1566 BOOST_CHECK_EQUAL(ToIntegral<uint16_t>("65535").value(), 65'535U);
1567 BOOST_CHECK(!ToIntegral<uint16_t>("65536"));
1568
1569 BOOST_CHECK(!ToIntegral<int8_t>("-129"));
1570 BOOST_CHECK_EQUAL(ToIntegral<int8_t>("-128").value(), -128);
1571 BOOST_CHECK_EQUAL(ToIntegral<int8_t>("127").value(), 127);
1572 BOOST_CHECK(!ToIntegral<int8_t>("128"));
1573
1574 BOOST_CHECK(!ToIntegral<uint8_t>("-1"));
1575 BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("0").value(), 0U);
1576 BOOST_CHECK_EQUAL(ToIntegral<uint8_t>("255").value(), 255U);
1577 BOOST_CHECK(!ToIntegral<uint8_t>("256"));
1578}
1579
1580BOOST_AUTO_TEST_CASE(test_LocaleIndependentAtoi)
1581{
1582 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1234"), 1'234);
1583 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0"), 0);
1584 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("01234"), 1'234);
1585 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1234"), -1'234);
1586 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" 1"), 1);
1587 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1 "), 1);
1588 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1a"), 1);
1589 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.1"), 1);
1590 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("1.9"), 1);
1591 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+01.9"), 1);
1592 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1"), -1);
1593 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1"), -1);
1594 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-1 "), -1);
1595 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" -1 "), -1);
1596 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+1"), 1);
1597 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1"), 1);
1598 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(" +1 "), 1);
1599
1600 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("+-1"), 0);
1601 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-+1"), 0);
1602 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("++1"), 0);
1603 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("--1"), 0);
1604 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>(""), 0);
1605 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("aap"), 0);
1606 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("0x1"), 0);
1607 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-32482348723847471234"), 0);
1608 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("32482348723847471234"), 0);
1609
1610 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775809"), 0);
1611 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("-9223372036854775808"), -9'223'372'036'854'775'807LL - 1LL);
1612 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775807"), 9'223'372'036'854'775'807);
1613 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int64_t>("9223372036854775808"), 0);
1614
1615 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("-1"), 0U);
1616 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("0"), 0U);
1617 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551615"), 18'446'744'073'709'551'615ULL);
1618 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint64_t>("18446744073709551616"), 0U);
1619
1620 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483649"), 0);
1621 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("-2147483648"), -2'147'483'648LL);
1622 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483647"), 2'147'483'647);
1623 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int32_t>("2147483648"), 0);
1624
1625 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("-1"), 0U);
1626 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("0"), 0U);
1627 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967295"), 4'294'967'295U);
1628 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint32_t>("4294967296"), 0U);
1629
1630 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32769"), 0);
1631 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("-32768"), -32'768);
1632 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32767"), 32'767);
1633 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int16_t>("32768"), 0);
1634
1635 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("-1"), 0U);
1636 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("0"), 0U);
1637 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65535"), 65'535U);
1638 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint16_t>("65536"), 0U);
1639
1640 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-129"), 0);
1641 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("-128"), -128);
1642 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("127"), 127);
1643 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<int8_t>("128"), 0);
1644
1645 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("-1"), 0U);
1646 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("0"), 0U);
1647 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("255"), 255U);
1648 BOOST_CHECK_EQUAL(LocaleIndependentAtoi<uint8_t>("256"), 0U);
1649}
1650
1651BOOST_AUTO_TEST_CASE(test_ParseInt64)
1652{
1653 int64_t n;
1654 // Valid values
1655 BOOST_CHECK(ParseInt64("1234", nullptr));
1656 BOOST_CHECK(ParseInt64("0", &n) && n == 0LL);
1657 BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL);
1658 BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal
1659 BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL);
1660 BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL);
1661 BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == (int64_t)9223372036854775807);
1662 BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == (int64_t)-9223372036854775807-1);
1663 BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL);
1664 // Invalid values
1665 BOOST_CHECK(!ParseInt64("", &n));
1666 BOOST_CHECK(!ParseInt64(" 1", &n)); // no padding inside
1667 BOOST_CHECK(!ParseInt64("1 ", &n));
1668 BOOST_CHECK(!ParseInt64("1a", &n));
1669 BOOST_CHECK(!ParseInt64("aap", &n));
1670 BOOST_CHECK(!ParseInt64("0x1", &n)); // no hex
1672 // Overflow and underflow
1673 BOOST_CHECK(!ParseInt64("-9223372036854775809", nullptr));
1674 BOOST_CHECK(!ParseInt64("9223372036854775808", nullptr));
1675 BOOST_CHECK(!ParseInt64("-32482348723847471234", nullptr));
1676 BOOST_CHECK(!ParseInt64("32482348723847471234", nullptr));
1677}
1678
1679BOOST_AUTO_TEST_CASE(test_ParseUInt8)
1680{
1681 uint8_t n;
1682 // Valid values
1683 BOOST_CHECK(ParseUInt8("255", nullptr));
1684 BOOST_CHECK(ParseUInt8("0", &n) && n == 0);
1685 BOOST_CHECK(ParseUInt8("255", &n) && n == 255);
1686 BOOST_CHECK(ParseUInt8("0255", &n) && n == 255); // no octal
1687 BOOST_CHECK(ParseUInt8("255", &n) && n == static_cast<uint8_t>(255));
1688 BOOST_CHECK(ParseUInt8("+255", &n) && n == 255);
1689 BOOST_CHECK(ParseUInt8("00000000000000000012", &n) && n == 12);
1690 BOOST_CHECK(ParseUInt8("00000000000000000000", &n) && n == 0);
1691 // Invalid values
1692 BOOST_CHECK(!ParseUInt8("-00000000000000000000", &n));
1693 BOOST_CHECK(!ParseUInt8("", &n));
1694 BOOST_CHECK(!ParseUInt8(" 1", &n)); // no padding inside
1695 BOOST_CHECK(!ParseUInt8(" -1", &n));
1696 BOOST_CHECK(!ParseUInt8("++1", &n));
1697 BOOST_CHECK(!ParseUInt8("+-1", &n));
1698 BOOST_CHECK(!ParseUInt8("-+1", &n));
1699 BOOST_CHECK(!ParseUInt8("--1", &n));
1700 BOOST_CHECK(!ParseUInt8("-1", &n));
1701 BOOST_CHECK(!ParseUInt8("1 ", &n));
1702 BOOST_CHECK(!ParseUInt8("1a", &n));
1703 BOOST_CHECK(!ParseUInt8("aap", &n));
1704 BOOST_CHECK(!ParseUInt8("0x1", &n)); // no hex
1706 // Overflow and underflow
1707 BOOST_CHECK(!ParseUInt8("-255", &n));
1708 BOOST_CHECK(!ParseUInt8("256", &n));
1709 BOOST_CHECK(!ParseUInt8("-123", &n));
1710 BOOST_CHECK(!ParseUInt8("-123", nullptr));
1711 BOOST_CHECK(!ParseUInt8("256", nullptr));
1712}
1713
1714BOOST_AUTO_TEST_CASE(test_ParseUInt16)
1715{
1716 uint16_t n;
1717 // Valid values
1718 BOOST_CHECK(ParseUInt16("1234", nullptr));
1719 BOOST_CHECK(ParseUInt16("0", &n) && n == 0);
1720 BOOST_CHECK(ParseUInt16("1234", &n) && n == 1234);
1721 BOOST_CHECK(ParseUInt16("01234", &n) && n == 1234); // no octal
1722 BOOST_CHECK(ParseUInt16("65535", &n) && n == static_cast<uint16_t>(65535));
1723 BOOST_CHECK(ParseUInt16("+65535", &n) && n == 65535);
1724 BOOST_CHECK(ParseUInt16("00000000000000000012", &n) && n == 12);
1725 BOOST_CHECK(ParseUInt16("00000000000000000000", &n) && n == 0);
1726 // Invalid values
1727 BOOST_CHECK(!ParseUInt16("-00000000000000000000", &n));
1728 BOOST_CHECK(!ParseUInt16("", &n));
1729 BOOST_CHECK(!ParseUInt16(" 1", &n)); // no padding inside
1730 BOOST_CHECK(!ParseUInt16(" -1", &n));
1731 BOOST_CHECK(!ParseUInt16("++1", &n));
1732 BOOST_CHECK(!ParseUInt16("+-1", &n));
1733 BOOST_CHECK(!ParseUInt16("-+1", &n));
1734 BOOST_CHECK(!ParseUInt16("--1", &n));
1735 BOOST_CHECK(!ParseUInt16("-1", &n));
1736 BOOST_CHECK(!ParseUInt16("1 ", &n));
1737 BOOST_CHECK(!ParseUInt16("1a", &n));
1738 BOOST_CHECK(!ParseUInt16("aap", &n));
1739 BOOST_CHECK(!ParseUInt16("0x1", &n)); // no hex
1741 // Overflow and underflow
1742 BOOST_CHECK(!ParseUInt16("-65535", &n));
1743 BOOST_CHECK(!ParseUInt16("65536", &n));
1744 BOOST_CHECK(!ParseUInt16("-123", &n));
1745 BOOST_CHECK(!ParseUInt16("-123", nullptr));
1746 BOOST_CHECK(!ParseUInt16("65536", nullptr));
1747}
1748
1749BOOST_AUTO_TEST_CASE(test_ParseUInt32)
1750{
1751 uint32_t n;
1752 // Valid values
1753 BOOST_CHECK(ParseUInt32("1234", nullptr));
1754 BOOST_CHECK(ParseUInt32("0", &n) && n == 0);
1755 BOOST_CHECK(ParseUInt32("1234", &n) && n == 1234);
1756 BOOST_CHECK(ParseUInt32("01234", &n) && n == 1234); // no octal
1757 BOOST_CHECK(ParseUInt32("2147483647", &n) && n == 2147483647);
1758 BOOST_CHECK(ParseUInt32("2147483648", &n) && n == (uint32_t)2147483648);
1759 BOOST_CHECK(ParseUInt32("4294967295", &n) && n == (uint32_t)4294967295);
1760 BOOST_CHECK(ParseUInt32("+1234", &n) && n == 1234);
1761 BOOST_CHECK(ParseUInt32("00000000000000001234", &n) && n == 1234);
1762 BOOST_CHECK(ParseUInt32("00000000000000000000", &n) && n == 0);
1763 // Invalid values
1764 BOOST_CHECK(!ParseUInt32("-00000000000000000000", &n));
1765 BOOST_CHECK(!ParseUInt32("", &n));
1766 BOOST_CHECK(!ParseUInt32(" 1", &n)); // no padding inside
1767 BOOST_CHECK(!ParseUInt32(" -1", &n));
1768 BOOST_CHECK(!ParseUInt32("++1", &n));
1769 BOOST_CHECK(!ParseUInt32("+-1", &n));
1770 BOOST_CHECK(!ParseUInt32("-+1", &n));
1771 BOOST_CHECK(!ParseUInt32("--1", &n));
1772 BOOST_CHECK(!ParseUInt32("-1", &n));
1773 BOOST_CHECK(!ParseUInt32("1 ", &n));
1774 BOOST_CHECK(!ParseUInt32("1a", &n));
1775 BOOST_CHECK(!ParseUInt32("aap", &n));
1776 BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex
1778 // Overflow and underflow
1779 BOOST_CHECK(!ParseUInt32("-2147483648", &n));
1780 BOOST_CHECK(!ParseUInt32("4294967296", &n));
1781 BOOST_CHECK(!ParseUInt32("-1234", &n));
1782 BOOST_CHECK(!ParseUInt32("-32482348723847471234", nullptr));
1783 BOOST_CHECK(!ParseUInt32("32482348723847471234", nullptr));
1784}
1785
1786BOOST_AUTO_TEST_CASE(test_ParseUInt64)
1787{
1788 uint64_t n;
1789 // Valid values
1790 BOOST_CHECK(ParseUInt64("1234", nullptr));
1791 BOOST_CHECK(ParseUInt64("0", &n) && n == 0LL);
1792 BOOST_CHECK(ParseUInt64("1234", &n) && n == 1234LL);
1793 BOOST_CHECK(ParseUInt64("01234", &n) && n == 1234LL); // no octal
1794 BOOST_CHECK(ParseUInt64("2147483647", &n) && n == 2147483647LL);
1795 BOOST_CHECK(ParseUInt64("9223372036854775807", &n) && n == 9223372036854775807ULL);
1796 BOOST_CHECK(ParseUInt64("9223372036854775808", &n) && n == 9223372036854775808ULL);
1797 BOOST_CHECK(ParseUInt64("18446744073709551615", &n) && n == 18446744073709551615ULL);
1798 // Invalid values
1799 BOOST_CHECK(!ParseUInt64("", &n));
1800 BOOST_CHECK(!ParseUInt64(" 1", &n)); // no padding inside
1801 BOOST_CHECK(!ParseUInt64(" -1", &n));
1802 BOOST_CHECK(!ParseUInt64("1 ", &n));
1803 BOOST_CHECK(!ParseUInt64("1a", &n));
1804 BOOST_CHECK(!ParseUInt64("aap", &n));
1805 BOOST_CHECK(!ParseUInt64("0x1", &n)); // no hex
1807 // Overflow and underflow
1808 BOOST_CHECK(!ParseUInt64("-9223372036854775809", nullptr));
1809 BOOST_CHECK(!ParseUInt64("18446744073709551616", nullptr));
1810 BOOST_CHECK(!ParseUInt64("-32482348723847471234", nullptr));
1811 BOOST_CHECK(!ParseUInt64("-2147483648", &n));
1812 BOOST_CHECK(!ParseUInt64("-9223372036854775808", &n));
1813 BOOST_CHECK(!ParseUInt64("-1234", &n));
1814}
1815
1816BOOST_AUTO_TEST_CASE(test_FormatParagraph)
1817{
1818 BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");
1819 BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test");
1820 BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), " test");
1821 BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test");
1822 BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest");
1823 BOOST_CHECK_EQUAL(FormatParagraph("testerde test", 4, 0), "testerde\ntest");
1824 BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test");
1825
1826 // Make sure we don't indent a fully-new line following a too-long line ending
1827 BOOST_CHECK_EQUAL(FormatParagraph("test test\nabc", 4, 4), "test\n test\nabc");
1828
1829 BOOST_CHECK_EQUAL(FormatParagraph("This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length until it gets here", 79), "This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length\nuntil it gets here");
1830
1831 // Test wrap length is exact
1832 BOOST_CHECK_EQUAL(FormatParagraph("a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p");
1833 BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p");
1834 // Indent should be included in length of lines
1835 BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg h i j k", 79, 4), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\n f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg\n h i j k");
1836
1837 BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string. This is a second sentence in the very long test string.", 79), "This is a very long test string. This is a second sentence in the very long\ntest string.");
1838 BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string.");
1839 BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string.");
1840 BOOST_CHECK_EQUAL(FormatParagraph("Testing that normal newlines do not get indented.\nLike here.", 79), "Testing that normal newlines do not get indented.\nLike here.");
1841}
1842
1843BOOST_AUTO_TEST_CASE(test_FormatSubVersion)
1844{
1845 std::vector<std::string> comments;
1846 comments.push_back(std::string("comment1"));
1847 std::vector<std::string> comments2;
1848 comments2.push_back(std::string("comment1"));
1849 comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014
1850 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:9.99.0/"));
1851 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:9.99.0(comment1)/"));
1852 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:9.99.0(comment1; Comment2; .,_?@-; )/"));
1853}
1854
1855BOOST_AUTO_TEST_CASE(test_ParseFixedPoint)
1856{
1857 int64_t amount = 0;
1858 BOOST_CHECK(ParseFixedPoint("0", 8, &amount));
1859 BOOST_CHECK_EQUAL(amount, 0LL);
1860 BOOST_CHECK(ParseFixedPoint("1", 8, &amount));
1861 BOOST_CHECK_EQUAL(amount, 100000000LL);
1862 BOOST_CHECK(ParseFixedPoint("0.0", 8, &amount));
1863 BOOST_CHECK_EQUAL(amount, 0LL);
1864 BOOST_CHECK(ParseFixedPoint("-0.1", 8, &amount));
1865 BOOST_CHECK_EQUAL(amount, -10000000LL);
1866 BOOST_CHECK(ParseFixedPoint("1.1", 8, &amount));
1867 BOOST_CHECK_EQUAL(amount, 110000000LL);
1868 BOOST_CHECK(ParseFixedPoint("1.10000000000000000", 8, &amount));
1869 BOOST_CHECK_EQUAL(amount, 110000000LL);
1870 BOOST_CHECK(ParseFixedPoint("1.1e1", 8, &amount));
1871 BOOST_CHECK_EQUAL(amount, 1100000000LL);
1872 BOOST_CHECK(ParseFixedPoint("1.1e-1", 8, &amount));
1873 BOOST_CHECK_EQUAL(amount, 11000000LL);
1874 BOOST_CHECK(ParseFixedPoint("1000", 8, &amount));
1875 BOOST_CHECK_EQUAL(amount, 100000000000LL);
1876 BOOST_CHECK(ParseFixedPoint("-1000", 8, &amount));
1877 BOOST_CHECK_EQUAL(amount, -100000000000LL);
1878 BOOST_CHECK(ParseFixedPoint("0.00000001", 8, &amount));
1879 BOOST_CHECK_EQUAL(amount, 1LL);
1880 BOOST_CHECK(ParseFixedPoint("0.0000000100000000", 8, &amount));
1881 BOOST_CHECK_EQUAL(amount, 1LL);
1882 BOOST_CHECK(ParseFixedPoint("-0.00000001", 8, &amount));
1883 BOOST_CHECK_EQUAL(amount, -1LL);
1884 BOOST_CHECK(ParseFixedPoint("1000000000.00000001", 8, &amount));
1885 BOOST_CHECK_EQUAL(amount, 100000000000000001LL);
1886 BOOST_CHECK(ParseFixedPoint("9999999999.99999999", 8, &amount));
1887 BOOST_CHECK_EQUAL(amount, 999999999999999999LL);
1888 BOOST_CHECK(ParseFixedPoint("-9999999999.99999999", 8, &amount));
1889 BOOST_CHECK_EQUAL(amount, -999999999999999999LL);
1890
1891 BOOST_CHECK(!ParseFixedPoint("", 8, &amount));
1892 BOOST_CHECK(!ParseFixedPoint("-", 8, &amount));
1893 BOOST_CHECK(!ParseFixedPoint("a-1000", 8, &amount));
1894 BOOST_CHECK(!ParseFixedPoint("-a1000", 8, &amount));
1895 BOOST_CHECK(!ParseFixedPoint("-1000a", 8, &amount));
1896 BOOST_CHECK(!ParseFixedPoint("-01000", 8, &amount));
1897 BOOST_CHECK(!ParseFixedPoint("00.1", 8, &amount));
1898 BOOST_CHECK(!ParseFixedPoint(".1", 8, &amount));
1899 BOOST_CHECK(!ParseFixedPoint("--0.1", 8, &amount));
1900 BOOST_CHECK(!ParseFixedPoint("0.000000001", 8, &amount));
1901 BOOST_CHECK(!ParseFixedPoint("-0.000000001", 8, &amount));
1902 BOOST_CHECK(!ParseFixedPoint("0.00000001000000001", 8, &amount));
1903 BOOST_CHECK(!ParseFixedPoint("-10000000000.00000000", 8, &amount));
1904 BOOST_CHECK(!ParseFixedPoint("10000000000.00000000", 8, &amount));
1905 BOOST_CHECK(!ParseFixedPoint("-10000000000.00000001", 8, &amount));
1906 BOOST_CHECK(!ParseFixedPoint("10000000000.00000001", 8, &amount));
1907 BOOST_CHECK(!ParseFixedPoint("-10000000000.00000009", 8, &amount));
1908 BOOST_CHECK(!ParseFixedPoint("10000000000.00000009", 8, &amount));
1909 BOOST_CHECK(!ParseFixedPoint("-99999999999.99999999", 8, &amount));
1910 BOOST_CHECK(!ParseFixedPoint("99999909999.09999999", 8, &amount));
1911 BOOST_CHECK(!ParseFixedPoint("92233720368.54775807", 8, &amount));
1912 BOOST_CHECK(!ParseFixedPoint("92233720368.54775808", 8, &amount));
1913 BOOST_CHECK(!ParseFixedPoint("-92233720368.54775808", 8, &amount));
1914 BOOST_CHECK(!ParseFixedPoint("-92233720368.54775809", 8, &amount));
1915 BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount));
1916 BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount));
1917 BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount));
1918
1919 // Test with 3 decimal places for fee rates in sat/vB.
1920 BOOST_CHECK(ParseFixedPoint("0.001", 3, &amount));
1921 BOOST_CHECK_EQUAL(amount, CAmount{1});
1922 BOOST_CHECK(!ParseFixedPoint("0.0009", 3, &amount));
1923 BOOST_CHECK(!ParseFixedPoint("31.00100001", 3, &amount));
1924 BOOST_CHECK(!ParseFixedPoint("31.0011", 3, &amount));
1925 BOOST_CHECK(!ParseFixedPoint("31.99999999", 3, &amount));
1926 BOOST_CHECK(!ParseFixedPoint("31.999999999999999999999", 3, &amount));
1927}
1928
1929static void TestOtherThread(fs::path dirname, std::string lockname, bool *result)
1930{
1931 *result = LockDirectory(dirname, lockname);
1932}
1933
1934#ifndef WIN32 // Cannot do this test on WIN32 due to lack of fork()
1935static constexpr char LockCommand = 'L';
1936static constexpr char UnlockCommand = 'U';
1937static constexpr char ExitCommand = 'X';
1938
1939[[noreturn]] static void TestOtherProcess(fs::path dirname, std::string lockname, int fd)
1940{
1941 char ch;
1942 while (true) {
1943 int rv = read(fd, &ch, 1); // Wait for command
1944 assert(rv == 1);
1945 switch(ch) {
1946 case LockCommand:
1947 ch = LockDirectory(dirname, lockname);
1948 rv = write(fd, &ch, 1);
1949 assert(rv == 1);
1950 break;
1951 case UnlockCommand:
1953 ch = true; // Always succeeds
1954 rv = write(fd, &ch, 1);
1955 assert(rv == 1);
1956 break;
1957 case ExitCommand:
1958 close(fd);
1959 exit(0);
1960 default:
1961 assert(0);
1962 }
1963 }
1964}
1965#endif
1966
1967BOOST_AUTO_TEST_CASE(test_LockDirectory)
1968{
1969 fs::path dirname = m_args.GetDataDirBase() / "lock_dir";
1970 const std::string lockname = ".lock";
1971#ifndef WIN32
1972 // Revert SIGCHLD to default, otherwise boost.test will catch and fail on
1973 // it: there is BOOST_TEST_IGNORE_SIGCHLD but that only works when defined
1974 // at build-time of the boost library
1975 void (*old_handler)(int) = signal(SIGCHLD, SIG_DFL);
1976
1977 // Fork another process for testing before creating the lock, so that we
1978 // won't fork while holding the lock (which might be undefined, and is not
1979 // relevant as test case as that is avoided with -daemonize).
1980 int fd[2];
1981 BOOST_CHECK_EQUAL(socketpair(AF_UNIX, SOCK_STREAM, 0, fd), 0);
1982 pid_t pid = fork();
1983 if (!pid) {
1984 BOOST_CHECK_EQUAL(close(fd[1]), 0); // Child: close parent end
1985 TestOtherProcess(dirname, lockname, fd[0]);
1986 }
1987 BOOST_CHECK_EQUAL(close(fd[0]), 0); // Parent: close child end
1988#endif
1989 // Lock on non-existent directory should fail
1990 BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), false);
1991
1992 fs::create_directories(dirname);
1993
1994 // Probing lock on new directory should succeed
1995 BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true);
1996
1997 // Persistent lock on new directory should succeed
1998 BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), true);
1999
2000 // Another lock on the directory from the same thread should succeed
2001 BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), true);
2002
2003 // Another lock on the directory from a different thread within the same process should succeed
2004 bool threadresult;
2005 std::thread thr(TestOtherThread, dirname, lockname, &threadresult);
2006 thr.join();
2007 BOOST_CHECK_EQUAL(threadresult, true);
2008#ifndef WIN32
2009 // Try to acquire lock in child process while we're holding it, this should fail.
2010 char ch;
2011 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
2012 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
2013 BOOST_CHECK_EQUAL((bool)ch, false);
2014
2015 // Give up our lock
2017 // Probing lock from our side now should succeed, but not hold on to the lock.
2018 BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true);
2019
2020 // Try to acquire the lock in the child process, this should be successful.
2021 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
2022 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
2023 BOOST_CHECK_EQUAL((bool)ch, true);
2024
2025 // When we try to probe the lock now, it should fail.
2026 BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), false);
2027
2028 // Unlock the lock in the child process
2029 BOOST_CHECK_EQUAL(write(fd[1], &UnlockCommand, 1), 1);
2030 BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1);
2031 BOOST_CHECK_EQUAL((bool)ch, true);
2032
2033 // When we try to probe the lock now, it should succeed.
2034 BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true);
2035
2036 // Re-lock the lock in the child process, then wait for it to exit, check
2037 // successful return. After that, we check that exiting the process
2038 // has released the lock as we would expect by probing it.
2039 int processstatus;
2040 BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1);
2041 BOOST_CHECK_EQUAL(write(fd[1], &ExitCommand, 1), 1);
2042 BOOST_CHECK_EQUAL(waitpid(pid, &processstatus, 0), pid);
2043 BOOST_CHECK_EQUAL(processstatus, 0);
2044 BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true);
2045
2046 // Restore SIGCHLD
2047 signal(SIGCHLD, old_handler);
2048 BOOST_CHECK_EQUAL(close(fd[1]), 0); // Close our side of the socketpair
2049#endif
2050 // Clean up
2052 fs::remove_all(dirname);
2053}
2054
2055BOOST_AUTO_TEST_CASE(test_DirIsWritable)
2056{
2057 // Should be able to write to the data dir.
2058 fs::path tmpdirname = m_args.GetDataDirBase();
2059 BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true);
2060
2061 // Should not be able to write to a non-existent dir.
2062 tmpdirname = GetUniquePath(tmpdirname);
2063 BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), false);
2064
2065 fs::create_directory(tmpdirname);
2066 // Should be able to write to it now.
2067 BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true);
2068 fs::remove(tmpdirname);
2069}
2070
2072{
2073 BOOST_CHECK_EQUAL(ToLower('@'), '@');
2074 BOOST_CHECK_EQUAL(ToLower('A'), 'a');
2075 BOOST_CHECK_EQUAL(ToLower('Z'), 'z');
2076 BOOST_CHECK_EQUAL(ToLower('['), '[');
2078 BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff');
2079
2080 BOOST_CHECK_EQUAL(ToLower(""), "");
2081 BOOST_CHECK_EQUAL(ToLower("#HODL"), "#hodl");
2082 BOOST_CHECK_EQUAL(ToLower("\x00\xfe\xff"), "\x00\xfe\xff");
2083}
2084
2086{
2087 BOOST_CHECK_EQUAL(ToUpper('`'), '`');
2088 BOOST_CHECK_EQUAL(ToUpper('a'), 'A');
2089 BOOST_CHECK_EQUAL(ToUpper('z'), 'Z');
2090 BOOST_CHECK_EQUAL(ToUpper('{'), '{');
2092 BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff');
2093
2094 BOOST_CHECK_EQUAL(ToUpper(""), "");
2095 BOOST_CHECK_EQUAL(ToUpper("#hodl"), "#HODL");
2096 BOOST_CHECK_EQUAL(ToUpper("\x00\xfe\xff"), "\x00\xfe\xff");
2097}
2098
2099BOOST_AUTO_TEST_CASE(test_Capitalize)
2100{
2102 BOOST_CHECK_EQUAL(Capitalize("bitcoin"), "Bitcoin");
2103 BOOST_CHECK_EQUAL(Capitalize("\x00\xfe\xff"), "\x00\xfe\xff");
2104}
2105
2106static std::string SpanToStr(const Span<const char>& span)
2107{
2108 return std::string(span.begin(), span.end());
2109}
2110
2111BOOST_AUTO_TEST_CASE(test_spanparsing)
2112{
2113 using namespace spanparsing;
2114 std::string input;
2116 bool success;
2117
2118 // Const(...): parse a constant, update span to skip it if successful
2119 input = "MilkToastHoney";
2120 sp = input;
2121 success = Const("", sp); // empty
2122 BOOST_CHECK(success);
2123 BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney");
2124
2125 success = Const("Milk", sp);
2126 BOOST_CHECK(success);
2127 BOOST_CHECK_EQUAL(SpanToStr(sp), "ToastHoney");
2128
2129 success = Const("Bread", sp);
2130 BOOST_CHECK(!success);
2131
2132 success = Const("Toast", sp);
2133 BOOST_CHECK(success);
2134 BOOST_CHECK_EQUAL(SpanToStr(sp), "Honey");
2135
2136 success = Const("Honeybadger", sp);
2137 BOOST_CHECK(!success);
2138
2139 success = Const("Honey", sp);
2140 BOOST_CHECK(success);
2142
2143 // Func(...): parse a function call, update span to argument if successful
2144 input = "Foo(Bar(xy,z()))";
2145 sp = input;
2146
2147 success = Func("FooBar", sp);
2148 BOOST_CHECK(!success);
2149
2150 success = Func("Foo(", sp);
2151 BOOST_CHECK(!success);
2152
2153 success = Func("Foo", sp);
2154 BOOST_CHECK(success);
2155 BOOST_CHECK_EQUAL(SpanToStr(sp), "Bar(xy,z())");
2156
2157 success = Func("Bar", sp);
2158 BOOST_CHECK(success);
2159 BOOST_CHECK_EQUAL(SpanToStr(sp), "xy,z()");
2160
2161 success = Func("xy", sp);
2162 BOOST_CHECK(!success);
2163
2164 // Expr(...): return expression that span begins with, update span to skip it
2165 Span<const char> result;
2166
2167 input = "(n*(n-1))/2";
2168 sp = input;
2169 result = Expr(sp);
2170 BOOST_CHECK_EQUAL(SpanToStr(result), "(n*(n-1))/2");
2172
2173 input = "foo,bar";
2174 sp = input;
2175 result = Expr(sp);
2176 BOOST_CHECK_EQUAL(SpanToStr(result), "foo");
2177 BOOST_CHECK_EQUAL(SpanToStr(sp), ",bar");
2178
2179 input = "(aaaaa,bbbbb()),c";
2180 sp = input;
2181 result = Expr(sp);
2182 BOOST_CHECK_EQUAL(SpanToStr(result), "(aaaaa,bbbbb())");
2183 BOOST_CHECK_EQUAL(SpanToStr(sp), ",c");
2184
2185 input = "xyz)foo";
2186 sp = input;
2187 result = Expr(sp);
2188 BOOST_CHECK_EQUAL(SpanToStr(result), "xyz");
2189 BOOST_CHECK_EQUAL(SpanToStr(sp), ")foo");
2190
2191 input = "((a),(b),(c)),xxx";
2192 sp = input;
2193 result = Expr(sp);
2194 BOOST_CHECK_EQUAL(SpanToStr(result), "((a),(b),(c))");
2195 BOOST_CHECK_EQUAL(SpanToStr(sp), ",xxx");
2196
2197 // Split(...): split a string on every instance of sep, return vector
2198 std::vector<Span<const char>> results;
2199
2200 input = "xxx";
2201 results = Split(input, 'x');
2202 BOOST_CHECK_EQUAL(results.size(), 4U);
2203 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
2204 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "");
2205 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "");
2206 BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
2207
2208 input = "one#two#three";
2209 results = Split(input, '-');
2210 BOOST_CHECK_EQUAL(results.size(), 1U);
2211 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#two#three");
2212
2213 input = "one#two#three";
2214 results = Split(input, '#');
2215 BOOST_CHECK_EQUAL(results.size(), 3U);
2216 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one");
2217 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two");
2218 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three");
2219
2220 input = "*foo*bar*";
2221 results = Split(input, '*');
2222 BOOST_CHECK_EQUAL(results.size(), 4U);
2223 BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
2224 BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo");
2225 BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar");
2226 BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
2227}
2228
2229BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
2230{
2231 // ASCII and UTF-8 must pass through unaltered.
2232 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Valid log message貓"), "Valid log message貓");
2233 // Newlines must pass through unaltered.
2234 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Message\n with newlines\n"), "Message\n with newlines\n");
2235 // Other control characters are escaped in C syntax.
2236 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("\x01\x7f Corrupted log message\x0d"), R"(\x01\x7f Corrupted log message\x0d)");
2237 // Embedded NULL characters are escaped too.
2238 const std::string NUL("O\x00O", 3);
2239 BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)");
2240}
2241
2242namespace {
2243
2244struct Tracker
2245{
2247 const Tracker* origin;
2249 int copies;
2250
2251 Tracker() noexcept : origin(this), copies(0) {}
2252 Tracker(const Tracker& t) noexcept : origin(t.origin), copies(t.copies + 1) {}
2253 Tracker(Tracker&& t) noexcept : origin(t.origin), copies(t.copies) {}
2254 Tracker& operator=(const Tracker& t) noexcept
2255 {
2256 origin = t.origin;
2257 copies = t.copies + 1;
2258 return *this;
2259 }
2260};
2261
2262}
2263
2264BOOST_AUTO_TEST_CASE(test_tracked_vector)
2265{
2266 Tracker t1;
2267 Tracker t2;
2268 Tracker t3;
2269
2270 BOOST_CHECK(t1.origin == &t1);
2271 BOOST_CHECK(t2.origin == &t2);
2272 BOOST_CHECK(t3.origin == &t3);
2273
2274 auto v1 = Vector(t1);
2275 BOOST_CHECK_EQUAL(v1.size(), 1U);
2276 BOOST_CHECK(v1[0].origin == &t1);
2277 BOOST_CHECK_EQUAL(v1[0].copies, 1);
2278
2279 auto v2 = Vector(std::move(t2));
2280 BOOST_CHECK_EQUAL(v2.size(), 1U);
2281 BOOST_CHECK(v2[0].origin == &t2);
2282 BOOST_CHECK_EQUAL(v2[0].copies, 0);
2283
2284 auto v3 = Vector(t1, std::move(t2));
2285 BOOST_CHECK_EQUAL(v3.size(), 2U);
2286 BOOST_CHECK(v3[0].origin == &t1);
2287 BOOST_CHECK(v3[1].origin == &t2);
2288 BOOST_CHECK_EQUAL(v3[0].copies, 1);
2289 BOOST_CHECK_EQUAL(v3[1].copies, 0);
2290
2291 auto v4 = Vector(std::move(v3[0]), v3[1], std::move(t3));
2292 BOOST_CHECK_EQUAL(v4.size(), 3U);
2293 BOOST_CHECK(v4[0].origin == &t1);
2294 BOOST_CHECK(v4[1].origin == &t2);
2295 BOOST_CHECK(v4[2].origin == &t3);
2296 BOOST_CHECK_EQUAL(v4[0].copies, 1);
2297 BOOST_CHECK_EQUAL(v4[1].copies, 1);
2298 BOOST_CHECK_EQUAL(v4[2].copies, 0);
2299
2300 auto v5 = Cat(v1, v4);
2301 BOOST_CHECK_EQUAL(v5.size(), 4U);
2302 BOOST_CHECK(v5[0].origin == &t1);
2303 BOOST_CHECK(v5[1].origin == &t1);
2304 BOOST_CHECK(v5[2].origin == &t2);
2305 BOOST_CHECK(v5[3].origin == &t3);
2306 BOOST_CHECK_EQUAL(v5[0].copies, 2);
2307 BOOST_CHECK_EQUAL(v5[1].copies, 2);
2308 BOOST_CHECK_EQUAL(v5[2].copies, 2);
2309 BOOST_CHECK_EQUAL(v5[3].copies, 1);
2310
2311 auto v6 = Cat(std::move(v1), v3);
2312 BOOST_CHECK_EQUAL(v6.size(), 3U);
2313 BOOST_CHECK(v6[0].origin == &t1);
2314 BOOST_CHECK(v6[1].origin == &t1);
2315 BOOST_CHECK(v6[2].origin == &t2);
2316 BOOST_CHECK_EQUAL(v6[0].copies, 1);
2317 BOOST_CHECK_EQUAL(v6[1].copies, 2);
2318 BOOST_CHECK_EQUAL(v6[2].copies, 1);
2319
2320 auto v7 = Cat(v2, std::move(v4));
2321 BOOST_CHECK_EQUAL(v7.size(), 4U);
2322 BOOST_CHECK(v7[0].origin == &t2);
2323 BOOST_CHECK(v7[1].origin == &t1);
2324 BOOST_CHECK(v7[2].origin == &t2);
2325 BOOST_CHECK(v7[3].origin == &t3);
2326 BOOST_CHECK_EQUAL(v7[0].copies, 1);
2327 BOOST_CHECK_EQUAL(v7[1].copies, 1);
2328 BOOST_CHECK_EQUAL(v7[2].copies, 1);
2329 BOOST_CHECK_EQUAL(v7[3].copies, 0);
2330
2331 auto v8 = Cat(std::move(v2), std::move(v3));
2332 BOOST_CHECK_EQUAL(v8.size(), 3U);
2333 BOOST_CHECK(v8[0].origin == &t2);
2334 BOOST_CHECK(v8[1].origin == &t1);
2335 BOOST_CHECK(v8[2].origin == &t2);
2336 BOOST_CHECK_EQUAL(v8[0].copies, 0);
2337 BOOST_CHECK_EQUAL(v8[1].copies, 1);
2338 BOOST_CHECK_EQUAL(v8[2].copies, 0);
2339}
2340
2342{
2343 const std::array<unsigned char, 32> privkey_bytes = {
2344 // just some random data
2345 // derived address from this private key: 15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs
2346 0xD9, 0x7F, 0x51, 0x08, 0xF1, 0x1C, 0xDA, 0x6E,
2347 0xEE, 0xBA, 0xAA, 0x42, 0x0F, 0xEF, 0x07, 0x26,
2348 0xB1, 0xF8, 0x98, 0x06, 0x0B, 0x98, 0x48, 0x9F,
2349 0xA3, 0x09, 0x84, 0x63, 0xC0, 0x03, 0x28, 0x66
2350 };
2351
2352 const std::string message = "Trust no one";
2353
2354 const std::string expected_signature =
2355 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=";
2356
2357 CKey privkey;
2358 std::string generated_signature;
2359
2360 BOOST_REQUIRE_MESSAGE(!privkey.IsValid(),
2361 "Confirm the private key is invalid");
2362
2363 BOOST_CHECK_MESSAGE(!MessageSign(privkey, message, generated_signature),
2364 "Sign with an invalid private key");
2365
2366 privkey.Set(privkey_bytes.begin(), privkey_bytes.end(), true);
2367
2368 BOOST_REQUIRE_MESSAGE(privkey.IsValid(),
2369 "Confirm the private key is valid");
2370
2371 BOOST_CHECK_MESSAGE(MessageSign(privkey, message, generated_signature),
2372 "Sign with a valid private key");
2373
2374 BOOST_CHECK_EQUAL(expected_signature, generated_signature);
2375}
2376
2378{
2381 "invalid address",
2382 "signature should be irrelevant",
2383 "message too"),
2385
2388 "3B5fQsEXEaV8v6U3ejYc8XaKXAkyQj2MjV",
2389 "signature should be irrelevant",
2390 "message too"),
2392
2395 "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
2396 "invalid signature, not in base64 encoding",
2397 "message should be irrelevant"),
2399
2402 "1KqbBpLy5FARmTPD4VZnDDpYjkUvkr82Pm",
2403 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2404 "message should be irrelevant"),
2406
2409 "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
2410 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
2411 "I never signed this"),
2413
2416 "15CRxFdyRpGZLW9w8HnHvVduizdL5jKNbs",
2417 "IPojfrX2dfPnH26UegfbGQQLrdK844DlHq5157/P6h57WyuS/Qsl+h/WSVGDF4MUi4rWSswW38oimDYfNNUBUOk=",
2418 "Trust no one"),
2420
2423 "11canuhp9X2NocwCq7xNrQYTmUgZAnLK3",
2424 "IIcaIENoYW5jZWxsb3Igb24gYnJpbmsgb2Ygc2Vjb25kIGJhaWxvdXQgZm9yIGJhbmtzIAaHRtbCeDZINyavx14=",
2425 "Trust me"),
2427}
2428
2430{
2431 const std::string unsigned_tx = "...";
2432 const std::string prefixed_message =
2433 std::string(1, (char)MESSAGE_MAGIC.length()) +
2435 std::string(1, (char)unsigned_tx.length()) +
2436 unsigned_tx;
2437
2438 const uint256 signature_hash = Hash(unsigned_tx);
2439 const uint256 message_hash1 = Hash(prefixed_message);
2440 const uint256 message_hash2 = MessageHash(unsigned_tx);
2441
2442 BOOST_CHECK_EQUAL(message_hash1, message_hash2);
2443 BOOST_CHECK_NE(message_hash1, signature_hash);
2444}
2445
2447{
2448 BOOST_CHECK_EQUAL(RemovePrefix("./util/system.h", "./"), "util/system.h");
2449 BOOST_CHECK_EQUAL(RemovePrefix("foo", "foo"), "");
2450 BOOST_CHECK_EQUAL(RemovePrefix("foo", "fo"), "o");
2451 BOOST_CHECK_EQUAL(RemovePrefix("foo", "f"), "oo");
2452 BOOST_CHECK_EQUAL(RemovePrefix("foo", ""), "foo");
2453 BOOST_CHECK_EQUAL(RemovePrefix("fo", "foo"), "fo");
2454 BOOST_CHECK_EQUAL(RemovePrefix("f", "foo"), "f");
2455 BOOST_CHECK_EQUAL(RemovePrefix("", "foo"), "");
2456 BOOST_CHECK_EQUAL(RemovePrefix("", ""), "");
2457}
2458
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
static constexpr CAmount COIN
The amount of satoshis in one BTC.
Definition: amount.h:15
int flags
Definition: bitcoin-tx.cpp:525
#define Assert(val)
Identity function.
Definition: check.h:57
#define Assume(val)
Assume is the identity function.
Definition: check.h:72
const fs::path & GetDataDirBase() const
Get data directory path.
Definition: system.h:280
const std::set< std::string > GetUnsuitableSectionOnlyArgs() const
Log warnings for options in m_section_only_args when they are specified in the default section but no...
Definition: system.cpp:266
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: system.cpp:585
@ ALLOW_ANY
disable validation
Definition: system.h:166
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: system.cpp:542
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: system.cpp:624
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr) const
Write settings file.
Definition: system.cpp:565
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:308
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:487
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: system.h:437
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: system.cpp:608
void SelectConfigNetwork(const std::string &network)
Select the network in use.
Definition: system.cpp:302
void ClearPathCache()
Clear cached directory paths.
Definition: system.cpp:458
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:496
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:596
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: system.cpp:1030
RecursiveMutex cs_args
Definition: system.h:193
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:590
util::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: system.cpp:1023
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:869
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:602
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:642
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
Definition: system.cpp:989
static const std::string TESTNET
static const std::string SIGNET
static const std::string MAIN
Chain name strings.
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
Definition: hash.h:24
void Finalize(Span< unsigned char > output)
Definition: hash.h:30
CHash256 & Write(Span< const unsigned char > input)
Definition: hash.h:37
An encapsulated private key.
Definition: key.h:27
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:93
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:73
static const size_t OUTPUT_SIZE
Definition: sha256.h:21
Test GetSetting and GetArg type coercion, negation, and default value handling.
Definition: util_tests.cpp:245
void CheckValue(unsigned int flags, const char *arg, const Expect &expect)
Definition: util_tests.cpp:269
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
constexpr C * begin() const noexcept
Definition: span.h:170
constexpr C * end() const noexcept
Definition: span.h:171
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
Path class wrapper to prepare application code for transition from boost::filesystem library to std::...
Definition: fs.h:34
256-bit opaque blob.
Definition: uint256.h:124
std::string FormatSubVersion(const std::string &name, int nClientVersion, const std::vector< std::string > &comments)
Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip...
BOOST_AUTO_TEST_SUITE_END()
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
fs::path GetUniquePath(const fs::path &base)
Helper function for getting a unique path.
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:75
static void pool cs
@ ERR_MALFORMED_SIGNATURE
The provided signature couldn't be parsed (maybe invalid base64).
@ ERR_INVALID_ADDRESS
The provided address is invalid.
@ ERR_ADDRESS_NO_KEY
The provided address is valid but does not refer to a public key.
@ ERR_NOT_SIGNED
The message was not signed with the private key of the provided address.
@ OK
The message verification was successful.
@ ERR_PUBKEY_NOT_RECOVERED
A public key could not be recovered from the provided signature and message.
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
Definition: moneystr.cpp:41
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition: moneystr.cpp:15
std::string LogEscapeMessage(const std::string &str)
Belts and suspenders: make sure outgoing log messages don't contain potentially suspicious characters...
Definition: logging.cpp:235
static std::string PathToString(const path &path)
Convert path object to byte string.
Definition: fs.h:120
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:25
std::vector< Span< const char > > Split(const Span< const char > &sp, char sep)
Split a string on every instance of sep, returning a vector.
Definition: spanparsing.cpp:51
Span< const char > Expr(Span< const char > &sp)
Extract the expression that sp begins with.
Definition: spanparsing.cpp:32
bool Const(const std::string &str, Span< const char > &sp)
Parse a constant.
Definition: spanparsing.cpp:14
bool Func(const std::string &str, Span< const char > &sp)
Parse a function call.
Definition: spanparsing.cpp:23
#define BOOST_CHECK_THROW(stmt, excMatch)
Definition: object.cpp:19
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
const char * prefix
Definition: rest.cpp:714
const char * name
Definition: rest.cpp:43
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
@ ZEROS
Seed with a compile time constant of zeros.
static void SeedInsecureRand(SeedRand seed=SeedRand::SEED)
Definition: setup_common.h:56
static uint32_t InsecureRand32()
Definition: setup_common.h:65
constexpr auto MakeUCharSpan(V &&v) -> decltype(UCharSpanCast(MakeSpan(std::forward< V >(v))))
Like MakeSpan, but for (const) unsigned char member types only.
Definition: span.h:249
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.
Definition: str.h:32
std::string Capitalize(std::string str)
Capitalizes the first character of the given string.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::string FormatParagraph(const std::string &in, size_t width, size_t indent)
Format a paragraph of text to a fixed width, adding spaces for indentation to any added line.
bool ParseUInt16(const std::string &str, uint16_t *out)
Convert decimal string to unsigned 16-bit integer with strict parse error feedback.
std::string ToLower(const std::string &str)
Returns the lowercase equivalent of the given string.
bool ParseUInt64(const std::string &str, uint64_t *out)
Convert decimal string to unsigned 64-bit integer with strict parse error feedback.
std::vector< unsigned char > ParseHex(const char *psz)
bool ParseUInt32(const std::string &str, uint32_t *out)
Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
Parse number as fixed point according to JSON number syntax.
bool IsHex(const std::string &str)
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
bool IsHexNumber(const std::string &str)
Return true if the string is a hex number, optionally prefixed with "0x".
bool ParseInt64(const std::string &str, int64_t *out)
Convert string to signed 64-bit integer with strict parse error feedback.
std::string ToUpper(const std::string &str)
Returns the uppercase equivalent of the given string.
bool ParseUInt8(const std::string &str, uint8_t *out)
Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
Definition: strencodings.h:105
bool TimingResistantEqual(const T &a, const T &b)
Timing-attack-resistant comparison.
Definition: strencodings.h:205
@ SAFE_CHARS_UA_COMMENT
BIP-0014 subset.
Definition: strencodings.h:27
auto Join(const std::vector< T > &list, const BaseType &separator, UnaryOp unary_op) -> decltype(unary_op(list.at(0)))
Join a list of items.
Definition: string.h:44
std::string RemovePrefix(const std::string &str, const std::string &prefix)
Definition: string.h:28
std::string TrimString(const std::string &str, const std::string &pattern=" \f\n\r\t\v")
Definition: string.h:18
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:87
void ForEachMergeSetup(Fn &&fn)
Enumerate all possible test configurations.
Definition: util_tests.cpp:910
static constexpr int MAX_ACTIONS
Max number of actions to sequence together.
Definition: util_tests.cpp:903
std::vector< std::string > GetValues(const ActionList &actions, const std::string &section, const std::string &name, const std::string &value_prefix)
Translate actions into a list of <key>=setting strings.
Definition: util_tests.cpp:933
Action[MAX_ACTIONS] ActionList
Definition: util_tests.cpp:906
Basic testing setup.
Definition: setup_common.h:76
void ForEachMergeSetup(Fn &&fn)
Enumerate all possible test configurations.
Action[MAX_ACTIONS] ActionList
static constexpr int MAX_ACTIONS
Expect & List(std::vector< std::string > m)
Definition: util_tests.cpp:265
Expect(util::SettingsValue s)
Definition: util_tests.cpp:258
Expect & Bool(bool b)
Definition: util_tests.cpp:264
Expect & String(const char *s)
Definition: util_tests.cpp:262
std::optional< int64_t > int_value
Definition: util_tests.cpp:253
std::optional< std::vector< std::string > > list_value
Definition: util_tests.cpp:255
Expect & Error(const char *e)
Definition: util_tests.cpp:266
std::optional< bool > bool_value
Definition: util_tests.cpp:254
Expect & Int(int64_t i)
Definition: util_tests.cpp:263
util::SettingsValue setting
Definition: util_tests.cpp:248
const char * string_value
Definition: util_tests.cpp:252
std::string Parse(const char *arg)
Definition: util_tests.cpp:349
void SetupArgs(const std::vector< std::pair< std::string, unsigned int > > &args)
Definition: util_tests.cpp:229
void SetNetworkOnlyArg(const std::string arg)
Definition: util_tests.cpp:224
void ReadConfigString(const std::string str_config)
Definition: util_tests.cpp:213
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: system.cpp:1030
RecursiveMutex cs_args
Definition: system.h:193
util::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: system.cpp:1023
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:869
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
Definition: setup_common.h:116
Stored settings.
Definition: settings.h:31
std::map< std::string, SettingsValue > rw_settings
Map of setting name to read-write file setting value.
Definition: settings.h:37
#define LOCK(cs)
Definition: sync.h:226
#define TRY_LOCK(cs, name)
Definition: sync.h:230
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
#define ASSERT_DEBUG_LOG(message)
Definition: logging.h:39
static int count
Definition: tests.c:41
void UninterruptibleSleep(const std::chrono::microseconds &n)
Definition: time.cpp:22
int64_t GetTimeSeconds()
Returns the system time (not mockable)
Definition: time.cpp:127
std::string FormatISO8601Date(int64_t nTime)
Definition: time.cpp:145
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition: time.cpp:101
int64_t ParseISO8601DateTime(const std::string &str)
Definition: time.cpp:158
int64_t GetTime()
DEPRECATED Use either GetTimeSeconds (not mockable) or GetTime<T> (mockable)
Definition: time.cpp:26
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Definition: time.cpp:132
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
#define expect(bit)
uint256 MessageHash(const std::string &message)
Hashes a message for signing and verification in a manner that prevents inadvertently signing a trans...
Definition: message.cpp:72
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
Definition: message.cpp:56
const std::string MESSAGE_MAGIC
Text used to signify that a signed message follows and to prevent inadvertently signing a transaction...
Definition: message.cpp:22
MessageVerificationResult MessageVerify(const std::string &address, const std::string &signature, const std::string &message)
Verify a signed message.
Definition: message.cpp:24
bool LockDirectory(const fs::path &directory, const std::string lockfile_name, bool probe_only)
Definition: system.cpp:96
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:132
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: system.cpp:126
#define E
BOOST_FIXTURE_TEST_CASE(util_CheckValue, CheckValueTest)
Definition: util_tests.cpp:329
#define B
static void TestParse(const std::string &str, bool expected_bool, int64_t expected_int)
Definition: util_tests.cpp:425
static constexpr char ExitCommand
static constexpr char UnlockCommand
static void TestOtherProcess(fs::path dirname, std::string lockname, int fd)
static const unsigned char ParseHex_expected[65]
Definition: util_tests.cpp:110
static void RunToIntegralTests()
static const std::string STRING_WITH_EMBEDDED_NULL_CHAR
Definition: util_tests.cpp:41
static constexpr char LockCommand
BOOST_AUTO_TEST_CASE(util_datadir)
Definition: util_tests.cpp:50
static void TestOtherThread(fs::path dirname, std::string lockname, bool *result)
static std::string SpanToStr(const Span< const char > &span)
assert(!tx.IsCoinBase())
V Cat(V v1, V &&v2)
Concatenate two vectors, moving elements.
Definition: vector.h:31
std::vector< typename std::common_type< Args... >::type > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition: vector.h:20