diff --git a/lib/api/LogManagerFactory.cpp b/lib/api/LogManagerFactory.cpp index 0f6a31171..669c1a63d 100644 --- a/lib/api/LogManagerFactory.cpp +++ b/lib/api/LogManagerFactory.cpp @@ -19,12 +19,6 @@ namespace MAT_NS_BEGIN { - // This mutex has to be recursive because we allow both - // Destroy and destrutor to lock it. destructor could be - // called directly, and Destroy calls destructor. - std::recursive_mutex ILogManagerInternal::managers_lock; - std::set ILogManagerInternal::managers; - /// /// Creates an instance of ILogManager using specified configuration. /// @@ -32,9 +26,9 @@ namespace MAT_NS_BEGIN /// ILogManager instance ILogManager* LogManagerFactory::Create(ILogConfiguration& configuration) { - LOCKGUARD(ILogManagerInternal::managers_lock); + LOCKGUARD(ILogManagerInternal::GetManagersLock()); auto logManager = new LogManagerImpl(configuration); - ILogManagerInternal::managers.emplace(logManager); + ILogManagerInternal::GetManagers().emplace(logManager); return logManager; } @@ -50,11 +44,12 @@ namespace MAT_NS_BEGIN return STATUS_EFAIL; } - LOCKGUARD(ILogManagerInternal::managers_lock); - auto it = ILogManagerInternal::managers.find(instance); - if (it != std::end(ILogManagerInternal::managers)) + LOCKGUARD(ILogManagerInternal::GetManagersLock()); + std::set& managers = ILogManagerInternal::GetManagers(); + auto it = managers.find(instance); + if (it != std::end(managers)) { - ILogManagerInternal::managers.erase(it); + managers.erase(it); delete instance; return STATUS_SUCCESS; } diff --git a/lib/api/LogManagerImpl.cpp b/lib/api/LogManagerImpl.cpp index 7b1629a78..0034c540a 100644 --- a/lib/api/LogManagerImpl.cpp +++ b/lib/api/LogManagerImpl.cpp @@ -74,6 +74,24 @@ namespace MAT_NS_BEGIN { + // This mutex has to be recursive because we allow both + // Destroy and destrutor to lock it. destructor could be + // called directly, and Destroy calls destructor. + + // static + std::recursive_mutex& ILogManagerInternal::GetManagersLock() + { + static std::recursive_mutex managers_lock; + return managers_lock; + }; + + // static + std::set& ILogManagerInternal::GetManagers() noexcept + { + static std::set managers; + return managers; + } + void DeadLoggers::AddMap(LoggerMap&& source) { std::lock_guard lock(m_deadLoggersMutex); @@ -94,8 +112,8 @@ namespace MAT_NS_BEGIN bool ILogManager::DispatchEventBroadcast(DebugEvent evt) { - // LOCKGUARD(ILogManagerInternal::managers_lock); - for (auto instance : ILogManagerInternal::managers) + // LOCKGUARD(ILogManagerInternal::GetManagersLock()); + for (auto instance : ILogManagerInternal::GetManagers()) { instance->DispatchEvent(evt); } @@ -353,8 +371,8 @@ namespace MAT_NS_BEGIN LogManagerImpl::~LogManagerImpl() noexcept { FlushAndTeardown(); - LOCKGUARD(ILogManagerInternal::managers_lock); - ILogManagerInternal::managers.erase(this); + LOCKGUARD(ILogManagerInternal::GetManagersLock()); + ILogManagerInternal::GetManagers().erase(this); } size_t LogManagerImpl::GetDeadLoggerCount() diff --git a/lib/api/LogManagerImpl.hpp b/lib/api/LogManagerImpl.hpp index f48b7a847..90e6fa78f 100644 --- a/lib/api/LogManagerImpl.hpp +++ b/lib/api/LogManagerImpl.hpp @@ -114,8 +114,8 @@ namespace MAT_NS_BEGIN class ILogManagerInternal : public ILogManager { public: - static std::recursive_mutex managers_lock; - static std::set managers; + static std::recursive_mutex& GetManagersLock(); + static std::set& GetManagers() noexcept; /// /// Optional decorator runs on event before passing it to sendEvent diff --git a/lib/config/RuntimeConfig_Default.hpp b/lib/config/RuntimeConfig_Default.hpp index 3ff7cbdba..75b286cba 100644 --- a/lib/config/RuntimeConfig_Default.hpp +++ b/lib/config/RuntimeConfig_Default.hpp @@ -10,68 +10,6 @@ namespace MAT_NS_BEGIN { - static ILogConfiguration defaultRuntimeConfig{ - {CFG_INT_TRACE_LEVEL_MIN, ACTTraceLevel::ACTTraceLevel_Error}, - {CFG_INT_SDK_MODE, SdkModeTypes::SdkModeTypes_CS}, - {CFG_BOOL_ENABLE_ANALYTICS, false}, - {CFG_INT_CACHE_FILE_SIZE, 3145728}, - {CFG_INT_RAM_QUEUE_SIZE, 524288}, - {CFG_BOOL_ENABLE_MULTITENANT, true}, - {CFG_BOOL_ENABLE_DB_DROP_IF_FULL, false}, - {CFG_INT_MAX_TEARDOWN_TIME, 1}, - {CFG_INT_MAX_PENDING_REQ, 4}, - {CFG_INT_RAM_QUEUE_BUFFERS, 3}, - {CFG_INT_TRACE_LEVEL_MASK, 0}, - {CFG_BOOL_ENABLE_TRACE, true}, - {CFG_STR_COLLECTOR_URL, COLLECTOR_URL_PROD}, - {CFG_INT_STORAGE_FULL_PCT, 75}, - {CFG_INT_STORAGE_FULL_CHECK_TIME, 5000}, - {CFG_INT_RAMCACHE_FULL_PCT, 75}, - {CFG_BOOL_ENABLE_NET_DETECT, true}, - {CFG_BOOL_SESSION_RESET_ENABLED, false}, - {CFG_MAP_METASTATS_CONFIG, - {/* Parameter that allows to split stats events by tenant */ - {"split", false}, - {"interval", 1800}, - {"tokenProd", STATS_TOKEN_PROD}, - {"tokenInt", STATS_TOKEN_INT}}}, - {"utc", - { -#ifdef HAVE_MAT_UTC - {"providerGroupId", "780dddc8-18a1-5781-895a-a690464fa89c"}, - {CFG_BOOL_UTC_ENABLED, true}, - {CFG_BOOL_UTC_ACTIVE, false}, - {CFG_BOOL_UTC_LARGE_PAYLOADS, false} -#else - {CFG_BOOL_UTC_ENABLED, false} -#endif - }}, - {CFG_MAP_HTTP, - { -#ifdef HAVE_MAT_ZLIB - {CFG_BOOL_HTTP_COMPRESSION, true} -#else - {CFG_BOOL_HTTP_COMPRESSION, false} -#endif - , - {"contentEncoding", "deflate"}, - /* Optional parameter to require Microsoft Root CA */ - {CFG_BOOL_HTTP_MS_ROOT_CHECK, false}}}, - {CFG_MAP_TPM, - { - {CFG_INT_TPM_MAX_BLOB_BYTES, 2097152}, - {CFG_INT_TPM_MAX_RETRY, 5}, - {CFG_BOOL_TPM_CLOCK_SKEW_ENABLED, true}, - {CFG_STR_TPM_BACKOFF, "E,3000,300000,2,1"}, - }}, - {CFG_MAP_COMPAT, - { - {CFG_BOOL_COMPAT_DOTS, true}, // false: v1 backwards-compat: event.SetType("My.Custom.Type") => custom.my_custom_type - {CFG_STR_COMPAT_PREFIX, EVENTRECORD_TYPE_CUSTOM_EVENT} // custom type prefix for Interchange / Geneva / Cosmos flow - }}, - {"sample", - {{"rate", 0}}}}; - /// /// This class overlays a custom configuration provided by the customer /// on top of default configuration above (defaultRuntimeConfig) @@ -81,12 +19,79 @@ namespace MAT_NS_BEGIN { protected: ILogConfiguration& config; - + public: + static ILogConfiguration& GetDefaultRuntimeConfig() + { + static ILogConfiguration defaultRuntimeConfig { + {CFG_INT_TRACE_LEVEL_MIN, ACTTraceLevel::ACTTraceLevel_Error}, + {CFG_INT_SDK_MODE, SdkModeTypes::SdkModeTypes_CS}, + {CFG_BOOL_ENABLE_ANALYTICS, false}, + {CFG_INT_CACHE_FILE_SIZE, 3145728}, + {CFG_INT_RAM_QUEUE_SIZE, 524288}, + {CFG_BOOL_ENABLE_MULTITENANT, true}, + {CFG_BOOL_ENABLE_DB_DROP_IF_FULL, false}, + {CFG_INT_MAX_TEARDOWN_TIME, 1}, + {CFG_INT_MAX_PENDING_REQ, 4}, + {CFG_INT_RAM_QUEUE_BUFFERS, 3}, + {CFG_INT_TRACE_LEVEL_MASK, 0}, + {CFG_BOOL_ENABLE_TRACE, true}, + {CFG_STR_COLLECTOR_URL, COLLECTOR_URL_PROD}, + {CFG_INT_STORAGE_FULL_PCT, 75}, + {CFG_INT_STORAGE_FULL_CHECK_TIME, 5000}, + {CFG_INT_RAMCACHE_FULL_PCT, 75}, + {CFG_BOOL_ENABLE_NET_DETECT, true}, + {CFG_BOOL_SESSION_RESET_ENABLED, false}, + {CFG_MAP_METASTATS_CONFIG, + {/* Parameter that allows to split stats events by tenant */ + {"split", false}, + {"interval", 1800}, + {"tokenProd", STATS_TOKEN_PROD}, + {"tokenInt", STATS_TOKEN_INT}}}, + {"utc", + { + #ifdef HAVE_MAT_UTC + {"providerGroupId", "780dddc8-18a1-5781-895a-a690464fa89c"}, + {CFG_BOOL_UTC_ENABLED, true}, + {CFG_BOOL_UTC_ACTIVE, false}, + {CFG_BOOL_UTC_LARGE_PAYLOADS, false} + #else + {CFG_BOOL_UTC_ENABLED, false} + #endif + }}, + {CFG_MAP_HTTP, + { + #ifdef HAVE_MAT_ZLIB + {CFG_BOOL_HTTP_COMPRESSION, true} + #else + {CFG_BOOL_HTTP_COMPRESSION, false} + #endif + , + {"contentEncoding", "deflate"}, + /* Optional parameter to require Microsoft Root CA */ + {CFG_BOOL_HTTP_MS_ROOT_CHECK, false}}}, + {CFG_MAP_TPM, + { + {CFG_INT_TPM_MAX_BLOB_BYTES, 2097152}, + {CFG_INT_TPM_MAX_RETRY, 5}, + {CFG_BOOL_TPM_CLOCK_SKEW_ENABLED, true}, + {CFG_STR_TPM_BACKOFF, "E,3000,300000,2,1"}, + }}, + {CFG_MAP_COMPAT, + { + {CFG_BOOL_COMPAT_DOTS, true}, // false: v1 backwards-compat: event.SetType("My.Custom.Type") => custom.my_custom_type + {CFG_STR_COMPAT_PREFIX, EVENTRECORD_TYPE_CUSTOM_EVENT} // custom type prefix for Interchange / Geneva / Cosmos flow + }}, + {"sample", + {{"rate", 0}}}}; + + return defaultRuntimeConfig; + } + RuntimeConfig_Default(ILogConfiguration& customConfig) : config(customConfig) { - Variant::merge_map(*customConfig, *defaultRuntimeConfig); + Variant::merge_map(*customConfig, *GetDefaultRuntimeConfig()); }; virtual ~RuntimeConfig_Default() diff --git a/lib/include/public/TransmitProfiles.hpp b/lib/include/public/TransmitProfiles.hpp index 7af3b6c69..c05bfccc7 100644 --- a/lib/include/public/TransmitProfiles.hpp +++ b/lib/include/public/TransmitProfiles.hpp @@ -131,15 +131,6 @@ namespace MAT_NS_BEGIN class TransmitProfiles { protected: - /// - /// A map that contains all transmit profiles. - /// - static std::map profiles; - - /// - /// A string that contains the name of the currently active transmit profile. - /// - static std::string currProfileName; /// /// The size of the currently active transmit profile rule. @@ -161,13 +152,22 @@ namespace MAT_NS_BEGIN /// static bool isTimerUpdated; + /// + /// A map that contains all transmit profiles. + /// + static std::map& GetProfiles() noexcept; + + /// + /// A string that contains the name of the currently active transmit profile. + /// + static std::string& GetCurrProfileName() noexcept; + static void UpdateProfiles(const std::vector& newProfiles) noexcept; static void EnsureDefaultProfiles() noexcept; public: - /// /// The TransmitProfiles default constructor. /// diff --git a/lib/pal/PAL.cpp b/lib/pal/PAL.cpp index 6b6bdbb9d..31001a362 100644 --- a/lib/pal/PAL.cpp +++ b/lib/pal/PAL.cpp @@ -96,9 +96,18 @@ namespace PAL_NS_BEGIN { bool isLoggingInited = false; #ifdef HAVE_MAT_LOGGING - std::recursive_mutex debugLogMutex; - std::string debugLogPath; - std::unique_ptr debugLogStream; + + std::recursive_mutex& GetDebugLogMutex() + { + static std::recursive_mutex debugLogMutex; + return debugLogMutex; + } + + std::shared_ptr& GetDebugLogStream() noexcept + { + static std::shared_ptr debugLogStream; + return debugLogStream; + } bool log_init(bool isTraceEnabled, const std::string& traceFolderPath) { @@ -108,18 +117,19 @@ namespace PAL_NS_BEGIN { } bool result = true; - if (debugLogStream != nullptr) + if (GetDebugLogStream() != nullptr) { return result; } - debugLogMutex.lock(); - debugLogPath = traceFolderPath; + std::lock_guard lockguard(GetDebugLogMutex()); + std::string debugLogPath = traceFolderPath; debugLogPath += "mat-debug-"; debugLogPath += std::to_string(MAT::GetCurrentProcessId()); debugLogPath += ".log"; - debugLogStream = std::unique_ptr(new std::fstream()); + std::shared_ptr& debugLogStream = GetDebugLogStream(); + debugLogStream = std::make_shared(); debugLogStream->open(debugLogPath, std::fstream::out); if (!debugLogStream->is_open()) { @@ -127,19 +137,18 @@ namespace PAL_NS_BEGIN { debugLogStream->open(DEBUG_LOG_NULL); result = false; } - debugLogMutex.unlock(); return result; } void log_done() { - debugLogMutex.lock(); - if (debugLogStream) + std::lock_guard lockguard(GetDebugLogMutex()); + std::shared_ptr& debugLogStream = GetDebugLogStream(); + if (debugLogStream != nullptr) { debugLogStream = nullptr; isLoggingInited = false; } - debugLogMutex.unlock(); } #else bool log_init(bool /*isTraceEnabled*/, const std::string& /*traceFolderPath*/) @@ -258,14 +267,14 @@ namespace PAL_NS_BEGIN { // Make sure all of our debug strings contain EOL buffer[len] = '\n'; // Log to debug log file if enabled - debugLogMutex.lock(); + std::lock_guard lockguard(GetDebugLogMutex()); + std::shared_ptr debugLogStream = GetDebugLogStream(); if (debugLogStream->good()) { (*debugLogStream) << buffer; // flush is not very efficient, but needed to get realtime file updates debugLogStream->flush(); } - debugLogMutex.unlock(); } va_end(ap); #endif diff --git a/lib/tpm/TransmitProfiles.cpp b/lib/tpm/TransmitProfiles.cpp index 3d6748fd2..05058843d 100644 --- a/lib/tpm/TransmitProfiles.cpp +++ b/lib/tpm/TransmitProfiles.cpp @@ -61,25 +61,46 @@ static void initTransmitProfileFields() }; #endif -#define LOCK_PROFILES std::lock_guard lock(profiles_mtx) +#define LOCK_PROFILES std::lock_guard lock(GetProfilesMutex()) namespace MAT_NS_BEGIN { - static std::recursive_mutex profiles_mtx; - map TransmitProfiles::profiles; - string TransmitProfiles::currProfileName = DEFAULT_PROFILE; + std::recursive_mutex& GetProfilesMutex() + { + static std::recursive_mutex profiles_mtx; + return profiles_mtx; + } + size_t TransmitProfiles::currRule = 0; NetworkCost TransmitProfiles::currNetCost = NetworkCost::NetworkCost_Any; PowerSource TransmitProfiles::currPowState = PowerSource::PowerSource_Any; bool TransmitProfiles::isTimerUpdated = true; + /// + /// A map that contains all transmit profiles. + /// + std::map& TransmitProfiles::GetProfiles() noexcept + { + static std::map profiles; + return profiles; + } + + /// + /// A string that contains the name of the currently active transmit profile. + /// + std::string& TransmitProfiles::GetCurrProfileName() noexcept + { + static std::string currProfileName = DEFAULT_PROFILE; + return currProfileName; + } + /// /// Get current transmit profile name /// /// std::string& TransmitProfiles::getProfile() { LOCK_PROFILES; - return currProfileName; + return GetCurrProfileName(); }; /// @@ -98,6 +119,7 @@ namespace MAT_NS_BEGIN { void TransmitProfiles::dump() { #ifdef HAVE_MAT_LOGGING LOCK_PROFILES; + std::map& profiles = GetProfiles(); for (auto &kv : profiles) { auto &profile = kv.second; LOG_TRACE("name=%s", profile.name.c_str()); @@ -118,6 +140,7 @@ namespace MAT_NS_BEGIN { /// Remove custom profiles. This function is only called from parse and does not require the lock. /// void TransmitProfiles::removeCustomProfiles() { + std::map& profiles = GetProfiles(); auto it = profiles.begin(); while (it != profiles.end()) { @@ -133,12 +156,14 @@ namespace MAT_NS_BEGIN { { LOCK_PROFILES; removeCustomProfiles(); + std::map& profiles = GetProfiles(); // Add new profiles for (const auto& profile : newProfiles) { profiles[profile.name] = profile; } // Check if profile is still valid. If no such profile loaded anymore, then switch to default. + std::string& currProfileName = GetCurrProfileName(); auto it = profiles.find(currProfileName); if (it == profiles.end()) { @@ -164,7 +189,7 @@ namespace MAT_NS_BEGIN { void TransmitProfiles::EnsureDefaultProfiles() noexcept { LOCK_PROFILES; - if (profiles.size() == 0) + if (GetProfiles().size() == 0) { LOG_TRACE("Loading default profiles..."); reset(); @@ -437,6 +462,8 @@ namespace MAT_NS_BEGIN { EnsureDefaultProfiles(); LOCK_PROFILES; + std::map& profiles = GetProfiles(); + std::string& currProfileName = GetCurrProfileName(); auto it = profiles.find(profileName); if (it != profiles.end()) { currProfileName = profileName; @@ -460,6 +487,8 @@ namespace MAT_NS_BEGIN { EnsureDefaultProfiles(); LOCK_PROFILES; + std::map& profiles = GetProfiles(); + std::string& currProfileName = GetCurrProfileName(); auto it = profiles.find(currProfileName); // When we can't get timers, we won't set isTimerUpdated to false, // so we will keep calling getTimers from TransmissionPolicyManager. @@ -511,7 +540,8 @@ namespace MAT_NS_BEGIN { void TransmitProfiles::onTimersUpdated() { isTimerUpdated = true; #ifdef HAVE_MAT_LOGGING - auto it = profiles.find(currProfileName); + std::map& profiles = GetProfiles(); + auto it = profiles.find(GetCurrProfileName()); if (it != profiles.end()) { /* Debug routine to print the list of currently selected timers */ TransmitProfileRule &rule = (it->second).rules[currRule]; @@ -535,7 +565,8 @@ namespace MAT_NS_BEGIN { LOCK_PROFILES; currNetCost = netCost; currPowState = powState; - auto it = profiles.find(currProfileName); + std::map& profiles = GetProfiles(); + auto it = profiles.find(GetCurrProfileName()); if (it != profiles.end()) { auto &profile = it->second; // Search for a matching rule. If not found, then return the first (the most restrictive) rule in the list. diff --git a/tests/unittests/TransmitProfilesTests.cpp b/tests/unittests/TransmitProfilesTests.cpp index 58e9d36b5..b3519e453 100644 --- a/tests/unittests/TransmitProfilesTests.cpp +++ b/tests/unittests/TransmitProfilesTests.cpp @@ -13,12 +13,12 @@ class TransmitProfilesTests : public TransmitProfiles, public ::testing::Test protected: virtual void SetUp() override { - TransmitProfiles::profiles.clear(); + TransmitProfiles::GetProfiles().clear(); } virtual void TearDown() override { - TransmitProfiles::profiles.clear(); + TransmitProfiles::GetProfiles().clear(); } }; @@ -58,224 +58,224 @@ class TransmitProfilesTests_EnsureDefaultProfiles : public TransmitProfilesTests TEST_F(TransmitProfilesTests, EnsureDefaultProfiles_NeverCalledBefore_ProfilesSizeIsThree) { - ASSERT_EQ(TransmitProfiles::profiles.size(), size_t{0}); + ASSERT_EQ(TransmitProfiles::GetProfiles().size(), size_t{0}); TransmitProfiles::EnsureDefaultProfiles(); - ASSERT_EQ(TransmitProfiles::profiles.size(), size_t{3}); + ASSERT_EQ(TransmitProfiles::GetProfiles().size(), size_t{3}); } TEST_F(TransmitProfilesTests, EnsureDefaultProfiles_CalledTwice_ProfilesSizeIsThree) { - ASSERT_EQ(TransmitProfiles::profiles.size(), size_t{0}); + ASSERT_EQ(TransmitProfiles::GetProfiles().size(), size_t{0}); TransmitProfiles::EnsureDefaultProfiles(); TransmitProfiles::EnsureDefaultProfiles(); - ASSERT_EQ(TransmitProfiles::profiles.size(), size_t{3}); + ASSERT_EQ(TransmitProfiles::GetProfiles().size(), size_t{3}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeProfileEntryMatchesKey) { - ASSERT_EQ(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].name, defaultRealTimeProfileName); + ASSERT_EQ(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].name, defaultRealTimeProfileName); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeProfileHasElevenRules) { - const auto& profile = TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}]; + const auto& profile = TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}]; ASSERT_EQ(profile.rules.size(), size_t{11}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleZeroIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[0], NetworkCost::NetworkCost_Roaming, {-1, -1, -1}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[0], NetworkCost::NetworkCost_Roaming, {-1, -1, -1}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleOneIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[1], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Unknown, {16, 8, 4}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[1], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Unknown, {16, 8, 4}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleTwoIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[2], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Battery, {16, 8, 4}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[2], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Battery, {16, 8, 4}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleThreeIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[3], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Charging, {12, 6, 3}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[3], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Charging, {12, 6, 3}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleFourIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[4], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Unknown, {8, 4, 2}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[4], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Unknown, {8, 4, 2}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleFiveIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[5], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Battery, {8, 4, 2}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[5], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Battery, {8, 4, 2}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleSixIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[6], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Charging, {4, 2, 1}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[6], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Charging, {4, 2, 1}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleSevenIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[7], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Unknown, {8, 4, 2}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[7], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Unknown, {8, 4, 2}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleEightIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[8], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Battery, {8, 4, 2}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[8], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Battery, {8, 4, 2}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleNineIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[9], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Charging, {4, 2, 1}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[9], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Charging, {4, 2, 1}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_RealTimeRuleTenIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultRealTimeProfileName}].rules[10], {-1, -1, -1}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultRealTimeProfileName}].rules[10], {-1, -1, -1}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeProfileEntryMatchesKey) { - ASSERT_EQ(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].name, defaultNearRealTimeProfileName); + ASSERT_EQ(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].name, defaultNearRealTimeProfileName); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeProfileHasElevenRules) { - const auto& profile = TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}]; + const auto& profile = TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}]; ASSERT_EQ(profile.rules.size(), size_t{11}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleZeroIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[0], NetworkCost::NetworkCost_Roaming, {-1, -1, -1}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[0], NetworkCost::NetworkCost_Roaming, {-1, -1, -1}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleOneIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[1], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Unknown, {-1, 24, 12}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[1], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Unknown, {-1, 24, 12}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleTwoIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[2], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Battery, {-1, 24, 12}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[2], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Battery, {-1, 24, 12}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleThreeIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[3], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Charging, {-1, 18, 9}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[3], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Charging, {-1, 18, 9}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleFourIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[4], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Unknown, {24, 12, 6}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[4], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Unknown, {24, 12, 6}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleFiveIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[5], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Battery, {24, 12, 6}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[5], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Battery, {24, 12, 6}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleSixIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[6], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Charging, {12, 6, 3}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[6], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Charging, {12, 6, 3}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleSevenIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[7], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Unknown, {24, 12, 6}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[7], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Unknown, {24, 12, 6}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleEightIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[8], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Battery, {24, 12, 6}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[8], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Battery, {24, 12, 6}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleNineIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[9], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Charging, {12, 6, 3}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[9], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Charging, {12, 6, 3}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_NearRealTimeRuleTenIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultNearRealTimeProfileName}].rules[10], {-1, -1, -1}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultNearRealTimeProfileName}].rules[10], {-1, -1, -1}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortProfileEntryMatchesKey) { - ASSERT_EQ(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].name, defaultBestEffortProfileName); + ASSERT_EQ(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].name, defaultBestEffortProfileName); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortProfileHasElevenRules) { - const auto& profile = TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}]; + const auto& profile = TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}]; ASSERT_EQ(profile.rules.size(), size_t{11}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleZeroIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[0], NetworkCost::NetworkCost_Roaming, {-1, -1, -1}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[0], NetworkCost::NetworkCost_Roaming, {-1, -1, -1}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleOneIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[1], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Unknown, {-1, 72, 36}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[1], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Unknown, {-1, 72, 36}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleTwoIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[2], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Battery, {-1, 72, 36}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[2], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Battery, {-1, 72, 36}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleThreeIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[3], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Charging, {-1, 54, 27}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[3], NetworkCost::NetworkCost_Metered, PowerSource::PowerSource_Charging, {-1, 54, 27}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleFourIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[4], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Unknown, {72, 36, 18}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[4], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Unknown, {72, 36, 18}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleFiveIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[5], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Battery, {72, 36, 18}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[5], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Battery, {72, 36, 18}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleSixIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[6], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Charging, {36, 18, 9}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[6], NetworkCost::NetworkCost_Unmetered, PowerSource::PowerSource_Charging, {36, 18, 9}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleSevenIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[7], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Unknown, {72, 36, 18}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[7], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Unknown, {72, 36, 18}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleEightIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[8], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Battery, {72, 36, 18}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[8], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Battery, {72, 36, 18}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleNineIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[9], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Charging, {36, 18, 9}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[9], NetworkCost::NetworkCost_Unknown, PowerSource::PowerSource_Charging, {36, 18, 9}); } TEST_F(TransmitProfilesTests_EnsureDefaultProfiles, Pinning_BestEffortRuleTenIsCorrect) { - ValidateTransmitProfileRule(TransmitProfiles::profiles[std::string{defaultBestEffortProfileName}].rules[10], {-1, -1, -1}); + ValidateTransmitProfileRule(TransmitProfiles::GetProfiles()[std::string{defaultBestEffortProfileName}].rules[10], {-1, -1, -1}); } TEST_F(TransmitProfilesTests, UpdateProfiles_ProfileAlreadyAddedAndNotInNewProfiles_PreviousCustomProfilesRemoved) { const std::string previousRuleName = "previousRule"; TransmitProfileRules previousRule{previousRuleName, {}}; - TransmitProfiles::profiles[previousRuleName] = previousRule; + TransmitProfiles::GetProfiles()[previousRuleName] = previousRule; TransmitProfiles::UpdateProfiles(std::vector{}); - ASSERT_TRUE(TransmitProfiles::profiles.find(previousRuleName) == TransmitProfiles::profiles.end()); + ASSERT_TRUE(TransmitProfiles::GetProfiles().find(previousRuleName) == TransmitProfiles::GetProfiles().end()); } TEST_F(TransmitProfilesTests, UpdateProfiles_NewRule_NewRuleAddedToProfiles) @@ -283,32 +283,32 @@ TEST_F(TransmitProfilesTests, UpdateProfiles_NewRule_NewRuleAddedToProfiles) const std::string newRuleName = "newRule"; TransmitProfileRules newRule{newRuleName, {}}; TransmitProfiles::UpdateProfiles(std::vector{newRule}); - ASSERT_TRUE(TransmitProfiles::profiles.find(newRuleName) != TransmitProfiles::profiles.end()); + ASSERT_TRUE(TransmitProfiles::GetProfiles().find(newRuleName) != TransmitProfiles::GetProfiles().end()); } TEST_F(TransmitProfilesTests, UpdateProfiles_OldCurrentProfileDoesntExistInNewRules_SetCurrentProfileToDefault) { - TransmitProfiles::currProfileName = std::string{"newRule"}; + TransmitProfiles::GetCurrProfileName() = std::string{"newRule"}; TransmitProfiles::UpdateProfiles(std::vector{}); - ASSERT_EQ(TransmitProfiles::currProfileName, std::string{"REAL_TIME"}); + ASSERT_EQ(TransmitProfiles::GetCurrProfileName(), std::string{"REAL_TIME"}); } TEST_F(TransmitProfilesTests, UpdateProfiles_OldCurrentProfileExistsInNewRules_CurrentProfileNotChanged) { const std::string newRuleName = "newRule"; - TransmitProfiles::currProfileName = newRuleName; + TransmitProfiles::GetCurrProfileName() = newRuleName; TransmitProfileRule rule; rule.timers = {1, 2, 3}; TransmitProfileRules newRule{newRuleName, {rule}}; TransmitProfiles::UpdateProfiles(std::vector{newRule}); - ASSERT_EQ(TransmitProfiles::currProfileName, newRuleName); + ASSERT_EQ(TransmitProfiles::GetCurrProfileName(), newRuleName); } TEST_F(TransmitProfilesTests, load_VectorIsLargerThanMaxTransmitProfiles_ReturnsFalseAndSizeThree) { std::vector newProfiles{MAX_TRANSMIT_PROFILES + 1}; ASSERT_FALSE(TransmitProfiles::load(newProfiles)); - ASSERT_EQ(TransmitProfiles::profiles.size(), size_t { 3 }); + ASSERT_EQ(TransmitProfiles::GetProfiles().size(), size_t { 3 }); } TEST_F(TransmitProfilesTests, load_OneProfileTooManyRules_ReturnsFalseAndSizeThree) @@ -317,7 +317,7 @@ TEST_F(TransmitProfilesTests, load_OneProfileTooManyRules_ReturnsFalseAndSizeThr profile.rules = std::vector{MAX_TRANSMIT_RULES + 1}; std::vector newProfiles{profile}; ASSERT_FALSE(TransmitProfiles::load(newProfiles)); - ASSERT_EQ(TransmitProfiles::profiles.size(), size_t { 3 }); + ASSERT_EQ(TransmitProfiles::GetProfiles().size(), size_t { 3 }); } TEST_F(TransmitProfilesTests, load_OneProfileNoRules_ReturnsFalseAndSizeThree) @@ -325,7 +325,7 @@ TEST_F(TransmitProfilesTests, load_OneProfileNoRules_ReturnsFalseAndSizeThree) TransmitProfileRules profile{"testProfile", { }}; std::vector newProfiles{profile}; ASSERT_FALSE(TransmitProfiles::load(newProfiles)); - ASSERT_EQ(TransmitProfiles::profiles.size(), size_t { 3 }); + ASSERT_EQ(TransmitProfiles::GetProfiles().size(), size_t { 3 }); } TEST_F(TransmitProfilesTests, load_OneProfileOneRuleNoTimers_ReturnsFalseAndSizeThree) @@ -334,7 +334,7 @@ TEST_F(TransmitProfilesTests, load_OneProfileOneRuleNoTimers_ReturnsFalseAndSize TransmitProfileRules profile{"testProfile", { rule }}; std::vector newProfiles{profile}; ASSERT_FALSE(TransmitProfiles::load(newProfiles)); - ASSERT_EQ(TransmitProfiles::profiles.size(), size_t { 3 }); + ASSERT_EQ(TransmitProfiles::GetProfiles().size(), size_t { 3 }); } TEST_F(TransmitProfilesTests, load_OneRule_ReturnsTrueAndSizeFour) @@ -344,7 +344,7 @@ TEST_F(TransmitProfilesTests, load_OneRule_ReturnsTrueAndSizeFour) TransmitProfileRules profile{"testProfile", { rule }}; std::vector newProfiles{profile}; ASSERT_TRUE(TransmitProfiles::load(newProfiles)); - ASSERT_EQ(TransmitProfiles::profiles.size(), size_t { 4 }); + ASSERT_EQ(TransmitProfiles::GetProfiles().size(), size_t { 4 }); } #ifdef HAVE_MAT_JSONHPP