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