Index: base/synchronization/condition_variable_unittest.cc |
diff --git a/base/synchronization/condition_variable_unittest.cc b/base/synchronization/condition_variable_unittest.cc |
index 4230e635495962d7990bbf79070fcc4e37a059dd..65e153cd7909e254ae941f8afcd82c472d0ccae2 100644 |
--- a/base/synchronization/condition_variable_unittest.cc |
+++ b/base/synchronization/condition_variable_unittest.cc |
@@ -8,12 +8,14 @@ |
#include <algorithm> |
#include <vector> |
+#include "base/bind.h" |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/synchronization/condition_variable.h" |
#include "base/synchronization/lock.h" |
#include "base/synchronization/spin_wait.h" |
#include "base/threading/platform_thread.h" |
+#include "base/threading/thread.h" |
#include "base/threading/thread_collision_warner.h" |
#include "base/time/time.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -188,6 +190,57 @@ TEST_F(ConditionVariableTest, TimeoutTest) { |
lock.Release(); |
} |
+#if defined(OS_POSIX) |
+const int kDiscontinuitySeconds = 2; |
+ |
+void BackInTime(Lock* lock) { |
+ AutoLock auto_lock(*lock); |
+ |
+ timeval tv; |
+ gettimeofday(&tv, NULL); |
+ tv.tv_sec -= kDiscontinuitySeconds; |
+ settimeofday(&tv, NULL); |
+} |
+ |
+// Tests that TimedWait ignores changes to the system clock. |
+// Test is disabled by default, because it needs to run as root to muck with the |
+// system clock. |
+// http://crbug.com/293736 |
+TEST_F(ConditionVariableTest, DISABLED_TimeoutAcrossSetTimeOfDay) { |
Alexander Potapenko
2013/10/03 09:16:17
A disabled test will rot in no time, because nobod
|
+ timeval tv; |
+ gettimeofday(&tv, NULL); |
+ tv.tv_sec += kDiscontinuitySeconds; |
+ if (settimeofday(&tv, NULL) < 0) { |
+ PLOG(ERROR) << "Could not set time of day. Run as root?"; |
+ return; |
+ } |
+ |
+ Lock lock; |
+ ConditionVariable cv(&lock); |
+ lock.Acquire(); |
+ |
+ Thread thread("Helper"); |
+ thread.Start(); |
+ thread.message_loop()->PostTask(FROM_HERE, base::Bind(&BackInTime, &lock)); |
+ |
+ TimeTicks start = TimeTicks::Now(); |
+ const TimeDelta kWaitTime = TimeDelta::FromMilliseconds(300); |
+ // Allow for clocking rate granularity. |
+ const TimeDelta kFudgeTime = TimeDelta::FromMilliseconds(50); |
+ |
+ cv.TimedWait(kWaitTime + kFudgeTime); |
+ TimeDelta duration = TimeTicks::Now() - start; |
+ |
+ thread.Stop(); |
+ // We can't use EXPECT_GE here as the TimeDelta class does not support the |
+ // required stream conversion. |
+ EXPECT_TRUE(duration >= kWaitTime); |
+ EXPECT_TRUE(duration <= TimeDelta::FromSeconds(kDiscontinuitySeconds)); |
+ |
+ lock.Release(); |
+} |
+#endif |
+ |
// Suddenly got flaky on Win, see http://crbug.com/10607 (starting at |
// comment #15) |