Roll ANGLE e754fb8..6ffeb74
[chromium-blink-merge.git] / content / browser / tracing / background_tracing_manager_browsertest.cc
blob13a309ecbc34226ee0ac9cbea781c1bea494eb3a
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/trace_event/trace_event.h"
7 #include "content/public/browser/background_tracing_manager.h"
8 #include "content/public/browser/background_tracing_preemptive_config.h"
9 #include "content/public/browser/background_tracing_reactive_config.h"
10 #include "content/public/test/content_browser_test.h"
11 #include "content/public/test/content_browser_test_utils.h"
12 #include "content/public/test/test_utils.h"
13 #include "third_party/zlib/zlib.h"
15 namespace content {
17 class BackgroundTracingManagerBrowserTest : public ContentBrowserTest {
18 public:
19 BackgroundTracingManagerBrowserTest() {}
21 private:
22 DISALLOW_COPY_AND_ASSIGN(BackgroundTracingManagerBrowserTest);
25 class BackgroundTracingManagerUploadConfigWrapper {
26 public:
27 BackgroundTracingManagerUploadConfigWrapper(const base::Closure& callback)
28 : callback_(callback), receive_count_(0) {
29 receive_callback_ =
30 base::Bind(&BackgroundTracingManagerUploadConfigWrapper::Upload,
31 base::Unretained(this));
34 void Upload(const scoped_refptr<base::RefCountedString>& file_contents,
35 base::Callback<void()> done_callback) {
36 receive_count_ += 1;
37 EXPECT_TRUE(file_contents);
39 size_t compressed_length = file_contents->data().length();
40 const size_t kOutputBufferLength = 10 * 1024 * 1024;
41 std::vector<char> output_str(kOutputBufferLength);
43 z_stream stream = {0};
44 stream.avail_in = compressed_length;
45 stream.avail_out = kOutputBufferLength;
46 stream.next_in = (Bytef*)&file_contents->data()[0];
47 stream.next_out = (Bytef*)vector_as_array(&output_str);
49 // 16 + MAX_WBITS means only decoding gzip encoded streams, and using
50 // the biggest window size, according to zlib.h
51 int result = inflateInit2(&stream, 16 + MAX_WBITS);
52 EXPECT_EQ(Z_OK, result);
53 result = inflate(&stream, Z_FINISH);
54 int bytes_written = kOutputBufferLength - stream.avail_out;
56 inflateEnd(&stream);
57 EXPECT_EQ(Z_STREAM_END, result);
59 last_file_contents_.assign(vector_as_array(&output_str), bytes_written);
60 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
61 base::Bind(done_callback));
62 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
63 base::Bind(callback_));
66 bool TraceHasMatchingString(const char* str) {
67 return last_file_contents_.find(str) != std::string::npos;
70 int get_receive_count() const { return receive_count_; }
72 const BackgroundTracingManager::ReceiveCallback& get_receive_callback()
73 const {
74 return receive_callback_;
77 private:
78 BackgroundTracingManager::ReceiveCallback receive_callback_;
79 base::Closure callback_;
80 int receive_count_;
81 std::string last_file_contents_;
84 void StartedFinalizingCallback(base::Closure callback,
85 bool expected,
86 bool value) {
87 EXPECT_EQ(expected, value);
88 if (!callback.is_null())
89 callback.Run();
92 scoped_ptr<BackgroundTracingPreemptiveConfig> CreatePreemptiveConfig() {
93 scoped_ptr<BackgroundTracingPreemptiveConfig> config(
94 new BackgroundTracingPreemptiveConfig());
96 BackgroundTracingPreemptiveConfig::MonitoringRule rule;
97 rule.type =
98 BackgroundTracingPreemptiveConfig::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
99 rule.named_trigger_info.trigger_name = "preemptive_test";
101 config->configs.push_back(rule);
103 return config.Pass();
106 scoped_ptr<BackgroundTracingReactiveConfig> CreateReactiveConfig() {
107 scoped_ptr<BackgroundTracingReactiveConfig> config(
108 new BackgroundTracingReactiveConfig());
110 BackgroundTracingReactiveConfig::TracingRule rule;
111 rule.type =
112 BackgroundTracingReactiveConfig::TRACE_FOR_10S_OR_TRIGGER_OR_FULL;
113 rule.trigger_name = "reactive_test";
114 rule.category_preset =
115 BackgroundTracingConfig::CategoryPreset::BENCHMARK_DEEP;
117 config->configs.push_back(rule);
119 return config.Pass();
122 void SetupBackgroundTracingManager() {
123 content::BackgroundTracingManager::GetInstance()
124 ->InvalidateTriggerHandlesForTesting();
127 void DisableScenarioWhenIdle() {
128 BackgroundTracingManager::GetInstance()->SetActiveScenario(
129 NULL, BackgroundTracingManager::ReceiveCallback(),
130 BackgroundTracingManager::NO_DATA_FILTERING);
133 // This tests that the endpoint receives the final trace data.
134 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
135 ReceiveTraceFinalContentsOnTrigger) {
137 SetupBackgroundTracingManager();
139 base::RunLoop run_loop;
140 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
141 run_loop.QuitClosure());
143 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
144 CreatePreemptiveConfig();
146 BackgroundTracingManager::TriggerHandle handle =
147 BackgroundTracingManager::
148 GetInstance()->RegisterTriggerType("preemptive_test");
150 BackgroundTracingManager::GetInstance()->SetActiveScenario(
151 config.Pass(), upload_config_wrapper.get_receive_callback(),
152 BackgroundTracingManager::NO_DATA_FILTERING);
154 BackgroundTracingManager::GetInstance()->WhenIdle(
155 base::Bind(&DisableScenarioWhenIdle));
157 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
158 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
160 run_loop.Run();
162 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
166 // This tests triggering more than once still only gathers once.
167 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
168 CallTriggersMoreThanOnceOnlyGatherOnce) {
170 SetupBackgroundTracingManager();
172 base::RunLoop run_loop;
173 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
174 run_loop.QuitClosure());
176 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
177 CreatePreemptiveConfig();
179 content::BackgroundTracingManager::TriggerHandle handle =
180 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
181 "preemptive_test");
183 BackgroundTracingManager::GetInstance()->SetActiveScenario(
184 config.Pass(), upload_config_wrapper.get_receive_callback(),
185 BackgroundTracingManager::NO_DATA_FILTERING);
187 BackgroundTracingManager::GetInstance()->WhenIdle(
188 base::Bind(&DisableScenarioWhenIdle));
190 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
191 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
192 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
193 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), false));
195 run_loop.Run();
197 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
201 namespace {
203 bool IsTraceEventArgsWhitelisted(const char* category_group_name,
204 const char* event_name) {
205 if (MatchPattern(category_group_name, "benchmark") &&
206 MatchPattern(event_name, "whitelisted")) {
207 return true;
210 return false;
213 } // namespace
215 // This tests that non-whitelisted args get stripped if required.
216 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
217 NoWhitelistedArgsStripped) {
218 SetupBackgroundTracingManager();
220 base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
221 base::Bind(&IsTraceEventArgsWhitelisted));
223 base::RunLoop wait_for_upload;
224 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
225 wait_for_upload.QuitClosure());
227 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
228 CreatePreemptiveConfig();
230 content::BackgroundTracingManager::TriggerHandle handle =
231 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
232 "preemptive_test");
234 base::RunLoop wait_for_activated;
235 BackgroundTracingManager::GetInstance()->SetTracingEnabledCallbackForTesting(
236 wait_for_activated.QuitClosure());
237 EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
238 config.Pass(), upload_config_wrapper.get_receive_callback(),
239 BackgroundTracingManager::ANONYMIZE_DATA));
241 wait_for_activated.Run();
243 TRACE_EVENT1("benchmark", "whitelisted", "find_this", 1);
244 TRACE_EVENT1("benchmark", "not_whitelisted", "this_not_found", 1);
246 BackgroundTracingManager::GetInstance()->WhenIdle(
247 base::Bind(&DisableScenarioWhenIdle));
249 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
250 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
252 wait_for_upload.Run();
254 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
255 EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("{"));
256 EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("find_this"));
257 EXPECT_TRUE(!upload_config_wrapper.TraceHasMatchingString("this_not_found"));
260 // This tests subprocesses (like a navigating renderer) which gets told to
261 // provide a argument-filtered trace and has no predicate in place to do the
262 // filtering (in this case, only the browser process gets it set), will crash
263 // rather than return potential PII.
264 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
265 CrashWhenSubprocessWithoutArgumentFilter) {
266 SetupBackgroundTracingManager();
268 base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
269 base::Bind(&IsTraceEventArgsWhitelisted));
271 base::RunLoop wait_for_upload;
272 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
273 wait_for_upload.QuitClosure());
275 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
276 CreatePreemptiveConfig();
278 content::BackgroundTracingManager::TriggerHandle handle =
279 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
280 "preemptive_test");
282 base::RunLoop wait_for_activated;
283 BackgroundTracingManager::GetInstance()->SetTracingEnabledCallbackForTesting(
284 wait_for_activated.QuitClosure());
285 EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
286 config.Pass(), upload_config_wrapper.get_receive_callback(),
287 BackgroundTracingManager::ANONYMIZE_DATA));
289 wait_for_activated.Run();
291 NavigateToURL(shell(), GetTestUrl("", "about:blank"));
293 BackgroundTracingManager::GetInstance()->WhenIdle(
294 base::Bind(&DisableScenarioWhenIdle));
296 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
297 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
299 wait_for_upload.Run();
301 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
302 // We should *not* receive anything at all from the renderer,
303 // the process should've crashed rather than letting that happen.
304 EXPECT_TRUE(!upload_config_wrapper.TraceHasMatchingString("CrRendererMain"));
307 // This tests multiple triggers still only gathers once.
308 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
309 CallMultipleTriggersOnlyGatherOnce) {
311 SetupBackgroundTracingManager();
313 base::RunLoop run_loop;
314 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
315 run_loop.QuitClosure());
317 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
318 CreatePreemptiveConfig();
320 BackgroundTracingPreemptiveConfig::MonitoringRule rule;
321 rule.type =
322 BackgroundTracingPreemptiveConfig::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
323 rule.named_trigger_info.trigger_name = "test1";
324 config->configs.push_back(rule);
326 rule.named_trigger_info.trigger_name = "test2";
327 config->configs.push_back(rule);
329 BackgroundTracingManager::TriggerHandle handle1 =
330 BackgroundTracingManager::GetInstance()->RegisterTriggerType("test1");
331 BackgroundTracingManager::TriggerHandle handle2 =
332 BackgroundTracingManager::GetInstance()->RegisterTriggerType("test2");
334 BackgroundTracingManager::GetInstance()->SetActiveScenario(
335 config.Pass(), upload_config_wrapper.get_receive_callback(),
336 BackgroundTracingManager::NO_DATA_FILTERING);
338 BackgroundTracingManager::GetInstance()->WhenIdle(
339 base::Bind(&DisableScenarioWhenIdle));
341 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
342 handle1, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
343 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
344 handle2,
345 base::Bind(&StartedFinalizingCallback, base::Closure(), false));
347 run_loop.Run();
349 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
353 // This tests that you can't trigger without a scenario set.
354 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
355 CannotTriggerWithoutScenarioSet) {
357 SetupBackgroundTracingManager();
359 base::RunLoop run_loop;
360 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
361 (base::Closure()));
363 scoped_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();
365 content::BackgroundTracingManager::TriggerHandle handle =
366 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
367 "preemptive_test");
369 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
370 handle,
371 base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
373 run_loop.Run();
375 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
379 // This tests that no trace is triggered with a handle that isn't specified
380 // in the config.
381 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
382 DoesNotTriggerWithWrongHandle) {
384 SetupBackgroundTracingManager();
386 base::RunLoop run_loop;
387 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
388 (base::Closure()));
390 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
391 CreatePreemptiveConfig();
393 content::BackgroundTracingManager::TriggerHandle handle =
394 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
395 "does_not_exist");
397 BackgroundTracingManager::GetInstance()->SetActiveScenario(
398 config.Pass(), upload_config_wrapper.get_receive_callback(),
399 BackgroundTracingManager::NO_DATA_FILTERING);
401 BackgroundTracingManager::GetInstance()->WhenIdle(
402 base::Bind(&DisableScenarioWhenIdle));
404 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
405 handle,
406 base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
408 run_loop.Run();
410 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
414 // This tests that no trace is triggered with an invalid handle.
415 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
416 DoesNotTriggerWithInvalidHandle) {
418 SetupBackgroundTracingManager();
420 base::RunLoop run_loop;
421 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
422 (base::Closure()));
424 scoped_ptr<BackgroundTracingPreemptiveConfig> config =
425 CreatePreemptiveConfig();
427 content::BackgroundTracingManager::TriggerHandle handle =
428 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
429 "preemptive_test");
431 content::BackgroundTracingManager::GetInstance()
432 ->InvalidateTriggerHandlesForTesting();
434 BackgroundTracingManager::GetInstance()->SetActiveScenario(
435 config.Pass(), upload_config_wrapper.get_receive_callback(),
436 BackgroundTracingManager::NO_DATA_FILTERING);
438 BackgroundTracingManager::GetInstance()->WhenIdle(
439 base::Bind(&DisableScenarioWhenIdle));
441 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
442 handle,
443 base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
445 run_loop.Run();
447 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
451 // This tests that preemptive mode configs will fail.
452 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
453 DoesNotAllowPreemptiveConfigThatsNotManual) {
455 SetupBackgroundTracingManager();
457 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
458 (base::Closure()));
460 scoped_ptr<BackgroundTracingPreemptiveConfig> config(
461 new content::BackgroundTracingPreemptiveConfig());
463 BackgroundTracingPreemptiveConfig::MonitoringRule rule;
464 rule.type = BackgroundTracingPreemptiveConfig::
465 MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE;
466 rule.histogram_trigger_info.histogram_name_to_trigger_on = "fake";
467 rule.histogram_trigger_info.histogram_bin_to_trigger_on = 0;
468 config->configs.push_back(rule);
470 bool result = BackgroundTracingManager::GetInstance()->SetActiveScenario(
471 config.Pass(), upload_config_wrapper.get_receive_callback(),
472 BackgroundTracingManager::NO_DATA_FILTERING);
474 EXPECT_FALSE(result);
478 // This tests that reactive mode records and terminates with timeout.
479 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
480 ReactiveTimeoutTermination) {
482 SetupBackgroundTracingManager();
484 base::RunLoop run_loop;
485 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
486 run_loop.QuitClosure());
488 scoped_ptr<BackgroundTracingReactiveConfig> config =
489 CreateReactiveConfig();
491 BackgroundTracingManager::TriggerHandle handle =
492 BackgroundTracingManager::
493 GetInstance()->RegisterTriggerType("reactive_test");
495 BackgroundTracingManager::GetInstance()->SetActiveScenario(
496 config.Pass(), upload_config_wrapper.get_receive_callback(),
497 BackgroundTracingManager::NO_DATA_FILTERING);
499 BackgroundTracingManager::GetInstance()->WhenIdle(
500 base::Bind(&DisableScenarioWhenIdle));
502 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
503 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
505 BackgroundTracingManager::GetInstance()->FireTimerForTesting();
507 run_loop.Run();
509 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
513 // This tests that reactive mode records and terminates with a second trigger.
514 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
515 ReactiveSecondTriggerTermination) {
517 SetupBackgroundTracingManager();
519 base::RunLoop run_loop;
520 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
521 run_loop.QuitClosure());
523 scoped_ptr<BackgroundTracingReactiveConfig> config =
524 CreateReactiveConfig();
526 BackgroundTracingManager::TriggerHandle handle =
527 BackgroundTracingManager::
528 GetInstance()->RegisterTriggerType("reactive_test");
530 BackgroundTracingManager::GetInstance()->SetActiveScenario(
531 config.Pass(), upload_config_wrapper.get_receive_callback(),
532 BackgroundTracingManager::NO_DATA_FILTERING);
534 BackgroundTracingManager::GetInstance()->WhenIdle(
535 base::Bind(&DisableScenarioWhenIdle));
537 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
538 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
539 // second trigger to terminate.
540 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
541 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
543 run_loop.Run();
545 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
549 // This tests a third trigger in reactive more does not start another trace.
550 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
551 ReactiveThirdTriggerTimeout) {
553 SetupBackgroundTracingManager();
555 base::RunLoop run_loop;
556 BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
557 run_loop.QuitClosure());
559 scoped_ptr<BackgroundTracingReactiveConfig> config =
560 CreateReactiveConfig();
562 BackgroundTracingManager::TriggerHandle handle =
563 BackgroundTracingManager::
564 GetInstance()->RegisterTriggerType("reactive_test");
566 BackgroundTracingManager::GetInstance()->SetActiveScenario(
567 config.Pass(), upload_config_wrapper.get_receive_callback(),
568 BackgroundTracingManager::NO_DATA_FILTERING);
570 BackgroundTracingManager::GetInstance()->WhenIdle(
571 base::Bind(&DisableScenarioWhenIdle));
573 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
574 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
575 // second trigger to terminate.
576 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
577 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
578 // third trigger to trigger again, fails as it is still gathering.
579 BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
580 handle, base::Bind(&StartedFinalizingCallback, base::Closure(), false));
582 run_loop.Run();
584 EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
588 } // namespace content