• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "sync/engine/backoff_delay_provider.h"
6 
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"
13 
14 using base::TimeDelta;
15 
16 namespace syncer {
17 
18 class BackoffDelayProviderTest : public testing::Test {};
19 
TEST_F(BackoffDelayProviderTest,GetRecommendedDelay)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)));
34 }
35 
TEST_F(BackoffDelayProviderTest,GetInitialDelay)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());
42 
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());
47 
48   state.last_download_updates_result = NETWORK_CONNECTION_UNAVAILABLE;
49   EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
50             delay->GetInitialDelay(state).InSeconds());
51 
52   state.last_download_updates_result = SERVER_RETURN_TRANSIENT_ERROR;
53   EXPECT_EQ(kInitialBackoffRetrySeconds,
54             delay->GetInitialDelay(state).InSeconds());
55 
56   state.last_download_updates_result = SERVER_RESPONSE_VALIDATION_FAILED;
57   EXPECT_EQ(kInitialBackoffRetrySeconds,
58             delay->GetInitialDelay(state).InSeconds());
59 
60   state.last_download_updates_result = DATATYPE_TRIGGERED_RETRY;
61   EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
62             delay->GetInitialDelay(state).InSeconds());
63 
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());
71 
72   state.commit_result = SERVER_RETURN_MIGRATION_DONE;
73   EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
74             delay->GetInitialDelay(state).InSeconds());
75 
76   state.commit_result = NETWORK_CONNECTION_UNAVAILABLE;
77   EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
78             delay->GetInitialDelay(state).InSeconds());
79 
80   state.commit_result = SERVER_RETURN_CONFLICT;
81   EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
82             delay->GetInitialDelay(state).InSeconds());
83 }
84 
TEST_F(BackoffDelayProviderTest,GetInitialDelayWithOverride)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());
92 
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());
97 
98   state.last_download_updates_result = SERVER_RETURN_TRANSIENT_ERROR;
99   EXPECT_EQ(kInitialBackoffShortRetrySeconds,
100             delay->GetInitialDelay(state).InSeconds());
101 
102   state.last_download_updates_result = SERVER_RESPONSE_VALIDATION_FAILED;
103   EXPECT_EQ(kInitialBackoffShortRetrySeconds,
104             delay->GetInitialDelay(state).InSeconds());
105 
106   state.last_download_updates_result = DATATYPE_TRIGGERED_RETRY;
107   EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
108             delay->GetInitialDelay(state).InSeconds());
109 
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());
117 
118   state.commit_result = SERVER_RETURN_MIGRATION_DONE;
119   EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
120             delay->GetInitialDelay(state).InSeconds());
121 
122   state.commit_result = SERVER_RETURN_CONFLICT;
123   EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
124             delay->GetInitialDelay(state).InSeconds());
125 }
126 
127 }  // namespace syncer
128