Adding the ability to use a simulated clock for unit tests.

This will be useful for any tests that test objects with time-dependent
behavior. It will allow such tests to be written in such a way that their
outcome is more repeatable (less flaky), and will also allow such tests
to finish quicker. For example, a test for STUN timeout doesn't need to
wait the full timeout interval in real time; it can simply advance the
simulated clock.

BUG=webrtc:4925
R=pthatcher@webrtc.org

Review URL: https://codereview.webrtc.org/1895933003 .

Cr-Commit-Position: refs/heads/master@{#12950}
diff --git a/webrtc/base/base_tests.gyp b/webrtc/base/base_tests.gyp
index 063e8e1..3c0e912 100644
--- a/webrtc/base/base_tests.gyp
+++ b/webrtc/base/base_tests.gyp
@@ -64,6 +64,8 @@
           'event_tracer_unittest.cc',
           'event_unittest.cc',
           'exp_filter_unittest.cc',
+          'fakeclock.cc',
+          'fakeclock.h',
           'filerotatingstream_unittest.cc',
           'fileutils_unittest.cc',
           'helpers_unittest.cc',
@@ -113,6 +115,7 @@
           'testclient_unittest.cc',
           'thread_checker_unittest.cc',
           'thread_unittest.cc',
+          'timedelta.h',
           'timeutils_unittest.cc',
           'urlencode_unittest.cc',
           'versionparsing_unittest.cc',
diff --git a/webrtc/base/fakeclock.cc b/webrtc/base/fakeclock.cc
new file mode 100644
index 0000000..e5aa3bc
--- /dev/null
+++ b/webrtc/base/fakeclock.cc
@@ -0,0 +1,40 @@
+/*
+ *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/base/fakeclock.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/messagequeue.h"
+
+namespace rtc {
+
+uint64_t FakeClock::TimeNanos() const {
+  CritScope cs(&lock_);
+  return time_;
+}
+
+void FakeClock::SetTimeNanos(uint64_t nanos) {
+  {
+    CritScope cs(&lock_);
+    RTC_DCHECK(nanos >= time_);
+    time_ = nanos;
+  }
+  // If message queues are waiting in a socket select() with a timeout provided
+  // by the OS, they should wake up to check if there are any messages ready to
+  // be dispatched based on the fake time.
+  MessageQueueManager::WakeAllMessageQueues();
+}
+
+void FakeClock::AdvanceTime(TimeDelta delta) {
+  CritScope cs(&lock_);
+  SetTimeNanos(time_ + delta.ToNanoseconds());
+}
+
+}  // namespace rtc
diff --git a/webrtc/base/fakeclock.h b/webrtc/base/fakeclock.h
new file mode 100644
index 0000000..2b3afdd
--- /dev/null
+++ b/webrtc/base/fakeclock.h
@@ -0,0 +1,43 @@
+/*
+ *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_BASE_FAKECLOCK_H_
+#define WEBRTC_BASE_FAKECLOCK_H_
+
+#include "webrtc/base/criticalsection.h"
+#include "webrtc/base/timedelta.h"
+#include "webrtc/base/timeutils.h"
+
+namespace rtc {
+
+// Fake clock for use with unit tests, which does not tick on its own.
+// Starts at time 0.
+class FakeClock : public ClockInterface {
+ public:
+  ~FakeClock() override {}
+
+  // ClockInterface implementation.
+  uint64_t TimeNanos() const override;
+
+  // Methods that can be used by the test to control the time.
+
+  // Should only be used to set a time in the future.
+  void SetTimeNanos(uint64_t nanos);
+
+  void AdvanceTime(TimeDelta delta);
+
+ private:
+  CriticalSection lock_;
+  uint64_t time_ GUARDED_BY(lock_) = 0u;
+};
+
+}  // namespace rtc
+
+#endif  // WEBRTC_BASE_FAKECLOCK_H_
diff --git a/webrtc/base/messagequeue.cc b/webrtc/base/messagequeue.cc
index 84fdaf1..da50e23 100644
--- a/webrtc/base/messagequeue.cc
+++ b/webrtc/base/messagequeue.cc
@@ -15,6 +15,11 @@
 #include "webrtc/base/messagequeue.h"
 #include "webrtc/base/trace_event.h"
 
+namespace {
+
+enum { MSG_WAKE_MESSAGE_QUEUE = 1 };
+}
+
 namespace rtc {
 
 const int kMaxMsgLatency = 150;  // 150 ms
@@ -103,6 +108,28 @@
     (*iter)->Clear(handler);
 }
 
+void MessageQueueManager::WakeAllMessageQueues() {
+  if (!instance_) {
+    return;
+  }
+  return Instance()->WakeAllMessageQueuesInternal();
+}
+
+void MessageQueueManager::WakeAllMessageQueuesInternal() {
+#if CS_DEBUG_CHECKS  // CurrentThreadIsOwner returns true by default.
+  ASSERT(!crit_.CurrentThreadIsOwner());  // See note above.
+#endif
+  CritScope cs(&crit_);
+  for (MessageQueue* queue : message_queues_) {
+    // Posting an arbitrary message will force the message queue to wake up.
+    queue->Post(this, MSG_WAKE_MESSAGE_QUEUE);
+  }
+}
+
+void MessageQueueManager::OnMessage(Message* pmsg) {
+  RTC_DCHECK(pmsg->message_id == MSG_WAKE_MESSAGE_QUEUE);
+}
+
 //------------------------------------------------------------------
 // MessageQueue
 MessageQueue::MessageQueue(SocketServer* ss, bool init_queue)
diff --git a/webrtc/base/messagequeue.h b/webrtc/base/messagequeue.h
index 03dfc98..3a5226c 100644
--- a/webrtc/base/messagequeue.h
+++ b/webrtc/base/messagequeue.h
@@ -37,7 +37,7 @@
 
 // MessageQueueManager does cleanup of of message queues
 
-class MessageQueueManager {
+class MessageQueueManager : public MessageHandler {
  public:
   static void Add(MessageQueue *message_queue);
   static void Remove(MessageQueue *message_queue);
@@ -49,15 +49,22 @@
   // MessageQueueManager instance when necessary.
   static bool IsInitialized();
 
+  // Mainly for testing purposes, for use with a simulated clock.
+  // Posts a no-op event on all message queues so they will wake from the
+  // socket server select() and process messages again.
+  static void WakeAllMessageQueues();
+
  private:
   static MessageQueueManager* Instance();
 
   MessageQueueManager();
-  ~MessageQueueManager();
+  ~MessageQueueManager() override;
 
   void AddInternal(MessageQueue *message_queue);
   void RemoveInternal(MessageQueue *message_queue);
   void ClearInternal(MessageHandler *handler);
+  void WakeAllMessageQueuesInternal();
+  void OnMessage(Message* pmsg) override;
 
   static MessageQueueManager* instance_;
   // This list contains all live MessageQueues.
diff --git a/webrtc/base/timedelta.h b/webrtc/base/timedelta.h
new file mode 100644
index 0000000..fe8e6aa
--- /dev/null
+++ b/webrtc/base/timedelta.h
@@ -0,0 +1,128 @@
+/*
+ *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_BASE_TIMEDELTA_H_
+#define WEBRTC_BASE_TIMEDELTA_H_
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/timeutils.h"
+
+// Convenience class to convert between different units of relative time.
+// Stores time to precision of nanoseconds, as int64_t internally.
+// Doesn't check for overflow/underflow.
+//
+// Based on TimeDelta in:
+// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time.h
+namespace rtc {
+
+class TimeDelta {
+ public:
+  TimeDelta() : delta_(0) {}
+
+  // Converts units of time to TimeDeltas.
+  static constexpr TimeDelta FromSeconds(int64_t secs) {
+    return TimeDelta(secs * kNumNanosecsPerSec);
+  }
+  static constexpr TimeDelta FromMilliseconds(int64_t ms) {
+    return TimeDelta(ms * kNumNanosecsPerMillisec);
+  }
+  static constexpr TimeDelta FromMicroseconds(int64_t us) {
+    return TimeDelta(us * kNumNanosecsPerMicrosec);
+  }
+  static constexpr TimeDelta FromNanoseconds(int64_t ns) {
+    return TimeDelta(ns);
+  }
+
+  // Returns true if the time delta is zero.
+  bool is_zero() const { return delta_ == 0; }
+
+  // Converts TimeDelta to units of time.
+  int64_t ToSeconds() const { return delta_ / kNumNanosecsPerSec; }
+  int64_t ToMilliseconds() const { return delta_ / kNumNanosecsPerMillisec; }
+  int64_t ToMicroseconds() const { return delta_ / kNumNanosecsPerMicrosec; }
+  int64_t ToNanoseconds() const { return delta_; }
+
+  TimeDelta& operator=(TimeDelta other) {
+    delta_ = other.delta_;
+    return *this;
+  }
+
+  // Computations with other deltas.
+  TimeDelta operator+(TimeDelta other) const {
+    return TimeDelta(delta_ + other.delta_);
+  }
+  TimeDelta operator-(TimeDelta other) const {
+    return TimeDelta(delta_ + other.delta_);
+  }
+
+  TimeDelta& operator+=(TimeDelta other) { return *this = (*this + other); }
+  TimeDelta& operator-=(TimeDelta other) { return *this = (*this - other); }
+  TimeDelta operator-() const { return TimeDelta(-delta_); }
+
+  // Computations with numeric types.
+  template <typename T>
+  TimeDelta operator*(T a) const {
+    return TimeDelta(delta_ * a);
+  }
+  template <typename T>
+  TimeDelta operator/(T a) const {
+    return TimeDelta(delta_ / a);
+  }
+  template <typename T>
+  TimeDelta& operator*=(T a) {
+    return *this = (*this * a);
+  }
+  template <typename T>
+  TimeDelta& operator/=(T a) {
+    return *this = (*this / a);
+  }
+
+  TimeDelta operator%(TimeDelta a) const {
+    return TimeDelta(delta_ % a.delta_);
+  }
+
+  // Comparison operators.
+  constexpr bool operator==(TimeDelta other) const {
+    return delta_ == other.delta_;
+  }
+  constexpr bool operator!=(TimeDelta other) const {
+    return delta_ != other.delta_;
+  }
+  constexpr bool operator<(TimeDelta other) const {
+    return delta_ < other.delta_;
+  }
+  constexpr bool operator<=(TimeDelta other) const {
+    return delta_ <= other.delta_;
+  }
+  constexpr bool operator>(TimeDelta other) const {
+    return delta_ > other.delta_;
+  }
+  constexpr bool operator>=(TimeDelta other) const {
+    return delta_ >= other.delta_;
+  }
+
+ private:
+  // Constructs a delta given the duration in nanoseconds. This is private
+  // to avoid confusion by callers with an integer constructor. Use
+  // FromSeconds, FromMilliseconds, etc. instead.
+  constexpr explicit TimeDelta(int64_t delta_ns) : delta_(delta_ns) {}
+
+  // Delta in nanoseconds.
+  int64_t delta_;
+};
+
+template <typename T>
+inline TimeDelta operator*(T a, TimeDelta td) {
+  return td * a;
+}
+
+}  // namespace rtc
+
+#endif  // WEBRTC_BASE_TIMEDELTA_H_
diff --git a/webrtc/base/timeutils.cc b/webrtc/base/timeutils.cc
index a9fe49d..ecd0911 100644
--- a/webrtc/base/timeutils.cc
+++ b/webrtc/base/timeutils.cc
@@ -30,8 +30,17 @@
 
 namespace rtc {
 
+ClockInterface* g_clock = nullptr;
+
+void SetClock(ClockInterface* clock) {
+  g_clock = clock;
+}
+
 uint64_t TimeNanos() {
-  int64_t ticks = 0;
+  if (g_clock) {
+    return g_clock->TimeNanos();
+  }
+  int64_t ticks;
 #if defined(WEBRTC_MAC)
   static mach_timebase_info_data_t timebase;
   if (timebase.denom == 0) {
@@ -45,8 +54,8 @@
   ticks = mach_absolute_time() * timebase.numer / timebase.denom;
 #elif defined(WEBRTC_POSIX)
   struct timespec ts;
-  // TODO: Do we need to handle the case when CLOCK_MONOTONIC
-  // is not supported?
+  // TODO(deadbeef): Do we need to handle the case when CLOCK_MONOTONIC is not
+  // supported?
   clock_gettime(CLOCK_MONOTONIC, &ts);
   ticks = kNumNanosecsPerSec * static_cast<int64_t>(ts.tv_sec) +
           static_cast<int64_t>(ts.tv_nsec);
@@ -58,8 +67,7 @@
   // Atomically update the last gotten time
   DWORD old = InterlockedExchange(last_timegettime_ptr, now);
   if (now < old) {
-    // If now is earlier than old, there may have been a race between
-    // threads.
+    // If now is earlier than old, there may have been a race between threads.
     // 0x0fffffff ~3.1 days, the code will not take that long to execute
     // so it must have been a wrap around.
     if (old > 0xf0000000 && now < 0x0fffffff) {
@@ -67,8 +75,8 @@
     }
   }
   ticks = now + (num_wrap_timegettime << 32);
-  // TODO: Calculate with nanosecond precision.  Otherwise, we're just
-  // wasting a multiply and divide when doing Time() on Windows.
+  // TODO(deadbeef): Calculate with nanosecond precision. Otherwise, we're
+  // just wasting a multiply and divide when doing Time() on Windows.
   ticks = ticks * kNumNanosecsPerMillisec;
 #else
 #error Unsupported platform.
diff --git a/webrtc/base/timeutils.h b/webrtc/base/timeutils.h
index 222d5c2..78ebace 100644
--- a/webrtc/base/timeutils.h
+++ b/webrtc/base/timeutils.h
@@ -31,6 +31,26 @@
 
 // TODO(honghaiz): Define a type for the time value specifically.
 
+class ClockInterface {
+ public:
+  virtual ~ClockInterface() {}
+  virtual uint64_t TimeNanos() const = 0;
+};
+
+// Sets the global source of time. This is useful mainly for unit tests.
+//
+// Does not transfer ownership of the clock.
+// SetClock(nullptr) should be called before the ClockInterface is deleted.
+//
+// This method is not thread-safe; it should only be used when no other thread
+// is running (for example, at the start/end of a unit test, or start/end of
+// main()).
+//
+// TODO(deadbeef): Instead of having functions that access this global
+// ClockInterface, we may want to pass the ClockInterface into everything
+// that uses it, eliminating the need for a global variable and this function.
+void SetClock(ClockInterface* clock);
+
 // Returns the current time in milliseconds in 32 bits.
 uint32_t Time32();
 
diff --git a/webrtc/base/timeutils_unittest.cc b/webrtc/base/timeutils_unittest.cc
index 0971c03..f183684 100644
--- a/webrtc/base/timeutils_unittest.cc
+++ b/webrtc/base/timeutils_unittest.cc
@@ -9,6 +9,8 @@
  */
 
 #include "webrtc/base/common.h"
+#include "webrtc/base/event.h"
+#include "webrtc/base/fakeclock.h"
 #include "webrtc/base/gunit.h"
 #include "webrtc/base/helpers.h"
 #include "webrtc/base/thread.h"
@@ -205,4 +207,176 @@
   TestTmToSeconds(100000);
 }
 
+TEST(TimeDelta, FromAndTo) {
+  EXPECT_TRUE(TimeDelta::FromSeconds(2) == TimeDelta::FromMilliseconds(2000));
+  EXPECT_TRUE(TimeDelta::FromMilliseconds(3) ==
+              TimeDelta::FromMicroseconds(3000));
+  EXPECT_TRUE(TimeDelta::FromMicroseconds(4) ==
+              TimeDelta::FromNanoseconds(4000));
+  EXPECT_EQ(13, TimeDelta::FromSeconds(13).ToSeconds());
+  EXPECT_EQ(13, TimeDelta::FromMilliseconds(13).ToMilliseconds());
+  EXPECT_EQ(13, TimeDelta::FromMicroseconds(13).ToMicroseconds());
+  EXPECT_EQ(13, TimeDelta::FromNanoseconds(13).ToNanoseconds());
+}
+
+TEST(TimeDelta, ComparisonOperators) {
+  EXPECT_LT(TimeDelta::FromSeconds(1), TimeDelta::FromSeconds(2));
+  EXPECT_EQ(TimeDelta::FromSeconds(3), TimeDelta::FromSeconds(3));
+  EXPECT_GT(TimeDelta::FromSeconds(5), TimeDelta::FromSeconds(4));
+}
+
+TEST(TimeDelta, NumericOperators) {
+  double d = 0.5;
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) * d);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) / d);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) *= d);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) /= d);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            d * TimeDelta::FromMilliseconds(1000));
+
+  float f = 0.5;
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) * f);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) / f);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) *= f);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) /= f);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            f * TimeDelta::FromMilliseconds(1000));
+
+  int i = 2;
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) * i);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) / i);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) *= i);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) /= i);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            i * TimeDelta::FromMilliseconds(1000));
+
+  int64_t i64 = 2;
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) * i64);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) / i64);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) *= i64);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) /= i64);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            i64 * TimeDelta::FromMilliseconds(1000));
+
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) * 0.5);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) / 0.5);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) *= 0.5);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) /= 0.5);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            0.5 * TimeDelta::FromMilliseconds(1000));
+
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) * 2);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) / 2);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            TimeDelta::FromMilliseconds(1000) *= 2);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(500),
+            TimeDelta::FromMilliseconds(1000) /= 2);
+  EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
+            2 * TimeDelta::FromMilliseconds(1000));
+}
+
+// Test that all the time functions exposed by TimeUtils get time from the
+// fake clock when it's set.
+TEST(FakeClock, TimeFunctionsUseFakeClock) {
+  FakeClock clock;
+  SetClock(&clock);
+
+  clock.SetTimeNanos(987654321u);
+  EXPECT_EQ(987u, Time32());
+  EXPECT_EQ(987, TimeMillis());
+  EXPECT_EQ(987654u, TimeMicros());
+  EXPECT_EQ(987654321u, TimeNanos());
+  EXPECT_EQ(1000u, TimeAfter(13));
+
+  SetClock(nullptr);
+  // After it's unset, we should get a normal time.
+  EXPECT_NE(987, TimeMillis());
+}
+
+TEST(FakeClock, InitialTime) {
+  FakeClock clock;
+  EXPECT_EQ(0u, clock.TimeNanos());
+}
+
+TEST(FakeClock, SetTimeNanos) {
+  FakeClock clock;
+  clock.SetTimeNanos(123u);
+  EXPECT_EQ(123u, clock.TimeNanos());
+  clock.SetTimeNanos(456u);
+  EXPECT_EQ(456u, clock.TimeNanos());
+}
+
+TEST(FakeClock, AdvanceTime) {
+  FakeClock clock;
+  clock.AdvanceTime(TimeDelta::FromNanoseconds(1111u));
+  EXPECT_EQ(1111u, clock.TimeNanos());
+  clock.AdvanceTime(TimeDelta::FromMicroseconds(2222u));
+  EXPECT_EQ(2223111u, clock.TimeNanos());
+  clock.AdvanceTime(TimeDelta::FromMilliseconds(3333u));
+  EXPECT_EQ(3335223111u, clock.TimeNanos());
+  clock.AdvanceTime(TimeDelta::FromSeconds(4444u));
+  EXPECT_EQ(4447335223111u, clock.TimeNanos());
+}
+
+// When the clock is advanced, threads that are waiting in a socket select
+// should wake up and look at the new time. This allows tests using the
+// fake clock to run much faster, if the test is bound by time constraints
+// (such as a test for a STUN ping timeout).
+TEST(FakeClock, SettingTimeWakesThreads) {
+  int64_t real_start_time_ms = TimeMillis();
+
+  FakeClock clock;
+  SetClock(&clock);
+
+  Thread worker;
+  worker.Start();
+
+  // Post an event that won't be executed for 10 seconds.
+  Event message_handler_dispatched(false, false);
+  auto functor = [&message_handler_dispatched] {
+    message_handler_dispatched.Set();
+  };
+  FunctorMessageHandler<void, decltype(functor)> handler(functor);
+  worker.PostDelayed(10000, &handler);
+
+  // Wait for a bit for the worker thread to be started and enter its socket
+  // select().
+  Thread::Current()->SleepMs(1000);
+
+  // Advance the fake clock, expecting the worker thread to wake up
+  // and dispatch the message quickly.
+  clock.AdvanceTime(TimeDelta::FromSeconds(10u));
+  message_handler_dispatched.Wait(Event::kForever);
+  worker.Stop();
+
+  SetClock(nullptr);
+
+  // The message should have been dispatched long before the 10 seconds fully
+  // elapsed.
+  int64_t real_end_time_ms = TimeMillis();
+  EXPECT_LT(real_end_time_ms - real_start_time_ms, 2000);
+}
+
 }  // namespace rtc
diff --git a/webrtc/base/timing.h b/webrtc/base/timing.h
index e709f88..a73c57d 100644
--- a/webrtc/base/timing.h
+++ b/webrtc/base/timing.h
@@ -13,6 +13,7 @@
 
 namespace rtc {
 
+// TODO(deadbeef): Remove this and use ClockInterface instead.
 class Timing {
  public:
   Timing();