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.
6 #include "base/command_line.h"
7 #include "base/prefs/pref_service.h"
8 #include "chrome/app/chrome_command_ids.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/tracing/background_tracing_field_trial.h"
11 #include "chrome/browser/ui/browser_commands.h"
12 #include "chrome/browser/ui/browser_list.h"
13 #include "chrome/common/chrome_switches.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/in_process_browser_test.h"
16 #include "content/public/browser/background_tracing_config.h"
17 #include "content/public/browser/background_tracing_manager.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/test/test_utils.h"
23 class ChromeTracingDelegateBrowserTest
: public InProcessBrowserTest
{
25 ChromeTracingDelegateBrowserTest()
27 started_finalizations_count_(0),
28 last_on_started_finalizing_success_(false) {}
30 bool StartPreemptiveScenario(
31 const base::Closure
& on_upload_callback
,
32 content::BackgroundTracingManager::DataFiltering data_filtering
) {
33 on_upload_callback_
= on_upload_callback
;
35 base::DictionaryValue dict
;
37 dict
.SetString("mode", "PREEMPTIVE_TRACING_MODE");
38 dict
.SetString("category", "BENCHMARK");
40 scoped_ptr
<base::ListValue
> rules_list(new base::ListValue());
42 scoped_ptr
<base::DictionaryValue
> rules_dict(new base::DictionaryValue());
43 rules_dict
->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
44 rules_dict
->SetString("trigger_name", "test");
45 rules_list
->Append(rules_dict
.Pass());
47 dict
.Set("configs", rules_list
.Pass());
49 scoped_ptr
<content::BackgroundTracingConfig
> config(
50 content::BackgroundTracingConfig::FromDict(&dict
));
53 content::BackgroundTracingManager::ReceiveCallback receive_callback
=
54 base::Bind(&ChromeTracingDelegateBrowserTest::OnUpload
,
55 base::Unretained(this));
57 return content::BackgroundTracingManager::GetInstance()->SetActiveScenario(
58 config
.Pass(), receive_callback
, data_filtering
);
61 void TriggerReactiveScenario(
62 const base::Closure
& on_started_finalization_callback
) {
63 on_started_finalization_callback_
= on_started_finalization_callback
;
65 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
68 content::BackgroundTracingManager::StartedFinalizingCallback
69 started_finalizing_callback
=
70 base::Bind(&ChromeTracingDelegateBrowserTest::OnStartedFinalizing
,
71 base::Unretained(this));
72 content::BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
73 trigger_handle_
, started_finalizing_callback
);
76 int get_receive_count() const { return receive_count_
; }
77 bool get_started_finalizations() const {
78 return started_finalizations_count_
;
80 bool get_last_started_finalization_success() const {
81 return last_on_started_finalizing_success_
;
85 void OnUpload(const scoped_refptr
<base::RefCountedString
>& file_contents
,
86 scoped_ptr
<base::DictionaryValue
> metadata
,
87 base::Callback
<void()> done_callback
) {
90 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
91 base::Bind(done_callback
));
92 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
93 base::Bind(on_upload_callback_
));
96 void OnStartedFinalizing(bool success
) {
97 started_finalizations_count_
++;
98 last_on_started_finalizing_success_
= success
;
100 if (!on_started_finalization_callback_
.is_null()) {
101 content::BrowserThread::PostTask(
102 content::BrowserThread::UI
, FROM_HERE
,
103 base::Bind(on_started_finalization_callback_
));
107 base::Closure on_upload_callback_
;
108 base::Closure on_started_finalization_callback_
;
110 int started_finalizations_count_
;
111 content::BackgroundTracingManager::TriggerHandle trigger_handle_
;
112 bool last_on_started_finalizing_success_
;
115 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest
,
116 BackgroundTracingTimeThrottled
) {
117 base::RunLoop wait_for_upload
;
119 EXPECT_TRUE(StartPreemptiveScenario(
120 wait_for_upload
.QuitClosure(),
121 content::BackgroundTracingManager::NO_DATA_FILTERING
));
123 TriggerReactiveScenario(base::Closure());
125 wait_for_upload
.Run();
127 EXPECT_TRUE(get_receive_count() == 1);
129 PrefService
* local_state
= g_browser_process
->local_state();
131 const base::Time last_upload_time
= base::Time::FromInternalValue(
132 local_state
->GetInt64(prefs::kBackgroundTracingLastUpload
));
133 EXPECT_FALSE(last_upload_time
.is_null());
135 // We should not be able to start a new reactive scenario immediately after
136 // a previous one gets uploaded.
137 EXPECT_FALSE(StartPreemptiveScenario(
138 base::Closure(), content::BackgroundTracingManager::NO_DATA_FILTERING
));
141 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest
,
142 BackgroundTracingThrottleTimeElapsed
) {
143 base::RunLoop wait_for_upload
;
145 EXPECT_TRUE(StartPreemptiveScenario(
146 wait_for_upload
.QuitClosure(),
147 content::BackgroundTracingManager::NO_DATA_FILTERING
));
149 TriggerReactiveScenario(base::Closure());
151 wait_for_upload
.Run();
153 EXPECT_TRUE(get_receive_count() == 1);
155 PrefService
* local_state
= g_browser_process
->local_state();
157 const base::Time last_upload_time
= base::Time::FromInternalValue(
158 local_state
->GetInt64(prefs::kBackgroundTracingLastUpload
));
159 EXPECT_FALSE(last_upload_time
.is_null());
161 // We move the last upload time to eight days in the past,
162 // and at that point should be able to start a scenario again.
163 base::Time new_upload_time
= last_upload_time
- base::TimeDelta::FromDays(8);
164 local_state
->SetInt64(prefs::kBackgroundTracingLastUpload
,
165 new_upload_time
.ToInternalValue());
166 EXPECT_TRUE(StartPreemptiveScenario(
167 base::Closure(), content::BackgroundTracingManager::NO_DATA_FILTERING
));
170 // If we need a PII-stripped trace, any existing OTR session should block the
172 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest
,
173 ExistingIncognitoSessionBlockingTraceStart
) {
174 EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_NEW_INCOGNITO_WINDOW
));
175 EXPECT_TRUE(BrowserList::IsOffTheRecordSessionActive());
176 EXPECT_FALSE(StartPreemptiveScenario(
177 base::Closure(), content::BackgroundTracingManager::ANONYMIZE_DATA
));
180 // If we need a PII-stripped trace, any new OTR session during tracing should
181 // block the finalization of the trace.
182 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest
,
183 NewIncognitoSessionBlockingTraceFinalization
) {
184 EXPECT_TRUE(StartPreemptiveScenario(
185 base::Closure(), content::BackgroundTracingManager::ANONYMIZE_DATA
));
187 EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_NEW_INCOGNITO_WINDOW
));
188 EXPECT_TRUE(BrowserList::IsOffTheRecordSessionActive());
190 base::RunLoop wait_for_finalization_start
;
191 TriggerReactiveScenario(wait_for_finalization_start
.QuitClosure());
192 wait_for_finalization_start
.Run();
194 EXPECT_TRUE(get_started_finalizations() == 1);
195 EXPECT_FALSE(get_last_started_finalization_success());
198 class ChromeTracingDelegateBrowserTestOnStartup
199 : public ChromeTracingDelegateBrowserTest
{
201 ChromeTracingDelegateBrowserTestOnStartup() {}
203 static void FieldTrialConfigTextFilter(std::string
* config_text
) {
204 ASSERT_TRUE(config_text
);
205 // We need to replace the config JSON with the full one here, as we can't
206 // pass JSON through the fieldtrial switch parsing.
207 if (*config_text
== "default_config_for_testing") {
209 "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
210 "\"BENCHMARK\",\"configs\": [{\"rule\": "
211 "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\",\"trigger_name\":"
216 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
217 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
218 switches::kForceFieldTrials
, "BackgroundTracing/TestGroup/");
219 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
220 switches::kForceFieldTrialParams
,
221 "BackgroundTracing.TestGroup:config/default_config_for_testing");
223 tracing::SetConfigTextFilterForTesting(&FieldTrialConfigTextFilter
);
227 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup
,
228 ScenarioSetFromFieldtrial
) {
229 // We should reach this point without crashing.
230 EXPECT_TRUE(content::BackgroundTracingManager::GetInstance()
231 ->HasActiveScenarioForTesting());
234 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup
,
235 PRE_StartupTracingThrottle
) {
236 EXPECT_TRUE(content::BackgroundTracingManager::GetInstance()
237 ->HasActiveScenarioForTesting());
239 // Simulate a trace upload.
240 PrefService
* local_state
= g_browser_process
->local_state();
242 local_state
->SetInt64(prefs::kBackgroundTracingLastUpload
,
243 base::Time::Now().ToInternalValue());
246 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup
,
247 StartupTracingThrottle
) {
248 // The startup scenario should *not* be started, since not enough
249 // time has elapsed since the last upload (set in the PRE_ above).
250 EXPECT_FALSE(content::BackgroundTracingManager::GetInstance()
251 ->HasActiveScenarioForTesting());