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