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.
5 #include "base/json/json_reader.h"
6 #include "base/json/json_writer.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/values.h"
9 #include "content/browser/tracing/background_tracing_config_impl.h"
10 #include "content/browser/tracing/background_tracing_rule.h"
11 #include "content/public/test/test_browser_thread.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 class BackgroundTracingConfigTest
: public testing::Test
{
18 BackgroundTracingConfigTest()
19 : ui_thread_(BrowserThread::UI
, &message_loop_
) {}
22 base::MessageLoop message_loop_
;
23 TestBrowserThread ui_thread_
;
26 scoped_ptr
<BackgroundTracingConfigImpl
> ReadFromJSONString(
27 const std::string
& json_text
) {
28 scoped_ptr
<base::Value
> json_value(base::JSONReader::Read(json_text
));
30 base::DictionaryValue
* dict
= NULL
;
32 json_value
->GetAsDictionary(&dict
);
34 scoped_ptr
<BackgroundTracingConfigImpl
> config(
35 static_cast<BackgroundTracingConfigImpl
*>(
36 BackgroundTracingConfig::FromDict(dict
).release()));
40 std::string
ConfigToString(const BackgroundTracingConfig
* config
) {
41 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue());
43 config
->IntoDict(dict
.get());
46 if (base::JSONWriter::Write(*dict
.get(), &results
))
51 std::string
RuleToString(const BackgroundTracingRule
* rule
) {
52 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue());
54 rule
->IntoDict(dict
.get());
57 if (base::JSONWriter::Write(*dict
.get(), &results
))
62 TEST_F(BackgroundTracingConfigTest
, ConfigFromInvalidString
) {
63 // Missing or invalid mode
64 EXPECT_FALSE(ReadFromJSONString("{}"));
65 EXPECT_FALSE(ReadFromJSONString("{\"mode\":\"invalid\"}"));
68 TEST_F(BackgroundTracingConfigTest
, PreemptiveConfigFromInvalidString
) {
69 // Missing or invalid category
70 EXPECT_FALSE(ReadFromJSONString("{\"mode\":\"preemptive\"}"));
71 EXPECT_FALSE(ReadFromJSONString(
72 "{\"mode\":\"preemptive\", \"category\": \"invalid\"}"));
73 EXPECT_FALSE(ReadFromJSONString(
74 "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
75 "\"invalid\",\"configs\": [{\"rule\": "
76 "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\", \"trigger_name\":\"foo\"}]}"));
80 ReadFromJSONString("{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
81 "\"BENCHMARK\",\"configs\": []}"));
83 // Missing or invalid configs
84 EXPECT_FALSE(ReadFromJSONString(
85 "{\"mode\":\"preemptive\", \"category\": \"benchmark\"}"));
86 EXPECT_FALSE(ReadFromJSONString(
87 "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
88 "\"configs\": \"\"}"));
89 EXPECT_FALSE(ReadFromJSONString(
90 "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
93 // Invalid config entries
94 EXPECT_FALSE(ReadFromJSONString(
95 "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
96 "\"configs\": [{}]}"));
97 EXPECT_FALSE(ReadFromJSONString(
98 "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
99 "\"configs\": [\"invalid\"]}"));
100 EXPECT_FALSE(ReadFromJSONString(
101 "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
102 "\"configs\": [[]]}"));
103 EXPECT_FALSE(ReadFromJSONString(
104 "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
105 "\"configs\": [{\"rule\": \"invalid\"}]}"));
107 // Missing or invalid keys for a named trigger.
108 EXPECT_FALSE(ReadFromJSONString(
109 "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
110 "\"configs\": [{\"rule\": \"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\"}]}"));
113 TEST_F(BackgroundTracingConfigTest
, ReactiveConfigFromInvalidString
) {
114 // Missing or invalid configs
115 EXPECT_FALSE(ReadFromJSONString("{\"mode\":\"reactive\"}"));
117 ReadFromJSONString("{\"mode\":\"reactive\", \"configs\": \"invalid\"}"));
118 EXPECT_FALSE(ReadFromJSONString("{\"mode\":\"reactive\", \"configs\": {}}"));
120 EXPECT_FALSE(ReadFromJSONString(
121 "{\"mode\":\"REACTIVE_TRACING_MODE\", \"configs\": []}"));
123 // Invalid config entries
125 ReadFromJSONString("{\"mode\":\"reactive\", \"configs\": [{}]}"));
126 EXPECT_FALSE(ReadFromJSONString(
127 "{\"mode\":\"reactive\", \"configs\": [\"invalid\"]}"));
129 // Invalid tracing rule type
130 EXPECT_FALSE(ReadFromJSONString(
131 "{\"mode\":\"reactive\","
132 "\"configs\": [{\"rule\": []}]}"));
133 EXPECT_FALSE(ReadFromJSONString(
134 "{\"mode\":\"reactive\","
135 "\"configs\": [{\"rule\": \"\"}]}"));
137 ReadFromJSONString("{\"mode\":\"reactive\","
138 "\"configs\": [{\"rule\": "
139 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\"}]}"));
141 EXPECT_FALSE(ReadFromJSONString(
142 "{\"mode\":\"reactive\","
143 "\"configs\": [{\"rule\": "
144 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", \"category\": "
146 EXPECT_FALSE(ReadFromJSONString(
147 "{\"mode\":\"reactive\","
148 "\"configs\": [{\"rule\": "
149 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", \"category\": "
151 EXPECT_FALSE(ReadFromJSONString(
152 "{\"mode\":\"reactive\","
153 "\"configs\": [{\"rule\": "
154 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", \"category\": "
155 "\"benchmark\"}]}"));
157 EXPECT_FALSE(ReadFromJSONString(
158 "{\"mode\":\"reactive\","
159 "\"configs\": [{\"rule\": "
160 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", \"category\": "
161 "\"benchmark\", \"trigger_name\": []}]}"));
162 EXPECT_FALSE(ReadFromJSONString(
163 "{\"mode\":\"reactive\","
164 "\"configs\": [{\"rule\": "
165 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", \"category\": "
166 "\"benchmark\", \"trigger_name\": 0}]}"));
169 TEST_F(BackgroundTracingConfigTest
, PreemptiveConfigFromValidString
) {
170 scoped_ptr
<BackgroundTracingConfigImpl
> config
;
172 config
= ReadFromJSONString(
173 "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
174 "\"BENCHMARK\",\"configs\": [{\"rule\": "
175 "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\", \"trigger_name\":\"foo\"}]}");
177 EXPECT_EQ(config
->tracing_mode(), BackgroundTracingConfig::PREEMPTIVE
);
178 EXPECT_EQ(config
->category_preset(), BackgroundTracingConfigImpl::BENCHMARK
);
179 EXPECT_EQ(config
->rules().size(), 1u);
180 EXPECT_EQ(RuleToString(config
->rules()[0]),
181 "{\"rule\":\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\","
182 "\"trigger_name\":\"foo\"}");
184 config
= ReadFromJSONString(
185 "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
186 "\"BENCHMARK\",\"configs\": [{\"rule\": "
187 "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
188 "\"histogram_name\":\"foo\", \"histogram_value\": 1}]}");
190 EXPECT_EQ(config
->tracing_mode(), BackgroundTracingConfig::PREEMPTIVE
);
191 EXPECT_EQ(config
->category_preset(), BackgroundTracingConfigImpl::BENCHMARK
);
192 EXPECT_EQ(config
->rules().size(), 1u);
193 EXPECT_EQ(RuleToString(config
->rules()[0]),
194 "{\"histogram_name\":\"foo\",\"histogram_value\":1,"
195 "\"rule\":\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\"}");
197 config
= ReadFromJSONString(
198 "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
199 "\"BENCHMARK\",\"configs\": [{\"rule\": "
200 "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\", \"trigger_name\":\"foo1\"}, "
201 "{\"rule\": \"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\", "
202 "\"trigger_name\":\"foo2\"}]}");
204 EXPECT_EQ(config
->tracing_mode(), BackgroundTracingConfig::PREEMPTIVE
);
205 EXPECT_EQ(config
->category_preset(), BackgroundTracingConfigImpl::BENCHMARK
);
206 EXPECT_EQ(config
->rules().size(), 2u);
207 EXPECT_EQ(RuleToString(config
->rules()[0]),
208 "{\"rule\":\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\","
209 "\"trigger_name\":\"foo1\"}");
210 EXPECT_EQ(RuleToString(config
->rules()[1]),
211 "{\"rule\":\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\","
212 "\"trigger_name\":\"foo2\"}");
215 TEST_F(BackgroundTracingConfigTest
, ReactiveConfigFromValidString
) {
216 scoped_ptr
<BackgroundTracingConfigImpl
> config
;
218 config
= ReadFromJSONString(
219 "{\"mode\":\"REACTIVE_TRACING_MODE\",\"configs\": [{\"rule\": "
220 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", "
221 "\"category\": \"BENCHMARK\", \"trigger_name\": \"foo\"}]}");
223 EXPECT_EQ(config
->tracing_mode(), BackgroundTracingConfig::REACTIVE
);
224 EXPECT_EQ(config
->rules().size(), 1u);
225 EXPECT_EQ(RuleToString(config
->rules()[0]),
226 "{\"category\":\"BENCHMARK\","
227 "\"rule\":\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\","
228 "\"trigger_name\":\"foo\"}");
230 config
= ReadFromJSONString(
231 "{\"mode\":\"REACTIVE_TRACING_MODE\",\"configs\": [{\"rule\": "
232 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", "
233 "\"category\": \"BENCHMARK_DEEP\", \"trigger_name\": \"foo\"}]}");
235 EXPECT_EQ(config
->tracing_mode(), BackgroundTracingConfig::REACTIVE
);
236 EXPECT_EQ(config
->rules().size(), 1u);
237 EXPECT_EQ(RuleToString(config
->rules()[0]),
238 "{\"category\":\"BENCHMARK_DEEP\","
239 "\"rule\":\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\","
240 "\"trigger_name\":\"foo\"}");
241 config
= ReadFromJSONString(
242 "{\"mode\":\"REACTIVE_TRACING_MODE\",\"configs\": [{\"rule\": "
243 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", "
244 "\"category\": \"BENCHMARK_DEEP\", \"trigger_name\": "
245 "\"foo1\"},{\"rule\": "
246 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", "
247 "\"category\": \"BENCHMARK_DEEP\", \"trigger_name\": \"foo2\"}]}");
249 EXPECT_EQ(config
->tracing_mode(), BackgroundTracingConfig::REACTIVE
);
250 EXPECT_EQ(config
->rules().size(), 2u);
251 EXPECT_EQ(RuleToString(config
->rules()[0]),
252 "{\"category\":\"BENCHMARK_DEEP\","
253 "\"rule\":\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\","
254 "\"trigger_name\":\"foo1\"}");
255 EXPECT_EQ(RuleToString(config
->rules()[1]),
256 "{\"category\":\"BENCHMARK_DEEP\","
257 "\"rule\":\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\","
258 "\"trigger_name\":\"foo2\"}");
259 config
= ReadFromJSONString(
260 "{\"mode\":\"REACTIVE_TRACING_MODE\",\"configs\": [{\"rule\": "
261 "\"TRACE_AT_RANDOM_INTERVALS\",\"category\": \"BENCHMARK_DEEP\","
262 "\"timeout_min\":10, \"timeout_max\":20}]}");
264 EXPECT_EQ(config
->tracing_mode(), BackgroundTracingConfig::REACTIVE
);
265 EXPECT_EQ(config
->rules().size(), 1u);
266 EXPECT_EQ(RuleToString(config
->rules()[0]),
267 "{\"category\":\"BENCHMARK_DEEP\",\"rule\":\"TRACE_AT_RANDOM_"
268 "INTERVALS\",\"timeout_max\":20,\"timeout_min\":10}");
271 TEST_F(BackgroundTracingConfigTest
, ValidPreemptiveConfigToString
) {
272 scoped_ptr
<BackgroundTracingConfigImpl
> config(
273 new BackgroundTracingConfigImpl(BackgroundTracingConfig::PREEMPTIVE
));
276 EXPECT_EQ(ConfigToString(config
.get()),
277 "{\"category\":\"BENCHMARK\",\"configs\":[],\"mode\":\"PREEMPTIVE_"
280 // Change category_preset
281 config
->set_category_preset(BackgroundTracingConfigImpl::BENCHMARK_DEEP
);
282 EXPECT_EQ(ConfigToString(config
.get()),
283 "{\"category\":\"BENCHMARK_DEEP\",\"configs\":[],\"mode\":"
284 "\"PREEMPTIVE_TRACING_MODE\"}");
288 new BackgroundTracingConfigImpl(BackgroundTracingConfig::PREEMPTIVE
));
289 config
->set_category_preset(BackgroundTracingConfigImpl::BENCHMARK_DEEP
);
291 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue());
292 dict
->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
293 dict
->SetString("trigger_name", "foo");
294 config
->AddPreemptiveRule(dict
.get());
296 EXPECT_EQ(ConfigToString(config
.get()),
297 "{\"category\":\"BENCHMARK_DEEP\",\"configs\":[{\"rule\":"
298 "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\",\"trigger_name\":"
299 "\"foo\"}],\"mode\":\"PREEMPTIVE_TRACING_MODE\"}");
304 new BackgroundTracingConfigImpl(BackgroundTracingConfig::PREEMPTIVE
));
305 config
->set_category_preset(BackgroundTracingConfigImpl::BENCHMARK_DEEP
);
307 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue());
308 dict
->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
309 dict
->SetString("trigger_name", "foo1");
310 config
->AddPreemptiveRule(dict
.get());
312 dict
->SetString("trigger_name", "foo2");
313 config
->AddPreemptiveRule(dict
.get());
315 EXPECT_EQ(ConfigToString(config
.get()),
316 "{\"category\":\"BENCHMARK_DEEP\",\"configs\":[{\"rule\":"
317 "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\",\"trigger_name\":"
318 "\"foo1\"},{\"rule\":\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\","
319 "\"trigger_name\":\"foo2\"}],\"mode\":\"PREEMPTIVE_TRACING_"
325 new BackgroundTracingConfigImpl(BackgroundTracingConfig::PREEMPTIVE
));
327 scoped_ptr
<base::DictionaryValue
> second_dict(new base::DictionaryValue());
328 second_dict
->SetString(
329 "rule", "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
330 second_dict
->SetString("histogram_name", "foo");
331 second_dict
->SetInteger("histogram_value", 1);
332 config
->AddPreemptiveRule(second_dict
.get());
334 EXPECT_EQ(ConfigToString(config
.get()),
335 "{\"category\":\"BENCHMARK\",\"configs\":[{\"histogram_name\":"
336 "\"foo\",\"histogram_value\":1,\"rule\":\"MONITOR_AND_DUMP_WHEN_"
337 "SPECIFIC_HISTOGRAM_AND_VALUE\"}],\"mode\":\"PREEMPTIVE_TRACING_"
342 TEST_F(BackgroundTracingConfigTest
, InvalidPreemptiveConfigToString
) {
343 scoped_ptr
<BackgroundTracingConfigImpl
> config
;
347 new BackgroundTracingConfigImpl(BackgroundTracingConfig::PREEMPTIVE
));
349 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue());
350 dict
->SetString("rule", "MONITOR_AND_DUMP_WHEN_BROWSER_STARTUP_COMPLETE");
351 config
->AddPreemptiveRule(dict
.get());
353 EXPECT_EQ(ConfigToString(config
.get()),
354 "{\"category\":\"BENCHMARK\",\"configs\":[],\"mode\":"
355 "\"PREEMPTIVE_TRACING_MODE\"}");
359 TEST_F(BackgroundTracingConfigTest
, ValidReactiveConfigToString
) {
360 scoped_ptr
<BackgroundTracingConfigImpl
> config(
361 new BackgroundTracingConfigImpl(BackgroundTracingConfig::REACTIVE
));
364 EXPECT_EQ(ConfigToString(config
.get()),
365 "{\"configs\":[],\"mode\":\"REACTIVE_TRACING_MODE\"}");
369 new BackgroundTracingConfigImpl(BackgroundTracingConfig::REACTIVE
));
371 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue());
372 dict
->SetString("rule", "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
373 dict
->SetString("trigger_name", "foo");
374 config
->AddReactiveRule(dict
.get(),
375 BackgroundTracingConfigImpl::BENCHMARK_DEEP
);
377 EXPECT_EQ(ConfigToString(config
.get()),
378 "{\"configs\":[{\"category\":\"BENCHMARK_DEEP\",\"rule\":\"TRACE_"
379 "ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\",\"trigger_name\":\"foo\"}]"
380 ",\"mode\":\"REACTIVE_TRACING_MODE\"}");
385 new BackgroundTracingConfigImpl(BackgroundTracingConfig::REACTIVE
));
387 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue());
388 dict
->SetString("rule", "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
389 dict
->SetString("trigger_name", "foo1");
390 config
->AddReactiveRule(dict
.get(),
391 BackgroundTracingConfigImpl::BENCHMARK_DEEP
);
393 dict
->SetString("trigger_name", "foo2");
394 config
->AddReactiveRule(dict
.get(),
395 BackgroundTracingConfigImpl::BENCHMARK_DEEP
);
398 ConfigToString(config
.get()),
399 "{\"configs\":[{\"category\":\"BENCHMARK_DEEP\",\"rule\":\"TRACE_"
400 "ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\",\"trigger_name\":\"foo1\"},{"
401 "\"category\":\"BENCHMARK_DEEP\",\"rule\":"
402 "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\",\"trigger_name\":"
403 "\"foo2\"}],\"mode\":\"REACTIVE_TRACING_MODE\"}");
407 } // namspace content