mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-09 13:18:09 +00:00
test: Restore config test environment variables with a guard (#8333)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -122,6 +122,83 @@ backend=sqlite
|
||||
return std::format(kConfigContentsTemplate, dbPathSection, valFileSection);
|
||||
}
|
||||
|
||||
// setenv and unsetenv are POSIX only, and MSVC does not have them.
|
||||
#ifndef _MSC_VER
|
||||
|
||||
/**
|
||||
* Read an environment variable into a value the caller owns.
|
||||
*
|
||||
* The value is copied, because POSIX allows a later `setenv` to release the
|
||||
* string `getenv` returned.
|
||||
*
|
||||
* @param name Name of the environment variable to read.
|
||||
* @return The value, or std::nullopt when the variable is not set.
|
||||
*/
|
||||
[[nodiscard]] std::optional<std::string>
|
||||
envVar(char const* name)
|
||||
{
|
||||
if (char const* const value = std::getenv(name); value != nullptr)
|
||||
return std::string{value};
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an environment variable and restore its previous value when done.
|
||||
*/
|
||||
class EnvVarGuard
|
||||
{
|
||||
private:
|
||||
std::string const name_;
|
||||
std::optional<std::string> const saved_;
|
||||
|
||||
/**
|
||||
* Give an environment variable a value, or remove it.
|
||||
*
|
||||
* @param name Name of the environment variable to write.
|
||||
* @param value Value to set, or std::nullopt to remove the variable.
|
||||
*/
|
||||
static void
|
||||
apply(char const* name, std::optional<std::string> const& value) noexcept
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
setenv(name, value->c_str(), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsetenv(name);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Save the variable's current value, then write the given one.
|
||||
*
|
||||
* @param name Name of the environment variable to set.
|
||||
* @param value Value to set, or std::nullopt to remove the variable.
|
||||
*/
|
||||
[[nodiscard]] EnvVarGuard(char const* name, std::optional<std::string> const& value)
|
||||
: name_(name), saved_(envVar(name))
|
||||
{
|
||||
apply(name_.c_str(), value);
|
||||
}
|
||||
|
||||
EnvVarGuard(EnvVarGuard const&) = delete;
|
||||
EnvVarGuard&
|
||||
operator=(EnvVarGuard const&) = delete;
|
||||
|
||||
/**
|
||||
* Restore the value the variable held before construction.
|
||||
*/
|
||||
~EnvVarGuard()
|
||||
{
|
||||
apply(name_.c_str(), saved_);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
/**
|
||||
* Write an xrpld config file and remove when done.
|
||||
*/
|
||||
@@ -335,7 +412,11 @@ port_wss_admin
|
||||
}
|
||||
|
||||
// Config file in HOME or XDG_CONFIG_HOME directory.
|
||||
#if BOOST_OS_LINUX || BOOST_OS_MACOS
|
||||
#ifndef _MSC_VER
|
||||
// Save the values the guards below must put back.
|
||||
auto const home = detail::envVar("HOME");
|
||||
auto const xdgConfigHome = detail::envVar("XDG_CONFIG_HOME");
|
||||
|
||||
for (auto const& configFile : configFiles)
|
||||
{
|
||||
// Point the current working directory to a temporary directory, so
|
||||
@@ -348,13 +429,11 @@ port_wss_admin
|
||||
{
|
||||
TempDir const tc;
|
||||
|
||||
// Set the HOME and XDG_CONFIG_HOME environment variables. The
|
||||
// HOME variable is not used when XDG_CONFIG_HOME is set, but
|
||||
// must be set.
|
||||
char const* h = getenv("HOME");
|
||||
setenv("HOME", tc.path().c_str(), 1);
|
||||
char const* x = getenv("XDG_CONFIG_HOME");
|
||||
setenv("XDG_CONFIG_HOME", tc.path().c_str(), 1);
|
||||
// The HOME variable is not used when XDG_CONFIG_HOME is set,
|
||||
// but must be set. Both guards are declared after tc, so they
|
||||
// restore before it is removed.
|
||||
detail::EnvVarGuard const homeGuard("HOME", tc.path());
|
||||
detail::EnvVarGuard const xdgGuard("XDG_CONFIG_HOME", tc.path());
|
||||
|
||||
// Create the config file in '${XDG_CONFIG_HOME}/[systemName]'.
|
||||
Path p = tc.file(systemName());
|
||||
@@ -371,22 +450,21 @@ port_wss_admin
|
||||
BEAST_EXPECT(
|
||||
c.section(Sections::kDebugLogfile).values()[0] ==
|
||||
"/Users/dummy/xrpld/config/log/debug.log");
|
||||
|
||||
// Restore the environment variables.
|
||||
(h != nullptr) ? setenv("HOME", h, 1) : unsetenv("HOME");
|
||||
(x != nullptr) ? setenv("XDG_CONFIG_HOME", x, 1) : unsetenv("XDG_CONFIG_HOME");
|
||||
}
|
||||
|
||||
// Both guards are gone: both variables must hold their old values.
|
||||
BEAST_EXPECT(detail::envVar("HOME") == home);
|
||||
BEAST_EXPECT(detail::envVar("XDG_CONFIG_HOME") == xdgConfigHome);
|
||||
|
||||
// The XDG config directory is not set: the config file must be in a
|
||||
// subdirectory named .config followed by the system name.
|
||||
{
|
||||
TempDir const tc;
|
||||
|
||||
// Set only the HOME environment variable.
|
||||
char const* h = getenv("HOME");
|
||||
setenv("HOME", tc.path().c_str(), 1);
|
||||
char const* x = getenv("XDG_CONFIG_HOME");
|
||||
unsetenv("XDG_CONFIG_HOME");
|
||||
// Both guards are declared after tc, so they restore before it
|
||||
// is removed.
|
||||
detail::EnvVarGuard const homeGuard("HOME", tc.path());
|
||||
detail::EnvVarGuard const xdgGuard("XDG_CONFIG_HOME", std::nullopt);
|
||||
|
||||
// Create the config file in '${HOME}/.config/[systemName]'.
|
||||
std::string s = ".config";
|
||||
@@ -407,14 +485,13 @@ port_wss_admin
|
||||
BEAST_EXPECT(
|
||||
c.section(Sections::kDebugLogfile).values()[0] ==
|
||||
"/Users/dummy/xrpld/config/log/debug.log");
|
||||
|
||||
// Restore the environment variables.
|
||||
(h != nullptr) ? setenv("HOME", h, 1) : unsetenv("HOME");
|
||||
if (x != nullptr)
|
||||
setenv("XDG_CONFIG_HOME", x, 1);
|
||||
}
|
||||
|
||||
// Both guards are gone: both variables must hold their old values.
|
||||
BEAST_EXPECT(detail::envVar("HOME") == home);
|
||||
BEAST_EXPECT(detail::envVar("XDG_CONFIG_HOME") == xdgConfigHome);
|
||||
}
|
||||
#endif
|
||||
#endif // _MSC_VER
|
||||
|
||||
// Restore the current working directory.
|
||||
current_path(cwd);
|
||||
|
||||
Reference in New Issue
Block a user