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 
TEST(TraceConfigTest,TraceConfigFromValidLegacyFormat)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 
TEST(TraceConfigTest,TraceConfigFromInvalidLegacyStrings)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 
TEST(TraceConfigTest,ConstructDefaultTraceConfig)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 
TEST(TraceConfigTest,TraceConfigFromValidString)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 
TEST(TraceConfigTest,TraceConfigFromInvalidString)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 
TEST(TraceConfigTest,MergingTraceConfigs)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 
TEST(TraceConfigTest,IsCategoryGroupEnabled)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 
TEST(TraceConfigTest,IsEmptyOrContainsLeadingOrTrailingWhitespace)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 
TEST(TraceConfigTest,SetTraceOptionValues)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 
TEST(TraceConfigTest,TraceConfigFromMemoryConfigString)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 
TEST(TraceConfigTest,EmptyMemoryDumpConfigTest)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 
TEST(TraceConfigTest,LegacyStringToMemoryDumpConfig)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