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 "sync/engine/backoff_delay_provider.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/time/time.h"
9 #include "sync/internal_api/public/engine/polling_constants.h"
10 #include "sync/internal_api/public/sessions/model_neutral_state.h"
11 #include "sync/internal_api/public/util/syncer_error.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 using base::TimeDelta
;
18 class BackoffDelayProviderTest
: public testing::Test
{};
20 TEST_F(BackoffDelayProviderTest
, GetRecommendedDelay
) {
21 scoped_ptr
<BackoffDelayProvider
> delay(BackoffDelayProvider::FromDefaults());
22 EXPECT_EQ(TimeDelta::FromSeconds(1),
23 delay
->GetDelay(TimeDelta::FromSeconds(0)));
24 EXPECT_LE(TimeDelta::FromSeconds(1),
25 delay
->GetDelay(TimeDelta::FromSeconds(1)));
26 EXPECT_LE(TimeDelta::FromSeconds(50),
27 delay
->GetDelay(TimeDelta::FromSeconds(50)));
28 EXPECT_LE(TimeDelta::FromSeconds(10),
29 delay
->GetDelay(TimeDelta::FromSeconds(10)));
30 EXPECT_EQ(TimeDelta::FromSeconds(kMaxBackoffSeconds
),
31 delay
->GetDelay(TimeDelta::FromSeconds(kMaxBackoffSeconds
)));
32 EXPECT_EQ(TimeDelta::FromSeconds(kMaxBackoffSeconds
),
33 delay
->GetDelay(TimeDelta::FromSeconds(kMaxBackoffSeconds
+ 1)));
36 TEST_F(BackoffDelayProviderTest
, GetInitialDelay
) {
37 scoped_ptr
<BackoffDelayProvider
> delay(BackoffDelayProvider::FromDefaults());
38 sessions::ModelNeutralState state
;
39 state
.last_get_key_result
= SYNC_SERVER_ERROR
;
40 EXPECT_EQ(kInitialBackoffRetrySeconds
,
41 delay
->GetInitialDelay(state
).InSeconds());
43 state
.last_get_key_result
= UNSET
;
44 state
.last_download_updates_result
= SERVER_RETURN_MIGRATION_DONE
;
45 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
46 delay
->GetInitialDelay(state
).InSeconds());
48 state
.last_download_updates_result
= NETWORK_CONNECTION_UNAVAILABLE
;
49 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
50 delay
->GetInitialDelay(state
).InSeconds());
52 state
.last_download_updates_result
= SERVER_RETURN_TRANSIENT_ERROR
;
53 EXPECT_EQ(kInitialBackoffRetrySeconds
,
54 delay
->GetInitialDelay(state
).InSeconds());
56 state
.last_download_updates_result
= SERVER_RESPONSE_VALIDATION_FAILED
;
57 EXPECT_EQ(kInitialBackoffRetrySeconds
,
58 delay
->GetInitialDelay(state
).InSeconds());
60 state
.last_download_updates_result
= DATATYPE_TRIGGERED_RETRY
;
61 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
62 delay
->GetInitialDelay(state
).InSeconds());
64 state
.last_download_updates_result
= SYNCER_OK
;
65 // Note that updating credentials triggers a canary job, trumping
66 // the initial delay, but in theory we still expect this function to treat
67 // it like any other error in the system (except migration).
68 state
.commit_result
= SERVER_RETURN_INVALID_CREDENTIAL
;
69 EXPECT_EQ(kInitialBackoffRetrySeconds
,
70 delay
->GetInitialDelay(state
).InSeconds());
72 state
.commit_result
= SERVER_RETURN_MIGRATION_DONE
;
73 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
74 delay
->GetInitialDelay(state
).InSeconds());
76 state
.commit_result
= NETWORK_CONNECTION_UNAVAILABLE
;
77 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
78 delay
->GetInitialDelay(state
).InSeconds());
80 state
.commit_result
= SERVER_RETURN_CONFLICT
;
81 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
82 delay
->GetInitialDelay(state
).InSeconds());
85 TEST_F(BackoffDelayProviderTest
, GetInitialDelayWithOverride
) {
86 scoped_ptr
<BackoffDelayProvider
> delay(
87 BackoffDelayProvider::WithShortInitialRetryOverride());
88 sessions::ModelNeutralState state
;
89 state
.last_get_key_result
= SYNC_SERVER_ERROR
;
90 EXPECT_EQ(kInitialBackoffShortRetrySeconds
,
91 delay
->GetInitialDelay(state
).InSeconds());
93 state
.last_get_key_result
= UNSET
;
94 state
.last_download_updates_result
= SERVER_RETURN_MIGRATION_DONE
;
95 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
96 delay
->GetInitialDelay(state
).InSeconds());
98 state
.last_download_updates_result
= SERVER_RETURN_TRANSIENT_ERROR
;
99 EXPECT_EQ(kInitialBackoffShortRetrySeconds
,
100 delay
->GetInitialDelay(state
).InSeconds());
102 state
.last_download_updates_result
= SERVER_RESPONSE_VALIDATION_FAILED
;
103 EXPECT_EQ(kInitialBackoffShortRetrySeconds
,
104 delay
->GetInitialDelay(state
).InSeconds());
106 state
.last_download_updates_result
= DATATYPE_TRIGGERED_RETRY
;
107 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
108 delay
->GetInitialDelay(state
).InSeconds());
110 state
.last_download_updates_result
= SYNCER_OK
;
111 // Note that updating credentials triggers a canary job, trumping
112 // the initial delay, but in theory we still expect this function to treat
113 // it like any other error in the system (except migration).
114 state
.commit_result
= SERVER_RETURN_INVALID_CREDENTIAL
;
115 EXPECT_EQ(kInitialBackoffShortRetrySeconds
,
116 delay
->GetInitialDelay(state
).InSeconds());
118 state
.commit_result
= SERVER_RETURN_MIGRATION_DONE
;
119 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
120 delay
->GetInitialDelay(state
).InSeconds());
122 state
.commit_result
= SERVER_RETURN_CONFLICT
;
123 EXPECT_EQ(kInitialBackoffImmediateRetrySeconds
,
124 delay
->GetInitialDelay(state
).InSeconds());
127 } // namespace syncer