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 14using base::TimeDelta; 15 16namespace syncer { 17 18class BackoffDelayProviderTest : public testing::Test {}; 19 20TEST_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 36TEST_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 85TEST_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