Config test uses unique directories for each test:

* This fixes an uncommon, but annoying, spurious failure running this
  test, particularly in release builds. This appears to be an issue with
  Windows of the FS where quickly creating and deleting the same
  directory repeatedly will eventually fail.
* RIPD-1390
This commit is contained in:
Edward Hennis
2017-01-13 22:58:02 -05:00
parent f6a0345831
commit b514f1aae9

View File

@@ -144,12 +144,16 @@ protected:
};
public:
ConfigGuard (beast::unit_test::suite& test, std::string subDir)
ConfigGuard (beast::unit_test::suite& test, path subDir,
bool useCounter = true)
: subDir_ (std::move (subDir))
, test_ (test)
{
using namespace boost::filesystem;
{
static auto subDirCounter = 0;
if (useCounter)
subDir_ += std::to_string(++subDirCounter);
if (!exists (subDir_))
{
create_directory (subDir_);
@@ -166,6 +170,7 @@ public:
}
}
}
~ConfigGuard ()
{
try
@@ -184,12 +189,17 @@ public:
test_.log << "Error in ~ConfigGuard: " << e.what () << std::endl;
};
}
path const& subdir() const
{
return subDir_;
}
};
/**
Write a rippled config file and remove when done.
*/
class RippledCfgGuard : ConfigGuard
class RippledCfgGuard : public ConfigGuard
{
private:
path configFile_;
@@ -201,9 +211,11 @@ private:
public:
RippledCfgGuard (beast::unit_test::suite& test,
std::string subDir, std::string const& dbPath,
std::string const& validatorsFile)
: ConfigGuard (test, std::move (subDir)), dataDir_ (dbPath)
path subDir, path const& dbPath,
path const& validatorsFile,
bool useCounter = true)
: ConfigGuard (test, std::move (subDir), useCounter)
, dataDir_ (dbPath)
{
if (dbPath.empty ())
dataDir_ = subDir_ / path (Config::databaseDirName);
@@ -213,7 +225,7 @@ public:
if (!exists (configFile_))
{
std::ofstream o (configFile_.string ());
o << configContents (dbPath, validatorsFile);
o << configContents (dbPath.string (), validatorsFile.string ());
}
else
{
@@ -223,25 +235,30 @@ public:
}
rmDataDir_ = !exists (dataDir_);
config_.setup (configFile_.string (), /*bQuiet*/ false,
config_.setup (configFile_.string (), /*bQuiet*/ true,
/* bSilent */ false, /* bStandalone */ false);
}
Config& config ()
Config const& config () const
{
return config_;
}
std::string configFile() const
{
return configFile_.string();
}
bool dataDirExists () const
{
return boost::filesystem::is_directory (dataDir_);
}
bool configFileExists () const
{
return boost::filesystem::exists (configFile_);
}
~RippledCfgGuard ()
{
try
@@ -251,7 +268,7 @@ public:
test_.log << "Expected " << configFile_.string ()
<< " to be an existing file." << std::endl;
else
remove (configFile_.string ());
remove (configFile_);
if (rmDataDir_)
rmDir (dataDir_);
@@ -296,16 +313,16 @@ nHUPDdcdb2Y5DZAJne4c2iabFuAP3F34xZUgYQT2NH7qfkdapgnz
/**
Write a validators.txt file and remove when done.
*/
class ValidatorsTxtGuard : ConfigGuard
class ValidatorsTxtGuard : public ConfigGuard
{
private:
path validatorsFile_;
public:
ValidatorsTxtGuard (beast::unit_test::suite& test,
std::string subDir, std::string const& validatorsFileName,
boost::optional<int> const& quorum)
: ConfigGuard (test, std::move (subDir))
path subDir, path const& validatorsFileName,
boost::optional<int> const& quorum, bool useCounter = true)
: ConfigGuard (test, std::move (subDir), useCounter)
{
using namespace boost::filesystem;
validatorsFile_ = current_path () / subDir_ / path (
@@ -324,14 +341,17 @@ public:
validatorsFile_.string ());
}
}
bool validatorsFileExists () const
{
return boost::filesystem::exists (validatorsFile_);
}
std::string validatorsFile () const
{
return validatorsFile_.string ();
}
~ValidatorsTxtGuard ()
{
try
@@ -341,7 +361,7 @@ public:
test_.log << "Expected " << validatorsFile_.string ()
<< " to be an existing file." << std::endl;
else
remove (validatorsFile_.string ());
remove (validatorsFile_);
}
catch (std::exception& e)
{
@@ -422,10 +442,12 @@ port_wss_admin
{
// read from file absolute path
auto const cwd = current_path ();
detail::ConfigGuard const g0(*this, "test_db");
path const dataDirRel ("test_data_dir");
path const dataDirAbs (cwd / path ("test_db") / dataDirRel);
detail::RippledCfgGuard g (*this, "test_db", dataDirAbs.string (), "");
auto& c (g.config ());
path const dataDirAbs(cwd / g0.subdir () / dataDirRel);
detail::RippledCfgGuard const g (*this, g0.subdir(),
dataDirAbs, "", false);
auto const& c (g.config ());
BEAST_EXPECT(g.dataDirExists ());
BEAST_EXPECT(g.configFileExists ());
BEAST_EXPECT(c.legacy ("database_path") == dataDirAbs.string ());
@@ -433,8 +455,8 @@ port_wss_admin
{
// read from file relative path
std::string const dbPath ("my_db");
detail::RippledCfgGuard g (*this, "test_db", dbPath, "");
auto& c (g.config ());
detail::RippledCfgGuard const g (*this, "test_db", dbPath, "");
auto const& c (g.config ());
std::string const nativeDbPath = absolute (path (dbPath)).string ();
BEAST_EXPECT(g.dataDirExists ());
BEAST_EXPECT(g.configFileExists ());
@@ -442,10 +464,10 @@ port_wss_admin
}
{
// read from file no path
detail::RippledCfgGuard g (*this, "test_db", "", "");
auto& c (g.config ());
detail::RippledCfgGuard const g (*this, "test_db", "", "");
auto const& c (g.config ());
std::string const nativeDbPath =
absolute (path ("test_db") /
absolute (g.subdir () /
path (Config::databaseDirName))
.string ();
BEAST_EXPECT(g.dataDirExists ());
@@ -461,7 +483,6 @@ port_wss_admin
using namespace boost::filesystem;
{
// load should throw for missing specified validators file
Config c;
boost::format cc ("[validators_file]\n%1%\n");
std::string error;
std::string const missingPath = "/no/way/this/path/exists";
@@ -469,6 +490,7 @@ port_wss_admin
"The file specified in [validators_file] does not exist: " +
missingPath;
try {
Config c;
c.loadFromString (boost::str (cc % missingPath));
} catch (std::runtime_error& e) {
error = e.what();
@@ -478,16 +500,16 @@ port_wss_admin
{
// load should throw for invalid [validators_file]
int const quorum = 3;
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", "validators.cfg", quorum);
Config c;
path const invalidFile = current_path () / "test_cfg";
path const invalidFile = current_path () / vtg.subdir ();
boost::format cc ("[validators_file]\n%1%\n");
std::string error;
auto const expectedError =
"Invalid file specified in [validators_file]: " +
invalidFile.string ();
try {
Config c;
c.loadFromString (boost::str (cc % invalidFile.string ()));
} catch (std::runtime_error& e) {
error = e.what();
@@ -519,7 +541,7 @@ nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
{
// load from specified [validators_file] absolute path
int const quorum = 3;
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", "validators.cfg", quorum);
BEAST_EXPECT(vtg.validatorsFileExists ());
Config c;
@@ -535,13 +557,13 @@ nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
// in config directory
int const quorum = 3;
std::string const valFileName = "validators.txt";
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", valFileName, quorum);
detail::RippledCfgGuard rcg (
*this, "test_cfg", "", valFileName);
detail::RippledCfgGuard const rcg (
*this, vtg.subdir (), "", valFileName, false);
BEAST_EXPECT(vtg.validatorsFileExists ());
BEAST_EXPECT(rcg.configFileExists ());
auto& c (rcg.config ());
auto const& c (rcg.config ());
BEAST_EXPECT(c.legacy ("validators_file") == valFileName);
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
@@ -551,14 +573,14 @@ nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
// load from specified [validators_file] relative path
// to config directory
int const quorum = 3;
std::string const valFilePath = "../test_cfg/validators.txt";
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", "validators.txt", quorum);
detail::RippledCfgGuard rcg (
*this, "test_cfg", "", valFilePath);
auto const valFilePath = ".." / vtg.subdir() / "validators.txt";
detail::RippledCfgGuard const rcg (
*this, vtg.subdir (), "", valFilePath, false);
BEAST_EXPECT(vtg.validatorsFileExists ());
BEAST_EXPECT(rcg.configFileExists ());
auto& c (rcg.config ());
auto const& c (rcg.config ());
BEAST_EXPECT(c.legacy ("validators_file") == valFilePath);
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
@@ -567,12 +589,13 @@ nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
{
// load from validators file in default location
int const quorum = 3;
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", "validators.txt", quorum);
detail::RippledCfgGuard rcg (*this, "test_cfg", "", "");
detail::RippledCfgGuard const rcg (*this, vtg.subdir (),
"", "", false);
BEAST_EXPECT(vtg.validatorsFileExists ());
BEAST_EXPECT(rcg.configFileExists ());
auto& c (rcg.config ());
auto const& c (rcg.config ());
BEAST_EXPECT(c.legacy ("validators_file").empty ());
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
@@ -582,16 +605,16 @@ nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
// load from specified [validators_file] instead
// of default location
int const quorum = 3;
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", "validators.cfg", quorum);
BEAST_EXPECT(vtg.validatorsFileExists ());
detail::ValidatorsTxtGuard vtgDefault (
*this, "test_cfg", "validators.txt", 4);
detail::ValidatorsTxtGuard const vtgDefault (
*this, vtg.subdir (), "validators.txt", 4, false);
BEAST_EXPECT(vtgDefault.validatorsFileExists ());
detail::RippledCfgGuard rcg (
*this, "test_cfg", "", vtg.validatorsFile ());
detail::RippledCfgGuard const rcg (
*this, vtg.subdir (), "", vtg.validatorsFile (), false);
BEAST_EXPECT(rcg.configFileExists ());
auto& c (rcg.config ());
auto const& c (rcg.config ());
BEAST_EXPECT(c.legacy ("validators_file") == vtg.validatorsFile ());
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
@@ -607,7 +630,7 @@ nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
4
)rippleConfig");
int const quorum = 3;
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", "validators.cfg", quorum);
BEAST_EXPECT(vtg.validatorsFileExists ());
Config c;
@@ -617,6 +640,7 @@ nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
BEAST_EXPECT(c.VALIDATION_QUORUM == 4);
}
{
// load validators from both config and validators file
boost::format cc (R"rippleConfig(
@@ -636,7 +660,7 @@ nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
)rippleConfig");
int const quorum = 3;
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", "validators.cfg", quorum);
BEAST_EXPECT(vtg.validatorsFileExists ());
Config c;
@@ -649,10 +673,9 @@ nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
{
// load should throw if [validators] and [validator_keys] are
// missing from rippled cfg and validators file
Config c;
boost::format cc ("[validators_file]\n%1%\n");
std::string error;
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", "validators.cfg", boost::none);
BEAST_EXPECT(vtg.validatorsFileExists ());
auto const expectedError =
@@ -662,6 +685,7 @@ nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
std::ofstream o (vtg.validatorsFile ());
o << "[validation_quorum]\n3\n";
try {
Config c;
c.loadFromString (boost::str (cc % vtg.validatorsFile ()));
} catch (std::runtime_error& e) {
error = e.what();
@@ -671,16 +695,16 @@ nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
{
// load should throw if [validation_quorum] is
// missing from rippled cfg and validators file
Config c;
boost::format cc ("[validators_file]\n%1%\n");
std::string error;
detail::ValidatorsTxtGuard vtg (
detail::ValidatorsTxtGuard const vtg (
*this, "test_cfg", "validators.cfg", boost::none);
BEAST_EXPECT(vtg.validatorsFileExists ());
auto const expectedError =
"The file specified in [validators_file] does not contain a "
"[validation_quorum] section: " + vtg.validatorsFile ();
try {
Config c;
c.loadFromString (boost::str (cc % vtg.validatorsFile ()));
} catch (std::runtime_error& e) {
error = e.what();
@@ -691,7 +715,7 @@ nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
void testSetup(bool explicitPath)
{
detail::RippledCfgGuard cfg(*this, "testSetup",
detail::RippledCfgGuard const cfg(*this, "testSetup",
explicitPath ? "test_db" : "", "");
/* ConfigGuard has a Config object that gets loaded on construction,
but Config::setup is not reentrant, so we need a fresh config