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

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: Comment on usage of TestPartialLaunchCycle. Always save the time of last run. Misc cleanups. 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 // Run through the steps needed to launch the reporter, as many times as
75 const base::FilePath& expected_launch_path) { 82 // needed to launch all the reporters given in |expected_launch_paths|. Test
83 // that each of those launches succeeded. But do not test that ONLY those
84 // launches succeeded.
85 //
86 // After this, if more launches are expected you can call
87 // |TestPartialLaunchCycle| again with another list of paths, to test that
88 // the launch cycle will continue with those paths.
89 //
90 // To test that a list of paths are launched AND NO OTHERS, use
91 // |TestReporterLaunchCycle|.
92 void TestPartialLaunchCycle(
93 const std::vector<base::FilePath>& expected_launch_paths) {
94 reporter_launch_count_ = 0;
csharp 2016/09/13 17:09:03 nit: I'd move these below the comment block to kee
Joe Mason 2016/09/13 19:24:54 Done.
95 reporter_launch_parameters_ = SwReporterInvocation();
96
76 // This test has an unfortunate amount of knowledge of the internals of 97 // 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 98 // ReporterRunner, because it needs to pump the right message loops at the
78 // right time so that all its internal messages are delivered. This 99 // right time so that all its internal messages are delivered. This
79 // function might need to be updated if the internals change. 100 // function might need to be updated if the internals change.
80 // 101 //
81 // The basic sequence is: 102 // The basic sequence is:
82 103
83 // 1. TryToRun kicks the whole thing off. If the reporter should not be 104 // 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 105 // 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 106 // 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 121 // it in a loop to make sure we're past all pending TryToRun calls before
101 // LaunchAndWaitForExit will be called. 122 // LaunchAndWaitForExit will be called.
102 // 123 //
103 // Once a call to LaunchAndWaitForExit has been posted, TryToRun won't be 124 // 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 125 // called again until we pump the UI message loop in order to run
105 // ReporterDone. 126 // ReporterDone.
106 127
107 ASSERT_TRUE(task_runner_->HasPendingTask()); 128 ASSERT_TRUE(task_runner_->HasPendingTask());
108 ASSERT_FALSE(reporter_done_notified_); 129 ASSERT_FALSE(reporter_done_notified_);
109 130
110 // Clear out any pending TryToRun calls. Use a bounded loop so that if the 131 int current_launch_count = reporter_launch_count_;
111 // reporter will never be called, we'll eventually continue. (If 132 for (const auto& expected_launch_path : expected_launch_paths) {
112 // LaunchAndWaitForExit was pending but TryToRun wasn't, this will call 133 // If RunReporter was called with no pending messages, and it was already
113 // it.) 134 // time to launch the reporter, then |launch_ready_notified_| will
114 const int max_expected_launch_count = reporter_launch_count_ + 1; 135 // already be true. Otherwise there will be a TryToRun message pending,
115 for (int i = 0; !launch_ready_notified_ && i < 100; ++i) 136 // which must be processed first.
137 if (!launch_ready_notified_) {
138 task_runner_->RunPendingTasks();
139 // Since we're expecting a launch here, we expect it to schedule
140 // LaunchAndWaitForExit. So NOW |launch_ready_notified_| should be
141 // true.
142 ASSERT_TRUE(task_runner_->HasPendingTask());
143 }
144 ASSERT_TRUE(launch_ready_notified_);
145 ASSERT_EQ(current_launch_count, reporter_launch_count_);
146
147 // Reset |launch_ready_notified_| so that we can tell if TryToRun gets
148 // called again unexpectedly.
149 launch_ready_notified_ = false;
150
151 // Call the pending LaunchAndWaitForExit.
116 task_runner_->RunPendingTasks(); 152 task_runner_->RunPendingTasks();
117 ASSERT_GE(max_expected_launch_count, reporter_launch_count_); 153 ASSERT_FALSE(launch_ready_notified_);
154 ASSERT_FALSE(reporter_done_notified_);
118 155
119 // Reset launch_ready_notified_ so that we can tell if TryToRun gets called 156 // At this point LaunchAndWaitForExit has definitely been called if
120 // again unexpectedly. 157 // it's going to be called at all. (If not, TryToRun will have been
121 launch_ready_notified_ = false; 158 // scheduled again.)
159 EXPECT_EQ(current_launch_count + 1, reporter_launch_count_);
160 EXPECT_EQ(expected_launch_path,
161 reporter_launch_parameters_.command_line.GetProgram());
122 162
123 // This will trigger LaunchAndWaitForExit if it's on the queue and hasn't 163 // Pump the UI message loop to process the ReporterDone call (which
124 // been called already. If it was called already, this will do nothing. 164 // will schedule the next TryToRun.) If LaunchAndWaitForExit wasn't
125 // (There definitely isn't anything queued up yet after 165 // called, this does nothing.
126 // LaunchAndWaitForExit because ReporterDone wasn't called yet.) 166 base::RunLoop().RunUntilIdle();
167
168 // At this point there are three things that could have happened:
169 //
170 // 1. LaunchAndWaitForExit was not called. There should be a TryToRun
171 // scheduled.
172 //
173 // 2. ReporterDone was called and there was nothing left in the queue
174 // of SwReporterInvocation's. There should be a TryToRun scheduled.
175 //
176 // 3. ReporterDone was called and there were more
177 // SwReporterInvocation's in the queue to run immediately. There should
178 // be a LaunchAndWaitForExit scheduled.
179 //
180 // So in all cases there should be a pending task, and if we are expecting
181 // more launches in this loop, |launch_ready_notified_| will already be
182 // true.
183 ASSERT_TRUE(task_runner_->HasPendingTask());
184
185 // The test task runner does not actually advance the clock. Pretend that
186 // one day has passed. (Otherwise, when we launch the last
187 // SwReporterInvocation in the queue, the next call to TryToRun will
188 // start a whole new launch cycle.)
189 SetDaysSinceLastReport(1);
190
191 reporter_done_notified_ = false;
192 current_launch_count = reporter_launch_count_;
193 }
194 }
195
196 // Run through the steps needed to launch the reporter, as many times as
197 // needed to launch all the reporters given in |expected_launch_paths|. Test
198 // that each of those launches succeeded. Then, run through the steps needed
199 // to launch the reporter again, to test that the launch cycle is complete
200 // (no more reporters will be launched).
201 void TestReporterLaunchCycle(
202 const std::vector<base::FilePath>& expected_launch_paths) {
203 TestPartialLaunchCycle(expected_launch_paths);
204
205 // Now that all expected launches have been tested, run the cycle once more
csharp 2016/09/13 17:09:03 Could you replace this code with a call to TestPAr
Joe Mason 2016/09/13 19:24:54 No, actually. This is just enough different that i
206 // to make sure no more launches happen.
207 ASSERT_TRUE(task_runner_->HasPendingTask());
208 ASSERT_FALSE(reporter_done_notified_);
209 ASSERT_FALSE(launch_ready_notified_);
210
211 int current_launch_count = reporter_launch_count_;
212
213 // Call the pending TryToRun.
127 task_runner_->RunPendingTasks(); 214 task_runner_->RunPendingTasks();
128 ASSERT_GE(max_expected_launch_count, reporter_launch_count_); 215
216 // We expect that this scheduled another TryToRun. If it scheduled
217 // LaunchAndWaitForExit an unexpected launch is about to happen.
218 ASSERT_TRUE(task_runner_->HasPendingTask());
129 ASSERT_FALSE(launch_ready_notified_); 219 ASSERT_FALSE(launch_ready_notified_);
130 ASSERT_FALSE(reporter_done_notified_); 220 ASSERT_FALSE(reporter_done_notified_);
131 221 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 } 222 }
152 223
153 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; 224 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
154 bool prompt_trigger_called_ = false; 225 bool prompt_trigger_called_ = false;
155 int reporter_launch_count_ = 0; 226 int reporter_launch_count_ = 0;
156 SwReporterInvocation reporter_launch_parameters_; 227 SwReporterInvocation reporter_launch_parameters_;
157 int exit_code_to_report_ = kReporterFailureExitCode; 228 int exit_code_to_report_ = kReporterFailureExitCode;
229
230 // This will be set to true when a call to |LaunchAndWaitForExit| is next in
231 // the task queue.
158 bool launch_ready_notified_ = false; 232 bool launch_ready_notified_ = false;
233
159 bool reporter_done_notified_ = false; 234 bool reporter_done_notified_ = false;
160 }; 235 };
161 236
162 } // namespace 237 } // namespace
163 238
164 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, NothingFound) { 239 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, NothingFound) {
165 exit_code_to_report_ = kSwReporterNothingFound; 240 exit_code_to_report_ = kSwReporterNothingFound;
166 RunReporter(); 241 RunReporter();
167 task_runner_->RunPendingTasks(); 242 task_runner_->RunPendingTasks();
168 EXPECT_EQ(1, reporter_launch_count_); 243 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"); 332 const base::FilePath path2(L"path2");
258 const base::FilePath path3(L"path3"); 333 const base::FilePath path3(L"path3");
259 334
260 // Schedule path1 with a day left in the reporting period. 335 // Schedule path1 with a day left in the reporting period.
261 // The reporter should not launch. 336 // The reporter should not launch.
262 constexpr int kDaysLeft = 1; 337 constexpr int kDaysLeft = 1;
263 { 338 {
264 SCOPED_TRACE("N days left until next reporter run"); 339 SCOPED_TRACE("N days left until next reporter run");
265 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft); 340 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft);
266 RunReporter(path1); 341 RunReporter(path1);
267 TestReporterLaunchCycle(0, base::FilePath()); 342 TestReporterLaunchCycle({});
268 } 343 }
269 344
270 // Schedule path2 just as we enter the next reporting period. 345 // Schedule path2 just as we enter the next reporting period.
271 // Now the reporter should launch, just once, using path2. 346 // Now the reporter should launch, just once, using path2.
272 { 347 {
273 SCOPED_TRACE("Reporter runs now"); 348 SCOPED_TRACE("Reporter runs now");
274 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); 349 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
275 RunReporter(path2); 350 RunReporter(path2);
276 // Schedule it twice; it should only actually run once. 351 // Schedule it twice; it should only actually run once.
277 RunReporter(path2); 352 RunReporter(path2);
278 TestReporterLaunchCycle(1, path2); 353 TestReporterLaunchCycle({path2});
279 } 354 }
280 355
281 // Schedule path3 before any more time has passed. 356 // Schedule path3 before any more time has passed.
282 // The reporter should not launch. 357 // The reporter should not launch.
283 { 358 {
284 SCOPED_TRACE("No more time passed"); 359 SCOPED_TRACE("No more time passed");
360 SetDaysSinceLastReport(0);
285 RunReporter(path3); 361 RunReporter(path3);
286 TestReporterLaunchCycle(1, path2); 362 TestReporterLaunchCycle({});
287 } 363 }
288 364
289 // Enter the next reporting period as path3 is still scheduled. 365 // Enter the next reporting period as path3 is still scheduled.
290 // Now the reporter should launch again using path3. (Tests that the 366 // Now the reporter should launch again using path3. (Tests that the
291 // parameters from the first launch aren't reused.) 367 // parameters from the first launch aren't reused.)
292 { 368 {
293 SCOPED_TRACE("Previous run still scheduled"); 369 SCOPED_TRACE("Previous run still scheduled");
294 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); 370 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
295 TestReporterLaunchCycle(2, path3); 371 TestReporterLaunchCycle({path3});
296 } 372 }
297 373
298 // Schedule path3 again in the next reporting period. 374 // Schedule path3 again in the next reporting period.
299 // The reporter should launch again using path3, since enough time has 375 // The reporter should launch again using path3, since enough time has
300 // passed, even though the parameters haven't changed. 376 // passed, even though the parameters haven't changed.
301 { 377 {
302 SCOPED_TRACE("Run with same parameters"); 378 SCOPED_TRACE("Run with same parameters");
303 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); 379 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
304 RunReporter(path3); 380 RunReporter(path3);
305 TestReporterLaunchCycle(3, path3); 381 TestReporterLaunchCycle({path3});
306 } 382 }
307 } 383 }
308 384
385 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, MultipleLaunches) {
386 exit_code_to_report_ = kSwReporterNothingFound;
387
388 const base::FilePath path1(L"path1");
389 const base::FilePath path2(L"path2");
390 const base::FilePath path3(L"path3");
391
392 SwReporterQueue invocations;
393 invocations.push(SwReporterInvocation::FromFilePath(path1));
394 invocations.push(SwReporterInvocation::FromFilePath(path2));
395
396 {
397 SCOPED_TRACE("Launch 2 times");
398 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
399 RunReporterQueue(invocations);
400 TestReporterLaunchCycle({path1, path2});
401 }
402
403 // Schedule a launch with 2 elements, then another with the same 2. It should
404 // just run 2 times, not 4.
405 {
406 SCOPED_TRACE("Launch 2 times with retry");
407 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
408 RunReporterQueue(invocations);
409 RunReporterQueue(invocations);
410 TestReporterLaunchCycle({path1, path2});
411 }
412
413 // Schedule a launch with 2 elements, then add a third while the queue is
414 // running.
415 {
416 SCOPED_TRACE("Add third launch while running");
417 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
418 RunReporterQueue(invocations);
419
420 // Only test the cycle once, to process the first element in queue.
421 TestPartialLaunchCycle({path1});
422
423 invocations.push(SwReporterInvocation::FromFilePath(path3));
424 RunReporterQueue(invocations);
425
426 // There is still a 2nd element on the queue - that should execute, and
427 // nothing more.
428 TestReporterLaunchCycle({path2});
429
430 // Time passes... Now the 3-element queue should run.
431 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
432 TestReporterLaunchCycle({path1, path2, path3});
433 }
434
435 // Second launch should not occur after a failure.
436 {
437 SCOPED_TRACE("Launch multiple times with failure");
438 exit_code_to_report_ = kReporterFailureExitCode;
439 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
440 RunReporterQueue(invocations);
441 TestReporterLaunchCycle({path1});
442
443 // If we try again before the reporting period is up, it should not do
444 // anything.
445 TestReporterLaunchCycle({});
446
447 // After enough time has passed, should try the queue again.
448 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
449 TestReporterLaunchCycle({path1});
450 }
451 }
452
309 } // namespace safe_browsing 453 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698