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

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: 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 on 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 class BadMessageTestDelegate : public ChromePromptImpl::TestDelegate {
260 public:
261 void OnPromptUser() override { mojo::ReportBadMessage("bad message"); }
262 void OnConnectionError() override { bad_message_reported_ = true; }
263
264 bool bad_message_reported() const { return bad_message_reported_; }
265
266 private:
267 bool bad_message_reported_ = false;
268 };
269
211 // Parameters for this test: 270 // Parameters for this test:
212 // - bool in_browser_cleaner_ui: indicates if InBrowserCleanerUI experiment 271 // - bool in_browser_cleaner_ui: indicates if InBrowserCleanerUI experiment
213 // is enabled; if so, the parent and the child processes will communicate 272 // is enabled; if so, the parent and the child processes will communicate
214 // via a Mojo IPC; 273 // via a Mojo IPC;
215 // - ElevationStatus elevation_status: indicates if the scan results sent by 274 // - ElevationStatus elevation_status: indicates if the scan results sent by
216 // the child process should consider that elevation will be required for 275 // the child process should consider that elevation will be required for
217 // cleanup. 276 // cleanup.
218 class SRTFetcherTest 277 class SRTFetcherTest
219 : public InProcessBrowserTest, 278 : public InProcessBrowserTest,
220 public SwReporterTestingDelegate, 279 public SwReporterTestingDelegate,
221 public ::testing::WithParamInterface<std::tuple<bool, ElevationStatus>> { 280 public ::testing::WithParamInterface<
281 std::tuple<bool, ElevationStatus, MockedReporterFailure>> {
grt (UTC plus 2) 2017/04/21 11:10:58 please add a note about this param to the doc comm
ftirelo 2017/04/24 15:47:45 Done.
222 public: 282 public:
223 void SetUpInProcessBrowserTestFixture() override { 283 void SetUpInProcessBrowserTestFixture() override {
224 SetSwReporterTestingDelegate(this); 284 SetSwReporterTestingDelegate(this);
225 285
226 std::tie(in_browser_cleaner_ui_, elevation_status_) = GetParam(); 286 std::tie(in_browser_cleaner_ui_, elevation_status_,
287 expected_reporter_failure_) = GetParam();
227 // The config should only accept elevation_status_ if InBrowserCleanerUI 288 // The config should only accept elevation_status_ if InBrowserCleanerUI
228 // feature is enabled. 289 // feature is enabled.
229 ASSERT_TRUE(elevation_status_ == ElevationStatus::NOT_REQUIRED || 290 ASSERT_TRUE(elevation_status_ == ElevationStatus::NOT_REQUIRED ||
230 in_browser_cleaner_ui_); 291 in_browser_cleaner_ui_);
231 292
232 if (in_browser_cleaner_ui_) 293 if (in_browser_cleaner_ui_)
233 scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature); 294 scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature);
234 else 295 else
235 scoped_feature_list_.InitAndDisableFeature(kInBrowserCleanerUIFeature); 296 scoped_feature_list_.InitAndDisableFeature(kInBrowserCleanerUIFeature);
297
298 chrome_prompt_test_delegate_.reset();
grt (UTC plus 2) 2017/04/21 11:10:58 isn't this a noop?
ftirelo 2017/04/24 15:47:45 This was misplaced. Moved to LaunchReporter() sinc
236 } 299 }
237 300
238 void SetUpOnMainThread() override { 301 void SetUpOnMainThread() override {
239 // During the test, use a task runner with a mock clock. 302 // During the test, use a task runner with a mock clock.
240 saved_task_runner_ = base::ThreadTaskRunnerHandle::Get(); 303 saved_task_runner_ = base::ThreadTaskRunnerHandle::Get();
241 ASSERT_NE(mock_time_task_runner_, saved_task_runner_); 304 ASSERT_NE(mock_time_task_runner_, saved_task_runner_);
242 base::MessageLoop::current()->SetTaskRunner(mock_time_task_runner_); 305 base::MessageLoop::current()->SetTaskRunner(mock_time_task_runner_);
243 306
244 InProcessBrowserTest::SetUpOnMainThread(); 307 InProcessBrowserTest::SetUpOnMainThread();
245 308
(...skipping 27 matching lines...) Expand all
273 // process. 336 // process.
274 // Records the launch and parameters used for further verification. 337 // Records the launch and parameters used for further verification.
275 base::Process LaunchReporter( 338 base::Process LaunchReporter(
276 const SwReporterInvocation& invocation, 339 const SwReporterInvocation& invocation,
277 const base::LaunchOptions& launch_options) override { 340 const base::LaunchOptions& launch_options) override {
278 ++reporter_launch_count_; 341 ++reporter_launch_count_;
279 reporter_launch_parameters_.push_back(invocation); 342 reporter_launch_parameters_.push_back(invocation);
280 if (first_launch_callback_) 343 if (first_launch_callback_)
281 std::move(first_launch_callback_).Run(); 344 std::move(first_launch_callback_).Run();
282 345
346 if (exit_code_to_report_ == kReporterNotLaunchedExitCode)
347 return base::Process(); // IsValid() will return false.
348
283 base::CommandLine command_line( 349 base::CommandLine command_line(
284 base::GetMultiProcessTestChildBaseCommandLine()); 350 base::GetMultiProcessTestChildBaseCommandLine());
285 command_line.AppendArguments(invocation.command_line, 351 command_line.AppendArguments(invocation.command_line,
286 /*include_program=*/false); 352 /*include_program=*/false);
287 command_line.AppendSwitchASCII(kExitCodeToReturnSwitch, 353 command_line.AppendSwitchASCII(kExitCodeToReturnSwitch,
288 base::IntToString(exit_code_to_report_)); 354 base::IntToString(exit_code_to_report_));
355
289 if (in_browser_cleaner_ui_) { 356 if (in_browser_cleaner_ui_) {
290 AddPromptAcceptanceToCommandLine(PromptAcceptance::DENIED, &command_line); 357 AddPromptAcceptanceToCommandLine(PromptAcceptance::DENIED, &command_line);
291 if (exit_code_to_report_ == chrome_cleaner::kSwReporterCleanupNeeded) { 358 if (exit_code_to_report_ == chrome_cleaner::kSwReporterCleanupNeeded) {
292 command_line.AppendSwitch(kReportUwSFoundSwitch); 359 command_line.AppendSwitch(kReportUwSFoundSwitch);
293 if (elevation_status_ == ElevationStatus::REQUIRED) 360 if (elevation_status_ == ElevationStatus::REQUIRED)
294 command_line.AppendSwitch(kReportElevationRequiredSwitch); 361 command_line.AppendSwitch(kReportElevationRequiredSwitch);
295 } 362 }
296 } 363 }
364
365 if (expected_reporter_failure_ != MockedReporterFailure::kNone)
366 AddExpectedCrashToCommandLine(expected_reporter_failure_, &command_line);
367
368 if (expected_reporter_failure_ ==
369 MockedReporterFailure::kBadMessageReported)
370 chrome_prompt_test_delegate_ = base::MakeUnique<BadMessageTestDelegate>();
grt (UTC plus 2) 2017/04/21 11:10:58 nit: braces around this
ftirelo 2017/04/24 15:47:45 Done.
371 ChromePromptImpl::SetTestDelegate(chrome_prompt_test_delegate_.get());
grt (UTC plus 2) 2017/04/21 11:10:58 clear the delegate in TearDownInProcessBrowserTest
ftirelo 2017/04/24 15:47:45 Moved cleanup to LaunchReporter(), since we only n
372
297 base::SpawnChildResult result = base::SpawnMultiProcessTestChild( 373 base::SpawnChildResult result = base::SpawnMultiProcessTestChild(
298 "MockSwReporterProcess", command_line, launch_options); 374 "MockSwReporterProcess", command_line, launch_options);
299 return std::move(result.process); 375 return std::move(result.process);
300 } 376 }
301 377
302 // Returns the test's idea of the current time. 378 // Returns the test's idea of the current time.
303 base::Time Now() const override { return mock_time_task_runner_->Now(); } 379 base::Time Now() const override { return mock_time_task_runner_->Now(); }
304 380
305 // Returns a task runner to use when launching the reporter (which is 381 // Returns a task runner to use when launching the reporter (which is
306 // normally a blocking action). 382 // normally a blocking action).
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 bool expect_prompt) { 469 bool expect_prompt) {
394 EXPECT_TRUE(mock_time_task_runner_->HasPendingTask()); 470 EXPECT_TRUE(mock_time_task_runner_->HasPendingTask());
395 reporter_launch_count_ = 0; 471 reporter_launch_count_ = 0;
396 reporter_launch_parameters_.clear(); 472 reporter_launch_parameters_.clear();
397 prompt_trigger_called_ = false; 473 prompt_trigger_called_ = false;
398 474
399 mock_time_task_runner_->FastForwardBy( 475 mock_time_task_runner_->FastForwardBy(
400 base::TimeDelta::FromDays(days_until_launch)); 476 base::TimeDelta::FromDays(days_until_launch));
401 477
402 EXPECT_EQ(expected_launch_count, reporter_launch_count_); 478 EXPECT_EQ(expected_launch_count, reporter_launch_count_);
403 EXPECT_EQ(expect_prompt, prompt_trigger_called_); 479 // Note: a bad message error will not prevent the prompt that is shown to
480 // the user today. Once we hook the new prompt here, we will need to review
481 // this expectation.
482 EXPECT_EQ(expect_prompt &&
483 (expected_reporter_failure_ == MockedReporterFailure::kNone ||
484 expected_reporter_failure_ ==
485 MockedReporterFailure::kBadMessageReported),
486 prompt_trigger_called_);
487
488 if (chrome_prompt_test_delegate_)
489 EXPECT_TRUE(chrome_prompt_test_delegate_->bad_message_reported());
404 } 490 }
405 491
406 // Expects that after |days_until_launched| days, the reporter will be 492 // Expects that after |days_until_launched| days, the reporter will be
407 // launched once with each path in |expected_launch_paths|, and TriggerPrompt 493 // launched once with each path in |expected_launch_paths|, and TriggerPrompt
408 // will be called if and only if |expect_prompt| is true. 494 // will be called if and only if |expect_prompt| is true.
409 void ExpectReporterLaunches( 495 void ExpectReporterLaunches(
410 int days_until_launch, 496 int days_until_launch,
411 const std::vector<base::FilePath>& expected_launch_paths, 497 const std::vector<base::FilePath>& expected_launch_paths,
412 bool expect_prompt) { 498 bool expect_prompt) {
413 ExpectReporterLaunches(days_until_launch, expected_launch_paths.size(), 499 ExpectReporterLaunches(days_until_launch, expected_launch_paths.size(),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 546
461 // A task runner with a mock clock. 547 // A task runner with a mock clock.
462 scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner_ = 548 scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner_ =
463 new base::TestMockTimeTaskRunner(); 549 new base::TestMockTimeTaskRunner();
464 550
465 // The task runner that was in use before installing |mock_time_task_runner_|. 551 // The task runner that was in use before installing |mock_time_task_runner_|.
466 scoped_refptr<base::SingleThreadTaskRunner> saved_task_runner_; 552 scoped_refptr<base::SingleThreadTaskRunner> saved_task_runner_;
467 553
468 bool in_browser_cleaner_ui_; 554 bool in_browser_cleaner_ui_;
469 ElevationStatus elevation_status_; 555 ElevationStatus elevation_status_;
556 MockedReporterFailure expected_reporter_failure_;
470 557
471 bool prompt_trigger_called_ = false; 558 bool prompt_trigger_called_ = false;
472 int reporter_launch_count_ = 0; 559 int reporter_launch_count_ = 0;
473 std::vector<SwReporterInvocation> reporter_launch_parameters_; 560 std::vector<SwReporterInvocation> reporter_launch_parameters_;
474 int exit_code_to_report_ = kReporterFailureExitCode; 561 int exit_code_to_report_ = kReporterNotLaunchedExitCode;
475 562
476 // A callback to invoke when the first reporter of a queue is launched. This 563 // 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 564 // can be used to perform actions in the middle of a queue of reporters which
478 // all launch on the same mock clock tick. 565 // all launch on the same mock clock tick.
479 base::OnceClosure first_launch_callback_; 566 base::OnceClosure first_launch_callback_;
480 567
481 base::test::ScopedFeatureList scoped_feature_list_; 568 base::test::ScopedFeatureList scoped_feature_list_;
569
570 std::unique_ptr<BadMessageTestDelegate> chrome_prompt_test_delegate_;
482 }; 571 };
483 572
484 class SRTFetcherPromptTest : public DialogBrowserTest { 573 class SRTFetcherPromptTest : public DialogBrowserTest {
485 public: 574 public:
486 void ShowDialog(const std::string& name) override { 575 void ShowDialog(const std::string& name) override {
487 if (name == "SRTErrorNoFile") 576 if (name == "SRTErrorNoFile")
488 DisplaySRTPromptForTesting(base::FilePath()); 577 DisplaySRTPromptForTesting(base::FilePath());
489 else if (name == "SRTErrorFile") 578 else if (name == "SRTErrorFile")
490 DisplaySRTPromptForTesting( 579 DisplaySRTPromptForTesting(
491 base::FilePath().Append(FILE_PATH_LITERAL("c:\temp\testfile.txt"))); 580 base::FilePath().Append(FILE_PATH_LITERAL("c:\temp\testfile.txt")));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(10)); 642 mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(10));
554 643
555 // On opening the new browser, the prompt should be shown and the reporter 644 // On opening the new browser, the prompt should be shown and the reporter
556 // should be scheduled to run later. 645 // should be scheduled to run later.
557 EXPECT_EQ(1, reporter_launch_count_); 646 EXPECT_EQ(1, reporter_launch_count_);
558 EXPECT_TRUE(prompt_trigger_called_); 647 EXPECT_TRUE(prompt_trigger_called_);
559 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 648 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
560 } 649 }
561 650
562 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, Failure) { 651 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, Failure) {
563 RunReporter(kReporterFailureExitCode); 652 RunReporter(kReporterNotLaunchedExitCode);
564 ExpectReporterLaunches(0, 1, false); 653 ExpectReporterLaunches(0, 1, false);
565 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 654 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
566 } 655 }
567 656
568 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, RunDaily) { 657 IN_PROC_BROWSER_TEST_P(SRTFetcherTest, RunDaily) {
569 PrefService* local_state = g_browser_process->local_state(); 658 PrefService* local_state = g_browser_process->local_state();
570 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, true); 659 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, true);
571 SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - 1); 660 SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - 1);
572 ASSERT_GT(kDaysBetweenSuccessfulSwReporterRuns - 1, 661 ASSERT_GT(kDaysBetweenSuccessfulSwReporterRuns - 1,
573 kDaysBetweenSwReporterRunsForPendingPrompt); 662 kDaysBetweenSwReporterRunsForPendingPrompt);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 785
697 // Time passes... Now the 3-element queue should run. 786 // Time passes... Now the 3-element queue should run.
698 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, 787 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns,
699 {path1, path2, path3}, false); 788 {path1, path2, path3}, false);
700 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 789 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
701 } 790 }
702 791
703 // Second launch should not occur after a failure. 792 // Second launch should not occur after a failure.
704 { 793 {
705 SCOPED_TRACE("Launch multiple times with failure"); 794 SCOPED_TRACE("Launch multiple times with failure");
706 RunReporterQueue(kReporterFailureExitCode, invocations); 795 RunReporterQueue(kReporterNotLaunchedExitCode, invocations);
707 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1}, 796 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1},
708 false); 797 false);
709 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 798 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
710 799
711 // If we try again before the reporting period is up, it should not do 800 // If we try again before the reporting period is up, it should not do
712 // anything. 801 // anything.
713 ExpectReporterLaunches(0, {}, false); 802 ExpectReporterLaunches(0, {}, false);
714 803
715 // After enough time has passed, should try the queue again. 804 // After enough time has passed, should try the queue again.
716 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1}, 805 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1},
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 ExpectLoggingSwitches(reporter_launch_parameters_[1], true); 887 ExpectLoggingSwitches(reporter_launch_parameters_[1], true);
799 ExpectLastReportSentInTheLastHour(); 888 ExpectLastReportSentInTheLastHour();
800 } 889 }
801 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); 890 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
802 } 891 }
803 892
804 INSTANTIATE_TEST_CASE_P( 893 INSTANTIATE_TEST_CASE_P(
805 NoInBrowserCleanerUI, 894 NoInBrowserCleanerUI,
806 SRTFetcherTest, 895 SRTFetcherTest,
807 testing::Combine(testing::Values(false), 896 testing::Combine(testing::Values(false),
808 testing::Values(ElevationStatus::NOT_REQUIRED))); 897 testing::Values(ElevationStatus::NOT_REQUIRED),
898 testing::Values(MockedReporterFailure::kNone,
899 MockedReporterFailure::kCrashOnStartup)));
809 900
810 INSTANTIATE_TEST_CASE_P( 901 INSTANTIATE_TEST_CASE_P(
811 InBrowserCleanerUI, 902 InBrowserCleanerUI,
812 SRTFetcherTest, 903 SRTFetcherTest,
813 testing::Combine(testing::Values(true), 904 testing::Combine(
814 testing::Values(ElevationStatus::NOT_REQUIRED, 905 testing::Values(true),
815 ElevationStatus::REQUIRED))); 906 testing::Values(ElevationStatus::NOT_REQUIRED,
907 ElevationStatus::REQUIRED),
908 testing::Values(
909 MockedReporterFailure::kNone,
910 MockedReporterFailure::kCrashOnStartup,
911 MockedReporterFailure::kCrashAfterConnectedToParentProcess,
912 MockedReporterFailure::kCrashWhileWaitingForResponse,
913 MockedReporterFailure::kCrashAfterReceivedResponse,
914 MockedReporterFailure::kBadMessageReported)));
816 915
817 // This provide tests which allows explicit invocation of the SRT Prompt 916 // This provide tests which allows explicit invocation of the SRT Prompt
818 // useful for checking dialog layout or any other interactive functionality 917 // useful for checking dialog layout or any other interactive functionality
819 // tests. See docs/testing/test_browser_dialog.md for description of the 918 // tests. See docs/testing/test_browser_dialog.md for description of the
820 // testing framework. 919 // testing framework.
821 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorNoFile) { 920 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorNoFile) {
822 RunDialog(); 921 RunDialog();
823 } 922 }
824 923
825 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorFile) { 924 IN_PROC_BROWSER_TEST_F(SRTFetcherPromptTest, InvokeDialog_SRTErrorFile) {
826 RunDialog(); 925 RunDialog();
827 } 926 }
828 927
829 } // namespace safe_browsing 928 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698