OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" | 5 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" |
6 | 6 |
7 #include <initializer_list> | 7 #include <initializer_list> |
8 #include <iterator> | |
9 #include <set> | 8 #include <set> |
9 #include <tuple> | |
10 #include <utility> | |
10 #include <vector> | 11 #include <vector> |
11 | 12 |
12 #include "base/bind.h" | 13 #include "base/bind.h" |
13 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
14 #include "base/callback.h" | 15 #include "base/callback.h" |
16 #include "base/callback_helpers.h" | |
15 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
16 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
17 #include "base/message_loop/message_loop.h" | 19 #include "base/message_loop/message_loop.h" |
20 #include "base/run_loop.h" | |
21 #include "base/strings/string_number_conversions.h" | |
22 #include "base/test/multiprocess_test.h" | |
18 #include "base/test/scoped_feature_list.h" | 23 #include "base/test/scoped_feature_list.h" |
19 #include "base/test/test_mock_time_task_runner.h" | 24 #include "base/test/test_mock_time_task_runner.h" |
25 #include "base/threading/sequenced_task_runner_handle.h" | |
20 #include "base/threading/thread_task_runner_handle.h" | 26 #include "base/threading/thread_task_runner_handle.h" |
21 #include "base/time/time.h" | 27 #include "base/time/time.h" |
22 #include "base/version.h" | 28 #include "base/version.h" |
23 #include "chrome/browser/browser_process.h" | 29 #include "chrome/browser/browser_process.h" |
24 #include "chrome/browser/lifetime/keep_alive_types.h" | 30 #include "chrome/browser/lifetime/keep_alive_types.h" |
25 #include "chrome/browser/lifetime/scoped_keep_alive.h" | 31 #include "chrome/browser/lifetime/scoped_keep_alive.h" |
26 #include "chrome/browser/profiles/profile.h" | 32 #include "chrome/browser/profiles/profile.h" |
27 #include "chrome/browser/safe_browsing/srt_client_info_win.h" | 33 #include "chrome/browser/safe_browsing/srt_client_info_win.h" |
28 #include "chrome/browser/ui/browser.h" | 34 #include "chrome/browser/ui/browser.h" |
29 #include "chrome/browser/ui/browser_finder.h" | 35 #include "chrome/browser/ui/browser_finder.h" |
30 #include "chrome/browser/ui/test/test_browser_dialog.h" | 36 #include "chrome/browser/ui/test/test_browser_dialog.h" |
31 #include "chrome/common/pref_names.h" | 37 #include "chrome/common/pref_names.h" |
32 #include "chrome/test/base/in_process_browser_test.h" | 38 #include "chrome/test/base/in_process_browser_test.h" |
39 #include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h" | |
33 #include "components/component_updater/pref_names.h" | 40 #include "components/component_updater/pref_names.h" |
34 #include "components/prefs/pref_service.h" | 41 #include "components/prefs/pref_service.h" |
35 #include "components/safe_browsing_db/safe_browsing_prefs.h" | 42 #include "components/safe_browsing_db/safe_browsing_prefs.h" |
43 #include "mojo/edk/embedder/embedder.h" | |
44 #include "mojo/edk/embedder/scoped_ipc_support.h" | |
45 #include "mojo/edk/system/core.h" | |
46 #include "testing/multiprocess_func_list.h" | |
36 | 47 |
37 namespace safe_browsing { | 48 namespace safe_browsing { |
38 | 49 |
39 namespace { | 50 namespace { |
40 | 51 |
41 const char* const kExpectedSwitches[] = {kExtendedSafeBrowsingEnabledSwitch, | 52 using chrome_cleaner::mojom::PromptAcceptance; |
42 kChromeVersionSwitch, | |
43 kChromeChannelSwitch}; | |
44 | 53 |
45 class SRTFetcherTest : public InProcessBrowserTest, | 54 // Special switches passed by the parent process (test case) to the reporter |
46 public SwReporterTestingDelegate { | 55 // child process to indicate the behavior that should be mocked. |
56 constexpr char kExitCodeToReturnSwitch[] = "exit-code-to-return"; | |
57 constexpr char kReportUwSFoundSwitch[] = "report-uws-found"; | |
58 constexpr char kReportElevationRequiredSwitch[] = "report-elevation-required"; | |
59 constexpr char kExpectedPromptAcceptanceSwitch[] = "expected-prompt-acceptance"; | |
60 | |
61 // The exit code to be returned in case of failure in the child process. | |
62 // This should never passed as the expected exit code to be reported by tests. | |
joenotcharles
2017/04/06 21:41:56
Another typo: "never be passed"
ftirelo
2017/04/07 14:57:04
Done.
| |
63 constexpr int kFailureExitCode = -1; | |
64 | |
65 // Pass the |prompt_acceptance| to the mock child process in command line | |
66 // switch kExpectedPromptAcceptanceSwitch. | |
67 void AddPromptAcceptanceToCommandLine(PromptAcceptance prompt_acceptance, | |
68 base::CommandLine* command_line) { | |
69 command_line->AppendSwitchASCII( | |
70 kExpectedPromptAcceptanceSwitch, | |
71 base::IntToString(static_cast<int>(prompt_acceptance))); | |
72 } | |
73 | |
74 // Parses and returns the prompt acceptance value passed by the parent process | |
75 // in command line switch kExpectedPromptAcceptanceSwitch. Returns | |
76 // PromptAcceptance::UNSPECIFIED if the switch doesn't exist or can't be | |
77 // parsed to a valid PromptAcceptance enumerator. | |
78 PromptAcceptance PromptAcceptanceFromCommandLine( | |
79 const base::CommandLine& command_line) { | |
80 const std::string& prompt_acceptance_str = | |
81 command_line.GetSwitchValueASCII(kExpectedPromptAcceptanceSwitch); | |
82 int val = -1; | |
83 if (base::StringToInt(prompt_acceptance_str, &val)) { | |
84 PromptAcceptance prompt_acceptance = static_cast<PromptAcceptance>(val); | |
85 if (chrome_cleaner::mojom::IsKnownEnumValue(prompt_acceptance)) | |
86 return prompt_acceptance; | |
87 } | |
88 return PromptAcceptance::UNSPECIFIED; | |
89 } | |
90 | |
91 // Pointer to ChromePromptPtr object to be used by the child process. The | |
92 // object must be created, deleted, and accessed on the IPC thread only. | |
93 chrome_cleaner::mojom::ChromePromptPtr* g_chrome_prompt_ptr = nullptr; | |
94 | |
95 // The callback function to be passed to ChromePrompt::PromptUser to check if | |
96 // the prompt accepted returned by the parent process is equals to | |
alito
2017/04/06 21:13:26
nit: equals -> equal
ftirelo
2017/04/06 21:27:09
Done.
| |
97 // |expected_prompt_acceptance|. Will set |expected_value_received| with the | |
98 // comparison result, so that the main thread can report failure. Will invoke | |
99 // |done| callback when done. | |
100 void PromptUserCallback(const base::Closure& done, | |
101 PromptAcceptance expected_prompt_acceptance, | |
102 bool* expected_value_received, | |
103 PromptAcceptance prompt_acceptance) { | |
104 *expected_value_received = prompt_acceptance == expected_prompt_acceptance; | |
105 // It's safe to delete the ChromePromptPtr object here, since it will not be | |
106 // used anymore by the child process. | |
107 delete g_chrome_prompt_ptr; | |
joenotcharles
2017/04/06 21:41:56
Should set to null after deleting it.
ftirelo
2017/04/07 14:57:04
Done.
| |
108 done.Run(); | |
109 } | |
110 | |
111 // Mocks the sending of scan results from the child process to the parent | |
112 // process. Obtains the behavior to be mocked from special switches in | |
113 // |command_line|. Sets |expected_value_received| as true if the parent | |
114 // process replies with the expected prompt acceptance value. | |
115 void SendScanResults(const std::string& chrome_mojo_pipe_token, | |
116 const base::CommandLine& command_line, | |
117 const base::Closure& done, | |
118 bool* expected_value_received) { | |
119 constexpr int kDefaultUwSId = 10; | |
120 constexpr char kDefaultUwSName[] = "RemovedUwS"; | |
121 | |
122 mojo::ScopedMessagePipeHandle message_pipe_handle = | |
123 mojo::edk::CreateChildMessagePipe(chrome_mojo_pipe_token); | |
124 // This pointer will be deleted by PromptUserCallback. | |
125 g_chrome_prompt_ptr = new chrome_cleaner::mojom::ChromePromptPtr(); | |
126 g_chrome_prompt_ptr->Bind(chrome_cleaner::mojom::ChromePromptPtrInfo( | |
127 std::move(message_pipe_handle), 0)); | |
128 | |
129 std::vector<chrome_cleaner::mojom::UwSPtr> removable_uws_found; | |
130 if (command_line.HasSwitch(kReportUwSFoundSwitch)) { | |
131 chrome_cleaner::mojom::UwSPtr uws = chrome_cleaner::mojom::UwS::New(); | |
132 uws->id = kDefaultUwSId; | |
133 uws->name = kDefaultUwSName; | |
134 uws->observed_behaviours = chrome_cleaner::mojom::ObservedBehaviours::New(); | |
135 removable_uws_found.push_back(std::move(uws)); | |
136 } | |
137 const bool elevation_required = | |
138 command_line.HasSwitch(kReportElevationRequiredSwitch); | |
139 const PromptAcceptance expected_prompt_acceptance = | |
140 PromptAcceptanceFromCommandLine(command_line); | |
141 | |
142 (*g_chrome_prompt_ptr) | |
143 ->PromptUser( | |
144 std::move(removable_uws_found), elevation_required, | |
145 base::Bind(&PromptUserCallback, done, expected_prompt_acceptance, | |
146 expected_value_received)); | |
147 } | |
148 | |
149 // Connects to the parent process and send mocked scan results. Returns true if | |
alito
2017/04/06 21:13:26
nit: send -> sends
ftirelo
2017/04/06 21:27:09
Done.
| |
150 // connection was successful and the prompt acceptance results sent by the | |
151 // parent process are the same as expected. | |
152 bool ConnectAndSendDataToParentProcess( | |
153 const std::string& chrome_mojo_pipe_token, | |
154 const base::CommandLine& command_line) { | |
155 if (chrome_mojo_pipe_token.empty()) | |
156 return false; | |
joenotcharles
2017/04/06 21:41:56
Nit: I'd prefer a DCHECK here since the caller alr
ftirelo
2017/04/07 14:57:04
Done.
| |
157 | |
158 mojo::edk::Init(); | |
159 base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); | |
160 base::Thread io_thread("IPCThread"); | |
161 if (!io_thread.StartWithOptions(options)) | |
162 return false; | |
163 mojo::edk::ScopedIPCSupport ipc_support( | |
164 io_thread.task_runner(), | |
165 mojo::edk::ScopedIPCSupport::ShutdownPolicy::CLEAN); | |
166 mojo::edk::SetParentPipeHandleFromCommandLine(); | |
167 base::MessageLoop message_loop; | |
alito
2017/04/06 21:13:26
Is message_loop supposed to be used somewhere?
joenotcharles
2017/04/06 21:21:06
MessageLoop's constructor registers itself with th
ftirelo
2017/04/06 21:27:09
Done.
alito
2017/04/06 21:27:45
In other words, magic!
| |
168 base::RunLoop run_loop; | |
169 // After the response from the parent process is received, this will post a | |
170 // task to unblock the child's process main thread. | |
joenotcharles
2017/04/06 21:41:56
Nit: I think you mean "child process's main thread
ftirelo
2017/04/07 14:57:04
Done.
| |
171 auto done = base::Bind( | |
172 [](scoped_refptr<base::SequencedTaskRunner> main_runner, | |
173 base::Closure quit_closure) { | |
174 main_runner->PostTask(FROM_HERE, std::move(quit_closure)); | |
175 }, | |
176 base::SequencedTaskRunnerHandle::Get(), | |
177 base::Passed(run_loop.QuitClosure())); | |
178 | |
179 bool expected_value_received = false; | |
180 io_thread.task_runner()->PostTask( | |
181 FROM_HERE, base::Bind(&SendScanResults, chrome_mojo_pipe_token, | |
182 command_line, done, &expected_value_received)); | |
183 run_loop.Run(); | |
184 | |
185 return expected_value_received; | |
186 } | |
187 | |
188 // Mocks a Software Reporter process that returns an exit code specified by | |
189 // command line switch kExitCodeToReturnSwitch. If a Mojo IPC is available, | |
190 // this will also connect to the parent process and send mocked scan results | |
191 // to the parent process using data passed as command line switches. | |
192 MULTIPROCESS_TEST_MAIN(MockSwReporterProcess) { | |
193 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
194 const std::string& str = | |
195 command_line->GetSwitchValueASCII(kExitCodeToReturnSwitch); | |
196 const std::string& chrome_mojo_pipe_token = | |
alito
2017/04/06 21:13:26
Could getting the token from the command line be d
ftirelo
2017/04/06 21:27:09
As discussed, by getting the switch value here, we
| |
197 command_line->GetSwitchValueASCII(kChromeMojoPipeTokenSwitch); | |
198 int exit_code_to_report = kFailureExitCode; | |
199 bool success = base::StringToInt(str, &exit_code_to_report) && | |
200 (chrome_mojo_pipe_token.empty() || | |
201 ConnectAndSendDataToParentProcess(chrome_mojo_pipe_token, | |
202 *command_line)); | |
203 return success ? exit_code_to_report : kFailureExitCode; | |
204 } | |
205 | |
206 // Parameters for this test: | |
207 // - bool in_browser_cleaner_ui: indicates if InBrowserCleanerUI experiment | |
208 // is enabled; if so, the parent and the child processes will communicate | |
209 // via a Mojo IPC; | |
210 // - bool elevation_required: indicates if the scan results sent by the child | |
211 // process should consider that elevation will be required for cleanup. | |
212 class SRTFetcherTest | |
213 : public InProcessBrowserTest, | |
214 public SwReporterTestingDelegate, | |
215 public ::testing::WithParamInterface<std::tuple<bool, bool>> { | |
47 public: | 216 public: |
48 void SetUpInProcessBrowserTestFixture() override { | 217 void SetUpInProcessBrowserTestFixture() override { |
49 SetSwReporterTestingDelegate(this); | 218 SetSwReporterTestingDelegate(this); |
219 | |
220 std::tie(in_browser_cleaner_ui_, elevation_required_) = GetParam(); | |
221 // The config should only accept elevation_required_ if InBrowserCleanerUI | |
222 // feature is enabled. | |
223 ASSERT_TRUE(!elevation_required_ || in_browser_cleaner_ui_); | |
224 | |
225 if (in_browser_cleaner_ui_) | |
226 scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature); | |
227 else | |
228 scoped_feature_list_.InitAndDisableFeature(kInBrowserCleanerUIFeature); | |
50 } | 229 } |
51 | 230 |
52 void SetUpOnMainThread() override { | 231 void SetUpOnMainThread() override { |
53 // During the test, use a task runner with a mock clock. | 232 // During the test, use a task runner with a mock clock. |
54 saved_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 233 saved_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
55 ASSERT_NE(mock_time_task_runner_, saved_task_runner_); | 234 ASSERT_NE(mock_time_task_runner_, saved_task_runner_); |
56 base::MessageLoop::current()->SetTaskRunner(mock_time_task_runner_); | 235 base::MessageLoop::current()->SetTaskRunner(mock_time_task_runner_); |
57 | 236 |
58 InProcessBrowserTest::SetUpOnMainThread(); | 237 InProcessBrowserTest::SetUpOnMainThread(); |
59 | 238 |
(...skipping 13 matching lines...) Expand all Loading... | |
73 | 252 |
74 void TearDownInProcessBrowserTestFixture() override { | 253 void TearDownInProcessBrowserTestFixture() override { |
75 SetSwReporterTestingDelegate(nullptr); | 254 SetSwReporterTestingDelegate(nullptr); |
76 } | 255 } |
77 | 256 |
78 // Records that the prompt was shown. | 257 // Records that the prompt was shown. |
79 void TriggerPrompt(Browser* browser, const std::string& version) override { | 258 void TriggerPrompt(Browser* browser, const std::string& version) override { |
80 prompt_trigger_called_ = true; | 259 prompt_trigger_called_ = true; |
81 } | 260 } |
82 | 261 |
83 // Records that the reporter was launched with the parameters given in | 262 // Spawns and returns a subprocess to mock an execution of the reporter with |
84 // |invocation|. | 263 // the parameters given in |invocation| and that will return |
joenotcharles
2017/04/06 21:41:56
Typo: "and that" should just be "that", I think.
ftirelo
2017/04/07 14:57:04
Done.
| |
85 int LaunchReporter(const SwReporterInvocation& invocation) override { | 264 // |exit_code_to_report_|. If IPC communication needs to be mocked, this will |
265 // also provide values that define the expected behavior of the child | |
266 // process. | |
267 // Records the launch and parameters used for further verification. | |
268 base::Process LaunchReporter( | |
269 const SwReporterInvocation& invocation, | |
270 const base::LaunchOptions& launch_options) override { | |
86 ++reporter_launch_count_; | 271 ++reporter_launch_count_; |
87 reporter_launch_parameters_.push_back(invocation); | 272 reporter_launch_parameters_.push_back(invocation); |
88 if (first_launch_callback_) | 273 if (first_launch_callback_) |
89 std::move(first_launch_callback_).Run(); | 274 std::move(first_launch_callback_).Run(); |
90 return exit_code_to_report_; | 275 |
276 base::CommandLine command_line( | |
277 base::GetMultiProcessTestChildBaseCommandLine()); | |
278 command_line.AppendArguments(invocation.command_line, | |
279 /*include_program=*/false); | |
280 command_line.AppendSwitchASCII(kExitCodeToReturnSwitch, | |
281 base::IntToString(exit_code_to_report_)); | |
282 if (in_browser_cleaner_ui_) { | |
283 AddPromptAcceptanceToCommandLine(PromptAcceptance::DENIED, &command_line); | |
284 if (exit_code_to_report_ == kSwReporterCleanupNeeded) { | |
285 command_line.AppendSwitch(kReportUwSFoundSwitch); | |
286 if (elevation_required_) | |
287 command_line.AppendSwitch(kReportElevationRequiredSwitch); | |
288 } | |
289 } | |
290 base::SpawnChildResult result = base::SpawnMultiProcessTestChild( | |
291 "MockSwReporterProcess", command_line, launch_options); | |
292 return std::move(result.process); | |
91 } | 293 } |
92 | 294 |
93 // Returns the test's idea of the current time. | 295 // Returns the test's idea of the current time. |
94 base::Time Now() const override { return mock_time_task_runner_->Now(); } | 296 base::Time Now() const override { return mock_time_task_runner_->Now(); } |
95 | 297 |
96 // Returns a task runner to use when launching the reporter (which is | 298 // Returns a task runner to use when launching the reporter (which is |
97 // normally a blocking action). | 299 // normally a blocking action). |
98 base::TaskRunner* BlockingTaskRunner() const override { | 300 base::TaskRunner* BlockingTaskRunner() const override { |
99 // Use the test's main task runner so that we don't need to pump another | 301 // Use the test's main task runner so that we don't need to pump another |
100 // message loop. Since the test calls LaunchReporter instead of actually | 302 // message loop. Since the test calls LaunchReporter instead of actually |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 const base::Time last_time_sent_logs = base::Time::FromInternalValue( | 426 const base::Time last_time_sent_logs = base::Time::FromInternalValue( |
225 local_state->GetInt64(prefs::kSwReporterLastTimeSentReport)); | 427 local_state->GetInt64(prefs::kSwReporterLastTimeSentReport)); |
226 | 428 |
227 // Checks if the last time sent logs is set as no more than one hour ago, | 429 // Checks if the last time sent logs is set as no more than one hour ago, |
228 // which should be enough time if the execution does not fail. | 430 // which should be enough time if the execution does not fail. |
229 EXPECT_LT(now - base::TimeDelta::FromHours(1), last_time_sent_logs); | 431 EXPECT_LT(now - base::TimeDelta::FromHours(1), last_time_sent_logs); |
230 EXPECT_GE(now, last_time_sent_logs); | 432 EXPECT_GE(now, last_time_sent_logs); |
231 } | 433 } |
232 | 434 |
233 // Expects |invocation|'s command line to contain all the switches required | 435 // Expects |invocation|'s command line to contain all the switches required |
234 // for reporter logging. | 436 // for reporter logging if and only if |expect_switches| is true. |
235 void ExpectLoggingSwitches(const SwReporterInvocation& invocation, | 437 void ExpectLoggingSwitches(const SwReporterInvocation& invocation, |
236 bool expect_switches) { | 438 bool expect_switches) { |
439 static const std::set<std::string> logging_switches{ | |
440 kExtendedSafeBrowsingEnabledSwitch, kChromeVersionSwitch, | |
441 kChromeChannelSwitch}; | |
442 | |
237 const base::CommandLine::SwitchMap& invocation_switches = | 443 const base::CommandLine::SwitchMap& invocation_switches = |
238 invocation.command_line.GetSwitches(); | 444 invocation.command_line.GetSwitches(); |
239 std::set<std::string> expected_switches; | 445 // Checks if switches that enable logging on the reporter are present on |
240 if (expect_switches) | 446 // the invocation if and only if logging is allowed. |
241 expected_switches = {std::begin(kExpectedSwitches), | 447 for (const std::string& logging_switch : logging_switches) { |
242 std::end(kExpectedSwitches)}; | 448 EXPECT_EQ(expect_switches, invocation_switches.find(logging_switch) != |
243 EXPECT_EQ(expected_switches.size(), invocation_switches.size()); | 449 invocation_switches.end()); |
244 // Checks if all expected switches are in the invocation switches. It's not | |
245 // necessary to check if all invocation switches are expected, since we | |
246 // checked if both sets should have the same size. | |
247 for (const std::string& expected_switch : expected_switches) { | |
248 EXPECT_NE(invocation_switches.end(), | |
249 invocation_switches.find(expected_switch)); | |
250 } | 450 } |
251 } | 451 } |
252 | 452 |
253 // A task runner with a mock clock. | 453 // A task runner with a mock clock. |
254 scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner_ = | 454 scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner_ = |
255 new base::TestMockTimeTaskRunner(); | 455 new base::TestMockTimeTaskRunner(); |
256 | 456 |
257 // The task runner that was in use before installing |mock_time_task_runner_|. | 457 // The task runner that was in use before installing |mock_time_task_runner_|. |
258 scoped_refptr<base::SingleThreadTaskRunner> saved_task_runner_; | 458 scoped_refptr<base::SingleThreadTaskRunner> saved_task_runner_; |
259 | 459 |
460 bool in_browser_cleaner_ui_; | |
461 bool elevation_required_; | |
462 | |
260 bool prompt_trigger_called_ = false; | 463 bool prompt_trigger_called_ = false; |
261 int reporter_launch_count_ = 0; | 464 int reporter_launch_count_ = 0; |
262 std::vector<SwReporterInvocation> reporter_launch_parameters_; | 465 std::vector<SwReporterInvocation> reporter_launch_parameters_; |
263 int exit_code_to_report_ = kReporterFailureExitCode; | 466 int exit_code_to_report_ = kReporterFailureExitCode; |
264 | 467 |
265 // A callback to invoke when the first reporter of a queue is launched. This | 468 // A callback to invoke when the first reporter of a queue is launched. This |
266 // can be used to perform actions in the middle of a queue of reporters which | 469 // can be used to perform actions in the middle of a queue of reporters which |
267 // all launch on the same mock clock tick. | 470 // all launch on the same mock clock tick. |
268 base::OnceClosure first_launch_callback_; | 471 base::OnceClosure first_launch_callback_; |
472 | |
473 base::test::ScopedFeatureList scoped_feature_list_; | |
269 }; | 474 }; |
270 | 475 |
271 class SRTFetcherPromptTest : public DialogBrowserTest { | 476 class SRTFetcherPromptTest : public DialogBrowserTest { |
272 public: | 477 public: |
273 void ShowDialog(const std::string& name) override { | 478 void ShowDialog(const std::string& name) override { |
274 if (name == "SRTErrorNoFile") | 479 if (name == "SRTErrorNoFile") |
275 DisplaySRTPromptForTesting(base::FilePath()); | 480 DisplaySRTPromptForTesting(base::FilePath()); |
276 else if (name == "SRTErrorFile") | 481 else if (name == "SRTErrorFile") |
277 DisplaySRTPromptForTesting( | 482 DisplaySRTPromptForTesting( |
278 base::FilePath().Append(FILE_PATH_LITERAL("c:\temp\testfile.txt"))); | 483 base::FilePath().Append(FILE_PATH_LITERAL("c:\temp\testfile.txt"))); |
279 else | 484 else |
280 ADD_FAILURE() << "Unknown dialog type."; | 485 ADD_FAILURE() << "Unknown dialog type."; |
281 } | 486 } |
282 }; | 487 }; |
283 | 488 |
284 } // namespace | 489 } // namespace |
285 | 490 |
286 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, NothingFound) { | 491 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, NothingFound) { |
287 RunReporter(kSwReporterNothingFound); | 492 RunReporter(kSwReporterNothingFound); |
288 ExpectReporterLaunches(0, 1, false); | 493 ExpectReporterLaunches(0, 1, false); |
289 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 494 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
290 } | 495 } |
291 | 496 |
292 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, CleanupNeeded) { | 497 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, CleanupNeeded) { |
293 RunReporter(kSwReporterCleanupNeeded); | 498 RunReporter(kSwReporterCleanupNeeded); |
294 ExpectReporterLaunches(0, 1, true); | 499 ExpectReporterLaunches(0, 1, true); |
295 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 500 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
296 } | 501 } |
297 | 502 |
298 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, RanRecently) { | 503 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, RanRecently) { |
299 constexpr int kDaysLeft = 1; | 504 constexpr int kDaysLeft = 1; |
300 SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft); | 505 SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft); |
301 RunReporter(kSwReporterNothingFound); | 506 RunReporter(kSwReporterNothingFound); |
302 ExpectReporterLaunches(0, 0, false); | 507 ExpectReporterLaunches(0, 0, false); |
303 ExpectToRunAgain(kDaysLeft); | 508 ExpectToRunAgain(kDaysLeft); |
304 ExpectReporterLaunches(kDaysLeft, 1, false); | 509 ExpectReporterLaunches(kDaysLeft, 1, false); |
305 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 510 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
306 } | 511 } |
307 | 512 |
308 // Test is flaky. crbug.com/705608 | 513 // Test is flaky. crbug.com/705608 |
309 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, DISABLED_WaitForBrowser) { | 514 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, DISABLED_WaitForBrowser) { |
310 Profile* profile = browser()->profile(); | 515 Profile* profile = browser()->profile(); |
311 | 516 |
312 // Ensure that even though we're closing the last browser, we don't enter the | 517 // Ensure that even though we're closing the last browser, we don't enter the |
313 // "shutting down" state, which will prevent the test from starting another | 518 // "shutting down" state, which will prevent the test from starting another |
314 // browser. | 519 // browser. |
315 ScopedKeepAlive test_keep_alive(KeepAliveOrigin::SESSION_RESTORE, | 520 ScopedKeepAlive test_keep_alive(KeepAliveOrigin::SESSION_RESTORE, |
316 KeepAliveRestartOption::ENABLED); | 521 KeepAliveRestartOption::ENABLED); |
317 | 522 |
318 // Use the standard task runner for browser cleanup, which will wait forever | 523 // Use the standard task runner for browser cleanup, which will wait forever |
319 // with the mock clock. | 524 // with the mock clock. |
(...skipping 19 matching lines...) Expand all Loading... | |
339 // pending task in the queue is the next reporter check. | 544 // pending task in the queue is the next reporter check. |
340 mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(10)); | 545 mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(10)); |
341 | 546 |
342 // On opening the new browser, the prompt should be shown and the reporter | 547 // On opening the new browser, the prompt should be shown and the reporter |
343 // should be scheduled to run later. | 548 // should be scheduled to run later. |
344 EXPECT_EQ(1, reporter_launch_count_); | 549 EXPECT_EQ(1, reporter_launch_count_); |
345 EXPECT_TRUE(prompt_trigger_called_); | 550 EXPECT_TRUE(prompt_trigger_called_); |
346 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 551 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
347 } | 552 } |
348 | 553 |
349 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, Failure) { | 554 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, Failure) { |
350 RunReporter(kReporterFailureExitCode); | 555 RunReporter(kReporterFailureExitCode); |
351 ExpectReporterLaunches(0, 1, false); | 556 ExpectReporterLaunches(0, 1, false); |
352 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 557 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
353 } | 558 } |
354 | 559 |
355 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, RunDaily) { | 560 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, RunDaily) { |
356 PrefService* local_state = g_browser_process->local_state(); | 561 PrefService* local_state = g_browser_process->local_state(); |
357 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, true); | 562 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, true); |
358 SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - 1); | 563 SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - 1); |
359 ASSERT_GT(kDaysBetweenSuccessfulSwReporterRuns - 1, | 564 ASSERT_GT(kDaysBetweenSuccessfulSwReporterRuns - 1, |
360 kDaysBetweenSwReporterRunsForPendingPrompt); | 565 kDaysBetweenSwReporterRunsForPendingPrompt); |
361 RunReporter(kSwReporterNothingFound); | 566 RunReporter(kSwReporterNothingFound); |
362 | 567 |
363 // Expect the reporter to run immediately, since a prompt is pending and it | 568 // Expect the reporter to run immediately, since a prompt is pending and it |
364 // has been more than kDaysBetweenSwReporterRunsForPendingPrompt days. | 569 // has been more than kDaysBetweenSwReporterRunsForPendingPrompt days. |
365 ExpectReporterLaunches(0, 1, false); | 570 ExpectReporterLaunches(0, 1, false); |
366 ExpectToRunAgain(kDaysBetweenSwReporterRunsForPendingPrompt); | 571 ExpectToRunAgain(kDaysBetweenSwReporterRunsForPendingPrompt); |
367 | 572 |
368 // Move the clock ahead kDaysBetweenSwReporterRunsForPendingPrompt days. The | 573 // Move the clock ahead kDaysBetweenSwReporterRunsForPendingPrompt days. The |
369 // expected run should trigger, but not cause the reporter to launch because | 574 // expected run should trigger, but not cause the reporter to launch because |
370 // a prompt is no longer pending. | 575 // a prompt is no longer pending. |
371 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, false); | 576 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, false); |
372 ExpectReporterLaunches(kDaysBetweenSwReporterRunsForPendingPrompt, 0, false); | 577 ExpectReporterLaunches(kDaysBetweenSwReporterRunsForPendingPrompt, 0, false); |
373 | 578 |
374 // Instead it should now run kDaysBetweenSuccessfulSwReporterRuns after the | 579 // Instead it should now run kDaysBetweenSuccessfulSwReporterRuns after the |
375 // first prompt (of which kDaysBetweenSwReporterRunsForPendingPrompt has | 580 // first prompt (of which kDaysBetweenSwReporterRunsForPendingPrompt has |
376 // already passed.) | 581 // already passed.) |
377 int days_left = kDaysBetweenSuccessfulSwReporterRuns - | 582 int days_left = kDaysBetweenSuccessfulSwReporterRuns - |
378 kDaysBetweenSwReporterRunsForPendingPrompt; | 583 kDaysBetweenSwReporterRunsForPendingPrompt; |
379 ExpectToRunAgain(days_left); | 584 ExpectToRunAgain(days_left); |
380 ExpectReporterLaunches(days_left, 1, false); | 585 ExpectReporterLaunches(days_left, 1, false); |
381 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 586 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
382 } | 587 } |
383 | 588 |
384 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ParameterChange) { | 589 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, ParameterChange) { |
385 // If the reporter is run several times with different parameters, it should | 590 // If the reporter is run several times with different parameters, it should |
386 // only be launched once, with the last parameter set. | 591 // only be launched once, with the last parameter set. |
387 const base::FilePath path1(L"path1"); | 592 const base::FilePath path1(L"path1"); |
388 const base::FilePath path2(L"path2"); | 593 const base::FilePath path2(L"path2"); |
389 const base::FilePath path3(L"path3"); | 594 const base::FilePath path3(L"path3"); |
390 | 595 |
391 // Schedule path1 with a day left in the reporting period. | 596 // Schedule path1 with a day left in the reporting period. |
392 // The reporter should not launch. | 597 // The reporter should not launch. |
393 constexpr int kDaysLeft = 1; | 598 constexpr int kDaysLeft = 1; |
394 { | 599 { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 { | 636 { |
432 SCOPED_TRACE("Run with same parameters"); | 637 SCOPED_TRACE("Run with same parameters"); |
433 RunReporter(kSwReporterNothingFound, path3); | 638 RunReporter(kSwReporterNothingFound, path3); |
434 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path3}, | 639 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path3}, |
435 false); | 640 false); |
436 } | 641 } |
437 | 642 |
438 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 643 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
439 } | 644 } |
440 | 645 |
441 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, MultipleLaunches) { | 646 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, MultipleLaunches) { |
442 const base::FilePath path1(L"path1"); | 647 const base::FilePath path1(L"path1"); |
443 const base::FilePath path2(L"path2"); | 648 const base::FilePath path2(L"path2"); |
444 const base::FilePath path3(L"path3"); | 649 const base::FilePath path3(L"path3"); |
445 | 650 |
446 SwReporterQueue invocations; | 651 SwReporterQueue invocations; |
447 invocations.push(SwReporterInvocation::FromFilePath(path1)); | 652 invocations.push(SwReporterInvocation::FromFilePath(path1)); |
448 invocations.push(SwReporterInvocation::FromFilePath(path2)); | 653 invocations.push(SwReporterInvocation::FromFilePath(path2)); |
449 | 654 |
450 { | 655 { |
451 SCOPED_TRACE("Launch 2 times"); | 656 SCOPED_TRACE("Launch 2 times"); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 // anything. | 704 // anything. |
500 ExpectReporterLaunches(0, {}, false); | 705 ExpectReporterLaunches(0, {}, false); |
501 | 706 |
502 // After enough time has passed, should try the queue again. | 707 // After enough time has passed, should try the queue again. |
503 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1}, | 708 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1}, |
504 false); | 709 false); |
505 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 710 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
506 } | 711 } |
507 } | 712 } |
508 | 713 |
509 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_NoSBExtendedReporting) { | 714 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, ReporterLogging_NoSBExtendedReporting) { |
510 base::test::ScopedFeatureList scoped_feature_list; | |
511 RunReporter(kSwReporterNothingFound); | 715 RunReporter(kSwReporterNothingFound); |
512 ExpectReporterLaunches(0, 1, false); | 716 ExpectReporterLaunches(0, 1, false); |
513 ExpectLoggingSwitches(reporter_launch_parameters_.front(), false); | 717 ExpectLoggingSwitches(reporter_launch_parameters_.front(), false); |
514 ExpectLastTimeSentReportNotSet(); | 718 ExpectLastTimeSentReportNotSet(); |
515 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 719 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
516 } | 720 } |
517 | 721 |
518 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledFirstRun) { | 722 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, ReporterLogging_EnabledFirstRun) { |
519 base::test::ScopedFeatureList scoped_feature_list; | |
520 EnableSBExtendedReporting(); | 723 EnableSBExtendedReporting(); |
521 // Note: don't set last time sent logs in the local state. | 724 // Note: don't set last time sent logs in the local state. |
522 // SBER is enabled and there is no record in the local state of the last time | 725 // SBER is enabled and there is no record in the local state of the last time |
523 // logs have been sent, so we should send logs in this run. | 726 // logs have been sent, so we should send logs in this run. |
524 RunReporter(kSwReporterNothingFound); | 727 RunReporter(kSwReporterNothingFound); |
525 ExpectReporterLaunches(0, 1, false); | 728 ExpectReporterLaunches(0, 1, false); |
526 ExpectLoggingSwitches(reporter_launch_parameters_.front(), true); | 729 ExpectLoggingSwitches(reporter_launch_parameters_.front(), true); |
527 ExpectLastReportSentInTheLastHour(); | 730 ExpectLastReportSentInTheLastHour(); |
528 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 731 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
529 } | 732 } |
530 | 733 |
531 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledNoRecentLogging) { | 734 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, ReporterLogging_EnabledNoRecentLogging) { |
532 base::test::ScopedFeatureList scoped_feature_list; | |
533 // SBER is enabled and last time logs were sent was more than | 735 // SBER is enabled and last time logs were sent was more than |
534 // |kDaysBetweenReporterLogsSent| day ago, so we should send logs in this run. | 736 // |kDaysBetweenReporterLogsSent| day ago, so we should send logs in this run. |
535 EnableSBExtendedReporting(); | 737 EnableSBExtendedReporting(); |
536 SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3); | 738 SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3); |
537 RunReporter(kSwReporterNothingFound); | 739 RunReporter(kSwReporterNothingFound); |
538 ExpectReporterLaunches(0, 1, false); | 740 ExpectReporterLaunches(0, 1, false); |
539 ExpectLoggingSwitches(reporter_launch_parameters_.front(), true); | 741 ExpectLoggingSwitches(reporter_launch_parameters_.front(), true); |
540 ExpectLastReportSentInTheLastHour(); | 742 ExpectLastReportSentInTheLastHour(); |
541 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 743 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
542 } | 744 } |
543 | 745 |
544 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledRecentlyLogged) { | 746 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, ReporterLogging_EnabledRecentlyLogged) { |
545 base::test::ScopedFeatureList scoped_feature_list; | |
546 // SBER is enabled, but logs have been sent less than | 747 // SBER is enabled, but logs have been sent less than |
547 // |kDaysBetweenReporterLogsSent| day ago, so we shouldn't send any logs in | 748 // |kDaysBetweenReporterLogsSent| day ago, so we shouldn't send any logs in |
548 // this run. | 749 // this run. |
549 EnableSBExtendedReporting(); | 750 EnableSBExtendedReporting(); |
550 SetLastTimeSentReport(kDaysBetweenReporterLogsSent - 1); | 751 SetLastTimeSentReport(kDaysBetweenReporterLogsSent - 1); |
551 int64_t last_time_sent_logs = GetLastTimeSentReport(); | 752 int64_t last_time_sent_logs = GetLastTimeSentReport(); |
552 RunReporter(kSwReporterNothingFound); | 753 RunReporter(kSwReporterNothingFound); |
553 ExpectReporterLaunches(0, 1, false); | 754 ExpectReporterLaunches(0, 1, false); |
554 ExpectLoggingSwitches(reporter_launch_parameters_.front(), false); | 755 ExpectLoggingSwitches(reporter_launch_parameters_.front(), false); |
555 EXPECT_EQ(last_time_sent_logs, GetLastTimeSentReport()); | 756 EXPECT_EQ(last_time_sent_logs, GetLastTimeSentReport()); |
556 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 757 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
557 } | 758 } |
558 | 759 |
559 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_MultipleLaunches) { | 760 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, ReporterLogging_MultipleLaunches) { |
560 base::test::ScopedFeatureList scoped_feature_list; | |
561 EnableSBExtendedReporting(); | 761 EnableSBExtendedReporting(); |
562 SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3); | 762 SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3); |
563 | 763 |
564 const base::FilePath path1(L"path1"); | 764 const base::FilePath path1(L"path1"); |
565 const base::FilePath path2(L"path2"); | 765 const base::FilePath path2(L"path2"); |
566 SwReporterQueue invocations; | 766 SwReporterQueue invocations; |
567 for (const auto& path : {path1, path2}) { | 767 for (const auto& path : {path1, path2}) { |
568 auto invocation = SwReporterInvocation::FromFilePath(path); | 768 auto invocation = SwReporterInvocation::FromFilePath(path); |
569 invocation.supported_behaviours = | 769 invocation.supported_behaviours = |
570 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS; | 770 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS; |
(...skipping 15 matching lines...) Expand all Loading... | |
586 // Logs should also be sent for the next run, even though LastTimeSentReport | 786 // Logs should also be sent for the next run, even though LastTimeSentReport |
587 // is now recent, because the run is part of the same set of invocations. | 787 // is now recent, because the run is part of the same set of invocations. |
588 { | 788 { |
589 SCOPED_TRACE("second launch"); | 789 SCOPED_TRACE("second launch"); |
590 ExpectLoggingSwitches(reporter_launch_parameters_[1], true); | 790 ExpectLoggingSwitches(reporter_launch_parameters_[1], true); |
591 ExpectLastReportSentInTheLastHour(); | 791 ExpectLastReportSentInTheLastHour(); |
592 } | 792 } |
593 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 793 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
594 } | 794 } |
595 | 795 |
796 INSTANTIATE_TEST_CASE_P(NoInBrowserCleanerUI, | |
797 SRTFetcherTest, | |
798 testing::Combine(testing::Values(false), | |
799 testing::Values(false))); | |
800 | |
801 INSTANTIATE_TEST_CASE_P(InBrowserCleanerUI, | |
802 SRTFetcherTest, | |
803 testing::Combine(testing::Values(true), | |
804 testing::Bool())); | |
805 | |
596 // This provide tests which allows explicit invocation of the SRT Prompt | 806 // This provide tests which allows explicit invocation of the SRT Prompt |
597 // useful for checking dialog layout or any other interactive functionality | 807 // useful for checking dialog layout or any other interactive functionality |
598 // tests. See docs/testing/test_browser_dialog.md for description of the | 808 // tests. See docs/testing/test_browser_dialog.md for description of the |
599 // testing framework. | 809 // testing framework. |
600 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorNoFile) { | 810 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorNoFile) { |
601 RunDialog(); | 811 RunDialog(); |
602 } | 812 } |
603 | 813 |
604 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorFile) { | 814 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorFile) { |
605 RunDialog(); | 815 RunDialog(); |
606 } | 816 } |
607 | 817 |
608 } // namespace safe_browsing | 818 } // namespace safe_browsing |
OLD | NEW |