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

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

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

Powered by Google App Engine
This is Rietveld 408576698