rippled
Config_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2015 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/basics/contract.h>
21 #include <ripple/core/Config.h>
22 #include <ripple/core/ConfigSections.h>
23 #include <ripple/server/Port.h>
24 #include <boost/filesystem.hpp>
25 #include <boost/format.hpp>
26 #include <fstream>
27 #include <iostream>
28 #include <test/jtx/TestSuite.h>
29 #include <test/unit_test/FileDirGuard.h>
30 
31 namespace ripple {
32 namespace detail {
34 configContents(std::string const& dbPath, std::string const& validatorsFile)
35 {
36  static boost::format configContentsTemplate(R"rippleConfig(
37 [server]
38 port_rpc
39 port_peer
40 port_wss_admin
41 
42 [port_rpc]
43 port = 5005
44 ip = 127.0.0.1
45 admin = 127.0.0.1, ::1
46 protocol = https
47 
48 [port_peer]
49 port = 51235
50 ip = 0.0.0.0
51 protocol = peer
52 
53 [port_wss_admin]
54 port = 6006
55 ip = 127.0.0.1
56 admin = 127.0.0.1
57 protocol = wss
58 
59 #[port_ws_public]
60 #port = 5005
61 #ip = 127.0.0.1
62 #protocol = wss
63 
64 #-------------------------------------------------------------------------------
65 
66 [node_size]
67 medium
68 
69 # This is primary persistent datastore for rippled. This includes transaction
70 # metadata, account states, and ledger headers. Helpful information can be
71 # found on https://xrpl.org/capacity-planning.html#node-db-type
72 # delete old ledgers while maintaining at least 2000. Do not require an
73 # external administrative command to initiate deletion.
74 [node_db]
75 type=memory
76 path=/Users/dummy/ripple/config/db/rocksdb
77 open_files=2000
78 filter_bits=12
79 cache_mb=256
80 file_size_mb=8
81 file_size_mult=2
82 
83 %1%
84 
85 %2%
86 
87 # This needs to be an absolute directory reference, not a relative one.
88 # Modify this value as required.
89 [debug_logfile]
90 /Users/dummy/ripple/config/log/debug.log
91 
92 [sntp_servers]
93 time.windows.com
94 time.apple.com
95 time.nist.gov
96 pool.ntp.org
97 
98 # Where to find some other servers speaking the Ripple protocol.
99 #
100 [ips]
101 r.ripple.com 51235
102 
103 # Turn down default logging to save disk space in the long run.
104 # Valid values here are trace, debug, info, warning, error, and fatal
105 [rpc_startup]
106 { "command": "log_level", "severity": "warning" }
107 
108 # Defaults to 1 ("yes") so that certificates will be validated. To allow the use
109 # of self-signed certificates for development or internal use, set to 0 ("no").
110 [ssl_verify]
111 0
112 
113 [sqdb]
114 backend=sqlite
115 )rippleConfig");
116 
117  std::string dbPathSection =
118  dbPath.empty() ? "" : "[database_path]\n" + dbPath;
119  std::string valFileSection =
120  validatorsFile.empty() ? "" : "[validators_file]\n" + validatorsFile;
121  return boost::str(configContentsTemplate % dbPathSection % valFileSection);
122 }
123 
128 {
129 private:
131 
132  bool rmDataDir_{false};
133 
135 
136 public:
138  beast::unit_test::suite& test,
139  path subDir,
140  path const& dbPath,
141  path const& validatorsFile,
142  bool useCounter = true)
143  : FileDirGuard(
144  test,
145  std::move(subDir),
146  path(Config::configFileName),
147  configContents(dbPath.string(), validatorsFile.string()),
148  useCounter)
149  , dataDir_(dbPath)
150  {
151  if (dbPath.empty())
153 
154  rmDataDir_ = !exists(dataDir_);
155  config_.setup(
156  file_.string(),
157  /* bQuiet */ true,
158  /* bSilent */ false,
159  /* bStandalone */ false);
160  }
161 
162  Config const&
163  config() const
164  {
165  return config_;
166  }
167 
169  configFile() const
170  {
171  return file().string();
172  }
173 
174  bool
176  {
177  return boost::filesystem::is_directory(dataDir_);
178  }
179 
180  bool
182  {
183  return fileExists();
184  }
185 
187  {
188  try
189  {
190  using namespace boost::filesystem;
191  if (rmDataDir_)
192  rmDir(dataDir_);
193  }
194  catch (std::exception& e)
195  {
196  // if we throw here, just let it die.
197  test_.log << "Error in ~RippledCfgGuard: " << e.what() << std::endl;
198  };
199  }
200 };
201 
204 {
205  std::string configContents(R"rippleConfig(
206 [validators]
207 n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
208 n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
209 n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
210 n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
211 n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
212 
213 [validator_keys]
214 nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
215 nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
216 nHUPDdcdb2Y5DZAJne4c2iabFuAP3F34xZUgYQT2NH7qfkdapgnz
217 
218 [validator_list_sites]
219 recommendedripplevalidators.com
220 moreripplevalidators.net
221 
222 [validator_list_keys]
223 03E74EE14CB525AFBB9F1B7D86CD58ECC4B91452294B42AB4E78F260BD905C091D
224 030775A669685BD6ABCEBD80385921C7851783D991A8055FD21D2F3966C96F1B56
225 )rippleConfig");
226  return configContents;
227 }
228 
233 {
234 public:
236  beast::unit_test::suite& test,
237  path subDir,
238  path const& validatorsFileName,
239  bool useCounter = true)
240  : FileDirGuard(
241  test,
242  std::move(subDir),
243  path(
244  validatorsFileName.empty() ? Config::validatorsFileName
245  : validatorsFileName),
246  valFileContents(),
247  useCounter)
248  {
249  }
250 
251  bool
253  {
254  return fileExists();
255  }
256 
259  {
260  return absolute(file()).string();
261  }
262 
264  {
265  }
266 };
267 } // namespace detail
268 
269 class Config_test final : public TestSuite
270 {
271 private:
272  using path = boost::filesystem::path;
273 
274 public:
275  void
277  {
278  testcase("legacy");
279 
280  Config c;
281 
282  std::string toLoad(R"rippleConfig(
283 [server]
284 port_rpc
285 port_peer
286 port_wss_admin
287 
288 [ssl_verify]
289 0
290 )rippleConfig");
291 
292  c.loadFromString(toLoad);
293 
294  BEAST_EXPECT(c.legacy("ssl_verify") == "0");
295  expectException([&c] { c.legacy("server"); }); // not a single line
296 
297  // set a legacy value
298  BEAST_EXPECT(c.legacy("not_in_file") == "");
299  c.legacy("not_in_file", "new_value");
300  BEAST_EXPECT(c.legacy("not_in_file") == "new_value");
301  }
302  void
304  {
305  testcase("database_path");
306 
307  using namespace boost::filesystem;
308  {
309  boost::format cc("[database_path]\n%1%\n");
310 
311  auto const cwd = current_path();
312  path const dataDirRel("test_data_dir");
313  path const dataDirAbs(cwd / dataDirRel);
314  {
315  // Dummy test - do we get back what we put in
316  Config c;
317  c.loadFromString(boost::str(cc % dataDirAbs.string()));
318  BEAST_EXPECT(c.legacy("database_path") == dataDirAbs.string());
319  }
320  {
321  // Rel paths should convert to abs paths
322  Config c;
323  c.loadFromString(boost::str(cc % dataDirRel.string()));
324  BEAST_EXPECT(c.legacy("database_path") == dataDirAbs.string());
325  }
326  {
327  // No db section.
328  // N.B. Config::setup will give database_path a default,
329  // load will not.
330  Config c;
331  c.loadFromString("");
332  BEAST_EXPECT(c.legacy("database_path") == "");
333  }
334  }
335  {
336  // read from file absolute path
337  auto const cwd = current_path();
338  ripple::test::detail::DirGuard const g0(*this, "test_db");
339  path const dataDirRel("test_data_dir");
340  path const dataDirAbs(cwd / g0.subdir() / dataDirRel);
341  detail::RippledCfgGuard const g(
342  *this, g0.subdir(), dataDirAbs, "", false);
343  auto const& c(g.config());
344  BEAST_EXPECT(g.dataDirExists());
345  BEAST_EXPECT(g.configFileExists());
346  BEAST_EXPECT(c.legacy("database_path") == dataDirAbs.string());
347  }
348  {
349  // read from file relative path
350  std::string const dbPath("my_db");
351  detail::RippledCfgGuard const g(*this, "test_db", dbPath, "");
352  auto const& c(g.config());
353  std::string const nativeDbPath = absolute(path(dbPath)).string();
354  BEAST_EXPECT(g.dataDirExists());
355  BEAST_EXPECT(g.configFileExists());
356  BEAST_EXPECT(c.legacy("database_path") == nativeDbPath);
357  }
358  {
359  // read from file no path
360  detail::RippledCfgGuard const g(*this, "test_db", "", "");
361  auto const& c(g.config());
362  std::string const nativeDbPath =
363  absolute(g.subdir() / path(Config::databaseDirName)).string();
364  BEAST_EXPECT(g.dataDirExists());
365  BEAST_EXPECT(g.configFileExists());
366  BEAST_EXPECT(c.legacy("database_path") == nativeDbPath);
367  }
368  }
369 
370  void
372  {
373  testcase("validator keys");
374 
375  std::string const validationSeed = "spA4sh1qTvwq92X715tYyGQKmAKfa";
376 
377  auto const token =
378  "eyJ2YWxpZGF0aW9uX3ByaXZhdGVfa2V5IjoiOWVkNDVmODY2MjQxY2MxOGEyNzQ3Yj"
379  "U0Mzg3YzA2MjU5MDc5NzJmNGU3MTkwMjMxZmFhOTM3NDU3ZmE5ZGFmNiIsIm1hbmlm"
380  "ZXN0IjoiSkFBQUFBRnhJZTFGdHdtaW12R3RIMmlDY01KcUM5Z1ZGS2lsR2Z3MS92Q3"
381  "hIWFhMcGxjMkduTWhBa0UxYWdxWHhCd0R3RGJJRDZPTVNZdU0wRkRBbHBBZ05rOFNL"
382  "Rm43TU8yZmRrY3dSUUloQU9uZ3U5c0FLcVhZb3VKK2wyVjBXK3NBT2tWQitaUlM2UF"
383  "NobEpBZlVzWGZBaUJzVkpHZXNhYWRPSmMvYUFab2tTMXZ5bUdtVnJsSFBLV1gzWXl3"
384  "dTZpbjhIQVNRS1B1Z0JENjdrTWFSRkd2bXBBVEhsR0tKZHZERmxXUFl5NUFxRGVkRn"
385  "Y1VEphMncwaTIxZXEzTVl5d0xWSlpuRk9yN0Mwa3cyQWlUelNDakl6ZGl0UTg9In0"
386  "=";
387 
388  {
389  Config c;
390  static boost::format configTemplate(R"rippleConfig(
391 [validation_seed]
392 %1%
393 
394 [validator_token]
395 %2%
396 )rippleConfig");
397  std::string error;
398  auto const expectedError =
399  "Cannot have both [validation_seed] "
400  "and [validator_token] config sections";
401  try
402  {
403  c.loadFromString(
404  boost::str(configTemplate % validationSeed % token));
405  }
406  catch (std::runtime_error& e)
407  {
408  error = e.what();
409  }
410  BEAST_EXPECT(error == expectedError);
411  }
412  }
413 
414  void
416  {
417  testcase("network id");
418  std::string error;
419  Config c;
420  try
421  {
422  c.loadFromString(R"rippleConfig(
423 [network_id]
424 main
425 )rippleConfig");
426  }
427  catch (std::runtime_error& e)
428  {
429  error = e.what();
430  }
431 
432  BEAST_EXPECT(error == "");
433  BEAST_EXPECT(c.NETWORK_ID == 0);
434 
435  try
436  {
437  c.loadFromString(R"rippleConfig(
438 )rippleConfig");
439  }
440  catch (std::runtime_error& e)
441  {
442  error = e.what();
443  }
444 
445  BEAST_EXPECT(error == "");
446  BEAST_EXPECT(c.NETWORK_ID == 0);
447 
448  try
449  {
450  c.loadFromString(R"rippleConfig(
451 [network_id]
452 255
453 )rippleConfig");
454  }
455  catch (std::runtime_error& e)
456  {
457  error = e.what();
458  }
459 
460  BEAST_EXPECT(error == "");
461  BEAST_EXPECT(c.NETWORK_ID == 255);
462 
463  try
464  {
465  c.loadFromString(R"rippleConfig(
466 [network_id]
467 10000
468 )rippleConfig");
469  }
470  catch (std::runtime_error& e)
471  {
472  error = e.what();
473  }
474 
475  BEAST_EXPECT(error == "");
476  BEAST_EXPECT(c.NETWORK_ID == 10000);
477  }
478 
479  void
481  {
482  testcase("validators_file");
483 
484  using namespace boost::filesystem;
485  {
486  // load should throw for missing specified validators file
487  boost::format cc("[validators_file]\n%1%\n");
488  std::string error;
489  std::string const missingPath = "/no/way/this/path/exists";
490  auto const expectedError =
491  "The file specified in [validators_file] does not exist: " +
492  missingPath;
493  try
494  {
495  Config c;
496  c.loadFromString(boost::str(cc % missingPath));
497  }
498  catch (std::runtime_error& e)
499  {
500  error = e.what();
501  }
502  BEAST_EXPECT(error == expectedError);
503  }
504  {
505  // load should throw for invalid [validators_file]
506  detail::ValidatorsTxtGuard const vtg(
507  *this, "test_cfg", "validators.cfg");
508  path const invalidFile = current_path() / vtg.subdir();
509  boost::format cc("[validators_file]\n%1%\n");
510  std::string error;
511  auto const expectedError =
512  "Invalid file specified in [validators_file]: " +
513  invalidFile.string();
514  try
515  {
516  Config c;
517  c.loadFromString(boost::str(cc % invalidFile.string()));
518  }
519  catch (std::runtime_error& e)
520  {
521  error = e.what();
522  }
523  BEAST_EXPECT(error == expectedError);
524  }
525  {
526  // load validators from config into single section
527  Config c;
528  std::string toLoad(R"rippleConfig(
529 [validators]
530 n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
531 n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
532 n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
533 
534 [validator_keys]
535 nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
536 nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
537 )rippleConfig");
538  c.loadFromString(toLoad);
539  BEAST_EXPECT(c.legacy("validators_file").empty());
540  BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 5);
541  }
542  {
543  // load validator list sites and keys from config
544  Config c;
545  std::string toLoad(R"rippleConfig(
546 [validator_list_sites]
547 ripplevalidators.com
548 trustthesevalidators.gov
549 
550 [validator_list_keys]
551 021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
552 )rippleConfig");
553  c.loadFromString(toLoad);
554  BEAST_EXPECT(
555  c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
556  BEAST_EXPECT(
557  c.section(SECTION_VALIDATOR_LIST_SITES).values()[0] ==
558  "ripplevalidators.com");
559  BEAST_EXPECT(
560  c.section(SECTION_VALIDATOR_LIST_SITES).values()[1] ==
561  "trustthesevalidators.gov");
562  BEAST_EXPECT(
563  c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 1);
564  BEAST_EXPECT(
565  c.section(SECTION_VALIDATOR_LIST_KEYS).values()[0] ==
566  "021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801"
567  "E566");
568  }
569  {
570  // load should throw if [validator_list_sites] is configured but
571  // [validator_list_keys] is not
572  Config c;
573  std::string toLoad(R"rippleConfig(
574 [validator_list_sites]
575 ripplevalidators.com
576 trustthesevalidators.gov
577 )rippleConfig");
578  std::string error;
579  auto const expectedError =
580  "[validator_list_keys] config section is missing";
581  try
582  {
583  c.loadFromString(toLoad);
584  }
585  catch (std::runtime_error& e)
586  {
587  error = e.what();
588  }
589  BEAST_EXPECT(error == expectedError);
590  }
591  {
592  // load from specified [validators_file] absolute path
593  detail::ValidatorsTxtGuard const vtg(
594  *this, "test_cfg", "validators.cfg");
595  BEAST_EXPECT(vtg.validatorsFileExists());
596  Config c;
597  boost::format cc("[validators_file]\n%1%\n");
598  c.loadFromString(boost::str(cc % vtg.validatorsFile()));
599  BEAST_EXPECT(c.legacy("validators_file") == vtg.validatorsFile());
600  BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 8);
601  BEAST_EXPECT(
602  c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
603  BEAST_EXPECT(
604  c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 2);
605  }
606  {
607  // load from specified [validators_file] file name
608  // in config directory
609  std::string const valFileName = "validators.txt";
610  detail::ValidatorsTxtGuard const vtg(
611  *this, "test_cfg", valFileName);
612  detail::RippledCfgGuard const rcg(
613  *this, vtg.subdir(), "", valFileName, false);
614  BEAST_EXPECT(vtg.validatorsFileExists());
615  BEAST_EXPECT(rcg.configFileExists());
616  auto const& c(rcg.config());
617  BEAST_EXPECT(c.legacy("validators_file") == valFileName);
618  BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 8);
619  BEAST_EXPECT(
620  c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
621  BEAST_EXPECT(
622  c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 2);
623  }
624  {
625  // load from specified [validators_file] relative path
626  // to config directory
627  detail::ValidatorsTxtGuard const vtg(
628  *this, "test_cfg", "validators.txt");
629  auto const valFilePath = ".." / vtg.subdir() / "validators.txt";
630  detail::RippledCfgGuard const rcg(
631  *this, vtg.subdir(), "", valFilePath, false);
632  BEAST_EXPECT(vtg.validatorsFileExists());
633  BEAST_EXPECT(rcg.configFileExists());
634  auto const& c(rcg.config());
635  BEAST_EXPECT(c.legacy("validators_file") == valFilePath);
636  BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 8);
637  BEAST_EXPECT(
638  c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
639  BEAST_EXPECT(
640  c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 2);
641  }
642  {
643  // load from validators file in default location
644  detail::ValidatorsTxtGuard const vtg(
645  *this, "test_cfg", "validators.txt");
646  detail::RippledCfgGuard const rcg(
647  *this, vtg.subdir(), "", "", false);
648  BEAST_EXPECT(vtg.validatorsFileExists());
649  BEAST_EXPECT(rcg.configFileExists());
650  auto const& c(rcg.config());
651  BEAST_EXPECT(c.legacy("validators_file").empty());
652  BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 8);
653  BEAST_EXPECT(
654  c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
655  BEAST_EXPECT(
656  c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 2);
657  }
658  {
659  // load from specified [validators_file] instead
660  // of default location
661  detail::ValidatorsTxtGuard const vtg(
662  *this, "test_cfg", "validators.cfg");
663  BEAST_EXPECT(vtg.validatorsFileExists());
664  detail::ValidatorsTxtGuard const vtgDefault(
665  *this, vtg.subdir(), "validators.txt", false);
666  BEAST_EXPECT(vtgDefault.validatorsFileExists());
667  detail::RippledCfgGuard const rcg(
668  *this, vtg.subdir(), "", vtg.validatorsFile(), false);
669  BEAST_EXPECT(rcg.configFileExists());
670  auto const& c(rcg.config());
671  BEAST_EXPECT(c.legacy("validators_file") == vtg.validatorsFile());
672  BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 8);
673  BEAST_EXPECT(
674  c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
675  BEAST_EXPECT(
676  c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 2);
677  }
678 
679  {
680  // load validators from both config and validators file
681  boost::format cc(R"rippleConfig(
682 [validators_file]
683 %1%
684 
685 [validators]
686 n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
687 n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
688 n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
689 n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
690 n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
691 
692 [validator_keys]
693 nHB1X37qrniVugfQcuBTAjswphC1drx7QjFFojJPZwKHHnt8kU7v
694 nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
695 
696 [validator_list_sites]
697 ripplevalidators.com
698 trustthesevalidators.gov
699 
700 [validator_list_keys]
701 021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
702 )rippleConfig");
703  detail::ValidatorsTxtGuard const vtg(
704  *this, "test_cfg", "validators.cfg");
705  BEAST_EXPECT(vtg.validatorsFileExists());
706  Config c;
707  c.loadFromString(boost::str(cc % vtg.validatorsFile()));
708  BEAST_EXPECT(c.legacy("validators_file") == vtg.validatorsFile());
709  BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 15);
710  BEAST_EXPECT(
711  c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 4);
712  BEAST_EXPECT(
713  c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 3);
714  }
715  {
716  // load should throw if [validators], [validator_keys] and
717  // [validator_list_keys] are missing from rippled cfg and
718  // validators file
719  Config c;
720  boost::format cc("[validators_file]\n%1%\n");
721  std::string error;
722  detail::ValidatorsTxtGuard const vtg(
723  *this, "test_cfg", "validators.cfg");
724  BEAST_EXPECT(vtg.validatorsFileExists());
725  auto const expectedError =
726  "The file specified in [validators_file] does not contain a "
727  "[validators], [validator_keys] or [validator_list_keys] "
728  "section: " +
729  vtg.validatorsFile();
730  std::ofstream o(vtg.validatorsFile());
731  try
732  {
733  Config c2;
734  c2.loadFromString(boost::str(cc % vtg.validatorsFile()));
735  }
736  catch (std::runtime_error& e)
737  {
738  error = e.what();
739  }
740  BEAST_EXPECT(error == expectedError);
741  }
742  }
743 
744  void
745  testSetup(bool explicitPath)
746  {
747  detail::RippledCfgGuard const cfg(
748  *this, "testSetup", explicitPath ? "test_db" : "", "");
749  /* RippledCfgGuard has a Config object that gets loaded on
750  construction, but Config::setup is not reentrant, so we
751  need a fresh config for every test case, so ignore it.
752  */
753  {
754  Config config;
755  config.setup(
756  cfg.configFile(),
757  /*bQuiet*/ false,
758  /* bSilent */ false,
759  /* bStandalone */ false);
760  BEAST_EXPECT(!config.quiet());
761  BEAST_EXPECT(!config.silent());
762  BEAST_EXPECT(!config.standalone());
763  BEAST_EXPECT(config.LEDGER_HISTORY == 256);
764  BEAST_EXPECT(!config.legacy("database_path").empty());
765  }
766  {
767  Config config;
768  config.setup(
769  cfg.configFile(),
770  /*bQuiet*/ true,
771  /* bSilent */ false,
772  /* bStandalone */ false);
773  BEAST_EXPECT(config.quiet());
774  BEAST_EXPECT(!config.silent());
775  BEAST_EXPECT(!config.standalone());
776  BEAST_EXPECT(config.LEDGER_HISTORY == 256);
777  BEAST_EXPECT(!config.legacy("database_path").empty());
778  }
779  {
780  Config config;
781  config.setup(
782  cfg.configFile(),
783  /*bQuiet*/ false,
784  /* bSilent */ true,
785  /* bStandalone */ false);
786  BEAST_EXPECT(config.quiet());
787  BEAST_EXPECT(config.silent());
788  BEAST_EXPECT(!config.standalone());
789  BEAST_EXPECT(config.LEDGER_HISTORY == 256);
790  BEAST_EXPECT(!config.legacy("database_path").empty());
791  }
792  {
793  Config config;
794  config.setup(
795  cfg.configFile(),
796  /*bQuiet*/ true,
797  /* bSilent */ true,
798  /* bStandalone */ false);
799  BEAST_EXPECT(config.quiet());
800  BEAST_EXPECT(config.silent());
801  BEAST_EXPECT(!config.standalone());
802  BEAST_EXPECT(config.LEDGER_HISTORY == 256);
803  BEAST_EXPECT(!config.legacy("database_path").empty());
804  }
805  {
806  Config config;
807  config.setup(
808  cfg.configFile(),
809  /*bQuiet*/ false,
810  /* bSilent */ false,
811  /* bStandalone */ true);
812  BEAST_EXPECT(!config.quiet());
813  BEAST_EXPECT(!config.silent());
814  BEAST_EXPECT(config.standalone());
815  BEAST_EXPECT(config.LEDGER_HISTORY == 0);
816  BEAST_EXPECT(
817  config.legacy("database_path").empty() == !explicitPath);
818  }
819  {
820  Config config;
821  config.setup(
822  cfg.configFile(),
823  /*bQuiet*/ true,
824  /* bSilent */ false,
825  /* bStandalone */ true);
826  BEAST_EXPECT(config.quiet());
827  BEAST_EXPECT(!config.silent());
828  BEAST_EXPECT(config.standalone());
829  BEAST_EXPECT(config.LEDGER_HISTORY == 0);
830  BEAST_EXPECT(
831  config.legacy("database_path").empty() == !explicitPath);
832  }
833  {
834  Config config;
835  config.setup(
836  cfg.configFile(),
837  /*bQuiet*/ false,
838  /* bSilent */ true,
839  /* bStandalone */ true);
840  BEAST_EXPECT(config.quiet());
841  BEAST_EXPECT(config.silent());
842  BEAST_EXPECT(config.standalone());
843  BEAST_EXPECT(config.LEDGER_HISTORY == 0);
844  BEAST_EXPECT(
845  config.legacy("database_path").empty() == !explicitPath);
846  }
847  {
848  Config config;
849  config.setup(
850  cfg.configFile(),
851  /*bQuiet*/ true,
852  /* bSilent */ true,
853  /* bStandalone */ true);
854  BEAST_EXPECT(config.quiet());
855  BEAST_EXPECT(config.silent());
856  BEAST_EXPECT(config.standalone());
857  BEAST_EXPECT(config.LEDGER_HISTORY == 0);
858  BEAST_EXPECT(
859  config.legacy("database_path").empty() == !explicitPath);
860  }
861  }
862 
863  void
865  {
866  detail::RippledCfgGuard const cfg(*this, "testPort", "", "");
867  auto const& conf = cfg.config();
868  if (!BEAST_EXPECT(conf.exists("port_rpc")))
869  return;
870  if (!BEAST_EXPECT(conf.exists("port_wss_admin")))
871  return;
872  ParsedPort rpc;
873  if (!unexcept([&]() { parse_Port(rpc, conf["port_rpc"], log); }))
874  return;
875  BEAST_EXPECT(rpc.admin_nets_v4.size() + rpc.admin_nets_v6.size() == 2);
876  ParsedPort wss;
877  if (!unexcept([&]() { parse_Port(wss, conf["port_wss_admin"], log); }))
878  return;
879  BEAST_EXPECT(wss.admin_nets_v4.size() + wss.admin_nets_v6.size() == 1);
880  }
881 
882  void
884  {
885  Config cfg;
886  /* NOTE: this string includes some explicit
887  * space chars in order to verify proper trimming */
888  std::string toLoad(R"(
889 [port_rpc])"
890  "\x20"
891  R"(
892 # comment
893  # indented comment
894 )"
895  "\x20\x20"
896  R"(
897 [ips])"
898  "\x20"
899  R"(
900 r.ripple.com 51235
901 
902  [ips_fixed])"
903  "\x20\x20"
904  R"(
905  # COMMENT
906  s1.ripple.com 51235
907  s2.ripple.com 51235
908 
909 )");
910  cfg.loadFromString(toLoad);
911  BEAST_EXPECT(
912  cfg.exists("port_rpc") && cfg.section("port_rpc").lines().empty() &&
913  cfg.section("port_rpc").values().empty());
914  BEAST_EXPECT(
915  cfg.exists(SECTION_IPS) &&
916  cfg.section(SECTION_IPS).lines().size() == 1 &&
917  cfg.section(SECTION_IPS).values().size() == 1);
918  BEAST_EXPECT(
919  cfg.exists(SECTION_IPS_FIXED) &&
920  cfg.section(SECTION_IPS_FIXED).lines().size() == 2 &&
921  cfg.section(SECTION_IPS_FIXED).values().size() == 2);
922  }
923 
924  void
925  testColons()
926  {
927  Config cfg;
928  /* NOTE: this string includes some explicit
929  * space chars in order to verify proper trimming */
930  std::string toLoad(R"(
931 [port_rpc])"
932  "\x20"
933  R"(
934 # comment
935  # indented comment
936 )"
937  "\x20\x20"
938  R"(
939 [ips])"
940  "\x20"
941  R"(
942 r.ripple.com:51235
943 
944  [ips_fixed])"
945  "\x20\x20"
946  R"(
947  # COMMENT
948  s1.ripple.com:51235
949  s2.ripple.com 51235
950  anotherserversansport
951  anotherserverwithport:12
952  1.1.1.1:1
953  1.1.1.1 1
954  12.34.12.123:12345
955  12.34.12.123 12345
956  ::
957  2001:db8::
958  ::1
959  ::1:12345
960  [::1]:12345
961  2001:db8:3333:4444:5555:6666:7777:8888:12345
962  [2001:db8:3333:4444:5555:6666:7777:8888]:1
963 
964 
965 )");
966  cfg.loadFromString(toLoad);
967  BEAST_EXPECT(
968  cfg.exists("port_rpc") && cfg.section("port_rpc").lines().empty() &&
969  cfg.section("port_rpc").values().empty());
970  BEAST_EXPECT(
971  cfg.exists(SECTION_IPS) &&
972  cfg.section(SECTION_IPS).lines().size() == 1 &&
973  cfg.section(SECTION_IPS).values().size() == 1);
974  BEAST_EXPECT(
975  cfg.exists(SECTION_IPS_FIXED) &&
976  cfg.section(SECTION_IPS_FIXED).lines().size() == 15 &&
977  cfg.section(SECTION_IPS_FIXED).values().size() == 15);
978  BEAST_EXPECT(cfg.IPS[0] == "r.ripple.com 51235");
979 
980  BEAST_EXPECT(cfg.IPS_FIXED[0] == "s1.ripple.com 51235");
981  BEAST_EXPECT(cfg.IPS_FIXED[1] == "s2.ripple.com 51235");
982  BEAST_EXPECT(cfg.IPS_FIXED[2] == "anotherserversansport");
983  BEAST_EXPECT(cfg.IPS_FIXED[3] == "anotherserverwithport 12");
984  BEAST_EXPECT(cfg.IPS_FIXED[4] == "1.1.1.1 1");
985  BEAST_EXPECT(cfg.IPS_FIXED[5] == "1.1.1.1 1");
986  BEAST_EXPECT(cfg.IPS_FIXED[6] == "12.34.12.123 12345");
987  BEAST_EXPECT(cfg.IPS_FIXED[7] == "12.34.12.123 12345");
988 
989  // all ipv6 should be ignored by colon replacer, howsoever formated
990  BEAST_EXPECT(cfg.IPS_FIXED[8] == "::");
991  BEAST_EXPECT(cfg.IPS_FIXED[9] == "2001:db8::");
992  BEAST_EXPECT(cfg.IPS_FIXED[10] == "::1");
993  BEAST_EXPECT(cfg.IPS_FIXED[11] == "::1:12345");
994  BEAST_EXPECT(cfg.IPS_FIXED[12] == "[::1]:12345");
995  BEAST_EXPECT(
996  cfg.IPS_FIXED[13] ==
997  "2001:db8:3333:4444:5555:6666:7777:8888:12345");
998  BEAST_EXPECT(
999  cfg.IPS_FIXED[14] == "[2001:db8:3333:4444:5555:6666:7777:8888]:1");
1000  }
1001 
1002  void
1003  testComments()
1004  {
1005  struct TestCommentData
1006  {
1007  std::string_view line;
1008  std::string_view field;
1009  std::string_view expect;
1010  bool had_comment;
1011  };
1012 
1014  {{"password = aaaa\\#bbbb", "password", "aaaa#bbbb", false},
1015  {"password = aaaa#bbbb", "password", "aaaa", true},
1016  {"password = aaaa #bbbb", "password", "aaaa", true},
1017  // since the value is all comment, this doesn't parse as k=v :
1018  {"password = #aaaa #bbbb", "", "password =", true},
1019  {"password = aaaa\\# #bbbb", "password", "aaaa#", true},
1020  {"password = aaaa\\##bbbb", "password", "aaaa#", true},
1021  {"aaaa#bbbb", "", "aaaa", true},
1022  {"aaaa\\#bbbb", "", "aaaa#bbbb", false},
1023  {"aaaa\\##bbbb", "", "aaaa#", true},
1024  {"aaaa #bbbb", "", "aaaa", true},
1025  {"1 #comment", "", "1", true},
1026  {"#whole thing is comment", "", "", false},
1027  {" #whole comment with space", "", "", false}}};
1028 
1029  for (auto const& t : tests)
1030  {
1031  Section s;
1032  s.append(t.line.data());
1033  BEAST_EXPECT(s.had_trailing_comments() == t.had_comment);
1034  if (t.field.empty())
1035  {
1036  BEAST_EXPECTS(s.legacy() == t.expect, s.legacy());
1037  }
1038  else
1039  {
1041  BEAST_EXPECTS(set(field, t.field.data(), s), t.line);
1042  BEAST_EXPECTS(field == t.expect, t.line);
1043  }
1044  }
1045 
1046  {
1047  Section s;
1048  s.append("online_delete = 3000");
1049  std::uint32_t od = 0;
1050  BEAST_EXPECT(set(od, "online_delete", s));
1051  BEAST_EXPECTS(od == 3000, *(s.get<std::string>("online_delete")));
1052  }
1053 
1054  {
1055  Section s;
1056  s.append("online_delete = 2000 #my comment on this");
1057  std::uint32_t od = 0;
1058  BEAST_EXPECT(set(od, "online_delete", s));
1059  BEAST_EXPECTS(od == 2000, *(s.get<std::string>("online_delete")));
1060  }
1061  }
1062 
1063  void
1064  testGetters()
1065  {
1066  using namespace std::string_literals;
1067  Section s{"MySection"};
1068  s.append("a_string = mystring");
1069  s.append("positive_int = 2");
1070  s.append("negative_int = -3");
1071  s.append("bool_ish = 1");
1072 
1073  {
1074  auto val_1 = "value 1"s;
1075  BEAST_EXPECT(set(val_1, "a_string", s));
1076  BEAST_EXPECT(val_1 == "mystring");
1077 
1078  auto val_2 = "value 2"s;
1079  BEAST_EXPECT(!set(val_2, "not_a_key", s));
1080  BEAST_EXPECT(val_2 == "value 2");
1081  BEAST_EXPECT(!set(val_2, "default"s, "not_a_key", s));
1082  BEAST_EXPECT(val_2 == "default");
1083 
1084  auto val_3 = get<std::string>(s, "a_string");
1085  BEAST_EXPECT(val_3 == "mystring");
1086  auto val_4 = get<std::string>(s, "not_a_key");
1087  BEAST_EXPECT(val_4 == "");
1088  auto val_5 = get<std::string>(s, "not_a_key", "default");
1089  BEAST_EXPECT(val_5 == "default");
1090 
1091  auto val_6 = "value 6"s;
1092  BEAST_EXPECT(get_if_exists(s, "a_string", val_6));
1093  BEAST_EXPECT(val_6 == "mystring");
1094 
1095  auto val_7 = "value 7"s;
1096  BEAST_EXPECT(!get_if_exists(s, "not_a_key", val_7));
1097  BEAST_EXPECT(val_7 == "value 7");
1098  }
1099 
1100  {
1101  int val_1 = 1;
1102  BEAST_EXPECT(set(val_1, "positive_int", s));
1103  BEAST_EXPECT(val_1 == 2);
1104 
1105  int val_2 = 2;
1106  BEAST_EXPECT(set(val_2, "negative_int", s));
1107  BEAST_EXPECT(val_2 == -3);
1108 
1109  int val_3 = 3;
1110  BEAST_EXPECT(!set(val_3, "a_string", s));
1111  BEAST_EXPECT(val_3 == 3);
1112 
1113  auto val_4 = get<int>(s, "positive_int");
1114  BEAST_EXPECT(val_4 == 2);
1115  auto val_5 = get<int>(s, "not_a_key");
1116  BEAST_EXPECT(val_5 == 0);
1117  auto val_6 = get<int>(s, "not_a_key", 5);
1118  BEAST_EXPECT(val_6 == 5);
1119  auto val_7 = get<int>(s, "a_string", 6);
1120  BEAST_EXPECT(val_7 == 6);
1121 
1122  int val_8 = 8;
1123  BEAST_EXPECT(get_if_exists(s, "positive_int", val_8));
1124  BEAST_EXPECT(val_8 == 2);
1125 
1126  auto val_9 = 9;
1127  BEAST_EXPECT(!get_if_exists(s, "not_a_key", val_9));
1128  BEAST_EXPECT(val_9 == 9);
1129 
1130  auto val_10 = 10;
1131  BEAST_EXPECT(!get_if_exists(s, "a_string", val_10));
1132  BEAST_EXPECT(val_10 == 10);
1133 
1134  BEAST_EXPECT(s.get<int>("not_a_key") == std::nullopt);
1135  try
1136  {
1137  s.get<int>("a_string");
1138  fail();
1139  }
1140  catch (boost::bad_lexical_cast&)
1141  {
1142  pass();
1143  }
1144  }
1145 
1146  {
1147  bool flag_1 = false;
1148  BEAST_EXPECT(get_if_exists(s, "bool_ish", flag_1));
1149  BEAST_EXPECT(flag_1 == true);
1150 
1151  bool flag_2 = false;
1152  BEAST_EXPECT(!get_if_exists(s, "not_a_key", flag_2));
1153  BEAST_EXPECT(flag_2 == false);
1154  }
1155  }
1156 
1157  void
1158  testAmendment()
1159  {
1160  testcase("amendment");
1161  struct ConfigUnit
1162  {
1163  std::string unit;
1164  std::uint32_t numSeconds;
1165  std::uint32_t configVal;
1166  bool shouldPass;
1167  };
1168 
1169  std::vector<ConfigUnit> units = {
1170  {"seconds", 1, 15 * 60, false},
1171  {"minutes", 60, 14, false},
1172  {"minutes", 60, 15, true},
1173  {"hours", 3600, 10, true},
1174  {"days", 86400, 10, true},
1175  {"weeks", 604800, 2, true},
1176  {"months", 2592000, 1, false},
1177  {"years", 31536000, 1, false}};
1178 
1179  std::string space = "";
1180  for (auto& [unit, sec, val, shouldPass] : units)
1181  {
1182  Config c;
1183  std::string toLoad(R"rippleConfig(
1184 [amendment_majority_time]
1185 )rippleConfig");
1186  toLoad += std::to_string(val) + space + unit;
1187  space = space == "" ? " " : "";
1188 
1189  try
1190  {
1191  c.loadFromString(toLoad);
1192  if (shouldPass)
1193  BEAST_EXPECT(
1194  c.AMENDMENT_MAJORITY_TIME.count() == val * sec);
1195  else
1196  fail();
1197  }
1198  catch (std::runtime_error&)
1199  {
1200  if (!shouldPass)
1201  pass();
1202  else
1203  fail();
1204  }
1205  }
1206  }
1207 
1208  void
1209  testOverlay()
1210  {
1211  testcase("overlay: unknown time");
1212 
1213  auto testUnknown =
1215  try
1216  {
1217  Config c;
1218  c.loadFromString("[overlay]\nmax_unknown_time=" + value);
1219  return c.MAX_UNKNOWN_TIME;
1220  }
1221  catch (std::runtime_error&)
1222  {
1223  return {};
1224  }
1225  };
1226 
1227  // Failures
1228  BEAST_EXPECT(!testUnknown("none"));
1229  BEAST_EXPECT(!testUnknown("0.5"));
1230  BEAST_EXPECT(!testUnknown("180 seconds"));
1231  BEAST_EXPECT(!testUnknown("9 minutes"));
1232 
1233  // Below lower bound
1234  BEAST_EXPECT(!testUnknown("299"));
1235 
1236  // In bounds
1237  BEAST_EXPECT(testUnknown("300") == std::chrono::seconds{300});
1238  BEAST_EXPECT(testUnknown("301") == std::chrono::seconds{301});
1239  BEAST_EXPECT(testUnknown("1799") == std::chrono::seconds{1799});
1240  BEAST_EXPECT(testUnknown("1800") == std::chrono::seconds{1800});
1241 
1242  // Above upper bound
1243  BEAST_EXPECT(!testUnknown("1801"));
1244 
1245  testcase("overlay: diverged time");
1246 
1247  // In bounds:
1248  auto testDiverged =
1250  try
1251  {
1252  Config c;
1253  c.loadFromString("[overlay]\nmax_diverged_time=" + value);
1254  return c.MAX_DIVERGED_TIME;
1255  }
1256  catch (std::runtime_error&)
1257  {
1258  return {};
1259  }
1260  };
1261 
1262  // Failures
1263  BEAST_EXPECT(!testDiverged("none"));
1264  BEAST_EXPECT(!testDiverged("0.5"));
1265  BEAST_EXPECT(!testDiverged("180 seconds"));
1266  BEAST_EXPECT(!testDiverged("9 minutes"));
1267 
1268  // Below lower bound
1269  BEAST_EXPECT(!testDiverged("0"));
1270  BEAST_EXPECT(!testDiverged("59"));
1271 
1272  // In bounds
1273  BEAST_EXPECT(testDiverged("60") == std::chrono::seconds{60});
1274  BEAST_EXPECT(testDiverged("61") == std::chrono::seconds{61});
1275  BEAST_EXPECT(testDiverged("899") == std::chrono::seconds{899});
1276  BEAST_EXPECT(testDiverged("900") == std::chrono::seconds{900});
1277 
1278  // Above upper bound
1279  BEAST_EXPECT(!testDiverged("901"));
1280  }
1281 
1282  void
1283  run() override
1284  {
1285  testLegacy();
1286  testDbPath();
1287  testValidatorKeys();
1288  testValidatorsFile();
1289  testSetup(false);
1290  testSetup(true);
1291  testPort();
1292  testWhitespace();
1293  testColons();
1294  testComments();
1295  testGetters();
1296  testAmendment();
1297  testOverlay();
1298  testNetworkID();
1299  }
1300 };
1301 
1302 BEAST_DEFINE_TESTSUITE(Config, core, ripple);
1303 
1304 } // namespace ripple
ripple::Config_test::testWhitespace
void testWhitespace()
Definition: Config_test.cpp:883
ripple::Config_test
Definition: Config_test.cpp:269
ripple::detail::RippledCfgGuard::RippledCfgGuard
RippledCfgGuard(beast::unit_test::suite &test, path subDir, path const &dbPath, path const &validatorsFile, bool useCounter=true)
Definition: Config_test.cpp:137
fstream
std::string
STL class.
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::detail::ValidatorsTxtGuard::ValidatorsTxtGuard
ValidatorsTxtGuard(beast::unit_test::suite &test, path subDir, path const &validatorsFileName, bool useCounter=true)
Definition: Config_test.cpp:235
std::exception
STL class.
std::string_view
STL class.
ripple::test::detail::DirGuard
Create a directory and remove it when it's done.
Definition: FileDirGuard.h:34
ripple::ParsedPort::admin_nets_v6
std::vector< boost::asio::ip::network_v6 > admin_nets_v6
Definition: Port.h:117
ripple::Config_test::testSetup
void testSetup(bool explicitPath)
Definition: Config_test.cpp:745
std::vector
STL class.
std::vector::size
T size(T... args)
ripple::detail::RippledCfgGuard::config_
Config config_
Definition: Config_test.cpp:134
std::chrono::seconds
ripple::Config::silent
bool silent() const
Definition: Config.h:327
ripple::detail::ValidatorsTxtGuard::validatorsFile
std::string validatorsFile() const
Definition: Config_test.cpp:258
ripple::Config_test::testDbPath
void testDbPath()
Definition: Config_test.cpp:303
ripple::parse_Port
void parse_Port(ParsedPort &port, Section const &section, std::ostream &log)
Definition: Port.cpp:199
ripple::Config_test::path
boost::filesystem::path path
Definition: Config_test.cpp:272
ripple::ParsedPort
Definition: Port.h:96
iostream
ripple::Config::quiet
bool quiet() const
Definition: Config.h:322
ripple::test::detail::DirGuard::subdir
path const & subdir() const
Definition: FileDirGuard.h:98
ripple::Section::values
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition: BasicConfig.h:77
ripple::detail::RippledCfgGuard::~RippledCfgGuard
~RippledCfgGuard()
Definition: Config_test.cpp:186
ripple::get_if_exists
bool get_if_exists(Section const &section, std::string const &name, T &v)
Definition: BasicConfig.h:384
ripple::Config_test::testLegacy
void testLegacy()
Definition: Config_test.cpp:276
ripple::test::detail::FileDirGuard::file
path const & file() const
Definition: FileDirGuard.h:164
ripple::detail::ValidatorsTxtGuard::validatorsFileExists
bool validatorsFileExists() const
Definition: Config_test.cpp:252
ripple::Config::loadFromString
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
Definition: Config.cpp:457
ripple::detail::RippledCfgGuard::configFile
std::string configFile() const
Definition: Config_test.cpp:169
ripple::Config
Definition: Config.h:89
std::ofstream
STL class.
ripple::Config_test::testPort
void testPort()
Definition: Config_test.cpp:864
ripple::Config::IPS_FIXED
std::vector< std::string > IPS_FIXED
Definition: Config.h:150
ripple::Config::standalone
bool standalone() const
Definition: Config.h:332
std::to_string
T to_string(T... args)
ripple::set
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
Definition: BasicConfig.h:313
std::array
STL class.
ripple::validationSeed
static std::optional< Seed > validationSeed(Json::Value const &params)
Definition: ValidationCreate.cpp:30
ripple::BasicConfig::legacy
void legacy(std::string const &section, std::string value)
Set a value that is not a key/value pair.
Definition: BasicConfig.cpp:164
ripple::Section::lines
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition: BasicConfig.h:68
ripple::detail::valFileContents
std::string valFileContents()
Definition: Config_test.cpp:203
std::runtime_error
STL class.
ripple::test::detail::DirGuard::test_
beast::unit_test::suite & test_
Definition: FileDirGuard.h:44
std::uint32_t
ripple::Config::databaseDirName
static char const *const databaseDirName
Definition: Config.h:94
ripple::detail::RippledCfgGuard::configFileExists
bool configFileExists() const
Definition: Config_test.cpp:181
ripple::detail::RippledCfgGuard
Write a rippled config file and remove when done.
Definition: Config_test.cpp:127
ripple::Config::LEDGER_HISTORY
std::uint32_t LEDGER_HISTORY
Definition: Config.h:212
ripple::TestSuite
Definition: TestSuite.h:28
std::experimental::filesystem::space
T space(T... args)
beast::field
field_t< CharT, Traits, Allocator > field(std::basic_string< CharT, Traits, Allocator > const &text, int width=8, int pad=0, bool right=false)
Definition: iosformat.h:162
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::detail::FileDirGuard::FileDirGuard
FileDirGuard(beast::unit_test::suite &test, path subDir, path file, std::string const &contents, bool useCounter=true, bool create=true)
Definition: FileDirGuard.h:114
ripple::detail::RippledCfgGuard::rmDataDir_
bool rmDataDir_
Definition: Config_test.cpp:132
ripple::Config::setup
void setup(std::string const &strConf, bool bQuiet, bool bSilent, bool bStandalone)
Definition: Config.cpp:315
std::endl
T endl(T... args)
ripple::Config::NETWORK_ID
uint32_t NETWORK_ID
Definition: Config.h:161
ripple::Config_test::testValidatorsFile
void testValidatorsFile()
Definition: Config_test.cpp:480
std
STL namespace.
std::string::empty
T empty(T... args)
std::optional
ripple::Config::IPS
std::vector< std::string > IPS
Definition: Config.h:149
ripple::test::detail::FileDirGuard::fileExists
bool fileExists() const
Definition: FileDirGuard.h:170
ripple::test::detail::FileDirGuard
Write a file in a directory and remove when done.
Definition: FileDirGuard.h:107
ripple::test::detail::DirGuard::rmDir
auto rmDir(path const &toRm)
Definition: FileDirGuard.h:47
ripple::Config_test::testValidatorKeys
void testValidatorKeys()
Definition: Config_test.cpp:371
ripple::test::detail::FileDirGuard::file_
const path file_
Definition: FileDirGuard.h:110
ripple::detail::RippledCfgGuard::dataDirExists
bool dataDirExists() const
Definition: Config_test.cpp:175
ripple::detail::ValidatorsTxtGuard
Write a validators.txt file and remove when done.
Definition: Config_test.cpp:232
ripple::detail::configContents
std::string configContents(std::string const &dbPath, std::string const &validatorsFile)
Definition: Config_test.cpp:34
ripple::Config_test::testNetworkID
void testNetworkID()
Definition: Config_test.cpp:415
ripple::detail::RippledCfgGuard::dataDir_
path dataDir_
Definition: Config_test.cpp:130
ripple::test::detail::DirGuard::path
boost::filesystem::path path
Definition: FileDirGuard.h:37
ripple::detail::ValidatorsTxtGuard::~ValidatorsTxtGuard
~ValidatorsTxtGuard()
Definition: Config_test.cpp:263
std::exception::what
T what(T... args)
ripple::BasicConfig::exists
bool exists(std::string const &name) const
Returns true if a section with the given name exists.
Definition: BasicConfig.cpp:121
ripple::BasicConfig::section
Section & section(std::string const &name)
Returns the section with the given name.
Definition: BasicConfig.cpp:127
ripple::Config::MAX_DIVERGED_TIME
std::chrono::seconds MAX_DIVERGED_TIME
Definition: Config.h:290
ripple::detail::RippledCfgGuard::config
Config const & config() const
Definition: Config_test.cpp:163
ripple::ParsedPort::admin_nets_v4
std::vector< boost::asio::ip::network_v4 > admin_nets_v4
Definition: Port.h:116