diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-14 14:26:38 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-14 14:26:38 -0300 |
| commit | 294bc6ecabf14c09c9bc8644704921dcf97cb44e (patch) | |
| tree | 279b1e0bab53901a1647ac63c1c724f0f789a663 /src/mongo/db/server_options_test.cpp | |
| parent | 70be7c27a251621187a1de533462ae2bb1e3bd39 (diff) | |
| parent | 1e917fd798aa25b7066d4b414b51184f13d5a092 (diff) | |
Update upstream source from tag 'upstream/6.0.10'debian/6.0.10-1
Update to upstream version '6.0.10'
with Debian dir 2d176fa254eee97b139f712fec5709641335a8c3
Diffstat (limited to 'src/mongo/db/server_options_test.cpp')
| -rw-r--r-- | src/mongo/db/server_options_test.cpp | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/src/mongo/db/server_options_test.cpp b/src/mongo/db/server_options_test.cpp index b608e3f1658..d8b0e3d0b12 100644 --- a/src/mongo/db/server_options_test.cpp +++ b/src/mongo/db/server_options_test.cpp @@ -37,6 +37,7 @@ #include <unistd.h> #endif #ifndef _WIN32 +#include <cstdlib> #include <sys/types.h> #include <sys/wait.h> #endif @@ -45,6 +46,7 @@ #include <TargetConditionals.h> #endif +#include <boost/algorithm/string/join.hpp> #include <boost/filesystem.hpp> #include "mongo/base/init.h" @@ -75,6 +77,7 @@ using mongo::unittest::getMinimumLogSeverity; using mongo::unittest::hasMinimumLogSeverity; namespace moe = mongo::optionenvironment; +using namespace fmt::literals; MONGO_INITIALIZER(ServerLogRedirection)(mongo::InitializerContext*) { // ssl_options_server.cpp has an initializer which depends on logging. @@ -109,6 +112,89 @@ class Verbosity : public mongo::unittest::Test { mongo::logv2::LogSeverity::Info()}; }; +class SetupOptionsTestConfig { +public: + SetupOptionsTestConfig() : binaryArgs_{}, configFileName_{}, configOpts_{}, envVars_{} {} + + SetupOptionsTestConfig(std::vector<std::string> binaryArgs, + std::string configFileName, + std::vector<std::pair<std::string, std::string>> configOpts, + std::vector<std::pair<std::string, std::string>> envVars) + : binaryArgs_{binaryArgs}, + configFileName_{configFileName}, + configOpts_{configOpts}, + envVars_{envVars} {} + + std::vector<std::string> binaryArgs() const { + std::vector<std::string> args = {"binaryname"}; + args.insert(args.end(), binaryArgs_.cbegin(), binaryArgs_.cend()); + + if (!configFileName_.empty()) { + args.push_back("--config"); + args.push_back(configFileName_); + } + + return args; + } + + std::vector<std::pair<std::string, std::string>> envVars() const { + return envVars_; + } + + bool hasEnvVars() const { + return !envVars_.empty(); + } + + std::string configFileName() const { + return configFileName_; + } + + bool hasConfigFile() const { + return !configFileName_.empty(); + } + + std::string configFileContents() const { + std::string fileContents; + for (auto&& [key, value] : configOpts_) { + std::vector<std::string> splitKeys; + str::splitStringDelim(key, &splitKeys, '.'); + + // Split up the configuration key by '.' into separate sections. + int indent = 0; + for (auto&& splitKey : splitKeys) { + if (indent > 0) { + fileContents += "\n"; + } + fileContents += std::string(indent, ' ') + splitKey + ":"; + indent += 4; + } + fileContents += " " + value + "\n"; + } + return fileContents; + } + + std::string toString() const { + std::string str = "argv=[{}],"_format(boost::algorithm::join(binaryArgs(), ", ")); + if (hasConfigFile()) { + str += "confFile=[\n{}],"_format(configFileContents()); + } + if (hasEnvVars()) { + std::vector<std::string> envs; + for (auto&& [k, v] : envVars_) { + envs.push_back("{}={}"_format(k, v)); + } + str += "env=[{}],"_format(boost::algorithm::join(envs, ", ")); + } + return "SetupOptionsTestConfig({})"_format(str); + } + +private: + std::vector<std::string> binaryArgs_; + std::string configFileName_; + std::vector<std::pair<std::string, std::string>> configOpts_; + std::vector<std::pair<std::string, std::string>> envVars_; +}; + TEST_F(Verbosity, Default) { OptionsParserTester parser; moe::Environment environment; @@ -709,6 +795,147 @@ TEST(SetupOptions, NonNumericSampleRateYAMLConfigOptionFailsToParse) { ASSERT_NOT_OK(parser.run(options, argv, &environment)); } +#ifndef _WIN32 +class ForkTestSpec { +public: + enum Value { + NO_OPTIONS, + COMMANDLINE_ONLY, + CONFIG_ONLY, + BOTH, + COMMANDLINE_WITH_ENV, + CONFIG_WITH_ENV, + BOTH_WITH_ENV, + }; + + ForkTestSpec() = default; + constexpr operator Value() const { + return value_; + } + explicit operator bool() = delete; + + ForkTestSpec(Value value) : value_{value} { + std::vector<std::string> args = {"--fork", "--syslog"}; + std::vector<std::pair<std::string, std::string>> envVars{ + {"MONGODB_CONFIG_OVERRIDE_NOFORK", "1"}}; + std::string confFileName = "config.yaml"; + std::vector<std::pair<std::string, std::string>> opts = { + {"systemLog.destination", "syslog"}, {"processManagement.fork", "true"}}; + + switch (value) { + case NO_OPTIONS: { + config_ = SetupOptionsTestConfig(); + name_ = "NO_OPTIONS"; + break; + } + case COMMANDLINE_ONLY: { + config_ = SetupOptionsTestConfig(args, "", {}, {}); + name_ = "COMMANDLINE_ONLY"; + break; + } + case CONFIG_ONLY: { + config_ = SetupOptionsTestConfig({}, confFileName, opts, {}); + name_ = "CONFIG_ONLY"; + break; + } + case BOTH: { + config_ = SetupOptionsTestConfig(args, confFileName, opts, {}); + name_ = "BOTH"; + break; + } + case COMMANDLINE_WITH_ENV: { + config_ = SetupOptionsTestConfig(args, "", {}, envVars); + name_ = "COMMANDLINE_WITH_ENV"; + break; + } + case CONFIG_WITH_ENV: { + config_ = SetupOptionsTestConfig({}, confFileName, opts, envVars); + name_ = "CONFIG_WITH_ENV"; + break; + } + case BOTH_WITH_ENV: { + config_ = SetupOptionsTestConfig(args, confFileName, opts, envVars); + name_ = "BOTH_WITH_ENV"; + break; + } + } + } + + SetupOptionsTestConfig config() const { + return config_; + } + + std::string toString() const { + return "SetupOptionsTestConfig(specName={}, config={})"_format(name_, config_.toString()); + } + +private: + Value value_; + std::string name_; + SetupOptionsTestConfig config_; +}; + +class ForkTest { +public: + ForkTest(const ForkTestSpec spec, bool doForkValue) + : spec_{spec}, doForkValue_{doForkValue}, parser_{}, environment_{}, options_{} { + ASSERT_OK(addGeneralServerOptions(&options_)); + ASSERT_OK(addNonGeneralServerOptions(&options_)); + + if (spec.config().hasConfigFile()) { + parser_.setConfig(spec.config().configFileName(), spec.config().configFileContents()); + } + } + + void run() { + auto&& argv = spec_.config().binaryArgs(); + + for (auto&& [envKey, envValue] : spec_.config().envVars()) { + setenv(envKey.c_str(), envValue.c_str(), 1); + } + + ScopeGuard sg = [&] { + serverGlobalParams.doFork = false; + for (auto&& [envKey, envValue] : spec_.config().envVars()) { + unsetenv(envKey.c_str()); + } + }; + + ASSERT_OK(parser_.run(options_, argv, &environment_)) << spec_.toString(); + + ASSERT_OK(validateServerOptions(environment_)) << spec_.toString(); + ASSERT_OK(canonicalizeServerOptions(&environment_)) << spec_.toString(); + ASSERT_OK(setupServerOptions(argv)) << spec_.toString(); + ASSERT_OK(storeServerOptions(environment_)) << spec_.toString(); + + ASSERT_EQ(serverGlobalParams.doFork, doForkValue_) << spec_.toString(); + } + +private: + ForkTestSpec spec_; + bool doForkValue_; + OptionsParserTester parser_; + moe::Environment environment_; + moe::OptionSection options_; +}; + +TEST(SetupOptions, ForkCommandLineParamParsesSuccessfully) { + ForkTest{ForkTestSpec::NO_OPTIONS, false}.run(); + ForkTest{ForkTestSpec::COMMANDLINE_ONLY, true}.run(); +} + +TEST(SetupOptions, ForkYAMLConfigOptionParsesSuccessfully) { + ForkTest{ForkTestSpec::NO_OPTIONS, false}.run(); + ForkTest{ForkTestSpec::CONFIG_ONLY, true}.run(); +} + +TEST(SetupOptions, ForkOptionAlwaysFalseWithNoforkEnvVar) { + ForkTest{ForkTestSpec::COMMANDLINE_WITH_ENV, false}.run(); + ForkTest{ForkTestSpec::CONFIG_WITH_ENV, false}.run(); + ForkTest{ForkTestSpec::BOTH_WITH_ENV, false}.run(); +} +#endif + #if !defined(_WIN32) && !(defined(__APPLE__) && TARGET_OS_TV) #define ASSERT_BOOST_SUCCESS(ec) ASSERT_FALSE(ec) << ec.message() |
