// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_config.h" #include "base/trace_event/trace_config_memory_test_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { namespace trace_event { namespace { const char kDefaultTraceConfigString[] = "{" "\"enable_argument_filter\":false," "\"enable_sampling\":false," "\"enable_systrace\":false," "\"excluded_categories\":[\"*Debug\",\"*Test\"]," "\"record_mode\":\"record-until-full\"" "}"; } // namespace TEST(TraceConfigTest, TraceConfigFromValidLegacyFormat) { // From trace options strings TraceConfig config("", "record-until-full"); EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("record-until-full", config.ToTraceOptionsString().c_str()); config = TraceConfig("", "record-continuously"); EXPECT_EQ(RECORD_CONTINUOUSLY, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("record-continuously", config.ToTraceOptionsString().c_str()); config = TraceConfig("", "trace-to-console"); EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("trace-to-console", config.ToTraceOptionsString().c_str()); config = TraceConfig("", "record-as-much-as-possible"); EXPECT_EQ(RECORD_AS_MUCH_AS_POSSIBLE, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("record-as-much-as-possible", config.ToTraceOptionsString().c_str()); config = TraceConfig("", "record-until-full, enable-sampling"); EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode()); EXPECT_TRUE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("record-until-full,enable-sampling", config.ToTraceOptionsString().c_str()); config = TraceConfig("", "enable-systrace, record-continuously"); EXPECT_EQ(RECORD_CONTINUOUSLY, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_TRUE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("record-continuously,enable-systrace", config.ToTraceOptionsString().c_str()); config = TraceConfig("", "enable-argument-filter,record-as-much-as-possible"); EXPECT_EQ(RECORD_AS_MUCH_AS_POSSIBLE, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_TRUE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("record-as-much-as-possible,enable-argument-filter", config.ToTraceOptionsString().c_str()); config = TraceConfig( "", "enable-systrace,trace-to-console,enable-sampling,enable-argument-filter"); EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode()); EXPECT_TRUE(config.IsSamplingEnabled()); EXPECT_TRUE(config.IsSystraceEnabled()); EXPECT_TRUE(config.IsArgumentFilterEnabled()); EXPECT_STREQ( "trace-to-console,enable-sampling,enable-systrace,enable-argument-filter", config.ToTraceOptionsString().c_str()); config = TraceConfig( "", "record-continuously, record-until-full, trace-to-console"); EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("trace-to-console", config.ToTraceOptionsString().c_str()); // From TraceRecordMode config = TraceConfig("", RECORD_UNTIL_FULL); EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("record-until-full", config.ToTraceOptionsString().c_str()); config = TraceConfig("", RECORD_CONTINUOUSLY); EXPECT_EQ(RECORD_CONTINUOUSLY, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("record-continuously", config.ToTraceOptionsString().c_str()); config = TraceConfig("", ECHO_TO_CONSOLE); EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("trace-to-console", config.ToTraceOptionsString().c_str()); config = TraceConfig("", RECORD_AS_MUCH_AS_POSSIBLE); EXPECT_EQ(RECORD_AS_MUCH_AS_POSSIBLE, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("record-as-much-as-possible", config.ToTraceOptionsString().c_str()); // From category filter strings config = TraceConfig("-*Debug,-*Test", ""); EXPECT_STREQ("-*Debug,-*Test", config.ToCategoryFilterString().c_str()); config = TraceConfig("included,-excluded,inc_pattern*,-exc_pattern*", ""); EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*", config.ToCategoryFilterString().c_str()); config = TraceConfig("only_inc_cat", ""); EXPECT_STREQ("only_inc_cat", config.ToCategoryFilterString().c_str()); config = TraceConfig("-only_exc_cat", ""); EXPECT_STREQ("-only_exc_cat", config.ToCategoryFilterString().c_str()); config = TraceConfig("disabled-by-default-cc,-excluded", ""); EXPECT_STREQ("disabled-by-default-cc,-excluded", config.ToCategoryFilterString().c_str()); config = TraceConfig("disabled-by-default-cc,included", ""); EXPECT_STREQ("included,disabled-by-default-cc", config.ToCategoryFilterString().c_str()); config = TraceConfig("DELAY(test.Delay1;16),included", ""); EXPECT_STREQ("included,DELAY(test.Delay1;16)", config.ToCategoryFilterString().c_str()); // From both trace options and category filter strings config = TraceConfig("", ""); EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("", config.ToCategoryFilterString().c_str()); EXPECT_STREQ("record-until-full", config.ToTraceOptionsString().c_str()); config = TraceConfig("included,-excluded,inc_pattern*,-exc_pattern*", "enable-systrace, trace-to-console, enable-sampling"); EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode()); EXPECT_TRUE(config.IsSamplingEnabled()); EXPECT_TRUE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*", config.ToCategoryFilterString().c_str()); EXPECT_STREQ("trace-to-console,enable-sampling,enable-systrace", config.ToTraceOptionsString().c_str()); // From both trace options and category filter strings with spaces. config = TraceConfig(" included , -excluded, inc_pattern*, ,-exc_pattern* ", "enable-systrace, ,trace-to-console, enable-sampling "); EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode()); EXPECT_TRUE(config.IsSamplingEnabled()); EXPECT_TRUE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*", config.ToCategoryFilterString().c_str()); EXPECT_STREQ("trace-to-console,enable-sampling,enable-systrace", config.ToTraceOptionsString().c_str()); // From category filter string and TraceRecordMode config = TraceConfig("included,-excluded,inc_pattern*,-exc_pattern*", RECORD_CONTINUOUSLY); EXPECT_EQ(RECORD_CONTINUOUSLY, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*", config.ToCategoryFilterString().c_str()); EXPECT_STREQ("record-continuously", config.ToTraceOptionsString().c_str()); } TEST(TraceConfigTest, TraceConfigFromInvalidLegacyStrings) { TraceConfig config("", "foo-bar-baz"); EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_FALSE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("", config.ToCategoryFilterString().c_str()); EXPECT_STREQ("record-until-full", config.ToTraceOptionsString().c_str()); config = TraceConfig("arbitrary-category", "foo-bar-baz, enable-systrace"); EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode()); EXPECT_FALSE(config.IsSamplingEnabled()); EXPECT_TRUE(config.IsSystraceEnabled()); EXPECT_FALSE(config.IsArgumentFilterEnabled()); EXPECT_STREQ("arbitrary-category", config.ToCategoryFilterString().c_str()); EXPECT_STREQ("record-until-full,enable-systrace", config.ToTraceOptionsString().c_str()); const char* const configs[] = { "", "DELAY(", "DELAY(;", "DELAY(;)", "DELAY(test.Delay)", "DELAY(test.Delay;)" }; for (size_t i = 0; i < arraysize(configs); i++) { TraceConfig tc(configs[i], ""); EXPECT_EQ(0u, tc.GetSyntheticDelayValues().size()); } } TEST(TraceConfigTest, ConstructDefaultTraceConfig) { // Make sure that upon an empty string, we fall back to the default config. TraceConfig tc; EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str()); EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode()); EXPECT_FALSE(tc.IsSamplingEnabled()); EXPECT_FALSE(tc.IsSystraceEnabled()); EXPECT_FALSE(tc.IsArgumentFilterEnabled()); EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str()); EXPECT_FALSE(tc.IsCategoryEnabled("Category1")); EXPECT_FALSE(tc.IsCategoryEnabled("not-excluded-category")); EXPECT_FALSE(tc.IsCategoryEnabled("CategoryTest")); EXPECT_FALSE(tc.IsCategoryEnabled("CategoryDebug")); EXPECT_FALSE(tc.IsCategoryEnabled("disabled-by-default-cc")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("Category1")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("not-excluded-category")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("CategoryTest")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("CategoryDebug")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("disabled-by-default-cc")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("Category1,CategoryDebug")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("CategoryDebug,Category1")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("CategoryTest,not-excluded-category")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("CategoryDebug,CategoryTest")); } TEST(TraceConfigTest, TraceConfigFromValidString) { // Using some non-empty config string. const char config_string[] = "{" "\"enable_argument_filter\":true," "\"enable_sampling\":true," "\"enable_systrace\":true," "\"excluded_categories\":[\"excluded\",\"exc_pattern*\"]," "\"included_categories\":[\"included\"," "\"inc_pattern*\"," "\"disabled-by-default-cc\"]," "\"record_mode\":\"record-continuously\"," "\"synthetic_delays\":[\"test.Delay1;16\",\"test.Delay2;32\"]" "}"; TraceConfig tc(config_string); EXPECT_STREQ(config_string, tc.ToString().c_str()); EXPECT_EQ(RECORD_CONTINUOUSLY, tc.GetTraceRecordMode()); EXPECT_TRUE(tc.IsSamplingEnabled()); EXPECT_TRUE(tc.IsSystraceEnabled()); EXPECT_TRUE(tc.IsArgumentFilterEnabled()); EXPECT_STREQ("included,inc_pattern*,disabled-by-default-cc,-excluded," "-exc_pattern*,DELAY(test.Delay1;16),DELAY(test.Delay2;32)", tc.ToCategoryFilterString().c_str()); EXPECT_TRUE(tc.IsCategoryEnabled("included")); EXPECT_TRUE(tc.IsCategoryEnabled("inc_pattern_category")); EXPECT_TRUE(tc.IsCategoryEnabled("disabled-by-default-cc")); EXPECT_FALSE(tc.IsCategoryEnabled("excluded")); EXPECT_FALSE(tc.IsCategoryEnabled("exc_pattern_category")); EXPECT_FALSE(tc.IsCategoryEnabled("disabled-by-default-others")); EXPECT_FALSE(tc.IsCategoryEnabled("not-excluded-nor-included")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("included")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("inc_pattern_category")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("disabled-by-default-cc")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("excluded")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("exc_pattern_category")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("disabled-by-default-others")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("not-excluded-nor-included")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("included,excluded")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("excluded,exc_pattern_category")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("included,DELAY(test.Delay1;16)")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("DELAY(test.Delay1;16)")); EXPECT_EQ(2u, tc.GetSyntheticDelayValues().size()); EXPECT_STREQ("test.Delay1;16", tc.GetSyntheticDelayValues()[0].c_str()); EXPECT_STREQ("test.Delay2;32", tc.GetSyntheticDelayValues()[1].c_str()); const char config_string_2[] = "{\"included_categories\":[\"*\"]}"; TraceConfig tc2(config_string_2); EXPECT_TRUE(tc2.IsCategoryEnabled("non-disabled-by-default-pattern")); EXPECT_FALSE(tc2.IsCategoryEnabled("disabled-by-default-pattern")); EXPECT_TRUE(tc2.IsCategoryGroupEnabled("non-disabled-by-default-pattern")); EXPECT_FALSE(tc2.IsCategoryGroupEnabled("disabled-by-default-pattern")); // Clear tc.Clear(); EXPECT_STREQ(tc.ToString().c_str(), "{" "\"enable_argument_filter\":false," "\"enable_sampling\":false," "\"enable_systrace\":false," "\"record_mode\":\"record-until-full\"" "}"); } TEST(TraceConfigTest, TraceConfigFromInvalidString) { // The config string needs to be a dictionary correctly formatted as a JSON // string. Otherwise, it will fall back to the default initialization. TraceConfig tc(""); EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str()); EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode()); EXPECT_FALSE(tc.IsSamplingEnabled()); EXPECT_FALSE(tc.IsSystraceEnabled()); EXPECT_FALSE(tc.IsArgumentFilterEnabled()); EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str()); tc = TraceConfig("This is an invalid config string."); EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str()); EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode()); EXPECT_FALSE(tc.IsSamplingEnabled()); EXPECT_FALSE(tc.IsSystraceEnabled()); EXPECT_FALSE(tc.IsArgumentFilterEnabled()); EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str()); tc = TraceConfig("[\"This\", \"is\", \"not\", \"a\", \"dictionary\"]"); EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str()); EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode()); EXPECT_FALSE(tc.IsSamplingEnabled()); EXPECT_FALSE(tc.IsSystraceEnabled()); EXPECT_FALSE(tc.IsArgumentFilterEnabled()); EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str()); tc = TraceConfig("{\"record_mode\": invalid-value-needs-double-quote}"); EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str()); EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode()); EXPECT_FALSE(tc.IsSamplingEnabled()); EXPECT_FALSE(tc.IsSystraceEnabled()); EXPECT_FALSE(tc.IsArgumentFilterEnabled()); EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str()); // If the config string a dictionary formatted as a JSON string, it will // initialize TraceConfig with best effort. tc = TraceConfig("{}"); EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode()); EXPECT_FALSE(tc.IsSamplingEnabled()); EXPECT_FALSE(tc.IsSystraceEnabled()); EXPECT_FALSE(tc.IsArgumentFilterEnabled()); EXPECT_STREQ("", tc.ToCategoryFilterString().c_str()); tc = TraceConfig("{\"arbitrary-key\":\"arbitrary-value\"}"); EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode()); EXPECT_FALSE(tc.IsSamplingEnabled()); EXPECT_FALSE(tc.IsSystraceEnabled()); EXPECT_FALSE(tc.IsArgumentFilterEnabled()); EXPECT_STREQ("", tc.ToCategoryFilterString().c_str()); const char invalid_config_string[] = "{" "\"enable_sampling\":\"true\"," "\"enable_systrace\":1," "\"excluded_categories\":[\"excluded\"]," "\"included_categories\":\"not a list\"," "\"record_mode\":\"arbitrary-mode\"," "\"synthetic_delays\":[\"test.Delay1;16\"," "\"invalid-delay\"," "\"test.Delay2;32\"]" "}"; tc = TraceConfig(invalid_config_string); EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode()); EXPECT_FALSE(tc.IsSamplingEnabled()); EXPECT_FALSE(tc.IsSystraceEnabled()); EXPECT_FALSE(tc.IsArgumentFilterEnabled()); EXPECT_STREQ("-excluded,DELAY(test.Delay1;16),DELAY(test.Delay2;32)", tc.ToCategoryFilterString().c_str()); const char invalid_config_string_2[] = "{" "\"included_categories\":[\"category\",\"disabled-by-default-pattern\"]," "\"excluded_categories\":[\"category\",\"disabled-by-default-pattern\"]" "}"; tc = TraceConfig(invalid_config_string_2); EXPECT_TRUE(tc.IsCategoryEnabled("category")); EXPECT_TRUE(tc.IsCategoryEnabled("disabled-by-default-pattern")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("category")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("disabled-by-default-pattern")); } TEST(TraceConfigTest, MergingTraceConfigs) { // Merge TraceConfig tc; TraceConfig tc2("included,-excluded,inc_pattern*,-exc_pattern*", ""); tc.Merge(tc2); EXPECT_STREQ("{" "\"enable_argument_filter\":false," "\"enable_sampling\":false," "\"enable_systrace\":false," "\"excluded_categories\":[" "\"*Debug\",\"*Test\",\"excluded\",\"exc_pattern*\"" "]," "\"record_mode\":\"record-until-full\"" "}", tc.ToString().c_str()); tc = TraceConfig("DELAY(test.Delay1;16)", ""); tc2 = TraceConfig("DELAY(test.Delay2;32)", ""); tc.Merge(tc2); EXPECT_EQ(2u, tc.GetSyntheticDelayValues().size()); EXPECT_STREQ("test.Delay1;16", tc.GetSyntheticDelayValues()[0].c_str()); EXPECT_STREQ("test.Delay2;32", tc.GetSyntheticDelayValues()[1].c_str()); } TEST(TraceConfigTest, IsCategoryGroupEnabled) { // Enabling a disabled- category does not require all categories to be traced // to be included. TraceConfig tc("disabled-by-default-cc,-excluded", ""); EXPECT_STREQ("disabled-by-default-cc,-excluded", tc.ToCategoryFilterString().c_str()); EXPECT_TRUE(tc.IsCategoryGroupEnabled("disabled-by-default-cc")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("some_other_group")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("excluded")); // Enabled a disabled- category and also including makes all categories to // be traced require including. tc = TraceConfig("disabled-by-default-cc,included", ""); EXPECT_STREQ("included,disabled-by-default-cc", tc.ToCategoryFilterString().c_str()); EXPECT_TRUE(tc.IsCategoryGroupEnabled("disabled-by-default-cc")); EXPECT_TRUE(tc.IsCategoryGroupEnabled("included")); EXPECT_FALSE(tc.IsCategoryGroupEnabled("other_included")); // Excluding categories won't enable disabled-by-default ones with the // excluded category is also present in the group. tc = TraceConfig("-excluded", ""); EXPECT_STREQ("-excluded", tc.ToCategoryFilterString().c_str()); EXPECT_FALSE(tc.IsCategoryGroupEnabled("excluded,disabled-by-default-cc")); } TEST(TraceConfigTest, IsEmptyOrContainsLeadingOrTrailingWhitespace) { // Test that IsEmptyOrContainsLeadingOrTrailingWhitespace actually catches // categories that are explicitly forbidden. // This method is called in a DCHECK to assert that we don't have these types // of strings as categories. EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace( " bad_category ")); EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace( " bad_category")); EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace( "bad_category ")); EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace( " bad_category")); EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace( "bad_category ")); EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace( " bad_category ")); EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace( "")); EXPECT_FALSE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace( "good_category")); } TEST(TraceConfigTest, SetTraceOptionValues) { TraceConfig tc; EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode()); EXPECT_FALSE(tc.IsSamplingEnabled()); EXPECT_FALSE(tc.IsSystraceEnabled()); tc.SetTraceRecordMode(RECORD_AS_MUCH_AS_POSSIBLE); EXPECT_EQ(RECORD_AS_MUCH_AS_POSSIBLE, tc.GetTraceRecordMode()); tc.EnableSampling(); EXPECT_TRUE(tc.IsSamplingEnabled()); tc.EnableSystrace(); EXPECT_TRUE(tc.IsSystraceEnabled()); } TEST(TraceConfigTest, TraceConfigFromMemoryConfigString) { std::string tc_str = TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(200, 2000); TraceConfig tc(tc_str); EXPECT_EQ(tc_str, tc.ToString()); EXPECT_TRUE(tc.IsCategoryGroupEnabled(MemoryDumpManager::kTraceCategory)); EXPECT_EQ(2u, tc.memory_dump_config_.size()); EXPECT_EQ(200u, tc.memory_dump_config_[0].periodic_interval_ms); EXPECT_EQ(MemoryDumpLevelOfDetail::LIGHT, tc.memory_dump_config_[0].level_of_detail); EXPECT_EQ(2000u, tc.memory_dump_config_[1].periodic_interval_ms); EXPECT_EQ(MemoryDumpLevelOfDetail::DETAILED, tc.memory_dump_config_[1].level_of_detail); } TEST(TraceConfigTest, EmptyMemoryDumpConfigTest) { // Empty trigger list should also be specified when converting back to string. TraceConfig tc(TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers()); EXPECT_EQ(TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers(), tc.ToString()); EXPECT_EQ(0u, tc.memory_dump_config_.size()); } TEST(TraceConfigTest, LegacyStringToMemoryDumpConfig) { TraceConfig tc(MemoryDumpManager::kTraceCategory, ""); EXPECT_TRUE(tc.IsCategoryGroupEnabled(MemoryDumpManager::kTraceCategory)); EXPECT_NE(std::string::npos, tc.ToString().find("memory_dump_config")); EXPECT_EQ(2u, tc.memory_dump_config_.size()); } } // namespace trace_event } // namespace base