1#include <test/jtx/TestSuite.h>
2#include <test/unit_test/FileDirGuard.h>
4#include <xrpld/core/Config.h>
6#include <xrpl/beast/unit_test/suite.h>
7#include <xrpl/beast/utility/temp_dir.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/filesystem/operations.hpp>
14#include <boost/format.hpp>
15#include <boost/format/free_funcs.hpp>
16#include <boost/lexical_cast/bad_lexical_cast.hpp>
39 static boost::format kConfigContentsTemplate(R
"xrpldConfig(
67#-------------------------------------------------------------------------------
72# This is primary persistent datastore for xrpld. This includes transaction
73# metadata, account states, and ledger headers. Helpful information can be
74# found on https://xrpl.org/capacity-planning.html#node-db-type
75# delete old ledgers while maintaining at least 2000. Do not require an
76# external administrative command to initiate deletion.
79path=/Users/dummy/xrpld/config/db/rocksdb
90# This needs to be an absolute directory reference, not a relative one.
91# Modify this value as required.
93/Users/dummy/xrpld/config/log/debug.log
101# Where to find some other servers speaking the XRPL protocol.
106# Turn down default logging to save disk space in the long run.
107# Valid values here are trace, debug, info, warning, error, and fatal
109{ "command": "log_level", "severity": "warning" }
111# Defaults to 1 ("yes") so that certificates will be validated. To allow the use
112# of self-signed certificates for development or internal use, set to 0 ("no").
120 std::string dbPathSection = dbPath.empty() ? "" :
"[database_path]\n" + dbPath;
122 validatorsFile.
empty() ?
"" :
"[validators_file]\n" + validatorsFile;
123 return boost::str(kConfigContentsTemplate % dbPathSection % valFileSection);
145 bool useCounter =
true,
182 return boost::filesystem::is_directory(
dataDir_);
195 using namespace boost::filesystem;
199 catch (std::exception& e)
212n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
213n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
214n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
215n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
216n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
219nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
220nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
221nHUPDdcdb2Y5DZAJne4c2iabFuAP3F34xZUgYQT2NH7qfkdapgnz
223[validator_list_sites]
224recommended-xrpl-validators.com
225more-xrpl-validators.net
22803E74EE14CB525AFBB9F1B7D86CD58ECC4B91452294B42AB4E78F260BD905C091D
229030775A669685BD6ABCEBD80385921C7851783D991A8055FD21D2F3966C96F1B56
231[validator_list_threshold]
244 beast::unit_test::Suite& test,
246 path const& validatorsFileName,
247 bool useCounter =
true)
251 path(validatorsFileName.
empty() ? Config::kValidatorsFileName : validatorsFileName),
263 [[nodiscard]] std::string
276 using path = boost::filesystem::path;
303 BEAST_EXPECT(c.
legacy(
"not_in_file").empty());
304 c.
legacy(
"not_in_file",
"new_value");
305 BEAST_EXPECT(c.
legacy(
"not_in_file") ==
"new_value");
312 using namespace boost::filesystem;
313 auto const cwd = current_path();
319 for (
auto const& configFile : configFiles)
322 beast::TempDir
const td;
324 path const f = td.
file(std::string{configFile});
325 std::ofstream o(f.string());
331 c.
setup(
"",
true,
false,
true);
335 "/Users/dummy/xrpld/config/log/debug.log");
339#if BOOST_OS_LINUX || BOOST_OS_MACOS
340 for (
auto const& configFile : configFiles)
344 beast::TempDir
const td;
350 beast::TempDir
const tc;
355 char const* h =
getenv(
"HOME");
357 char const* x =
getenv(
"XDG_CONFIG_HOME");
358 setenv(
"XDG_CONFIG_HOME", tc.
path().
c_str(), 1);
364 std::ofstream o(p.string());
370 c.setup(
"",
true,
false,
true);
374 "/Users/dummy/xrpld/config/log/debug.log");
377 (h !=
nullptr) ? setenv(
"HOME", h, 1) : unsetenv(
"HOME");
378 (x !=
nullptr) ? setenv(
"XDG_CONFIG_HOME", x, 1) : unsetenv(
"XDG_CONFIG_HOME");
384 beast::TempDir
const tc;
387 char const* h =
getenv(
"HOME");
389 char const* x =
getenv(
"XDG_CONFIG_HOME");
390 unsetenv(
"XDG_CONFIG_HOME");
393 std::string s =
".config";
399 p = tc.
file(s +
"/" + std::string{configFile});
400 std::ofstream o(p.string());
406 c.setup(
"",
true,
false,
true);
410 "/Users/dummy/xrpld/config/log/debug.log");
413 (h !=
nullptr) ? setenv(
"HOME", h, 1) : unsetenv(
"HOME");
415 setenv(
"XDG_CONFIG_HOME", x, 1);
428 using namespace boost::filesystem;
430 boost::format cc(
"[database_path]\n%1%\n");
433 path const dataDirRel(
"test_data_dir");
434 path const dataDirAbs(cwd / dataDirRel);
438 c.loadFromString(boost::str(cc % dataDirAbs.string()));
444 c.loadFromString(boost::str(cc % dataDirRel.string()));
452 c.loadFromString(
"");
459 detail::DirGuard
const g0(*
this,
"test_db");
460 path const dataDirRel(
"test_data_dir");
461 path const dataDirAbs(cwd / g0.subdir() / dataDirRel);
462 detail::FileCfgGuard
const g(
464 auto const& c(g.config());
465 BEAST_EXPECT(g.dataDirExists());
466 BEAST_EXPECT(g.configFileExists());
471 std::string
const dbPath(
"my_db");
473 auto const& c(g.config());
474 std::string
const nativeDbPath =
absolute(
path(dbPath)).string();
475 BEAST_EXPECT(g.dataDirExists());
476 BEAST_EXPECT(g.configFileExists());
482 auto const& c(g.config());
483 std::string
const nativeDbPath =
485 BEAST_EXPECT(g.dataDirExists());
486 BEAST_EXPECT(g.configFileExists());
499 "eyJ2YWxpZGF0aW9uX3ByaXZhdGVfa2V5IjoiOWVkNDVmODY2MjQxY2MxOGEyNzQ3Yj"
500 "U0Mzg3YzA2MjU5MDc5NzJmNGU3MTkwMjMxZmFhOTM3NDU3ZmE5ZGFmNiIsIm1hbmlm"
501 "ZXN0IjoiSkFBQUFBRnhJZTFGdHdtaW12R3RIMmlDY01KcUM5Z1ZGS2lsR2Z3MS92Q3"
502 "hIWFhMcGxjMkduTWhBa0UxYWdxWHhCd0R3RGJJRDZPTVNZdU0wRkRBbHBBZ05rOFNL"
503 "Rm43TU8yZmRrY3dSUUloQU9uZ3U5c0FLcVhZb3VKK2wyVjBXK3NBT2tWQitaUlM2UF"
504 "NobEpBZlVzWGZBaUJzVkpHZXNhYWRPSmMvYUFab2tTMXZ5bUdtVnJsSFBLV1gzWXl3"
505 "dTZpbjhIQVNRS1B1Z0JENjdrTWFSRkd2bXBBVEhsR0tKZHZERmxXUFl5NUFxRGVkRn"
506 "Y1VEphMncwaTIxZXEzTVl5d0xWSlpuRk9yN0Mwa3cyQWlUelNDakl6ZGl0UTg9In0"
511 static boost::format kConfigTemplate(R
"xrpldConfig(
519 auto const expectedError =
520 "Cannot have both [validation_seed] "
521 "and [validator_token] config sections";
524 c.loadFromString(boost::str(kConfigTemplate %
validationSeed % token));
530 BEAST_EXPECT(error == expectedError);
542 c.loadFromString(R
"xrpldConfig(
547 catch (std::runtime_error
const& e)
552 BEAST_EXPECT(error.
empty());
553 BEAST_EXPECT(c.networkId == 0);
557 c.loadFromString(R
"xrpldConfig(
560 catch (std::runtime_error
const& e)
565 BEAST_EXPECT(error.
empty());
566 BEAST_EXPECT(c.networkId == 0);
570 c.loadFromString(R
"xrpldConfig(
575 catch (std::runtime_error
const& e)
580 BEAST_EXPECT(error.
empty());
581 BEAST_EXPECT(c.networkId == 255);
585 c.loadFromString(R
"xrpldConfig(
595 BEAST_EXPECT(error.
empty());
596 BEAST_EXPECT(c.networkId == 10000);
604 using namespace boost::filesystem;
607 boost::format cc(
"[validators_file]\n%1%\n");
609 std::string
const missingPath =
"/no/way/this/path/exists";
610 auto const expectedError =
611 "The file specified in [validators_file] does not exist: " + missingPath;
615 c.loadFromString(boost::str(cc % missingPath));
617 catch (std::runtime_error
const& e)
621 BEAST_EXPECT(error == expectedError);
625 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.cfg");
627 boost::format cc(
"[validators_file]\n%1%\n");
629 auto const expectedError =
630 "Invalid file specified in [validators_file]: " + invalidFile.
string();
634 c.loadFromString(boost::str(cc % invalidFile.string()));
636 catch (std::runtime_error
const& e)
640 BEAST_EXPECT(error == expectedError);
645 std::string
const toLoad(R
"xrpldConfig(
647n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
648n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
649n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
652nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
653nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
655 c.loadFromString(toLoad);
658 BEAST_EXPECT(c.validatorListThreshold == std::nullopt);
663 std::string
const toLoad(R
"xrpldConfig(
664[validator_list_sites]
666trust-these-validators.gov
669021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
671[validator_list_threshold]
674 c.loadFromString(toLoad);
680 "trust-these-validators.gov");
684 "021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801"
688 BEAST_EXPECT(c.validatorListThreshold == std::size_t(1));
693 std::string
const toLoad(R
"xrpldConfig(
694[validator_list_sites]
696trust-these-validators.gov
699021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
701[validator_list_threshold]
704 c.loadFromString(toLoad);
710 "trust-these-validators.gov");
714 "021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801"
718 BEAST_EXPECT(c.validatorListThreshold == std::nullopt);
724 std::string
const toLoad(R
"xrpldConfig(
725[validator_list_sites]
727trust-these-validators.gov
730021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
732[validator_list_threshold]
736 auto const expectedError =
737 "Value in config section [validator_list_threshold] exceeds "
738 "the number of configured list keys";
741 c.loadFromString(toLoad);
744 catch (std::runtime_error
const& e)
748 BEAST_EXPECT(error == expectedError);
753 std::string
const toLoad(R
"xrpldConfig(
754[validator_list_sites]
756trust-these-validators.gov
759021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
761[validator_list_threshold]
765 auto const expectedError =
766 "Config section [validator_list_threshold] should contain "
770 c.loadFromString(toLoad);
773 catch (std::runtime_error
const& e)
777 BEAST_EXPECT(error == expectedError);
782 std::string
const toLoad(R
"xrpldConfig(
783[validator_list_sites]
785trust-these-validators.gov
788021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
790[validator_list_threshold]
796 c.loadFromString(toLoad);
799 catch (std::bad_cast& e)
809 std::string
const toLoad(R
"xrpldConfig(
810[validator_list_sites]
812trust-these-validators.gov
815 auto const expectedError =
"[validator_list_keys] config section is missing";
818 c.loadFromString(toLoad);
821 catch (std::runtime_error
const& e)
825 BEAST_EXPECT(error == expectedError);
829 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.cfg");
830 BEAST_EXPECT(vtg.validatorsFileExists());
832 boost::format cc(
"[validators_file]\n%1%\n");
833 c.loadFromString(boost::str(cc % vtg.validatorsFile()));
839 BEAST_EXPECT(c.validatorListThreshold == 2);
844 std::string
const valFileName =
"validators.txt";
845 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg", valFileName);
846 detail::FileCfgGuard
const rcg(
848 BEAST_EXPECT(vtg.validatorsFileExists());
849 BEAST_EXPECT(rcg.configFileExists());
850 auto const& c(rcg.config());
856 BEAST_EXPECT(c.validatorListThreshold == 2);
861 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.txt");
862 auto const valFilePath =
".." / vtg.subdir() /
"validators.txt";
863 detail::FileCfgGuard
const rcg(
865 BEAST_EXPECT(vtg.validatorsFileExists());
866 BEAST_EXPECT(rcg.configFileExists());
867 auto const& c(rcg.config());
873 BEAST_EXPECT(c.validatorListThreshold == 2);
877 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.txt");
878 detail::FileCfgGuard
const rcg(
880 BEAST_EXPECT(vtg.validatorsFileExists());
881 BEAST_EXPECT(rcg.configFileExists());
882 auto const& c(rcg.config());
888 BEAST_EXPECT(c.validatorListThreshold == 2);
894 BEAST_EXPECT(vtg.validatorsFileExists());
896 *
this, vtg.subdir(),
"validators.txt",
false);
897 BEAST_EXPECT(vtgDefault.validatorsFileExists());
900 BEAST_EXPECT(rcg.configFileExists());
901 auto const& c(rcg.config());
907 BEAST_EXPECT(c.validatorListThreshold == 2);
912 boost::format cc(R
"xrpldConfig(
917n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
918n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
919n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
920n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
921n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
924nHB1X37qrniVugfQcuBTAjswphC1drx7QjFFojJPZwKHHnt8kU7v
925nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
927[validator_list_sites]
929trust-these-validators.gov
932021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
934 detail::ValidatorsTxtGuard const vtg(*
this,
"test_cfg",
"validators.cfg");
935 BEAST_EXPECT(vtg.validatorsFileExists());
937 c.loadFromString(boost::str(cc % vtg.validatorsFile()));
943 BEAST_EXPECT(c.validatorListThreshold == 2);
948 boost::format cc(R
"xrpldConfig(
952[validator_list_threshold]
956 detail::ValidatorsTxtGuard const vtg(*
this,
"test_cfg",
"validators.cfg");
957 BEAST_EXPECT(vtg.validatorsFileExists());
958 auto const expectedError =
959 "Config section [validator_list_threshold] should contain "
964 c.loadFromString(boost::str(cc % vtg.validatorsFile()));
967 catch (std::runtime_error
const& e)
971 BEAST_EXPECT(error == expectedError);
978 boost::format cc(
"[validators_file]\n%1%\n");
980 detail::ValidatorsTxtGuard
const vtg(*
this,
"test_cfg",
"validators.cfg");
981 BEAST_EXPECT(vtg.validatorsFileExists());
982 auto const expectedError =
983 "The file specified in [validators_file] does not contain a "
984 "[validators], [validator_keys] or [validator_list_keys] "
986 vtg.validatorsFile();
987 std::ofstream
const o(vtg.validatorsFile());
991 c2.loadFromString(boost::str(cc % vtg.validatorsFile()));
993 catch (std::runtime_error
const& e)
997 BEAST_EXPECT(error == expectedError);
1017 BEAST_EXPECT(!config.
quiet());
1018 BEAST_EXPECT(!config.
silent());
1030 BEAST_EXPECT(config.
quiet());
1031 BEAST_EXPECT(!config.
silent());
1043 BEAST_EXPECT(config.quiet());
1044 BEAST_EXPECT(config.silent());
1045 BEAST_EXPECT(!config.standalone());
1046 BEAST_EXPECT(config.ledgerHistory == 256);
1056 BEAST_EXPECT(config.
quiet());
1057 BEAST_EXPECT(config.
silent());
1069 BEAST_EXPECT(!config.quiet());
1070 BEAST_EXPECT(!config.silent());
1071 BEAST_EXPECT(config.standalone());
1072 BEAST_EXPECT(config.ledgerHistory == 0);
1082 BEAST_EXPECT(config.
quiet());
1083 BEAST_EXPECT(!config.
silent());
1095 BEAST_EXPECT(config.quiet());
1096 BEAST_EXPECT(config.silent());
1097 BEAST_EXPECT(config.standalone());
1098 BEAST_EXPECT(config.ledgerHistory == 0);
1108 BEAST_EXPECT(config.quiet());
1109 BEAST_EXPECT(config.silent());
1110 BEAST_EXPECT(config.standalone());
1111 BEAST_EXPECT(config.ledgerHistory == 0);
1120 auto const& conf = cfg.
config();
1145 BEAST_EXPECT(
false);
1160 std::string
const toLoad(
1183 cfg.loadFromString(toLoad);
1223 anotherserversansport
1224 anotherserverwithport:12
1234 2001:db8:3333:4444:5555:6666:7777:8888:12345
1235 [2001:db8:3333:4444:5555:6666:7777:8888]:1
1239 cfg.loadFromString(toLoad);
1250 BEAST_EXPECT(cfg.ips[0] == "r.ripple.com 51235");
1252 BEAST_EXPECT(cfg.ipsFixed[0] ==
"s1.ripple.com 51235");
1253 BEAST_EXPECT(cfg.ipsFixed[1] ==
"s2.ripple.com 51235");
1254 BEAST_EXPECT(cfg.ipsFixed[2] ==
"anotherserversansport");
1255 BEAST_EXPECT(cfg.ipsFixed[3] ==
"anotherserverwithport 12");
1256 BEAST_EXPECT(cfg.ipsFixed[4] ==
"1.1.1.1 1");
1257 BEAST_EXPECT(cfg.ipsFixed[5] ==
"1.1.1.1 1");
1258 BEAST_EXPECT(cfg.ipsFixed[6] ==
"12.34.12.123 12345");
1259 BEAST_EXPECT(cfg.ipsFixed[7] ==
"12.34.12.123 12345");
1262 BEAST_EXPECT(cfg.ipsFixed[8] ==
"::");
1263 BEAST_EXPECT(cfg.ipsFixed[9] ==
"2001:db8::");
1264 BEAST_EXPECT(cfg.ipsFixed[10] ==
"::1");
1265 BEAST_EXPECT(cfg.ipsFixed[11] ==
"::1:12345");
1266 BEAST_EXPECT(cfg.ipsFixed[12] ==
"[::1]:12345");
1267 BEAST_EXPECT(cfg.ipsFixed[13] ==
"2001:db8:3333:4444:5555:6666:7777:8888:12345");
1268 BEAST_EXPECT(cfg.ipsFixed[14] ==
"[2001:db8:3333:4444:5555:6666:7777:8888]:1");
1274 struct TestCommentData
1283 {{.line =
"password = aaaa\\#bbbb",
1284 .field =
"password",
1285 .expect =
"aaaa#bbbb",
1286 .hadComment =
false},
1287 {.line =
"password = aaaa#bbbb",
1288 .field =
"password",
1290 .hadComment =
true},
1291 {.line =
"password = aaaa #bbbb",
1292 .field =
"password",
1294 .hadComment =
true},
1296 {.line =
"password = #aaaa #bbbb",
1298 .expect =
"password =",
1299 .hadComment =
true},
1300 {.line =
"password = aaaa\\# #bbbb",
1301 .field =
"password",
1303 .hadComment =
true},
1304 {.line =
"password = aaaa\\##bbbb",
1305 .field =
"password",
1307 .hadComment =
true},
1308 {.line =
"aaaa#bbbb", .field =
"", .expect =
"aaaa", .hadComment =
true},
1309 {.line =
"aaaa\\#bbbb", .field =
"", .expect =
"aaaa#bbbb", .hadComment =
false},
1310 {.line =
"aaaa\\##bbbb", .field =
"", .expect =
"aaaa#", .hadComment =
true},
1311 {.line =
"aaaa #bbbb", .field =
"", .expect =
"aaaa", .hadComment =
true},
1312 {.line =
"1 #comment", .field =
"", .expect =
"1", .hadComment =
true},
1313 {.line =
"#whole thing is comment", .field =
"", .expect =
"", .hadComment =
false},
1314 {.line =
" #whole comment with space",
1317 .hadComment =
false}}};
1319 for (
auto const& t : tests)
1322 s.
append(std::string(t.line));
1323 BEAST_EXPECT(s.hadTrailingComments() == t.hadComment);
1324 if (t.field.empty())
1326 BEAST_EXPECTS(s.legacy() == t.expect, s.legacy());
1331 BEAST_EXPECTS(
set(field, std::string(t.field), s), t.line);
1332 BEAST_EXPECTS(field == t.expect, t.line);
1338 s.append(
"online_delete = 3000");
1339 std::uint32_t od = 0;
1347 s.append(
"online_delete = 2000 #my comment on this");
1348 std::uint32_t od = 0;
1358 using namespace std::string_literals;
1359 Section s{
"MySection"};
1360 s.append(
"a_string = mystring");
1361 s.append(
"positive_int = 2");
1362 s.append(
"negative_int = -3");
1363 s.append(
"bool_ish = 1");
1366 auto val1 =
"value 1"s;
1367 BEAST_EXPECT(
set(val1,
"a_string", s));
1368 BEAST_EXPECT(val1 ==
"mystring");
1370 auto val2 =
"value 2"s;
1371 BEAST_EXPECT(!
set(val2,
"not_a_key", s));
1372 BEAST_EXPECT(val2 ==
"value 2");
1373 BEAST_EXPECT(!
set(val2,
"default"s,
"not_a_key", s));
1374 BEAST_EXPECT(val2 ==
"default");
1377 BEAST_EXPECT(val3 ==
"mystring");
1379 BEAST_EXPECT(val4.empty());
1381 BEAST_EXPECT(val5 ==
"default");
1383 auto val6 =
"value 6"s;
1385 BEAST_EXPECT(val6 ==
"mystring");
1387 auto val7 =
"value 7"s;
1389 BEAST_EXPECT(val7 ==
"value 7");
1394 BEAST_EXPECT(
set(val1,
"positive_int", s));
1395 BEAST_EXPECT(val1 == 2);
1398 BEAST_EXPECT(
set(val2,
"negative_int", s));
1399 BEAST_EXPECT(val2 == -3);
1402 BEAST_EXPECT(!
set(val3,
"a_string", s));
1403 BEAST_EXPECT(val3 == 3);
1405 auto val4 =
get<int>(s,
"positive_int");
1406 BEAST_EXPECT(val4 == 2);
1407 auto val5 =
get<int>(s,
"not_a_key");
1408 BEAST_EXPECT(val5 == 0);
1409 auto val6 =
get<int>(s,
"not_a_key", 5);
1410 BEAST_EXPECT(val6 == 5);
1411 auto val7 =
get<int>(s,
"a_string", 6);
1412 BEAST_EXPECT(val7 == 6);
1415 BEAST_EXPECT(
getIfExists(s,
"positive_int", val8));
1416 BEAST_EXPECT(val8 == 2);
1420 BEAST_EXPECT(val9 == 9);
1424 BEAST_EXPECT(val10 == 10);
1426 BEAST_EXPECT(s.get<
int>(
"not_a_key") == std::nullopt);
1429 [[maybe_unused]]
auto _ = s.get<
int>(
"a_string");
1432 catch (boost::bad_lexical_cast&)
1441 BEAST_EXPECT(flag1 ==
true);
1444 BEAST_EXPECT(!
getIfExists(s,
"not_a_key", flag2));
1445 BEAST_EXPECT(flag2 ==
false);
1456 std::uint32_t numSeconds;
1457 std::uint32_t configVal;
1461 std::vector<ConfigUnit>
const units = {
1462 {.unit =
"seconds", .numSeconds = 1, .configVal = 15 * 60, .shouldPass =
false},
1463 {.unit =
"minutes", .numSeconds = 60, .configVal = 14, .shouldPass =
false},
1464 {.unit =
"minutes", .numSeconds = 60, .configVal = 15, .shouldPass =
true},
1465 {.unit =
"hours", .numSeconds = 3600, .configVal = 10, .shouldPass =
true},
1466 {.unit =
"days", .numSeconds = 86400, .configVal = 10, .shouldPass =
true},
1467 {.unit =
"weeks", .numSeconds = 604800, .configVal = 2, .shouldPass =
true},
1468 {.unit =
"months", .numSeconds = 2592000, .configVal = 1, .shouldPass =
false},
1469 {.unit =
"years", .numSeconds = 31536000, .configVal = 1, .shouldPass =
false}};
1472 for (
auto& [unit, sec, val, shouldPass] : units)
1475 std::string toLoad(R
"xrpldConfig(
1476[amendment_majority_time]
1483 c.loadFromString(toLoad);
1486 BEAST_EXPECT(c.amendmentMajorityTime.count() == val * sec);
1493 catch (std::runtime_error
const&)
1512 auto testUnknown = [](std::string value) -> std::optional<std::chrono::seconds> {
1516 c.loadFromString(
"[overlay]\nmax_unknown_time=" + value);
1517 return c.maxUnknownTime;
1519 catch (std::runtime_error
const&)
1526 BEAST_EXPECT(!testUnknown(
"none"));
1527 BEAST_EXPECT(!testUnknown(
"0.5"));
1528 BEAST_EXPECT(!testUnknown(
"180 seconds"));
1529 BEAST_EXPECT(!testUnknown(
"9 minutes"));
1532 BEAST_EXPECT(!testUnknown(
"299"));
1535 BEAST_EXPECT(testUnknown(
"300") == std::chrono::seconds{300});
1536 BEAST_EXPECT(testUnknown(
"301") == std::chrono::seconds{301});
1537 BEAST_EXPECT(testUnknown(
"1799") == std::chrono::seconds{1799});
1538 BEAST_EXPECT(testUnknown(
"1800") == std::chrono::seconds{1800});
1541 BEAST_EXPECT(!testUnknown(
"1801"));
1543 testcase(
"overlay: diverged time");
1546 auto testDiverged = [](std::string value) -> std::optional<std::chrono::seconds> {
1550 c.loadFromString(
"[overlay]\nmax_diverged_time=" + value);
1551 return c.maxDivergedTime;
1553 catch (std::runtime_error
const&)
1560 BEAST_EXPECT(!testDiverged(
"none"));
1561 BEAST_EXPECT(!testDiverged(
"0.5"));
1562 BEAST_EXPECT(!testDiverged(
"180 seconds"));
1563 BEAST_EXPECT(!testDiverged(
"9 minutes"));
1566 BEAST_EXPECT(!testDiverged(
"0"));
1567 BEAST_EXPECT(!testDiverged(
"59"));
1570 BEAST_EXPECT(testDiverged(
"60") == std::chrono::seconds{60});
1571 BEAST_EXPECT(testDiverged(
"61") == std::chrono::seconds{61});
1572 BEAST_EXPECT(testDiverged(
"899") == std::chrono::seconds{899});
1573 BEAST_EXPECT(testDiverged(
"900") == std::chrono::seconds{900});
1576 BEAST_EXPECT(!testDiverged(
"901"));
std::string path() const
Get the native path for the temporary directory.
std::string file(std::string const &name) const
Get the native path for the a file.
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()
boost::filesystem::path path
void setup(std::string const &strConf, bool bQuiet, bool bSilent, bool bStandalone)
static char const *const kDatabaseDirName
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
static char const *const kConfigLegacyName
static char const *const kConfigFileName
std::uint32_t ledgerHistory
bool expectException(Functor f, std::string const &message="")
beast::unit_test::Suite & test_
path const & subdir() const
auto rmDir(path const &toRm)
boost::filesystem::path path
Write an xrpld config file and remove when done.
Config const & config() const
std::string configFile() const
bool configFileExists() const
bool dataDirExists() const
FileCfgGuard(beast::unit_test::Suite &test, path subDir, path const &dbPath, path const &configFile, path const &validatorsFile, bool useCounter=true, std::string confContents="")
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)
FieldT< CharT, Traits, Allocator > field(std::basic_string< CharT, Traits, Allocator > const &text, int width=8, int pad=0, bool right=false)
std::string valFileContents()
std::string configContents(std::string const &dbPath, std::string const &validatorsFile)
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,...
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