mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-05 16:57:53 +00:00
BasicConfig support for legacy values:
* A legacy value is a config section with a single-line. * These values may be read from the BasicConfig interface so the deprecated Config class does not need to be exposed to clients. * Made Config class more testable.
This commit is contained in:
@@ -1926,6 +1926,9 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\LoadMonitor.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\core\tests\Config.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\tests\LoadFeeTrack.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
||||
@@ -2844,6 +2844,9 @@
|
||||
<ClInclude Include="..\..\src\ripple\core\LoadMonitor.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\core\tests\Config.test.cpp">
|
||||
<Filter>ripple\core\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\tests\LoadFeeTrack.test.cpp">
|
||||
<Filter>ripple\core\tests</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -698,7 +698,8 @@
|
||||
# There are 4 book-keeping SQLite database that the server creates and
|
||||
# maintains. If you omit this configuration setting, it will default to
|
||||
# creating a directory called "db" located in the same place as your
|
||||
# rippled.cfg file.
|
||||
# rippled.cfg file. Partial pathnames will be considered relative to
|
||||
# the location of the rippled executable.
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
@@ -58,7 +58,7 @@ setup_DatabaseCon (Config const& c)
|
||||
setup.onlineDelete = c.nodeDatabase["online_delete"].getIntValue();
|
||||
setup.startUp = c.START_UP;
|
||||
setup.standAlone = c.RUN_STANDALONE;
|
||||
setup.dataDir = c.DATA_DIR;
|
||||
setup.dataDir = c.legacy ("database_path");
|
||||
|
||||
return setup;
|
||||
}
|
||||
|
||||
@@ -887,7 +887,8 @@ public:
|
||||
{
|
||||
// VFALCO TODO Move all this into doSweep
|
||||
|
||||
boost::filesystem::space_info space = boost::filesystem::space (getConfig ().DATA_DIR);
|
||||
boost::filesystem::space_info space =
|
||||
boost::filesystem::space (getConfig ().legacy ("database_path"));
|
||||
|
||||
// VFALCO TODO Give this magic constant a name and move it into a well documented header
|
||||
//
|
||||
|
||||
@@ -700,7 +700,7 @@ setup_SHAMapStore (Config const& c)
|
||||
setup.ledgerHistory = c.LEDGER_HISTORY;
|
||||
setup.nodeDatabase = c.nodeDatabase;
|
||||
setup.ephemeralNodeDatabase = c.ephemeralNodeDatabase;
|
||||
setup.databasePath = c.DATABASE_PATH;
|
||||
setup.databasePath = c.legacy("database_path");
|
||||
if (c.nodeDatabase["delete_batch"].isNotEmpty())
|
||||
setup.deleteBatch = c.nodeDatabase["delete_batch"].getIntValue();
|
||||
if (c.nodeDatabase["backOff"].isNotEmpty())
|
||||
|
||||
@@ -76,6 +76,38 @@ public:
|
||||
return values_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the legacy value for this section.
|
||||
*/
|
||||
void
|
||||
legacy (std::string value)
|
||||
{
|
||||
if (lines_.empty ())
|
||||
lines_.emplace_back (std::move (value));
|
||||
else
|
||||
{
|
||||
assert (lines_.size () == 1);
|
||||
lines_[0] = std::move (value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the legacy value for this section.
|
||||
*
|
||||
* @return The retrieved value. A section with an empty legacy value returns
|
||||
an empty string.
|
||||
*/
|
||||
std::string
|
||||
legacy () const
|
||||
{
|
||||
if (lines_.empty ())
|
||||
return "";
|
||||
else if (lines_.size () > 1)
|
||||
throw std::runtime_error (
|
||||
"A legacy value must have exactly one line. Section: " + name_);
|
||||
return lines_[0];
|
||||
}
|
||||
|
||||
/** Set a key/value pair.
|
||||
The previous value is discarded.
|
||||
*/
|
||||
@@ -150,6 +182,29 @@ public:
|
||||
overwrite (std::string const& section, std::string const& key,
|
||||
std::string const& value);
|
||||
|
||||
/**
|
||||
* Set a value that is not a key/value pair.
|
||||
*
|
||||
* The value is stored as the section's first value and may be retrieved
|
||||
* through section::legacy.
|
||||
*
|
||||
* @param section Name of the section to modify.
|
||||
* @param value Contents of the legacy value.
|
||||
*/
|
||||
void
|
||||
legacy(std::string const& section, std::string value);
|
||||
|
||||
/**
|
||||
* Get the legacy value of a section. A section with a
|
||||
* single-line value may be retrieved as a legacy value.
|
||||
*
|
||||
* @param sectionName Retrieve the contents of this section's
|
||||
* legacy value.
|
||||
* @returun Contents of the legacy value.
|
||||
*/
|
||||
std::string
|
||||
legacy(std::string const& sectionName) const;
|
||||
|
||||
friend
|
||||
std::ostream&
|
||||
operator<< (std::ostream& ss, BasicConfig const& c);
|
||||
@@ -157,15 +212,6 @@ public:
|
||||
protected:
|
||||
void
|
||||
build (IniFileSections const& ifs);
|
||||
|
||||
/** Insert a legacy single section as a key/value pair.
|
||||
Does nothing if the section does not exist, or does not contain
|
||||
a single line that is not a key/value pair.
|
||||
@deprecated
|
||||
*/
|
||||
void
|
||||
remap (std::string const& legacy_section,
|
||||
std::string const& key, std::string const& new_section);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -106,24 +106,6 @@ BasicConfig::section (std::string const& name) const
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void
|
||||
BasicConfig::remap (std::string const& legacy_section,
|
||||
std::string const& key, std::string const& new_section)
|
||||
{
|
||||
auto const iter = map_.find (legacy_section);
|
||||
if (iter == map_.end())
|
||||
return;
|
||||
if (iter->second.size() != 0)
|
||||
return;
|
||||
if (iter->second.lines().size() != 1)
|
||||
return;
|
||||
auto result = map_.emplace(std::piecewise_construct,
|
||||
std::make_tuple(new_section), std::make_tuple(new_section));
|
||||
auto& s = result.first->second;
|
||||
s.append (iter->second.lines().front());
|
||||
s.set (key, iter->second.lines().front());
|
||||
}
|
||||
|
||||
void
|
||||
BasicConfig::overwrite (std::string const& section, std::string const& key,
|
||||
std::string const& value)
|
||||
@@ -133,6 +115,18 @@ BasicConfig::overwrite (std::string const& section, std::string const& key,
|
||||
result.first->second.set (key, value);
|
||||
}
|
||||
|
||||
void
|
||||
BasicConfig::legacy(std::string const& section, std::string value)
|
||||
{
|
||||
map_[section].legacy(std::move(value));
|
||||
}
|
||||
|
||||
std::string
|
||||
BasicConfig::legacy(std::string const& sectionName) const
|
||||
{
|
||||
return section (sectionName).legacy ();
|
||||
}
|
||||
|
||||
void
|
||||
BasicConfig::build (IniFileSections const& ifs)
|
||||
{
|
||||
|
||||
@@ -87,10 +87,10 @@ struct SizedItem
|
||||
int sizes[5];
|
||||
};
|
||||
|
||||
// VFALCO NOTE This entire derived class is deprecated
|
||||
// For new config information use the style implied
|
||||
// in the base class. For existing config information
|
||||
// try to refactor code to use the new style.
|
||||
// This entire derived class is deprecated.
|
||||
// For new config information use the style implied
|
||||
// in the base class. For existing config information
|
||||
// try to refactor code to use the new style.
|
||||
//
|
||||
class Config : public BasicConfig
|
||||
{
|
||||
@@ -121,20 +121,17 @@ public:
|
||||
/** Returns the directory from which the configuration file was loaded. */
|
||||
beast::File getConfigDir () const;
|
||||
|
||||
/** Returns the directory in which the current database files are located. */
|
||||
beast::File getDatabaseDir () const;
|
||||
|
||||
/** Returns the full path and filename of the debug log file. */
|
||||
boost::filesystem::path getDebugLogFile () const;
|
||||
|
||||
// LEGACY FIELDS, REMOVE ASAP
|
||||
// DEPRECATED
|
||||
boost::filesystem::path CONFIG_FILE; // used by UniqueNodeList
|
||||
private:
|
||||
boost::filesystem::path CONFIG_DIR;
|
||||
boost::filesystem::path DEBUG_LOGFILE;
|
||||
|
||||
void load ();
|
||||
public:
|
||||
// VFALCO TODO Make this private and fix callers to go through getDatabaseDir()
|
||||
boost::filesystem::path DATA_DIR;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -152,10 +149,6 @@ public:
|
||||
/** List of Validators entries from rippled.cfg */
|
||||
std::vector <std::string> validators;
|
||||
|
||||
private:
|
||||
/** The folder where new module databases should be located */
|
||||
beast::File m_moduleDbPath;
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------------
|
||||
/** Returns the location were databases should be located
|
||||
@@ -164,7 +157,7 @@ public:
|
||||
stored in a file named after the module (e.g. "peerfinder.sqlite") that
|
||||
is inside that directory.
|
||||
*/
|
||||
beast::File const& getModuleDatabasePath ();
|
||||
beast::File getModuleDatabasePath () const;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -234,9 +227,6 @@ public:
|
||||
|
||||
std::string START_LEDGER;
|
||||
|
||||
// Database
|
||||
std::string DATABASE_PATH;
|
||||
|
||||
// Network parameters
|
||||
int TRANSACTION_FEE_BASE; // The number of fee units a reference transaction costs
|
||||
|
||||
@@ -312,10 +302,16 @@ public:
|
||||
|
||||
int getSize (SizedItemName) const;
|
||||
void setup (std::string const& strConf, bool bQuiet);
|
||||
void load ();
|
||||
|
||||
/**
|
||||
* Load the conig from the contents of the sting.
|
||||
*
|
||||
* @param fileContents String representing the config contents.
|
||||
*/
|
||||
void loadFromString (std::string const& fileContents);
|
||||
};
|
||||
|
||||
// VFALCO DEPRECATED
|
||||
// DEPRECATED
|
||||
extern Config& getConfig();
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -34,7 +34,6 @@ struct ConfigSection
|
||||
#define SECTION_ACCOUNT_PROBE_MAX "account_probe_max"
|
||||
#define SECTION_AMENDMENTS "amendments"
|
||||
#define SECTION_CLUSTER_NODES "cluster_nodes"
|
||||
#define SECTION_DATABASE_PATH "database_path"
|
||||
#define SECTION_DEBUG_LOGFILE "debug_logfile"
|
||||
#define SECTION_ELB_SUPPORT "elb_support"
|
||||
#define SECTION_FEE_DEFAULT "fee_default"
|
||||
|
||||
@@ -284,6 +284,7 @@ getEnvVar (char const* name)
|
||||
|
||||
void Config::setup (std::string const& strConf, bool bQuiet)
|
||||
{
|
||||
boost::filesystem::path dataDir;
|
||||
boost::system::error_code ec;
|
||||
std::string strDbPath, strConfFile;
|
||||
|
||||
@@ -309,13 +310,13 @@ void Config::setup (std::string const& strConf, bool bQuiet)
|
||||
CONFIG_FILE = strConfFile;
|
||||
CONFIG_DIR = boost::filesystem::absolute (CONFIG_FILE);
|
||||
CONFIG_DIR.remove_filename ();
|
||||
DATA_DIR = CONFIG_DIR / strDbPath;
|
||||
dataDir = CONFIG_DIR / strDbPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
CONFIG_DIR = boost::filesystem::current_path ();
|
||||
CONFIG_FILE = CONFIG_DIR / strConfFile;
|
||||
DATA_DIR = CONFIG_DIR / strDbPath;
|
||||
dataDir = CONFIG_DIR / strDbPath;
|
||||
|
||||
// Construct XDG config and data home.
|
||||
// http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
@@ -345,7 +346,7 @@ void Config::setup (std::string const& strConf, bool bQuiet)
|
||||
|
||||
CONFIG_DIR = strXdgConfigHome + "/" + systemName ();
|
||||
CONFIG_FILE = CONFIG_DIR / strConfFile;
|
||||
DATA_DIR = strXdgDataHome + "/" + systemName ();
|
||||
dataDir = strXdgDataHome + "/" + systemName ();
|
||||
|
||||
boost::filesystem::create_directories (CONFIG_DIR, ec);
|
||||
|
||||
@@ -358,274 +359,257 @@ void Config::setup (std::string const& strConf, bool bQuiet)
|
||||
|
||||
// Update default values
|
||||
load ();
|
||||
{
|
||||
// load() may have set a new value for the dataDir
|
||||
std::string const dbPath (legacy ("database_path"));
|
||||
if (!dbPath.empty ())
|
||||
{
|
||||
dataDir = boost::filesystem::path (dbPath);
|
||||
}
|
||||
}
|
||||
|
||||
boost::filesystem::create_directories (DATA_DIR, ec);
|
||||
boost::filesystem::create_directories (dataDir, ec);
|
||||
|
||||
if (ec)
|
||||
throw std::runtime_error (boost::str (boost::format ("Can not create %s") % DATA_DIR));
|
||||
throw std::runtime_error (
|
||||
boost::str (boost::format ("Can not create %s") % dataDir));
|
||||
|
||||
// Create the new unified database
|
||||
m_moduleDbPath = getDatabaseDir();
|
||||
|
||||
// This code is temporarily disabled, and modules will fall back to using
|
||||
// per-module databases (e.g. "peerfinder.sqlite") under the module db path
|
||||
//
|
||||
//if (m_moduleDbPath.isDirectory ())
|
||||
// m_moduleDbPath = m_moduleDbPath.getChildFile("rippled.sqlite");
|
||||
legacy ("database_path", boost::filesystem::absolute (dataDir).string ());
|
||||
}
|
||||
|
||||
void Config::load ()
|
||||
{
|
||||
if (!QUIET)
|
||||
std::cerr << "Loading: " << CONFIG_FILE << std::endl;
|
||||
std::cerr << "Loading: " << CONFIG_FILE << "\n";
|
||||
|
||||
std::ifstream ifsConfig (CONFIG_FILE.c_str (), std::ios::in);
|
||||
std::ifstream ifsConfig (CONFIG_FILE.c_str (), std::ios::in);
|
||||
|
||||
if (!ifsConfig)
|
||||
{
|
||||
std::cerr << "Failed to open '" << CONFIG_FILE << "'." << std::endl;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string file_contents;
|
||||
file_contents.assign ((std::istreambuf_iterator<char> (ifsConfig)),
|
||||
std::istreambuf_iterator<char> ());
|
||||
|
||||
if (ifsConfig.bad ())
|
||||
std::string fileContents;
|
||||
fileContents.assign ((std::istreambuf_iterator<char>(ifsConfig)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
if (ifsConfig.bad ())
|
||||
{
|
||||
std::cerr << "Failed to read '" << CONFIG_FILE << "'." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
loadFromString (fileContents);
|
||||
}
|
||||
|
||||
void Config::loadFromString (std::string const& fileContents)
|
||||
{
|
||||
IniFileSections secConfig = parseIniFile (fileContents, true);
|
||||
|
||||
build (secConfig);
|
||||
|
||||
if (auto s = getIniFileSection (secConfig, SECTION_VALIDATORS))
|
||||
validators = *s;
|
||||
|
||||
if (auto s = getIniFileSection (secConfig, SECTION_CLUSTER_NODES))
|
||||
CLUSTER_NODES = *s;
|
||||
|
||||
if (auto s = getIniFileSection (secConfig, SECTION_IPS))
|
||||
IPS = *s;
|
||||
|
||||
if (auto s = getIniFileSection (secConfig, SECTION_IPS_FIXED))
|
||||
IPS_FIXED = *s;
|
||||
|
||||
if (auto s = getIniFileSection (secConfig, SECTION_SNTP))
|
||||
SNTP_SERVERS = *s;
|
||||
|
||||
if (auto s = getIniFileSection (secConfig, SECTION_RPC_STARTUP))
|
||||
{
|
||||
RPC_STARTUP = Json::arrayValue;
|
||||
|
||||
for (auto const& strJson : *s)
|
||||
{
|
||||
std::cerr << "Failed to read '" << CONFIG_FILE << "'." << std::endl;
|
||||
Json::Reader jrReader;
|
||||
Json::Value jvCommand;
|
||||
|
||||
if (!jrReader.parse (strJson, jvCommand))
|
||||
throw std::runtime_error (
|
||||
boost::str (boost::format (
|
||||
"Couldn't parse [" SECTION_RPC_STARTUP "] command: %s") % strJson));
|
||||
|
||||
RPC_STARTUP.append (jvCommand);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::string dbPath;
|
||||
if (getSingleSection (secConfig, "database_path", dbPath))
|
||||
{
|
||||
boost::filesystem::path p(dbPath);
|
||||
legacy("database_path",
|
||||
boost::filesystem::absolute (p).string ());
|
||||
}
|
||||
}
|
||||
|
||||
(void) getSingleSection (secConfig, SECTION_VALIDATORS_SITE, VALIDATORS_SITE);
|
||||
|
||||
std::string strTemp;
|
||||
if (getSingleSection (secConfig, SECTION_PEER_PRIVATE, strTemp))
|
||||
PEER_PRIVATE = beast::lexicalCastThrow <bool> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_PEERS_MAX, strTemp))
|
||||
PEERS_MAX = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (auto s = getIniFileSection (secConfig, SECTION_RPC_ADMIN_ALLOW))
|
||||
{
|
||||
std::vector<beast::IP::Endpoint> parsedAddresses;
|
||||
parseAddresses (parsedAddresses, (*s).cbegin(), (*s).cend());
|
||||
RPC_ADMIN_ALLOW.insert (RPC_ADMIN_ALLOW.end(),
|
||||
parsedAddresses.cbegin (), parsedAddresses.cend ());
|
||||
}
|
||||
|
||||
insightSettings = parseKeyValueSection (secConfig, SECTION_INSIGHT);
|
||||
|
||||
nodeDatabase = parseKeyValueSection (
|
||||
secConfig, ConfigSection::nodeDatabase ());
|
||||
|
||||
ephemeralNodeDatabase = parseKeyValueSection (
|
||||
secConfig, ConfigSection::tempNodeDatabase ());
|
||||
|
||||
importNodeDatabase = parseKeyValueSection (
|
||||
secConfig, ConfigSection::importNodeDatabase ());
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_NODE_SIZE, strTemp))
|
||||
{
|
||||
if (strTemp == "tiny")
|
||||
NODE_SIZE = 0;
|
||||
else if (strTemp == "small")
|
||||
NODE_SIZE = 1;
|
||||
else if (strTemp == "medium")
|
||||
NODE_SIZE = 2;
|
||||
else if (strTemp == "large")
|
||||
NODE_SIZE = 3;
|
||||
else if (strTemp == "huge")
|
||||
NODE_SIZE = 4;
|
||||
else
|
||||
{
|
||||
IniFileSections secConfig = parseIniFile (file_contents, true);
|
||||
std::string strTemp;
|
||||
NODE_SIZE = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
build (secConfig);
|
||||
|
||||
// XXX Leak
|
||||
IniFileSections::mapped_type* smtTmp;
|
||||
|
||||
smtTmp = getIniFileSection (secConfig, SECTION_VALIDATORS);
|
||||
|
||||
if (smtTmp)
|
||||
{
|
||||
validators = *smtTmp;
|
||||
}
|
||||
|
||||
smtTmp = getIniFileSection (secConfig, SECTION_CLUSTER_NODES);
|
||||
|
||||
if (smtTmp)
|
||||
{
|
||||
CLUSTER_NODES = *smtTmp;
|
||||
}
|
||||
|
||||
smtTmp = getIniFileSection (secConfig, SECTION_IPS);
|
||||
|
||||
if (smtTmp)
|
||||
{
|
||||
IPS = *smtTmp;
|
||||
}
|
||||
|
||||
smtTmp = getIniFileSection (secConfig, SECTION_IPS_FIXED);
|
||||
|
||||
if (smtTmp)
|
||||
{
|
||||
IPS_FIXED = *smtTmp;
|
||||
}
|
||||
|
||||
smtTmp = getIniFileSection (secConfig, SECTION_SNTP);
|
||||
|
||||
if (smtTmp)
|
||||
{
|
||||
SNTP_SERVERS = *smtTmp;
|
||||
}
|
||||
|
||||
smtTmp = getIniFileSection (secConfig, SECTION_RPC_STARTUP);
|
||||
|
||||
if (smtTmp)
|
||||
{
|
||||
RPC_STARTUP = Json::arrayValue;
|
||||
|
||||
for (auto const& strJson : *smtTmp)
|
||||
{
|
||||
Json::Reader jrReader;
|
||||
Json::Value jvCommand;
|
||||
|
||||
if (!jrReader.parse (strJson, jvCommand))
|
||||
throw std::runtime_error (
|
||||
boost::str (boost::format (
|
||||
"Couldn't parse [" SECTION_RPC_STARTUP "] command: %s") % strJson));
|
||||
|
||||
RPC_STARTUP.append (jvCommand);
|
||||
}
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_DATABASE_PATH, DATABASE_PATH))
|
||||
DATA_DIR = DATABASE_PATH;
|
||||
|
||||
(void) getSingleSection (secConfig, SECTION_VALIDATORS_SITE, VALIDATORS_SITE);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_PEER_PRIVATE, strTemp))
|
||||
PEER_PRIVATE = beast::lexicalCastThrow <bool> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_PEERS_MAX, strTemp))
|
||||
PEERS_MAX = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
smtTmp = getIniFileSection (secConfig, SECTION_RPC_ADMIN_ALLOW);
|
||||
|
||||
if (smtTmp)
|
||||
{
|
||||
std::vector<beast::IP::Endpoint> parsedAddresses;
|
||||
//parseAddresses<std::vector<beast::IP::Endpoint>, std::vector<std::string>::const_iterator>
|
||||
// (parsedAddresses, (*smtTmp).cbegin(), (*smtTmp).cend());
|
||||
parseAddresses (parsedAddresses, (*smtTmp).cbegin(), (*smtTmp).cend());
|
||||
RPC_ADMIN_ALLOW.insert (RPC_ADMIN_ALLOW.end(),
|
||||
parsedAddresses.cbegin (), parsedAddresses.cend ());
|
||||
}
|
||||
|
||||
insightSettings = parseKeyValueSection (secConfig, SECTION_INSIGHT);
|
||||
|
||||
nodeDatabase = parseKeyValueSection (
|
||||
secConfig, ConfigSection::nodeDatabase ());
|
||||
|
||||
ephemeralNodeDatabase = parseKeyValueSection (
|
||||
secConfig, ConfigSection::tempNodeDatabase ());
|
||||
|
||||
importNodeDatabase = parseKeyValueSection (
|
||||
secConfig, ConfigSection::importNodeDatabase ());
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_NODE_SIZE, strTemp))
|
||||
{
|
||||
if (strTemp == "tiny")
|
||||
NODE_SIZE = 0;
|
||||
else if (strTemp == "small")
|
||||
NODE_SIZE = 1;
|
||||
else if (strTemp == "medium")
|
||||
NODE_SIZE = 2;
|
||||
else if (strTemp == "large")
|
||||
NODE_SIZE = 3;
|
||||
else if (strTemp == "huge")
|
||||
NODE_SIZE = 4;
|
||||
else
|
||||
{
|
||||
NODE_SIZE = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (NODE_SIZE < 0)
|
||||
NODE_SIZE = 0;
|
||||
else if (NODE_SIZE > 4)
|
||||
NODE_SIZE = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_ELB_SUPPORT, strTemp))
|
||||
ELB_SUPPORT = beast::lexicalCastThrow <bool> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_WEBSOCKET_PING_FREQ, strTemp))
|
||||
WEBSOCKET_PING_FREQ = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
getSingleSection (secConfig, SECTION_SSL_VERIFY_FILE, SSL_VERIFY_FILE);
|
||||
getSingleSection (secConfig, SECTION_SSL_VERIFY_DIR, SSL_VERIFY_DIR);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_SSL_VERIFY, strTemp))
|
||||
SSL_VERIFY = beast::lexicalCastThrow <bool> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_VALIDATION_SEED, strTemp))
|
||||
{
|
||||
VALIDATION_SEED.setSeedGeneric (strTemp);
|
||||
|
||||
if (VALIDATION_SEED.isValid ())
|
||||
{
|
||||
VALIDATION_PUB = RippleAddress::createNodePublic (VALIDATION_SEED);
|
||||
VALIDATION_PRIV = RippleAddress::createNodePrivate (VALIDATION_SEED);
|
||||
}
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_NODE_SEED, strTemp))
|
||||
{
|
||||
NODE_SEED.setSeedGeneric (strTemp);
|
||||
|
||||
if (NODE_SEED.isValid ())
|
||||
{
|
||||
NODE_PUB = RippleAddress::createNodePublic (NODE_SEED);
|
||||
NODE_PRIV = RippleAddress::createNodePrivate (NODE_SEED);
|
||||
}
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_NETWORK_QUORUM, strTemp))
|
||||
NETWORK_QUORUM = beast::lexicalCastThrow <std::size_t> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_VALIDATION_QUORUM, strTemp))
|
||||
VALIDATION_QUORUM = std::max (0, beast::lexicalCastThrow <int> (strTemp));
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_ACCOUNT_RESERVE, strTemp))
|
||||
FEE_ACCOUNT_RESERVE = beast::lexicalCastThrow <std::uint64_t> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_OWNER_RESERVE, strTemp))
|
||||
FEE_OWNER_RESERVE = beast::lexicalCastThrow <std::uint64_t> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_OFFER, strTemp))
|
||||
FEE_OFFER = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_DEFAULT, strTemp))
|
||||
FEE_DEFAULT = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_OPERATION, strTemp))
|
||||
FEE_CONTRACT_OPERATION = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_LEDGER_HISTORY, strTemp))
|
||||
{
|
||||
boost::to_lower (strTemp);
|
||||
|
||||
if (strTemp == "full")
|
||||
LEDGER_HISTORY = 1000000000u;
|
||||
else if (strTemp == "none")
|
||||
LEDGER_HISTORY = 0;
|
||||
else
|
||||
LEDGER_HISTORY = beast::lexicalCastThrow <std::uint32_t> (strTemp);
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FETCH_DEPTH, strTemp))
|
||||
{
|
||||
boost::to_lower (strTemp);
|
||||
|
||||
if (strTemp == "none")
|
||||
FETCH_DEPTH = 0;
|
||||
else if (strTemp == "full")
|
||||
FETCH_DEPTH = 1000000000u;
|
||||
else
|
||||
FETCH_DEPTH = beast::lexicalCastThrow <std::uint32_t> (strTemp);
|
||||
|
||||
if (FETCH_DEPTH < 10)
|
||||
FETCH_DEPTH = 10;
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_PATH_SEARCH_OLD, strTemp))
|
||||
PATH_SEARCH_OLD = beast::lexicalCastThrow <int> (strTemp);
|
||||
if (getSingleSection (secConfig, SECTION_PATH_SEARCH, strTemp))
|
||||
PATH_SEARCH = beast::lexicalCastThrow <int> (strTemp);
|
||||
if (getSingleSection (secConfig, SECTION_PATH_SEARCH_FAST, strTemp))
|
||||
PATH_SEARCH_FAST = beast::lexicalCastThrow <int> (strTemp);
|
||||
if (getSingleSection (secConfig, SECTION_PATH_SEARCH_MAX, strTemp))
|
||||
PATH_SEARCH_MAX = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_ACCOUNT_PROBE_MAX, strTemp))
|
||||
ACCOUNT_PROBE_MAX = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_FROM, SMS_FROM);
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_KEY, SMS_KEY);
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_SECRET, SMS_SECRET);
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_TO, SMS_TO);
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_URL, SMS_URL);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_VALIDATORS_FILE, strTemp))
|
||||
{
|
||||
VALIDATORS_FILE = strTemp;
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_DEBUG_LOGFILE, strTemp))
|
||||
DEBUG_LOGFILE = strTemp;
|
||||
if (NODE_SIZE < 0)
|
||||
NODE_SIZE = 0;
|
||||
else if (NODE_SIZE > 4)
|
||||
NODE_SIZE = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_ELB_SUPPORT, strTemp))
|
||||
ELB_SUPPORT = beast::lexicalCastThrow <bool> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_WEBSOCKET_PING_FREQ, strTemp))
|
||||
WEBSOCKET_PING_FREQ = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
getSingleSection (secConfig, SECTION_SSL_VERIFY_FILE, SSL_VERIFY_FILE);
|
||||
getSingleSection (secConfig, SECTION_SSL_VERIFY_DIR, SSL_VERIFY_DIR);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_SSL_VERIFY, strTemp))
|
||||
SSL_VERIFY = beast::lexicalCastThrow <bool> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_VALIDATION_SEED, strTemp))
|
||||
{
|
||||
VALIDATION_SEED.setSeedGeneric (strTemp);
|
||||
|
||||
if (VALIDATION_SEED.isValid ())
|
||||
{
|
||||
VALIDATION_PUB = RippleAddress::createNodePublic (VALIDATION_SEED);
|
||||
VALIDATION_PRIV = RippleAddress::createNodePrivate (VALIDATION_SEED);
|
||||
}
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_NODE_SEED, strTemp))
|
||||
{
|
||||
NODE_SEED.setSeedGeneric (strTemp);
|
||||
|
||||
if (NODE_SEED.isValid ())
|
||||
{
|
||||
NODE_PUB = RippleAddress::createNodePublic (NODE_SEED);
|
||||
NODE_PRIV = RippleAddress::createNodePrivate (NODE_SEED);
|
||||
}
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_NETWORK_QUORUM, strTemp))
|
||||
NETWORK_QUORUM = beast::lexicalCastThrow <std::size_t> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_VALIDATION_QUORUM, strTemp))
|
||||
VALIDATION_QUORUM = std::max (0, beast::lexicalCastThrow <int> (strTemp));
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_ACCOUNT_RESERVE, strTemp))
|
||||
FEE_ACCOUNT_RESERVE = beast::lexicalCastThrow <std::uint64_t> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_OWNER_RESERVE, strTemp))
|
||||
FEE_OWNER_RESERVE = beast::lexicalCastThrow <std::uint64_t> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_OFFER, strTemp))
|
||||
FEE_OFFER = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_DEFAULT, strTemp))
|
||||
FEE_DEFAULT = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FEE_OPERATION, strTemp))
|
||||
FEE_CONTRACT_OPERATION = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_LEDGER_HISTORY, strTemp))
|
||||
{
|
||||
boost::to_lower (strTemp);
|
||||
|
||||
if (strTemp == "full")
|
||||
LEDGER_HISTORY = 1000000000u;
|
||||
else if (strTemp == "none")
|
||||
LEDGER_HISTORY = 0;
|
||||
else
|
||||
LEDGER_HISTORY = beast::lexicalCastThrow <std::uint32_t> (strTemp);
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_FETCH_DEPTH, strTemp))
|
||||
{
|
||||
boost::to_lower (strTemp);
|
||||
|
||||
if (strTemp == "none")
|
||||
FETCH_DEPTH = 0;
|
||||
else if (strTemp == "full")
|
||||
FETCH_DEPTH = 1000000000u;
|
||||
else
|
||||
FETCH_DEPTH = beast::lexicalCastThrow <std::uint32_t> (strTemp);
|
||||
|
||||
if (FETCH_DEPTH < 10)
|
||||
FETCH_DEPTH = 10;
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_PATH_SEARCH_OLD, strTemp))
|
||||
PATH_SEARCH_OLD = beast::lexicalCastThrow <int> (strTemp);
|
||||
if (getSingleSection (secConfig, SECTION_PATH_SEARCH, strTemp))
|
||||
PATH_SEARCH = beast::lexicalCastThrow <int> (strTemp);
|
||||
if (getSingleSection (secConfig, SECTION_PATH_SEARCH_FAST, strTemp))
|
||||
PATH_SEARCH_FAST = beast::lexicalCastThrow <int> (strTemp);
|
||||
if (getSingleSection (secConfig, SECTION_PATH_SEARCH_MAX, strTemp))
|
||||
PATH_SEARCH_MAX = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_ACCOUNT_PROBE_MAX, strTemp))
|
||||
ACCOUNT_PROBE_MAX = beast::lexicalCastThrow <int> (strTemp);
|
||||
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_FROM, SMS_FROM);
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_KEY, SMS_KEY);
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_SECRET, SMS_SECRET);
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_TO, SMS_TO);
|
||||
(void) getSingleSection (secConfig, SECTION_SMS_URL, SMS_URL);
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_VALIDATORS_FILE, strTemp))
|
||||
{
|
||||
VALIDATORS_FILE = strTemp;
|
||||
}
|
||||
|
||||
if (getSingleSection (secConfig, SECTION_DEBUG_LOGFILE, strTemp))
|
||||
DEBUG_LOGFILE = strTemp;
|
||||
}
|
||||
|
||||
int Config::getSize (SizedItemName item) const
|
||||
@@ -702,19 +686,12 @@ boost::filesystem::path Config::getDebugLogFile () const
|
||||
return log_file;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// VFALCO NOTE Clean members area
|
||||
//
|
||||
|
||||
Config& getConfig ()
|
||||
{
|
||||
static Config config;
|
||||
return config;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
beast::File Config::getConfigDir () const
|
||||
{
|
||||
beast::String const s (CONFIG_FILE.native().c_str ());
|
||||
@@ -723,14 +700,6 @@ beast::File Config::getConfigDir () const
|
||||
return beast::File::nonexistent ();
|
||||
}
|
||||
|
||||
beast::File Config::getDatabaseDir () const
|
||||
{
|
||||
beast::String const s (DATA_DIR.native().c_str());
|
||||
if (s.isNotEmpty ())
|
||||
return beast::File (s);
|
||||
return beast::File::nonexistent ();
|
||||
}
|
||||
|
||||
beast::File Config::getValidatorsFile () const
|
||||
{
|
||||
beast::String const s (VALIDATORS_FILE.native().c_str());
|
||||
@@ -744,9 +713,14 @@ beast::URL Config::getValidatorsURL () const
|
||||
return beast::parse_URL (VALIDATORS_SITE).second;
|
||||
}
|
||||
|
||||
beast::File const& Config::getModuleDatabasePath ()
|
||||
beast::File Config::getModuleDatabasePath () const
|
||||
{
|
||||
return m_moduleDbPath;
|
||||
boost::filesystem::path dbPath (legacy ("database_path"));
|
||||
|
||||
beast::String const s (dbPath.native ().c_str ());
|
||||
if (s.isNotEmpty ())
|
||||
return beast::File (s);
|
||||
return beast::File::nonexistent ();
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
356
src/ripple/core/tests/Config.test.cpp
Normal file
356
src/ripple/core/tests/Config.test.cpp
Normal file
@@ -0,0 +1,356 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012-2015 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/core/impl/LoadFeeTrackImp.h>
|
||||
#include <ripple/core/Config.h>
|
||||
#include <ripple/basics/TestSuite.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace ripple {
|
||||
namespace detail {
|
||||
std::string configContents (std::string const& dbPath)
|
||||
{
|
||||
static boost::format configContentsTemplate (R"rippleConfig(
|
||||
[server]
|
||||
port_rpc
|
||||
port_peer
|
||||
port_wss_admin
|
||||
|
||||
[port_rpc]
|
||||
port = 5005
|
||||
ip = 127.0.0.1
|
||||
admin = allow
|
||||
protocol = https
|
||||
|
||||
[port_peer]
|
||||
port = 51235
|
||||
ip = 0.0.0.0
|
||||
protocol = peer
|
||||
|
||||
[port_wss_admin]
|
||||
port = 6006
|
||||
ip = 127.0.0.1
|
||||
admin = allow
|
||||
protocol = wss
|
||||
|
||||
#[port_ws_public]
|
||||
#port = 5005
|
||||
#ip = 127.0.0.1
|
||||
#protocol = wss
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
[node_size]
|
||||
medium
|
||||
|
||||
# This is primary persistent datastore for rippled. This includes transaction
|
||||
# metadata, account states, and ledger headers. Helpful information can be
|
||||
# found here: https://ripple.com/wiki/NodeBackEnd
|
||||
# delete old ledgers while maintaining at least 2000. Do not require an
|
||||
# external administrative command to initiate deletion.
|
||||
[node_db]
|
||||
type=memory
|
||||
path=/Users/dummy/ripple/config/db/rocksdb
|
||||
open_files=2000
|
||||
filter_bits=12
|
||||
cache_mb=256
|
||||
file_size_mb=8
|
||||
file_size_mult=2
|
||||
|
||||
%1%
|
||||
%2%
|
||||
|
||||
# This needs to be an absolute directory reference, not a relative one.
|
||||
# Modify this value as required.
|
||||
[debug_logfile]
|
||||
/Users/dummy/ripple/config/log/debug.log
|
||||
|
||||
[sntp_servers]
|
||||
time.windows.com
|
||||
time.apple.com
|
||||
time.nist.gov
|
||||
pool.ntp.org
|
||||
|
||||
# Where to find some other servers speaking the Ripple protocol.
|
||||
#
|
||||
[ips]
|
||||
r.ripple.com 51235
|
||||
|
||||
# The latest validators can be obtained from
|
||||
# https://ripple.com/ripple.txt
|
||||
#
|
||||
[validators]
|
||||
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
|
||||
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
|
||||
n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
|
||||
n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
|
||||
n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
|
||||
|
||||
# Ditto.
|
||||
[validation_quorum]
|
||||
3
|
||||
|
||||
# Turn down default logging to save disk space in the long run.
|
||||
# Valid values here are trace, debug, info, warning, error, and fatal
|
||||
[rpc_startup]
|
||||
{ "command": "log_level", "severity": "warning" }
|
||||
|
||||
# Defaults to 1 ("yes") so that certificates will be validated. To allow the use
|
||||
# of self-signed certificates for development or internal use, set to 0 ("no").
|
||||
[ssl_verify]
|
||||
0
|
||||
|
||||
[sqdb]
|
||||
backend=sqlite
|
||||
)rippleConfig");
|
||||
|
||||
if (!dbPath.empty ())
|
||||
return boost::str (configContentsTemplate % "[database_path]" % dbPath);
|
||||
else
|
||||
return boost::str (configContentsTemplate % "" % "");
|
||||
}
|
||||
|
||||
/**
|
||||
Write a config file and remove when done.
|
||||
*/
|
||||
class ConfigGuard
|
||||
{
|
||||
private:
|
||||
using path = boost::filesystem::path;
|
||||
path subDir_;
|
||||
path configFile_;
|
||||
path dataDir_;
|
||||
|
||||
bool rmSubDir_{false};
|
||||
bool rmDataDir_{false};
|
||||
|
||||
Config config_;
|
||||
|
||||
public:
|
||||
ConfigGuard (std::string subDir, std::string const& dbPath)
|
||||
: subDir_ (std::move (subDir)), dataDir_ (dbPath)
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
|
||||
if (dbPath.empty ())
|
||||
{
|
||||
dataDir_ = subDir_ / path (Config::Helpers::getDatabaseDirName ());
|
||||
}
|
||||
|
||||
configFile_ = subDir_ / path (Config::Helpers::getConfigFileName ());
|
||||
{
|
||||
if (!exists (subDir_))
|
||||
{
|
||||
create_directory (subDir_);
|
||||
rmSubDir_ = true;
|
||||
}
|
||||
else if (is_directory (subDir_))
|
||||
rmSubDir_ = false;
|
||||
else
|
||||
{
|
||||
// Cannot run the test someone created a file where we want to
|
||||
// put out directory
|
||||
throw std::runtime_error ("Cannot create directory: " +
|
||||
subDir_.string ());
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists (configFile_))
|
||||
{
|
||||
std::ofstream o (configFile_.string ());
|
||||
o << configContents (dbPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error (
|
||||
"Refusing to overwrite existing config file: " +
|
||||
configFile_.string ());
|
||||
}
|
||||
|
||||
rmDataDir_ = !exists (dataDir_);
|
||||
config_.setup (configFile_.string (), /*bQuiet*/ false);
|
||||
}
|
||||
Config& config ()
|
||||
{
|
||||
return config_;
|
||||
}
|
||||
bool dataDirExists () const
|
||||
{
|
||||
return boost::filesystem::is_directory (dataDir_);
|
||||
}
|
||||
bool configFileExists () const
|
||||
{
|
||||
return boost::filesystem::is_regular_file (configFile_);
|
||||
}
|
||||
~ConfigGuard ()
|
||||
{
|
||||
try
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
if (!is_regular_file (configFile_))
|
||||
std::cerr << "Expected " << configFile_.string ()
|
||||
<< " to be an existing file.\n";
|
||||
else
|
||||
remove (configFile_.string ());
|
||||
|
||||
auto rmDir = [](path const& toRm)
|
||||
{
|
||||
if (is_directory (toRm) && is_empty (toRm))
|
||||
remove (toRm);
|
||||
else
|
||||
std::cerr << "Expected " << toRm.string ()
|
||||
<< " to be an empty existing directory.\n";
|
||||
};
|
||||
|
||||
if (rmDataDir_)
|
||||
rmDir (dataDir_);
|
||||
else
|
||||
std::cerr << "Skipping rm dir: " << dataDir_.string () << "\n";
|
||||
|
||||
if (rmSubDir_)
|
||||
rmDir (subDir_);
|
||||
else
|
||||
std::cerr << "Skipping rm dir: " << subDir_.string () << "\n";
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
// if we throw here, just let it die.
|
||||
std::cerr << "Error in CreateConfigGuard: " << e.what () << "\n";
|
||||
};
|
||||
}
|
||||
};
|
||||
} // detail
|
||||
class Config_test final : public TestSuite
|
||||
{
|
||||
private:
|
||||
using path = boost::filesystem::path;
|
||||
|
||||
public:
|
||||
void testLegacy ()
|
||||
{
|
||||
testcase ("legacy");
|
||||
|
||||
Config c;
|
||||
|
||||
std::string toLoad(R"rippleConfig(
|
||||
[server]
|
||||
port_rpc
|
||||
port_peer
|
||||
port_wss_admin
|
||||
|
||||
[ssl_verify]
|
||||
0
|
||||
|
||||
[validation_quorum]
|
||||
3
|
||||
)rippleConfig");
|
||||
|
||||
c.loadFromString (toLoad);
|
||||
|
||||
expect (c.legacy ("ssl_verify") == "0");
|
||||
expectException ([&c] {c.legacy ("server");}); // not a single line
|
||||
|
||||
// set a legacy value
|
||||
expect (c.legacy ("not_in_file") == "");
|
||||
c.legacy ("not_in_file", "new_value");
|
||||
expect (c.legacy ("not_in_file") == "new_value");
|
||||
}
|
||||
void testDbPath ()
|
||||
{
|
||||
testcase ("database_path");
|
||||
|
||||
using namespace boost::filesystem;
|
||||
{
|
||||
boost::format cc ("[database_path]\n%1%\n");
|
||||
|
||||
auto const cwd = current_path ();
|
||||
path const dataDirRel ("test_data_dir");
|
||||
path const dataDirAbs (cwd / dataDirRel);
|
||||
{
|
||||
// Dummy test - do we get back what we put in
|
||||
Config c;
|
||||
c.loadFromString (boost::str (cc % dataDirAbs.string ()));
|
||||
expect (c.legacy ("database_path") == dataDirAbs.string ());
|
||||
}
|
||||
{
|
||||
// Rel paths should convert to abs paths
|
||||
Config c;
|
||||
c.loadFromString (boost::str (cc % dataDirRel.string ()));
|
||||
expect (c.legacy ("database_path") == dataDirAbs.string ());
|
||||
}
|
||||
{
|
||||
// No db sectcion.
|
||||
// N.B. Config::setup will give database_path a default,
|
||||
// load will not.
|
||||
Config c;
|
||||
c.loadFromString ("");
|
||||
expect (c.legacy ("database_path") == "");
|
||||
}
|
||||
}
|
||||
{
|
||||
// read from file absolute path
|
||||
auto const cwd = current_path ();
|
||||
path const dataDirRel ("test_data_dir");
|
||||
path const dataDirAbs (cwd / path ("test_db") / dataDirRel);
|
||||
detail::ConfigGuard g ("test_db", dataDirAbs.string ());
|
||||
auto& c (g.config ());
|
||||
expect (g.dataDirExists ());
|
||||
expect (g.configFileExists ());
|
||||
expect (c.legacy ("database_path") == dataDirAbs.string (),
|
||||
"dbPath Abs Path File");
|
||||
}
|
||||
{
|
||||
// read from file relative path
|
||||
std::string const dbPath ("my_db");
|
||||
detail::ConfigGuard g ("test_db", dbPath);
|
||||
auto& c (g.config ());
|
||||
std::string const nativeDbPath = absolute (path (dbPath)).string ();
|
||||
expect (g.dataDirExists ());
|
||||
expect (g.configFileExists ());
|
||||
expect (c.legacy ("database_path") == nativeDbPath,
|
||||
"dbPath Rel Path File");
|
||||
}
|
||||
{
|
||||
// read from file no path
|
||||
detail::ConfigGuard g ("test_db", "");
|
||||
auto& c (g.config ());
|
||||
std::string const nativeDbPath =
|
||||
absolute (path ("test_db") /
|
||||
path (Config::Helpers::getDatabaseDirName ()))
|
||||
.string ();
|
||||
expect (g.dataDirExists ());
|
||||
expect (g.configFileExists ());
|
||||
expect (c.legacy ("database_path") == nativeDbPath,
|
||||
"dbPath No Path");
|
||||
}
|
||||
}
|
||||
void run ()
|
||||
{
|
||||
testLegacy ();
|
||||
testDbPath ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE (Config, core, ripple);
|
||||
|
||||
} // ripple
|
||||
@@ -27,3 +27,4 @@
|
||||
#include <ripple/core/impl/JobQueue.cpp>
|
||||
|
||||
#include <ripple/core/tests/LoadFeeTrack.test.cpp>
|
||||
#include <ripple/core/tests/Config.test.cpp>
|
||||
|
||||
Reference in New Issue
Block a user