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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // 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.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/ntp_snippets/remote/remote_suggestions_scheduler.h"
6
7 #include <memory>
8 #include <set>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "base/command_line.h"
14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/run_loop.h"
18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/time/time.h"
20 #include "components/ntp_snippets/features.h"
21 #include "components/ntp_snippets/ntp_snippets_constants.h"
22 #include "components/ntp_snippets/pref_names.h"
23 #include "components/ntp_snippets/remote/remote_suggestions_hard_scheduler.h"
24 #include "components/ntp_snippets/remote/test_utils.h"
25 #include "components/ntp_snippets/user_classifier.h"
26 #include "components/prefs/testing_pref_service.h"
27 #include "components/variations/variations_params_manager.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30
31 using testing::ElementsAre;
32 using testing::Eq;
33 using testing::InSequence;
34 using testing::Invoke;
35 using testing::IsEmpty;
36 using testing::Mock;
37 using testing::MockFunction;
38 using testing::NiceMock;
39 using testing::Not;
40 using testing::SaveArg;
41 using testing::SizeIs;
42 using testing::StartsWith;
43 using testing::WithArgs;
44 using testing::_;
45
46 namespace ntp_snippets {
47
48 namespace {
49
50 const char* kDifferentWiFiInterval = "2";
51
52 class MockHardScheduler : public RemoteSuggestionsHardScheduler {
53 public:
54 MOCK_METHOD2(Schedule,
55 bool(base::TimeDelta period_wifi,
56 base::TimeDelta period_fallback));
57 MOCK_METHOD0(Unschedule, bool());
58 };
59
60 class MockUpdater : public RemoteSuggestionsScheduler::Updater {
61 public:
62 MOCK_METHOD0(UpdateRemoteSuggestionsBySchedule, void());
63 };
64
65 } // namespace
66
67 class RemoteSuggestionsSchedulerTest : public ::testing::Test {
68 public:
69 RemoteSuggestionsSchedulerTest()
70 : user_classifier_(/*pref_service=*/nullptr) {
71 RemoteSuggestionsScheduler::RegisterProfilePrefs(
72 utils_.pref_service()->registry());
73 }
74
75 std::unique_ptr<RemoteSuggestionsScheduler> MakeScheduler(bool enabled) {
76 auto scheduler = base::MakeUnique<RemoteSuggestionsScheduler>(
77 &mock_scheduler(), &user_classifier_, utils_.pref_service());
78
79 scheduler->SetUpdater(&updater());
80
81 if (enabled) {
Marc Treib 2016/12/09 12:25:27 Hm. Might be better to do this in the individual t
82 scheduler->Schedule();
83 } else {
84 scheduler->Unschedule();
85 }
86 return scheduler;
87 }
88
89 protected:
90 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.
91 MockUpdater& updater() { return updater_; }
92
93 private:
94 test::RemoteSuggestionsTestUtils utils_;
95 UserClassifier user_classifier_;
96 NiceMock<MockHardScheduler> hard_scheduler_;
97 NiceMock<MockUpdater> updater_;
98
99 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsSchedulerTest);
100 };
101
102 TEST_F(RemoteSuggestionsSchedulerTest, SchedulesOnStart) {
103 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
104 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
105
106 auto scheduler = MakeScheduler(/*enabled=*/true);
107 }
108
109 TEST_F(RemoteSuggestionsSchedulerTest, UnschedulesAfterBeingScheduled) {
110 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.
111 auto scheduler = MakeScheduler(/*enabled=*/true);
112
113 Mock::VerifyAndClearExpectations(&mock_scheduler());
Marc Treib 2016/12/09 12:25:27 FYI: Tim considers VerifyAndClearExpectations an a
114 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1);
115 scheduler->Unschedule();
116 }
117
118 TEST_F(RemoteSuggestionsSchedulerTest, DoesNotUnscheduleOnShutdown) {
119 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
120 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
121
122 auto scheduler = MakeScheduler(/*enabled=*/true);
123
124 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.
125 }
126
127 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.
128 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
129 auto scheduler = MakeScheduler(/*enabled=*/true);
130
131 // Unschedule for the first time.
132 Mock::VerifyAndClearExpectations(&mock_scheduler());
133 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1);
134 scheduler->Unschedule();
135
136 // When unscheduling again, we should not get any |Schedule| calls:
137 // The tasks are already unscheduled, so no need to do it again.
138 Mock::VerifyAndClearExpectations(&mock_scheduler());
139 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
140 scheduler->Unschedule();
141 }
142
143 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.
144 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
145
146 auto scheduler = MakeScheduler(/*enabled=*/true);
147
148 // When scheduling again, we should not get any |Schedule| calls:
149 // The tasks are already scheduled with the correct intervals, so no need to
150 // do it again.
151 Mock::VerifyAndClearExpectations(&mock_scheduler());
152 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0);
153 scheduler->Schedule();
154 }
155
156 TEST_F(RemoteSuggestionsSchedulerTest, RescheduleWhenWifiParamChanges) {
157 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
158 auto scheduler = MakeScheduler(/*enabled=*/true);
159
160 // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
161 // null. Change the wifi interval for this class.
162 variations::testing::VariationParamsManager params_manager(
163 ntp_snippets::kStudyName,
164 {{"fetching_interval_hours-wifi-active_ntp_user",
165 kDifferentWiFiInterval}},
166 {kArticleSuggestionsFeature.name});
167
168 Mock::VerifyAndClearExpectations(&mock_scheduler());
169 // After the change of a paramter, it should reschedule.
170 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
171 scheduler->Schedule();
172 }
173
174 TEST_F(RemoteSuggestionsSchedulerTest, RescheduleWhenFallbackParamChanges) {
175 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
176 auto scheduler = MakeScheduler(/*enabled=*/true);
177
178 // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
179 // null. Change the wifi interval for this class.
180 variations::testing::VariationParamsManager params_manager(
181 ntp_snippets::kStudyName,
182 {{"fetching_interval_hours-fallback-active_ntp_user",
183 kDifferentWiFiInterval}},
184 {kArticleSuggestionsFeature.name});
185
186 Mock::VerifyAndClearExpectations(&mock_scheduler());
187 // After the change of a paramter, it should reschedule.
188 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
189 scheduler->Schedule();
190 }
191
192 TEST_F(RemoteSuggestionsSchedulerTest, HandlesForcedReschedules) {
193 {
194 InSequence s;
195 // The initial scheduling.
196 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
197 // Forced rescheduling.
198 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1);
199 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
200 }
201
202 auto scheduler = MakeScheduler(/*enabled=*/true);
203 // Forced reschedule
204 scheduler->Unschedule();
205 scheduler->Schedule();
206 }
207
208 TEST_F(RemoteSuggestionsSchedulerTest, ReschedulesAfterSuccessfulUpdate) {
209 // The initial scheduling.
210 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
211 auto scheduler = MakeScheduler(/*enabled=*/true);
212 Mock::VerifyAndClearExpectations(&mock_scheduler());
213
214 // 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.
215 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
216 scheduler->PerformHardUpdate();
217 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.
218 }
219
220 TEST_F(RemoteSuggestionsSchedulerTest, DoesNotRescheduleAfterFailedUpdate) {
221 // The initial scheduling.
222 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
223 auto scheduler = MakeScheduler(/*enabled=*/true);
224 Mock::VerifyAndClearExpectations(&mock_scheduler());
225
226 // Simulate a succesfull update.
227 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0);
228 scheduler->PerformHardUpdate();
229 // Failed -> do not call OnSuccessfulUpdate().
230 }
231
232 TEST_F(RemoteSuggestionsSchedulerTest, CallsUpdater) {
233 // The initial scheduling.
234 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(1);
235 auto scheduler = MakeScheduler(/*enabled=*/true);
236
237 // Simulate a succesfull update.
238 EXPECT_CALL(updater(), UpdateRemoteSuggestionsBySchedule()).Times(1);
239 scheduler->PerformHardUpdate();
240 }
241
242 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698