1d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#include "chrome/browser/sync/test/integration/retry_verifier.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/engine/polling_constants.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/sessions/sync_session_snapshot.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given the current delay calculate the minimum and maximum wait times for 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the next retry. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DelayInfo CalculateDelay(int64 current_delay) { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 backoff_s = std::max(static_cast<int64>(1), current_delay * 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::kBackoffRandomizationFactor); 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayInfo delay_info; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_info.min_delay = backoff_s + (-1 * current_delay/ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::kBackoffRandomizationFactor); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_info.max_delay = backoff_s + current_delay/2; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_info.min_delay = std::max(static_cast<int64>(1), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(delay_info.min_delay, syncer::kMaxBackoffSeconds)); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_info.max_delay = std::max(static_cast<int64>(1), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(delay_info.max_delay, syncer::kMaxBackoffSeconds)); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return delay_info; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fills the table with the maximum and minimum values for each retry, upto 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |count| number of retries. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FillDelayTable(DelayInfo* delay_table, int count) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(count > 1); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We start off with the minimum value of 2 seconds. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_table[0].min_delay = static_cast<int64>(2); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_table[0].max_delay = static_cast<int64>(2); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 1 ; i < count ; ++i) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_table[i].min_delay = CalculateDelay(delay_table[i-1].min_delay). 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_delay; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_table[i].max_delay = CalculateDelay(delay_table[i-1].max_delay). 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_delay; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies if the current retry is on time. Note that we dont use the 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// maximum value of the retry range in verifying, only the minimum. Reason 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// being there is no guarantee that the retry will be on the dot. However in 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// practice it is on the dot. But making that assumption for all the platforms 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// would make the test flaky. However we have the global timeout for the 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// verification which would make sure all retries take place in a reasonable 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// amount of time. The global timeout is defined in profile sync service 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// harness as |kExponentialBackoffVerificationTimeoutMs|. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsRetryOnTime(DelayInfo* delay_table, int retry_count, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta& time_elapsed) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Retry Count : " << retry_count 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Time elapsed : " << time_elapsed.InSeconds() 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Retry table min: " << delay_table[retry_count].min_delay 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Retry table max: " << delay_table[retry_count].max_delay; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((time_elapsed.InSeconds() >= delay_table[retry_count].min_delay)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RetryVerifier::RetryVerifier() : retry_count_(0), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success_(false), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_(false) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&delay_table_, 0, sizeof(delay_table_)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RetryVerifier::~RetryVerifier() { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes the state for verification. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RetryVerifier::Initialize( 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::sessions::SyncSessionSnapshot& snap) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retry_count_ = 0; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_sync_time_ = snap.sync_start_time(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillDelayTable(delay_table_, kMaxRetry); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_ = false; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success_ = false; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RetryVerifier::VerifyRetryInterval( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::sessions::SyncSessionSnapshot& snap) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(retry_count_ < kMaxRetry); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retry_count_ == 0) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (snap.sync_start_time() != last_sync_time_) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retry_count_++; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_sync_time_ = snap.sync_start_time(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success_ = true; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the sync start time has changed. If so indicates a new sync 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has taken place. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (snap.sync_start_time() != last_sync_time_) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delta = snap.sync_start_time() - last_sync_time_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success_ = IsRetryOnTime(delay_table_,retry_count_ -1, delta); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_sync_time_ = snap.sync_start_time(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++retry_count_; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_ = (retry_count_ >= kMaxRetry); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 111d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 112