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

Unified Diff: components/ntp_snippets/remote/remote_suggestions_scheduler_unittest.cc

Issue 2557363002: [NTP Snippets] Refactor background scheduling for remote suggestions (Closed)
Patch Set: Make unit-tests pass Created 4 years 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: components/ntp_snippets/remote/remote_suggestions_scheduler_unittest.cc
diff --git a/components/ntp_snippets/remote/remote_suggestions_scheduler_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_scheduler_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1bf9caed0eb06270172339cc4aadf9141799bd36
--- /dev/null
+++ b/components/ntp_snippets/remote/remote_suggestions_scheduler_unittest.cc
@@ -0,0 +1,242 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
Marc Treib 2016/12/09 12:25:27 2016
jkrcal 2016/12/19 09:40:23 Done.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/ntp_snippets/remote/remote_suggestions_scheduler.h"
+
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "components/ntp_snippets/features.h"
+#include "components/ntp_snippets/ntp_snippets_constants.h"
+#include "components/ntp_snippets/pref_names.h"
+#include "components/ntp_snippets/remote/remote_suggestions_hard_scheduler.h"
+#include "components/ntp_snippets/remote/test_utils.h"
+#include "components/ntp_snippets/user_classifier.h"
+#include "components/prefs/testing_pref_service.h"
+#include "components/variations/variations_params_manager.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAre;
+using testing::Eq;
+using testing::InSequence;
+using testing::Invoke;
+using testing::IsEmpty;
+using testing::Mock;
+using testing::MockFunction;
+using testing::NiceMock;
+using testing::Not;
+using testing::SaveArg;
+using testing::SizeIs;
+using testing::StartsWith;
+using testing::WithArgs;
+using testing::_;
+
+namespace ntp_snippets {
+
+namespace {
+
+const char* kDifferentWiFiInterval = "2";
+
+class MockHardScheduler : public RemoteSuggestionsHardScheduler {
+ public:
+ MOCK_METHOD2(Schedule,
+ bool(base::TimeDelta period_wifi,
+ base::TimeDelta period_fallback));
+ MOCK_METHOD0(Unschedule, bool());
+};
+
+class MockUpdater : public RemoteSuggestionsScheduler::Updater {
+ public:
+ MOCK_METHOD0(UpdateRemoteSuggestionsBySchedule, void());
+};
+
+} // namespace
+
+class RemoteSuggestionsSchedulerTest : public ::testing::Test {
+ public:
+ RemoteSuggestionsSchedulerTest()
+ : user_classifier_(/*pref_service=*/nullptr) {
+ RemoteSuggestionsScheduler::RegisterProfilePrefs(
+ utils_.pref_service()->registry());
+ }
+
+ std::unique_ptr<RemoteSuggestionsScheduler> MakeScheduler(bool enabled) {
+ auto scheduler = base::MakeUnique<RemoteSuggestionsScheduler>(
+ &mock_scheduler(), &user_classifier_, utils_.pref_service());
+
+ scheduler->SetUpdater(&updater());
+
+ if (enabled) {
Marc Treib 2016/12/09 12:25:27 Hm. Might be better to do this in the individual t
+ scheduler->Schedule();
+ } else {
+ scheduler->Unschedule();
+ }
+ return scheduler;
+ }
+
+ protected:
+ MockHardScheduler& mock_scheduler() { return hard_scheduler_; }
Marc Treib 2016/12/09 12:25:27 Please rename, otherwise it's difficult to keep th
jkrcal 2016/12/19 09:40:23 Done.
+ MockUpdater& updater() { return updater_; }
+
+ private:
+ test::RemoteSuggestionsTestUtils utils_;
+ UserClassifier user_classifier_;
+ NiceMock<MockHardScheduler> hard_scheduler_;
+ NiceMock<MockUpdater> updater_;
+
+ DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsSchedulerTest);
+};
+
+TEST_F(RemoteSuggestionsSchedulerTest, SchedulesOnStart) {
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
+
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, UnschedulesAfterBeingScheduled) {
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
Marc Treib 2016/12/09 12:25:27 Probably you mostly copy-pasted this code, but: Ti
jkrcal 2016/12/19 09:40:23 Done.
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+
+ Mock::VerifyAndClearExpectations(&mock_scheduler());
Marc Treib 2016/12/09 12:25:27 FYI: Tim considers VerifyAndClearExpectations an a
+ EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1);
+ scheduler->Unschedule();
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, DoesNotUnscheduleOnShutdown) {
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
+
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+
+ scheduler.reset();
Marc Treib 2016/12/09 12:25:27 Not really necessary; it'll go out of scope anyway
jkrcal 2016/12/19 09:40:24 Done.
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, UnscheduleOnlyOnce) {
Marc Treib 2016/12/09 12:25:27 nitty nit: UnschedulesOnlyOnce (add an "s")
jkrcal 2016/12/19 09:40:23 Done.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+
+ // Unschedule for the first time.
+ Mock::VerifyAndClearExpectations(&mock_scheduler());
+ EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1);
+ scheduler->Unschedule();
+
+ // When unscheduling again, we should not get any |Schedule| calls:
+ // The tasks are already unscheduled, so no need to do it again.
+ Mock::VerifyAndClearExpectations(&mock_scheduler());
+ EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
+ scheduler->Unschedule();
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, ScheduleOnlyOnce) {
Marc Treib 2016/12/09 12:25:27 Also here: +s (and a few more below)
jkrcal 2016/12/19 09:40:23 Done.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+
+ // When scheduling again, we should not get any |Schedule| calls:
+ // The tasks are already scheduled with the correct intervals, so no need to
+ // do it again.
+ Mock::VerifyAndClearExpectations(&mock_scheduler());
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0);
+ scheduler->Schedule();
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, RescheduleWhenWifiParamChanges) {
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+
+ // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
+ // null. Change the wifi interval for this class.
+ variations::testing::VariationParamsManager params_manager(
+ ntp_snippets::kStudyName,
+ {{"fetching_interval_hours-wifi-active_ntp_user",
+ kDifferentWiFiInterval}},
+ {kArticleSuggestionsFeature.name});
+
+ Mock::VerifyAndClearExpectations(&mock_scheduler());
+ // After the change of a paramter, it should reschedule.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ scheduler->Schedule();
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, RescheduleWhenFallbackParamChanges) {
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+
+ // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
+ // null. Change the wifi interval for this class.
+ variations::testing::VariationParamsManager params_manager(
+ ntp_snippets::kStudyName,
+ {{"fetching_interval_hours-fallback-active_ntp_user",
+ kDifferentWiFiInterval}},
+ {kArticleSuggestionsFeature.name});
+
+ Mock::VerifyAndClearExpectations(&mock_scheduler());
+ // After the change of a paramter, it should reschedule.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ scheduler->Schedule();
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, HandlesForcedReschedules) {
+ {
+ InSequence s;
+ // The initial scheduling.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ // Forced rescheduling.
+ EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1);
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ }
+
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+ // Forced reschedule
+ scheduler->Unschedule();
+ scheduler->Schedule();
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, ReschedulesAfterSuccessfulUpdate) {
+ // The initial scheduling.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+ Mock::VerifyAndClearExpectations(&mock_scheduler());
+
+ // Simulate a succesfull update.
Marc Treib 2016/12/09 12:25:27 nitty nit: successful (only one "l")
jkrcal 2016/12/19 09:40:23 Done.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ scheduler->PerformHardUpdate();
+ scheduler->OnSuccessfulUpdate();
Marc Treib 2016/12/09 12:25:27 Why do we need both of these calls? OnSuccessfulUp
jkrcal 2016/12/19 09:40:23 Done.
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, DoesNotRescheduleAfterFailedUpdate) {
+ // The initial scheduling.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+ Mock::VerifyAndClearExpectations(&mock_scheduler());
+
+ // Simulate a succesfull update.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0);
+ scheduler->PerformHardUpdate();
+ // Failed -> do not call OnSuccessfulUpdate().
+}
+
+TEST_F(RemoteSuggestionsSchedulerTest, CallsUpdater) {
+ // The initial scheduling.
+ EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
+ auto scheduler = MakeScheduler(/*enabled=*/true);
+
+ // Simulate a succesfull update.
+ EXPECT_CALL(updater(), UpdateRemoteSuggestionsBySchedule()).Times(1);
+ scheduler->PerformHardUpdate();
+}
+
+} // namespace ntp_snippets

Powered by Google App Engine
This is Rietveld 408576698