Loading system/build/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,9 @@ fluoride_defaults { sanitize: { misc_undefined: ["bounds"], }, static_libs: [ "libbluetooth_gd", ], } // Enables code coverage for a set of source files. Must be combined with Loading system/gd/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -328,6 +328,7 @@ cc_test { ], host_supported: true, srcs: [ ":BluetoothCommonSources", ":BluetoothPacketSources", ":BluetoothPacketParserTestPacketTestSources", ], Loading system/gd/common/init_flags.cc +72 −29 Original line number Diff line number Diff line Loading @@ -20,50 +20,67 @@ #include <string> #include "common/strings.h" #include "os/log.h" namespace bluetooth { namespace common { const std::string kGdAdvertisingFlag = "INIT_gd_advertising"; bool InitFlags::gd_core_enabled = false; bool InitFlags::gd_advertising_enabled = false; const std::string kGdSecurityFlag = "INIT_gd_security"; bool InitFlags::gd_security_enabled = false; const std::string kGdAclFlag = "INIT_gd_acl"; bool InitFlags::gd_acl_enabled = false; const std::string kGdHciFlag = "INIT_gd_hci"; bool InitFlags::gd_hci_enabled = false; const std::string kGdControllerFlag = "INIT_gd_controller"; bool InitFlags::gd_controller_enabled = false; const std::string kGdCoreFlag = "INIT_gd_core"; bool InitFlags::gd_core_enabled = false; const std::string kGattRobustCachingFlag = "INIT_gatt_robust_caching"; bool InitFlags::gatt_robust_caching_enabled = false; bool InitFlags::logging_debug_enabled_for_all = false; std::unordered_map<std::string, bool> InitFlags::logging_debug_explicit_tag_settings = {}; bool ParseBoolFlag(const std::vector<std::string>& flag_pair, const std::string& flag, bool* variable) { if (flag != flag_pair[0]) { return false; } auto value = BoolFromString(flag_pair[1]); if (!value) { return false; } *variable = *value; return true; } void InitFlags::Load(const char** flags) { SetAll(false); while (flags != nullptr && *flags != nullptr) { if (kGdCoreFlag == *flags) { gd_core_enabled = true; } else if (kGdAdvertisingFlag == *flags) { // TODO enable when module ready // gd_advertising_enabled = true; } else if (kGdSecurityFlag == *flags) { gd_security_enabled = true; } else if (kGdAclFlag == *flags) { gd_acl_enabled = true; } else if (kGdHciFlag == *flags) { gd_hci_enabled = true; } else if (kGdControllerFlag == *flags) { gd_controller_enabled = true; } else if (kGattRobustCachingFlag == *flags) { gatt_robust_caching_enabled = true; std::string flag_element = *flags; auto flag_pair = StringSplit(flag_element, "=", 2); if (flag_pair.size() != 2) { LOG_ERROR("Bad flag %s, must be in <FLAG>=<VALUE> format", flag_element.c_str()); flags++; continue; } ParseBoolFlag(flag_pair, "INIT_gd_core", &gd_core_enabled); ParseBoolFlag(flag_pair, "INIT_gd_advertising", &gd_advertising_enabled); ParseBoolFlag(flag_pair, "INIT_gd_security", &gd_security_enabled); ParseBoolFlag(flag_pair, "INIT_gd_acl", &gd_acl_enabled); ParseBoolFlag(flag_pair, "INIT_gd_hci", &gd_hci_enabled); ParseBoolFlag(flag_pair, "INIT_gd_controller", &gd_controller_enabled); ParseBoolFlag(flag_pair, "INIT_gatt_robust_caching", &gatt_robust_caching_enabled); ParseBoolFlag(flag_pair, "INIT_logging_debug_enabled_for_all", &logging_debug_enabled_for_all); if ("INIT_logging_debug_enabled_for_tags" == flag_pair[0]) { auto tags = StringSplit(flag_pair[1], ","); for (const auto& tag : tags) { auto setting = logging_debug_explicit_tag_settings.find(tag); if (setting == logging_debug_explicit_tag_settings.end()) { logging_debug_explicit_tag_settings.insert_or_assign(tag, true); } } } if ("INIT_logging_debug_disabled_for_tags" == flag_pair[0]) { auto tags = StringSplit(flag_pair[1], ","); for (const auto& tag : tags) { logging_debug_explicit_tag_settings.insert_or_assign(tag, false); } } flags++; } Loading @@ -80,6 +97,30 @@ void InitFlags::Load(const char** flags) { if (gd_controller_enabled && !gd_hci_enabled) { gd_hci_enabled = true; } std::vector<std::string> logging_debug_enabled_tags; std::vector<std::string> logging_debug_disabled_tags; for (const auto& tag_setting : logging_debug_explicit_tag_settings) { if (tag_setting.second) { logging_debug_enabled_tags.emplace_back(tag_setting.first); } else { logging_debug_disabled_tags.emplace_back(tag_setting.first); } } LOG_INFO( "Flags loaded: gd_advertising_enabled=%s, gd_security_enabled=%s, gd_acl_enabled=%s, gd_hci_enabled=%s, " "gd_controller_enabled=%s, gd_core_enabled=%s, logging_debug_enabled_for_all=%s, " "logging_debug_enabled_tags=%s, logging_debug_disabled_tags=%s", ToString(gd_advertising_enabled).c_str(), ToString(gd_security_enabled).c_str(), ToString(gd_acl_enabled).c_str(), ToString(gd_hci_enabled).c_str(), ToString(gd_controller_enabled).c_str(), ToString(gd_core_enabled).c_str(), ToString(logging_debug_enabled_for_all).c_str(), StringJoin(logging_debug_enabled_tags, ",").c_str(), StringJoin(logging_debug_disabled_tags, ",").c_str()); } void InitFlags::SetAll(bool value) { Loading @@ -90,6 +131,8 @@ void InitFlags::SetAll(bool value) { gd_controller_enabled = value; gd_hci_enabled = value; gatt_robust_caching_enabled = value; logging_debug_enabled_for_all = value; logging_debug_explicit_tag_settings.clear(); } void InitFlags::SetAllForTesting() { Loading system/gd/common/init_flags.h +18 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ #pragma once #include <string> #include <unordered_map> namespace bluetooth { namespace common { Loading Loading @@ -51,6 +54,18 @@ class InitFlags final { return gatt_robust_caching_enabled; } inline static bool IsDebugLoggingEnabledForTag(const std::string& tag) { auto tag_setting = logging_debug_explicit_tag_settings.find(tag); if (tag_setting != logging_debug_explicit_tag_settings.end()) { return tag_setting->second; } return logging_debug_enabled_for_all; } inline static bool IsDebugLoggingEnabledForAll() { return logging_debug_enabled_for_all; } static void SetAllForTesting(); private: Loading @@ -62,6 +77,9 @@ class InitFlags final { static bool gd_controller_enabled; static bool gd_core_enabled; static bool gatt_robust_caching_enabled; static bool logging_debug_enabled_for_all; // save both log allow list and block list in the map to save hashing time static std::unordered_map<std::string, bool> logging_debug_explicit_tag_settings; }; } // namespace common Loading system/gd/common/init_flags_test.cc +58 −17 Original line number Diff line number Diff line Loading @@ -24,47 +24,88 @@ using bluetooth::common::InitFlags; TEST(InitFlagsTest, test_load_nullptr) { InitFlags::Load(nullptr); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); } TEST(InitFlagsTest, test_load_empty) { const char* input[] = {nullptr}; InitFlags::Load(input); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); } TEST(InitFlagsTest, test_load_garbage) { const char* input[] = {"some random non-existent flag", nullptr}; InitFlags::Load(input); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); } TEST(InitFlagsTest, test_load_core) { const char* input[] = {"INIT_gd_core", nullptr}; const char* input[] = {"INIT_gd_core=true", nullptr}; InitFlags::Load(input); ASSERT_EQ(true, InitFlags::GdCoreEnabled()); ASSERT_EQ(true, InitFlags::GdControllerEnabled()); ASSERT_EQ(true, InitFlags::GdHciEnabled()); ASSERT_TRUE(InitFlags::GdCoreEnabled()); ASSERT_TRUE(InitFlags::GdControllerEnabled()); ASSERT_TRUE(InitFlags::GdHciEnabled()); } TEST(InitFlagsTest, test_load_controller) { const char* input[] = {"INIT_gd_controller", nullptr}; const char* input[] = {"INIT_gd_controller=true", nullptr}; InitFlags::Load(input); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_EQ(true, InitFlags::GdControllerEnabled()); ASSERT_EQ(true, InitFlags::GdHciEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); ASSERT_TRUE(InitFlags::GdControllerEnabled()); ASSERT_TRUE(InitFlags::GdHciEnabled()); } TEST(InitFlagsTest, test_load_hci) { const char* input[] = {"INIT_gd_hci", nullptr}; const char* input[] = {"INIT_gd_hci=true", nullptr}; InitFlags::Load(input); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_EQ(false, InitFlags::GdControllerEnabled()); ASSERT_EQ(true, InitFlags::GdHciEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); ASSERT_FALSE(InitFlags::GdControllerEnabled()); ASSERT_TRUE(InitFlags::GdHciEnabled()); } TEST(InitFlagsTest, test_load_gatt_robust_caching) { const char* input[] = {"INIT_gatt_robust_caching", nullptr}; const char* input[] = {"INIT_gatt_robust_caching=true", nullptr}; InitFlags::Load(input); ASSERT_EQ(true, InitFlags::GattRobustCachingEnabled()); ASSERT_TRUE(InitFlags::GattRobustCachingEnabled()); } TEST(InitFlagsTest, test_enable_debug_logging_for_all) { const char* input[] = {"INIT_logging_debug_enabled_for_all=true", nullptr}; InitFlags::Load(input); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("foo")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("bar")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForAll()); } TEST(InitFlagsTest, test_enable_debug_logging_for_tags) { const char* input[] = {"INIT_logging_debug_enabled_for_tags=foo,bar,hello", nullptr}; InitFlags::Load(input); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("foo")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("bar")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("hello")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("Foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForAll()); } TEST(InitFlagsTest, test_disable_debug_logging_for_tags) { const char* input[] = {"INIT_logging_debug_disabled_for_tags=foo,bar,hello", nullptr}; InitFlags::Load(input); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("bar")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("hello")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("Foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForAll()); } TEST(InitFlagsTest, test_debug_logging_multiple_flags) { const char* input[] = {"INIT_logging_debug_enabled_for_tags=foo,hello", "INIT_logging_debug_disabled_for_tags=foo,bar", "INIT_logging_debug_enabled_for_all=false", nullptr}; InitFlags::Load(input); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("bar")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("hello")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("Foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForAll()); } Loading
system/build/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,9 @@ fluoride_defaults { sanitize: { misc_undefined: ["bounds"], }, static_libs: [ "libbluetooth_gd", ], } // Enables code coverage for a set of source files. Must be combined with Loading
system/gd/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -328,6 +328,7 @@ cc_test { ], host_supported: true, srcs: [ ":BluetoothCommonSources", ":BluetoothPacketSources", ":BluetoothPacketParserTestPacketTestSources", ], Loading
system/gd/common/init_flags.cc +72 −29 Original line number Diff line number Diff line Loading @@ -20,50 +20,67 @@ #include <string> #include "common/strings.h" #include "os/log.h" namespace bluetooth { namespace common { const std::string kGdAdvertisingFlag = "INIT_gd_advertising"; bool InitFlags::gd_core_enabled = false; bool InitFlags::gd_advertising_enabled = false; const std::string kGdSecurityFlag = "INIT_gd_security"; bool InitFlags::gd_security_enabled = false; const std::string kGdAclFlag = "INIT_gd_acl"; bool InitFlags::gd_acl_enabled = false; const std::string kGdHciFlag = "INIT_gd_hci"; bool InitFlags::gd_hci_enabled = false; const std::string kGdControllerFlag = "INIT_gd_controller"; bool InitFlags::gd_controller_enabled = false; const std::string kGdCoreFlag = "INIT_gd_core"; bool InitFlags::gd_core_enabled = false; const std::string kGattRobustCachingFlag = "INIT_gatt_robust_caching"; bool InitFlags::gatt_robust_caching_enabled = false; bool InitFlags::logging_debug_enabled_for_all = false; std::unordered_map<std::string, bool> InitFlags::logging_debug_explicit_tag_settings = {}; bool ParseBoolFlag(const std::vector<std::string>& flag_pair, const std::string& flag, bool* variable) { if (flag != flag_pair[0]) { return false; } auto value = BoolFromString(flag_pair[1]); if (!value) { return false; } *variable = *value; return true; } void InitFlags::Load(const char** flags) { SetAll(false); while (flags != nullptr && *flags != nullptr) { if (kGdCoreFlag == *flags) { gd_core_enabled = true; } else if (kGdAdvertisingFlag == *flags) { // TODO enable when module ready // gd_advertising_enabled = true; } else if (kGdSecurityFlag == *flags) { gd_security_enabled = true; } else if (kGdAclFlag == *flags) { gd_acl_enabled = true; } else if (kGdHciFlag == *flags) { gd_hci_enabled = true; } else if (kGdControllerFlag == *flags) { gd_controller_enabled = true; } else if (kGattRobustCachingFlag == *flags) { gatt_robust_caching_enabled = true; std::string flag_element = *flags; auto flag_pair = StringSplit(flag_element, "=", 2); if (flag_pair.size() != 2) { LOG_ERROR("Bad flag %s, must be in <FLAG>=<VALUE> format", flag_element.c_str()); flags++; continue; } ParseBoolFlag(flag_pair, "INIT_gd_core", &gd_core_enabled); ParseBoolFlag(flag_pair, "INIT_gd_advertising", &gd_advertising_enabled); ParseBoolFlag(flag_pair, "INIT_gd_security", &gd_security_enabled); ParseBoolFlag(flag_pair, "INIT_gd_acl", &gd_acl_enabled); ParseBoolFlag(flag_pair, "INIT_gd_hci", &gd_hci_enabled); ParseBoolFlag(flag_pair, "INIT_gd_controller", &gd_controller_enabled); ParseBoolFlag(flag_pair, "INIT_gatt_robust_caching", &gatt_robust_caching_enabled); ParseBoolFlag(flag_pair, "INIT_logging_debug_enabled_for_all", &logging_debug_enabled_for_all); if ("INIT_logging_debug_enabled_for_tags" == flag_pair[0]) { auto tags = StringSplit(flag_pair[1], ","); for (const auto& tag : tags) { auto setting = logging_debug_explicit_tag_settings.find(tag); if (setting == logging_debug_explicit_tag_settings.end()) { logging_debug_explicit_tag_settings.insert_or_assign(tag, true); } } } if ("INIT_logging_debug_disabled_for_tags" == flag_pair[0]) { auto tags = StringSplit(flag_pair[1], ","); for (const auto& tag : tags) { logging_debug_explicit_tag_settings.insert_or_assign(tag, false); } } flags++; } Loading @@ -80,6 +97,30 @@ void InitFlags::Load(const char** flags) { if (gd_controller_enabled && !gd_hci_enabled) { gd_hci_enabled = true; } std::vector<std::string> logging_debug_enabled_tags; std::vector<std::string> logging_debug_disabled_tags; for (const auto& tag_setting : logging_debug_explicit_tag_settings) { if (tag_setting.second) { logging_debug_enabled_tags.emplace_back(tag_setting.first); } else { logging_debug_disabled_tags.emplace_back(tag_setting.first); } } LOG_INFO( "Flags loaded: gd_advertising_enabled=%s, gd_security_enabled=%s, gd_acl_enabled=%s, gd_hci_enabled=%s, " "gd_controller_enabled=%s, gd_core_enabled=%s, logging_debug_enabled_for_all=%s, " "logging_debug_enabled_tags=%s, logging_debug_disabled_tags=%s", ToString(gd_advertising_enabled).c_str(), ToString(gd_security_enabled).c_str(), ToString(gd_acl_enabled).c_str(), ToString(gd_hci_enabled).c_str(), ToString(gd_controller_enabled).c_str(), ToString(gd_core_enabled).c_str(), ToString(logging_debug_enabled_for_all).c_str(), StringJoin(logging_debug_enabled_tags, ",").c_str(), StringJoin(logging_debug_disabled_tags, ",").c_str()); } void InitFlags::SetAll(bool value) { Loading @@ -90,6 +131,8 @@ void InitFlags::SetAll(bool value) { gd_controller_enabled = value; gd_hci_enabled = value; gatt_robust_caching_enabled = value; logging_debug_enabled_for_all = value; logging_debug_explicit_tag_settings.clear(); } void InitFlags::SetAllForTesting() { Loading
system/gd/common/init_flags.h +18 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ #pragma once #include <string> #include <unordered_map> namespace bluetooth { namespace common { Loading Loading @@ -51,6 +54,18 @@ class InitFlags final { return gatt_robust_caching_enabled; } inline static bool IsDebugLoggingEnabledForTag(const std::string& tag) { auto tag_setting = logging_debug_explicit_tag_settings.find(tag); if (tag_setting != logging_debug_explicit_tag_settings.end()) { return tag_setting->second; } return logging_debug_enabled_for_all; } inline static bool IsDebugLoggingEnabledForAll() { return logging_debug_enabled_for_all; } static void SetAllForTesting(); private: Loading @@ -62,6 +77,9 @@ class InitFlags final { static bool gd_controller_enabled; static bool gd_core_enabled; static bool gatt_robust_caching_enabled; static bool logging_debug_enabled_for_all; // save both log allow list and block list in the map to save hashing time static std::unordered_map<std::string, bool> logging_debug_explicit_tag_settings; }; } // namespace common Loading
system/gd/common/init_flags_test.cc +58 −17 Original line number Diff line number Diff line Loading @@ -24,47 +24,88 @@ using bluetooth::common::InitFlags; TEST(InitFlagsTest, test_load_nullptr) { InitFlags::Load(nullptr); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); } TEST(InitFlagsTest, test_load_empty) { const char* input[] = {nullptr}; InitFlags::Load(input); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); } TEST(InitFlagsTest, test_load_garbage) { const char* input[] = {"some random non-existent flag", nullptr}; InitFlags::Load(input); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); } TEST(InitFlagsTest, test_load_core) { const char* input[] = {"INIT_gd_core", nullptr}; const char* input[] = {"INIT_gd_core=true", nullptr}; InitFlags::Load(input); ASSERT_EQ(true, InitFlags::GdCoreEnabled()); ASSERT_EQ(true, InitFlags::GdControllerEnabled()); ASSERT_EQ(true, InitFlags::GdHciEnabled()); ASSERT_TRUE(InitFlags::GdCoreEnabled()); ASSERT_TRUE(InitFlags::GdControllerEnabled()); ASSERT_TRUE(InitFlags::GdHciEnabled()); } TEST(InitFlagsTest, test_load_controller) { const char* input[] = {"INIT_gd_controller", nullptr}; const char* input[] = {"INIT_gd_controller=true", nullptr}; InitFlags::Load(input); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_EQ(true, InitFlags::GdControllerEnabled()); ASSERT_EQ(true, InitFlags::GdHciEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); ASSERT_TRUE(InitFlags::GdControllerEnabled()); ASSERT_TRUE(InitFlags::GdHciEnabled()); } TEST(InitFlagsTest, test_load_hci) { const char* input[] = {"INIT_gd_hci", nullptr}; const char* input[] = {"INIT_gd_hci=true", nullptr}; InitFlags::Load(input); ASSERT_EQ(false, InitFlags::GdCoreEnabled()); ASSERT_EQ(false, InitFlags::GdControllerEnabled()); ASSERT_EQ(true, InitFlags::GdHciEnabled()); ASSERT_FALSE(InitFlags::GdCoreEnabled()); ASSERT_FALSE(InitFlags::GdControllerEnabled()); ASSERT_TRUE(InitFlags::GdHciEnabled()); } TEST(InitFlagsTest, test_load_gatt_robust_caching) { const char* input[] = {"INIT_gatt_robust_caching", nullptr}; const char* input[] = {"INIT_gatt_robust_caching=true", nullptr}; InitFlags::Load(input); ASSERT_EQ(true, InitFlags::GattRobustCachingEnabled()); ASSERT_TRUE(InitFlags::GattRobustCachingEnabled()); } TEST(InitFlagsTest, test_enable_debug_logging_for_all) { const char* input[] = {"INIT_logging_debug_enabled_for_all=true", nullptr}; InitFlags::Load(input); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("foo")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("bar")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForAll()); } TEST(InitFlagsTest, test_enable_debug_logging_for_tags) { const char* input[] = {"INIT_logging_debug_enabled_for_tags=foo,bar,hello", nullptr}; InitFlags::Load(input); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("foo")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("bar")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("hello")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("Foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForAll()); } TEST(InitFlagsTest, test_disable_debug_logging_for_tags) { const char* input[] = {"INIT_logging_debug_disabled_for_tags=foo,bar,hello", nullptr}; InitFlags::Load(input); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("bar")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("hello")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("Foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForAll()); } TEST(InitFlagsTest, test_debug_logging_multiple_flags) { const char* input[] = {"INIT_logging_debug_enabled_for_tags=foo,hello", "INIT_logging_debug_disabled_for_tags=foo,bar", "INIT_logging_debug_enabled_for_all=false", nullptr}; InitFlags::Load(input); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("bar")); ASSERT_TRUE(InitFlags::IsDebugLoggingEnabledForTag("hello")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("Foo")); ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForAll()); }