Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: chrome/browser/safe_browsing/srt_fetcher_browsertest_win.cc

Issue 2844113002: Revert of Adds error handling support for the SwReporter launcher. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <set> 8 #include <set>
9 #include <tuple> 9 #include <tuple>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/callback.h" 15 #include "base/callback.h"
16 #include "base/callback_helpers.h" 16 #include "base/callback_helpers.h"
17 #include "base/files/file_path.h" 17 #include "base/files/file_path.h"
18 #include "base/macros.h"
19 #include "base/memory/ref_counted.h" 18 #include "base/memory/ref_counted.h"
20 #include "base/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
21 #include "base/run_loop.h" 20 #include "base/run_loop.h"
22 #include "base/strings/string_number_conversions.h" 21 #include "base/strings/string_number_conversions.h"
23 #include "base/test/multiprocess_test.h" 22 #include "base/test/multiprocess_test.h"
24 #include "base/test/scoped_feature_list.h" 23 #include "base/test/scoped_feature_list.h"
25 #include "base/test/test_mock_time_task_runner.h" 24 #include "base/test/test_mock_time_task_runner.h"
26 #include "base/threading/sequenced_task_runner_handle.h" 25 #include "base/threading/sequenced_task_runner_handle.h"
27 #include "base/threading/thread_task_runner_handle.h" 26 #include "base/threading/thread_task_runner_handle.h"
28 #include "base/time/time.h" 27 #include "base/time/time.h"
29 #include "base/version.h" 28 #include "base/version.h"
30 #include "chrome/browser/browser_process.h" 29 #include "chrome/browser/browser_process.h"
31 #include "chrome/browser/lifetime/keep_alive_types.h" 30 #include "chrome/browser/lifetime/keep_alive_types.h"
32 #include "chrome/browser/lifetime/scoped_keep_alive.h" 31 #include "chrome/browser/lifetime/scoped_keep_alive.h"
33 #include "chrome/browser/profiles/profile.h" 32 #include "chrome/browser/profiles/profile.h"
34 #include "chrome/browser/safe_browsing/srt_chrome_prompt_impl.h"
35 #include "chrome/browser/safe_browsing/srt_client_info_win.h" 33 #include "chrome/browser/safe_browsing/srt_client_info_win.h"
36 #include "chrome/browser/ui/browser.h" 34 #include "chrome/browser/ui/browser.h"
37 #include "chrome/browser/ui/browser_finder.h" 35 #include "chrome/browser/ui/browser_finder.h"
38 #include "chrome/browser/ui/test/test_browser_dialog.h" 36 #include "chrome/browser/ui/test/test_browser_dialog.h"
39 #include "chrome/common/pref_names.h" 37 #include "chrome/common/pref_names.h"
40 #include "chrome/test/base/in_process_browser_test.h" 38 #include "chrome/test/base/in_process_browser_test.h"
41 #include "components/chrome_cleaner/public/constants/constants.h" 39 #include "components/chrome_cleaner/public/constants/constants.h"
40 #include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
42 #include "components/component_updater/pref_names.h" 41 #include "components/component_updater/pref_names.h"
43 #include "components/prefs/pref_service.h" 42 #include "components/prefs/pref_service.h"
44 #include "components/safe_browsing_db/safe_browsing_prefs.h" 43 #include "components/safe_browsing_db/safe_browsing_prefs.h"
45 #include "mojo/edk/embedder/embedder.h" 44 #include "mojo/edk/embedder/embedder.h"
46 #include "mojo/edk/embedder/scoped_ipc_support.h" 45 #include "mojo/edk/embedder/scoped_ipc_support.h"
47 #include "mojo/edk/system/core.h" 46 #include "mojo/edk/system/core.h"
48 #include "testing/multiprocess_func_list.h" 47 #include "testing/multiprocess_func_list.h"
49 48
50 namespace safe_browsing { 49 namespace safe_browsing {
51 50
52 namespace { 51 namespace {
53 52
54 using chrome_cleaner::mojom::ElevationStatus; 53 using chrome_cleaner::mojom::ElevationStatus;
55 using chrome_cleaner::mojom::PromptAcceptance; 54 using chrome_cleaner::mojom::PromptAcceptance;
56 55
57 // Special switches passed by the parent process (test case) to the reporter 56 // Special switches passed by the parent process (test case) to the reporter
58 // child process to indicate the behavior that should be mocked. 57 // child process to indicate the behavior that should be mocked.
59 constexpr char kExitCodeToReturnSwitch[] = "exit-code-to-return"; 58 constexpr char kExitCodeToReturnSwitch[] = "exit-code-to-return";
60 constexpr char kReportUwSFoundSwitch[] = "report-uws-found"; 59 constexpr char kReportUwSFoundSwitch[] = "report-uws-found";
61 constexpr char kReportElevationRequiredSwitch[] = "report-elevation-required"; 60 constexpr char kReportElevationRequiredSwitch[] = "report-elevation-required";
62 constexpr char kExpectedPromptAcceptanceSwitch[] = "expected-prompt-acceptance"; 61 constexpr char kExpectedPromptAcceptanceSwitch[] = "expected-prompt-acceptance";
63 constexpr char kExpectedReporterFailureSwitch[] = "expected-reporter-crash";
64 62
65 // The exit code to be returned in case of failure in the child process. 63 // The exit code to be returned in case of failure in the child process.
66 // This should never be passed as the expected exit code to be reported by 64 // This should never be passed as the expected exit code to be reported by
67 // tests. 65 // tests.
68 constexpr int kFailureExitCode = -1; 66 constexpr int kFailureExitCode = -1;
69 67
70 // Pass the |prompt_acceptance| to the mock child process in command line 68 // Pass the |prompt_acceptance| to the mock child process in command line
71 // switch kExpectedPromptAcceptanceSwitch. 69 // switch kExpectedPromptAcceptanceSwitch.
72 void AddPromptAcceptanceToCommandLine(PromptAcceptance prompt_acceptance, 70 void AddPromptAcceptanceToCommandLine(PromptAcceptance prompt_acceptance,
73 base::CommandLine* command_line) { 71 base::CommandLine* command_line) {
(...skipping 16 matching lines...) Expand all
90 if (chrome_cleaner::mojom::IsKnownEnumValue(prompt_acceptance)) 88 if (chrome_cleaner::mojom::IsKnownEnumValue(prompt_acceptance))
91 return prompt_acceptance; 89 return prompt_acceptance;
92 } 90 }
93 return PromptAcceptance::UNSPECIFIED; 91 return PromptAcceptance::UNSPECIFIED;
94 } 92 }
95 93
96 // Pointer to ChromePromptPtr object to be used by the child process. The 94 // Pointer to ChromePromptPtr object to be used by the child process. The
97 // object must be created, deleted, and accessed on the IPC thread only. 95 // object must be created, deleted, and accessed on the IPC thread only.
98 chrome_cleaner::mojom::ChromePromptPtr* g_chrome_prompt_ptr = nullptr; 96 chrome_cleaner::mojom::ChromePromptPtr* g_chrome_prompt_ptr = nullptr;
99 97
100 // Potential failures in the reporter process that should be handled by the
101 // parent process.
102 enum class MockedReporterFailure {
103 kNone = 0,
104 // Crashes at specific moments in the reporter when connected to the IPC.
105 kCrashOnStartup = 1,
106 kCrashAfterConnectedToParentProcess = 2,
107 kCrashWhileWaitingForResponse = 3,
108 kCrashAfterReceivedResponse = 4,
109 // Once an IPC message is sent by the reporter, the parent process will
110 // report a bad message that will lead to an invocation of OnConnectionError.
111 kBadMessageReported = 5,
112 };
113
114 void AddExpectedCrashToCommandLine(MockedReporterFailure reporter_failure,
115 base::CommandLine* command_line) {
116 command_line->AppendSwitchASCII(
117 kExpectedReporterFailureSwitch,
118 base::IntToString(static_cast<int>(reporter_failure)));
119 }
120
121 void CrashIf(MockedReporterFailure reporter_failure) {
122 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
123 const std::string& expected_str =
124 command_line->GetSwitchValueASCII(kExpectedReporterFailureSwitch);
125 int val = -1;
126 if (base::StringToInt(expected_str, &val) &&
127 static_cast<MockedReporterFailure>(val) == reporter_failure) {
128 exit(kFailureExitCode);
129 }
130 }
131
132 // The callback function to be passed to ChromePrompt::PromptUser to check if 98 // The callback function to be passed to ChromePrompt::PromptUser to check if
133 // the prompt accepted returned by the parent process is equal to 99 // the prompt accepted returned by the parent process is equal to
134 // |expected_prompt_acceptance|. Will set |expected_value_received| with the 100 // |expected_prompt_acceptance|. Will set |expected_value_received| with the
135 // comparison result, so that the main thread can report failure. Will invoke 101 // comparison result, so that the main thread can report failure. Will invoke
136 // |done| callback when done. 102 // |done| callback when done.
137 void PromptUserCallback(const base::Closure& done, 103 void PromptUserCallback(const base::Closure& done,
138 PromptAcceptance expected_prompt_acceptance, 104 PromptAcceptance expected_prompt_acceptance,
139 bool* expected_value_received, 105 bool* expected_value_received,
140 PromptAcceptance prompt_acceptance) { 106 PromptAcceptance prompt_acceptance) {
141 *expected_value_received = prompt_acceptance == expected_prompt_acceptance; 107 *expected_value_received = prompt_acceptance == expected_prompt_acceptance;
142 // It's safe to delete the ChromePromptPtr object here, since it will not be 108 // It's safe to delete the ChromePromptPtr object here, since it will not be
143 // used anymore by the child process. 109 // used anymore by the child process.
144 delete g_chrome_prompt_ptr; 110 delete g_chrome_prompt_ptr;
145 g_chrome_prompt_ptr = nullptr; 111 g_chrome_prompt_ptr = nullptr;
146 CrashIf(MockedReporterFailure::kCrashAfterReceivedResponse);
147 done.Run(); 112 done.Run();
148 } 113 }
149 114
150 // Mocks the sending of scan results from the child process to the parent 115 // Mocks the sending of scan results from the child process to the parent
151 // process. Obtains the behavior to be mocked from special switches in 116 // process. Obtains the behavior to be mocked from special switches in
152 // |command_line|. Sets |expected_value_received| as true if the parent 117 // |command_line|. Sets |expected_value_received| as true if the parent
153 // process replies with the expected prompt acceptance value. 118 // process replies with the expected prompt acceptance value.
154 void SendScanResults(const std::string& chrome_mojo_pipe_token, 119 void SendScanResults(const std::string& chrome_mojo_pipe_token,
155 const base::CommandLine& command_line, 120 const base::CommandLine& command_line,
156 const base::Closure& done, 121 const base::Closure& done,
(...skipping 16 matching lines...) Expand all
173 uws->observed_behaviours = chrome_cleaner::mojom::ObservedBehaviours::New(); 138 uws->observed_behaviours = chrome_cleaner::mojom::ObservedBehaviours::New();
174 removable_uws_found.push_back(std::move(uws)); 139 removable_uws_found.push_back(std::move(uws));
175 } 140 }
176 const ElevationStatus elevation_status = 141 const ElevationStatus elevation_status =
177 command_line.HasSwitch(kReportElevationRequiredSwitch) 142 command_line.HasSwitch(kReportElevationRequiredSwitch)
178 ? ElevationStatus::REQUIRED 143 ? ElevationStatus::REQUIRED
179 : ElevationStatus::NOT_REQUIRED; 144 : ElevationStatus::NOT_REQUIRED;
180 const PromptAcceptance expected_prompt_acceptance = 145 const PromptAcceptance expected_prompt_acceptance =
181 PromptAcceptanceFromCommandLine(command_line); 146 PromptAcceptanceFromCommandLine(command_line);
182 147
183 // This task is posted to the IPC thread so that it will happen after the
184 // request is sent to the parent process and before the response gets
185 // handled on the IPC thread.
186 base::SequencedTaskRunnerHandle::Get()->PostTask(
187 FROM_HERE,
188 base::Bind(&CrashIf,
189 MockedReporterFailure::kCrashWhileWaitingForResponse));
190
191 (*g_chrome_prompt_ptr) 148 (*g_chrome_prompt_ptr)
192 ->PromptUser( 149 ->PromptUser(
193 std::move(removable_uws_found), elevation_status, 150 std::move(removable_uws_found), elevation_status,
194 base::Bind(&PromptUserCallback, done, expected_prompt_acceptance, 151 base::Bind(&PromptUserCallback, done, expected_prompt_acceptance,
195 expected_value_received)); 152 expected_value_received));
196 } 153 }
197 154
198 // Connects to the parent process and sends mocked scan results. Returns true 155 // Connects to the parent process and sends mocked scan results. Returns true
199 // if connection was successful and the prompt acceptance results sent by the 156 // if connection was successful and the prompt acceptance results sent by the
200 // parent process are the same as expected. 157 // parent process are the same as expected.
201 bool ConnectAndSendDataToParentProcess( 158 bool ConnectAndSendDataToParentProcess(
202 const std::string& chrome_mojo_pipe_token, 159 const std::string& chrome_mojo_pipe_token,
203 const base::CommandLine& command_line) { 160 const base::CommandLine& command_line) {
204 DCHECK(!chrome_mojo_pipe_token.empty()); 161 DCHECK(!chrome_mojo_pipe_token.empty());
205 162
206 mojo::edk::Init(); 163 mojo::edk::Init();
207 base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); 164 base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
208 base::Thread io_thread("IPCThread"); 165 base::Thread io_thread("IPCThread");
209 if (!io_thread.StartWithOptions(options)) 166 if (!io_thread.StartWithOptions(options))
210 return false; 167 return false;
211 mojo::edk::ScopedIPCSupport ipc_support( 168 mojo::edk::ScopedIPCSupport ipc_support(
212 io_thread.task_runner(), 169 io_thread.task_runner(),
213 mojo::edk::ScopedIPCSupport::ShutdownPolicy::CLEAN); 170 mojo::edk::ScopedIPCSupport::ShutdownPolicy::CLEAN);
214 mojo::edk::SetParentPipeHandleFromCommandLine(); 171 mojo::edk::SetParentPipeHandleFromCommandLine();
215
216 CrashIf(MockedReporterFailure::kCrashAfterConnectedToParentProcess);
217
218 base::MessageLoop message_loop; 172 base::MessageLoop message_loop;
219 base::RunLoop run_loop; 173 base::RunLoop run_loop;
220 // After the response from the parent process is received, this will post a 174 // After the response from the parent process is received, this will post a
221 // task to unblock the child process's main thread. 175 // task to unblock the child process's main thread.
222 auto done = base::Bind( 176 auto done = base::Bind(
223 [](scoped_refptr<base::SequencedTaskRunner> main_runner, 177 [](scoped_refptr<base::SequencedTaskRunner> main_runner,
224 base::Closure quit_closure) { 178 base::Closure quit_closure) {
225 main_runner->PostTask(FROM_HERE, std::move(quit_closure)); 179 main_runner->PostTask(FROM_HERE, std::move(quit_closure));
226 }, 180 },
227 base::SequencedTaskRunnerHandle::Get(), 181 base::SequencedTaskRunnerHandle::Get(),
228 base::Passed(run_loop.QuitClosure())); 182 base::Passed(run_loop.QuitClosure()));
229 183
230 bool expected_value_received = false; 184 bool expected_value_received = false;
231 io_thread.task_runner()->PostTask( 185 io_thread.task_runner()->PostTask(
232 FROM_HERE, base::Bind(&SendScanResults, chrome_mojo_pipe_token, 186 FROM_HERE, base::Bind(&SendScanResults, chrome_mojo_pipe_token,
233 command_line, done, &expected_value_received)); 187 command_line, done, &expected_value_received));
234
235 run_loop.Run(); 188 run_loop.Run();
236 189
237 return expected_value_received; 190 return expected_value_received;
238 } 191 }
239 192
240 // Mocks a Software Reporter process that returns an exit code specified by 193 // Mocks a Software Reporter process that returns an exit code specified by
241 // command line switch kExitCodeToReturnSwitch. If a Mojo IPC is available, 194 // command line switch kExitCodeToReturnSwitch. If a Mojo IPC is available,
242 // this will also connect to the parent process and send mocked scan results 195 // this will also connect to the parent process and send mocked scan results
243 // to the parent process using data passed as command line switches. 196 // to the parent process using data passed as command line switches.
244 MULTIPROCESS_TEST_MAIN(MockSwReporterProcess) { 197 MULTIPROCESS_TEST_MAIN(MockSwReporterProcess) {
245 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 198 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
246 CrashIf(MockedReporterFailure::kCrashOnStartup);
247 const std::string& str = 199 const std::string& str =
248 command_line->GetSwitchValueASCII(kExitCodeToReturnSwitch); 200 command_line->GetSwitchValueASCII(kExitCodeToReturnSwitch);
249 const std::string& chrome_mojo_pipe_token = command_line->GetSwitchValueASCII( 201 const std::string& chrome_mojo_pipe_token = command_line->GetSwitchValueASCII(
250 chrome_cleaner::kChromeMojoPipeTokenSwitch); 202 chrome_cleaner::kChromeMojoPipeTokenSwitch);
251 int exit_code_to_report = kFailureExitCode; 203 int exit_code_to_report = kFailureExitCode;
252 bool success = base::StringToInt(str, &exit_code_to_report) && 204 bool success = base::StringToInt(str, &exit_code_to_report) &&
253 (chrome_mojo_pipe_token.empty() || 205 (chrome_mojo_pipe_token.empty() ||
254 ConnectAndSendDataToParentProcess(chrome_mojo_pipe_token, 206 ConnectAndSendDataToParentProcess(chrome_mojo_pipe_token,
255 *command_line)); 207 *command_line));
256 return success ? exit_code_to_report : kFailureExitCode; 208 return success ? exit_code_to_report : kFailureExitCode;
257 } 209 }
258 210
259 // Decorates a ChromePromptImpl object to simulate failures indentified by the
260 // parent process and keeps track of errors handled. By default, delegates all
261 // actions to the decorated object.
262 class ReportBadMessageChromePromptImpl : public ChromePromptImpl {
263 public:
264 ReportBadMessageChromePromptImpl(
265 chrome_cleaner::mojom::ChromePromptRequest request,
266 bool bad_message_expected,
267 base::Closure on_connection_closed)
268 : ChromePromptImpl(std::move(request), std::move(on_connection_closed)),
269 bad_message_expected_(bad_message_expected) {}
270 ~ReportBadMessageChromePromptImpl() override = default;
271
272 void PromptUser(
273 std::vector<chrome_cleaner::mojom::UwSPtr> removable_uws_found,
274 chrome_cleaner::mojom::ElevationStatus elevation_status,
275 const chrome_cleaner::mojom::ChromePrompt::PromptUserCallback& callback)
276 override {
277 if (bad_message_expected_)
278 mojo::ReportBadMessage("bad message");
279
280 ChromePromptImpl::PromptUser(std::move(removable_uws_found),
281 elevation_status, callback);
282 }
283
284 private:
285 bool bad_message_expected_ = false;
286
287 DISALLOW_COPY_AND_ASSIGN(ReportBadMessageChromePromptImpl);
288 };
289
290 // Parameters for this test: 211 // Parameters for this test:
291 // - bool in_browser_cleaner_ui: indicates if InBrowserCleanerUI experiment 212 // - bool in_browser_cleaner_ui: indicates if InBrowserCleanerUI experiment
292 // is enabled; if so, the parent and the child processes will communicate 213 // is enabled; if so, the parent and the child processes will communicate
293 // via a Mojo IPC. 214 // via a Mojo IPC;
294 // - ElevationStatus elevation_status: indicates if the scan results sent by 215 // - ElevationStatus elevation_status: indicates if the scan results sent by
295 // the child process should consider that elevation will be required for 216 // the child process should consider that elevation will be required for
296 // cleanup. 217 // cleanup.
297 // - MockedReporterFailure expected_reporter_failure: indicates errors that
298 // should be simulated in the reporter process.
299 class SRTFetcherTest 218 class SRTFetcherTest
300 : public InProcessBrowserTest, 219 : public InProcessBrowserTest,
301 public SwReporterTestingDelegate, 220 public SwReporterTestingDelegate,
302 public ::testing::WithParamInterface< 221 public ::testing::WithParamInterface<std::tuple<bool, ElevationStatus>> {
303 std::tuple<bool, ElevationStatus, MockedReporterFailure>> {
304 public: 222 public:
305 SRTFetcherTest() = default;
306
307 void SetUpInProcessBrowserTestFixture() override { 223 void SetUpInProcessBrowserTestFixture() override {
308 SetSwReporterTestingDelegate(this); 224 SetSwReporterTestingDelegate(this);
309 225
310 std::tie(in_browser_cleaner_ui_, elevation_status_, 226 std::tie(in_browser_cleaner_ui_, elevation_status_) = GetParam();
311 expected_reporter_failure_) = GetParam();
312 // The config should only accept elevation_status_ if InBrowserCleanerUI 227 // The config should only accept elevation_status_ if InBrowserCleanerUI
313 // feature is enabled. 228 // feature is enabled.
314 ASSERT_TRUE(elevation_status_ == ElevationStatus::NOT_REQUIRED || 229 ASSERT_TRUE(elevation_status_ == ElevationStatus::NOT_REQUIRED ||
315 in_browser_cleaner_ui_); 230 in_browser_cleaner_ui_);
316 231
317 if (in_browser_cleaner_ui_) 232 if (in_browser_cleaner_ui_)
318 scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature); 233 scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature);
319 else 234 else
320 scoped_feature_list_.InitAndDisableFeature(kInBrowserCleanerUIFeature); 235 scoped_feature_list_.InitAndDisableFeature(kInBrowserCleanerUIFeature);
321 } 236 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 // process. 273 // process.
359 // Records the launch and parameters used for further verification. 274 // Records the launch and parameters used for further verification.
360 base::Process LaunchReporter( 275 base::Process LaunchReporter(
361 const SwReporterInvocation& invocation, 276 const SwReporterInvocation& invocation,
362 const base::LaunchOptions& launch_options) override { 277 const base::LaunchOptions& launch_options) override {
363 ++reporter_launch_count_; 278 ++reporter_launch_count_;
364 reporter_launch_parameters_.push_back(invocation); 279 reporter_launch_parameters_.push_back(invocation);
365 if (first_launch_callback_) 280 if (first_launch_callback_)
366 std::move(first_launch_callback_).Run(); 281 std::move(first_launch_callback_).Run();
367 282
368 if (exit_code_to_report_ == kReporterNotLaunchedExitCode)
369 return base::Process(); // IsValid() will return false.
370
371 base::CommandLine command_line( 283 base::CommandLine command_line(
372 base::GetMultiProcessTestChildBaseCommandLine()); 284 base::GetMultiProcessTestChildBaseCommandLine());
373 command_line.AppendArguments(invocation.command_line, 285 command_line.AppendArguments(invocation.command_line,
374 /*include_program=*/false); 286 /*include_program=*/false);
375 command_line.AppendSwitchASCII(kExitCodeToReturnSwitch, 287 command_line.AppendSwitchASCII(kExitCodeToReturnSwitch,
376 base::IntToString(exit_code_to_report_)); 288 base::IntToString(exit_code_to_report_));
377
378 if (in_browser_cleaner_ui_) { 289 if (in_browser_cleaner_ui_) {
379 AddPromptAcceptanceToCommandLine(PromptAcceptance::DENIED, &command_line); 290 AddPromptAcceptanceToCommandLine(PromptAcceptance::DENIED, &command_line);
380 if (exit_code_to_report_ == chrome_cleaner::kSwReporterCleanupNeeded) { 291 if (exit_code_to_report_ == chrome_cleaner::kSwReporterCleanupNeeded) {
381 command_line.AppendSwitch(kReportUwSFoundSwitch); 292 command_line.AppendSwitch(kReportUwSFoundSwitch);
382 if (elevation_status_ == ElevationStatus::REQUIRED) 293 if (elevation_status_ == ElevationStatus::REQUIRED)
383 command_line.AppendSwitch(kReportElevationRequiredSwitch); 294 command_line.AppendSwitch(kReportElevationRequiredSwitch);
384 } 295 }
385 } 296 }
386
387 if (expected_reporter_failure_ != MockedReporterFailure::kNone)
388 AddExpectedCrashToCommandLine(expected_reporter_failure_, &command_line);
389
390 bad_message_expected_ = expected_reporter_failure_ ==
391 MockedReporterFailure::kBadMessageReported;
392 bad_message_reported_ = false;
393
394 base::SpawnChildResult result = base::SpawnMultiProcessTestChild( 297 base::SpawnChildResult result = base::SpawnMultiProcessTestChild(
395 "MockSwReporterProcess", command_line, launch_options); 298 "MockSwReporterProcess", command_line, launch_options);
396 return std::move(result.process); 299 return std::move(result.process);
397 } 300 }
398 301
399 // Returns the test's idea of the current time. 302 // Returns the test's idea of the current time.
400 base::Time Now() const override { return mock_time_task_runner_->Now(); } 303 base::Time Now() const override { return mock_time_task_runner_->Now(); }
401 304
402 // Returns a task runner to use when launching the reporter (which is 305 // Returns a task runner to use when launching the reporter (which is
403 // normally a blocking action). 306 // normally a blocking action).
404 base::TaskRunner* BlockingTaskRunner() const override { 307 base::TaskRunner* BlockingTaskRunner() const override {
405 // Use the test's main task runner so that we don't need to pump another 308 // Use the test's main task runner so that we don't need to pump another
406 // message loop. Since the test calls LaunchReporter instead of actually 309 // message loop. Since the test calls LaunchReporter instead of actually
407 // doing a blocking reporter launch, it doesn't matter that the task runner 310 // doing a blocking reporter launch, it doesn't matter that the task runner
408 // doesn't have the MayBlock trait. 311 // doesn't have the MayBlock trait.
409 return mock_time_task_runner_.get(); 312 return mock_time_task_runner_.get();
410 } 313 }
411 314
412 std::unique_ptr<ChromePromptImpl> CreateChromePromptImpl(
413 chrome_cleaner::mojom::ChromePromptRequest request) override {
414 return base::MakeUnique<ReportBadMessageChromePromptImpl>(
415 std::move(request), bad_message_expected_,
416 base::Bind(&SRTFetcherTest::OnConnectionClosed,
417 base::Unretained(this)));
418 }
419
420 void OnConnectionClosed() override {}
421
422 void OnConnectionError(const std::string& message) override {
423 bad_message_reported_ = true;
424 }
425
426 // Schedules a single reporter to run. 315 // Schedules a single reporter to run.
427 void RunReporter(int exit_code_to_report, 316 void RunReporter(int exit_code_to_report,
428 const base::FilePath& exe_path = base::FilePath()) { 317 const base::FilePath& exe_path = base::FilePath()) {
429 exit_code_to_report_ = exit_code_to_report; 318 exit_code_to_report_ = exit_code_to_report;
430 auto invocation = SwReporterInvocation::FromFilePath(exe_path); 319 auto invocation = SwReporterInvocation::FromFilePath(exe_path);
431 invocation.supported_behaviours = 320 invocation.supported_behaviours =
432 SwReporterInvocation::BEHAVIOUR_LOG_EXIT_CODE_TO_PREFS | 321 SwReporterInvocation::BEHAVIOUR_LOG_EXIT_CODE_TO_PREFS |
433 SwReporterInvocation::BEHAVIOUR_TRIGGER_PROMPT | 322 SwReporterInvocation::BEHAVIOUR_TRIGGER_PROMPT |
434 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS; 323 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS;
435 324
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 bool expect_prompt) { 393 bool expect_prompt) {
505 EXPECT_TRUE(mock_time_task_runner_->HasPendingTask()); 394 EXPECT_TRUE(mock_time_task_runner_->HasPendingTask());
506 reporter_launch_count_ = 0; 395 reporter_launch_count_ = 0;
507 reporter_launch_parameters_.clear(); 396 reporter_launch_parameters_.clear();
508 prompt_trigger_called_ = false; 397 prompt_trigger_called_ = false;
509 398
510 mock_time_task_runner_->FastForwardBy( 399 mock_time_task_runner_->FastForwardBy(
511 base::TimeDelta::FromDays(days_until_launch)); 400 base::TimeDelta::FromDays(days_until_launch));
512 401
513 EXPECT_EQ(expected_launch_count, reporter_launch_count_); 402 EXPECT_EQ(expected_launch_count, reporter_launch_count_);
514 // Note: a bad message error will not prevent the prompt that is shown to 403 EXPECT_EQ(expect_prompt, prompt_trigger_called_);
515 // the user today. Once we hook the new prompt here, we will need to review
516 // this expectation.
517 EXPECT_EQ(expect_prompt &&
518 (expected_reporter_failure_ == MockedReporterFailure::kNone ||
519 expected_reporter_failure_ ==
520 MockedReporterFailure::kBadMessageReported),
521 prompt_trigger_called_);
522
523 EXPECT_EQ(bad_message_expected_, bad_message_reported_);
524 } 404 }
525 405
526 // Expects that after |days_until_launched| days, the reporter will be 406 // Expects that after |days_until_launched| days, the reporter will be
527 // launched once with each path in |expected_launch_paths|, and TriggerPrompt 407 // launched once with each path in |expected_launch_paths|, and TriggerPrompt
528 // will be called if and only if |expect_prompt| is true. 408 // will be called if and only if |expect_prompt| is true.
529 void ExpectReporterLaunches( 409 void ExpectReporterLaunches(
530 int days_until_launch, 410 int days_until_launch,
531 const std::vector<base::FilePath>& expected_launch_paths, 411 const std::vector<base::FilePath>& expected_launch_paths,
532 bool expect_prompt) { 412 bool expect_prompt) {
533 ExpectReporterLaunches(days_until_launch, expected_launch_paths.size(), 413 ExpectReporterLaunches(days_until_launch, expected_launch_paths.size(),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 460
581 // A task runner with a mock clock. 461 // A task runner with a mock clock.
582 scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner_ = 462 scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner_ =
583 new base::TestMockTimeTaskRunner(); 463 new base::TestMockTimeTaskRunner();
584 464
585 // The task runner that was in use before installing |mock_time_task_runner_|. 465 // The task runner that was in use before installing |mock_time_task_runner_|.
586 scoped_refptr<base::SingleThreadTaskRunner> saved_task_runner_; 466 scoped_refptr<base::SingleThreadTaskRunner> saved_task_runner_;
587 467
588 bool in_browser_cleaner_ui_; 468 bool in_browser_cleaner_ui_;
589 ElevationStatus elevation_status_; 469 ElevationStatus elevation_status_;
590 MockedReporterFailure expected_reporter_failure_;
591
592 // Indicates if a bad message error should be simulated by the parent
593 // process.
594 bool bad_message_expected_;
595
596 // Set by ReportBadMessageChromePromptImpl if a bad message error is reported.
597 bool bad_message_reported_;
598 470
599 bool prompt_trigger_called_ = false; 471 bool prompt_trigger_called_ = false;
600 int reporter_launch_count_ = 0; 472 int reporter_launch_count_ = 0;
601 std::vector<SwReporterInvocation> reporter_launch_parameters_; 473 std::vector<SwReporterInvocation> reporter_launch_parameters_;
602 int exit_code_to_report_ = kReporterNotLaunchedExitCode; 474 int exit_code_to_report_ = kReporterFailureExitCode;
603 475
604 // A callback to invoke when the first reporter of a queue is launched. This 476 // A callback to invoke when the first reporter of a queue is launched. This
605 // can be used to perform actions in the middle of a queue of reporters which 477 // can be used to perform actions in the middle of a queue of reporters which
606 // all launch on the same mock clock tick. 478 // all launch on the same mock clock tick.
607 base::OnceClosure first_launch_callback_; 479 base::OnceClosure first_launch_callback_;
608 480
609 base::test::ScopedFeatureList scoped_feature_list_; 481 base::test::ScopedFeatureList scoped_feature_list_;
610
611 DISALLOW_COPY_AND_ASSIGN(SRTFetcherTest);
612 }; 482 };
613 483
614 class SRTFetcherPromptTest : public DialogBrowserTest { 484 class SRTFetcherPromptTest : public DialogBrowserTest {
615 public: 485 public:
616 void ShowDialog(const std::string& name) override { 486 void ShowDialog(const std::string& name) override {
617 if (name == "SRTErrorNoFile") 487 if (name == "SRTErrorNoFile")
618 DisplaySRTPromptForTesting(base::FilePath()); 488 DisplaySRTPromptForTesting(base::FilePath());
619 else if (name == "SRTErrorFile") 489 else if (name == "SRTErrorFile")
620 DisplaySRTPromptForTesting( 490 DisplaySRTPromptForTesting(
621 base::FilePath().Append(FILE_PATH_LITERAL("c:\temp\testfile.txt"))); 491 base::FilePath().Append(FILE_PATH_LITERAL("c:\temp\testfile.txt")));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(10)); 553 mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(10));
684 554
685 // On opening the new browser, the prompt should be shown and the reporter 555 // On opening the new browser, the prompt should be shown and the reporter
686 // should be scheduled to run later. 556 // should be scheduled to run later.
687 EXPECT_EQ(1, reporter_launch_count_); 557 EXPECT_EQ(1, reporter_launch_count_);
688 EXPECT_TRUE(prompt_trigger_called_); 558 EXPECT_TRUE(prompt_trigger_called_);
689 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 559 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
690 } 560 }
691 561
692 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, Failure) { 562 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, Failure) {
693 RunReporter(kReporterNotLaunchedExitCode); 563 RunReporter(kReporterFailureExitCode);
694 ExpectReporterLaunches(0, 1, false); 564 ExpectReporterLaunches(0, 1, false);
695 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 565 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
696 } 566 }
697 567
698 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, RunDaily) { 568 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, RunDaily) {
699 PrefService* local_state = g_browser_process->local_state(); 569 PrefService* local_state = g_browser_process->local_state();
700 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, true); 570 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, true);
701 SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - 1); 571 SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - 1);
702 ASSERT_GT(kDaysBetweenSuccessfulSwReporterRuns - 1, 572 ASSERT_GT(kDaysBetweenSuccessfulSwReporterRuns - 1,
703 kDaysBetweenSwReporterRunsForPendingPrompt); 573 kDaysBetweenSwReporterRunsForPendingPrompt);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 696
827 // Time passes... Now the 3-element queue should run. 697 // Time passes... Now the 3-element queue should run.
828 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, 698 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns,
829 {path1, path2, path3}, false); 699 {path1, path2, path3}, false);
830 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 700 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
831 } 701 }
832 702
833 // Second launch should not occur after a failure. 703 // Second launch should not occur after a failure.
834 { 704 {
835 SCOPED_TRACE("Launch multiple times with failure"); 705 SCOPED_TRACE("Launch multiple times with failure");
836 RunReporterQueue(kReporterNotLaunchedExitCode, invocations); 706 RunReporterQueue(kReporterFailureExitCode, invocations);
837 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1}, 707 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1},
838 false); 708 false);
839 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 709 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
840 710
841 // If we try again before the reporting period is up, it should not do 711 // If we try again before the reporting period is up, it should not do
842 // anything. 712 // anything.
843 ExpectReporterLaunches(0, {}, false); 713 ExpectReporterLaunches(0, {}, false);
844 714
845 // After enough time has passed, should try the queue again. 715 // After enough time has passed, should try the queue again.
846 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1}, 716 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1},
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 ExpectLoggingSwitches(reporter_launch_parameters_[1], true); 798 ExpectLoggingSwitches(reporter_launch_parameters_[1], true);
929 ExpectLastReportSentInTheLastHour(); 799 ExpectLastReportSentInTheLastHour();
930 } 800 }
931 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 801 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
932 } 802 }
933 803
934 INSTANTIATE_TEST_CASE_P( 804 INSTANTIATE_TEST_CASE_P(
935 NoInBrowserCleanerUI, 805 NoInBrowserCleanerUI,
936 SRTFetcherTest, 806 SRTFetcherTest,
937 testing::Combine(testing::Values(false), 807 testing::Combine(testing::Values(false),
938 testing::Values(ElevationStatus::NOT_REQUIRED), 808 testing::Values(ElevationStatus::NOT_REQUIRED)));
939 testing::Values(MockedReporterFailure::kNone,
940 MockedReporterFailure::kCrashOnStartup)));
941 809
942 INSTANTIATE_TEST_CASE_P( 810 INSTANTIATE_TEST_CASE_P(
943 InBrowserCleanerUI, 811 InBrowserCleanerUI,
944 SRTFetcherTest, 812 SRTFetcherTest,
945 testing::Combine( 813 testing::Combine(testing::Values(true),
946 testing::Values(true), 814 testing::Values(ElevationStatus::NOT_REQUIRED,
947 testing::Values(ElevationStatus::NOT_REQUIRED, 815 ElevationStatus::REQUIRED)));
948 ElevationStatus::REQUIRED),
949 testing::Values(
950 MockedReporterFailure::kNone,
951 MockedReporterFailure::kCrashOnStartup,
952 MockedReporterFailure::kCrashAfterConnectedToParentProcess,
953 MockedReporterFailure::kCrashWhileWaitingForResponse,
954 MockedReporterFailure::kCrashAfterReceivedResponse,
955 MockedReporterFailure::kBadMessageReported)));
956 816
957 // This provide tests which allows explicit invocation of the SRT Prompt 817 // This provide tests which allows explicit invocation of the SRT Prompt
958 // useful for checking dialog layout or any other interactive functionality 818 // useful for checking dialog layout or any other interactive functionality
959 // tests. See docs/testing/test_browser_dialog.md for description of the 819 // tests. See docs/testing/test_browser_dialog.md for description of the
960 // testing framework. 820 // testing framework.
961 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorNoFile) { 821 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorNoFile) {
962 RunDialog(); 822 RunDialog();
963 } 823 }
964 824
965 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorFile) { 825 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorFile) {
966 RunDialog(); 826 RunDialog();
967 } 827 }
968 828
969 } // namespace safe_browsing 829 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/srt_chrome_prompt_impl.cc ('k') | chrome/browser/safe_browsing/srt_fetcher_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698