Home | History | Annotate | Download | only in trace_event
      1 // Copyright 2015 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stddef.h>
      6 
      7 #include "base/macros.h"
      8 #include "base/trace_event/memory_dump_manager.h"
      9 #include "base/trace_event/trace_config.h"
     10 #include "base/trace_event/trace_config_memory_test_util.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 namespace base {
     14 namespace trace_event {
     15 
     16 namespace {
     17 
     18 const char kDefaultTraceConfigString[] =
     19   "{"
     20     "\"enable_argument_filter\":false,"
     21     "\"enable_sampling\":false,"
     22     "\"enable_systrace\":false,"
     23     "\"excluded_categories\":[\"*Debug\",\"*Test\"],"
     24     "\"record_mode\":\"record-until-full\""
     25   "}";
     26 }  // namespace
     27 
     28 TEST(TraceConfigTest, TraceConfigFromValidLegacyFormat) {
     29   // From trace options strings
     30   TraceConfig config("", "record-until-full");
     31   EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode());
     32   EXPECT_FALSE(config.IsSamplingEnabled());
     33   EXPECT_FALSE(config.IsSystraceEnabled());
     34   EXPECT_FALSE(config.IsArgumentFilterEnabled());
     35   EXPECT_STREQ("record-until-full", config.ToTraceOptionsString().c_str());
     36 
     37   config = TraceConfig("", "record-continuously");
     38   EXPECT_EQ(RECORD_CONTINUOUSLY, config.GetTraceRecordMode());
     39   EXPECT_FALSE(config.IsSamplingEnabled());
     40   EXPECT_FALSE(config.IsSystraceEnabled());
     41   EXPECT_FALSE(config.IsArgumentFilterEnabled());
     42   EXPECT_STREQ("record-continuously", config.ToTraceOptionsString().c_str());
     43 
     44   config = TraceConfig("", "trace-to-console");
     45   EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode());
     46   EXPECT_FALSE(config.IsSamplingEnabled());
     47   EXPECT_FALSE(config.IsSystraceEnabled());
     48   EXPECT_FALSE(config.IsArgumentFilterEnabled());
     49   EXPECT_STREQ("trace-to-console", config.ToTraceOptionsString().c_str());
     50 
     51   config = TraceConfig("", "record-as-much-as-possible");
     52   EXPECT_EQ(RECORD_AS_MUCH_AS_POSSIBLE, config.GetTraceRecordMode());
     53   EXPECT_FALSE(config.IsSamplingEnabled());
     54   EXPECT_FALSE(config.IsSystraceEnabled());
     55   EXPECT_FALSE(config.IsArgumentFilterEnabled());
     56   EXPECT_STREQ("record-as-much-as-possible",
     57                config.ToTraceOptionsString().c_str());
     58 
     59   config = TraceConfig("", "record-until-full, enable-sampling");
     60   EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode());
     61   EXPECT_TRUE(config.IsSamplingEnabled());
     62   EXPECT_FALSE(config.IsSystraceEnabled());
     63   EXPECT_FALSE(config.IsArgumentFilterEnabled());
     64   EXPECT_STREQ("record-until-full,enable-sampling",
     65                config.ToTraceOptionsString().c_str());
     66 
     67   config = TraceConfig("", "enable-systrace, record-continuously");
     68   EXPECT_EQ(RECORD_CONTINUOUSLY, config.GetTraceRecordMode());
     69   EXPECT_FALSE(config.IsSamplingEnabled());
     70   EXPECT_TRUE(config.IsSystraceEnabled());
     71   EXPECT_FALSE(config.IsArgumentFilterEnabled());
     72   EXPECT_STREQ("record-continuously,enable-systrace",
     73                config.ToTraceOptionsString().c_str());
     74 
     75   config = TraceConfig("", "enable-argument-filter,record-as-much-as-possible");
     76   EXPECT_EQ(RECORD_AS_MUCH_AS_POSSIBLE, config.GetTraceRecordMode());
     77   EXPECT_FALSE(config.IsSamplingEnabled());
     78   EXPECT_FALSE(config.IsSystraceEnabled());
     79   EXPECT_TRUE(config.IsArgumentFilterEnabled());
     80   EXPECT_STREQ("record-as-much-as-possible,enable-argument-filter",
     81                config.ToTraceOptionsString().c_str());
     82 
     83   config = TraceConfig(
     84     "",
     85     "enable-systrace,trace-to-console,enable-sampling,enable-argument-filter");
     86   EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode());
     87   EXPECT_TRUE(config.IsSamplingEnabled());
     88   EXPECT_TRUE(config.IsSystraceEnabled());
     89   EXPECT_TRUE(config.IsArgumentFilterEnabled());
     90   EXPECT_STREQ(
     91     "trace-to-console,enable-sampling,enable-systrace,enable-argument-filter",
     92     config.ToTraceOptionsString().c_str());
     93 
     94   config = TraceConfig(
     95     "", "record-continuously, record-until-full, trace-to-console");
     96   EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode());
     97   EXPECT_FALSE(config.IsSamplingEnabled());
     98   EXPECT_FALSE(config.IsSystraceEnabled());
     99   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    100   EXPECT_STREQ("trace-to-console", config.ToTraceOptionsString().c_str());
    101 
    102   // From TraceRecordMode
    103   config = TraceConfig("", RECORD_UNTIL_FULL);
    104   EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode());
    105   EXPECT_FALSE(config.IsSamplingEnabled());
    106   EXPECT_FALSE(config.IsSystraceEnabled());
    107   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    108   EXPECT_STREQ("record-until-full", config.ToTraceOptionsString().c_str());
    109 
    110   config = TraceConfig("", RECORD_CONTINUOUSLY);
    111   EXPECT_EQ(RECORD_CONTINUOUSLY, config.GetTraceRecordMode());
    112   EXPECT_FALSE(config.IsSamplingEnabled());
    113   EXPECT_FALSE(config.IsSystraceEnabled());
    114   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    115   EXPECT_STREQ("record-continuously", config.ToTraceOptionsString().c_str());
    116 
    117   config = TraceConfig("", ECHO_TO_CONSOLE);
    118   EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode());
    119   EXPECT_FALSE(config.IsSamplingEnabled());
    120   EXPECT_FALSE(config.IsSystraceEnabled());
    121   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    122   EXPECT_STREQ("trace-to-console", config.ToTraceOptionsString().c_str());
    123 
    124   config = TraceConfig("", RECORD_AS_MUCH_AS_POSSIBLE);
    125   EXPECT_EQ(RECORD_AS_MUCH_AS_POSSIBLE, config.GetTraceRecordMode());
    126   EXPECT_FALSE(config.IsSamplingEnabled());
    127   EXPECT_FALSE(config.IsSystraceEnabled());
    128   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    129   EXPECT_STREQ("record-as-much-as-possible",
    130                config.ToTraceOptionsString().c_str());
    131 
    132   // From category filter strings
    133   config = TraceConfig("-*Debug,-*Test", "");
    134   EXPECT_STREQ("-*Debug,-*Test", config.ToCategoryFilterString().c_str());
    135 
    136   config = TraceConfig("included,-excluded,inc_pattern*,-exc_pattern*", "");
    137   EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*",
    138                config.ToCategoryFilterString().c_str());
    139 
    140   config = TraceConfig("only_inc_cat", "");
    141   EXPECT_STREQ("only_inc_cat", config.ToCategoryFilterString().c_str());
    142 
    143   config = TraceConfig("-only_exc_cat", "");
    144   EXPECT_STREQ("-only_exc_cat", config.ToCategoryFilterString().c_str());
    145 
    146   config = TraceConfig("disabled-by-default-cc,-excluded", "");
    147   EXPECT_STREQ("disabled-by-default-cc,-excluded",
    148                config.ToCategoryFilterString().c_str());
    149 
    150   config = TraceConfig("disabled-by-default-cc,included", "");
    151   EXPECT_STREQ("included,disabled-by-default-cc",
    152                config.ToCategoryFilterString().c_str());
    153 
    154   config = TraceConfig("DELAY(test.Delay1;16),included", "");
    155   EXPECT_STREQ("included,DELAY(test.Delay1;16)",
    156                config.ToCategoryFilterString().c_str());
    157 
    158   // From both trace options and category filter strings
    159   config = TraceConfig("", "");
    160   EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode());
    161   EXPECT_FALSE(config.IsSamplingEnabled());
    162   EXPECT_FALSE(config.IsSystraceEnabled());
    163   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    164   EXPECT_STREQ("", config.ToCategoryFilterString().c_str());
    165   EXPECT_STREQ("record-until-full", config.ToTraceOptionsString().c_str());
    166 
    167   config = TraceConfig("included,-excluded,inc_pattern*,-exc_pattern*",
    168                        "enable-systrace, trace-to-console, enable-sampling");
    169   EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode());
    170   EXPECT_TRUE(config.IsSamplingEnabled());
    171   EXPECT_TRUE(config.IsSystraceEnabled());
    172   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    173   EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*",
    174                config.ToCategoryFilterString().c_str());
    175   EXPECT_STREQ("trace-to-console,enable-sampling,enable-systrace",
    176                config.ToTraceOptionsString().c_str());
    177 
    178   // From both trace options and category filter strings with spaces.
    179   config = TraceConfig(" included , -excluded, inc_pattern*, ,-exc_pattern*   ",
    180                        "enable-systrace, ,trace-to-console, enable-sampling  ");
    181   EXPECT_EQ(ECHO_TO_CONSOLE, config.GetTraceRecordMode());
    182   EXPECT_TRUE(config.IsSamplingEnabled());
    183   EXPECT_TRUE(config.IsSystraceEnabled());
    184   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    185   EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*",
    186                config.ToCategoryFilterString().c_str());
    187   EXPECT_STREQ("trace-to-console,enable-sampling,enable-systrace",
    188                config.ToTraceOptionsString().c_str());
    189 
    190   // From category filter string and TraceRecordMode
    191   config = TraceConfig("included,-excluded,inc_pattern*,-exc_pattern*",
    192                        RECORD_CONTINUOUSLY);
    193   EXPECT_EQ(RECORD_CONTINUOUSLY, config.GetTraceRecordMode());
    194   EXPECT_FALSE(config.IsSystraceEnabled());
    195   EXPECT_FALSE(config.IsSamplingEnabled());
    196   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    197   EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*",
    198                config.ToCategoryFilterString().c_str());
    199   EXPECT_STREQ("record-continuously", config.ToTraceOptionsString().c_str());
    200 }
    201 
    202 TEST(TraceConfigTest, TraceConfigFromInvalidLegacyStrings) {
    203   TraceConfig config("", "foo-bar-baz");
    204   EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode());
    205   EXPECT_FALSE(config.IsSamplingEnabled());
    206   EXPECT_FALSE(config.IsSystraceEnabled());
    207   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    208   EXPECT_STREQ("", config.ToCategoryFilterString().c_str());
    209   EXPECT_STREQ("record-until-full", config.ToTraceOptionsString().c_str());
    210 
    211   config = TraceConfig("arbitrary-category", "foo-bar-baz, enable-systrace");
    212   EXPECT_EQ(RECORD_UNTIL_FULL, config.GetTraceRecordMode());
    213   EXPECT_FALSE(config.IsSamplingEnabled());
    214   EXPECT_TRUE(config.IsSystraceEnabled());
    215   EXPECT_FALSE(config.IsArgumentFilterEnabled());
    216   EXPECT_STREQ("arbitrary-category", config.ToCategoryFilterString().c_str());
    217   EXPECT_STREQ("record-until-full,enable-systrace",
    218                config.ToTraceOptionsString().c_str());
    219 
    220   const char* const configs[] = {
    221     "",
    222     "DELAY(",
    223     "DELAY(;",
    224     "DELAY(;)",
    225     "DELAY(test.Delay)",
    226     "DELAY(test.Delay;)"
    227   };
    228   for (size_t i = 0; i < arraysize(configs); i++) {
    229     TraceConfig tc(configs[i], "");
    230     EXPECT_EQ(0u, tc.GetSyntheticDelayValues().size());
    231   }
    232 }
    233 
    234 TEST(TraceConfigTest, ConstructDefaultTraceConfig) {
    235   // Make sure that upon an empty string, we fall back to the default config.
    236   TraceConfig tc;
    237   EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str());
    238   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
    239   EXPECT_FALSE(tc.IsSamplingEnabled());
    240   EXPECT_FALSE(tc.IsSystraceEnabled());
    241   EXPECT_FALSE(tc.IsArgumentFilterEnabled());
    242   EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str());
    243 
    244   EXPECT_FALSE(tc.IsCategoryEnabled("Category1"));
    245   EXPECT_FALSE(tc.IsCategoryEnabled("not-excluded-category"));
    246   EXPECT_FALSE(tc.IsCategoryEnabled("CategoryTest"));
    247   EXPECT_FALSE(tc.IsCategoryEnabled("CategoryDebug"));
    248   EXPECT_FALSE(tc.IsCategoryEnabled("disabled-by-default-cc"));
    249 
    250   EXPECT_TRUE(tc.IsCategoryGroupEnabled("Category1"));
    251   EXPECT_TRUE(tc.IsCategoryGroupEnabled("not-excluded-category"));
    252   EXPECT_FALSE(tc.IsCategoryGroupEnabled("CategoryTest"));
    253   EXPECT_FALSE(tc.IsCategoryGroupEnabled("CategoryDebug"));
    254   EXPECT_FALSE(tc.IsCategoryGroupEnabled("disabled-by-default-cc"));
    255 
    256   EXPECT_TRUE(tc.IsCategoryGroupEnabled("Category1,CategoryDebug"));
    257   EXPECT_TRUE(tc.IsCategoryGroupEnabled("CategoryDebug,Category1"));
    258   EXPECT_TRUE(tc.IsCategoryGroupEnabled("CategoryTest,not-excluded-category"));
    259   EXPECT_FALSE(tc.IsCategoryGroupEnabled("CategoryDebug,CategoryTest"));
    260 }
    261 
    262 TEST(TraceConfigTest, TraceConfigFromValidString) {
    263   // Using some non-empty config string.
    264   const char config_string[] =
    265     "{"
    266       "\"enable_argument_filter\":true,"
    267       "\"enable_sampling\":true,"
    268       "\"enable_systrace\":true,"
    269       "\"excluded_categories\":[\"excluded\",\"exc_pattern*\"],"
    270       "\"included_categories\":[\"included\","
    271                                "\"inc_pattern*\","
    272                                "\"disabled-by-default-cc\"],"
    273       "\"record_mode\":\"record-continuously\","
    274       "\"synthetic_delays\":[\"test.Delay1;16\",\"test.Delay2;32\"]"
    275     "}";
    276   TraceConfig tc(config_string);
    277 
    278   EXPECT_STREQ(config_string, tc.ToString().c_str());
    279   EXPECT_EQ(RECORD_CONTINUOUSLY, tc.GetTraceRecordMode());
    280   EXPECT_TRUE(tc.IsSamplingEnabled());
    281   EXPECT_TRUE(tc.IsSystraceEnabled());
    282   EXPECT_TRUE(tc.IsArgumentFilterEnabled());
    283   EXPECT_STREQ("included,inc_pattern*,disabled-by-default-cc,-excluded,"
    284                "-exc_pattern*,DELAY(test.Delay1;16),DELAY(test.Delay2;32)",
    285                tc.ToCategoryFilterString().c_str());
    286 
    287   EXPECT_TRUE(tc.IsCategoryEnabled("included"));
    288   EXPECT_TRUE(tc.IsCategoryEnabled("inc_pattern_category"));
    289   EXPECT_TRUE(tc.IsCategoryEnabled("disabled-by-default-cc"));
    290   EXPECT_FALSE(tc.IsCategoryEnabled("excluded"));
    291   EXPECT_FALSE(tc.IsCategoryEnabled("exc_pattern_category"));
    292   EXPECT_FALSE(tc.IsCategoryEnabled("disabled-by-default-others"));
    293   EXPECT_FALSE(tc.IsCategoryEnabled("not-excluded-nor-included"));
    294 
    295   EXPECT_TRUE(tc.IsCategoryGroupEnabled("included"));
    296   EXPECT_TRUE(tc.IsCategoryGroupEnabled("inc_pattern_category"));
    297   EXPECT_TRUE(tc.IsCategoryGroupEnabled("disabled-by-default-cc"));
    298   EXPECT_FALSE(tc.IsCategoryGroupEnabled("excluded"));
    299   EXPECT_FALSE(tc.IsCategoryGroupEnabled("exc_pattern_category"));
    300   EXPECT_FALSE(tc.IsCategoryGroupEnabled("disabled-by-default-others"));
    301   EXPECT_FALSE(tc.IsCategoryGroupEnabled("not-excluded-nor-included"));
    302 
    303   EXPECT_TRUE(tc.IsCategoryGroupEnabled("included,excluded"));
    304   EXPECT_FALSE(tc.IsCategoryGroupEnabled("excluded,exc_pattern_category"));
    305   EXPECT_TRUE(tc.IsCategoryGroupEnabled("included,DELAY(test.Delay1;16)"));
    306   EXPECT_FALSE(tc.IsCategoryGroupEnabled("DELAY(test.Delay1;16)"));
    307 
    308   EXPECT_EQ(2u, tc.GetSyntheticDelayValues().size());
    309   EXPECT_STREQ("test.Delay1;16", tc.GetSyntheticDelayValues()[0].c_str());
    310   EXPECT_STREQ("test.Delay2;32", tc.GetSyntheticDelayValues()[1].c_str());
    311 
    312   const char config_string_2[] = "{\"included_categories\":[\"*\"]}";
    313   TraceConfig tc2(config_string_2);
    314   EXPECT_TRUE(tc2.IsCategoryEnabled("non-disabled-by-default-pattern"));
    315   EXPECT_FALSE(tc2.IsCategoryEnabled("disabled-by-default-pattern"));
    316   EXPECT_TRUE(tc2.IsCategoryGroupEnabled("non-disabled-by-default-pattern"));
    317   EXPECT_FALSE(tc2.IsCategoryGroupEnabled("disabled-by-default-pattern"));
    318 
    319   // Clear
    320   tc.Clear();
    321   EXPECT_STREQ(tc.ToString().c_str(),
    322                "{"
    323                  "\"enable_argument_filter\":false,"
    324                  "\"enable_sampling\":false,"
    325                  "\"enable_systrace\":false,"
    326                  "\"record_mode\":\"record-until-full\""
    327                "}");
    328 }
    329 
    330 TEST(TraceConfigTest, TraceConfigFromInvalidString) {
    331   // The config string needs to be a dictionary correctly formatted as a JSON
    332   // string. Otherwise, it will fall back to the default initialization.
    333   TraceConfig tc("");
    334   EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str());
    335   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
    336   EXPECT_FALSE(tc.IsSamplingEnabled());
    337   EXPECT_FALSE(tc.IsSystraceEnabled());
    338   EXPECT_FALSE(tc.IsArgumentFilterEnabled());
    339   EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str());
    340 
    341   tc = TraceConfig("This is an invalid config string.");
    342   EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str());
    343   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
    344   EXPECT_FALSE(tc.IsSamplingEnabled());
    345   EXPECT_FALSE(tc.IsSystraceEnabled());
    346   EXPECT_FALSE(tc.IsArgumentFilterEnabled());
    347   EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str());
    348 
    349   tc = TraceConfig("[\"This\", \"is\", \"not\", \"a\", \"dictionary\"]");
    350   EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str());
    351   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
    352   EXPECT_FALSE(tc.IsSamplingEnabled());
    353   EXPECT_FALSE(tc.IsSystraceEnabled());
    354   EXPECT_FALSE(tc.IsArgumentFilterEnabled());
    355   EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str());
    356 
    357   tc = TraceConfig("{\"record_mode\": invalid-value-needs-double-quote}");
    358   EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str());
    359   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
    360   EXPECT_FALSE(tc.IsSamplingEnabled());
    361   EXPECT_FALSE(tc.IsSystraceEnabled());
    362   EXPECT_FALSE(tc.IsArgumentFilterEnabled());
    363   EXPECT_STREQ("-*Debug,-*Test", tc.ToCategoryFilterString().c_str());
    364 
    365   // If the config string a dictionary formatted as a JSON string, it will
    366   // initialize TraceConfig with best effort.
    367   tc = TraceConfig("{}");
    368   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
    369   EXPECT_FALSE(tc.IsSamplingEnabled());
    370   EXPECT_FALSE(tc.IsSystraceEnabled());
    371   EXPECT_FALSE(tc.IsArgumentFilterEnabled());
    372   EXPECT_STREQ("", tc.ToCategoryFilterString().c_str());
    373 
    374   tc = TraceConfig("{\"arbitrary-key\":\"arbitrary-value\"}");
    375   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
    376   EXPECT_FALSE(tc.IsSamplingEnabled());
    377   EXPECT_FALSE(tc.IsSystraceEnabled());
    378   EXPECT_FALSE(tc.IsArgumentFilterEnabled());
    379   EXPECT_STREQ("", tc.ToCategoryFilterString().c_str());
    380 
    381   const char invalid_config_string[] =
    382     "{"
    383       "\"enable_sampling\":\"true\","
    384       "\"enable_systrace\":1,"
    385       "\"excluded_categories\":[\"excluded\"],"
    386       "\"included_categories\":\"not a list\","
    387       "\"record_mode\":\"arbitrary-mode\","
    388       "\"synthetic_delays\":[\"test.Delay1;16\","
    389                             "\"invalid-delay\","
    390                             "\"test.Delay2;32\"]"
    391     "}";
    392   tc = TraceConfig(invalid_config_string);
    393   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
    394   EXPECT_FALSE(tc.IsSamplingEnabled());
    395   EXPECT_FALSE(tc.IsSystraceEnabled());
    396   EXPECT_FALSE(tc.IsArgumentFilterEnabled());
    397   EXPECT_STREQ("-excluded,DELAY(test.Delay1;16),DELAY(test.Delay2;32)",
    398                tc.ToCategoryFilterString().c_str());
    399 
    400   const char invalid_config_string_2[] =
    401     "{"
    402       "\"included_categories\":[\"category\",\"disabled-by-default-pattern\"],"
    403       "\"excluded_categories\":[\"category\",\"disabled-by-default-pattern\"]"
    404     "}";
    405   tc = TraceConfig(invalid_config_string_2);
    406   EXPECT_TRUE(tc.IsCategoryEnabled("category"));
    407   EXPECT_TRUE(tc.IsCategoryEnabled("disabled-by-default-pattern"));
    408   EXPECT_TRUE(tc.IsCategoryGroupEnabled("category"));
    409   EXPECT_TRUE(tc.IsCategoryGroupEnabled("disabled-by-default-pattern"));
    410 }
    411 
    412 TEST(TraceConfigTest, MergingTraceConfigs) {
    413   // Merge
    414   TraceConfig tc;
    415   TraceConfig tc2("included,-excluded,inc_pattern*,-exc_pattern*", "");
    416   tc.Merge(tc2);
    417   EXPECT_STREQ("{"
    418                  "\"enable_argument_filter\":false,"
    419                  "\"enable_sampling\":false,"
    420                  "\"enable_systrace\":false,"
    421                  "\"excluded_categories\":["
    422                    "\"*Debug\",\"*Test\",\"excluded\",\"exc_pattern*\""
    423                  "],"
    424                  "\"record_mode\":\"record-until-full\""
    425                "}",
    426                tc.ToString().c_str());
    427 
    428   tc = TraceConfig("DELAY(test.Delay1;16)", "");
    429   tc2 = TraceConfig("DELAY(test.Delay2;32)", "");
    430   tc.Merge(tc2);
    431   EXPECT_EQ(2u, tc.GetSyntheticDelayValues().size());
    432   EXPECT_STREQ("test.Delay1;16", tc.GetSyntheticDelayValues()[0].c_str());
    433   EXPECT_STREQ("test.Delay2;32", tc.GetSyntheticDelayValues()[1].c_str());
    434 }
    435 
    436 TEST(TraceConfigTest, IsCategoryGroupEnabled) {
    437   // Enabling a disabled- category does not require all categories to be traced
    438   // to be included.
    439   TraceConfig tc("disabled-by-default-cc,-excluded", "");
    440   EXPECT_STREQ("disabled-by-default-cc,-excluded",
    441                tc.ToCategoryFilterString().c_str());
    442   EXPECT_TRUE(tc.IsCategoryGroupEnabled("disabled-by-default-cc"));
    443   EXPECT_TRUE(tc.IsCategoryGroupEnabled("some_other_group"));
    444   EXPECT_FALSE(tc.IsCategoryGroupEnabled("excluded"));
    445 
    446   // Enabled a disabled- category and also including makes all categories to
    447   // be traced require including.
    448   tc = TraceConfig("disabled-by-default-cc,included", "");
    449   EXPECT_STREQ("included,disabled-by-default-cc",
    450                tc.ToCategoryFilterString().c_str());
    451   EXPECT_TRUE(tc.IsCategoryGroupEnabled("disabled-by-default-cc"));
    452   EXPECT_TRUE(tc.IsCategoryGroupEnabled("included"));
    453   EXPECT_FALSE(tc.IsCategoryGroupEnabled("other_included"));
    454 
    455   // Excluding categories won't enable disabled-by-default ones with the
    456   // excluded category is also present in the group.
    457   tc = TraceConfig("-excluded", "");
    458   EXPECT_STREQ("-excluded", tc.ToCategoryFilterString().c_str());
    459   EXPECT_FALSE(tc.IsCategoryGroupEnabled("excluded,disabled-by-default-cc"));
    460 }
    461 
    462 TEST(TraceConfigTest, IsEmptyOrContainsLeadingOrTrailingWhitespace) {
    463   // Test that IsEmptyOrContainsLeadingOrTrailingWhitespace actually catches
    464   // categories that are explicitly forbidden.
    465   // This method is called in a DCHECK to assert that we don't have these types
    466   // of strings as categories.
    467   EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
    468       " bad_category "));
    469   EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
    470       " bad_category"));
    471   EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
    472       "bad_category "));
    473   EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
    474       "   bad_category"));
    475   EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
    476       "bad_category   "));
    477   EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
    478       "   bad_category   "));
    479   EXPECT_TRUE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
    480       ""));
    481   EXPECT_FALSE(TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
    482       "good_category"));
    483 }
    484 
    485 TEST(TraceConfigTest, SetTraceOptionValues) {
    486   TraceConfig tc;
    487   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
    488   EXPECT_FALSE(tc.IsSamplingEnabled());
    489   EXPECT_FALSE(tc.IsSystraceEnabled());
    490 
    491   tc.SetTraceRecordMode(RECORD_AS_MUCH_AS_POSSIBLE);
    492   EXPECT_EQ(RECORD_AS_MUCH_AS_POSSIBLE, tc.GetTraceRecordMode());
    493 
    494   tc.EnableSampling();
    495   EXPECT_TRUE(tc.IsSamplingEnabled());
    496 
    497   tc.EnableSystrace();
    498   EXPECT_TRUE(tc.IsSystraceEnabled());
    499 }
    500 
    501 TEST(TraceConfigTest, TraceConfigFromMemoryConfigString) {
    502   std::string tc_str =
    503       TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(200, 2000);
    504   TraceConfig tc(tc_str);
    505   EXPECT_EQ(tc_str, tc.ToString());
    506   EXPECT_TRUE(tc.IsCategoryGroupEnabled(MemoryDumpManager::kTraceCategory));
    507   EXPECT_EQ(2u, tc.memory_dump_config_.size());
    508 
    509   EXPECT_EQ(200u, tc.memory_dump_config_[0].periodic_interval_ms);
    510   EXPECT_EQ(MemoryDumpLevelOfDetail::LIGHT,
    511             tc.memory_dump_config_[0].level_of_detail);
    512 
    513   EXPECT_EQ(2000u, tc.memory_dump_config_[1].periodic_interval_ms);
    514   EXPECT_EQ(MemoryDumpLevelOfDetail::DETAILED,
    515             tc.memory_dump_config_[1].level_of_detail);
    516 }
    517 
    518 TEST(TraceConfigTest, EmptyMemoryDumpConfigTest) {
    519   // Empty trigger list should also be specified when converting back to string.
    520   TraceConfig tc(TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers());
    521   EXPECT_EQ(TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers(),
    522             tc.ToString());
    523   EXPECT_EQ(0u, tc.memory_dump_config_.size());
    524 }
    525 
    526 TEST(TraceConfigTest, LegacyStringToMemoryDumpConfig) {
    527   TraceConfig tc(MemoryDumpManager::kTraceCategory, "");
    528   EXPECT_TRUE(tc.IsCategoryGroupEnabled(MemoryDumpManager::kTraceCategory));
    529   EXPECT_NE(std::string::npos, tc.ToString().find("memory_dump_config"));
    530   EXPECT_EQ(2u, tc.memory_dump_config_.size());
    531 }
    532 
    533 }  // namespace trace_event
    534 }  // namespace base
    535