1#include <test/jtx/TestSuite.h>
2#include <test/unit_test/FileDirGuard.h>
4#include <xrpld/core/Config.h>
6#include <xrpl/basics/FileUtilities.h>
7#include <xrpl/beast/unit_test/suite.h>
8#include <xrpl/config/BasicConfig.h>
9#include <xrpl/config/Constants.h>
10#include <xrpl/protocol/SystemParameters.h>
11#include <xrpl/server/Port.h>
13#include <boost/lexical_cast/bad_lexical_cast.hpp>
38 static constexpr char const* kConfigContentsTemplate = R
"xrpldConfig(
66#-------------------------------------------------------------------------------
71# This is primary persistent datastore for xrpld. This includes transaction
72# metadata, account states, and ledger headers. Helpful information can be
73# found on https://xrpl.org/capacity-planning.html#node-db-type
74# delete old ledgers while maintaining at least 2000. Do not require an
75# external administrative command to initiate deletion.
78path=/Users/dummy/xrpld/config/db/rocksdb
89# This needs to be an absolute directory reference, not a relative one.
90# Modify this value as required.
92/Users/dummy/xrpld/config/log/debug.log
100# Where to find some other servers speaking the XRPL protocol.
105# Turn down default logging to save disk space in the long run.
106# Valid values here are trace, debug, info, warning, error, and fatal
108{{ "command": "log_level", "severity": "warning" }}
110# Defaults to 1 ("yes") so that certificates will be validated. To allow the use
111# of self-signed certificates for development or internal use, set to 0 ("no").
119 std::string dbPathSection = dbPath.empty() ? "" :
"[database_path]\n" + dbPath;
121 validatorsFile.
empty() ?
"" :
"[validators_file]\n" + validatorsFile;
122 return std::format(kConfigContentsTemplate, dbPathSection, valFileSection);
138envVar(
char const* name)
140 if (
char const*
const value =
std::getenv(name); value !=
nullptr)
166 setenv(name, value->c_str(), 1);
182 : name_(name), saved_(envVar(name))
187 EnvVarGuard(EnvVarGuard
const&) =
delete;
189 operator=(EnvVarGuard
const&) =
delete;
221 bool useCounter =
true,
271 using namespace std::filesystem;
275 catch (std::exception& e)
288n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
289n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
290n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
291n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
292n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
295nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
296nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
297nHUPDdcdb2Y5DZAJne4c2iabFuAP3F34xZUgYQT2NH7qfkdapgnz
299[validator_list_sites]
300recommended-xrpl-validators.com
301more-xrpl-validators.net
30403E74EE14CB525AFBB9F1B7D86CD58ECC4B91452294B42AB4E78F260BD905C091D
305030775A669685BD6ABCEBD80385921C7851783D991A8055FD21D2F3966C96F1B56
307[validator_list_threshold]
320 beast::unit_test::Suite& test,
322 Path const& validatorsFileName,
323 bool useCounter =
true)
327 Path(validatorsFileName.
empty() ? Config::kValidatorsFileName : validatorsFileName),
339 [[nodiscard]] std::string
379 BEAST_EXPECT(c.
legacy(
"not_in_file").empty());
380 c.
legacy(
"not_in_file",
"new_value");
381 BEAST_EXPECT(c.
legacy(
"not_in_file") ==
"new_value");
395 for (
auto const& configFile : configFiles)
400 Path const f = td.file(std::string{configFile});
401 std::ofstream o(f.string());
407 c.
setup(
"",
true,
false,
true);
411 "/Users/dummy/xrpld/config/log/debug.log");
417 auto const home = detail::envVar(
"HOME");
418 auto const xdgConfigHome = detail::envVar(
"XDG_CONFIG_HOME");
420 for (
auto const& configFile : configFiles)
435 detail::EnvVarGuard
const homeGuard(
"HOME", tc.path());
436 detail::EnvVarGuard
const xdgGuard(
"XDG_CONFIG_HOME", tc.path());
441 p = tc.file(
systemName() +
"/" + std::string{configFile});
442 std::ofstream o(p.string());
448 c.setup(
"",
true,
false,
true);
452 "/Users/dummy/xrpld/config/log/debug.log");
456 BEAST_EXPECT(detail::envVar(
"HOME") == home);
457 BEAST_EXPECT(detail::envVar(
"XDG_CONFIG_HOME") == xdgConfigHome);
466 detail::EnvVarGuard
const homeGuard(
"HOME", tc.path());
467 detail::EnvVarGuard
const xdgGuard(
"XDG_CONFIG_HOME", std::nullopt);
470 std::string s =
".config";
476 p = tc.file(s +
"/" + std::string{configFile});
477 std::ofstream o(p.string());
483 c.setup(
"",
true,
false,
true);
487 "/Users/dummy/xrpld/config/log/debug.log");
491 BEAST_EXPECT(detail::envVar(
"HOME") == home);
492 BEAST_EXPECT(detail::envVar(
"XDG_CONFIG_HOME") == xdgConfigHome);
506 constexpr char const* cc =
"[database_path]\n{}\n";
509 Path const dataDirRel(
"test_data_dir");
510 Path const dataDirAbs(cwd / dataDirRel);
514 c.loadFromString(
std::format(cc, dataDirAbs.string()));
520 c.loadFromString(
std::format(cc, dataDirRel.string()));
528 c.loadFromString(
"");
535 detail::DirGuard
const g0(*
this,
"test_db");
536 Path const dataDirRel(
"test_data_dir");
537 Path const dataDirAbs(cwd / g0.subdir() / dataDirRel);
538 detail::FileCfgGuard
const g(
540 auto const& c(g.config());
541 BEAST_EXPECT(g.dataDirExists());
542 BEAST_EXPECT(g.configFileExists());
547 std::string
const dbPath(
"my_db");
549 auto const& c(g.config());
550 std::string
const nativeDbPath =
absolute(
Path(dbPath)).string();
551 BEAST_EXPECT(g.dataDirExists());
552 BEAST_EXPECT(g.configFileExists());
558 auto const& c(g.config());
559 std::string
const nativeDbPath =
561 BEAST_EXPECT(g.dataDirExists());
562 BEAST_EXPECT(g.configFileExists());
575 "eyJ2YWxpZGF0aW9uX3ByaXZhdGVfa2V5IjoiOWVkNDVmODY2MjQxY2MxOGEyNzQ3Yj"
576 "U0Mzg3YzA2MjU5MDc5NzJmNGU3MTkwMjMxZmFhOTM3NDU3ZmE5ZGFmNiIsIm1hbmlm"
577 "ZXN0IjoiSkFBQUFBRnhJZTFGdHdtaW12R3RIMmlDY01KcUM5Z1ZGS2lsR2Z3MS92Q3"
578 "hIWFhMcGxjMkduTWhBa0UxYWdxWHhCd0R3RGJJRDZPTVNZdU0wRkRBbHBBZ05rOFNL"
579 "Rm43TU8yZmRrY3dSUUloQU9uZ3U5c0FLcVhZb3VKK2wyVjBXK3NBT2tWQitaUlM2UF"
580 "NobEpBZlVzWGZBaUJzVkpHZXNhYWRPSmMvYUFab2tTMXZ5bUdtVnJsSFBLV1gzWXl3"
581 "dTZpbjhIQVNRS1B1Z0JENjdrTWFSRkd2bXBBVEhsR0tKZHZERmxXUFl5NUFxRGVkRn"
582 "Y1VEphMncwaTIxZXEzTVl5d0xWSlpuRk9yN0Mwa3cyQWlUelNDakl6ZGl0UTg9In0"
587 static constexpr char const* kConfigTemplate = R
"xrpldConfig(
595 auto const expectedError =
596 "Cannot have both [validation_seed] "
597 "and [validator_token] config sections";
606 BEAST_EXPECT(error == expectedError);
618 c.loadFromString(R
"xrpldConfig(
623 catch (std::runtime_error
const& e)
628 BEAST_EXPECT(error.
empty());
629 BEAST_EXPECT(c.networkId == 0);
633 c.loadFromString(R
"xrpldConfig(
636 catch (std::runtime_error
const& e)
641 BEAST_EXPECT(error.
empty());
642 BEAST_EXPECT(c.networkId == 0);
646 c.loadFromString(R
"xrpldConfig(
651 catch (std::runtime_error
const& e)
656 BEAST_EXPECT(error.
empty());
657 BEAST_EXPECT(c.networkId == 255);
661 c.loadFromString(R
"xrpldConfig(
671 BEAST_EXPECT(error.
empty());
672 BEAST_EXPECT(c.networkId == 10000);
680 using namespace std::filesystem;
683 constexpr char const* cc =
"[validators_file]\n{}\n";
685 std::string
const missingPath =
"/no/way/this/path/exists";
686 auto const expectedError =
687 "The file specified in [validators_file] does not exist: " + missingPath;
693 catch (std::runtime_error
const& e)
697 BEAST_EXPECT(error == expectedError);
701 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.cfg");
703 constexpr char const* cc =
"[validators_file]\n{}\n";
705 auto const expectedError =
706 "Invalid file specified in [validators_file]: " + invalidFile.
string();
710 c.loadFromString(
std::format(cc, invalidFile.string()));
712 catch (std::runtime_error
const& e)
716 BEAST_EXPECT(error == expectedError);
721 std::string
const toLoad(R
"xrpldConfig(
723n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
724n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
725n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
728nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
729nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
731 c.loadFromString(toLoad);
734 BEAST_EXPECT(c.validatorListThreshold == std::nullopt);
739 std::string
const toLoad(R
"xrpldConfig(
740[validator_list_sites]
742trust-these-validators.gov
745021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
747[validator_list_threshold]
750 c.loadFromString(toLoad);
756 "trust-these-validators.gov");
760 "021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801"
764 BEAST_EXPECT(c.validatorListThreshold == std::size_t(1));
769 std::string
const toLoad(R
"xrpldConfig(
770[validator_list_sites]
772trust-these-validators.gov
775021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
777[validator_list_threshold]
780 c.loadFromString(toLoad);
786 "trust-these-validators.gov");
790 "021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801"
794 BEAST_EXPECT(c.validatorListThreshold == std::nullopt);
800 std::string
const toLoad(R
"xrpldConfig(
801[validator_list_sites]
803trust-these-validators.gov
806021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
808[validator_list_threshold]
812 auto const expectedError =
813 "Value in config section [validator_list_threshold] exceeds "
814 "the number of configured list keys";
817 c.loadFromString(toLoad);
820 catch (std::runtime_error
const& e)
824 BEAST_EXPECT(error == expectedError);
829 std::string
const toLoad(R
"xrpldConfig(
830[validator_list_sites]
832trust-these-validators.gov
835021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
837[validator_list_threshold]
841 auto const expectedError =
842 "Config section [validator_list_threshold] should contain "
846 c.loadFromString(toLoad);
849 catch (std::runtime_error
const& e)
853 BEAST_EXPECT(error == expectedError);
858 std::string
const toLoad(R
"xrpldConfig(
859[validator_list_sites]
861trust-these-validators.gov
864021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
866[validator_list_threshold]
872 c.loadFromString(toLoad);
875 catch (std::bad_cast& e)
885 std::string
const toLoad(R
"xrpldConfig(
886[validator_list_sites]
888trust-these-validators.gov
891 auto const expectedError =
"[validator_list_keys] config section is missing";
894 c.loadFromString(toLoad);
897 catch (std::runtime_error
const& e)
901 BEAST_EXPECT(error == expectedError);
905 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.cfg");
906 BEAST_EXPECT(vtg.validatorsFileExists());
908 constexpr char const* cc =
"[validators_file]\n{}\n";
909 c.loadFromString(
std::format(cc, vtg.validatorsFile()));
915 BEAST_EXPECT(c.validatorListThreshold == 2);
920 std::string
const valFileName =
"validators.txt";
921 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg", valFileName);
922 detail::FileCfgGuard
const rcg(
924 BEAST_EXPECT(vtg.validatorsFileExists());
925 BEAST_EXPECT(rcg.configFileExists());
926 auto const& c(rcg.config());
932 BEAST_EXPECT(c.validatorListThreshold == 2);
937 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.txt");
938 auto const valFilePath =
".." / vtg.subdir() /
"validators.txt";
939 detail::FileCfgGuard
const rcg(
941 BEAST_EXPECT(vtg.validatorsFileExists());
942 BEAST_EXPECT(rcg.configFileExists());
943 auto const& c(rcg.config());
949 BEAST_EXPECT(c.validatorListThreshold == 2);
953 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.txt");
954 detail::FileCfgGuard
const rcg(
956 BEAST_EXPECT(vtg.validatorsFileExists());
957 BEAST_EXPECT(rcg.configFileExists());
958 auto const& c(rcg.config());
964 BEAST_EXPECT(c.validatorListThreshold == 2);
970 BEAST_EXPECT(vtg.validatorsFileExists());
972 *
this, vtg.subdir(),
"validators.txt",
false);
973 BEAST_EXPECT(vtgDefault.validatorsFileExists());
976 BEAST_EXPECT(rcg.configFileExists());
977 auto const& c(rcg.config());
983 BEAST_EXPECT(c.validatorListThreshold == 2);
988 constexpr char const* cc = R
"xrpldConfig(
993n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
994n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
995n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
996n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
997n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
1000nHB1X37qrniVugfQcuBTAjswphC1drx7QjFFojJPZwKHHnt8kU7v
1001nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
1003[validator_list_sites]
1005trust-these-validators.gov
1007[validator_list_keys]
1008021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
1010 detail::ValidatorsTxtGuard const vtg(*
this,
"test_cfg",
"validators.cfg");
1011 BEAST_EXPECT(vtg.validatorsFileExists());
1013 c.loadFromString(
std::format(cc, vtg.validatorsFile()));
1019 BEAST_EXPECT(c.validatorListThreshold == 2);
1024 constexpr char const* cc = R
"xrpldConfig(
1028[validator_list_threshold]
1032 detail::ValidatorsTxtGuard const vtg(*
this,
"test_cfg",
"validators.cfg");
1033 BEAST_EXPECT(vtg.validatorsFileExists());
1034 auto const expectedError =
1035 "Config section [validator_list_threshold] should contain "
1036 "single value only";
1040 c.loadFromString(
std::format(cc, vtg.validatorsFile()));
1043 catch (std::runtime_error
const& e)
1047 BEAST_EXPECT(error == expectedError);
1054 constexpr char const* cc =
"[validators_file]\n{}\n";
1056 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.cfg");
1057 BEAST_EXPECT(vtg.validatorsFileExists());
1058 auto const expectedError =
1059 "The file specified in [validators_file] does not contain a "
1060 "[validators], [validator_keys] or [validator_list_keys] "
1062 vtg.validatorsFile();
1063 std::ofstream
const o(vtg.validatorsFile());
1067 c2.loadFromString(
std::format(cc, vtg.validatorsFile()));
1069 catch (std::runtime_error
const& e)
1073 BEAST_EXPECT(error == expectedError);
1093 BEAST_EXPECT(!config.
quiet());
1094 BEAST_EXPECT(!config.
silent());
1106 BEAST_EXPECT(config.
quiet());
1107 BEAST_EXPECT(!config.
silent());
1119 BEAST_EXPECT(config.quiet());
1120 BEAST_EXPECT(config.silent());
1121 BEAST_EXPECT(!config.standalone());
1122 BEAST_EXPECT(config.ledgerHistory == 256);
1132 BEAST_EXPECT(config.
quiet());
1133 BEAST_EXPECT(config.
silent());
1145 BEAST_EXPECT(!config.quiet());
1146 BEAST_EXPECT(!config.silent());
1147 BEAST_EXPECT(config.standalone());
1148 BEAST_EXPECT(config.ledgerHistory == 0);
1158 BEAST_EXPECT(config.
quiet());
1159 BEAST_EXPECT(!config.
silent());
1171 BEAST_EXPECT(config.quiet());
1172 BEAST_EXPECT(config.silent());
1173 BEAST_EXPECT(config.standalone());
1174 BEAST_EXPECT(config.ledgerHistory == 0);
1184 BEAST_EXPECT(config.quiet());
1185 BEAST_EXPECT(config.silent());
1186 BEAST_EXPECT(config.standalone());
1187 BEAST_EXPECT(config.ledgerHistory == 0);
1196 auto const& conf = cfg.
config();
1204 BEAST_EXPECT(
rpc.adminNetsV4.size() +
rpc.adminNetsV6.size() == 2);
1221 BEAST_EXPECT(
false);
1236 std::string
const toLoad(
1259 cfg.loadFromString(toLoad);
1299 anotherserversansport
1300 anotherserverwithport:12
1310 2001:db8:3333:4444:5555:6666:7777:8888:12345
1311 [2001:db8:3333:4444:5555:6666:7777:8888]:1
1315 cfg.loadFromString(toLoad);
1326 BEAST_EXPECT(cfg.ips[0] == "r.ripple.com 51235");
1328 BEAST_EXPECT(cfg.ipsFixed[0] ==
"s1.ripple.com 51235");
1329 BEAST_EXPECT(cfg.ipsFixed[1] ==
"s2.ripple.com 51235");
1330 BEAST_EXPECT(cfg.ipsFixed[2] ==
"anotherserversansport");
1331 BEAST_EXPECT(cfg.ipsFixed[3] ==
"anotherserverwithport 12");
1332 BEAST_EXPECT(cfg.ipsFixed[4] ==
"1.1.1.1 1");
1333 BEAST_EXPECT(cfg.ipsFixed[5] ==
"1.1.1.1 1");
1334 BEAST_EXPECT(cfg.ipsFixed[6] ==
"12.34.12.123 12345");
1335 BEAST_EXPECT(cfg.ipsFixed[7] ==
"12.34.12.123 12345");
1338 BEAST_EXPECT(cfg.ipsFixed[8] ==
"::");
1339 BEAST_EXPECT(cfg.ipsFixed[9] ==
"2001:db8::");
1340 BEAST_EXPECT(cfg.ipsFixed[10] ==
"::1");
1341 BEAST_EXPECT(cfg.ipsFixed[11] ==
"::1:12345");
1342 BEAST_EXPECT(cfg.ipsFixed[12] ==
"[::1]:12345");
1343 BEAST_EXPECT(cfg.ipsFixed[13] ==
"2001:db8:3333:4444:5555:6666:7777:8888:12345");
1344 BEAST_EXPECT(cfg.ipsFixed[14] ==
"[2001:db8:3333:4444:5555:6666:7777:8888]:1");
1350 struct TestCommentData
1359 {{.line =
"password = aaaa\\#bbbb",
1360 .field =
"password",
1361 .expect =
"aaaa#bbbb",
1362 .hadComment =
false},
1363 {.line =
"password = aaaa#bbbb",
1364 .field =
"password",
1366 .hadComment =
true},
1367 {.line =
"password = aaaa #bbbb",
1368 .field =
"password",
1370 .hadComment =
true},
1372 {.line =
"password = #aaaa #bbbb",
1374 .expect =
"password =",
1375 .hadComment =
true},
1376 {.line =
"password = aaaa\\# #bbbb",
1377 .field =
"password",
1379 .hadComment =
true},
1380 {.line =
"password = aaaa\\##bbbb",
1381 .field =
"password",
1383 .hadComment =
true},
1384 {.line =
"aaaa#bbbb", .field =
"", .expect =
"aaaa", .hadComment =
true},
1385 {.line =
"aaaa\\#bbbb", .field =
"", .expect =
"aaaa#bbbb", .hadComment =
false},
1386 {.line =
"aaaa\\##bbbb", .field =
"", .expect =
"aaaa#", .hadComment =
true},
1387 {.line =
"aaaa #bbbb", .field =
"", .expect =
"aaaa", .hadComment =
true},
1388 {.line =
"1 #comment", .field =
"", .expect =
"1", .hadComment =
true},
1389 {.line =
"#whole thing is comment", .field =
"", .expect =
"", .hadComment =
false},
1390 {.line =
" #whole comment with space",
1393 .hadComment =
false}}};
1395 for (
auto const& t : tests)
1398 s.
append(std::string(t.line));
1399 BEAST_EXPECT(s.hadTrailingComments() == t.hadComment);
1400 if (t.field.empty())
1402 BEAST_EXPECTS(s.legacy() == t.expect, s.legacy());
1407 BEAST_EXPECTS(
set(field, std::string(t.field), s), t.line);
1408 BEAST_EXPECTS(field == t.expect, t.line);
1414 s.append(
"online_delete = 3000");
1415 std::uint32_t od = 0;
1423 s.append(
"online_delete = 2000 #my comment on this");
1424 std::uint32_t od = 0;
1434 using namespace std::string_literals;
1436 s.
append(
"a_string = mystring");
1437 s.
append(
"positive_int = 2");
1438 s.
append(
"negative_int = -3");
1439 s.
append(
"bool_ish = 1");
1442 auto val1 =
"value 1"s;
1443 BEAST_EXPECT(
set(val1,
"a_string", s));
1444 BEAST_EXPECT(val1 ==
"mystring");
1446 auto val2 =
"value 2"s;
1447 BEAST_EXPECT(!
set(val2,
"not_a_key", s));
1448 BEAST_EXPECT(val2 ==
"value 2");
1449 BEAST_EXPECT(!
set(val2,
"default"s,
"not_a_key", s));
1450 BEAST_EXPECT(val2 ==
"default");
1453 BEAST_EXPECT(val3 ==
"mystring");
1455 BEAST_EXPECT(val4.empty());
1457 BEAST_EXPECT(val5 ==
"default");
1459 auto val6 =
"value 6"s;
1461 BEAST_EXPECT(val6 ==
"mystring");
1463 auto val7 =
"value 7"s;
1465 BEAST_EXPECT(val7 ==
"value 7");
1470 BEAST_EXPECT(
set(val1,
"positive_int", s));
1471 BEAST_EXPECT(val1 == 2);
1474 BEAST_EXPECT(
set(val2,
"negative_int", s));
1475 BEAST_EXPECT(val2 == -3);
1478 BEAST_EXPECT(!
set(val3,
"a_string", s));
1479 BEAST_EXPECT(val3 == 3);
1481 auto val4 =
get<int>(s,
"positive_int");
1482 BEAST_EXPECT(val4 == 2);
1483 auto val5 =
get<int>(s,
"not_a_key");
1484 BEAST_EXPECT(val5 == 0);
1485 auto val6 =
get<int>(s,
"not_a_key", 5);
1486 BEAST_EXPECT(val6 == 5);
1487 auto val7 =
get<int>(s,
"a_string", 6);
1488 BEAST_EXPECT(val7 == 6);
1491 BEAST_EXPECT(
getIfExists(s,
"positive_int", val8));
1492 BEAST_EXPECT(val8 == 2);
1496 BEAST_EXPECT(val9 == 9);
1500 BEAST_EXPECT(val10 == 10);
1502 BEAST_EXPECT(s.
get<
int>(
"not_a_key") == std::nullopt);
1505 [[maybe_unused]]
auto _ = s.
get<
int>(
"a_string");
1508 catch (boost::bad_lexical_cast&)
1517 BEAST_EXPECT(flag1 ==
true);
1520 BEAST_EXPECT(!
getIfExists(s,
"not_a_key", flag2));
1521 BEAST_EXPECT(flag2 ==
false);
1532 std::uint32_t numSeconds;
1533 std::uint32_t configVal;
1537 std::vector<ConfigUnit>
const units = {
1538 {.unit =
"seconds", .numSeconds = 1, .configVal = 15 * 60, .shouldPass =
false},
1539 {.unit =
"minutes", .numSeconds = 60, .configVal = 14, .shouldPass =
false},
1540 {.unit =
"minutes", .numSeconds = 60, .configVal = 15, .shouldPass =
true},
1541 {.unit =
"hours", .numSeconds = 3600, .configVal = 10, .shouldPass =
true},
1542 {.unit =
"days", .numSeconds = 86400, .configVal = 10, .shouldPass =
true},
1543 {.unit =
"weeks", .numSeconds = 604800, .configVal = 2, .shouldPass =
true},
1544 {.unit =
"months", .numSeconds = 2592000, .configVal = 1, .shouldPass =
false},
1545 {.unit =
"years", .numSeconds = 31536000, .configVal = 1, .shouldPass =
false}};
1548 for (
auto& [unit, sec, val, shouldPass] : units)
1551 std::string toLoad(R
"xrpldConfig(
1552[amendment_majority_time]
1560 c.loadFromString(toLoad);
1563 BEAST_EXPECT(c.amendmentMajorityTime.count() == val * sec);
1570 catch (std::runtime_error
const&)
1603 BEAST_EXPECT(!testUnknown(
"none"));
1604 BEAST_EXPECT(!testUnknown(
"0.5"));
1605 BEAST_EXPECT(!testUnknown(
"180 seconds"));
1606 BEAST_EXPECT(!testUnknown(
"9 minutes"));
1609 BEAST_EXPECT(!testUnknown(
"299"));
1613 BEAST_EXPECT(testUnknown(
"301") == std::chrono::seconds{301});
1614 BEAST_EXPECT(testUnknown(
"1799") == std::chrono::seconds{1799});
1615 BEAST_EXPECT(testUnknown(
"1800") == std::chrono::seconds{1800});
1618 BEAST_EXPECT(!testUnknown(
"1801"));
1620 testcase(
"overlay: diverged time");
1623 auto testDiverged = [](std::string value) -> std::optional<std::chrono::seconds> {
1627 c.loadFromString(
"[overlay]\nmax_diverged_time=" + value);
1628 return c.maxDivergedTime;
1630 catch (std::runtime_error
const&)
1637 BEAST_EXPECT(!testDiverged(
"none"));
1638 BEAST_EXPECT(!testDiverged(
"0.5"));
1639 BEAST_EXPECT(!testDiverged(
"180 seconds"));
1640 BEAST_EXPECT(!testDiverged(
"9 minutes"));
1643 BEAST_EXPECT(!testDiverged(
"0"));
1644 BEAST_EXPECT(!testDiverged(
"59"));
1647 BEAST_EXPECT(testDiverged(
"60") == std::chrono::seconds{60});
1648 BEAST_EXPECT(testDiverged(
"61") == std::chrono::seconds{61});
1649 BEAST_EXPECT(testDiverged(
"899") == std::chrono::seconds{899});
1650 BEAST_EXPECT(testDiverged(
"900") == std::chrono::seconds{900});
1653 BEAST_EXPECT(!testDiverged(
"901"));
1655 testcase(
"overlay: manifest counts");
1659 auto testCount = [](std::string
const& key,
1660 std::string
const& value) -> std::optional<std::size_t> {
1664 c.loadFromString(
"[overlay]\n" + key +
"=" + value);
1665 return key ==
"max_trusted_count" ? c.maxTrustedCount : c.maxUntrustedCount;
1667 catch (std::runtime_error
const&)
1673 for (
auto const* key : {
"max_untrusted_count",
"max_trusted_count"})
1677 BEAST_EXPECT(!testCount(key,
"none"));
1678 BEAST_EXPECT(!testCount(key,
"0.5"));
1679 BEAST_EXPECT(!testCount(key,
"400 manifests"));
1680 BEAST_EXPECT(!testCount(key,
"-1"));
1683 BEAST_EXPECT(!testCount(key,
"0"));
1684 BEAST_EXPECT(!testCount(key,
"49"));
1687 BEAST_EXPECT(testCount(key,
"50") == 50);
1688 BEAST_EXPECT(testCount(key,
"51") == 51);
1689 BEAST_EXPECT(testCount(key,
"300") == 300);
1690 BEAST_EXPECT(testCount(key,
"400") == 400);
1691 BEAST_EXPECT(testCount(key,
"999") == 999);
1692 BEAST_EXPECT(testCount(key,
"1000") == 1000);
1695 BEAST_EXPECT(!testCount(key,
"1001"));
1701 c.loadFromString(
"[overlay]\nmax_untrusted_count=500");
1702 BEAST_EXPECT(c.maxUntrustedCount == 500);
1703 BEAST_EXPECT(!c.maxTrustedCount);
1707 c.loadFromString(
"[overlay]\nmax_trusted_count=500");
1708 BEAST_EXPECT(c.maxTrustedCount == 500);
1709 BEAST_EXPECT(!c.maxUntrustedCount);
1715 c.loadFromString(
"[overlay]\nmax_untrusted_count=250\nmax_trusted_count=750");
1716 BEAST_EXPECT(c.maxUntrustedCount == 250);
1717 BEAST_EXPECT(c.maxTrustedCount == 750);
1723 c.loadFromString(
"[overlay]\nip_limit=64");
1724 BEAST_EXPECT(!c.maxUntrustedCount);
1725 BEAST_EXPECT(!c.maxTrustedCount);
1731 c.loadFromString(
"");
1732 BEAST_EXPECT(!c.maxUntrustedCount);
1733 BEAST_EXPECT(!c.maxTrustedCount);
bool unexcept(F &&f, String const &reason)
void pass()
Record a successful test condition.
void fail(String const &reason, char const *file, int line)
Record a failure.
LogOs< char > log
Logging output stream.
TestcaseT testcase
Memberspace for declaring test cases.
void legacy(std::string const §ion, std::string value)
Set a value that is not a key/value pair.
void testSetup(bool explicitPath)
void run() override
Runs the suite.
void testValidatorsFile()
std::filesystem::path Path
static constexpr std::string_view kConfigLegacyName
static constexpr std::string_view kDatabaseDirName
static constexpr std::string_view kConfigFileName
void setup(std::string const &strConf, bool bQuiet, bool bSilent, bool bStandalone)
std::chrono::seconds maxUnknownTime
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
std::uint32_t ledgerHistory
Holds a collection of configuration values.
std::optional< T > get(std::string const &name) const
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
bool expectException(Functor f, std::string const &message="")
auto rmDir(Path const &toRm)
beast::unit_test::Suite & test_
Path const & subdir() const
std::filesystem::path Path
Write an xrpld config file and remove when done.
Config const & config() const
std::string configFile() const
bool configFileExists() const
FileCfgGuard(beast::unit_test::Suite &test, Path subDir, Path const &dbPath, Path const &configFile, Path const &validatorsFile, bool useCounter=true, std::string confContents="")
bool dataDirExists() const
Write a file in a directory and remove when done.
Path const & file() const
FileDirGuard(beast::unit_test::Suite &test, Path subDir, Path file, std::string const &contents, bool useCounter=true, bool create=true)
Write a validators.txt file and remove when done.
std::string validatorsFile() const
bool validatorsFileExists() const
~ValidatorsTxtGuard()=default
ValidatorsTxtGuard(beast::unit_test::Suite &test, Path subDir, Path const &validatorsFileName, bool useCounter=true)
T create_directory(T... args)
T current_path(T... args)
T is_directory(T... args)
std::string valFileContents()
std::string configContents(std::string const &dbPath, std::string const &validatorsFile)
API version numbers used in later API versions.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool set(T &target, std::string const &name, Section const §ion)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
ApplyResult apply(ServiceRegistry ®istry, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
void parsePort(ParsedPort &port, Section const §ion, std::ostream &log)
T get(Section const §ion, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
bool getIfExists(Section const §ion, std::string const &name, T &v)
static std::string const & systemName()
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, xrpl)
static std::optional< Seed > validationSeed(json::Value const ¶ms)
T regex_replace(T... args)
static constexpr auto kOnlineDelete
std::vector< boost::asio::ip::network_v4 > adminNetsV4
std::vector< boost::asio::ip::network_v6 > adminNetsV6
static constexpr auto kIps
static constexpr auto kPortWssAdmin
static constexpr auto kValidatorListThreshold
static constexpr auto kValidators
static constexpr auto kValidatorListKeys
static constexpr auto kServer
static constexpr auto kPortRpc
static constexpr auto kSslVerify
static constexpr auto kValidatorsFile
static constexpr auto kIpsFixed
static constexpr auto kDatabasePath
static constexpr auto kDebugLogfile
static constexpr auto kValidatorListSites