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