diff options
-rw-r--r-- | base/base.gyp | 4 | ||||
-rw-r--r-- | base/base.gypi | 9 | ||||
-rw-r--r-- | base/test/mock_time_provider.h | 3 | ||||
-rw-r--r-- | base/test/simple_test_clock.cc | 23 | ||||
-rw-r--r-- | base/test/simple_test_clock.h | 39 | ||||
-rw-r--r-- | base/test/simple_test_tick_clock.cc | 26 | ||||
-rw-r--r-- | base/test/simple_test_tick_clock.h | 39 | ||||
-rw-r--r-- | base/time/clock.cc | 11 | ||||
-rw-r--r-- | base/time/clock.h | 40 | ||||
-rw-r--r-- | base/time/default_clock.cc | 15 | ||||
-rw-r--r-- | base/time/default_clock.h | 25 | ||||
-rw-r--r-- | base/time/default_tick_clock.cc | 15 | ||||
-rw-r--r-- | base/time/default_tick_clock.h | 25 | ||||
-rw-r--r-- | base/time/tick_clock.cc | 11 | ||||
-rw-r--r-- | base/time/tick_clock.h | 40 | ||||
-rw-r--r-- | media/base/clock.cc | 16 | ||||
-rw-r--r-- | media/base/clock.h | 14 | ||||
-rw-r--r-- | media/base/clock_unittest.cc | 15 | ||||
-rw-r--r-- | media/base/pipeline.cc | 2 | ||||
-rw-r--r-- | media/base/pipeline.h | 4 | ||||
-rw-r--r-- | media/base/pipeline_unittest.cc | 17 | ||||
-rw-r--r-- | sync/notifier/ack_tracker.cc | 19 | ||||
-rw-r--r-- | sync/notifier/ack_tracker.h | 11 | ||||
-rw-r--r-- | sync/notifier/ack_tracker_unittest.cc | 87 |
24 files changed, 407 insertions, 103 deletions
diff --git a/base/base.gyp b/base/base.gyp index 2c1ecc7..7c63ec2 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -834,6 +834,10 @@ 'test/scoped_path_override.h', 'test/sequenced_task_runner_test_template.cc', 'test/sequenced_task_runner_test_template.h', + 'test/simple_test_clock.cc', + 'test/simple_test_clock.h', + 'test/simple_test_tick_clock.cc', + 'test/simple_test_tick_clock.h', 'test/task_runner_test_template.cc', 'test/task_runner_test_template.h', 'test/test_file_util.h', diff --git a/base/base.gypi b/base/base.gypi index 9f588c8..7cad42a 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -491,6 +491,15 @@ 'threading/worker_pool_posix.cc', 'threading/worker_pool_posix.h', 'threading/worker_pool_win.cc', + 'time/clock.cc', + 'time/clock.h', + 'time/default_clock.cc', + 'time/default_clock.h', + 'time/default_tick_clock.cc', + 'time/default_tick_clock.h', + 'time/tick_clock.cc', + 'time/tick_clock.h', + # TODO(akalin): Move time* into time/. 'time.cc', 'time.h', 'time_mac.cc', diff --git a/base/test/mock_time_provider.h b/base/test/mock_time_provider.h index 81240f7..b493209 100644 --- a/base/test/mock_time_provider.h +++ b/base/test/mock_time_provider.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// TODO(akalin): Change all users of this class to use SimpleTestClock +// or SimpleTestTickClock and remove this class. + // A helper class used to mock out calls to the static method base::Time::Now. // // Example usage: diff --git a/base/test/simple_test_clock.cc b/base/test/simple_test_clock.cc new file mode 100644 index 0000000..3bd6080 --- /dev/null +++ b/base/test/simple_test_clock.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/simple_test_clock.h" + +namespace base { + +SimpleTestClock::SimpleTestClock() {} + +SimpleTestClock::~SimpleTestClock() {} + +Time SimpleTestClock::Now() { + AutoLock lock(lock_); + return now_; +} + +void SimpleTestClock::Advance(TimeDelta delta) { + AutoLock lock(lock_); + now_ += delta; +} + +} // namespace base diff --git a/base/test/simple_test_clock.h b/base/test/simple_test_clock.h new file mode 100644 index 0000000..a83312f --- /dev/null +++ b/base/test/simple_test_clock.h @@ -0,0 +1,39 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_SIMPLE_TEST_CLOCK_H_ +#define BASE_SIMPLE_TEST_CLOCK_H_ + +#include "base/compiler_specific.h" +#include "base/synchronization/lock.h" +#include "base/time.h" +#include "base/time/clock.h" + +namespace base { + +// SimpleTestClock is a Clock implementation that gives control over +// the returned Time objects. All methods can be called from any +// thread. +class SimpleTestClock : public Clock { + public: + // Starts off with a clock set to Time(). + SimpleTestClock(); + virtual ~SimpleTestClock(); + + virtual Time Now() OVERRIDE; + + // Sets the current time forward by |delta|. Safe to call from any + // thread. + void Advance(TimeDelta delta); + + private: + // Protects |now_|. + Lock lock_; + + Time now_; +}; + +} // namespace base + +#endif // BASE_SIMPLE_TEST_CLOCK_H_ diff --git a/base/test/simple_test_tick_clock.cc b/base/test/simple_test_tick_clock.cc new file mode 100644 index 0000000..1b4696f --- /dev/null +++ b/base/test/simple_test_tick_clock.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/simple_test_tick_clock.h" + +#include "base/logging.h" + +namespace base { + +SimpleTestTickClock::SimpleTestTickClock() {} + +SimpleTestTickClock::~SimpleTestTickClock() {} + +TimeTicks SimpleTestTickClock::NowTicks() { + AutoLock lock(lock_); + return now_ticks_; +} + +void SimpleTestTickClock::Advance(TimeDelta delta) { + AutoLock lock(lock_); + DCHECK(delta >= TimeDelta()); + now_ticks_ += delta; +} + +} // namespace base diff --git a/base/test/simple_test_tick_clock.h b/base/test/simple_test_tick_clock.h new file mode 100644 index 0000000..c53301b --- /dev/null +++ b/base/test/simple_test_tick_clock.h @@ -0,0 +1,39 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_SIMPLE_TEST_TICK_CLOCK_H_ +#define BASE_SIMPLE_TEST_TICK_CLOCK_H_ + +#include "base/compiler_specific.h" +#include "base/synchronization/lock.h" +#include "base/time.h" +#include "base/time/tick_clock.h" + +namespace base { + +// SimpleTestTickClock is a TickClock implementation that gives +// control over the returned TimeTicks objects. All methods can be +// called from any thread. +class SimpleTestTickClock : public TickClock { + public: + // Starts off with a clock set to TimeTicks(). + SimpleTestTickClock(); + virtual ~SimpleTestTickClock(); + + virtual TimeTicks NowTicks() OVERRIDE; + + // Sets the current time forward by |delta|. Safe to call from any + // thread. + void Advance(TimeDelta delta); + + private: + // Protects |now_ticks_|. + Lock lock_; + + TimeTicks now_ticks_; +}; + +} // namespace base + +#endif // BASE_SIMPLE_TEST_TICK_CLOCK_H_ diff --git a/base/time/clock.cc b/base/time/clock.cc new file mode 100644 index 0000000..34dc37e --- /dev/null +++ b/base/time/clock.cc @@ -0,0 +1,11 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/time/clock.h" + +namespace base { + +Clock::~Clock() {} + +} // namespace base diff --git a/base/time/clock.h b/base/time/clock.h new file mode 100644 index 0000000..9fef254 --- /dev/null +++ b/base/time/clock.h @@ -0,0 +1,40 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_CLOCK_H_ +#define BASE_CLOCK_H_ + +#include "base/base_export.h" +#include "base/time.h" + +namespace base { + +// A Clock is an interface for objects that vend Times. It is +// intended to be able to test the behavior of classes with respect to +// time. +// +// See DefaultClock (base/default_clock.h) for the default +// implementation that simply uses Time::Now(). +// +// (An implementation that uses Time::SystemTime() should be added as +// needed.) +// +// See SimpleTestClock (base/test/simple_test_clock.h) for a simple +// test implementation. +// +// See TickClock (base/tick_clock.h) for the equivalent interface for +// TimeTicks. +class BASE_EXPORT Clock { + public: + virtual ~Clock(); + + // Now() must be safe to call from any thread. The caller cannot + // make any ordering assumptions about the returned Time. For + // example, the system clock may change to an earlier time. + virtual Time Now() = 0; +}; + +} // namespace base + +#endif // BASE_CLOCK_H_ diff --git a/base/time/default_clock.cc b/base/time/default_clock.cc new file mode 100644 index 0000000..5f70114 --- /dev/null +++ b/base/time/default_clock.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/time/default_clock.h" + +namespace base { + +DefaultClock::~DefaultClock() {} + +Time DefaultClock::Now() { + return Time::Now(); +} + +} // namespace base diff --git a/base/time/default_clock.h b/base/time/default_clock.h new file mode 100644 index 0000000..2022d5c --- /dev/null +++ b/base/time/default_clock.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_DEFAULT_CLOCK_H_ +#define BASE_DEFAULT_CLOCK_H_ + +#include "base/base_export.h" +#include "base/compiler_specific.h" +#include "base/time/clock.h" + +namespace base { + +// DefaultClock is a Clock implementation that uses Time::Now(). +class BASE_EXPORT DefaultClock : public Clock { + public: + virtual ~DefaultClock(); + + // Simply returns Time::Now(). + virtual Time Now() OVERRIDE; +}; + +} // namespace base + +#endif // BASE_DEFAULT_CLOCK_H_ diff --git a/base/time/default_tick_clock.cc b/base/time/default_tick_clock.cc new file mode 100644 index 0000000..ce62fcc --- /dev/null +++ b/base/time/default_tick_clock.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/time/default_tick_clock.h" + +namespace base { + +DefaultTickClock::~DefaultTickClock() {} + +TimeTicks DefaultTickClock::NowTicks() { + return TimeTicks::Now(); +} + +} // namespace base diff --git a/base/time/default_tick_clock.h b/base/time/default_tick_clock.h new file mode 100644 index 0000000..553a8d2 --- /dev/null +++ b/base/time/default_tick_clock.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_DEFAULT_TICK_CLOCK_H_ +#define BASE_DEFAULT_TICK_CLOCK_H_ + +#include "base/base_export.h" +#include "base/compiler_specific.h" +#include "base/time/tick_clock.h" + +namespace base { + +// DefaultClock is a Clock implementation that uses TimeTicks::Now(). +class BASE_EXPORT DefaultTickClock : public TickClock { + public: + virtual ~DefaultTickClock(); + + // Simply returns TimeTicks::Now(). + virtual TimeTicks NowTicks() OVERRIDE; +}; + +} // namespace base + +#endif // BASE_DEFAULT_CLOCK_H_ diff --git a/base/time/tick_clock.cc b/base/time/tick_clock.cc new file mode 100644 index 0000000..495805c --- /dev/null +++ b/base/time/tick_clock.cc @@ -0,0 +1,11 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/time/tick_clock.h" + +namespace base { + +TickClock::~TickClock() {} + +} // namespace base diff --git a/base/time/tick_clock.h b/base/time/tick_clock.h new file mode 100644 index 0000000..396e0c9 --- /dev/null +++ b/base/time/tick_clock.h @@ -0,0 +1,40 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TICK_CLOCK_H_ +#define BASE_TICK_CLOCK_H_ + +#include "base/base_export.h" +#include "base/time.h" + +namespace base { + +// A TickClock is an interface for objects that vend TimeTicks. It is +// intended to be able to test the behavior of classes with respect to +// non-decreasing time. +// +// See DefaultTickClock (base/default_tick_clock.h) for the default +// implementation that simply uses TimeTicks::Now(). +// +// (Other implementations that use TimeTicks::HighResNow() or +// TimeTicks::NowFromSystemTime() should be added as needed.) +// +// See SimpleTestTickClock (base/test/simple_test_tick_clock.h) for a +// simple test implementation. +// +// See Clock (base/clock.h) for the equivalent interface for Times. +class BASE_EXPORT TickClock { + public: + virtual ~TickClock(); + + // NowTicks() must be safe to call from any thread. The caller may + // assume that NowTicks() is monotonic (but not strictly monotonic). + // In other words, the returned TimeTicks will never decrease with + // time, although they might "stand still". + virtual TimeTicks NowTicks() = 0; +}; + +} // namespace base + +#endif // BASE_TICK_CLOCK_H_ diff --git a/media/base/clock.cc b/media/base/clock.cc index 2432f91..733c5fe 100644 --- a/media/base/clock.cc +++ b/media/base/clock.cc @@ -7,12 +7,13 @@ #include <algorithm> #include "base/logging.h" +#include "base/time/clock.h" #include "media/base/buffers.h" namespace media { -Clock::Clock(TimeProvider* time_provider) - : time_provider_(time_provider) { +Clock::Clock(base::Clock* clock) : clock_(clock) { + DCHECK(clock_); Reset(); } @@ -95,12 +96,6 @@ base::TimeDelta Clock::ElapsedViaProvidedTime(const base::Time& time) const { return media_time_ + base::TimeDelta::FromMicroseconds(now_us); } -base::Time Clock::GetTimeFromProvider() const { - if (time_provider_) - return time_provider_(); - return base::Time(); -} - base::TimeDelta Clock::ClampToValidTimeRange(base::TimeDelta time) const { if (duration_ == kNoTimestamp()) return base::TimeDelta(); @@ -124,12 +119,11 @@ void Clock::UpdateReferencePoints() { void Clock::UpdateReferencePoints(base::TimeDelta current_time) { media_time_ = ClampToValidTimeRange(current_time); - reference_ = GetTimeFromProvider(); + reference_ = clock_->Now(); } base::TimeDelta Clock::EstimatedElapsedTime() { - return ClampToValidTimeRange( - ElapsedViaProvidedTime(GetTimeFromProvider())); + return ClampToValidTimeRange(ElapsedViaProvidedTime(clock_->Now())); } void Clock::Reset() { diff --git a/media/base/clock.h b/media/base/clock.h index 5b2a90c..267666f 100644 --- a/media/base/clock.h +++ b/media/base/clock.h @@ -9,6 +9,10 @@ #include "base/time.h" #include "media/base/media_export.h" +namespace base { +class Clock; +} // namespace base + namespace media { // A clock represents a single source of time to allow audio and video streams @@ -26,10 +30,7 @@ namespace media { // we'll keep using a poll-and-sleep solution. class MEDIA_EXPORT Clock { public: - // Type for a static function pointer that acts as a time source. - typedef base::Time(TimeProvider)(); - - explicit Clock(TimeProvider* time_provider); + explicit Clock(base::Clock* clock); ~Clock(); // Returns true if the clock is running. @@ -91,12 +92,9 @@ class MEDIA_EXPORT Clock { // value as returned by |time_provider_|. base::TimeDelta ElapsedViaProvidedTime(const base::Time& time) const; - base::Time GetTimeFromProvider() const; - base::TimeDelta ClampToValidTimeRange(base::TimeDelta time) const; - // Function returning current time in base::Time units. - TimeProvider* time_provider_; + base::Clock* const clock_; // Whether the clock is running. bool playing_; diff --git a/media/base/clock_unittest.cc b/media/base/clock_unittest.cc index 6773a5b..919c7e5 100644 --- a/media/base/clock_unittest.cc +++ b/media/base/clock_unittest.cc @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/compiler_specific.h" #include "base/logging.h" -#include "base/test/mock_time_provider.h" +#include "base/test/simple_test_clock.h" +#include "base/time/clock.h" #include "media/base/clock.h" #include "testing/gmock/include/gmock/gmock.h" @@ -28,11 +30,8 @@ static const int kDurationInSeconds = 120; class ClockTest : public ::testing::Test { public: - ClockTest() - : clock_(&base::MockTimeProvider::StaticNow) { + ClockTest() : clock_(&test_clock_) { SetDuration(); - EXPECT_CALL(mock_time_, Now()) - .WillRepeatedly(Return(base::Time::UnixEpoch())); } protected: @@ -44,13 +43,11 @@ class ClockTest : public ::testing::Test { } void AdvanceSystemTime(base::TimeDelta delta) { - time_elapsed_ += delta; - EXPECT_CALL(mock_time_, Now()) - .WillRepeatedly(Return(base::Time::UnixEpoch() + time_elapsed_)); + test_clock_.Advance(delta); } + base::SimpleTestClock test_clock_; Clock clock_; - StrictMock<base::MockTimeProvider> mock_time_; base::TimeDelta time_elapsed_; }; diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc index 6af4935..9cc56c5 100644 --- a/media/base/pipeline.cc +++ b/media/base/pipeline.cc @@ -72,7 +72,7 @@ Pipeline::Pipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop, natural_size_(0, 0), volume_(1.0f), playback_rate_(0.0f), - clock_(new Clock(&base::Time::Now)), + clock_(new Clock(&default_clock_)), waiting_for_clock_update_(false), status_(PIPELINE_OK), has_audio_(false), diff --git a/media/base/pipeline.h b/media/base/pipeline.h index 8f976c9..4a24fd2 100644 --- a/media/base/pipeline.h +++ b/media/base/pipeline.h @@ -11,6 +11,7 @@ #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" +#include "base/time/default_clock.h" #include "media/base/audio_renderer.h" #include "media/base/demuxer.h" #include "media/base/media_export.h" @@ -404,6 +405,9 @@ class MEDIA_EXPORT Pipeline // the filters. float playback_rate_; + // base::Clock used by |clock_|. + base::DefaultClock default_clock_; + // Reference clock. Keeps track of current playback time. Uses system // clock and linear interpolation, but can have its time manually set // by filters. diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc index 320c83a..d2d14b2 100644 --- a/media/base/pipeline_unittest.cc +++ b/media/base/pipeline_unittest.cc @@ -7,7 +7,9 @@ #include "base/bind.h" #include "base/message_loop.h" #include "base/stl_util.h" +#include "base/test/simple_test_clock.h" #include "base/threading/simple_thread.h" +#include "base/time/clock.h" #include "media/base/clock.h" #include "media/base/gmock_callback_support.h" #include "media/base/media_log.h" @@ -298,6 +300,7 @@ class PipelineTest : public ::testing::Test { // Fixture members. StrictMock<CallbackHelper> callbacks_; + base::SimpleTestClock test_clock_; MessageLoop message_loop_; scoped_refptr<Pipeline> pipeline_; @@ -608,12 +611,6 @@ TEST_F(PipelineTest, EndedCallback) { message_loop_.RunUntilIdle(); } -// Static function & time variable used to simulate changes in wallclock time. -static int64 g_static_clock_time; -static base::Time StaticClockFunction() { - return base::Time::FromInternalValue(g_static_clock_time); -} - TEST_F(PipelineTest, AudioStreamShorterThanVideo) { base::TimeDelta duration = base::TimeDelta::FromSeconds(10); @@ -625,7 +622,7 @@ TEST_F(PipelineTest, AudioStreamShorterThanVideo) { // Replace the clock so we can simulate wallclock time advancing w/o using // Sleep(). - pipeline_->SetClockForTesting(new Clock(&StaticClockFunction)); + pipeline_->SetClockForTesting(new Clock(&test_clock_)); InitializeDemuxer(&streams, duration); InitializeAudioRenderer(audio_stream(), false); @@ -646,8 +643,7 @@ TEST_F(PipelineTest, AudioStreamShorterThanVideo) { // Verify that the clock doesn't advance since it hasn't been started by // a time update from the audio stream. int64 start_time = pipeline_->GetMediaTime().ToInternalValue(); - g_static_clock_time += - base::TimeDelta::FromMilliseconds(100).ToInternalValue(); + test_clock_.Advance(base::TimeDelta::FromMilliseconds(100)); EXPECT_EQ(pipeline_->GetMediaTime().ToInternalValue(), start_time); // Signal end of audio stream. @@ -656,8 +652,7 @@ TEST_F(PipelineTest, AudioStreamShorterThanVideo) { // Verify that the clock advances. start_time = pipeline_->GetMediaTime().ToInternalValue(); - g_static_clock_time += - base::TimeDelta::FromMilliseconds(100).ToInternalValue(); + test_clock_.Advance(base::TimeDelta::FromMilliseconds(100)); EXPECT_GT(pipeline_->GetMediaTime().ToInternalValue(), start_time); // Signal end of video stream and make sure OnEnded() callback occurs. diff --git a/sync/notifier/ack_tracker.cc b/sync/notifier/ack_tracker.cc index 4014672..759b869 100644 --- a/sync/notifier/ack_tracker.cc +++ b/sync/notifier/ack_tracker.cc @@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/stl_util.h" +#include "base/time/tick_clock.h" #include "google/cacheinvalidation/include/types.h" namespace syncer { @@ -73,10 +74,11 @@ AckTracker::Entry::Entry(scoped_ptr<net::BackoffEntry> backoff, AckTracker::Entry::~Entry() { } -AckTracker::AckTracker(Delegate* delegate) - : now_callback_(base::Bind(&base::TimeTicks::Now)), - create_backoff_entry_callback_(base::Bind(&CreateDefaultBackoffEntry)), +AckTracker::AckTracker(base::TickClock* tick_clock, Delegate* delegate) + : create_backoff_entry_callback_(base::Bind(&CreateDefaultBackoffEntry)), + tick_clock_(tick_clock), delegate_(delegate) { + DCHECK(tick_clock_); DCHECK(delegate_); } @@ -139,7 +141,7 @@ void AckTracker::NudgeTimer() { return; } - const base::TimeTicks now = now_callback_.Run(); + const base::TimeTicks now = tick_clock_->NowTicks(); // There are two cases when the timer needs to be started: // 1. |desired_run_time_| is in the past. By definition, the timer has already // fired at this point. Since the queue is non-empty, we need to set the @@ -159,7 +161,7 @@ void AckTracker::NudgeTimer() { void AckTracker::OnTimeout() { DCHECK(thread_checker_.CalledOnValidThread()); - OnTimeoutAt(now_callback_.Run()); + OnTimeoutAt(tick_clock_->NowTicks()); } void AckTracker::OnTimeoutAt(base::TimeTicks now) { @@ -188,13 +190,6 @@ void AckTracker::OnTimeoutAt(base::TimeTicks now) { } // Testing helpers. -void AckTracker::SetNowCallbackForTest( - const NowCallback& now_callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - - now_callback_ = now_callback; -} - void AckTracker::SetCreateBackoffEntryCallbackForTest( const CreateBackoffEntryCallback& create_backoff_entry_callback) { DCHECK(thread_checker_.CalledOnValidThread()); diff --git a/sync/notifier/ack_tracker.h b/sync/notifier/ack_tracker.h index 08fcad9..a21a914 100644 --- a/sync/notifier/ack_tracker.h +++ b/sync/notifier/ack_tracker.h @@ -17,6 +17,10 @@ #include "sync/base/sync_export.h" #include "sync/notifier/invalidation_util.h" +namespace base { +class TickClock; +} // namespace base + namespace syncer { // A simple class that tracks sets of object IDs that have not yet been @@ -34,11 +38,10 @@ class SYNC_EXPORT_PRIVATE AckTracker { virtual void OnTimeout(const ObjectIdSet& ids) = 0; }; - typedef base::Callback<base::TimeTicks()> NowCallback; typedef base::Callback<scoped_ptr<net::BackoffEntry>( const net::BackoffEntry::Policy* const)> CreateBackoffEntryCallback; - explicit AckTracker(Delegate* delegate); + AckTracker(base::TickClock* tick_clock, Delegate* delegate); ~AckTracker(); // Equivalent to calling Ack() on all currently registered object IDs. @@ -53,7 +56,6 @@ class SYNC_EXPORT_PRIVATE AckTracker { void Ack(const ObjectIdSet& ids); // Testing methods. - void SetNowCallbackForTest(const NowCallback& now_callback); void SetCreateBackoffEntryCallbackForTest( const CreateBackoffEntryCallback& create_backoff_entry_callback); // Returns true iff there are no timeouts scheduled to occur before |now|. @@ -83,9 +85,10 @@ class SYNC_EXPORT_PRIVATE AckTracker { const net::BackoffEntry::Policy* const policy); // Used for testing purposes. - NowCallback now_callback_; CreateBackoffEntryCallback create_backoff_entry_callback_; + base::TickClock* const tick_clock_; + Delegate* const delegate_; base::OneShotTimer<AckTracker> timer_; diff --git a/sync/notifier/ack_tracker_unittest.cc b/sync/notifier/ack_tracker_unittest.cc index 9a5c802..7208d76 100644 --- a/sync/notifier/ack_tracker_unittest.cc +++ b/sync/notifier/ack_tracker_unittest.cc @@ -4,8 +4,10 @@ #include "sync/notifier/ack_tracker.h" +#include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/message_loop.h" +#include "base/time/tick_clock.h" #include "google/cacheinvalidation/include/types.h" #include "google/cacheinvalidation/types.pb.h" #include "testing/gmock/include/gmock/gmock.h" @@ -15,15 +17,15 @@ namespace syncer { namespace { -typedef AckTracker::NowCallback NowCallback; - -class MockTimeProvider : public base::RefCountedThreadSafe<MockTimeProvider> { +class FakeTickClock : public base::TickClock { public: - MockTimeProvider() : fake_now_(base::TimeTicks::Now()) {} + FakeTickClock() {} + + virtual ~FakeTickClock() {} void LeapForward(int seconds) { ASSERT_GT(seconds, 0); - fake_now_ += base::TimeDelta::FromSeconds(seconds); + fake_now_ticks_ += base::TimeDelta::FromSeconds(seconds); } // After the next call to Now(), immediately leap forward by |seconds|. @@ -32,38 +34,34 @@ class MockTimeProvider : public base::RefCountedThreadSafe<MockTimeProvider> { delayed_leap_ = base::TimeDelta::FromSeconds(seconds); } - base::TimeTicks Now() { - base::TimeTicks fake_now = fake_now_; + virtual base::TimeTicks NowTicks() OVERRIDE { + base::TimeTicks fake_now_ticks = fake_now_ticks_; if (delayed_leap_ > base::TimeDelta()) { - fake_now_ += delayed_leap_; + fake_now_ticks_ += delayed_leap_; delayed_leap_ = base::TimeDelta(); } - return fake_now; + return fake_now_ticks; } private: - friend class base::RefCountedThreadSafe<MockTimeProvider>; - - ~MockTimeProvider() {} - - base::TimeTicks fake_now_; + base::TimeTicks fake_now_ticks_; base::TimeDelta delayed_leap_; }; class FakeBackoffEntry : public net::BackoffEntry { public: - FakeBackoffEntry(const Policy* const policy, const NowCallback& now_callback) + FakeBackoffEntry(const Policy* const policy, base::TickClock* tick_clock) : BackoffEntry(policy), - now_callback_(now_callback) { + tick_clock_(tick_clock) { } protected: virtual base::TimeTicks ImplGetTimeNow() const OVERRIDE { - return now_callback_.Run(); + return tick_clock_->NowTicks(); } private: - NowCallback now_callback_; + base::TickClock* const tick_clock_; }; class MockDelegate : public AckTracker::Delegate { @@ -72,10 +70,10 @@ class MockDelegate : public AckTracker::Delegate { }; scoped_ptr<net::BackoffEntry> CreateMockEntry( - const NowCallback& now_callback, + base::TickClock* tick_clock, const net::BackoffEntry::Policy* const policy) { return scoped_ptr<net::BackoffEntry>(new FakeBackoffEntry( - policy, now_callback)); + policy, tick_clock)); } } // namespace @@ -83,21 +81,16 @@ scoped_ptr<net::BackoffEntry> CreateMockEntry( class AckTrackerTest : public testing::Test { public: AckTrackerTest() - : time_provider_(new MockTimeProvider), - ack_tracker_(&delegate_), + : ack_tracker_(&fake_tick_clock_, &delegate_), kIdOne(ipc::invalidation::ObjectSource::TEST, "one"), kIdTwo(ipc::invalidation::ObjectSource::TEST, "two") { - ack_tracker_.SetNowCallbackForTest( - base::Bind(&MockTimeProvider::Now, time_provider_)); ack_tracker_.SetCreateBackoffEntryCallbackForTest( - base::Bind(&CreateMockEntry, - base::Bind(&MockTimeProvider::Now, - time_provider_))); + base::Bind(&CreateMockEntry, &fake_tick_clock_)); } protected: bool TriggerTimeoutNow() { - return ack_tracker_.TriggerTimeoutAtForTest(time_provider_->Now()); + return ack_tracker_.TriggerTimeoutAtForTest(fake_tick_clock_.NowTicks()); } base::TimeDelta GetTimerDelay() const { @@ -107,7 +100,7 @@ class AckTrackerTest : public testing::Test { return timer.GetCurrentDelay(); } - scoped_refptr<MockTimeProvider> time_provider_; + FakeTickClock fake_tick_clock_; ::testing::StrictMock<MockDelegate> delegate_; AckTracker ack_tracker_; @@ -200,32 +193,32 @@ TEST_F(AckTrackerTest, SimpleTimeout) { EXPECT_FALSE(ack_tracker_.IsQueueEmptyForTest()); EXPECT_EQ(base::TimeDelta::FromSeconds(60), GetTimerDelay()); - time_provider_->LeapForward(60); + fake_tick_clock_.LeapForward(60); EXPECT_CALL(delegate_, OnTimeout(ids)); EXPECT_TRUE(TriggerTimeoutNow()); EXPECT_EQ(base::TimeDelta::FromSeconds(120), GetTimerDelay()); - time_provider_->LeapForward(120); + fake_tick_clock_.LeapForward(120); EXPECT_CALL(delegate_, OnTimeout(ids)); EXPECT_TRUE(TriggerTimeoutNow()); EXPECT_EQ(base::TimeDelta::FromSeconds(240), GetTimerDelay()); - time_provider_->LeapForward(240); + fake_tick_clock_.LeapForward(240); EXPECT_CALL(delegate_, OnTimeout(ids)); EXPECT_TRUE(TriggerTimeoutNow()); EXPECT_EQ(base::TimeDelta::FromSeconds(480), GetTimerDelay()); - time_provider_->LeapForward(480); + fake_tick_clock_.LeapForward(480); EXPECT_CALL(delegate_, OnTimeout(ids)); EXPECT_TRUE(TriggerTimeoutNow()); EXPECT_EQ(base::TimeDelta::FromSeconds(600), GetTimerDelay()); - time_provider_->LeapForward(600); + fake_tick_clock_.LeapForward(600); EXPECT_CALL(delegate_, OnTimeout(ids)); EXPECT_TRUE(TriggerTimeoutNow()); EXPECT_EQ(base::TimeDelta::FromSeconds(600), GetTimerDelay()); - time_provider_->LeapForward(600); + fake_tick_clock_.LeapForward(600); EXPECT_CALL(delegate_, OnTimeout(ids)); EXPECT_TRUE(TriggerTimeoutNow()); @@ -238,7 +231,7 @@ TEST_F(AckTrackerTest, SimpleTimeout) { EXPECT_FALSE(ack_tracker_.IsQueueEmptyForTest()); EXPECT_EQ(base::TimeDelta::FromSeconds(60), GetTimerDelay()); - time_provider_->LeapForward(60); + fake_tick_clock_.LeapForward(60); EXPECT_CALL(delegate_, OnTimeout(ids)); EXPECT_TRUE(TriggerTimeoutNow()); @@ -259,27 +252,27 @@ TEST_F(AckTrackerTest, InterleavedTimeout) { ack_tracker_.Track(ids_one); EXPECT_FALSE(ack_tracker_.IsQueueEmptyForTest()); - time_provider_->LeapForward(30); + fake_tick_clock_.LeapForward(30); ack_tracker_.Track(ids_two); EXPECT_FALSE(ack_tracker_.IsQueueEmptyForTest()); EXPECT_EQ(base::TimeDelta::FromSeconds(60), GetTimerDelay()); - time_provider_->LeapForward(30); + fake_tick_clock_.LeapForward(30); EXPECT_CALL(delegate_, OnTimeout(ids_one)); EXPECT_TRUE(TriggerTimeoutNow()); EXPECT_EQ(base::TimeDelta::FromSeconds(30), GetTimerDelay()); - time_provider_->LeapForward(30); + fake_tick_clock_.LeapForward(30); EXPECT_CALL(delegate_, OnTimeout(ids_two)); EXPECT_TRUE(TriggerTimeoutNow()); EXPECT_EQ(base::TimeDelta::FromSeconds(90), GetTimerDelay()); - time_provider_->LeapForward(90); + fake_tick_clock_.LeapForward(90); EXPECT_CALL(delegate_, OnTimeout(ids_one)); EXPECT_TRUE(TriggerTimeoutNow()); EXPECT_EQ(base::TimeDelta::FromSeconds(30), GetTimerDelay()); - time_provider_->LeapForward(30); + fake_tick_clock_.LeapForward(30); EXPECT_CALL(delegate_, OnTimeout(ids_two)); EXPECT_TRUE(TriggerTimeoutNow()); @@ -301,27 +294,27 @@ TEST_F(AckTrackerTest, ShortenTimeout) { EXPECT_FALSE(ack_tracker_.IsQueueEmptyForTest()); EXPECT_EQ(base::TimeDelta::FromSeconds(60), GetTimerDelay()); - time_provider_->LeapForward(60); + fake_tick_clock_.LeapForward(60); EXPECT_CALL(delegate_, OnTimeout(ids_one)); EXPECT_TRUE(TriggerTimeoutNow()); // Without this next register, the next timeout should occur in 120 seconds // from the last timeout event. EXPECT_EQ(base::TimeDelta::FromSeconds(120), GetTimerDelay()); - time_provider_->LeapForward(30); + fake_tick_clock_.LeapForward(30); ack_tracker_.Track(ids_two); EXPECT_FALSE(ack_tracker_.IsQueueEmptyForTest()); // Now that we've registered another entry though, we should receive a timeout // in 60 seconds. EXPECT_EQ(base::TimeDelta::FromSeconds(60), GetTimerDelay()); - time_provider_->LeapForward(60); + fake_tick_clock_.LeapForward(60); EXPECT_CALL(delegate_, OnTimeout(ids_two)); EXPECT_TRUE(TriggerTimeoutNow()); // Verify that the original timeout for kIdOne still occurs as expected. EXPECT_EQ(base::TimeDelta::FromSeconds(30), GetTimerDelay()); - time_provider_->LeapForward(30); + fake_tick_clock_.LeapForward(30); EXPECT_CALL(delegate_, OnTimeout(ids_one)); EXPECT_TRUE(TriggerTimeoutNow()); @@ -337,7 +330,7 @@ TEST_F(AckTrackerTest, ImmediateTimeout) { ObjectIdSet ids; ids.insert(kIdOne); - time_provider_->DelayedLeapForward(90); + fake_tick_clock_.DelayedLeapForward(90); EXPECT_TRUE(ack_tracker_.IsQueueEmptyForTest()); ack_tracker_.Track(ids); EXPECT_FALSE(ack_tracker_.IsQueueEmptyForTest()); @@ -348,7 +341,7 @@ TEST_F(AckTrackerTest, ImmediateTimeout) { // The next timeout should still be scheduled normally. EXPECT_EQ(base::TimeDelta::FromSeconds(120), GetTimerDelay()); - time_provider_->LeapForward(120); + fake_tick_clock_.LeapForward(120); EXPECT_CALL(delegate_, OnTimeout(ids)); EXPECT_TRUE(TriggerTimeoutNow()); |