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

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

Issue 2226133005: Add support for the ExperimentalSwReporterEngine field trial. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Keep explicit current_invocations queue, rename LaunchNextInvocation, explicitly disallow RunSwRepo… Created 4 years, 3 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 <memory> 7 #include <memory>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 20 matching lines...) Expand all
31 task_runner_ = new base::TestSimpleTaskRunner; 31 task_runner_ = new base::TestSimpleTaskRunner;
32 32
33 SetSwReporterTestingDelegate(this); 33 SetSwReporterTestingDelegate(this);
34 } 34 }
35 35
36 void TearDownInProcessBrowserTestFixture() override { 36 void TearDownInProcessBrowserTestFixture() override {
37 SetSwReporterTestingDelegate(nullptr); 37 SetSwReporterTestingDelegate(nullptr);
38 } 38 }
39 39
40 void RunReporter(const base::FilePath& exe_path = base::FilePath()) { 40 void RunReporter(const base::FilePath& exe_path = base::FilePath()) {
41 RunSwReporter(SwReporterInvocation::FromFilePath(exe_path), 41 SwReporterQueue invocations;
42 base::Version("1.2.3"), task_runner_, task_runner_); 42 invocations.push(SwReporterInvocation::FromFilePath(exe_path));
43 RunSwReporters(invocations, base::Version("1.2.3"), task_runner_,
44 task_runner_);
45 }
46
47 void RunReporterQueue(const SwReporterQueue& invocations) {
48 RunSwReporters(invocations, base::Version("1.2.3"), task_runner_,
49 task_runner_);
43 } 50 }
44 51
45 void TriggerPrompt(Browser* browser, const std::string& version) override { 52 void TriggerPrompt(Browser* browser, const std::string& version) override {
46 prompt_trigger_called_ = true; 53 prompt_trigger_called_ = true;
47 } 54 }
48 55
49 int LaunchReporter(const SwReporterInvocation& invocation) override { 56 int LaunchReporter(const SwReporterInvocation& invocation) override {
50 ++reporter_launch_count_; 57 ++reporter_launch_count_;
51 reporter_launch_parameters_ = invocation; 58 reporter_launch_parameters_ = invocation;
52 return exit_code_to_report_; 59 return exit_code_to_report_;
(...skipping 11 matching lines...) Expand all
64 } 71 }
65 72
66 void ExpectToRunAgain(int days) { 73 void ExpectToRunAgain(int days) {
67 ASSERT_TRUE(task_runner_->HasPendingTask()); 74 ASSERT_TRUE(task_runner_->HasPendingTask());
68 EXPECT_LE(task_runner_->NextPendingTaskDelay(), 75 EXPECT_LE(task_runner_->NextPendingTaskDelay(),
69 base::TimeDelta::FromDays(days)); 76 base::TimeDelta::FromDays(days));
70 EXPECT_GT(task_runner_->NextPendingTaskDelay(), 77 EXPECT_GT(task_runner_->NextPendingTaskDelay(),
71 base::TimeDelta::FromDays(days) - base::TimeDelta::FromHours(1)); 78 base::TimeDelta::FromDays(days) - base::TimeDelta::FromHours(1));
72 } 79 }
73 80
74 void TestReporterLaunchCycle(int expected_launch_count, 81 void TestPartialLaunchCycle(
Jialiu Lin 2016/09/12 20:55:13 nit: maybe add some comment to this function and T
Joe Mason 2016/09/12 23:33:29 Done.
75 const base::FilePath& expected_launch_path) { 82 const std::vector<base::FilePath>& expected_launch_paths) {
83 reporter_launch_count_ = 0;
84 reporter_launch_parameters_ = SwReporterInvocation();
85
76 // This test has an unfortunate amount of knowledge of the internals of 86 // This test has an unfortunate amount of knowledge of the internals of
77 // ReporterRunner, because it needs to pump the right message loops at the 87 // ReporterRunner, because it needs to pump the right message loops at the
78 // right time so that all its internal messages are delivered. This 88 // right time so that all its internal messages are delivered. This
79 // function might need to be updated if the internals change. 89 // function might need to be updated if the internals change.
80 // 90 //
81 // The basic sequence is: 91 // The basic sequence is:
82 92
83 // 1. TryToRun kicks the whole thing off. If the reporter should not be 93 // 1. TryToRun kicks the whole thing off. If the reporter should not be
84 // launched now (eg. DaysSinceLastReport is too low) it posts a call to 94 // launched now (eg. DaysSinceLastReport is too low) it posts a call to
85 // itself again. (In a regular task runner this will be scheduled with a 95 // itself again. (In a regular task runner this will be scheduled with a
(...skipping 14 matching lines...) Expand all
100 // it in a loop to make sure we're past all pending TryToRun calls before 110 // it in a loop to make sure we're past all pending TryToRun calls before
101 // LaunchAndWaitForExit will be called. 111 // LaunchAndWaitForExit will be called.
102 // 112 //
103 // Once a call to LaunchAndWaitForExit has been posted, TryToRun won't be 113 // Once a call to LaunchAndWaitForExit has been posted, TryToRun won't be
104 // called again until we pump the UI message loop in order to run 114 // called again until we pump the UI message loop in order to run
105 // ReporterDone. 115 // ReporterDone.
106 116
107 ASSERT_TRUE(task_runner_->HasPendingTask()); 117 ASSERT_TRUE(task_runner_->HasPendingTask());
108 ASSERT_FALSE(reporter_done_notified_); 118 ASSERT_FALSE(reporter_done_notified_);
109 119
110 // Clear out any pending TryToRun calls. Use a bounded loop so that if the 120 int current_launch_count = reporter_launch_count_;
111 // reporter will never be called, we'll eventually continue. (If 121 for (const auto& expected_launch_path : expected_launch_paths) {
112 // LaunchAndWaitForExit was pending but TryToRun wasn't, this will call 122 // If RunReporter was called with no pending messages, and it was already
113 // it.) 123 // time to launch the reporter, then |launch_ready_notified_| will
114 const int max_expected_launch_count = reporter_launch_count_ + 1; 124 // already be true. Otherwise there will be a TryToRun message pending,
115 for (int i = 0; !launch_ready_notified_ && i < 100; ++i) 125 // which must be processed first.
126 if (!launch_ready_notified_) {
127 task_runner_->RunPendingTasks();
128 // Since we're expecting a launch here, we expect it to schedule
129 // LaunchAndWaitForExit. So NOW |launch_ready_notified_| should be
130 // true.
131 ASSERT_TRUE(task_runner_->HasPendingTask());
132 }
133 ASSERT_TRUE(launch_ready_notified_);
134 ASSERT_EQ(current_launch_count, reporter_launch_count_);
135
136 // Reset |launch_ready_notified_| so that we can tell if TryToRun gets
137 // called again unexpectedly.
138 launch_ready_notified_ = false;
139
140 // Call the pending LaunchAndWaitForExit.
116 task_runner_->RunPendingTasks(); 141 task_runner_->RunPendingTasks();
117 ASSERT_GE(max_expected_launch_count, reporter_launch_count_); 142 ASSERT_FALSE(launch_ready_notified_);
143 ASSERT_FALSE(reporter_done_notified_);
118 144
119 // Reset launch_ready_notified_ so that we can tell if TryToRun gets called 145 // At this point LaunchAndWaitForExit has definitely been called if
120 // again unexpectedly. 146 // it's going to be called at all. (If not, TryToRun will have been
121 launch_ready_notified_ = false; 147 // scheduled again.)
148 EXPECT_EQ(current_launch_count + 1, reporter_launch_count_);
149 EXPECT_EQ(expected_launch_path,
150 reporter_launch_parameters_.command_line.GetProgram());
122 151
123 // This will trigger LaunchAndWaitForExit if it's on the queue and hasn't 152 // Pump the UI message loop to process the ReporterDone call (which
124 // been called already. If it was called already, this will do nothing. 153 // will schedule the next TryToRun.) If LaunchAndWaitForExit wasn't
125 // (There definitely isn't anything queued up yet after 154 // called, this does nothing.
126 // LaunchAndWaitForExit because ReporterDone wasn't called yet.) 155 base::RunLoop().RunUntilIdle();
156
157 // At this point there are three things that could have happened:
158 //
159 // 1. LaunchAndWaitForExit was not called. There should be a TryToRun
160 // scheduled.
161 //
162 // 2. ReporterDone was called and there was nothing left in the queue
163 // of SwReporterInvocation's. There should be a TryToRun scheduled.
164 //
165 // 3. ReporterDone was called and there were more
166 // SwReporterInvocation's in the queue to run immediately. There should
167 // be a LaunchAndWaitForExit scheduled.
168 //
169 // So in all cases there should be a pending task, and if we are expecting
170 // more launches in this loop, |launch_ready_notified_| will already be
171 // true.
172 ASSERT_TRUE(task_runner_->HasPendingTask());
173
174 // The test task runner does not actually advance the clock. Pretend that
175 // one day has passed. (Otherwise, when we launch the last
176 // SwReporterInvocation in the queue, the next call to TryToRun will
177 // start a whole new launch cycle.)
178 SetDaysSinceLastReport(1);
179
180 reporter_done_notified_ = false;
181 current_launch_count = reporter_launch_count_;
182 }
183 }
184
185 void TestReporterLaunchCycle(
186 const std::vector<base::FilePath>& expected_launch_paths) {
187 TestPartialLaunchCycle(expected_launch_paths);
188
189 // Now that all expected launches have been tested, run the cycle once more
190 // to make sure no more launches happen.
191 ASSERT_TRUE(task_runner_->HasPendingTask());
192 ASSERT_FALSE(reporter_done_notified_);
193 ASSERT_FALSE(launch_ready_notified_);
194
195 int current_launch_count = reporter_launch_count_;
196
197 // Call the pending TryToRun.
127 task_runner_->RunPendingTasks(); 198 task_runner_->RunPendingTasks();
128 ASSERT_GE(max_expected_launch_count, reporter_launch_count_); 199
200 // We expect that this scheduled another TryToRun. If it scheduled
201 // LaunchAndWaitForExit an unexpected launch is about to happen.
202 ASSERT_TRUE(task_runner_->HasPendingTask());
129 ASSERT_FALSE(launch_ready_notified_); 203 ASSERT_FALSE(launch_ready_notified_);
130 ASSERT_FALSE(reporter_done_notified_); 204 ASSERT_FALSE(reporter_done_notified_);
131 205 ASSERT_EQ(current_launch_count, reporter_launch_count_);
132 // At this point LaunchAndWaitForExit has definitely been called if it's
133 // going to be called at all. (If not, TryToRun will have been scheduled
134 // again.)
135 EXPECT_EQ(expected_launch_count, reporter_launch_count_);
136 EXPECT_EQ(expected_launch_path,
137 reporter_launch_parameters_.command_line.GetProgram());
138
139 // Pump the UI message loop to process the ReporterDone call (which will
140 // schedule the next TryToRun.) If LaunchAndWaitForExit wasn't called, this
141 // does nothing.
142 base::RunLoop().RunUntilIdle();
143
144 // At this point another call to TryToRun should be scheduled, whether or
145 // not LaunchAndWaitForExit was called.
146 ASSERT_TRUE(task_runner_->HasPendingTask());
147
148 // Make sure the flags are false for the next launch cycle test.
149 ASSERT_FALSE(launch_ready_notified_);
150 reporter_done_notified_ = false;
151 } 206 }
152 207
153 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; 208 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
154 bool prompt_trigger_called_ = false; 209 bool prompt_trigger_called_ = false;
155 int reporter_launch_count_ = 0; 210 int reporter_launch_count_ = 0;
156 SwReporterInvocation reporter_launch_parameters_; 211 SwReporterInvocation reporter_launch_parameters_;
157 int exit_code_to_report_ = kReporterFailureExitCode; 212 int exit_code_to_report_ = kReporterFailureExitCode;
213
214 // This will be set to true when a call to |LaunchAndWaitForExit| is next in
215 // the task queue.
158 bool launch_ready_notified_ = false; 216 bool launch_ready_notified_ = false;
217
159 bool reporter_done_notified_ = false; 218 bool reporter_done_notified_ = false;
160 }; 219 };
161 220
162 } // namespace 221 } // namespace
163 222
164 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, NothingFound) { 223 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, NothingFound) {
165 exit_code_to_report_ = kSwReporterNothingFound; 224 exit_code_to_report_ = kSwReporterNothingFound;
166 RunReporter(); 225 RunReporter();
167 task_runner_->RunPendingTasks(); 226 task_runner_->RunPendingTasks();
168 EXPECT_EQ(1, reporter_launch_count_); 227 EXPECT_EQ(1, reporter_launch_count_);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 const base::FilePath path2(L"path2"); 316 const base::FilePath path2(L"path2");
258 const base::FilePath path3(L"path3"); 317 const base::FilePath path3(L"path3");
259 318
260 // Schedule path1 with a day left in the reporting period. 319 // Schedule path1 with a day left in the reporting period.
261 // The reporter should not launch. 320 // The reporter should not launch.
262 constexpr int kDaysLeft = 1; 321 constexpr int kDaysLeft = 1;
263 { 322 {
264 SCOPED_TRACE("N days left until next reporter run"); 323 SCOPED_TRACE("N days left until next reporter run");
265 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft); 324 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft);
266 RunReporter(path1); 325 RunReporter(path1);
267 TestReporterLaunchCycle(0, base::FilePath()); 326 TestReporterLaunchCycle({});
268 } 327 }
269 328
270 // Schedule path2 just as we enter the next reporting period. 329 // Schedule path2 just as we enter the next reporting period.
271 // Now the reporter should launch, just once, using path2. 330 // Now the reporter should launch, just once, using path2.
272 { 331 {
273 SCOPED_TRACE("Reporter runs now"); 332 SCOPED_TRACE("Reporter runs now");
274 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); 333 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
275 RunReporter(path2); 334 RunReporter(path2);
276 // Schedule it twice; it should only actually run once. 335 // Schedule it twice; it should only actually run once.
277 RunReporter(path2); 336 RunReporter(path2);
278 TestReporterLaunchCycle(1, path2); 337 TestReporterLaunchCycle({path2});
279 } 338 }
280 339
281 // Schedule path3 before any more time has passed. 340 // Schedule path3 before any more time has passed.
282 // The reporter should not launch. 341 // The reporter should not launch.
283 { 342 {
284 SCOPED_TRACE("No more time passed"); 343 SCOPED_TRACE("No more time passed");
344 SetDaysSinceLastReport(0);
285 RunReporter(path3); 345 RunReporter(path3);
286 TestReporterLaunchCycle(1, path2); 346 TestReporterLaunchCycle({});
287 } 347 }
288 348
289 // Enter the next reporting period as path3 is still scheduled. 349 // Enter the next reporting period as path3 is still scheduled.
290 // Now the reporter should launch again using path3. (Tests that the 350 // Now the reporter should launch again using path3. (Tests that the
291 // parameters from the first launch aren't reused.) 351 // parameters from the first launch aren't reused.)
292 { 352 {
293 SCOPED_TRACE("Previous run still scheduled"); 353 SCOPED_TRACE("Previous run still scheduled");
294 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); 354 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
295 TestReporterLaunchCycle(2, path3); 355 TestReporterLaunchCycle({path3});
296 } 356 }
297 357
298 // Schedule path3 again in the next reporting period. 358 // Schedule path3 again in the next reporting period.
299 // The reporter should launch again using path3, since enough time has 359 // The reporter should launch again using path3, since enough time has
300 // passed, even though the parameters haven't changed. 360 // passed, even though the parameters haven't changed.
301 { 361 {
302 SCOPED_TRACE("Run with same parameters"); 362 SCOPED_TRACE("Run with same parameters");
303 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); 363 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
304 RunReporter(path3); 364 RunReporter(path3);
305 TestReporterLaunchCycle(3, path3); 365 TestReporterLaunchCycle({path3});
306 } 366 }
307 } 367 }
308 368
369 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, MultipleLaunches) {
370 exit_code_to_report_ = kSwReporterNothingFound;
371
372 const base::FilePath path1(L"path1");
373 const base::FilePath path2(L"path2");
374 const base::FilePath path3(L"path3");
375
376 SwReporterQueue invocations;
377 invocations.push(SwReporterInvocation::FromFilePath(path1));
378 invocations.push(SwReporterInvocation::FromFilePath(path2));
379
380 {
381 SCOPED_TRACE("Launch 2 times");
382 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
383 RunReporterQueue(invocations);
384 TestReporterLaunchCycle({path1, path2});
385 }
386
387 // Schedule a launch with 2 elements, then another with the same 2. It should
388 // just run 2 times, not 4.
389 {
390 SCOPED_TRACE("Launch 2 times with retry");
391 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
392 RunReporterQueue(invocations);
393 RunReporterQueue(invocations);
394 TestReporterLaunchCycle({path1, path2});
395 }
396
397 // Schedule a launch with 2 elements, then add a third while the queue is
398 // running.
399 {
400 SCOPED_TRACE("Add third launch while running");
401 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
402 RunReporterQueue(invocations);
403
404 // Only test the cycle once, to process the first element in queue.
405 TestPartialLaunchCycle({path1});
406
407 invocations.push(SwReporterInvocation::FromFilePath(path3));
408 RunReporterQueue(invocations);
409
410 // There is still a 2nd element on the queue - that should execute, and
411 // nothing more.
412 TestReporterLaunchCycle({path2});
413
414 // Time passes... Now the 3-element queue should run.
415 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
416 TestReporterLaunchCycle({path1, path2, path3});
417 }
418
419 // Second launch should not occur after a failure.
420 {
421 SCOPED_TRACE("Launch multiple times with failure");
422 exit_code_to_report_ = kReporterFailureExitCode;
423 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
424 RunReporterQueue(invocations);
425 TestReporterLaunchCycle({path1});
426
427 // If we try again before the reporting period is up, it should not do
428 // anything.
429 TestReporterLaunchCycle({});
430
431 // After enough time has passed, should try the queue again.
432 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
433 TestReporterLaunchCycle({path1});
434 }
435 }
436
309 } // namespace safe_browsing 437 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « chrome/browser/component_updater/sw_reporter_installer_win_unittest.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