Move MatchPattern to its own header and the base namespace.
[chromium-blink-merge.git] / content / browser / tracing / background_tracing_manager_browsertest.cc
blobab408454452c96edbba03eaa06bb68d7d1a6102e
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/bind.h"
6 #include "base/strings/pattern.h"
7 #include "base/trace_event/trace_event.h"
8 #include "content/public/browser/background_tracing_manager.h"
9 #include "content/public/browser/background_tracing_preemptive_config.h"
10 #include "content/public/browser/background_tracing_reactive_config.h"
11 #include "content/public/test/content_browser_test.h"
12 #include "content/public/test/content_browser_test_utils.h"
13 #include "content/public/test/test_utils.h"
14 #include "third_party/zlib/zlib.h"
16 namespace content {
18 class BackgroundTracingManagerBrowserTest : public ContentBrowserTest {
19 public:
20 BackgroundTracingManagerBrowserTest() {}
22 private:
23 DISALLOW_COPY_AND_ASSIGN(BackgroundTracingManagerBrowserTest);
26 class BackgroundTracingManagerUploadConfigWrapper {
27 public:
28 BackgroundTracingManagerUploadConfigWrapper(const base::Closure& callback)
29 : callback_(callback), receive_count_(0) {
30 receive_callback_ =
31 base::Bind(&BackgroundTracingManagerUploadConfigWrapper::Upload,
32 base::Unretained(this));
35 void Upload(const scoped_refptr<base::RefCountedString>& file_contents,
36 scoped_ptr<base::DictionaryValue> metadata,
37 base::Callback<void()> done_callback) {
38 receive_count_ += 1;
39 EXPECT_TRUE(file_contents);
41 size_t compressed_length = file_contents->data().length();
42 const size_t kOutputBufferLength = 10 * 1024 * 1024;
43 std::vector<char> output_str(kOutputBufferLength);
45 z_stream stream = {0};
46 stream.avail_in = compressed_length;
47 stream.avail_out = kOutputBufferLength;
48 stream.next_in = (Bytef*)&file_contents->data()[0];
49 stream.next_out = (Bytef*)vector_as_array(&output_str);
51 // 16 + MAX_WBITS means only decoding gzip encoded streams, and using
52 // the biggest window size, according to zlib.h
53 int result = inflateInit2(&stream, 16 + MAX_WBITS);
54 EXPECT_EQ(Z_OK, result);
55 result = inflate(&stream, Z_FINISH);
56 int bytes_written = kOutputBufferLength - stream.avail_out;
58 inflateEnd(&stream);
59 EXPECT_EQ(Z_STREAM_END, result);
61 last_file_contents_.assign(vector_as_array(&output_str), bytes_written);
62 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
63 base::Bind(done_callback));
64 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
65 base::Bind(callback_));
68 bool TraceHasMatchingString(const char* str) {
69 return last_file_contents_.find(str) != std::string::npos;
72 int get_receive_count() const { return receive_count_; }
74 const BackgroundTracingManager::ReceiveCallback& get_receive_callback()
75 const {
76 return receive_callback_;
79 private:
80 BackgroundTracingManager::ReceiveCallback receive_callback_;
81 base::Closure callback_;
82 int receive_count_;
83 std::string last_file_contents_;
86 void StartedFinalizingCallback(base::Closure callback,
87 bool expected,
88 bool value) {
89 EXPECT_EQ(expected, value);
90 if (!callback.is_null())
91 callback.Run();
94 scoped_ptr<BackgroundTracingPreemptiveConfig> CreatePreemptiveConfig() {
95 scoped_ptr<BackgroundTracingPreemptiveConfig> config(
96 new BackgroundTracingPreemptiveConfig());
98 BackgroundTracingPreemptiveConfig::MonitoringRule rule;
99 rule.type =
100 BackgroundTracingPreemptiveConfig::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
101 rule.named_trigger_info.trigger_name = "preemptive_test";
103 config->configs.push_back(rule);
105 return config.Pass();
108 scoped_ptr<BackgroundTracingReactiveConfig> CreateReactiveConfig() {
109 scoped_ptr<BackgroundTracingReactiveConfig> config(
110 new BackgroundTracingReactiveConfig());
112 BackgroundTracingReactiveConfig::TracingRule rule;
113 rule.type =
114 BackgroundTracingReactiveConfig::TRACE_FOR_10S_OR_TRIGGER_OR_FULL;
115 rule.trigger_name = "reactive_test";
116 rule.category_preset =
117 BackgroundTracingConfig::CategoryPreset::BENCHMARK_DEEP;
119 config->configs.push_back(rule);
121 return config.Pass();
124 void SetupBackgroundTracingManager() {
125 content::BackgroundTracingManager::GetInstance()
126 ->InvalidateTriggerHandlesForTesting();
129 void DisableScenarioWhenIdle() {
130 BackgroundTracingManager::GetInstance()->SetActiveScenario(
131 NULL, BackgroundTracingManager::ReceiveCallback(),
132 BackgroundTracingManager::NO_DATA_FILTERING);
135 // This tests that the endpoint receives the final trace data.
136 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
137 ReceiveTraceFinalContentsOnTrigger) {
139 SetupBackgroundTracingManager();
141 base::RunLoop run_loop;
142 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
143 run_loop.QuitClosure());
145 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
146 CreatePreemptiveConfig();
148 BackgroundTracingManager::TriggerHandle handle =
149 BackgroundTracingManager::
150 GetInstance()->RegisterTriggerType("preemptive_test");
152 BackgroundTracingManager::GetInstance()->SetActiveScenario(
153 config.Pass(), upload_config_wrapper.get_receive_callback(),
154 BackgroundTracingManager::NO_DATA_FILTERING);
156 BackgroundTracingManager::GetInstance()->WhenIdle(
157 base::Bind(&DisableScenarioWhenIdle));
159 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
160 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
162 run_loop.Run();
164 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
168 // This tests triggering more than once still only gathers once.
169 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
170 CallTriggersMoreThanOnceOnlyGatherOnce) {
172 SetupBackgroundTracingManager();
174 base::RunLoop run_loop;
175 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
176 run_loop.QuitClosure());
178 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
179 CreatePreemptiveConfig();
181 content::BackgroundTracingManager::TriggerHandle handle =
182 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
183 "preemptive_test");
185 BackgroundTracingManager::GetInstance()->SetActiveScenario(
186 config.Pass(), upload_config_wrapper.get_receive_callback(),
187 BackgroundTracingManager::NO_DATA_FILTERING);
189 BackgroundTracingManager::GetInstance()->WhenIdle(
190 base::Bind(&DisableScenarioWhenIdle));
192 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
193 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
194 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
195 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), false));
197 run_loop.Run();
199 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
203 namespace {
205 bool IsTraceEventArgsWhitelisted(const char* category_group_name,
206 const char* event_name) {
207 if (base::MatchPattern(category_group_name, "benchmark") &&
208 base::MatchPattern(event_name, "whitelisted")) {
209 return true;
212 return false;
215 } // namespace
217 // This tests that non-whitelisted args get stripped if required.
218 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
219 NoWhitelistedArgsStripped) {
220 SetupBackgroundTracingManager();
222 base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
223 base::Bind(&IsTraceEventArgsWhitelisted));
225 base::RunLoop wait_for_upload;
226 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
227 wait_for_upload.QuitClosure());
229 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
230 CreatePreemptiveConfig();
232 content::BackgroundTracingManager::TriggerHandle handle =
233 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
234 "preemptive_test");
236 base::RunLoop wait_for_activated;
237 BackgroundTracingManager::GetInstance()->SetTracingEnabledCallbackForTesting(
238 wait_for_activated.QuitClosure());
239 EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
240 config.Pass(), upload_config_wrapper.get_receive_callback(),
241 BackgroundTracingManager::ANONYMIZE_DATA));
243 wait_for_activated.Run();
245 TRACE_EVENT1("benchmark", "whitelisted", "find_this", 1);
246 TRACE_EVENT1("benchmark", "not_whitelisted", "this_not_found", 1);
248 BackgroundTracingManager::GetInstance()->WhenIdle(
249 base::Bind(&DisableScenarioWhenIdle));
251 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
252 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
254 wait_for_upload.Run();
256 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
257 EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("{"));
258 EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("find_this"));
259 EXPECT_TRUE(!upload_config_wrapper.TraceHasMatchingString("this_not_found"));
262 // This tests subprocesses (like a navigating renderer) which gets told to
263 // provide a argument-filtered trace and has no predicate in place to do the
264 // filtering (in this case, only the browser process gets it set), will crash
265 // rather than return potential PII.
266 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
267 CrashWhenSubprocessWithoutArgumentFilter) {
268 SetupBackgroundTracingManager();
270 base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
271 base::Bind(&IsTraceEventArgsWhitelisted));
273 base::RunLoop wait_for_upload;
274 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
275 wait_for_upload.QuitClosure());
277 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
278 CreatePreemptiveConfig();
280 content::BackgroundTracingManager::TriggerHandle handle =
281 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
282 "preemptive_test");
284 base::RunLoop wait_for_activated;
285 BackgroundTracingManager::GetInstance()->SetTracingEnabledCallbackForTesting(
286 wait_for_activated.QuitClosure());
287 EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
288 config.Pass(), upload_config_wrapper.get_receive_callback(),
289 BackgroundTracingManager::ANONYMIZE_DATA));
291 wait_for_activated.Run();
293 NavigateToURL(shell(), GetTestUrl("", "about:blank"));
295 BackgroundTracingManager::GetInstance()->WhenIdle(
296 base::Bind(&DisableScenarioWhenIdle));
298 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
299 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
301 wait_for_upload.Run();
303 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
304 // We should *not* receive anything at all from the renderer,
305 // the process should've crashed rather than letting that happen.
306 EXPECT_TRUE(!upload_config_wrapper.TraceHasMatchingString("CrRendererMain"));
309 // This tests multiple triggers still only gathers once.
310 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
311 CallMultipleTriggersOnlyGatherOnce) {
313 SetupBackgroundTracingManager();
315 base::RunLoop run_loop;
316 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
317 run_loop.QuitClosure());
319 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
320 CreatePreemptiveConfig();
322 BackgroundTracingPreemptiveConfig::MonitoringRule rule;
323 rule.type =
324 BackgroundTracingPreemptiveConfig::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
325 rule.named_trigger_info.trigger_name = "test1";
326 config->configs.push_back(rule);
328 rule.named_trigger_info.trigger_name = "test2";
329 config->configs.push_back(rule);
331 BackgroundTracingManager::TriggerHandle handle1 =
332 BackgroundTracingManager::GetInstance()->RegisterTriggerType("test1");
333 BackgroundTracingManager::TriggerHandle handle2 =
334 BackgroundTracingManager::GetInstance()->RegisterTriggerType("test2");
336 BackgroundTracingManager::GetInstance()->SetActiveScenario(
337 config.Pass(), upload_config_wrapper.get_receive_callback(),
338 BackgroundTracingManager::NO_DATA_FILTERING);
340 BackgroundTracingManager::GetInstance()->WhenIdle(
341 base::Bind(&DisableScenarioWhenIdle));
343 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
344 handle1, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
345 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
346 handle2,
347 base::Bind(&StartedFinalizingCallback, base::Closure(), false));
349 run_loop.Run();
351 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
355 // This tests that you can't trigger without a scenario set.
356 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
357 CannotTriggerWithoutScenarioSet) {
359 SetupBackgroundTracingManager();
361 base::RunLoop run_loop;
362 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
363 (base::Closure()));
365 scoped_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();
367 content::BackgroundTracingManager::TriggerHandle handle =
368 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
369 "preemptive_test");
371 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
372 handle,
373 base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
375 run_loop.Run();
377 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
381 // This tests that no trace is triggered with a handle that isn't specified
382 // in the config.
383 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
384 DoesNotTriggerWithWrongHandle) {
386 SetupBackgroundTracingManager();
388 base::RunLoop run_loop;
389 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
390 (base::Closure()));
392 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
393 CreatePreemptiveConfig();
395 content::BackgroundTracingManager::TriggerHandle handle =
396 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
397 "does_not_exist");
399 BackgroundTracingManager::GetInstance()->SetActiveScenario(
400 config.Pass(), upload_config_wrapper.get_receive_callback(),
401 BackgroundTracingManager::NO_DATA_FILTERING);
403 BackgroundTracingManager::GetInstance()->WhenIdle(
404 base::Bind(&DisableScenarioWhenIdle));
406 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
407 handle,
408 base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
410 run_loop.Run();
412 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
416 // This tests that no trace is triggered with an invalid handle.
417 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
418 DoesNotTriggerWithInvalidHandle) {
420 SetupBackgroundTracingManager();
422 base::RunLoop run_loop;
423 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
424 (base::Closure()));
426 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
427 CreatePreemptiveConfig();
429 content::BackgroundTracingManager::TriggerHandle handle =
430 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
431 "preemptive_test");
433 content::BackgroundTracingManager::GetInstance()
434 ->InvalidateTriggerHandlesForTesting();
436 BackgroundTracingManager::GetInstance()->SetActiveScenario(
437 config.Pass(), upload_config_wrapper.get_receive_callback(),
438 BackgroundTracingManager::NO_DATA_FILTERING);
440 BackgroundTracingManager::GetInstance()->WhenIdle(
441 base::Bind(&DisableScenarioWhenIdle));
443 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
444 handle,
445 base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
447 run_loop.Run();
449 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
453 // This tests that preemptive mode configs will fail.
454 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
455 DoesNotAllowPreemptiveConfigThatsNotManual) {
457 SetupBackgroundTracingManager();
459 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
460 (base::Closure()));
462 scoped_ptr<BackgroundTracingPreemptiveConfig> config(
463 new content::BackgroundTracingPreemptiveConfig());
465 BackgroundTracingPreemptiveConfig::MonitoringRule rule;
466 rule.type = BackgroundTracingPreemptiveConfig::
467 MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE;
468 rule.histogram_trigger_info.histogram_name_to_trigger_on = "fake";
469 rule.histogram_trigger_info.histogram_bin_to_trigger_on = 0;
470 config->configs.push_back(rule);
472 bool result = BackgroundTracingManager::GetInstance()->SetActiveScenario(
473 config.Pass(), upload_config_wrapper.get_receive_callback(),
474 BackgroundTracingManager::NO_DATA_FILTERING);
476 EXPECT_FALSE(result);
480 // This tests that reactive mode records and terminates with timeout.
481 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
482 ReactiveTimeoutTermination) {
484 SetupBackgroundTracingManager();
486 base::RunLoop run_loop;
487 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
488 run_loop.QuitClosure());
490 scoped_ptr<BackgroundTracingReactiveConfig> config =
491 CreateReactiveConfig();
493 BackgroundTracingManager::TriggerHandle handle =
494 BackgroundTracingManager::
495 GetInstance()->RegisterTriggerType("reactive_test");
497 BackgroundTracingManager::GetInstance()->SetActiveScenario(
498 config.Pass(), upload_config_wrapper.get_receive_callback(),
499 BackgroundTracingManager::NO_DATA_FILTERING);
501 BackgroundTracingManager::GetInstance()->WhenIdle(
502 base::Bind(&DisableScenarioWhenIdle));
504 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
505 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
507 BackgroundTracingManager::GetInstance()->FireTimerForTesting();
509 run_loop.Run();
511 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
515 // This tests that reactive mode records and terminates with a second trigger.
516 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
517 ReactiveSecondTriggerTermination) {
519 SetupBackgroundTracingManager();
521 base::RunLoop run_loop;
522 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
523 run_loop.QuitClosure());
525 scoped_ptr<BackgroundTracingReactiveConfig> config =
526 CreateReactiveConfig();
528 BackgroundTracingManager::TriggerHandle handle =
529 BackgroundTracingManager::
530 GetInstance()->RegisterTriggerType("reactive_test");
532 BackgroundTracingManager::GetInstance()->SetActiveScenario(
533 config.Pass(), upload_config_wrapper.get_receive_callback(),
534 BackgroundTracingManager::NO_DATA_FILTERING);
536 BackgroundTracingManager::GetInstance()->WhenIdle(
537 base::Bind(&DisableScenarioWhenIdle));
539 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
540 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
541 // second trigger to terminate.
542 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
543 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
545 run_loop.Run();
547 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
551 // This tests a third trigger in reactive more does not start another trace.
552 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
553 ReactiveThirdTriggerTimeout) {
555 SetupBackgroundTracingManager();
557 base::RunLoop run_loop;
558 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
559 run_loop.QuitClosure());
561 scoped_ptr<BackgroundTracingReactiveConfig> config =
562 CreateReactiveConfig();
564 BackgroundTracingManager::TriggerHandle handle =
565 BackgroundTracingManager::
566 GetInstance()->RegisterTriggerType("reactive_test");
568 BackgroundTracingManager::GetInstance()->SetActiveScenario(
569 config.Pass(), upload_config_wrapper.get_receive_callback(),
570 BackgroundTracingManager::NO_DATA_FILTERING);
572 BackgroundTracingManager::GetInstance()->WhenIdle(
573 base::Bind(&DisableScenarioWhenIdle));
575 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
576 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
577 // second trigger to terminate.
578 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
579 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
580 // third trigger to trigger again, fails as it is still gathering.
581 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
582 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), false));
584 run_loop.Run();
586 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
590 } // namespace content