summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base.gyp4
-rw-r--r--base/base.gypi9
-rw-r--r--base/test/mock_time_provider.h3
-rw-r--r--base/test/simple_test_clock.cc23
-rw-r--r--base/test/simple_test_clock.h39
-rw-r--r--base/test/simple_test_tick_clock.cc26
-rw-r--r--base/test/simple_test_tick_clock.h39
-rw-r--r--base/time/clock.cc11
-rw-r--r--base/time/clock.h40
-rw-r--r--base/time/default_clock.cc15
-rw-r--r--base/time/default_clock.h25
-rw-r--r--base/time/default_tick_clock.cc15
-rw-r--r--base/time/default_tick_clock.h25
-rw-r--r--base/time/tick_clock.cc11
-rw-r--r--base/time/tick_clock.h40
-rw-r--r--media/base/clock.cc16
-rw-r--r--media/base/clock.h14
-rw-r--r--media/base/clock_unittest.cc15
-rw-r--r--media/base/pipeline.cc2
-rw-r--r--media/base/pipeline.h4
-rw-r--r--media/base/pipeline_unittest.cc17
-rw-r--r--sync/notifier/ack_tracker.cc19
-rw-r--r--sync/notifier/ack_tracker.h11
-rw-r--r--sync/notifier/ack_tracker_unittest.cc87
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());