1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/message_loop.h"
7 #include "sync/engine/backoff_delay_provider.h"
8 #include "sync/engine/sync_scheduler_impl.h"
9 #include "sync/engine/throttled_data_type_tracker.h"
10 #include "sync/internal_api/public/engine/polling_constants.h"
11 #include "sync/sessions/sync_session_context.h"
12 #include "sync/sessions/test_util.h"
13 #include "sync/test/engine/fake_model_worker.h"
14 #include "sync/test/engine/mock_connection_manager.h"
15 #include "sync/test/engine/test_directory_setter_upper.h"
16 #include "sync/test/fake_extensions_activity_monitor.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using base::TimeDelta
;
21 using base::TimeTicks
;
24 using sessions::SyncSession
;
25 using sessions::SyncSessionContext
;
26 using sessions::SyncSourceInfo
;
27 using sync_pb::GetUpdatesCallerInfo
;
29 class SyncSchedulerWhiteboxTest
: public testing::Test
{
31 virtual void SetUp() {
33 Syncer
* syncer
= new Syncer();
35 ModelSafeRoutingInfo routes
;
36 routes
[BOOKMARKS
] = GROUP_UI
;
37 routes
[NIGORI
] = GROUP_PASSIVE
;
39 workers_
.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_UI
)));
40 workers_
.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_PASSIVE
)));
42 std::vector
<ModelSafeWorker
*> workers
;
43 for (std::vector
<scoped_refptr
<FakeModelWorker
> >::iterator it
=
44 workers_
.begin(); it
!= workers_
.end(); ++it
) {
45 workers
.push_back(it
->get());
48 connection_
.reset(new MockConnectionManager(NULL
));
49 throttled_data_type_tracker_
.reset(new ThrottledDataTypeTracker(NULL
));
51 new SyncSessionContext(
52 connection_
.get(), dir_maker_
.directory(),
53 workers
, &extensions_activity_monitor_
,
54 throttled_data_type_tracker_
.get(),
55 std::vector
<SyncEngineEventListener
*>(), NULL
, NULL
,
56 true /* enable keystore encryption */));
57 context_
->set_notifications_enabled(true);
58 context_
->set_account_name("Test");
60 new SyncSchedulerImpl("TestSyncSchedulerWhitebox",
61 BackoffDelayProvider::FromDefaults(),
66 virtual void TearDown() {
70 void SetMode(SyncScheduler::Mode mode
) {
71 scheduler_
->mode_
= mode
;
74 void ResetWaitInterval() {
75 scheduler_
->wait_interval_
.reset();
78 void SetWaitIntervalToThrottled() {
79 scheduler_
->wait_interval_
.reset(new SyncSchedulerImpl::WaitInterval(
80 SyncSchedulerImpl::WaitInterval::THROTTLED
, TimeDelta::FromSeconds(1)));
83 void SetWaitIntervalToExponentialBackoff() {
84 scheduler_
->wait_interval_
.reset(
85 new SyncSchedulerImpl::WaitInterval(
86 SyncSchedulerImpl::WaitInterval::EXPONENTIAL_BACKOFF
,
87 TimeDelta::FromSeconds(1)));
90 void SetWaitIntervalHadNudge(bool had_nudge
) {
91 scheduler_
->wait_interval_
->had_nudge
= had_nudge
;
94 SyncSchedulerImpl::JobProcessDecision
DecideOnJob(
95 const SyncSchedulerImpl::SyncSessionJob
& job
) {
96 return scheduler_
->DecideOnJob(job
);
99 void InitializeSyncerOnNormalMode() {
100 SetMode(SyncScheduler::NORMAL_MODE
);
104 SyncSchedulerImpl::JobProcessDecision
CreateAndDecideJob(
105 SyncSchedulerImpl::SyncSessionJob::SyncSessionJobPurpose purpose
) {
106 SyncSession
* s
= scheduler_
->CreateSyncSession(SyncSourceInfo());
107 SyncSchedulerImpl::SyncSessionJob
job(purpose
, TimeTicks::Now(),
110 ConfigurationParams(),
112 return DecideOnJob(job
);
115 SyncSessionContext
* context() { return context_
.get(); }
118 MessageLoop message_loop_
;
119 scoped_ptr
<MockConnectionManager
> connection_
;
120 scoped_ptr
<SyncSessionContext
> context_
;
121 std::vector
<scoped_refptr
<FakeModelWorker
> > workers_
;
122 FakeExtensionsActivityMonitor extensions_activity_monitor_
;
123 scoped_ptr
<ThrottledDataTypeTracker
> throttled_data_type_tracker_
;
124 TestDirectorySetterUpper dir_maker_
;
127 // Declared here to ensure it is destructed before the objects it references.
128 scoped_ptr
<SyncSchedulerImpl
> scheduler_
;
131 TEST_F(SyncSchedulerWhiteboxTest
, SaveNudge
) {
132 InitializeSyncerOnNormalMode();
134 // Now set the mode to configure.
135 SetMode(SyncScheduler::CONFIGURATION_MODE
);
137 SyncSchedulerImpl::JobProcessDecision decision
=
138 CreateAndDecideJob(SyncSchedulerImpl::SyncSessionJob::NUDGE
);
140 EXPECT_EQ(decision
, SyncSchedulerImpl::SAVE
);
143 TEST_F(SyncSchedulerWhiteboxTest
, SaveNudgeWhileTypeThrottled
) {
144 InitializeSyncerOnNormalMode();
147 types
.Put(BOOKMARKS
);
149 // Mark bookmarks as throttled.
150 context()->throttled_data_type_tracker()->SetUnthrottleTime(
151 types
, base::TimeTicks::Now() + base::TimeDelta::FromHours(2));
153 ModelTypeStateMap type_state_map
;
154 type_state_map
.insert(std::make_pair(BOOKMARKS
, InvalidationState()));
156 SyncSourceInfo
info(GetUpdatesCallerInfo::LOCAL
, type_state_map
);
157 SyncSession
* s
= scheduler_
->CreateSyncSession(info
);
159 // Now schedule a nudge with just bookmarks and the change is local.
160 SyncSchedulerImpl::SyncSessionJob
job(
161 SyncSchedulerImpl::SyncSessionJob::NUDGE
,
165 ConfigurationParams(),
168 SyncSchedulerImpl::JobProcessDecision decision
= DecideOnJob(job
);
169 EXPECT_EQ(decision
, SyncSchedulerImpl::SAVE
);
172 TEST_F(SyncSchedulerWhiteboxTest
, ContinueNudge
) {
173 InitializeSyncerOnNormalMode();
175 SyncSchedulerImpl::JobProcessDecision decision
= CreateAndDecideJob(
176 SyncSchedulerImpl::SyncSessionJob::NUDGE
);
178 EXPECT_EQ(decision
, SyncSchedulerImpl::CONTINUE
);
181 TEST_F(SyncSchedulerWhiteboxTest
, DropPoll
) {
182 InitializeSyncerOnNormalMode();
183 SetMode(SyncScheduler::CONFIGURATION_MODE
);
185 SyncSchedulerImpl::JobProcessDecision decision
= CreateAndDecideJob(
186 SyncSchedulerImpl::SyncSessionJob::POLL
);
188 EXPECT_EQ(decision
, SyncSchedulerImpl::DROP
);
191 TEST_F(SyncSchedulerWhiteboxTest
, ContinuePoll
) {
192 InitializeSyncerOnNormalMode();
194 SyncSchedulerImpl::JobProcessDecision decision
= CreateAndDecideJob(
195 SyncSchedulerImpl::SyncSessionJob::POLL
);
197 EXPECT_EQ(decision
, SyncSchedulerImpl::CONTINUE
);
200 TEST_F(SyncSchedulerWhiteboxTest
, ContinueConfiguration
) {
201 InitializeSyncerOnNormalMode();
202 SetMode(SyncScheduler::CONFIGURATION_MODE
);
204 SyncSchedulerImpl::JobProcessDecision decision
= CreateAndDecideJob(
205 SyncSchedulerImpl::SyncSessionJob::CONFIGURATION
);
207 EXPECT_EQ(decision
, SyncSchedulerImpl::CONTINUE
);
210 TEST_F(SyncSchedulerWhiteboxTest
, SaveConfigurationWhileThrottled
) {
211 InitializeSyncerOnNormalMode();
212 SetMode(SyncScheduler::CONFIGURATION_MODE
);
214 SetWaitIntervalToThrottled();
216 SyncSchedulerImpl::JobProcessDecision decision
= CreateAndDecideJob(
217 SyncSchedulerImpl::SyncSessionJob::CONFIGURATION
);
219 EXPECT_EQ(decision
, SyncSchedulerImpl::SAVE
);
222 TEST_F(SyncSchedulerWhiteboxTest
, SaveNudgeWhileThrottled
) {
223 InitializeSyncerOnNormalMode();
224 SetMode(SyncScheduler::CONFIGURATION_MODE
);
226 SetWaitIntervalToThrottled();
228 SyncSchedulerImpl::JobProcessDecision decision
= CreateAndDecideJob(
229 SyncSchedulerImpl::SyncSessionJob::NUDGE
);
231 EXPECT_EQ(decision
, SyncSchedulerImpl::SAVE
);
234 TEST_F(SyncSchedulerWhiteboxTest
, ContinueNudgeWhileExponentialBackOff
) {
235 InitializeSyncerOnNormalMode();
236 SetMode(SyncScheduler::NORMAL_MODE
);
237 SetWaitIntervalToExponentialBackoff();
239 SyncSchedulerImpl::JobProcessDecision decision
= CreateAndDecideJob(
240 SyncSchedulerImpl::SyncSessionJob::NUDGE
);
242 EXPECT_EQ(decision
, SyncSchedulerImpl::CONTINUE
);
245 TEST_F(SyncSchedulerWhiteboxTest
, DropNudgeWhileExponentialBackOff
) {
246 InitializeSyncerOnNormalMode();
247 SetMode(SyncScheduler::NORMAL_MODE
);
248 SetWaitIntervalToExponentialBackoff();
249 SetWaitIntervalHadNudge(true);
251 SyncSchedulerImpl::JobProcessDecision decision
= CreateAndDecideJob(
252 SyncSchedulerImpl::SyncSessionJob::NUDGE
);
254 EXPECT_EQ(decision
, SyncSchedulerImpl::DROP
);
257 TEST_F(SyncSchedulerWhiteboxTest
, ContinueCanaryJobConfig
) {
258 InitializeSyncerOnNormalMode();
259 SetMode(SyncScheduler::CONFIGURATION_MODE
);
260 SetWaitIntervalToExponentialBackoff();
262 struct SyncSchedulerImpl::SyncSessionJob job
;
263 job
.purpose
= SyncSchedulerImpl::SyncSessionJob::CONFIGURATION
;
264 job
.scheduled_start
= TimeTicks::Now();
265 job
.is_canary_job
= true;
266 SyncSchedulerImpl::JobProcessDecision decision
= DecideOnJob(job
);
268 EXPECT_EQ(decision
, SyncSchedulerImpl::CONTINUE
);
271 } // namespace syncer