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_manager.h"
17 #include "content/public/browser/background_tracing_preemptive_config.h"
18 #include "content/public/browser/background_tracing_reactive_config.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/test/test_utils.h"
24 class ChromeTracingDelegateBrowserTest
: public InProcessBrowserTest
{
26 ChromeTracingDelegateBrowserTest()
28 started_finalizations_count_(0),
29 last_on_started_finalizing_success_(false) {}
31 bool StartPreemptiveScenario(
32 const base::Closure
& on_upload_callback
,
33 content::BackgroundTracingManager::DataFiltering data_filtering
) {
34 on_upload_callback_
= on_upload_callback
;
36 scoped_ptr
<content::BackgroundTracingPreemptiveConfig
> config(
37 new content::BackgroundTracingPreemptiveConfig());
39 content::BackgroundTracingPreemptiveConfig::MonitoringRule rule
;
40 rule
.type
= content::BackgroundTracingPreemptiveConfig::
41 MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED
;
42 rule
.named_trigger_info
.trigger_name
= "test";
44 config
->configs
.push_back(rule
);
46 content::BackgroundTracingManager::ReceiveCallback receive_callback
=
47 base::Bind(&ChromeTracingDelegateBrowserTest::OnUpload
,
48 base::Unretained(this));
50 return content::BackgroundTracingManager::GetInstance()->SetActiveScenario(
51 config
.Pass(), receive_callback
, data_filtering
);
54 void TriggerReactiveScenario(
55 const base::Closure
& on_started_finalization_callback
) {
56 on_started_finalization_callback_
= on_started_finalization_callback
;
58 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
61 content::BackgroundTracingManager::StartedFinalizingCallback
62 started_finalizing_callback
=
63 base::Bind(&ChromeTracingDelegateBrowserTest::OnStartedFinalizing
,
64 base::Unretained(this));
65 content::BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
66 trigger_handle_
, started_finalizing_callback
);
69 int get_receive_count() const { return receive_count_
; }
70 bool get_started_finalizations() const {
71 return started_finalizations_count_
;
73 bool get_last_started_finalization_success() const {
74 return last_on_started_finalizing_success_
;
78 void OnUpload(const scoped_refptr
<base::RefCountedString
>& file_contents
,
79 scoped_ptr
<base::DictionaryValue
> metadata
,
80 base::Callback
<void()> done_callback
) {
83 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
84 base::Bind(done_callback
));
85 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
86 base::Bind(on_upload_callback_
));
89 void OnStartedFinalizing(bool success
) {
90 started_finalizations_count_
++;
91 last_on_started_finalizing_success_
= success
;
93 if (!on_started_finalization_callback_
.is_null()) {
94 content::BrowserThread::PostTask(
95 content::BrowserThread::UI
, FROM_HERE
,
96 base::Bind(on_started_finalization_callback_
));
100 base::Closure on_upload_callback_
;
101 base::Closure on_started_finalization_callback_
;
103 int started_finalizations_count_
;
104 content::BackgroundTracingManager::TriggerHandle trigger_handle_
;
105 bool last_on_started_finalizing_success_
;
108 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest
,
109 BackgroundTracingTimeThrottled
) {
110 base::RunLoop wait_for_upload
;
112 EXPECT_TRUE(StartPreemptiveScenario(
113 wait_for_upload
.QuitClosure(),
114 content::BackgroundTracingManager::NO_DATA_FILTERING
));
116 TriggerReactiveScenario(base::Closure());
118 wait_for_upload
.Run();
120 EXPECT_TRUE(get_receive_count() == 1);
122 PrefService
* local_state
= g_browser_process
->local_state();
124 const base::Time last_upload_time
= base::Time::FromInternalValue(
125 local_state
->GetInt64(prefs::kBackgroundTracingLastUpload
));
126 EXPECT_FALSE(last_upload_time
.is_null());
128 // We should not be able to start a new reactive scenario immediately after
129 // a previous one gets uploaded.
130 EXPECT_FALSE(StartPreemptiveScenario(
131 base::Closure(), content::BackgroundTracingManager::NO_DATA_FILTERING
));
134 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest
,
135 BackgroundTracingThrottleTimeElapsed
) {
136 base::RunLoop wait_for_upload
;
138 EXPECT_TRUE(StartPreemptiveScenario(
139 wait_for_upload
.QuitClosure(),
140 content::BackgroundTracingManager::NO_DATA_FILTERING
));
142 TriggerReactiveScenario(base::Closure());
144 wait_for_upload
.Run();
146 EXPECT_TRUE(get_receive_count() == 1);
148 PrefService
* local_state
= g_browser_process
->local_state();
150 const base::Time last_upload_time
= base::Time::FromInternalValue(
151 local_state
->GetInt64(prefs::kBackgroundTracingLastUpload
));
152 EXPECT_FALSE(last_upload_time
.is_null());
154 // We move the last upload time to eight days in the past,
155 // and at that point should be able to start a scenario again.
156 base::Time new_upload_time
= last_upload_time
- base::TimeDelta::FromDays(8);
157 local_state
->SetInt64(prefs::kBackgroundTracingLastUpload
,
158 new_upload_time
.ToInternalValue());
159 EXPECT_TRUE(StartPreemptiveScenario(
160 base::Closure(), content::BackgroundTracingManager::NO_DATA_FILTERING
));
163 // If we need a PII-stripped trace, any existing OTR session should block the
165 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest
,
166 ExistingIncognitoSessionBlockingTraceStart
) {
167 EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_NEW_INCOGNITO_WINDOW
));
168 EXPECT_TRUE(BrowserList::IsOffTheRecordSessionActive());
169 EXPECT_FALSE(StartPreemptiveScenario(
170 base::Closure(), content::BackgroundTracingManager::ANONYMIZE_DATA
));
173 // If we need a PII-stripped trace, any new OTR session during tracing should
174 // block the finalization of the trace.
175 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest
,
176 NewIncognitoSessionBlockingTraceFinalization
) {
177 EXPECT_TRUE(StartPreemptiveScenario(
178 base::Closure(), content::BackgroundTracingManager::ANONYMIZE_DATA
));
180 EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_NEW_INCOGNITO_WINDOW
));
181 EXPECT_TRUE(BrowserList::IsOffTheRecordSessionActive());
183 base::RunLoop wait_for_finalization_start
;
184 TriggerReactiveScenario(wait_for_finalization_start
.QuitClosure());
185 wait_for_finalization_start
.Run();
187 EXPECT_TRUE(get_started_finalizations() == 1);
188 EXPECT_FALSE(get_last_started_finalization_success());
191 class ChromeTracingDelegateBrowserTestOnStartup
192 : public ChromeTracingDelegateBrowserTest
{
194 ChromeTracingDelegateBrowserTestOnStartup() {}
196 static void FieldTrialConfigTextFilter(std::string
* config_text
) {
197 ASSERT_TRUE(config_text
);
198 // We need to replace the config JSON with the full one here, as we can't
199 // pass JSON through the fieldtrial switch parsing.
200 if (*config_text
== "default_config_for_testing") {
202 "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
203 "\"BENCHMARK\",\"configs\": [{\"rule\": "
204 "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\",\"trigger_name\":"
209 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
210 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
211 switches::kForceFieldTrials
, "BackgroundTracing/TestGroup/");
212 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
213 switches::kForceFieldTrialParams
,
214 "BackgroundTracing.TestGroup:config/default_config_for_testing");
216 tracing::SetConfigTextFilterForTesting(&FieldTrialConfigTextFilter
);
220 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup
,
221 ScenarioSetFromFieldtrial
) {
222 // We should reach this point without crashing.
223 EXPECT_TRUE(content::BackgroundTracingManager::GetInstance()
224 ->HasActiveScenarioForTesting());
227 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup
,
228 PRE_StartupTracingThrottle
) {
229 EXPECT_TRUE(content::BackgroundTracingManager::GetInstance()
230 ->HasActiveScenarioForTesting());
232 // Simulate a trace upload.
233 PrefService
* local_state
= g_browser_process
->local_state();
235 local_state
->SetInt64(prefs::kBackgroundTracingLastUpload
,
236 base::Time::Now().ToInternalValue());
239 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup
,
240 StartupTracingThrottle
) {
241 // The startup scenario should *not* be started, since not enough
242 // time has elapsed since the last upload (set in the PRE_ above).
243 EXPECT_FALSE(content::BackgroundTracingManager::GetInstance()
244 ->HasActiveScenarioForTesting());