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

Unified Diff: chrome/browser/safe_browsing/srt_fetcher_browsertest_win.cc

Issue 2700233002: Update SRTFetcher browser test to use ScopedMockTimeMessageLoopTaskRunner (Closed)
Patch Set: Rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/safe_browsing/srt_fetcher_browsertest_win.cc
diff --git a/chrome/browser/safe_browsing/srt_fetcher_browsertest_win.cc b/chrome/browser/safe_browsing/srt_fetcher_browsertest_win.cc
index 01409845850f07e3bd50b70e25bc5b4ebfc72b31..8f80e7bbee3037a186233390ec8d6dc548efb810 100644
--- a/chrome/browser/safe_browsing/srt_fetcher_browsertest_win.cc
+++ b/chrome/browser/safe_browsing/srt_fetcher_browsertest_win.cc
@@ -4,18 +4,25 @@
#include "chrome/browser/safe_browsing/srt_fetcher_win.h"
+#include <initializer_list>
#include <iterator>
-#include <memory>
#include <set>
+#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/callback.h"
#include "base/files/file_path.h"
-#include "base/run_loop.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/test/scoped_feature_list.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/test_mock_time_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "base/version.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/lifetime/keep_alive_types.h"
+#include "chrome/browser/lifetime/scoped_keep_alive.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/srt_client_info_win.h"
#include "chrome/browser/ui/browser.h"
@@ -25,7 +32,6 @@
#include "components/component_updater/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing_db/safe_browsing_prefs.h"
-#include "content/public/test/test_browser_thread_bundle.h"
namespace safe_browsing {
@@ -39,21 +45,67 @@ class SRTFetcherTest : public InProcessBrowserTest,
public SwReporterTestingDelegate {
public:
void SetUpInProcessBrowserTestFixture() override {
- task_runner_ = new base::TestSimpleTaskRunner;
-
SetSwReporterTestingDelegate(this);
}
void SetUpOnMainThread() override {
+ // During the test, use a task runner with a mock clock.
+ saved_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+ ASSERT_NE(mock_time_task_runner_, saved_task_runner_);
+ base::MessageLoop::current()->SetTaskRunner(mock_time_task_runner_);
+
InProcessBrowserTest::SetUpOnMainThread();
+
+ // SetDateInLocalState calculates a time as Now() minus an offset. Move the
+ // simulated clock ahead far enough that this calculation won't underflow.
+ mock_time_task_runner_->FastForwardBy(
+ base::TimeDelta::FromDays(kDaysBetweenSuccessfulSwReporterRuns * 2));
+
ClearLastTimeSentReport();
}
+ void TearDownOnMainThread() override {
+ // Restore the standard task runner to perform browser cleanup, which will
+ // wait forever with the mock clock.
+ base::MessageLoop::current()->SetTaskRunner(saved_task_runner_);
+ }
+
void TearDownInProcessBrowserTestFixture() override {
SetSwReporterTestingDelegate(nullptr);
}
- void RunReporter(const base::FilePath& exe_path = base::FilePath()) {
+ // Records that the prompt was shown.
+ void TriggerPrompt(Browser* browser, const std::string& version) override {
+ prompt_trigger_called_ = true;
+ }
+
+ // Records that the reporter was launched with the parameters given in
+ // |invocation|.
+ int LaunchReporter(const SwReporterInvocation& invocation) override {
+ ++reporter_launch_count_;
+ reporter_launch_parameters_.push_back(invocation);
+ if (first_launch_callback_)
+ std::move(first_launch_callback_).Run();
+ return exit_code_to_report_;
+ }
+
+ // Returns the test's idea of the current time.
+ base::Time Now() const override { return mock_time_task_runner_->Now(); }
+
+ // Returns a task runner to use when launching the reporter (which is
+ // normally a blocking action).
+ base::TaskRunner* BlockingTaskRunner() const override {
+ // Use the test's main task runner so that we don't need to pump another
+ // message loop. Since the test calls LaunchReporter instead of actually
+ // doing a blocking reporter launch, it doesn't matter that the task runner
+ // doesn't have the MayBlock trait.
+ return mock_time_task_runner_.get();
+ }
+
+ // Schedules a single reporter to run.
+ void RunReporter(int exit_code_to_report,
+ const base::FilePath& exe_path = base::FilePath()) {
+ exit_code_to_report_ = exit_code_to_report;
auto invocation = SwReporterInvocation::FromFilePath(exe_path);
invocation.supported_behaviours =
SwReporterInvocation::BEHAVIOUR_LOG_TO_RAPPOR |
@@ -63,364 +115,259 @@ class SRTFetcherTest : public InProcessBrowserTest,
SwReporterQueue invocations;
invocations.push(invocation);
- RunSwReporters(invocations, base::Version("1.2.3"), task_runner_,
- task_runner_);
- }
-
- void RunReporterQueue(const SwReporterQueue& invocations) {
- RunSwReporters(invocations, base::Version("1.2.3"), task_runner_,
- task_runner_);
+ RunSwReporters(invocations, base::Version("1.2.3"));
}
- void TriggerPrompt(Browser* browser, const std::string& version) override {
- prompt_trigger_called_ = true;
+ // Schedules a queue of reporters to run.
+ void RunReporterQueue(int exit_code_to_report,
+ const SwReporterQueue& invocations) {
+ exit_code_to_report_ = exit_code_to_report;
+ RunSwReporters(invocations, base::Version("1.2.3"));
}
- int LaunchReporter(const SwReporterInvocation& invocation) override {
- ++reporter_launch_count_;
- reporter_launch_parameters_ = invocation;
- return exit_code_to_report_;
- }
-
- void NotifyLaunchReady() override { launch_ready_notified_ = true; }
-
- void NotifyReporterDone() override { reporter_done_notified_ = true; }
-
// Sets |path| in the local state to a date corresponding to |days| days ago.
void SetDateInLocalState(const std::string& path, int days) {
PrefService* local_state = g_browser_process->local_state();
- DCHECK_NE(local_state, nullptr);
- local_state->SetInt64(path,
- (base::Time::Now() - base::TimeDelta::FromDays(days))
- .ToInternalValue());
+ local_state->SetInt64(
+ path, (Now() - base::TimeDelta::FromDays(days)).ToInternalValue());
}
- void SetDaysSinceLastReport(int days) {
+ // Sets local state for last time the software reporter ran to |days| days
+ // ago.
+ void SetDaysSinceLastTriggered(int days) {
SetDateInLocalState(prefs::kSwReporterLastTimeTriggered, days);
}
- void ExpectToRunAgain(int days) {
- ASSERT_TRUE(task_runner_->HasPendingTask());
- EXPECT_LE(task_runner_->NextPendingTaskDelay(),
- base::TimeDelta::FromDays(days));
- EXPECT_GT(task_runner_->NextPendingTaskDelay(),
- base::TimeDelta::FromDays(days) - base::TimeDelta::FromHours(1));
+ // Sets local state for last time the software reporter sent logs to |days|
+ // days ago.
+ void SetLastTimeSentReport(int days) {
+ SetDateInLocalState(prefs::kSwReporterLastTimeSentReport, days);
}
- // Clears local state for last time the software reporter sent logs to |days|
- // days ago. This prevents potential false positives that could arise from
- // state not properly cleaned between successive tests.
+ // Clears local state for last time the software reporter sent logs. This
+ // prevents potential false positives that could arise from state not
+ // properly cleaned between successive tests.
void ClearLastTimeSentReport() {
- DCHECK_NE(g_browser_process, nullptr);
PrefService* local_state = g_browser_process->local_state();
- DCHECK_NE(local_state, nullptr);
local_state->ClearPref(prefs::kSwReporterLastTimeSentReport);
}
- // Sets local state for last time the software reporter sent logs to |days|
- // days ago.
- void SetLastTimeSentReport(int days) {
- SetDateInLocalState(prefs::kSwReporterLastTimeSentReport, days);
- }
-
+ // Retrieves the timestamp of the last time the software reporter sent logs.
int64_t GetLastTimeSentReport() {
const PrefService* local_state = g_browser_process->local_state();
- DCHECK_NE(local_state, nullptr);
DCHECK(local_state->HasPrefPath(prefs::kSwReporterLastTimeSentReport));
return local_state->GetInt64(prefs::kSwReporterLastTimeSentReport);
}
+ void EnableSBExtendedReporting() {
+ Browser* browser = chrome::FindLastActive();
+ DCHECK(browser);
+ Profile* profile = browser->profile();
+ SetExtendedReportingPref(profile->GetPrefs(), true);
+ }
+
+ // Expects that the reporter has been scheduled to launch again in |days|
+ // days.
+ void ExpectToRunAgain(int days) {
+ EXPECT_TRUE(mock_time_task_runner_->HasPendingTask());
+ EXPECT_LT(base::TimeDelta::FromDays(days) - base::TimeDelta::FromHours(1),
+ mock_time_task_runner_->NextPendingTaskDelay());
+ EXPECT_GE(base::TimeDelta::FromDays(days),
+ mock_time_task_runner_->NextPendingTaskDelay());
+ }
+
+ // Expects that after |days_until_launch| days, the reporter will be
+ // launched |expected_launch_count| times, and TriggerPrompt will be
+ // called if and only if |expect_prompt| is true.
+ void ExpectReporterLaunches(int days_until_launch,
+ int expected_launch_count,
+ bool expect_prompt) {
+ EXPECT_TRUE(mock_time_task_runner_->HasPendingTask());
+ reporter_launch_count_ = 0;
+ reporter_launch_parameters_.clear();
+ prompt_trigger_called_ = false;
+
+ mock_time_task_runner_->FastForwardBy(
+ base::TimeDelta::FromDays(days_until_launch));
+
+ EXPECT_EQ(expected_launch_count, reporter_launch_count_);
+ EXPECT_EQ(expect_prompt, prompt_trigger_called_);
+ }
+
+ // Expects that after |days_until_launched| days, the reporter will be
+ // launched once with each path in |expected_launch_paths|, and TriggerPrompt
+ // will be called if and only if |expect_prompt| is true.
+ void ExpectReporterLaunches(
+ int days_until_launch,
+ const std::vector<base::FilePath>& expected_launch_paths,
+ bool expect_prompt) {
+ ExpectReporterLaunches(days_until_launch, expected_launch_paths.size(),
+ expect_prompt);
+ EXPECT_EQ(expected_launch_paths.size(), reporter_launch_parameters_.size());
+ for (size_t i = 0; i < expected_launch_paths.size() &&
+ i < reporter_launch_parameters_.size();
+ ++i) {
+ EXPECT_EQ(expected_launch_paths[i],
+ reporter_launch_parameters_[i].command_line.GetProgram());
+ }
+ }
+
void ExpectLastTimeSentReportNotSet() {
PrefService* local_state = g_browser_process->local_state();
- DCHECK_NE(local_state, nullptr);
EXPECT_FALSE(
local_state->HasPrefPath(prefs::kSwReporterLastTimeSentReport));
}
void ExpectLastReportSentInTheLastHour() {
const PrefService* local_state = g_browser_process->local_state();
- DCHECK_NE(local_state, nullptr);
- const base::Time now = base::Time::Now();
+ const base::Time now = Now();
const base::Time last_time_sent_logs = base::Time::FromInternalValue(
local_state->GetInt64(prefs::kSwReporterLastTimeSentReport));
// Checks if the last time sent logs is set as no more than one hour ago,
// which should be enough time if the execution does not fail.
EXPECT_LT(now - base::TimeDelta::FromHours(1), last_time_sent_logs);
- EXPECT_LT(last_time_sent_logs, now);
- }
-
- // Run through the steps needed to launch the reporter, as many times as
- // needed to launch all the reporters given in |expected_launch_paths|. Test
- // that each of those launches succeeded. But do not test that ONLY those
- // launches succeeded.
- //
- // After this, if more launches are expected you can call
- // |TestPartialLaunchCycle| again with another list of paths, to test that
- // the launch cycle will continue with those paths.
- //
- // To test that a list of paths are launched AND NO OTHERS, use
- // |TestReporterLaunchCycle|.
- void TestPartialLaunchCycle(
- const std::vector<base::FilePath>& expected_launch_paths) {
- // This test has an unfortunate amount of knowledge of the internals of
- // ReporterRunner, because it needs to pump the right message loops at the
- // right time so that all its internal messages are delivered. This
- // function might need to be updated if the internals change.
- //
- // The basic sequence is:
- //
- // 1. TryToRun kicks the whole thing off. If the reporter should not be
- // launched now (eg. DaysSinceLastReport is too low) it posts a call to
- // itself again. (In a regular task runner this will be scheduled with a
- // delay, but the test task runner ignores delays so TryToRun will be
- // called again on the next call to RunPendingTasks.)
- //
- // 2. When it is time to run a reporter, TryToRun calls NotifyLaunchReady
- // and then posts a call to LaunchAndWait.
- //
- // 3. When the reporter returns, a call to ReporterDone is posted on the UI
- // thread.
- //
- // 4. ReporterDone calls NotifyReporterDone and then posts another call to
- // TryToRun, which starts the whole process over for the next run.
- //
- // Each call to RunPendingTasks only handles messages already on the queue.
- // It doesn't handle messages posted by those messages. So, we need to call
- // it in a loop to make sure we're past all pending TryToRun calls before
- // LaunchAndWaitForExit will be called.
- //
- // Once a call to LaunchAndWaitForExit has been posted, TryToRun won't be
- // called again until we pump the UI message loop in order to run
- // ReporterDone.
-
- ASSERT_TRUE(task_runner_->HasPendingTask());
- ASSERT_FALSE(reporter_done_notified_);
-
- reporter_launch_count_ = 0;
- reporter_launch_parameters_ = SwReporterInvocation();
-
- int current_launch_count = reporter_launch_count_;
- for (const auto& expected_launch_path : expected_launch_paths) {
- // If RunReporter was called with no pending messages, and it was already
- // time to launch the reporter, then |launch_ready_notified_| will
- // already be true. Otherwise there will be a TryToRun message pending,
- // which must be processed first.
- if (!launch_ready_notified_) {
- task_runner_->RunPendingTasks();
- // Since we're expecting a launch here, we expect it to schedule
- // LaunchAndWaitForExit. So NOW |launch_ready_notified_| should be
- // true.
- ASSERT_TRUE(task_runner_->HasPendingTask());
- }
- ASSERT_TRUE(launch_ready_notified_);
- ASSERT_EQ(current_launch_count, reporter_launch_count_);
-
- // Reset |launch_ready_notified_| so that we can tell if TryToRun gets
- // called again unexpectedly.
- launch_ready_notified_ = false;
-
- // Call the pending LaunchAndWaitForExit.
- task_runner_->RunPendingTasks();
- ASSERT_FALSE(launch_ready_notified_);
- ASSERT_FALSE(reporter_done_notified_);
-
- // At this point LaunchAndWaitForExit has definitely been called if
- // it's going to be called at all. (If not, TryToRun will have been
- // scheduled again.)
- EXPECT_EQ(current_launch_count + 1, reporter_launch_count_);
- EXPECT_EQ(expected_launch_path,
- reporter_launch_parameters_.command_line.GetProgram());
-
- // Pump the UI message loop to process the ReporterDone call (which
- // will schedule the next TryToRun.) If LaunchAndWaitForExit wasn't
- // called, this does nothing.
- base::RunLoop().RunUntilIdle();
-
- // At this point there are three things that could have happened:
- //
- // 1. LaunchAndWaitForExit was not called. There should be a TryToRun
- // scheduled.
- //
- // 2. ReporterDone was called and there was nothing left in the queue
- // of SwReporterInvocation's. There should be a TryToRun scheduled.
- //
- // 3. ReporterDone was called and there were more
- // SwReporterInvocation's in the queue to run immediately. There should
- // be a LaunchAndWaitForExit scheduled.
- //
- // So in all cases there should be a pending task, and if we are expecting
- // more launches in this loop, |launch_ready_notified_| will already be
- // true.
- ASSERT_TRUE(task_runner_->HasPendingTask());
-
- // The test task runner does not actually advance the clock. Pretend that
- // one day has passed. (Otherwise, when we launch the last
- // SwReporterInvocation in the queue, the next call to TryToRun will
- // start a whole new launch cycle.)
- SetDaysSinceLastReport(1);
-
- reporter_done_notified_ = false;
- current_launch_count = reporter_launch_count_;
- }
- }
-
- // Run through the steps needed to launch the reporter, as many times as
- // needed to launch all the reporters given in |expected_launch_paths|. Test
- // that each of those launches succeeded. Then, run through the steps needed
- // to launch the reporter again, to test that the launch cycle is complete
- // (no more reporters will be launched).
- void TestReporterLaunchCycle(
- const std::vector<base::FilePath>& expected_launch_paths) {
- TestPartialLaunchCycle(expected_launch_paths);
-
- // Now that all expected launches have been tested, run the cycle once more
- // to make sure no more launches happen.
- ASSERT_TRUE(task_runner_->HasPendingTask());
- ASSERT_FALSE(reporter_done_notified_);
- ASSERT_FALSE(launch_ready_notified_);
-
- int current_launch_count = reporter_launch_count_;
-
- // Call the pending TryToRun.
- task_runner_->RunPendingTasks();
-
- // We expect that this scheduled another TryToRun. If it scheduled
- // LaunchAndWaitForExit an unexpected launch is about to happen.
- ASSERT_TRUE(task_runner_->HasPendingTask());
- ASSERT_FALSE(launch_ready_notified_);
- ASSERT_FALSE(reporter_done_notified_);
- ASSERT_EQ(current_launch_count, reporter_launch_count_);
+ EXPECT_GE(now, last_time_sent_logs);
}
- // Expects |reporter_launch_parameters_| to contain exactly the command line
- // switches specified in |expected_switches|.
- void ExpectLoggingSwitches(const std::set<std::string>& expected_switches) {
+ // Expects |invocation|'s command line to contain all the switches required
+ // for reporter logging.
+ void ExpectLoggingSwitches(const SwReporterInvocation& invocation,
+ bool expect_switches) {
const base::CommandLine::SwitchMap& invocation_switches =
- reporter_launch_parameters_.command_line.GetSwitches();
+ invocation.command_line.GetSwitches();
+ std::set<std::string> expected_switches;
+ if (expect_switches)
+ expected_switches = {std::begin(kExpectedSwitches),
+ std::end(kExpectedSwitches)};
EXPECT_EQ(expected_switches.size(), invocation_switches.size());
// Checks if all expected switches are in the invocation switches. It's not
// necessary to check if all invocation switches are expected, since we
// checked if both sets should have the same size.
for (const std::string& expected_switch : expected_switches) {
- EXPECT_NE(invocation_switches.find(expected_switch),
- invocation_switches.end());
+ EXPECT_NE(invocation_switches.end(),
+ invocation_switches.find(expected_switch));
}
}
- void EnableSBExtendedReporting() {
- Browser* browser = chrome::FindLastActive();
- ASSERT_NE(browser, nullptr);
- Profile* profile = browser->profile();
- ASSERT_NE(profile, nullptr);
- SetExtendedReportingPref(profile->GetPrefs(), true);
- }
+ // A task runner with a mock clock.
+ scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner_ =
+ new base::TestMockTimeTaskRunner();
+
+ // The task runner that was in use before installing |mock_time_task_runner_|.
+ scoped_refptr<base::SingleThreadTaskRunner> saved_task_runner_;
- scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
bool prompt_trigger_called_ = false;
int reporter_launch_count_ = 0;
- SwReporterInvocation reporter_launch_parameters_;
+ std::vector<SwReporterInvocation> reporter_launch_parameters_;
int exit_code_to_report_ = kReporterFailureExitCode;
- // This will be set to true when a call to |LaunchAndWaitForExit| is next in
- // the task queue.
- bool launch_ready_notified_ = false;
-
- bool reporter_done_notified_ = false;
+ // A callback to invoke when the first reporter of a queue is launched. This
+ // can be used to perform actions in the middle of a queue of reporters which
+ // all launch on the same mock clock tick.
+ base::OnceClosure first_launch_callback_;
};
} // namespace
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, NothingFound) {
- exit_code_to_report_ = kSwReporterNothingFound;
- RunReporter();
- task_runner_->RunPendingTasks();
- EXPECT_EQ(1, reporter_launch_count_);
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(prompt_trigger_called_);
+ RunReporter(kSwReporterNothingFound);
+ ExpectReporterLaunches(0, 1, false);
ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, CleanupNeeded) {
- exit_code_to_report_ = kSwReporterCleanupNeeded;
- RunReporter();
-
- task_runner_->RunPendingTasks();
- EXPECT_EQ(1, reporter_launch_count_);
- // The reply task from the task posted to run the reporter is run on a
- // specific thread, as opposed to a specific task runner, and that thread is
- // the current message loop's thread.
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(prompt_trigger_called_);
+ RunReporter(kSwReporterCleanupNeeded);
+ ExpectReporterLaunches(0, 1, true);
ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, RanRecently) {
constexpr int kDaysLeft = 1;
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft);
- RunReporter();
-
- // Here we can't run until idle since the ReporterRunner will re-post
- // infinitely.
- task_runner_->RunPendingTasks();
- EXPECT_EQ(0, reporter_launch_count_);
-
+ SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft);
+ RunReporter(kSwReporterNothingFound);
+ ExpectReporterLaunches(0, 0, false);
ExpectToRunAgain(kDaysLeft);
- task_runner_->ClearPendingTasks();
+ ExpectReporterLaunches(kDaysLeft, 1, false);
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, WaitForBrowser) {
Profile* profile = browser()->profile();
- CloseAllBrowsers();
- exit_code_to_report_ = kSwReporterCleanupNeeded;
- RunReporter();
-
- task_runner_->RunPendingTasks();
+ // Ensure that even though we're closing the last browser, we don't enter the
+ // "shutting down" state, which will prevent the test from starting another
+ // browser.
+ ScopedKeepAlive test_keep_alive(KeepAliveOrigin::SESSION_RESTORE,
+ KeepAliveRestartOption::ENABLED);
+
+ // Use the standard task runner for browser cleanup, which will wait forever
+ // with the mock clock.
+ base::MessageLoop::current()->SetTaskRunner(saved_task_runner_);
+ CloseBrowserSynchronously(browser());
+ base::MessageLoop::current()->SetTaskRunner(mock_time_task_runner_);
+ ASSERT_EQ(0u, chrome::GetTotalBrowserCount());
+ ASSERT_FALSE(chrome::FindLastActive());
+
+ // Start the reporter while the browser is closed. The prompt should not open.
+ RunReporter(kSwReporterCleanupNeeded);
+ ExpectReporterLaunches(0, 1, false);
+
+ // Create a Browser object directly instead of using helper functions like
+ // CreateBrowser, because they all wait on timed events but do not advance the
+ // mock timer. The Browser constructor registers itself with the global
+ // BrowserList, which is cleaned up when InProcessBrowserTest exits.
+ new Browser(Browser::CreateParams(profile, /*user_gesture=*/false));
+ ASSERT_EQ(1u, chrome::GetTotalBrowserCount());
+
+ // Some browser startup tasks are scheduled to run in the first few minutes
+ // after creation. Make sure they've all been processed so that the only
+ // pending task in the queue is the next reporter check.
+ mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(10));
+
+ // On opening the new browser, the prompt should be shown and the reporter
+ // should be scheduled to run later.
EXPECT_EQ(1, reporter_launch_count_);
-
- CreateBrowser(profile);
EXPECT_TRUE(prompt_trigger_called_);
ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, Failure) {
- exit_code_to_report_ = kReporterFailureExitCode;
- RunReporter();
-
- task_runner_->RunPendingTasks();
- EXPECT_EQ(1, reporter_launch_count_);
-
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(prompt_trigger_called_);
+ RunReporter(kReporterFailureExitCode);
+ ExpectReporterLaunches(0, 1, false);
ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, RunDaily) {
- exit_code_to_report_ = kSwReporterNothingFound;
PrefService* local_state = g_browser_process->local_state();
local_state->SetBoolean(prefs::kSwReporterPendingPrompt, true);
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - 1);
- DCHECK_GT(kDaysBetweenSuccessfulSwReporterRuns - 1,
+ SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - 1);
+ ASSERT_GT(kDaysBetweenSuccessfulSwReporterRuns - 1,
kDaysBetweenSwReporterRunsForPendingPrompt);
- RunReporter();
+ RunReporter(kSwReporterNothingFound);
- task_runner_->RunPendingTasks();
- EXPECT_EQ(1, reporter_launch_count_);
- reporter_launch_count_ = 0;
- base::RunLoop().RunUntilIdle();
+ // Expect the reporter to run immediately, since a prompt is pending and it
+ // has been more than kDaysBetweenSwReporterRunsForPendingPrompt days.
+ ExpectReporterLaunches(0, 1, false);
ExpectToRunAgain(kDaysBetweenSwReporterRunsForPendingPrompt);
+ // Move the clock ahead kDaysBetweenSwReporterRunsForPendingPrompt days. The
+ // expected run should trigger, but not cause the reporter to launch because
+ // a prompt is no longer pending.
local_state->SetBoolean(prefs::kSwReporterPendingPrompt, false);
- task_runner_->RunPendingTasks();
- EXPECT_EQ(0, reporter_launch_count_);
- base::RunLoop().RunUntilIdle();
+ ExpectReporterLaunches(kDaysBetweenSwReporterRunsForPendingPrompt, 0, false);
+
+ // Instead it should now run kDaysBetweenSuccessfulSwReporterRuns after the
+ // first prompt (of which kDaysBetweenSwReporterRunsForPendingPrompt has
+ // already passed.)
+ int days_left = kDaysBetweenSuccessfulSwReporterRuns -
+ kDaysBetweenSwReporterRunsForPendingPrompt;
+ ExpectToRunAgain(days_left);
+ ExpectReporterLaunches(days_left, 1, false);
ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ParameterChange) {
- exit_code_to_report_ = kSwReporterNothingFound;
-
// If the reporter is run several times with different parameters, it should
// only be launched once, with the last parameter set.
const base::FilePath path1(L"path1");
@@ -432,29 +379,27 @@ IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ParameterChange) {
constexpr int kDaysLeft = 1;
{
SCOPED_TRACE("N days left until next reporter run");
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft);
- RunReporter(path1);
- TestReporterLaunchCycle({});
+ SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns - kDaysLeft);
+ RunReporter(kSwReporterNothingFound, path1);
+ ExpectReporterLaunches(0, {}, false);
}
// Schedule path2 just as we enter the next reporting period.
// Now the reporter should launch, just once, using path2.
{
SCOPED_TRACE("Reporter runs now");
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
- RunReporter(path2);
+ RunReporter(kSwReporterNothingFound, path2);
// Schedule it twice; it should only actually run once.
- RunReporter(path2);
- TestReporterLaunchCycle({path2});
+ RunReporter(kSwReporterNothingFound, path2);
+ ExpectReporterLaunches(kDaysLeft, {path2}, false);
}
// Schedule path3 before any more time has passed.
// The reporter should not launch.
{
SCOPED_TRACE("No more time passed");
- SetDaysSinceLastReport(0);
- RunReporter(path3);
- TestReporterLaunchCycle({});
+ RunReporter(kSwReporterNothingFound, path3);
+ ExpectReporterLaunches(0, {}, false);
}
// Enter the next reporting period as path3 is still scheduled.
@@ -462,8 +407,8 @@ IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ParameterChange) {
// parameters from the first launch aren't reused.)
{
SCOPED_TRACE("Previous run still scheduled");
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
- TestReporterLaunchCycle({path3});
+ ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path3},
+ false);
}
// Schedule path3 again in the next reporting period.
@@ -471,15 +416,15 @@ IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ParameterChange) {
// passed, even though the parameters haven't changed.
{
SCOPED_TRACE("Run with same parameters");
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
- RunReporter(path3);
- TestReporterLaunchCycle({path3});
+ RunReporter(kSwReporterNothingFound, path3);
+ ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path3},
+ false);
}
+
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, MultipleLaunches) {
- exit_code_to_report_ = kSwReporterNothingFound;
-
const base::FilePath path1(L"path1");
const base::FilePath path2(L"path2");
const base::FilePath path3(L"path3");
@@ -490,100 +435,99 @@ IN_PROC_BROWSER_TEST_F(SRTFetcherTest, MultipleLaunches) {
{
SCOPED_TRACE("Launch 2 times");
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
- RunReporterQueue(invocations);
- TestReporterLaunchCycle({path1, path2});
+ SetDaysSinceLastTriggered(kDaysBetweenSuccessfulSwReporterRuns);
+ RunReporterQueue(kSwReporterNothingFound, invocations);
+ ExpectReporterLaunches(0, {path1, path2}, false);
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
// Schedule a launch with 2 elements, then another with the same 2. It should
// just run 2 times, not 4.
{
SCOPED_TRACE("Launch 2 times with retry");
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
- RunReporterQueue(invocations);
- RunReporterQueue(invocations);
- TestReporterLaunchCycle({path1, path2});
+ RunReporterQueue(kSwReporterNothingFound, invocations);
+ RunReporterQueue(kSwReporterNothingFound, invocations);
+ ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1, path2},
+ false);
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
- // Schedule a launch with 2 elements, then add a third while the queue is
- // running.
+ // Another launch with 2 elements is already scheduled. Add a third while the
+ // queue is running.
{
SCOPED_TRACE("Add third launch while running");
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
- RunReporterQueue(invocations);
-
- // Only test the cycle once, to process the first element in queue.
- TestPartialLaunchCycle({path1});
-
invocations.push(SwReporterInvocation::FromFilePath(path3));
- RunReporterQueue(invocations);
+ first_launch_callback_ = base::BindOnce(
+ &SRTFetcherTest::RunReporterQueue, base::Unretained(this),
+ kSwReporterNothingFound, invocations);
- // There is still a 2nd element on the queue - that should execute, and
- // nothing more.
- TestReporterLaunchCycle({path2});
+ // Only the first two elements should execute since the third was added
+ // during the cycle.
+ ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1, path2},
+ false);
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
// Time passes... Now the 3-element queue should run.
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
- TestReporterLaunchCycle({path1, path2, path3});
+ ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns,
+ {path1, path2, path3}, false);
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
// Second launch should not occur after a failure.
{
SCOPED_TRACE("Launch multiple times with failure");
- exit_code_to_report_ = kReporterFailureExitCode;
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
- RunReporterQueue(invocations);
- TestReporterLaunchCycle({path1});
+ RunReporterQueue(kReporterFailureExitCode, invocations);
+ ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1},
+ false);
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
// If we try again before the reporting period is up, it should not do
// anything.
- TestReporterLaunchCycle({});
+ ExpectReporterLaunches(0, {}, false);
// After enough time has passed, should try the queue again.
- SetDaysSinceLastReport(kDaysBetweenSuccessfulSwReporterRuns);
- TestReporterLaunchCycle({path1});
+ ExpectReporterLaunches(kDaysBetweenSuccessfulSwReporterRuns, {path1},
+ false);
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_NoSBExtendedReporting) {
- exit_code_to_report_ = kSwReporterNothingFound;
base::test::ScopedFeatureList scoped_feature_list;
- RunReporter();
- TestReporterLaunchCycle({base::FilePath()});
- ExpectLoggingSwitches({/*expect no switches*/});
+ RunReporter(kSwReporterNothingFound);
+ ExpectReporterLaunches(0, 1, false);
+ ExpectLoggingSwitches(reporter_launch_parameters_.front(), false);
ExpectLastTimeSentReportNotSet();
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledFirstRun) {
- exit_code_to_report_ = kSwReporterNothingFound;
base::test::ScopedFeatureList scoped_feature_list;
EnableSBExtendedReporting();
// Note: don't set last time sent logs in the local state.
// SBER is enabled and there is no record in the local state of the last time
// logs have been sent, so we should send logs in this run.
- RunReporter();
- TestReporterLaunchCycle({base::FilePath()});
- ExpectLoggingSwitches(std::set<std::string>(std::begin(kExpectedSwitches),
- std::end(kExpectedSwitches)));
+ RunReporter(kSwReporterNothingFound);
+ ExpectReporterLaunches(0, 1, false);
+ ExpectLoggingSwitches(reporter_launch_parameters_.front(), true);
ExpectLastReportSentInTheLastHour();
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledNoRecentLogging) {
- exit_code_to_report_ = kSwReporterNothingFound;
base::test::ScopedFeatureList scoped_feature_list;
// SBER is enabled and last time logs were sent was more than
// |kDaysBetweenReporterLogsSent| day ago, so we should send logs in this run.
EnableSBExtendedReporting();
SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3);
- RunReporter();
- TestReporterLaunchCycle({base::FilePath()});
- ExpectLoggingSwitches(std::set<std::string>(std::begin(kExpectedSwitches),
- std::end(kExpectedSwitches)));
+ RunReporter(kSwReporterNothingFound);
+ ExpectReporterLaunches(0, 1, false);
+ ExpectLoggingSwitches(reporter_launch_parameters_.front(), true);
ExpectLastReportSentInTheLastHour();
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledRecentlyLogged) {
- exit_code_to_report_ = kSwReporterNothingFound;
base::test::ScopedFeatureList scoped_feature_list;
// SBER is enabled, but logs have been sent less than
// |kDaysBetweenReporterLogsSent| day ago, so we shouldn't send any logs in
@@ -591,14 +535,14 @@ IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_EnabledRecentlyLogged) {
EnableSBExtendedReporting();
SetLastTimeSentReport(kDaysBetweenReporterLogsSent - 1);
int64_t last_time_sent_logs = GetLastTimeSentReport();
- RunReporter();
- TestReporterLaunchCycle({base::FilePath()});
- ExpectLoggingSwitches(std::set<std::string>{/*expect no switches*/});
+ RunReporter(kSwReporterNothingFound);
+ ExpectReporterLaunches(0, 1, false);
+ ExpectLoggingSwitches(reporter_launch_parameters_.front(), false);
EXPECT_EQ(last_time_sent_logs, GetLastTimeSentReport());
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_MultipleLaunches) {
- exit_code_to_report_ = kSwReporterNothingFound;
base::test::ScopedFeatureList scoped_feature_list;
EnableSBExtendedReporting();
SetLastTimeSentReport(kDaysBetweenReporterLogsSent + 3);
@@ -612,27 +556,27 @@ IN_PROC_BROWSER_TEST_F(SRTFetcherTest, ReporterLogging_MultipleLaunches) {
SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS;
invocations.push(invocation);
}
- RunReporterQueue(invocations);
+ RunReporterQueue(kSwReporterNothingFound, invocations);
// SBER is enabled and last time logs were sent was more than
// |kDaysBetweenReporterLogsSent| day ago, so we should send logs in this run.
{
SCOPED_TRACE("first launch");
- TestPartialLaunchCycle({path1});
- ExpectLoggingSwitches(std::set<std::string>(std::begin(kExpectedSwitches),
- std::end(kExpectedSwitches)));
- ExpectLastReportSentInTheLastHour();
+ first_launch_callback_ =
+ base::BindOnce(&SRTFetcherTest::ExpectLastReportSentInTheLastHour,
+ base::Unretained(this));
+ ExpectReporterLaunches(0, {path1, path2}, false);
+ ExpectLoggingSwitches(reporter_launch_parameters_[0], true);
}
// Logs should also be sent for the next run, even though LastTimeSentReport
// is now recent, because the run is part of the same set of invocations.
{
SCOPED_TRACE("second launch");
- TestReporterLaunchCycle({path2});
- ExpectLoggingSwitches(std::set<std::string>(std::begin(kExpectedSwitches),
- std::end(kExpectedSwitches)));
+ ExpectLoggingSwitches(reporter_launch_parameters_[1], true);
ExpectLastReportSentInTheLastHour();
}
+ ExpectToRunAgain(kDaysBetweenSuccessfulSwReporterRuns);
}
} // namespace safe_browsing
« no previous file with comments | « chrome/browser/component_updater/sw_reporter_installer_win.cc ('k') | chrome/browser/safe_browsing/srt_fetcher_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698