diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c0062e40..5bf62d9e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,6 +159,10 @@ if ( NOT ENVIRONMENT_VARIABLES) set( ENVIRONMENT_VARIABLES "\"XDG_RUNTIME_DIR=/tmp\",\"GST_REGISTRY=/tmp/rialto-server-gstreamer-cache.bin\",\"WESTEROS_SINK_USE_ESSRMGR=1\"" ) endif() +if ( NOT EXTRA_ENV_VARIABLES) + set( EXTRA_ENV_VARIABLES "" ) +endif() + if (NOT SESSION_SERVER_PATH) set( SESSION_SERVER_PATH "\"/usr/bin/RialtoServer\"" ) endif() diff --git a/serverManager/config/rialto-config.in.json b/serverManager/config/rialto-config.in.json index 68abb8dbf..2b89a8a93 100644 --- a/serverManager/config/rialto-config.in.json +++ b/serverManager/config/rialto-config.in.json @@ -21,14 +21,15 @@ // with fields that mimic the structure of this file, but with // alternative values - "environment_variables" : [@ENVIRONMENT_VARIABLES@], - "session_server_path" : @SESSION_SERVER_PATH@, - "startup_timeout_ms" : @STARTUP_TIMEOUT_MS@, - "healthcheck_interval_s" : @HEALTHCHECK_INTERVAL_S@, - "socket_permissions" : @SOCKET_PERMISSIONS@, - "socket_owner" : @SOCKET_OWNER@, - "socket_group" : @SOCKET_GROUP@, - "num_of_preloaded_servers" : @NUM_OF_PRELOADED_SERVERS@, - "log_level" : @LOG_LEVEL@, - "num_of_pings_before_recovery" : @NUM_OF_PINGS_BEFORE_RECOVERY@ + "environmentVariables" : [@ENVIRONMENT_VARIABLES@], + "extraEnvVariables" : [@EXTRA_ENV_VARIABLES@], + "sessionServerPath" : @SESSION_SERVER_PATH@, + "startupTimeoutMs" : @STARTUP_TIMEOUT_MS@, + "healthcheckIntervalInSeconds" : @HEALTHCHECK_INTERVAL_S@, + "socketPermissions" : @SOCKET_PERMISSIONS@, + "socketOwner" : @SOCKET_OWNER@, + "socketGroup" : @SOCKET_GROUP@, + "numOfPreloadedServers" : @NUM_OF_PRELOADED_SERVERS@, + "logLevel" : @LOG_LEVEL@, + "numOfPingsBeforeRecovery" : @NUM_OF_PINGS_BEFORE_RECOVERY@ } diff --git a/serverManager/service/CMakeLists.txt b/serverManager/service/CMakeLists.txt index ea6373bc6..6973a344d 100644 --- a/serverManager/service/CMakeLists.txt +++ b/serverManager/service/CMakeLists.txt @@ -68,6 +68,7 @@ if( RIALTO_ENABLE_CONFIG_FILE ) add_compile_definitions(RIALTO_ENABLE_CONFIG_FILE) add_compile_definitions(RIALTO_CONFIG_PATH="${RIALTO_CONFIG_FILE_DIR}/rialto-config.json") add_compile_definitions(RIALTO_CONFIG_OVERRIDES_PATH="${RIALTO_CONFIG_OVERRIDES_FILE_DIR}/rialto-config-overrides.json") + add_compile_definitions(RIALTO_CONFIG_SOC_PATH="${RIALTO_CONFIG_FILE_DIR}/rialto_soc.json") target_link_libraries( RialtoServerManager diff --git a/serverManager/service/include/ConfigHelper.h b/serverManager/service/include/ConfigHelper.h index fecb1e2b7..7623ce4c0 100644 --- a/serverManager/service/include/ConfigHelper.h +++ b/serverManager/service/include/ConfigHelper.h @@ -50,11 +50,14 @@ class ConfigHelper #ifdef RIALTO_ENABLE_CONFIG_FILE private: void readConfigFile(const std::string &filePath); + void mergeEnvVariables(); #endif // RIALTO_ENABLE_CONFIG_FILE private: std::unique_ptr m_configReaderFactory; std::map m_sessionServerEnvVars; + std::map m_envVarsFromConfigFile; + std::map m_extraEnvVarsFromConfigFile; std::string m_sessionServerPath; std::chrono::milliseconds m_sessionServerStartupTimeout; std::chrono::seconds m_healthcheckInterval; diff --git a/serverManager/service/include/ConfigReader.h b/serverManager/service/include/ConfigReader.h index d0fc26ada..6c2ba8735 100644 --- a/serverManager/service/include/ConfigReader.h +++ b/serverManager/service/include/ConfigReader.h @@ -39,6 +39,7 @@ class ConfigReader : public IConfigReader bool read() override; std::list getEnvironmentVariables() override; + std::list getExtraEnvVariables() override; std::optional getSessionServerPath() override; std::optional getSessionServerStartupTimeout() override; std::optional getHealthcheckInterval() override; @@ -51,6 +52,7 @@ class ConfigReader : public IConfigReader private: void parseEnvironmentVariables(std::shared_ptr root); + void parseExtraEnvVariables(std::shared_ptr root); void parseSessionServerPath(std::shared_ptr root); void parseSessionServerStartupTimeout(std::shared_ptr root); void parseHealthcheckInterval(std::shared_ptr root); @@ -61,10 +63,18 @@ class ConfigReader : public IConfigReader void parseLogLevel(std::shared_ptr root); void parseNumOfPingsBeforeRecovery(std::shared_ptr root); + std::list getListOfStrings(std::shared_ptr root, + const std::string &valueName) const; + std::optional getString(std::shared_ptr root, + const std::string &valueName) const; + std::optional getUInt(std::shared_ptr root, + const std::string &valueName) const; + std::shared_ptr m_jsonWrapper; std::shared_ptr m_fileReader; std::list m_envVars; + std::list m_extraEnvVars; std::optional m_sessionServerPath; std::optional m_sessionServerStartupTimeout; std::optional m_healthcheckInterval; diff --git a/serverManager/service/include/IConfigReader.h b/serverManager/service/include/IConfigReader.h index e1459cfaf..47f42c75a 100644 --- a/serverManager/service/include/IConfigReader.h +++ b/serverManager/service/include/IConfigReader.h @@ -35,6 +35,7 @@ class IConfigReader virtual bool read() = 0; virtual std::list getEnvironmentVariables() = 0; + virtual std::list getExtraEnvVariables() = 0; virtual std::optional getSessionServerPath() = 0; virtual std::optional getSessionServerStartupTimeout() = 0; virtual std::optional getHealthcheckInterval() = 0; diff --git a/serverManager/service/source/ConfigHelper.cpp b/serverManager/service/source/ConfigHelper.cpp index 05d2eca6c..464763471 100644 --- a/serverManager/service/source/ConfigHelper.cpp +++ b/serverManager/service/source/ConfigHelper.cpp @@ -66,8 +66,11 @@ ConfigHelper::ConfigHelper(std::unique_ptr &&configReaderF m_numOfFailedPingsBeforeRecovery{config.numOfFailedPingsBeforeRecovery}, m_loggingLevels{} { #ifdef RIALTO_ENABLE_CONFIG_FILE + // Read from least to most important file readConfigFile(RIALTO_CONFIG_PATH); + readConfigFile(RIALTO_CONFIG_SOC_PATH); readConfigFile(RIALTO_CONFIG_OVERRIDES_PATH); + mergeEnvVariables(); #endif // RIALTO_ENABLE_CONFIG_FILE } @@ -126,14 +129,18 @@ void ConfigHelper::readConfigFile(const std::string &filePath) return; } - std::map envVariables{convertToMap(configReader->getEnvironmentVariables())}; - for (const auto &[name, value] : envVariables) + // Always override env variables when present in "more important" file + // (envVariables + extraEnvVariables from less important file will be wiped if envVariables are present) + const std::map envVariables{convertToMap(configReader->getEnvironmentVariables())}; + if (!envVariables.empty()) { - // If environment variable exists in ServerManagerConfig, do not overwrite it - if (m_sessionServerEnvVars.end() == m_sessionServerEnvVars.find(name)) - { - m_sessionServerEnvVars.emplace(name, value); - } + m_envVarsFromConfigFile = envVariables; + m_extraEnvVarsFromConfigFile.clear(); + } + const std::map extraEnvVariables{convertToMap(configReader->getExtraEnvVariables())}; + if (!extraEnvVariables.empty()) + { + m_extraEnvVarsFromConfigFile = extraEnvVariables; } if (configReader->getSessionServerPath()) @@ -163,5 +170,19 @@ void ConfigHelper::readConfigFile(const std::string &filePath) if (configReader->getLoggingLevels()) m_loggingLevels = configReader->getLoggingLevels().value(); } + +void ConfigHelper::mergeEnvVariables() +{ + // Env vars from json are more important than values from config struct + if (!m_envVarsFromConfigFile.empty()) + { + m_sessionServerEnvVars = m_envVarsFromConfigFile; + } + for (const auto &[name, value] : m_extraEnvVarsFromConfigFile) + { + // If env variable exists both in envVariables and extraEnvVariables, overwrite it. + m_sessionServerEnvVars[name] = value; + } +} #endif // RIALTO_ENABLE_CONFIG_FILE } // namespace rialto::servermanager::service diff --git a/serverManager/service/source/ConfigReader.cpp b/serverManager/service/source/ConfigReader.cpp index dbd9e92c3..b845ab3ba 100644 --- a/serverManager/service/source/ConfigReader.cpp +++ b/serverManager/service/source/ConfigReader.cpp @@ -46,6 +46,7 @@ bool ConfigReader::read() } parseEnvironmentVariables(root); + parseExtraEnvVariables(root); parseSessionServerPath(root); parseSessionServerStartupTimeout(root); parseHealthcheckInterval(root); @@ -61,92 +62,110 @@ bool ConfigReader::read() void ConfigReader::parseEnvironmentVariables(std::shared_ptr root) { - if (root->isMember("environment_variables") && root->at("environment_variables")->isArray()) + m_envVars = getListOfStrings(root, "environmentVariables"); + if (m_envVars.empty()) { - std::shared_ptr envVarsJson = root->at("environment_variables"); - Json::ArrayIndex size = envVarsJson->size(); - for (Json::ArrayIndex index = 0; index < size; ++index) - { - if (envVarsJson->at(index)->isString()) - { - m_envVars.emplace_back(envVarsJson->at(index)->asString()); - } - } + m_envVars = getListOfStrings(root, "environment_variables"); } } +void ConfigReader::parseExtraEnvVariables(std::shared_ptr root) +{ + m_extraEnvVars = getListOfStrings(root, "extraEnvVariables"); +} + void ConfigReader::parseSessionServerPath(std::shared_ptr root) { - if (root->isMember("session_server_path") && root->at("session_server_path")->isString()) + m_sessionServerPath = getString(root, "sessionServerPath"); + if (!m_sessionServerPath.has_value()) { - m_sessionServerPath = root->at("session_server_path")->asString(); + m_sessionServerPath = getString(root, "session_server_path"); } } void ConfigReader::parseSessionServerStartupTimeout(std::shared_ptr root) { - if (root->isMember("startup_timeout_ms") && root->at("startup_timeout_ms")->isUInt()) + auto timeout{getUInt(root, "startupTimeoutMs")}; + if (!timeout.has_value()) + { + timeout = getUInt(root, "startup_timeout_ms"); + } + if (timeout.has_value()) { - m_sessionServerStartupTimeout = std::chrono::milliseconds(root->at("startup_timeout_ms")->asUInt()); + m_sessionServerStartupTimeout = std::chrono::milliseconds{timeout.value()}; } } void ConfigReader::parseHealthcheckInterval(std::shared_ptr root) { - if (root->isMember("healthcheck_interval_s") && root->at("healthcheck_interval_s")->isUInt()) + auto interval{getUInt(root, "healthcheckIntervalInSeconds")}; + if (!interval.has_value()) { - m_healthcheckInterval = std::chrono::seconds(root->at("healthcheck_interval_s")->asUInt()); + interval = getUInt(root, "healthcheck_interval_s"); + } + if (interval.has_value()) + { + m_healthcheckInterval = std::chrono::seconds{*interval}; } } void ConfigReader::parseSocketPermissions(std::shared_ptr root) { - if (root->isMember("socket_permissions") && root->at("socket_permissions")->isUInt()) + auto permissions{getUInt(root, "socketPermissions")}; + if (!permissions.has_value()) + { + permissions = getUInt(root, "socket_permissions"); + } + if (permissions.has_value()) { - unsigned permissions = root->at("socket_permissions")->asUInt(); - firebolt::rialto::common::SocketPermissions socketPermissions; - socketPermissions.ownerPermissions = (permissions / 100) % 10; - socketPermissions.groupPermissions = (permissions / 10) % 10; - socketPermissions.otherPermissions = (permissions) % 10; + socketPermissions.ownerPermissions = (*permissions / 100) % 10; + socketPermissions.groupPermissions = (*permissions / 10) % 10; + socketPermissions.otherPermissions = (*permissions) % 10; m_socketPermissions = socketPermissions; } } void ConfigReader::parseSocketOwner(std::shared_ptr root) { - const char *kFieldString = "socket_owner"; - if (root->isMember(kFieldString) && root->at(kFieldString)->isString()) + m_socketOwner = getString(root, "socketOwner"); + if (!m_socketOwner.has_value()) { - m_socketOwner = root->at(kFieldString)->asString(); + m_socketOwner = getString(root, "socket_owner"); } } void ConfigReader::parseSocketGroup(std::shared_ptr root) { - const char *kFieldString = "socket_group"; - if (root->isMember(kFieldString) && root->at(kFieldString)->isString()) + m_socketGroup = getString(root, "socketGroup"); + if (!m_socketGroup.has_value()) { - m_socketGroup = root->at(kFieldString)->asString(); + m_socketGroup = getString(root, "socket_group"); } } void ConfigReader::parseNumOfPreloadedServers(std::shared_ptr root) { - if (root->isMember("num_of_preloaded_servers") && root->at("num_of_preloaded_servers")->isUInt()) + m_numOfPreloadedServers = getUInt(root, "numOfPreloadedServers"); + if (!m_numOfPreloadedServers.has_value()) { - m_numOfPreloadedServers = root->at("num_of_preloaded_servers")->asUInt(); + m_numOfPreloadedServers = getUInt(root, "num_of_preloaded_servers"); } } void ConfigReader::parseLogLevel(std::shared_ptr root) { - if (root->isMember("log_level") && root->at("log_level")->isUInt()) + std::optional loggingLevel{getUInt(root, "logLevel")}; + if (!loggingLevel.has_value()) + { + loggingLevel = getUInt(root, "log_level"); + } + + if (loggingLevel) { - unsigned loggingLevel = root->at("log_level")->asUInt(); rialto::servermanager::service::LoggingLevel newLevel{rialto::servermanager::service::LoggingLevel::UNCHANGED}; - switch (loggingLevel) + switch (*loggingLevel) { case 0: newLevel = rialto::servermanager::service::LoggingLevel::FATAL; @@ -176,9 +195,10 @@ void ConfigReader::parseLogLevel(std::shared_ptr root) { - if (root->isMember("num_of_pings_before_recovery") && root->at("num_of_pings_before_recovery")->isUInt()) + m_numOfPingsBeforeRecovery = getUInt(root, "numOfPingsBeforeRecovery"); + if (!m_numOfPingsBeforeRecovery.has_value()) { - m_numOfPingsBeforeRecovery = root->at("num_of_pings_before_recovery")->asUInt(); + m_numOfPingsBeforeRecovery = getUInt(root, "num_of_pings_before_recovery"); } } @@ -187,6 +207,11 @@ std::list ConfigReader::getEnvironmentVariables() return m_envVars; } +std::list ConfigReader::getExtraEnvVariables() +{ + return m_extraEnvVars; +} + std::optional ConfigReader::getSessionServerPath() { return m_sessionServerPath; @@ -232,4 +257,43 @@ std::optional ConfigReader::getNumOfPingsBeforeRecovery() return m_numOfPingsBeforeRecovery; } +std::list ConfigReader::getListOfStrings(std::shared_ptr root, + const std::string &valueName) const +{ + std::list result; + if (root->isMember(valueName) && root->at(valueName)->isArray()) + { + std::shared_ptr envVarsJson = root->at(valueName); + Json::ArrayIndex size = envVarsJson->size(); + for (Json::ArrayIndex index = 0; index < size; ++index) + { + if (envVarsJson->at(index)->isString()) + { + result.emplace_back(envVarsJson->at(index)->asString()); + } + } + } + return result; +} + +std::optional ConfigReader::getString(std::shared_ptr root, + const std::string &valueName) const +{ + if (root->isMember(valueName) && root->at(valueName)->isString()) + { + return root->at(valueName)->asString(); + } + return std::nullopt; +} + +std::optional ConfigReader::getUInt(std::shared_ptr root, + const std::string &valueName) const +{ + if (root->isMember(valueName) && root->at(valueName)->isUInt()) + { + return root->at(valueName)->asUInt(); + } + return std::nullopt; +} + } // namespace rialto::servermanager::service diff --git a/tests/unittests/serverManager/mocks/ConfigReaderMock.h b/tests/unittests/serverManager/mocks/ConfigReaderMock.h index a8dbf7b67..aad9cfdd0 100644 --- a/tests/unittests/serverManager/mocks/ConfigReaderMock.h +++ b/tests/unittests/serverManager/mocks/ConfigReaderMock.h @@ -31,6 +31,7 @@ class ConfigReaderMock : public IConfigReader public: MOCK_METHOD(bool, read, (), (override)); MOCK_METHOD(std::list, getEnvironmentVariables, (), (override)); + MOCK_METHOD(std::list, getExtraEnvVariables, (), (override)); MOCK_METHOD(std::optional, getSessionServerPath, (), (override)); MOCK_METHOD(std::optional, getSessionServerStartupTimeout, (), (override)); MOCK_METHOD(std::optional, getHealthcheckInterval, (), (override)); diff --git a/tests/unittests/serverManager/unittests/service/ConfigHelperTests.cpp b/tests/unittests/serverManager/unittests/service/ConfigHelperTests.cpp index 55770a9c0..c16aea31e 100644 --- a/tests/unittests/serverManager/unittests/service/ConfigHelperTests.cpp +++ b/tests/unittests/serverManager/unittests/service/ConfigHelperTests.cpp @@ -35,17 +35,21 @@ using testing::StrictMock; namespace { const std::string kRialtoConfigPath{"/etc/rialto-config.json"}; +const std::string kRialtoConfigSocPath{"/etc/rialto_soc.json"}; const std::string kRialtoConfigOverridesPath{"/opt/persistent/sky/rialto-config-overrides.json"}; -const ServerManagerConfig kServerManagerConfig{{"env1=var1"}, +const std::list kEmptyEnvVars{}; +const std::list kOverwrittenEnvVar{"env1=var2"}; +const std::list kEnvVarSet1{"env1=var1"}; +const std::list kEnvVarSet2{"env2=var2"}; +const std::list kEnvVarSet3{"env3=var3"}; +const std::list kEnvVarSet4{"env4=var4"}; +const ServerManagerConfig kServerManagerConfig{kEnvVarSet1, 2, "sessionServerPath", std::chrono::milliseconds{3}, std::chrono::seconds{4}, {7, 7, 7, "user1", "group1"}, 5}; -const std::list kEmptyEnvVars{}; -const std::list kOverwrittenEnvVar{"env1=var2"}; -const std::list kJsonSessionServerEnvVars{"env2=var2"}; constexpr unsigned kJsonNumOfPreloadedServers{10}; const std::string kJsonSessionServerPath{"/usr/bin/RialtoServer"}; constexpr std::chrono::milliseconds kJsonStartupTimeout{0}; @@ -54,23 +58,39 @@ const SocketPermissions kJsonSocketPermissions{5, 5, 5, "user2", "group2"}; constexpr unsigned kJsonNumOfFailedPingsBeforeRecovery{3}; const LoggingLevels kJsonLoggingLevels{LoggingLevel::DEBUG, LoggingLevel::DEBUG, LoggingLevel::DEBUG, LoggingLevel::DEBUG, LoggingLevel::DEBUG, LoggingLevel::DEBUG}; -const std::list kJsonOverrideSessionServerEnvVars{"env3=var3"}; +constexpr unsigned kJsonSocNumOfPreloadedServers{11}; +const std::string kJsonSocSessionServerPath{"/usr/sbin/RialtoServer"}; +constexpr std::chrono::milliseconds kJsonSocStartupTimeout{2}; +constexpr std::chrono::seconds kJsonSocHealthcheckInterval{3}; +const SocketPermissions kJsonSocSocketPermissions{6, 0, 0, "user3", "group3"}; +constexpr unsigned kJsonSocNumOfFailedPingsBeforeRecovery{5}; +const LoggingLevels kJsonSocLoggingLevels{LoggingLevel::MILESTONE, LoggingLevel::MILESTONE, LoggingLevel::MILESTONE, + LoggingLevel::MILESTONE, LoggingLevel::MILESTONE, LoggingLevel::MILESTONE}; constexpr unsigned kJsonOverrideNumOfPreloadedServers{13}; const std::string kJsonOverrideSessionServerPath{"/tmp/RialtoServer"}; constexpr std::chrono::milliseconds kJsonOverrideStartupTimeout{12}; constexpr std::chrono::seconds kJsonOverrideHealthcheckInterval{4}; -const SocketPermissions kJsonOverrideSocketPermissions{7, 3, 4, "user3", "group3"}; +const SocketPermissions kJsonOverrideSocketPermissions{7, 3, 4, "user4", "group4"}; constexpr unsigned kJsonOverrideNumOfFailedPingsBeforeRecovery{7}; const LoggingLevels kJsonOverrideLoggingLevels{LoggingLevel::INFO, LoggingLevel::INFO, LoggingLevel::INFO, LoggingLevel::INFO, LoggingLevel::INFO, LoggingLevel::INFO}; +template std::list mergeLists(const Container... containers) +{ + std::list result; + for (const auto &container : {containers...}) + { + result.insert(result.end(), container.begin(), container.end()); + } + return result; +} } // namespace class ConfigHelperTests : public testing::Test { public: - void shouldReturnStructValues() + void shouldReturnStructValuesWithEnvVars(const std::list &expectedEnvVars) { - EXPECT_EQ(m_sut->getSessionServerEnvVars(), kServerManagerConfig.sessionServerEnvVars); + EXPECT_EQ(m_sut->getSessionServerEnvVars(), expectedEnvVars); EXPECT_EQ(m_sut->getSessionServerPath(), kServerManagerConfig.sessionServerPath); EXPECT_EQ(m_sut->getSessionServerStartupTimeout(), kServerManagerConfig.sessionServerStartupTimeout); EXPECT_EQ(m_sut->getHealthcheckInterval(), kServerManagerConfig.healthcheckInterval); @@ -92,11 +112,9 @@ class ConfigHelperTests : public testing::Test EXPECT_EQ(m_sut->getLoggingLevels().commonLoggingLevel, LoggingLevel::UNCHANGED); } - void shouldReturnJsonValues() + void shouldReturnJsonValues(const std::list &expectedEnvVars) { - const std::list kExpectedEnvVars{kServerManagerConfig.sessionServerEnvVars.front(), - kJsonSessionServerEnvVars.front()}; - EXPECT_EQ(m_sut->getSessionServerEnvVars(), kExpectedEnvVars); + EXPECT_EQ(m_sut->getSessionServerEnvVars(), expectedEnvVars); EXPECT_EQ(m_sut->getSessionServerPath(), kJsonSessionServerPath); EXPECT_EQ(m_sut->getSessionServerStartupTimeout(), kJsonStartupTimeout); EXPECT_EQ(m_sut->getHealthcheckInterval(), kJsonHealthcheckInterval); @@ -115,12 +133,9 @@ class ConfigHelperTests : public testing::Test EXPECT_EQ(m_sut->getLoggingLevels().commonLoggingLevel, kJsonLoggingLevels.commonLoggingLevel); } - void shouldReturnJsonOverrideValues() + void shouldReturnJsonOverrideValues(const std::list &expectedEnvVars) { - const std::list kExpectedEnvVars{kServerManagerConfig.sessionServerEnvVars.front(), - kJsonSessionServerEnvVars.front(), - kJsonOverrideSessionServerEnvVars.front()}; - EXPECT_EQ(m_sut->getSessionServerEnvVars(), kExpectedEnvVars); + EXPECT_EQ(m_sut->getSessionServerEnvVars(), expectedEnvVars); EXPECT_EQ(m_sut->getSessionServerPath(), kJsonOverrideSessionServerPath); EXPECT_EQ(m_sut->getSessionServerStartupTimeout(), kJsonOverrideStartupTimeout); EXPECT_EQ(m_sut->getHealthcheckInterval(), kJsonOverrideHealthcheckInterval); @@ -141,17 +156,40 @@ class ConfigHelperTests : public testing::Test EXPECT_EQ(m_sut->getLoggingLevels().commonLoggingLevel, kJsonOverrideLoggingLevels.commonLoggingLevel); } + void shouldReturnJsonSocValues(const std::list &expectedEnvVars) + { + EXPECT_EQ(m_sut->getSessionServerEnvVars(), expectedEnvVars); + EXPECT_EQ(m_sut->getSessionServerPath(), kJsonSocSessionServerPath); + EXPECT_EQ(m_sut->getSessionServerStartupTimeout(), kJsonSocStartupTimeout); + EXPECT_EQ(m_sut->getHealthcheckInterval(), kJsonSocHealthcheckInterval); + EXPECT_EQ(m_sut->getSocketPermissions().ownerPermissions, kJsonSocSocketPermissions.ownerPermissions); + EXPECT_EQ(m_sut->getSocketPermissions().groupPermissions, kJsonSocSocketPermissions.groupPermissions); + EXPECT_EQ(m_sut->getSocketPermissions().otherPermissions, kJsonSocSocketPermissions.otherPermissions); + EXPECT_EQ(m_sut->getSocketPermissions().owner, kJsonSocSocketPermissions.owner); + EXPECT_EQ(m_sut->getSocketPermissions().group, kJsonSocSocketPermissions.group); + EXPECT_EQ(m_sut->getNumOfPreloadedServers(), kJsonSocNumOfPreloadedServers); + EXPECT_EQ(m_sut->getNumOfFailedPingsBeforeRecovery(), kJsonSocNumOfFailedPingsBeforeRecovery); + EXPECT_EQ(m_sut->getLoggingLevels().defaultLoggingLevel, kJsonSocLoggingLevels.defaultLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().clientLoggingLevel, kJsonSocLoggingLevels.clientLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().sessionServerLoggingLevel, kJsonSocLoggingLevels.sessionServerLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().ipcLoggingLevel, kJsonSocLoggingLevels.ipcLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().serverManagerLoggingLevel, kJsonSocLoggingLevels.serverManagerLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().commonLoggingLevel, kJsonSocLoggingLevels.commonLoggingLevel); + } + void jsonConfigReaderWillFailToReadFile() { EXPECT_CALL(*m_configReaderFactoryMock, createConfigReader(kRialtoConfigPath)).WillOnce(Return(m_configReaderMock)); EXPECT_CALL(*m_configReaderMock, read()).WillOnce(Return(false)); } - void jsonConfigReaderWillReturnNulloptsWithEnvVars(const std::list &envVars) + void jsonConfigReaderWillReturnNulloptsWithEnvVars(const std::list &envVars, + const std::list &extraEnvVars) { EXPECT_CALL(*m_configReaderFactoryMock, createConfigReader(kRialtoConfigPath)).WillOnce(Return(m_configReaderMock)); EXPECT_CALL(*m_configReaderMock, read()).WillOnce(Return(true)); EXPECT_CALL(*m_configReaderMock, getEnvironmentVariables()).WillOnce(Return(envVars)); + EXPECT_CALL(*m_configReaderMock, getExtraEnvVariables()).WillOnce(Return(extraEnvVars)); EXPECT_CALL(*m_configReaderMock, getSessionServerPath()).WillOnce(Return(std::nullopt)); EXPECT_CALL(*m_configReaderMock, getSessionServerStartupTimeout()).WillOnce(Return(std::nullopt)); EXPECT_CALL(*m_configReaderMock, getHealthcheckInterval()).WillOnce(Return(std::nullopt)); @@ -163,11 +201,13 @@ class ConfigHelperTests : public testing::Test EXPECT_CALL(*m_configReaderMock, getNumOfPingsBeforeRecovery()).WillOnce(Return(std::nullopt)); } - void jsonConfigReaderWillReturnNewValues() + void jsonConfigReaderWillReturnNewValues(const std::list &envVars, + const std::list &extraEnvVars) { EXPECT_CALL(*m_configReaderFactoryMock, createConfigReader(kRialtoConfigPath)).WillOnce(Return(m_configReaderMock)); EXPECT_CALL(*m_configReaderMock, read()).WillOnce(Return(true)); - EXPECT_CALL(*m_configReaderMock, getEnvironmentVariables()).WillRepeatedly(Return(kJsonSessionServerEnvVars)); + EXPECT_CALL(*m_configReaderMock, getEnvironmentVariables()).WillRepeatedly(Return(envVars)); + EXPECT_CALL(*m_configReaderMock, getExtraEnvVariables()).WillOnce(Return(extraEnvVars)); EXPECT_CALL(*m_configReaderMock, getSessionServerPath()).WillRepeatedly(Return(kJsonSessionServerPath)); EXPECT_CALL(*m_configReaderMock, getSessionServerStartupTimeout()).WillRepeatedly(Return(kJsonStartupTimeout)); EXPECT_CALL(*m_configReaderMock, getHealthcheckInterval()).WillRepeatedly(Return(kJsonHealthcheckInterval)); @@ -187,12 +227,14 @@ class ConfigHelperTests : public testing::Test EXPECT_CALL(*m_configOverridesReaderMock, read()).WillOnce(Return(false)); } - void jsonConfigOverridesReaderWillReturnNulloptsWithEnvVars(const std::list &envVars) + void jsonConfigOverridesReaderWillReturnNulloptsWithEnvVars(const std::list &envVars, + const std::list &extraEnvVars) { EXPECT_CALL(*m_configReaderFactoryMock, createConfigReader(kRialtoConfigOverridesPath)) .WillOnce(Return(m_configOverridesReaderMock)); EXPECT_CALL(*m_configOverridesReaderMock, read()).WillOnce(Return(true)); EXPECT_CALL(*m_configOverridesReaderMock, getEnvironmentVariables()).WillOnce(Return(envVars)); + EXPECT_CALL(*m_configOverridesReaderMock, getExtraEnvVariables()).WillOnce(Return(extraEnvVars)); EXPECT_CALL(*m_configOverridesReaderMock, getSessionServerPath()).WillOnce(Return(std::nullopt)); EXPECT_CALL(*m_configOverridesReaderMock, getSessionServerStartupTimeout()).WillOnce(Return(std::nullopt)); EXPECT_CALL(*m_configOverridesReaderMock, getHealthcheckInterval()).WillOnce(Return(std::nullopt)); @@ -204,13 +246,14 @@ class ConfigHelperTests : public testing::Test EXPECT_CALL(*m_configOverridesReaderMock, getNumOfPingsBeforeRecovery()).WillOnce(Return(std::nullopt)); } - void jsonConfigOverridesReaderWillReturnNewValues() + void jsonConfigOverridesReaderWillReturnNewValues(const std::list &envVars, + const std::list &extraEnvVars) { EXPECT_CALL(*m_configReaderFactoryMock, createConfigReader(kRialtoConfigOverridesPath)) .WillOnce(Return(m_configOverridesReaderMock)); EXPECT_CALL(*m_configOverridesReaderMock, read()).WillOnce(Return(true)); - EXPECT_CALL(*m_configOverridesReaderMock, getEnvironmentVariables()) - .WillRepeatedly(Return(kJsonOverrideSessionServerEnvVars)); + EXPECT_CALL(*m_configOverridesReaderMock, getEnvironmentVariables()).WillRepeatedly(Return(envVars)); + EXPECT_CALL(*m_configOverridesReaderMock, getExtraEnvVariables()).WillOnce(Return(extraEnvVars)); EXPECT_CALL(*m_configOverridesReaderMock, getSessionServerPath()) .WillRepeatedly(Return(kJsonOverrideSessionServerPath)); EXPECT_CALL(*m_configOverridesReaderMock, getSessionServerStartupTimeout()) @@ -230,6 +273,52 @@ class ConfigHelperTests : public testing::Test .WillRepeatedly(Return(kJsonOverrideNumOfFailedPingsBeforeRecovery)); } + void jsonConfigSocReaderWillFailToReadFile() + { + EXPECT_CALL(*m_configReaderFactoryMock, createConfigReader(kRialtoConfigSocPath)) + .WillOnce(Return(m_configSocReaderMock)); + EXPECT_CALL(*m_configSocReaderMock, read()).WillOnce(Return(false)); + } + + void jsonConfigSocReaderWillReturnNulloptsWithEnvVars(const std::list &envVars, + const std::list &extraEnvVars) + { + EXPECT_CALL(*m_configReaderFactoryMock, createConfigReader(kRialtoConfigSocPath)) + .WillOnce(Return(m_configSocReaderMock)); + EXPECT_CALL(*m_configSocReaderMock, read()).WillOnce(Return(true)); + EXPECT_CALL(*m_configSocReaderMock, getEnvironmentVariables()).WillOnce(Return(envVars)); + EXPECT_CALL(*m_configSocReaderMock, getExtraEnvVariables()).WillOnce(Return(extraEnvVars)); + EXPECT_CALL(*m_configSocReaderMock, getSessionServerPath()).WillOnce(Return(std::nullopt)); + EXPECT_CALL(*m_configSocReaderMock, getSessionServerStartupTimeout()).WillOnce(Return(std::nullopt)); + EXPECT_CALL(*m_configSocReaderMock, getHealthcheckInterval()).WillOnce(Return(std::nullopt)); + EXPECT_CALL(*m_configSocReaderMock, getSocketPermissions()).WillOnce(Return(std::nullopt)); + EXPECT_CALL(*m_configSocReaderMock, getSocketOwner()).WillOnce(Return(std::nullopt)); + EXPECT_CALL(*m_configSocReaderMock, getSocketGroup()).WillOnce(Return(std::nullopt)); + EXPECT_CALL(*m_configSocReaderMock, getNumOfPreloadedServers()).WillOnce(Return(std::nullopt)); + EXPECT_CALL(*m_configSocReaderMock, getLoggingLevels()).WillOnce(Return(std::nullopt)); + EXPECT_CALL(*m_configSocReaderMock, getNumOfPingsBeforeRecovery()).WillOnce(Return(std::nullopt)); + } + + void jsonConfigSocReaderWillReturnNewValues(const std::list &envVars, + const std::list &extraEnvVars) + { + EXPECT_CALL(*m_configReaderFactoryMock, createConfigReader(kRialtoConfigSocPath)) + .WillOnce(Return(m_configSocReaderMock)); + EXPECT_CALL(*m_configSocReaderMock, read()).WillOnce(Return(true)); + EXPECT_CALL(*m_configSocReaderMock, getEnvironmentVariables()).WillRepeatedly(Return(envVars)); + EXPECT_CALL(*m_configSocReaderMock, getExtraEnvVariables()).WillOnce(Return(extraEnvVars)); + EXPECT_CALL(*m_configSocReaderMock, getSessionServerPath()).WillRepeatedly(Return(kJsonSocSessionServerPath)); + EXPECT_CALL(*m_configSocReaderMock, getSessionServerStartupTimeout()).WillRepeatedly(Return(kJsonSocStartupTimeout)); + EXPECT_CALL(*m_configSocReaderMock, getHealthcheckInterval()).WillRepeatedly(Return(kJsonSocHealthcheckInterval)); + EXPECT_CALL(*m_configSocReaderMock, getSocketPermissions()).WillRepeatedly(Return(kJsonSocSocketPermissions)); + EXPECT_CALL(*m_configSocReaderMock, getSocketOwner()).WillRepeatedly(Return(kJsonSocSocketPermissions.owner)); + EXPECT_CALL(*m_configSocReaderMock, getSocketGroup()).WillRepeatedly(Return(kJsonSocSocketPermissions.group)); + EXPECT_CALL(*m_configSocReaderMock, getNumOfPreloadedServers()).WillRepeatedly(Return(kJsonSocNumOfPreloadedServers)); + EXPECT_CALL(*m_configSocReaderMock, getLoggingLevels()).WillRepeatedly(Return(kJsonSocLoggingLevels)); + EXPECT_CALL(*m_configSocReaderMock, getNumOfPingsBeforeRecovery()) + .WillRepeatedly(Return(kJsonSocNumOfFailedPingsBeforeRecovery)); + } + void initSut(std::unique_ptr> &&configReaderFactory) { m_sut = std::make_unique(std::move(configReaderFactory), kServerManagerConfig); @@ -242,66 +331,121 @@ class ConfigHelperTests : public testing::Test std::shared_ptr> m_configReaderMock{std::make_shared>()}; std::shared_ptr> m_configOverridesReaderMock{ std::make_shared>()}; + std::shared_ptr> m_configSocReaderMock{std::make_shared>()}; }; TEST_F(ConfigHelperTests, ShouldNotUseMainJsonValuesWhenFactoryIsNull) { initSut(nullptr); - shouldReturnStructValues(); + shouldReturnStructValuesWithEnvVars(kEnvVarSet1); } TEST_F(ConfigHelperTests, ShouldNotUseMainJsonValuesWhenConfigReaderIsNull) { jsonConfigReaderWillFailToReadFile(); + jsonConfigSocReaderWillFailToReadFile(); jsonConfigOverridesReaderWillFailToReadFile(); initSut(std::move(m_configReaderFactoryMock)); - shouldReturnStructValues(); + shouldReturnStructValuesWithEnvVars(kEnvVarSet1); } TEST_F(ConfigHelperTests, ShouldNotUseMainJsonValuesWhenConfigReaderReturnsNullopts) { - jsonConfigReaderWillReturnNulloptsWithEnvVars(kEmptyEnvVars); + jsonConfigReaderWillReturnNulloptsWithEnvVars(kEmptyEnvVars, kEmptyEnvVars); + jsonConfigSocReaderWillFailToReadFile(); jsonConfigOverridesReaderWillFailToReadFile(); initSut(std::move(m_configReaderFactoryMock)); - shouldReturnStructValues(); + shouldReturnStructValuesWithEnvVars(kEnvVarSet1); } TEST_F(ConfigHelperTests, ShouldUseMainJsonValues) { - jsonConfigReaderWillReturnNewValues(); + jsonConfigReaderWillReturnNewValues(kEnvVarSet2, kEmptyEnvVars); + jsonConfigSocReaderWillFailToReadFile(); + jsonConfigOverridesReaderWillFailToReadFile(); + initSut(std::move(m_configReaderFactoryMock)); + shouldReturnJsonValues(kEnvVarSet2); +} + +TEST_F(ConfigHelperTests, ShouldOverrideEnvVariable) +{ + jsonConfigReaderWillReturnNulloptsWithEnvVars(kOverwrittenEnvVar, kEmptyEnvVars); + jsonConfigSocReaderWillFailToReadFile(); jsonConfigOverridesReaderWillFailToReadFile(); initSut(std::move(m_configReaderFactoryMock)); - shouldReturnJsonValues(); + shouldReturnStructValuesWithEnvVars(kOverwrittenEnvVar); } -TEST_F(ConfigHelperTests, ShouldNotOverrideEnvVariable) +TEST_F(ConfigHelperTests, ShouldOverrideEnvVariableWithExtraArgs) { - jsonConfigReaderWillReturnNulloptsWithEnvVars(kOverwrittenEnvVar); + jsonConfigReaderWillReturnNulloptsWithEnvVars(kOverwrittenEnvVar, kEnvVarSet2); + jsonConfigSocReaderWillFailToReadFile(); jsonConfigOverridesReaderWillFailToReadFile(); initSut(std::move(m_configReaderFactoryMock)); - shouldReturnStructValues(); + + const std::list kExpectedEnvVars{mergeLists(kOverwrittenEnvVar, kEnvVarSet2)}; + shouldReturnStructValuesWithEnvVars(kExpectedEnvVars); } TEST_F(ConfigHelperTests, ShouldNotUseMainJsonValuesWhenConfigReadersReturnNullopts) { - jsonConfigReaderWillReturnNulloptsWithEnvVars(kEmptyEnvVars); - jsonConfigOverridesReaderWillReturnNulloptsWithEnvVars(kEmptyEnvVars); + jsonConfigReaderWillReturnNulloptsWithEnvVars(kEmptyEnvVars, kEmptyEnvVars); + jsonConfigSocReaderWillReturnNulloptsWithEnvVars(kEmptyEnvVars, kEmptyEnvVars); + jsonConfigOverridesReaderWillReturnNulloptsWithEnvVars(kEmptyEnvVars, kEmptyEnvVars); + initSut(std::move(m_configReaderFactoryMock)); + shouldReturnStructValuesWithEnvVars(kEnvVarSet1); +} + +TEST_F(ConfigHelperTests, ShouldOverrideEnvVariablesBySocFile) +{ + jsonConfigReaderWillReturnNulloptsWithEnvVars(kEnvVarSet1, kEnvVarSet2); + jsonConfigSocReaderWillReturnNulloptsWithEnvVars(kEnvVarSet3, kEnvVarSet4); + jsonConfigOverridesReaderWillFailToReadFile(); + initSut(std::move(m_configReaderFactoryMock)); + shouldReturnStructValuesWithEnvVars(mergeLists(kEnvVarSet3, kEnvVarSet4)); +} + +TEST_F(ConfigHelperTests, ShouldUseJsonSocValues) +{ + jsonConfigReaderWillReturnNulloptsWithEnvVars(kEnvVarSet1, kEnvVarSet2); + jsonConfigSocReaderWillReturnNewValues(kEnvVarSet3, kEmptyEnvVars); + jsonConfigOverridesReaderWillFailToReadFile(); initSut(std::move(m_configReaderFactoryMock)); - shouldReturnStructValues(); + shouldReturnJsonSocValues(kEnvVarSet3); } -TEST_F(ConfigHelperTests, ShouldNotOverrideEnvVariableByOverridesFile) +TEST_F(ConfigHelperTests, ShouldOverrideEnvVariablesByOverridesFile) { - jsonConfigReaderWillReturnNulloptsWithEnvVars(kOverwrittenEnvVar); - jsonConfigOverridesReaderWillReturnNulloptsWithEnvVars(kOverwrittenEnvVar); + jsonConfigReaderWillReturnNulloptsWithEnvVars(kEnvVarSet1, kEnvVarSet2); + jsonConfigSocReaderWillReturnNulloptsWithEnvVars(kEnvVarSet3, kEnvVarSet4); + jsonConfigOverridesReaderWillReturnNulloptsWithEnvVars(kOverwrittenEnvVar, kEmptyEnvVars); initSut(std::move(m_configReaderFactoryMock)); - shouldReturnStructValues(); + shouldReturnStructValuesWithEnvVars(kOverwrittenEnvVar); +} + +TEST_F(ConfigHelperTests, ShouldAppendExtraEnvVars) +{ + jsonConfigReaderWillReturnNulloptsWithEnvVars(kEnvVarSet1, kEnvVarSet2); + jsonConfigSocReaderWillReturnNulloptsWithEnvVars(kEmptyEnvVars, kEnvVarSet3); + jsonConfigOverridesReaderWillReturnNulloptsWithEnvVars(kEmptyEnvVars, kEnvVarSet4); + initSut(std::move(m_configReaderFactoryMock)); + shouldReturnStructValuesWithEnvVars(mergeLists(kEnvVarSet1, kEnvVarSet4)); } TEST_F(ConfigHelperTests, ShouldUseJsonOverrideValues) { - jsonConfigReaderWillReturnNewValues(); - jsonConfigOverridesReaderWillReturnNewValues(); + jsonConfigReaderWillReturnNulloptsWithEnvVars(kEnvVarSet1, kEnvVarSet2); + jsonConfigSocReaderWillReturnNulloptsWithEnvVars(kEnvVarSet3, kEnvVarSet4); + jsonConfigOverridesReaderWillReturnNewValues(kEnvVarSet3, kEmptyEnvVars); + initSut(std::move(m_configReaderFactoryMock)); + shouldReturnJsonOverrideValues(kEnvVarSet3); +} + +TEST_F(ConfigHelperTests, ShouldOverrideOldValues) +{ + jsonConfigReaderWillReturnNulloptsWithEnvVars(kEnvVarSet1, kEnvVarSet2); + jsonConfigSocReaderWillReturnNewValues(kEnvVarSet3, kOverwrittenEnvVar); + jsonConfigOverridesReaderWillReturnNewValues(kEnvVarSet4, kEmptyEnvVars); initSut(std::move(m_configReaderFactoryMock)); - shouldReturnJsonOverrideValues(); + shouldReturnJsonOverrideValues(kEnvVarSet4); } diff --git a/tests/unittests/serverManager/unittests/service/ConfigReaderTests.cpp b/tests/unittests/serverManager/unittests/service/ConfigReaderTests.cpp index db2b7fb47..d5bdde8a3 100644 --- a/tests/unittests/serverManager/unittests/service/ConfigReaderTests.cpp +++ b/tests/unittests/serverManager/unittests/service/ConfigReaderTests.cpp @@ -139,7 +139,7 @@ TEST_F(ConfigReaderTests, thereWillBeNothing) EXPECT_EQ(m_sut->getNumOfPreloadedServers().has_value(), false); } -TEST_F(ConfigReaderTests, envVariablesNotArray) +TEST_F(ConfigReaderTests, envVariablesNotArraySnakeCase) { expectSuccessfulParsing(); @@ -153,7 +153,21 @@ TEST_F(ConfigReaderTests, envVariablesNotArray) EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); } -TEST_F(ConfigReaderTests, envVariablesEmptyArray) +TEST_F(ConfigReaderTests, envVariablesNotArray) +{ + expectSuccessfulParsing(); + + EXPECT_CALL(*m_rootJsonValueMock, isMember("environmentVariables")).WillOnce(Return(true)); + EXPECT_CALL(*m_rootJsonValueMock, at("environmentVariables")).WillOnce(Return(m_objectJsonValueMock)); + EXPECT_CALL(*m_objectJsonValueMock, isArray()).WillOnce(Return(false)); + + EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("environmentVariables"))).WillRepeatedly(Return(false)); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); +} + +TEST_F(ConfigReaderTests, envVariablesEmptyArraySnakeCase) { expectSuccessfulParsing(); @@ -168,7 +182,22 @@ TEST_F(ConfigReaderTests, envVariablesEmptyArray) EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); } -TEST_F(ConfigReaderTests, envVariablesOneElementArrayNotString) +TEST_F(ConfigReaderTests, envVariablesEmptyArray) +{ + expectSuccessfulParsing(); + + EXPECT_CALL(*m_rootJsonValueMock, isMember("environmentVariables")).WillOnce(Return(true)); + EXPECT_CALL(*m_rootJsonValueMock, at("environmentVariables")).WillRepeatedly(Return(m_objectJsonValueMock)); + EXPECT_CALL(*m_objectJsonValueMock, isArray()).WillOnce(Return(true)); + EXPECT_CALL(*m_objectJsonValueMock, size()).WillOnce(Return(0)); + + EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("environmentVariables"))).WillRepeatedly(Return(false)); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); +} + +TEST_F(ConfigReaderTests, envVariablesOneElementArrayNotStringSnakeCase) { std::shared_ptr> object1JsonValueMock = std::make_shared>(); @@ -188,7 +217,27 @@ TEST_F(ConfigReaderTests, envVariablesOneElementArrayNotString) EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); } -TEST_F(ConfigReaderTests, envVariablesMultipleElementArray) +TEST_F(ConfigReaderTests, envVariablesOneElementArrayNotString) +{ + std::shared_ptr> object1JsonValueMock = + std::make_shared>(); + + expectSuccessfulParsing(); + + EXPECT_CALL(*m_rootJsonValueMock, isMember("environmentVariables")).WillOnce(Return(true)); + EXPECT_CALL(*m_rootJsonValueMock, at("environmentVariables")).WillRepeatedly(Return(m_objectJsonValueMock)); + EXPECT_CALL(*m_objectJsonValueMock, isArray()).WillOnce(Return(true)); + EXPECT_CALL(*m_objectJsonValueMock, size()).WillOnce(Return(1)); + EXPECT_CALL(*m_objectJsonValueMock, at(Matcher(0u))).WillOnce(Return(object1JsonValueMock)); + EXPECT_CALL(*object1JsonValueMock, isString()).WillOnce(Return(false)); + + EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("environmentVariables"))).WillRepeatedly(Return(false)); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); +} + +TEST_F(ConfigReaderTests, envVariablesMultipleElementArraySnakeCase) { std::shared_ptr> object1JsonValueMock = std::make_shared>(); @@ -214,7 +263,33 @@ TEST_F(ConfigReaderTests, envVariablesMultipleElementArray) EXPECT_THAT(m_sut->getEnvironmentVariables(), UnorderedElementsAre("ELEM_1", "ELEM_2")); } -TEST_F(ConfigReaderTests, sessionServerPathNotString) +TEST_F(ConfigReaderTests, envVariablesMultipleElementArray) +{ + std::shared_ptr> object1JsonValueMock = + std::make_shared>(); + std::shared_ptr> object2JsonValueMock = + std::make_shared>(); + + expectSuccessfulParsing(); + + EXPECT_CALL(*m_rootJsonValueMock, isMember("environmentVariables")).WillOnce(Return(true)); + EXPECT_CALL(*m_rootJsonValueMock, at("environmentVariables")).WillRepeatedly(Return(m_objectJsonValueMock)); + EXPECT_CALL(*m_objectJsonValueMock, isArray()).WillOnce(Return(true)); + EXPECT_CALL(*m_objectJsonValueMock, size()).WillOnce(Return(2)); + EXPECT_CALL(*m_objectJsonValueMock, at(Matcher(0u))).WillRepeatedly(Return(object1JsonValueMock)); + EXPECT_CALL(*object1JsonValueMock, isString()).WillOnce(Return(true)); + EXPECT_CALL(*object1JsonValueMock, asString()).WillOnce(Return("ELEM_1")); + EXPECT_CALL(*m_objectJsonValueMock, at(Matcher(1u))).WillRepeatedly(Return(object2JsonValueMock)); + EXPECT_CALL(*object2JsonValueMock, isString()).WillOnce(Return(true)); + EXPECT_CALL(*object2JsonValueMock, asString()).WillOnce(Return("ELEM_2")); + + EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("environmentVariables"))).WillRepeatedly(Return(false)); + + EXPECT_TRUE(m_sut->read()); + EXPECT_THAT(m_sut->getEnvironmentVariables(), UnorderedElementsAre("ELEM_1", "ELEM_2")); +} + +TEST_F(ConfigReaderTests, sessionServerPathNotStringSnakeCase) { expectSuccessfulParsing(); expectNotString("session_server_path"); @@ -223,7 +298,16 @@ TEST_F(ConfigReaderTests, sessionServerPathNotString) EXPECT_EQ(m_sut->getSessionServerPath().has_value(), false); } -TEST_F(ConfigReaderTests, sessionServerPathExists) +TEST_F(ConfigReaderTests, sessionServerPathNotString) +{ + expectSuccessfulParsing(); + expectNotString("sessionServerPath"); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getSessionServerPath().has_value(), false); +} + +TEST_F(ConfigReaderTests, sessionServerPathExistsSnakeCase) { expectSuccessfulParsing(); expectReturnString("session_server_path", "/usr/bin/RialtoServer"); @@ -232,7 +316,16 @@ TEST_F(ConfigReaderTests, sessionServerPathExists) EXPECT_EQ(m_sut->getSessionServerPath(), "/usr/bin/RialtoServer"); } -TEST_F(ConfigReaderTests, startupTimerNotUint) +TEST_F(ConfigReaderTests, sessionServerPathExists) +{ + expectSuccessfulParsing(); + expectReturnString("sessionServerPath", "/usr/bin/RialtoServer"); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getSessionServerPath(), "/usr/bin/RialtoServer"); +} + +TEST_F(ConfigReaderTests, startupTimerNotUintSnakeCase) { expectSuccessfulParsing(); expectNotUint("startup_timeout_ms"); @@ -241,7 +334,16 @@ TEST_F(ConfigReaderTests, startupTimerNotUint) EXPECT_EQ(m_sut->getSessionServerStartupTimeout().has_value(), false); } -TEST_F(ConfigReaderTests, startupTimerExists) +TEST_F(ConfigReaderTests, startupTimerNotUint) +{ + expectSuccessfulParsing(); + expectNotUint("startupTimeoutMs"); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getSessionServerStartupTimeout().has_value(), false); +} + +TEST_F(ConfigReaderTests, startupTimerExistsSnakeCase) { expectSuccessfulParsing(); expectReturnUint("startup_timeout_ms", 5000); @@ -250,7 +352,16 @@ TEST_F(ConfigReaderTests, startupTimerExists) EXPECT_EQ(m_sut->getSessionServerStartupTimeout(), std::chrono::milliseconds(5000)); } -TEST_F(ConfigReaderTests, healthCheckIntervalNotUint) +TEST_F(ConfigReaderTests, startupTimerExists) +{ + expectSuccessfulParsing(); + expectReturnUint("startupTimeoutMs", 5000); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getSessionServerStartupTimeout(), std::chrono::milliseconds(5000)); +} + +TEST_F(ConfigReaderTests, healthCheckIntervalNotUintSnakeCase) { expectSuccessfulParsing(); expectNotUint("healthcheck_interval_s"); @@ -259,7 +370,16 @@ TEST_F(ConfigReaderTests, healthCheckIntervalNotUint) EXPECT_EQ(m_sut->getHealthcheckInterval().has_value(), false); } -TEST_F(ConfigReaderTests, healthCheckIntervalExists) +TEST_F(ConfigReaderTests, healthCheckIntervalNotUint) +{ + expectSuccessfulParsing(); + expectNotUint("healthcheckIntervalInSeconds"); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getHealthcheckInterval().has_value(), false); +} + +TEST_F(ConfigReaderTests, healthCheckIntervalExistsSnakeCase) { expectSuccessfulParsing(); expectReturnUint("healthcheck_interval_s", 1); @@ -268,7 +388,16 @@ TEST_F(ConfigReaderTests, healthCheckIntervalExists) EXPECT_EQ(m_sut->getHealthcheckInterval(), std::chrono::seconds(1)); } -TEST_F(ConfigReaderTests, socketPermissionsNotUint) +TEST_F(ConfigReaderTests, healthCheckIntervalExists) +{ + expectSuccessfulParsing(); + expectReturnUint("healthcheckIntervalInSeconds", 1); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getHealthcheckInterval(), std::chrono::seconds(1)); +} + +TEST_F(ConfigReaderTests, socketPermissionsNotUintSnakeCase) { expectSuccessfulParsing(); expectNotUint("socket_permissions"); @@ -277,7 +406,16 @@ TEST_F(ConfigReaderTests, socketPermissionsNotUint) EXPECT_EQ(m_sut->getSocketPermissions().has_value(), false); } -TEST_F(ConfigReaderTests, socketPermissionsExists) +TEST_F(ConfigReaderTests, socketPermissionsNotUint) +{ + expectSuccessfulParsing(); + expectNotUint("socketPermissions"); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getSocketPermissions().has_value(), false); +} + +TEST_F(ConfigReaderTests, socketPermissionsExistsSnakeCase) { expectSuccessfulParsing(); expectReturnUint("socket_permissions", 666); @@ -289,7 +427,19 @@ TEST_F(ConfigReaderTests, socketPermissionsExists) EXPECT_EQ(m_sut->getSocketPermissions().value().otherPermissions, expectedPermissions.otherPermissions); } -TEST_F(ConfigReaderTests, socketOwnerNotString) +TEST_F(ConfigReaderTests, socketPermissionsExists) +{ + expectSuccessfulParsing(); + expectReturnUint("socketPermissions", 666); + + EXPECT_TRUE(m_sut->read()); + firebolt::rialto::common::SocketPermissions expectedPermissions{6, 6, 6}; + EXPECT_EQ(m_sut->getSocketPermissions().value().ownerPermissions, expectedPermissions.ownerPermissions); + EXPECT_EQ(m_sut->getSocketPermissions().value().groupPermissions, expectedPermissions.groupPermissions); + EXPECT_EQ(m_sut->getSocketPermissions().value().otherPermissions, expectedPermissions.otherPermissions); +} + +TEST_F(ConfigReaderTests, socketOwnerNotStringSnakeCase) { expectSuccessfulParsing(); expectNotString("socket_owner"); @@ -297,7 +447,15 @@ TEST_F(ConfigReaderTests, socketOwnerNotString) EXPECT_EQ(m_sut->getSocketOwner().has_value(), false); } -TEST_F(ConfigReaderTests, socketOwnerExists) +TEST_F(ConfigReaderTests, socketOwnerNotString) +{ + expectSuccessfulParsing(); + expectNotString("socketOwner"); + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getSocketOwner().has_value(), false); +} + +TEST_F(ConfigReaderTests, socketOwnerExistsSnakeCase) { const char *kTestValue = "root"; expectSuccessfulParsing(); @@ -306,7 +464,16 @@ TEST_F(ConfigReaderTests, socketOwnerExists) EXPECT_EQ(m_sut->getSocketOwner().value(), kTestValue); } -TEST_F(ConfigReaderTests, socketGroupNotString) +TEST_F(ConfigReaderTests, socketOwnerExists) +{ + const char *kTestValue = "root"; + expectSuccessfulParsing(); + expectReturnString("socketOwner", kTestValue); + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getSocketOwner().value(), kTestValue); +} + +TEST_F(ConfigReaderTests, socketGroupNotStringSnakeCase) { expectSuccessfulParsing(); expectNotString("socket_group"); @@ -314,7 +481,15 @@ TEST_F(ConfigReaderTests, socketGroupNotString) EXPECT_EQ(m_sut->getSocketGroup().has_value(), false); } -TEST_F(ConfigReaderTests, socketGroupExists) +TEST_F(ConfigReaderTests, socketGroupNotString) +{ + expectSuccessfulParsing(); + expectNotString("socketGroup"); + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getSocketGroup().has_value(), false); +} + +TEST_F(ConfigReaderTests, socketGroupExistsSnakeCase) { const char *kTestValue = "root"; expectSuccessfulParsing(); @@ -323,7 +498,16 @@ TEST_F(ConfigReaderTests, socketGroupExists) EXPECT_EQ(m_sut->getSocketGroup().value(), kTestValue); } -TEST_F(ConfigReaderTests, numOfPreloadedServersNotUint) +TEST_F(ConfigReaderTests, socketGroupExists) +{ + const char *kTestValue = "root"; + expectSuccessfulParsing(); + expectReturnString("socketGroup", kTestValue); + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getSocketGroup().value(), kTestValue); +} + +TEST_F(ConfigReaderTests, numOfPreloadedServersNotUintSnakeCase) { expectSuccessfulParsing(); expectNotUint("num_of_preloaded_servers"); @@ -332,7 +516,16 @@ TEST_F(ConfigReaderTests, numOfPreloadedServersNotUint) EXPECT_EQ(m_sut->getNumOfPreloadedServers().has_value(), false); } -TEST_F(ConfigReaderTests, numOfPreloadedServersExists) +TEST_F(ConfigReaderTests, numOfPreloadedServersNotUint) +{ + expectSuccessfulParsing(); + expectNotUint("numOfPreloadedServers"); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getNumOfPreloadedServers().has_value(), false); +} + +TEST_F(ConfigReaderTests, numOfPreloadedServersExistsSnakeCase) { expectSuccessfulParsing(); expectReturnUint("num_of_preloaded_servers", 2); @@ -341,7 +534,16 @@ TEST_F(ConfigReaderTests, numOfPreloadedServersExists) EXPECT_EQ(m_sut->getNumOfPreloadedServers(), 2); } -TEST_F(ConfigReaderTests, logLevelNotUint) +TEST_F(ConfigReaderTests, numOfPreloadedServersExists) +{ + expectSuccessfulParsing(); + expectReturnUint("numOfPreloadedServers", 2); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getNumOfPreloadedServers(), 2); +} + +TEST_F(ConfigReaderTests, logLevelNotUintSnakeCase) { expectSuccessfulParsing(); expectNotUint("log_level"); @@ -350,7 +552,16 @@ TEST_F(ConfigReaderTests, logLevelNotUint) EXPECT_EQ(m_sut->getLoggingLevels().has_value(), false); } -TEST_F(ConfigReaderTests, logLevelSuccessfulParsing) +TEST_F(ConfigReaderTests, logLevelNotUint) +{ + expectSuccessfulParsing(); + expectNotUint("logLevel"); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getLoggingLevels().has_value(), false); +} + +TEST_F(ConfigReaderTests, logLevelSuccessfulParsingSnakeCase) { expectSuccessfulParsing(); expectReturnUint("log_level", 3); @@ -371,7 +582,28 @@ TEST_F(ConfigReaderTests, logLevelSuccessfulParsing) EXPECT_EQ(m_sut->getLoggingLevels().value().commonLoggingLevel, loggingLevel.commonLoggingLevel); } -TEST_F(ConfigReaderTests, numOfPingsBeforeRecoveryNotUint) +TEST_F(ConfigReaderTests, logLevelSuccessfulParsing) +{ + expectSuccessfulParsing(); + expectReturnUint("logLevel", 3); + + EXPECT_TRUE(m_sut->read()); + rialto::servermanager::service::LoggingLevels loggingLevel{rialto::servermanager::service::LoggingLevel::MILESTONE, + rialto::servermanager::service::LoggingLevel::MILESTONE, + rialto::servermanager::service::LoggingLevel::MILESTONE, + rialto::servermanager::service::LoggingLevel::MILESTONE, + rialto::servermanager::service::LoggingLevel::MILESTONE, + rialto::servermanager::service::LoggingLevel::MILESTONE}; + + EXPECT_EQ(m_sut->getLoggingLevels().value().defaultLoggingLevel, loggingLevel.defaultLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().value().clientLoggingLevel, loggingLevel.clientLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().value().sessionServerLoggingLevel, loggingLevel.sessionServerLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().value().ipcLoggingLevel, loggingLevel.ipcLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().value().serverManagerLoggingLevel, loggingLevel.serverManagerLoggingLevel); + EXPECT_EQ(m_sut->getLoggingLevels().value().commonLoggingLevel, loggingLevel.commonLoggingLevel); +} + +TEST_F(ConfigReaderTests, numOfPingsBeforeRecoveryNotUintSnakeCase) { expectSuccessfulParsing(); expectNotUint("num_of_pings_before_recovery"); @@ -380,7 +612,16 @@ TEST_F(ConfigReaderTests, numOfPingsBeforeRecoveryNotUint) EXPECT_EQ(m_sut->getNumOfPreloadedServers().has_value(), false); } -TEST_F(ConfigReaderTests, numOfPingsBeforeRecoveryExists) +TEST_F(ConfigReaderTests, numOfPingsBeforeRecoveryNotUint) +{ + expectSuccessfulParsing(); + expectNotUint("numOfPingsBeforeRecovery"); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getNumOfPreloadedServers().has_value(), false); +} + +TEST_F(ConfigReaderTests, numOfPingsBeforeRecoveryExistsSnakeCase) { expectSuccessfulParsing(); expectReturnUint("num_of_pings_before_recovery", 3); @@ -389,6 +630,15 @@ TEST_F(ConfigReaderTests, numOfPingsBeforeRecoveryExists) EXPECT_EQ(m_sut->getNumOfPingsBeforeRecovery(), 3); } +TEST_F(ConfigReaderTests, numOfPingsBeforeRecoveryExists) +{ + expectSuccessfulParsing(); + expectReturnUint("numOfPingsBeforeRecovery", 3); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getNumOfPingsBeforeRecovery(), 3); +} + TEST_F(ConfigReaderTests, defaultConfigValuesAreSet) { // "Real world" constants defined in rialto/CMakeLists.txt @@ -419,3 +669,78 @@ TEST_F(ConfigReaderTests, defaultConfigValuesAreSet) EXPECT_EQ(config.sessionManagementSocketPermissions.otherPermissions, kDefaultPermissions); EXPECT_EQ(config.numOfFailedPingsBeforeRecovery, kNumOfFailedPingsBeforeRecovery); } + +TEST_F(ConfigReaderTests, extraEnvVariablesNotArray) +{ + expectSuccessfulParsing(); + + EXPECT_CALL(*m_rootJsonValueMock, isMember("extraEnvVariables")).WillOnce(Return(true)); + EXPECT_CALL(*m_rootJsonValueMock, at("extraEnvVariables")).WillOnce(Return(m_objectJsonValueMock)); + EXPECT_CALL(*m_objectJsonValueMock, isArray()).WillOnce(Return(false)); + + EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("extraEnvVariables"))).WillRepeatedly(Return(false)); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getExtraEnvVariables().size(), 0); +} + +TEST_F(ConfigReaderTests, extraEnvVariablesEmptyArray) +{ + expectSuccessfulParsing(); + + EXPECT_CALL(*m_rootJsonValueMock, isMember("extraEnvVariables")).WillOnce(Return(true)); + EXPECT_CALL(*m_rootJsonValueMock, at("extraEnvVariables")).WillRepeatedly(Return(m_objectJsonValueMock)); + EXPECT_CALL(*m_objectJsonValueMock, isArray()).WillOnce(Return(true)); + EXPECT_CALL(*m_objectJsonValueMock, size()).WillOnce(Return(0)); + + EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("extraEnvVariables"))).WillRepeatedly(Return(false)); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getExtraEnvVariables().size(), 0); +} + +TEST_F(ConfigReaderTests, extraEnvVariablesOneElementArrayNotString) +{ + std::shared_ptr> object1JsonValueMock = + std::make_shared>(); + + expectSuccessfulParsing(); + + EXPECT_CALL(*m_rootJsonValueMock, isMember("extraEnvVariables")).WillOnce(Return(true)); + EXPECT_CALL(*m_rootJsonValueMock, at("extraEnvVariables")).WillRepeatedly(Return(m_objectJsonValueMock)); + EXPECT_CALL(*m_objectJsonValueMock, isArray()).WillOnce(Return(true)); + EXPECT_CALL(*m_objectJsonValueMock, size()).WillOnce(Return(1)); + EXPECT_CALL(*m_objectJsonValueMock, at(Matcher(0u))).WillOnce(Return(object1JsonValueMock)); + EXPECT_CALL(*object1JsonValueMock, isString()).WillOnce(Return(false)); + + EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("extraEnvVariables"))).WillRepeatedly(Return(false)); + + EXPECT_TRUE(m_sut->read()); + EXPECT_EQ(m_sut->getExtraEnvVariables().size(), 0); +} + +TEST_F(ConfigReaderTests, extraEnvVariablesMultipleElementArray) +{ + std::shared_ptr> object1JsonValueMock = + std::make_shared>(); + std::shared_ptr> object2JsonValueMock = + std::make_shared>(); + + expectSuccessfulParsing(); + + EXPECT_CALL(*m_rootJsonValueMock, isMember("extraEnvVariables")).WillOnce(Return(true)); + EXPECT_CALL(*m_rootJsonValueMock, at("extraEnvVariables")).WillRepeatedly(Return(m_objectJsonValueMock)); + EXPECT_CALL(*m_objectJsonValueMock, isArray()).WillOnce(Return(true)); + EXPECT_CALL(*m_objectJsonValueMock, size()).WillOnce(Return(2)); + EXPECT_CALL(*m_objectJsonValueMock, at(Matcher(0u))).WillRepeatedly(Return(object1JsonValueMock)); + EXPECT_CALL(*object1JsonValueMock, isString()).WillOnce(Return(true)); + EXPECT_CALL(*object1JsonValueMock, asString()).WillOnce(Return("ELEM_1")); + EXPECT_CALL(*m_objectJsonValueMock, at(Matcher(1u))).WillRepeatedly(Return(object2JsonValueMock)); + EXPECT_CALL(*object2JsonValueMock, isString()).WillOnce(Return(true)); + EXPECT_CALL(*object2JsonValueMock, asString()).WillOnce(Return("ELEM_2")); + + EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("extraEnvVariables"))).WillRepeatedly(Return(false)); + + EXPECT_TRUE(m_sut->read()); + EXPECT_THAT(m_sut->getExtraEnvVariables(), UnorderedElementsAre("ELEM_1", "ELEM_2")); +}