Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <iterator> | 7 #include <iterator> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/callback.h" | |
| 13 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
| 14 #include "base/run_loop.h" | 15 #include "base/memory/ptr_util.h" |
| 15 #include "base/test/scoped_feature_list.h" | 16 #include "base/test/scoped_feature_list.h" |
| 16 #include "base/test/test_simple_task_runner.h" | 17 #include "base/test/scoped_mock_time_message_loop_task_runner.h" |
| 17 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 19 #include "base/version.h" | |
| 18 #include "chrome/browser/browser_process.h" | 20 #include "chrome/browser/browser_process.h" |
| 21 #include "chrome/browser/lifetime/keep_alive_types.h" | |
| 22 #include "chrome/browser/lifetime/scoped_keep_alive.h" | |
| 19 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
| 20 #include "chrome/browser/safe_browsing/srt_client_info_win.h" | 24 #include "chrome/browser/safe_browsing/srt_client_info_win.h" |
| 21 #include "chrome/browser/ui/browser.h" | 25 #include "chrome/browser/ui/browser.h" |
| 22 #include "chrome/browser/ui/browser_finder.h" | 26 #include "chrome/browser/ui/browser_finder.h" |
| 23 #include "chrome/common/pref_names.h" | 27 #include "chrome/common/pref_names.h" |
| 24 #include "chrome/test/base/in_process_browser_test.h" | 28 #include "chrome/test/base/in_process_browser_test.h" |
| 25 #include "components/component_updater/pref_names.h" | 29 #include "components/component_updater/pref_names.h" |
| 26 #include "components/prefs/pref_service.h" | 30 #include "components/prefs/pref_service.h" |
| 27 #include "components/safe_browsing_db/safe_browsing_prefs.h" | 31 #include "components/safe_browsing_db/safe_browsing_prefs.h" |
| 28 #include "content/public/test/test_browser_thread_bundle.h" | |
| 29 | 32 |
| 30 namespace safe_browsing { | 33 namespace safe_browsing { |
| 31 | 34 |
| 32 namespace { | 35 namespace { |
| 33 | 36 |
| 34 const char* const kExpectedSwitches[] = {kExtendedSafeBrowsingEnabledSwitch, | 37 const char* const kExpectedSwitches[] = {kExtendedSafeBrowsingEnabledSwitch, |
| 35 kChromeVersionSwitch, | 38 kChromeVersionSwitch, |
| 36 kChromeChannelSwitch}; | 39 kChromeChannelSwitch}; |
| 37 | 40 |
| 38 class SRTFetcherTest : public InProcessBrowserTest, | 41 class SRTFetcherTest : public InProcessBrowserTest, |
| 39 public SwReporterTestingDelegate { | 42 public SwReporterTestingDelegate { |
| 40 public: | 43 public: |
| 41 void SetUpInProcessBrowserTestFixture() override { | 44 void SetUpInProcessBrowserTestFixture() override { |
| 42 task_runner_ = new base::TestSimpleTaskRunner; | |
| 43 | |
| 44 SetSwReporterTestingDelegate(this); | 45 SetSwReporterTestingDelegate(this); |
| 45 } | 46 } |
| 46 | 47 |
| 47 void SetUpOnMainThread() override { | 48 void SetUpOnMainThread() override { |
| 49 scoped_task_runner_ = | |
| 50 base::MakeUnique<base::ScopedMockTimeMessageLoopTaskRunner>(); | |
| 48 InProcessBrowserTest::SetUpOnMainThread(); | 51 InProcessBrowserTest::SetUpOnMainThread(); |
| 52 | |
| 53 // SetDateInLocalState calculates a time as Now() minus an offset. Move the | |
| 54 // simulated clock ahead far enough that this calculation won't underflow. | |
| 55 (*scoped_task_runner_) | |
|
grt (UTC plus 2)
2017/02/22 12:25:26
"(*scoped_task_runner_)->" everywhere is pretty fu
gab
2017/02/22 17:19:48
Ugh, my bad, there was such a method before and I
Joe Mason
2017/02/22 17:56:45
I just took that out based on gab's comment!
I re
| |
| 56 ->FastForwardBy(base::TimeDelta::FromDays( | |
| 57 kDaysBetweenSuccessfulSwReporterRuns * 2)); | |
| 58 | |
| 49 ClearLastTimeSentReport(); | 59 ClearLastTimeSentReport(); |
| 50 } | 60 } |
| 51 | 61 |
| 62 void TearDownOnMainThread() override { | |
| 63 // ScopedMockTimeMessageLoopTaskRunner's destructor re-posts pending tasks | |
| 64 // to the previous task runner. Get rid of them so they don't run after the | |
| 65 // test. | |
| 66 (*scoped_task_runner_)->ClearPendingTasks(); | |
| 67 | |
| 68 // Restore the standard task runner to perform browser cleanup, which posts | |
| 69 // some tasks with pending times but does not advance | |
| 70 // ScopedMockTimeMessageLoopTaskRunner's mock clock. | |
| 71 scoped_task_runner_.reset(); | |
| 72 } | |
| 73 | |
| 52 void TearDownInProcessBrowserTestFixture() override { | 74 void TearDownInProcessBrowserTestFixture() override { |
| 53 SetSwReporterTestingDelegate(nullptr); | 75 SetSwReporterTestingDelegate(nullptr); |
| 54 } | 76 } |
| 55 | 77 |
| 56 void RunReporter(const base::FilePath& exe_path = base::FilePath()) { | 78 void RunReporter(const base::FilePath& exe_path = base::FilePath()) { |
|
grt (UTC plus 2)
2017/02/22 12:25:26
wdyt of this taking the exit code as an in param s
Joe Mason
2017/02/22 17:56:45
Good idea. Done.
| |
| 57 auto invocation = SwReporterInvocation::FromFilePath(exe_path); | 79 auto invocation = SwReporterInvocation::FromFilePath(exe_path); |
| 58 invocation.supported_behaviours = | 80 invocation.supported_behaviours = |
| 59 SwReporterInvocation::BEHAVIOUR_LOG_TO_RAPPOR | | 81 SwReporterInvocation::BEHAVIOUR_LOG_TO_RAPPOR | |
| 60 SwReporterInvocation::BEHAVIOUR_LOG_EXIT_CODE_TO_PREFS | | 82 SwReporterInvocation::BEHAVIOUR_LOG_EXIT_CODE_TO_PREFS | |
| 61 SwReporterInvocation::BEHAVIOUR_TRIGGER_PROMPT | | 83 SwReporterInvocation::BEHAVIOUR_TRIGGER_PROMPT | |
| 62 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS; | 84 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS; |
| 63 | 85 |
| 64 SwReporterQueue invocations; | 86 SwReporterQueue invocations; |
| 65 invocations.push(invocation); | 87 invocations.push(invocation); |
| 66 RunSwReporters(invocations, base::Version("1.2.3"), task_runner_, | 88 RunSwReporters(invocations, base::Version("1.2.3")); |
| 67 task_runner_); | |
| 68 } | 89 } |
| 69 | 90 |
| 70 void RunReporterQueue(const SwReporterQueue& invocations) { | 91 void RunReporterQueue(const SwReporterQueue& invocations) { |
| 71 RunSwReporters(invocations, base::Version("1.2.3"), task_runner_, | 92 RunSwReporters(invocations, base::Version("1.2.3")); |
| 72 task_runner_); | |
| 73 } | 93 } |
| 74 | 94 |
| 75 void TriggerPrompt(Browser* browser, const std::string& version) override { | 95 void TriggerPrompt(Browser* browser, const std::string& version) override { |
| 76 prompt_trigger_called_ = true; | 96 prompt_trigger_called_ = true; |
| 77 } | 97 } |
| 78 | 98 |
| 79 int LaunchReporter(const SwReporterInvocation& invocation) override { | 99 int LaunchReporter(const SwReporterInvocation& invocation) override { |
|
grt (UTC plus 2)
2017/02/22 12:25:25
please document what this and the other delegate m
Joe Mason
2017/02/22 17:56:45
Done.
| |
| 80 ++reporter_launch_count_; | 100 ++reporter_launch_count_; |
| 81 reporter_launch_parameters_ = invocation; | 101 reporter_launch_parameters_.push_back(invocation); |
| 102 if (first_launch_callback_) | |
| 103 std::move(first_launch_callback_).Run(); | |
| 82 return exit_code_to_report_; | 104 return exit_code_to_report_; |
| 83 } | 105 } |
| 84 | 106 |
| 85 void NotifyLaunchReady() override { launch_ready_notified_ = true; } | 107 base::Time Now() const override { return (*scoped_task_runner_)->Now(); } |
| 86 | 108 |
| 87 void NotifyReporterDone() override { reporter_done_notified_ = true; } | 109 base::TaskRunner* BlockingTaskRunner() const override { |
| 110 return scoped_task_runner_->task_runner(); | |
| 111 } | |
| 88 | 112 |
| 89 // Sets |path| in the local state to a date corresponding to |days| days ago. | 113 // Sets |path| in the local state to a date corresponding to |days| days ago. |
| 90 void SetDateInLocalState(const std::string& path, int days) { | 114 void SetDateInLocalState(const std::string& path, int days) { |
| 91 PrefService* local_state = g_browser_process->local_state(); | 115 PrefService* local_state = g_browser_process->local_state(); |
| 92 DCHECK_NE(local_state, nullptr); | 116 DCHECK_NE(local_state, nullptr); |
|
grt (UTC plus 2)
2017/02/22 12:25:25
this is in the context of a browser test, so i don
Joe Mason
2017/02/22 17:56:45
Done.
| |
| 93 local_state->SetInt64(path, | 117 local_state->SetInt64( |
| 94 (base::Time::Now() - base::TimeDelta::FromDays(days)) | 118 path, (Now() - base::TimeDelta::FromDays(days)).ToInternalValue()); |
| 95 .ToInternalValue()); | |
| 96 } | 119 } |
| 97 | 120 |
| 98 void SetDaysSinceLastReport(int days) { | 121 void SetDaysSinceLastReport(int days) { |
|
grt (UTC plus 2)
2017/02/22 12:25:26
nit: group this with the other similar functions
Joe Mason
2017/02/22 17:56:45
Done.
| |
| 99 SetDateInLocalState(prefs::kSwReporterLastTimeTriggered, days); | 122 SetDateInLocalState(prefs::kSwReporterLastTimeTriggered, days); |
| 100 } | 123 } |
| 101 | 124 |
| 102 void ExpectToRunAgain(int days) { | 125 void ExpectToRunAgain(int days) { |
| 103 ASSERT_TRUE(task_runner_->HasPendingTask()); | 126 ASSERT_TRUE((*scoped_task_runner_)->HasPendingTask()); |
|
grt (UTC plus 2)
2017/02/22 12:25:25
ASSERT/FAIL in a helper function only has the desi
Joe Mason
2017/02/22 17:56:45
Fixed.
This particular ASSERT could just be an EX
grt (UTC plus 2)
2017/02/23 13:13:26
If you're not going to use ASSERT_NO_FATAL_FAILURE
Joe Mason
2017/02/23 15:49:29
Done.
| |
| 104 EXPECT_LE(task_runner_->NextPendingTaskDelay(), | 127 EXPECT_LE((*scoped_task_runner_)->NextPendingTaskDelay(), |
| 105 base::TimeDelta::FromDays(days)); | 128 base::TimeDelta::FromDays(days)); |
| 106 EXPECT_GT(task_runner_->NextPendingTaskDelay(), | 129 EXPECT_GT((*scoped_task_runner_)->NextPendingTaskDelay(), |
| 107 base::TimeDelta::FromDays(days) - base::TimeDelta::FromHours(1)); | 130 base::TimeDelta::FromDays(days) - base::TimeDelta::FromHours(1)); |
| 108 } | 131 } |
| 109 | 132 |
| 110 // Clears local state for last time the software reporter sent logs to |days| | 133 // Clears local state for last time the software reporter sent logs to |days| |
|
grt (UTC plus 2)
2017/02/22 12:25:25
comment seems out of sync ("...to |days| days ago.
Joe Mason
2017/02/22 17:56:45
Done.
| |
| 111 // days ago. This prevents potential false positives that could arise from | 134 // days ago. This prevents potential false positives that could arise from |
| 112 // state not properly cleaned between successive tests. | 135 // state not properly cleaned between successive tests. |
| 113 void ClearLastTimeSentReport() { | 136 void ClearLastTimeSentReport() { |
| 114 DCHECK_NE(g_browser_process, nullptr); | 137 DCHECK_NE(g_browser_process, nullptr); |
|
grt (UTC plus 2)
2017/02/22 12:25:25
same comment -- this runs in the context of a brow
Joe Mason
2017/02/22 17:56:45
Done.
| |
| 115 PrefService* local_state = g_browser_process->local_state(); | 138 PrefService* local_state = g_browser_process->local_state(); |
| 116 DCHECK_NE(local_state, nullptr); | 139 DCHECK_NE(local_state, nullptr); |
| 117 local_state->ClearPref(prefs::kSwReporterLastTimeSentReport); | 140 local_state->ClearPref(prefs::kSwReporterLastTimeSentReport); |
| 118 } | 141 } |
| 119 | 142 |
| 120 // Sets local state for last time the software reporter sent logs to |days| | 143 // Sets local state for last time the software reporter sent logs to |days| |
| 121 // days ago. | 144 // days ago. |
| 122 void SetLastTimeSentReport(int days) { | 145 void SetLastTimeSentReport(int days) { |
| 123 SetDateInLocalState(prefs::kSwReporterLastTimeSentReport, days); | 146 SetDateInLocalState(prefs::kSwReporterLastTimeSentReport, days); |
| 124 } | 147 } |
| 125 | 148 |
| 126 int64_t GetLastTimeSentReport() { | 149 int64_t GetLastTimeSentReport() { |
| 127 const PrefService* local_state = g_browser_process->local_state(); | 150 const PrefService* local_state = g_browser_process->local_state(); |
| 128 DCHECK_NE(local_state, nullptr); | 151 DCHECK_NE(local_state, nullptr); |
| 129 DCHECK(local_state->HasPrefPath(prefs::kSwReporterLastTimeSentReport)); | 152 DCHECK(local_state->HasPrefPath(prefs::kSwReporterLastTimeSentReport)); |
|
grt (UTC plus 2)
2017/02/22 12:25:26
why is this a DCHECK? is a failure here programmer
gab
2017/02/22 17:19:48
Note: ASSERT won't work with non-void return helpe
Joe Mason
2017/02/22 17:56:45
Programmer error in the test - calling GetLastTime
| |
| 130 return local_state->GetInt64(prefs::kSwReporterLastTimeSentReport); | 153 return local_state->GetInt64(prefs::kSwReporterLastTimeSentReport); |
| 131 } | 154 } |
| 132 | 155 |
| 133 void ExpectLastTimeSentReportNotSet() { | 156 void ExpectLastTimeSentReportNotSet() { |
| 134 PrefService* local_state = g_browser_process->local_state(); | 157 PrefService* local_state = g_browser_process->local_state(); |
| 135 DCHECK_NE(local_state, nullptr); | 158 DCHECK_NE(local_state, nullptr); |
| 136 EXPECT_FALSE( | 159 EXPECT_FALSE( |
| 137 local_state->HasPrefPath(prefs::kSwReporterLastTimeSentReport)); | 160 local_state->HasPrefPath(prefs::kSwReporterLastTimeSentReport)); |
| 138 } | 161 } |
| 139 | 162 |
| 140 void ExpectLastReportSentInTheLastHour() { | 163 void ExpectLastReportSentInTheLastHour() { |
| 141 const PrefService* local_state = g_browser_process->local_state(); | 164 const PrefService* local_state = g_browser_process->local_state(); |
| 142 DCHECK_NE(local_state, nullptr); | 165 DCHECK_NE(local_state, nullptr); |
| 143 const base::Time now = base::Time::Now(); | 166 const base::Time now = Now(); |
| 144 const base::Time last_time_sent_logs = base::Time::FromInternalValue( | 167 const base::Time last_time_sent_logs = base::Time::FromInternalValue( |
| 145 local_state->GetInt64(prefs::kSwReporterLastTimeSentReport)); | 168 local_state->GetInt64(prefs::kSwReporterLastTimeSentReport)); |
| 146 | 169 |
| 147 // Checks if the last time sent logs is set as no more than one hour ago, | 170 // Checks if the last time sent logs is set as no more than one hour ago, |
| 148 // which should be enough time if the execution does not fail. | 171 // which should be enough time if the execution does not fail. |
| 149 EXPECT_LT(now - base::TimeDelta::FromHours(1), last_time_sent_logs); | 172 EXPECT_LT(now - base::TimeDelta::FromHours(1), last_time_sent_logs); |
| 150 EXPECT_LT(last_time_sent_logs, now); | 173 EXPECT_LE(last_time_sent_logs, now); |
| 151 } | 174 } |
| 152 | 175 |
| 153 // Run through the steps needed to launch the reporter, as many times as | 176 // Expects that after |days_until_launched| days, the reporter will be |
| 154 // needed to launch all the reporters given in |expected_launch_paths|. Test | 177 // launched // |expected_launch_count| times, and TriggerPrompt will be |
|
grt (UTC plus 2)
2017/02/22 12:25:26
nit: "//" mid-comment
Joe Mason
2017/02/22 17:56:45
Done.
| |
| 155 // that each of those launches succeeded. But do not test that ONLY those | 178 // called if and only if |expect_prompt| is true. |
| 156 // launches succeeded. | 179 void ExpectReporterLaunches(int days_until_launch, |
| 157 // | 180 int expected_launch_count, |
| 158 // After this, if more launches are expected you can call | 181 bool expect_prompt) { |
| 159 // |TestPartialLaunchCycle| again with another list of paths, to test that | 182 ASSERT_TRUE((*scoped_task_runner_)->HasPendingTask()); |
| 160 // the launch cycle will continue with those paths. | 183 reporter_launch_count_ = 0; |
| 161 // | 184 reporter_launch_parameters_.clear(); |
| 162 // To test that a list of paths are launched AND NO OTHERS, use | 185 prompt_trigger_called_ = false; |
| 163 // |TestReporterLaunchCycle|. | |
| 164 void TestPartialLaunchCycle( | |
| 165 const std::vector<base::FilePath>& expected_launch_paths) { | |
| 166 // This test has an unfortunate amount of knowledge of the internals of | |
| 167 // ReporterRunner, because it needs to pump the right message loops at the | |
| 168 // right time so that all its internal messages are delivered. This | |
| 169 // function might need to be updated if the internals change. | |
| 170 // | |
| 171 // The basic sequence is: | |
| 172 // | |
| 173 // 1. TryToRun kicks the whole thing off. If the reporter should not be | |
| 174 // launched now (eg. DaysSinceLastReport is too low) it posts a call to | |
| 175 // itself again. (In a regular task runner this will be scheduled with a | |
| 176 // delay, but the test task runner ignores delays so TryToRun will be | |
| 177 // called again on the next call to RunPendingTasks.) | |
| 178 // | |
| 179 // 2. When it is time to run a reporter, TryToRun calls NotifyLaunchReady | |
| 180 // and then posts a call to LaunchAndWait. | |
| 181 // | |
| 182 // 3. When the reporter returns, a call to ReporterDone is posted on the UI | |
| 183 // thread. | |
| 184 // | |
| 185 // 4. ReporterDone calls NotifyReporterDone and then posts another call to | |
| 186 // TryToRun, which starts the whole process over for the next run. | |
| 187 // | |
| 188 // Each call to RunPendingTasks only handles messages already on the queue. | |
| 189 // It doesn't handle messages posted by those messages. So, we need to call | |
| 190 // it in a loop to make sure we're past all pending TryToRun calls before | |
| 191 // LaunchAndWaitForExit will be called. | |
| 192 // | |
| 193 // Once a call to LaunchAndWaitForExit has been posted, TryToRun won't be | |
| 194 // called again until we pump the UI message loop in order to run | |
| 195 // ReporterDone. | |
| 196 | 186 |
| 197 ASSERT_TRUE(task_runner_->HasPendingTask()); | 187 (*scoped_task_runner_) |
| 198 ASSERT_FALSE(reporter_done_notified_); | 188 ->FastForwardBy(base::TimeDelta::FromDays(days_until_launch)); |
| 199 | 189 |
| 200 reporter_launch_count_ = 0; | 190 EXPECT_EQ(reporter_launch_count_, expected_launch_count); |
|
grt (UTC plus 2)
2017/02/22 12:25:26
always put the expected value first for EXPECT_{EQ
Joe Mason
2017/02/22 17:56:45
I could have sworn I saw a thread on chromium-dev
grt (UTC plus 2)
2017/02/23 13:13:26
It's true in ToT gtest, but we're not using it yet
| |
| 201 reporter_launch_parameters_ = SwReporterInvocation(); | 191 EXPECT_EQ(prompt_trigger_called_, expect_prompt); |
| 192 } | |
| 202 | 193 |
| 203 int current_launch_count = reporter_launch_count_; | 194 // Expects that after |days_until_launched| days, the reporter will be |
| 204 for (const auto& expected_launch_path : expected_launch_paths) { | 195 // launched once with each path in |expected_launch_paths|, and TriggerPrompt |
| 205 // If RunReporter was called with no pending messages, and it was already | 196 // will be called if and only if |expect_prompt| is true. |
| 206 // time to launch the reporter, then |launch_ready_notified_| will | 197 void ExpectReporterLaunches( |
| 207 // already be true. Otherwise there will be a TryToRun message pending, | 198 int days_until_launch, |
| 208 // which must be processed first. | 199 const std::vector<base::FilePath>& expected_launch_paths, |
| 209 if (!launch_ready_notified_) { | 200 bool expect_prompt) { |
| 210 task_runner_->RunPendingTasks(); | 201 ExpectReporterLaunches(days_until_launch, expected_launch_paths.size(), |
| 211 // Since we're expecting a launch here, we expect it to schedule | 202 expect_prompt); |
| 212 // LaunchAndWaitForExit. So NOW |launch_ready_notified_| should be | 203 ASSERT_EQ(reporter_launch_parameters_.size(), expected_launch_paths.size()); |
| 213 // true. | 204 for (size_t i = 0; i < expected_launch_paths.size(); ++i) { |
| 214 ASSERT_TRUE(task_runner_->HasPendingTask()); | 205 EXPECT_EQ(expected_launch_paths[i], |
| 215 } | 206 reporter_launch_parameters_[i].command_line.GetProgram()); |
| 216 ASSERT_TRUE(launch_ready_notified_); | |
| 217 ASSERT_EQ(current_launch_count, reporter_launch_count_); | |
| 218 | |
| 219 // Reset |launch_ready_notified_| so that we can tell if TryToRun gets | |
| 220 // called again unexpectedly. | |
| 221 launch_ready_notified_ = false; | |
| 222 | |
| 223 // Call the pending LaunchAndWaitForExit. | |
| 224 task_runner_->RunPendingTasks(); | |
| 225 ASSERT_FALSE(launch_ready_notified_); | |
| 226 ASSERT_FALSE(reporter_done_notified_); | |
| 227 | |
| 228 // At this point LaunchAndWaitForExit has definitely been called if | |
| 229 // it's going to be called at all. (If not, TryToRun will have been | |
| 230 // scheduled again.) | |
| 231 EXPECT_EQ(current_launch_count + 1, reporter_launch_count_); | |
| 232 EXPECT_EQ(expected_launch_path, | |
| 233 reporter_launch_parameters_.command_line.GetProgram()); | |
| 234 | |
| 235 // Pump the UI message loop to process the ReporterDone call (which | |
| 236 // will schedule the next TryToRun.) If LaunchAndWaitForExit wasn't | |
| 237 // called, this does nothing. | |
| 238 base::RunLoop().RunUntilIdle(); | |
| 239 | |
| 240 // At this point there are three things that could have happened: | |
| 241 // | |
| 242 // 1. LaunchAndWaitForExit was not called. There should be a TryToRun | |
| 243 // scheduled. | |
| 244 // | |
| 245 // 2. ReporterDone was called and there was nothing left in the queue | |
| 246 // of SwReporterInvocation's. There should be a TryToRun scheduled. | |
| 247 // | |
| 248 // 3. ReporterDone was called and there were more | |
| 249 // SwReporterInvocation's in the queue to run immediately. There should | |
| 250 // be a LaunchAndWaitForExit scheduled. | |
| 251 // | |
| 252 // So in all cases there should be a pending task, and if we are expecting | |
| 253 // more launches in this loop, |launch_ready_notified_| will already be | |
| 254 // true. | |
| 255 ASSERT_TRUE(task_runner_->HasPendingTask()); | |
| 256 | |
| 257 // The test task runner does not actually advance the clock. Pretend that | |
| 258 // one day has passed. (Otherwise, when we launch the last | |
| 259 // SwReporterInvocation in the queue, the next call to TryToRun will | |
| 260 // start a whole new launch cycle.) | |
| 261 SetDaysSinceLastReport(1); | |
| 262 | |
| 263 reporter_done_notified_ = false; | |
| 264 current_launch_count = reporter_launch_count_; | |
| 265 } | 207 } |
| 266 } | 208 } |
| 267 | 209 |
| 268 // Run through the steps needed to launch the reporter, as many times as | 210 // Expects |invocation|'s command line to contain all the switches required |
| 269 // needed to launch all the reporters given in |expected_launch_paths|. Test | 211 // for reporter logging. |
| 270 // that each of those launches succeeded. Then, run through the steps needed | 212 void ExpectLoggingSwitches(const SwReporterInvocation& invocation, |
| 271 // to launch the reporter again, to test that the launch cycle is complete | 213 bool expect_switches) { |
| 272 // (no more reporters will be launched). | |
| 273 void TestReporterLaunchCycle( | |
| 274 const std::vector<base::FilePath>& expected_launch_paths) { | |
| 275 TestPartialLaunchCycle(expected_launch_paths); | |
| 276 | |
| 277 // Now that all expected launches have been tested, run the cycle once more | |
| 278 // to make sure no more launches happen. | |
| 279 ASSERT_TRUE(task_runner_->HasPendingTask()); | |
| 280 ASSERT_FALSE(reporter_done_notified_); | |
| 281 ASSERT_FALSE(launch_ready_notified_); | |
| 282 | |
| 283 int current_launch_count = reporter_launch_count_; | |
| 284 | |
| 285 // Call the pending TryToRun. | |
| 286 task_runner_->RunPendingTasks(); | |
| 287 | |
| 288 // We expect that this scheduled another TryToRun. If it scheduled | |
| 289 // LaunchAndWaitForExit an unexpected launch is about to happen. | |
| 290 ASSERT_TRUE(task_runner_->HasPendingTask()); | |
| 291 ASSERT_FALSE(launch_ready_notified_); | |
| 292 ASSERT_FALSE(reporter_done_notified_); | |
| 293 ASSERT_EQ(current_launch_count, reporter_launch_count_); | |
| 294 } | |
| 295 | |
| 296 // Expects |reporter_launch_parameters_| to contain exactly the command line | |
| 297 // switches specified in |expected_switches|. | |
| 298 void ExpectLoggingSwitches(const std::set<std::string>& expected_switches) { | |
| 299 const base::CommandLine::SwitchMap& invocation_switches = | 214 const base::CommandLine::SwitchMap& invocation_switches = |
| 300 reporter_launch_parameters_.command_line.GetSwitches(); | 215 invocation.command_line.GetSwitches(); |
| 216 std::set<std::string> expected_switches; | |
| 217 if (expect_switches) | |
| 218 expected_switches = {std::begin(kExpectedSwitches), | |
| 219 std::end(kExpectedSwitches)}; | |
| 301 EXPECT_EQ(expected_switches.size(), invocation_switches.size()); | 220 EXPECT_EQ(expected_switches.size(), invocation_switches.size()); |
| 302 // Checks if all expected switches are in the invocation switches. It's not | 221 // Checks if all expected switches are in the invocation switches. It's not |
| 303 // necessary to check if all invocation switches are expected, since we | 222 // necessary to check if all invocation switches are expected, since we |
| 304 // checked if both sets should have the same size. | 223 // checked if both sets should have the same size. |
| 305 for (const std::string& expected_switch : expected_switches) { | 224 for (const std::string& expected_switch : expected_switches) { |
| 306 EXPECT_NE(invocation_switches.find(expected_switch), | 225 EXPECT_NE(invocation_switches.find(expected_switch), |
| 307 invocation_switches.end()); | 226 invocation_switches.end()); |
| 308 } | 227 } |
| 309 } | 228 } |
| 310 | 229 |
| 311 void EnableSBExtendedReporting() { | 230 void EnableSBExtendedReporting() { |
| 312 Browser* browser = chrome::FindLastActive(); | 231 Browser* browser = chrome::FindLastActive(); |
| 313 ASSERT_NE(browser, nullptr); | 232 ASSERT_NE(browser, nullptr); |
| 314 Profile* profile = browser->profile(); | 233 Profile* profile = browser->profile(); |
| 315 ASSERT_NE(profile, nullptr); | 234 ASSERT_NE(profile, nullptr); |
| 316 SetExtendedReportingPref(profile->GetPrefs(), true); | 235 SetExtendedReportingPref(profile->GetPrefs(), true); |
| 317 } | 236 } |
| 318 | 237 |
| 319 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 238 // Replaces the main MessageLoop's TaskRunner with a TaskRunner on which time |
| 239 // is mocked to allow testing of scheduled launches. | |
| 240 std::unique_ptr<base::ScopedMockTimeMessageLoopTaskRunner> | |
| 241 scoped_task_runner_; | |
| 242 | |
| 320 bool prompt_trigger_called_ = false; | 243 bool prompt_trigger_called_ = false; |
| 321 int reporter_launch_count_ = 0; | 244 int reporter_launch_count_ = 0; |
| 322 SwReporterInvocation reporter_launch_parameters_; | 245 std::vector<SwReporterInvocation> reporter_launch_parameters_; |
| 323 int exit_code_to_report_ = kReporterFailureExitCode; | 246 int exit_code_to_report_ = kReporterFailureExitCode; |
| 324 | 247 |
| 325 // This will be set to true when a call to |LaunchAndWaitForExit| is next in | 248 // A callback to invoke when the first reporter of a queue is launched. This |
| 326 // the task queue. | 249 // can be used to perform actions in the middle of a queue of reporters which |
| 327 bool launch_ready_notified_ = false; | 250 // all launch on the same mock clock tick. |
| 328 | 251 base::OnceClosure first_launch_callback_; |
| 329 bool reporter_done_notified_ = false; | |
| 330 }; | 252 }; |
| 331 | 253 |
| 332 } // namespace | 254 } // namespace |
| 333 | 255 |
| 334 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, NothingFound) { | 256 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, NothingFound) { |
| 335 exit_code_to_report_ = kSwReporterNothingFound; | 257 exit_code_to_report_ = kSwReporterNothingFound; |
| 336 RunReporter(); | 258 RunReporter(); |
| 337 task_runner_->RunPendingTasks(); | 259 ExpectReporterLaunches(0, 1, false); |
| 338 EXPECT_EQ(1, reporter_launch_count_); | |
| 339 base::RunLoop().RunUntilIdle(); | |
| 340 EXPECT_FALSE(prompt_trigger_called_); | |
| 341 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 260 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
| 342 } | 261 } |
| 343 | 262 |
| 344 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, CleanupNeeded) { | 263 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, CleanupNeeded) { |
| 345 exit_code_to_report_ = kSwReporterCleanupNeeded; | 264 exit_code_to_report_ = kSwReporterCleanupNeeded; |
| 346 RunReporter(); | 265 RunReporter(); |
| 347 | 266 ExpectReporterLaunches(0, 1, true); |
| 348 task_runner_->RunPendingTasks(); | |
| 349 EXPECT_EQ(1, reporter_launch_count_); | |
| 350 // The reply task from the task posted to run the reporter is run on a | |
| 351 // specific thread, as opposed to a specific task runner, and that thread is | |
| 352 // the current message loop's thread. | |
| 353 base::RunLoop().RunUntilIdle(); | |
| 354 EXPECT_TRUE(prompt_trigger_called_); | |
| 355 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 267 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
| 356 } | 268 } |
| 357 | 269 |
| 358 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, RanRecently) { | 270 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, RanRecently) { |
| 359 constexpr int kDaysLeft = 1; | 271 constexpr int kDaysLeft = 1; |
| 360 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft); | 272 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft); |
| 361 RunReporter(); | 273 RunReporter(); |
| 362 | 274 ExpectReporterLaunches(0, 0, false); |
| 363 // Here we can't run until idle since the ReporterRunner will re-post | |
| 364 // infinitely. | |
| 365 task_runner_->RunPendingTasks(); | |
| 366 EXPECT_EQ(0, reporter_launch_count_); | |
| 367 | |
| 368 ExpectToRunAgain(kDaysLeft); | 275 ExpectToRunAgain(kDaysLeft); |
| 369 task_runner_->ClearPendingTasks(); | 276 ExpectReporterLaunches(kDaysLeft, 1, false); |
| 277 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | |
| 370 } | 278 } |
| 371 | 279 |
| 372 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, WaitForBrowser) { | 280 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, WaitForBrowser) { |
| 373 Profile* profile = browser()->profile(); | 281 Profile* profile = browser()->profile(); |
| 374 CloseAllBrowsers(); | |
| 375 | 282 |
| 283 // Ensure that even though we're closing the last browser, we don't enter the | |
| 284 // "shutting down" state, which will prevent the test from starting another | |
| 285 // browser. | |
| 286 ScopedKeepAlive test_keep_alive(KeepAliveOrigin::SESSION_RESTORE, | |
| 287 KeepAliveRestartOption::ENABLED); | |
| 288 | |
| 289 // Restore the standard task runner to perform browser cleanup, which posts | |
| 290 // some tasks with pending times but does not advance | |
| 291 // ScopedMockTimeMessageLoopTaskRunner's mock clock. | |
| 292 scoped_task_runner_.reset(); | |
| 293 CloseBrowserSynchronously(browser()); | |
| 294 scoped_task_runner_ = | |
| 295 base::MakeUnique<base::ScopedMockTimeMessageLoopTaskRunner>(); | |
| 296 ASSERT_EQ(0u, chrome::GetTotalBrowserCount()); | |
| 297 ASSERT_FALSE(chrome::FindLastActive()); | |
| 298 | |
| 299 // Start the reporter while the browser is closed. The prompt should not open. | |
| 376 exit_code_to_report_ = kSwReporterCleanupNeeded; | 300 exit_code_to_report_ = kSwReporterCleanupNeeded; |
| 377 RunReporter(); | 301 RunReporter(); |
| 302 ExpectReporterLaunches(0, 1, false); | |
| 378 | 303 |
| 379 task_runner_->RunPendingTasks(); | 304 // Create a Browser object directly instead of using helper functions like |
| 305 // CreateBrowser, because they all wait on timed events but do not advance the | |
| 306 // mock timer. The Browser constructor registers itself with the global | |
| 307 // BrowserList, which is cleaned up when InProcessBrowserTest exits. | |
| 308 new Browser(Browser::CreateParams(profile)); | |
| 309 ASSERT_EQ(1u, chrome::GetTotalBrowserCount()); | |
| 310 | |
| 311 // Some browser startup tasks are scheduled to run in the first few minutes | |
| 312 // after creation. Make sure they've all been processed so that the only | |
| 313 // pending task in the queue is the next reporter check. | |
| 314 (*scoped_task_runner_)->FastForwardBy(base::TimeDelta::FromMinutes(10)); | |
| 315 | |
| 316 // On opening the new browser, the prompt should be shown and the reporter | |
| 317 // should be scheduled to run later. | |
| 380 EXPECT_EQ(1, reporter_launch_count_); | 318 EXPECT_EQ(1, reporter_launch_count_); |
| 381 | |
| 382 CreateBrowser(profile); | |
| 383 EXPECT_TRUE(prompt_trigger_called_); | 319 EXPECT_TRUE(prompt_trigger_called_); |
| 384 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 320 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
| 385 } | 321 } |
| 386 | 322 |
| 387 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, Failure) { | 323 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, Failure) { |
| 388 exit_code_to_report_ = kReporterFailureExitCode; | 324 exit_code_to_report_ = kReporterFailureExitCode; |
| 389 RunReporter(); | 325 RunReporter(); |
| 390 | 326 ExpectReporterLaunches(0, 1, false); |
| 391 task_runner_->RunPendingTasks(); | |
| 392 EXPECT_EQ(1, reporter_launch_count_); | |
| 393 | |
| 394 base::RunLoop().RunUntilIdle(); | |
| 395 EXPECT_FALSE(prompt_trigger_called_); | |
| 396 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 327 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
| 397 } | 328 } |
| 398 | 329 |
| 399 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, RunDaily) { | 330 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, RunDaily) { |
| 400 exit_code_to_report_ = kSwReporterNothingFound; | 331 exit_code_to_report_ = kSwReporterNothingFound; |
| 401 PrefService* local_state = g_browser_process->local_state(); | 332 PrefService* local_state = g_browser_process->local_state(); |
| 402 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, true); | 333 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, true); |
| 403 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - 1); | 334 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - 1); |
| 404 DCHECK_GT(kDaysBetweenSuccessfulSwReporterRuns - 1, | 335 DCHECK_GT(kDaysBetweenSuccessfulSwReporterRuns - 1, |
| 405 kDaysBetweenSwReporterRunsForPendingPrompt); | 336 kDaysBetweenSwReporterRunsForPendingPrompt); |
| 406 RunReporter(); | 337 RunReporter(); |
| 407 | 338 |
| 408 task_runner_->RunPendingTasks(); | 339 // Expect the reporter to run immediately, since a prompt is pending and it |
| 409 EXPECT_EQ(1, reporter_launch_count_); | 340 // has been more than kDaysBetweenSwReporterRunsForPendingPrompt days. |
| 410 reporter_launch_count_ = 0; | 341 ExpectReporterLaunches(0, 1, false); |
| 411 base::RunLoop().RunUntilIdle(); | |
| 412 ExpectToRunAgain(kDaysBetweenSwReporterRunsForPendingPrompt); | 342 ExpectToRunAgain(kDaysBetweenSwReporterRunsForPendingPrompt); |
| 413 | 343 |
| 344 // Move the clock ahead kDaysBetweenSwReporterRunsForPendingPrompt days. The | |
| 345 // expected run should trigger, but not cause the reporter to launch because | |
| 346 // a prompt is no longer pending. | |
| 414 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, false); | 347 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, false); |
| 415 task_runner_->RunPendingTasks(); | 348 ExpectReporterLaunches(kDaysBetweenSwReporterRunsForPendingPrompt, 0, false); |
| 416 EXPECT_EQ(0, reporter_launch_count_); | 349 |
| 417 base::RunLoop().RunUntilIdle(); | 350 // Instead it should now run kDaysBetweenSuccessfulSwReporterRuns after the |
| 351 // first prompt (of which kDaysBetweenSwReporterRunsForPendingPrompt has | |
| 352 // already passed.) | |
| 353 int days_left = kDaysBetweenSuccessfulSwReporterRuns - | |
| 354 kDaysBetweenSwReporterRunsForPendingPrompt; | |
| 355 ExpectToRunAgain(days_left); | |
| 356 ExpectReporterLaunches(days_left, 1, false); | |
| 418 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | 357 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
| 419 } | 358 } |
| 420 | 359 |
| 421 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ParameterChange) { | 360 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ParameterChange) { |
| 422 exit_code_to_report_ = kSwReporterNothingFound; | 361 exit_code_to_report_ = kSwReporterNothingFound; |
| 423 | 362 |
| 424 // If the reporter is run several times with different parameters, it should | 363 // If the reporter is run several times with different parameters, it should |
| 425 // only be launched once, with the last parameter set. | 364 // only be launched once, with the last parameter set. |
| 426 const base::FilePath path1(L"path1"); | 365 const base::FilePath path1(L"path1"); |
| 427 const base::FilePath path2(L"path2"); | 366 const base::FilePath path2(L"path2"); |
| 428 const base::FilePath path3(L"path3"); | 367 const base::FilePath path3(L"path3"); |
| 429 | 368 |
| 430 // Schedule path1 with a day left in the reporting period. | 369 // Schedule path1 with a day left in the reporting period. |
| 431 // The reporter should not launch. | 370 // The reporter should not launch. |
| 432 constexpr int kDaysLeft = 1; | 371 constexpr int kDaysLeft = 1; |
| 433 { | 372 { |
| 434 SCOPED_TRACE("N days left until next reporter run"); | 373 SCOPED_TRACE("N days left until next reporter run"); |
| 435 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft); | 374 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft); |
| 436 RunReporter(path1); | 375 RunReporter(path1); |
| 437 TestReporterLaunchCycle({}); | 376 ExpectReporterLaunches(0, {}, false); |
|
grt (UTC plus 2)
2017/02/22 12:25:25
do you not need to #include <initializer_list> for
Joe Mason
2017/02/22 17:56:45
I think only when the type is used explicitly (suc
grt (UTC plus 2)
2017/02/23 13:13:26
I think you do need it. You're getting by without
Joe Mason
2017/02/23 15:49:29
Done. Also noticed <vector> was missing, and <memo
| |
| 438 } | 377 } |
| 439 | 378 |
| 440 // Schedule path2 just as we enter the next reporting period. | 379 // Schedule path2 just as we enter the next reporting period. |
| 441 // Now the reporter should launch, just once, using path2. | 380 // Now the reporter should launch, just once, using path2. |
| 442 { | 381 { |
| 443 SCOPED_TRACE("Reporter runs now"); | 382 SCOPED_TRACE("Reporter runs now"); |
| 444 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); | |
| 445 RunReporter(path2); | 383 RunReporter(path2); |
| 446 // Schedule it twice; it should only actually run once. | 384 // Schedule it twice; it should only actually run once. |
| 447 RunReporter(path2); | 385 RunReporter(path2); |
| 448 TestReporterLaunchCycle({path2}); | 386 ExpectReporterLaunches(kDaysLeft, {path2}, false); |
| 449 } | 387 } |
| 450 | 388 |
| 451 // Schedule path3 before any more time has passed. | 389 // Schedule path3 before any more time has passed. |
| 452 // The reporter should not launch. | 390 // The reporter should not launch. |
| 453 { | 391 { |
| 454 SCOPED_TRACE("No more time passed"); | 392 SCOPED_TRACE("No more time passed"); |
| 455 SetDaysSinceLastReport(0); | |
| 456 RunReporter(path3); | 393 RunReporter(path3); |
| 457 TestReporterLaunchCycle({}); | 394 ExpectReporterLaunches(0, {}, false); |
| 458 } | 395 } |
| 459 | 396 |
| 460 // Enter the next reporting period as path3 is still scheduled. | 397 // Enter the next reporting period as path3 is still scheduled. |
| 461 // Now the reporter should launch again using path3. (Tests that the | 398 // Now the reporter should launch again using path3. (Tests that the |
| 462 // parameters from the first launch aren't reused.) | 399 // parameters from the first launch aren't reused.) |
| 463 { | 400 { |
| 464 SCOPED_TRACE("Previous run still scheduled"); | 401 SCOPED_TRACE("Previous run still scheduled"); |
| 465 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); | 402 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path3}, |
| 466 TestReporterLaunchCycle({path3}); | 403 false); |
| 467 } | 404 } |
| 468 | 405 |
| 469 // Schedule path3 again in the next reporting period. | 406 // Schedule path3 again in the next reporting period. |
| 470 // The reporter should launch again using path3, since enough time has | 407 // The reporter should launch again using path3, since enough time has |
| 471 // passed, even though the parameters haven't changed. | 408 // passed, even though the parameters haven't changed. |
| 472 { | 409 { |
| 473 SCOPED_TRACE("Run with same parameters"); | 410 SCOPED_TRACE("Run with same parameters"); |
| 474 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); | |
| 475 RunReporter(path3); | 411 RunReporter(path3); |
| 476 TestReporterLaunchCycle({path3}); | 412 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path3}, |
| 413 false); | |
| 477 } | 414 } |
| 478 } | 415 } |
| 479 | 416 |
| 480 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, MultipleLaunches) { | 417 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, MultipleLaunches) { |
| 481 exit_code_to_report_ = kSwReporterNothingFound; | 418 exit_code_to_report_ = kSwReporterNothingFound; |
| 482 | 419 |
| 483 const base::FilePath path1(L"path1"); | 420 const base::FilePath path1(L"path1"); |
| 484 const base::FilePath path2(L"path2"); | 421 const base::FilePath path2(L"path2"); |
| 485 const base::FilePath path3(L"path3"); | 422 const base::FilePath path3(L"path3"); |
| 486 | 423 |
| 487 SwReporterQueue invocations; | 424 SwReporterQueue invocations; |
| 488 invocations.push(SwReporterInvocation::FromFilePath(path1)); | 425 invocations.push(SwReporterInvocation::FromFilePath(path1)); |
| 489 invocations.push(SwReporterInvocation::FromFilePath(path2)); | 426 invocations.push(SwReporterInvocation::FromFilePath(path2)); |
| 490 | 427 |
| 491 { | 428 { |
| 492 SCOPED_TRACE("Launch 2 times"); | 429 SCOPED_TRACE("Launch 2 times"); |
| 493 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); | 430 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); |
| 494 RunReporterQueue(invocations); | 431 RunReporterQueue(invocations); |
| 495 TestReporterLaunchCycle({path1, path2}); | 432 ExpectReporterLaunches(0, {path1, path2}, false); |
| 433 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | |
| 496 } | 434 } |
| 497 | 435 |
| 498 // Schedule a launch with 2 elements, then another with the same 2. It should | 436 // Schedule a launch with 2 elements, then another with the same 2. It should |
| 499 // just run 2 times, not 4. | 437 // just run 2 times, not 4. |
| 500 { | 438 { |
| 501 SCOPED_TRACE("Launch 2 times with retry"); | 439 SCOPED_TRACE("Launch 2 times with retry"); |
| 502 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); | |
| 503 RunReporterQueue(invocations); | 440 RunReporterQueue(invocations); |
| 504 RunReporterQueue(invocations); | 441 RunReporterQueue(invocations); |
| 505 TestReporterLaunchCycle({path1, path2}); | 442 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1, path2}, |
| 443 false); | |
| 444 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | |
| 506 } | 445 } |
| 507 | 446 |
| 508 // Schedule a launch with 2 elements, then add a third while the queue is | 447 // Another launch with 2 elements is already scheduled. Add a third while the |
| 509 // running. | 448 // queue is running. |
| 510 { | 449 { |
| 511 SCOPED_TRACE("Add third launch while running"); | 450 SCOPED_TRACE("Add third launch while running"); |
| 512 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); | 451 invocations.push(SwReporterInvocation::FromFilePath(path3)); |
| 513 RunReporterQueue(invocations); | 452 first_launch_callback_ = base::BindOnce( |
| 453 &SRTFetcherTest::RunReporterQueue, base::Unretained(this), invocations); | |
| 514 | 454 |
| 515 // Only test the cycle once, to process the first element in queue. | 455 // Only the first two elements should execute since the third was added |
| 516 TestPartialLaunchCycle({path1}); | 456 // during the cycle. |
| 517 | 457 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1, path2}, |
| 518 invocations.push(SwReporterInvocation::FromFilePath(path3)); | 458 false); |
| 519 RunReporterQueue(invocations); | 459 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); |
| 520 | |
| 521 // There is still a 2nd element on the queue - that should execute, and | |
| 522 // nothing more. | |
| 523 TestReporterLaunchCycle({path2}); | |
| 524 | 460 |
| 525 // Time passes... Now the 3-element queue should run. | 461 // Time passes... Now the 3-element queue should run. |
| 526 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); | 462 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, |
| 527 TestReporterLaunchCycle({path1, path2, path3}); | 463 {path1, path2, path3}, false); |
| 464 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | |
| 528 } | 465 } |
| 529 | 466 |
| 530 // Second launch should not occur after a failure. | 467 // Second launch should not occur after a failure. |
| 531 { | 468 { |
| 532 SCOPED_TRACE("Launch multiple times with failure"); | 469 SCOPED_TRACE("Launch multiple times with failure"); |
| 533 exit_code_to_report_ = kReporterFailureExitCode; | 470 exit_code_to_report_ = kReporterFailureExitCode; |
| 534 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); | |
| 535 RunReporterQueue(invocations); | 471 RunReporterQueue(invocations); |
| 536 TestReporterLaunchCycle({path1}); | 472 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1}, |
| 473 false); | |
| 474 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | |
| 537 | 475 |
| 538 // If we try again before the reporting period is up, it should not do | 476 // If we try again before the reporting period is up, it should not do |
| 539 // anything. | 477 // anything. |
| 540 TestReporterLaunchCycle({}); | 478 ExpectReporterLaunches(0, {}, false); |
| 541 | 479 |
| 542 // After enough time has passed, should try the queue again. | 480 // After enough time has passed, should try the queue again. |
| 543 SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns); | 481 ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1}, |
| 544 TestReporterLaunchCycle({path1}); | 482 false); |
| 483 ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns); | |
| 545 } | 484 } |
| 546 } | 485 } |
| 547 | 486 |
| 548 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_NoSBExtendedReporting) { | 487 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_NoSBExtendedReporting) { |
| 549 exit_code_to_report_ = kSwReporterNothingFound; | 488 exit_code_to_report_ = kSwReporterNothingFound; |
| 550 base::test::ScopedFeatureList scoped_feature_list; | 489 base::test::ScopedFeatureList scoped_feature_list; |
| 551 RunReporter(); | 490 RunReporter(); |
| 552 TestReporterLaunchCycle({base::FilePath()}); | 491 ExpectReporterLaunches(0, 1, false); |
| 553 ExpectLoggingSwitches({/*expect no switches*/}); | 492 ExpectLoggingSwitches(reporter_launch_parameters_.front(), false); |
| 554 ExpectLastTimeSentReportNotSet(); | 493 ExpectLastTimeSentReportNotSet(); |
| 555 } | 494 } |
| 556 | 495 |
| 557 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledFirstRun) { | 496 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledFirstRun) { |
| 558 exit_code_to_report_ = kSwReporterNothingFound; | 497 exit_code_to_report_ = kSwReporterNothingFound; |
| 559 base::test::ScopedFeatureList scoped_feature_list; | 498 base::test::ScopedFeatureList scoped_feature_list; |
| 560 EnableSBExtendedReporting(); | 499 EnableSBExtendedReporting(); |
| 561 // Note: don't set last time sent logs in the local state. | 500 // Note: don't set last time sent logs in the local state. |
| 562 // SBER is enabled and there is no record in the local state of the last time | 501 // SBER is enabled and there is no record in the local state of the last time |
| 563 // logs have been sent, so we should send logs in this run. | 502 // logs have been sent, so we should send logs in this run. |
| 564 RunReporter(); | 503 RunReporter(); |
| 565 TestReporterLaunchCycle({base::FilePath()}); | 504 ExpectReporterLaunches(0, 1, false); |
| 566 ExpectLoggingSwitches(std::set<std::string>(std::begin(kExpectedSwitches), | 505 ExpectLoggingSwitches(reporter_launch_parameters_.front(), true); |
| 567 std::end(kExpectedSwitches))); | |
| 568 ExpectLastReportSentInTheLastHour(); | 506 ExpectLastReportSentInTheLastHour(); |
| 569 } | 507 } |
| 570 | 508 |
| 571 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledNoRecentLogging) { | 509 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledNoRecentLogging) { |
| 572 exit_code_to_report_ = kSwReporterNothingFound; | 510 exit_code_to_report_ = kSwReporterNothingFound; |
| 573 base::test::ScopedFeatureList scoped_feature_list; | 511 base::test::ScopedFeatureList scoped_feature_list; |
| 574 // SBER is enabled and last time logs were sent was more than | 512 // SBER is enabled and last time logs were sent was more than |
| 575 // |kDaysBetweenReporterLogsSent| day ago, so we should send logs in this run. | 513 // |kDaysBetweenReporterLogsSent| day ago, so we should send logs in this run. |
| 576 EnableSBExtendedReporting(); | 514 EnableSBExtendedReporting(); |
| 577 SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3); | 515 SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3); |
| 578 RunReporter(); | 516 RunReporter(); |
| 579 TestReporterLaunchCycle({base::FilePath()}); | 517 ExpectReporterLaunches(0, 1, false); |
| 580 ExpectLoggingSwitches(std::set<std::string>(std::begin(kExpectedSwitches), | 518 ExpectLoggingSwitches(reporter_launch_parameters_.front(), true); |
| 581 std::end(kExpectedSwitches))); | |
| 582 ExpectLastReportSentInTheLastHour(); | 519 ExpectLastReportSentInTheLastHour(); |
| 583 } | 520 } |
| 584 | 521 |
| 585 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledRecentlyLogged) { | 522 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledRecentlyLogged) { |
| 586 exit_code_to_report_ = kSwReporterNothingFound; | 523 exit_code_to_report_ = kSwReporterNothingFound; |
| 587 base::test::ScopedFeatureList scoped_feature_list; | 524 base::test::ScopedFeatureList scoped_feature_list; |
| 588 // SBER is enabled, but logs have been sent less than | 525 // SBER is enabled, but logs have been sent less than |
| 589 // |kDaysBetweenReporterLogsSent| day ago, so we shouldn't send any logs in | 526 // |kDaysBetweenReporterLogsSent| day ago, so we shouldn't send any logs in |
| 590 // this run. | 527 // this run. |
| 591 EnableSBExtendedReporting(); | 528 EnableSBExtendedReporting(); |
| 592 SetLastTimeSentReport(kDaysBetweenReporterLogsSent - 1); | 529 SetLastTimeSentReport(kDaysBetweenReporterLogsSent - 1); |
| 593 int64_t last_time_sent_logs = GetLastTimeSentReport(); | 530 int64_t last_time_sent_logs = GetLastTimeSentReport(); |
| 594 RunReporter(); | 531 RunReporter(); |
| 595 TestReporterLaunchCycle({base::FilePath()}); | 532 ExpectReporterLaunches(0, 1, false); |
| 596 ExpectLoggingSwitches(std::set<std::string>{/*expect no switches*/}); | 533 ExpectLoggingSwitches(reporter_launch_parameters_.front(), false); |
| 597 EXPECT_EQ(last_time_sent_logs, GetLastTimeSentReport()); | 534 EXPECT_EQ(last_time_sent_logs, GetLastTimeSentReport()); |
| 598 } | 535 } |
| 599 | 536 |
| 600 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_MultipleLaunches) { | 537 IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_MultipleLaunches) { |
| 601 exit_code_to_report_ = kSwReporterNothingFound; | 538 exit_code_to_report_ = kSwReporterNothingFound; |
| 602 base::test::ScopedFeatureList scoped_feature_list; | 539 base::test::ScopedFeatureList scoped_feature_list; |
| 603 EnableSBExtendedReporting(); | 540 EnableSBExtendedReporting(); |
| 604 SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3); | 541 SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3); |
| 605 | 542 |
| 606 const base::FilePath path1(L"path1"); | 543 const base::FilePath path1(L"path1"); |
| 607 const base::FilePath path2(L"path2"); | 544 const base::FilePath path2(L"path2"); |
| 608 SwReporterQueue invocations; | 545 SwReporterQueue invocations; |
| 609 for (const auto& path : {path1, path2}) { | 546 for (const auto& path : {path1, path2}) { |
| 610 auto invocation = SwReporterInvocation::FromFilePath(path); | 547 auto invocation = SwReporterInvocation::FromFilePath(path); |
| 611 invocation.supported_behaviours = | 548 invocation.supported_behaviours = |
| 612 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS; | 549 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS; |
| 613 invocations.push(invocation); | 550 invocations.push(invocation); |
| 614 } | 551 } |
| 615 RunReporterQueue(invocations); | 552 RunReporterQueue(invocations); |
| 616 | 553 |
| 617 // SBER is enabled and last time logs were sent was more than | 554 // SBER is enabled and last time logs were sent was more than |
| 618 // |kDaysBetweenReporterLogsSent| day ago, so we should send logs in this run. | 555 // |kDaysBetweenReporterLogsSent| day ago, so we should send logs in this run. |
| 619 { | 556 { |
| 620 SCOPED_TRACE("first launch"); | 557 SCOPED_TRACE("first launch"); |
| 621 TestPartialLaunchCycle({path1}); | 558 first_launch_callback_ = |
| 622 ExpectLoggingSwitches(std::set<std::string>(std::begin(kExpectedSwitches), | 559 base::BindOnce(&SRTFetcherTest::ExpectLastReportSentInTheLastHour, |
| 623 std::end(kExpectedSwitches))); | 560 base::Unretained(this)); |
| 624 ExpectLastReportSentInTheLastHour(); | 561 ExpectReporterLaunches(0, {path1, path2}, false); |
| 562 ExpectLoggingSwitches(reporter_launch_parameters_[0], true); | |
| 625 } | 563 } |
| 626 | 564 |
| 627 // Logs should also be sent for the next run, even though LastTimeSentReport | 565 // Logs should also be sent for the next run, even though LastTimeSentReport |
| 628 // is now recent, because the run is part of the same set of invocations. | 566 // is now recent, because the run is part of the same set of invocations. |
| 629 { | 567 { |
| 630 SCOPED_TRACE("second launch"); | 568 SCOPED_TRACE("second launch"); |
| 631 TestReporterLaunchCycle({path2}); | 569 ExpectLoggingSwitches(reporter_launch_parameters_[1], true); |
| 632 ExpectLoggingSwitches(std::set<std::string>(std::begin(kExpectedSwitches), | |
| 633 std::end(kExpectedSwitches))); | |
| 634 ExpectLastReportSentInTheLastHour(); | 570 ExpectLastReportSentInTheLastHour(); |
| 635 } | 571 } |
| 636 } | 572 } |
| 637 | 573 |
| 638 } // namespace safe_browsing | 574 } // namespace safe_browsing |
| OLD | NEW |