Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: mojo/system/waiter_unittest.cc

Issue 281893002: Mojo: Base our epsilon timeouts off of TestTimeouts::tiny_timeout(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mojo/system/waiter_list_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // NOTE(vtl): These tests are inherently flaky (e.g., if run on a heavily-loaded 5 // NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a
6 // system). Sorry. |kEpsilonMicros| may be increased to increase tolerance and 6 // heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to
7 // reduce observed flakiness. 7 // increase tolerance and reduce observed flakiness (though doing so reduces the
8 // meaningfulness of the test).
8 9
9 #include "mojo/system/waiter.h" 10 #include "mojo/system/waiter.h"
10 11
11 #include "base/basictypes.h" 12 #include "base/basictypes.h"
12 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
13 #include "base/synchronization/lock.h" 14 #include "base/synchronization/lock.h"
14 #include "base/threading/platform_thread.h" // For |Sleep()|. 15 #include "base/threading/platform_thread.h" // For |Sleep()|.
15 #include "base/threading/simple_thread.h" 16 #include "base/threading/simple_thread.h"
16 #include "base/time/time.h" 17 #include "base/time/time.h"
17 #include "mojo/system/test_utils.h" 18 #include "mojo/system/test_utils.h"
18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
19 20
20 namespace mojo { 21 namespace mojo {
21 namespace system { 22 namespace system {
22 namespace { 23 namespace {
23 24
24 const int64_t kMicrosPerMs = 1000; 25 const int64_t kMicrosPerMs = 1000;
25 const int64_t kEpsilonMicros = 30 * kMicrosPerMs; // 30 ms.
26 const int64_t kPollTimeMicros = 10 * kMicrosPerMs; // 10 ms. 26 const int64_t kPollTimeMicros = 10 * kMicrosPerMs; // 10 ms.
27 27
28 class WaitingThread : public base::SimpleThread { 28 class WaitingThread : public base::SimpleThread {
29 public: 29 public:
30 explicit WaitingThread(MojoDeadline deadline) 30 explicit WaitingThread(MojoDeadline deadline)
31 : base::SimpleThread("waiting_thread"), 31 : base::SimpleThread("waiting_thread"),
32 deadline_(deadline), 32 deadline_(deadline),
33 done_(false), 33 done_(false),
34 result_(MOJO_RESULT_UNKNOWN), 34 result_(MOJO_RESULT_UNKNOWN) {
35 elapsed_micros_(-1) {
36 waiter_.Init(); 35 waiter_.Init();
37 } 36 }
38 37
39 virtual ~WaitingThread() { 38 virtual ~WaitingThread() {
40 Join(); 39 Join();
41 } 40 }
42 41
43 void WaitUntilDone(MojoResult* result, int64_t* elapsed_micros) { 42 void WaitUntilDone(MojoResult* result, base::TimeDelta* elapsed) {
44 for (;;) { 43 for (;;) {
45 { 44 {
46 base::AutoLock locker(lock_); 45 base::AutoLock locker(lock_);
47 if (done_) { 46 if (done_) {
48 *result = result_; 47 *result = result_;
49 *elapsed_micros = elapsed_micros_; 48 *elapsed = elapsed_;
50 break; 49 break;
51 } 50 }
52 } 51 }
53 52
54 base::PlatformThread::Sleep( 53 base::PlatformThread::Sleep(
55 base::TimeDelta::FromMicroseconds(kPollTimeMicros)); 54 base::TimeDelta::FromMicroseconds(kPollTimeMicros));
56 } 55 }
57 } 56 }
58 57
59 Waiter* waiter() { return &waiter_; } 58 Waiter* waiter() { return &waiter_; }
60 59
61 private: 60 private:
62 virtual void Run() OVERRIDE { 61 virtual void Run() OVERRIDE {
63 test::Stopwatch stopwatch; 62 test::Stopwatch stopwatch;
64 MojoResult result; 63 MojoResult result;
65 int64_t elapsed_micros; 64 base::TimeDelta elapsed;
66 65
67 stopwatch.Start(); 66 stopwatch.Start();
68 result = waiter_.Wait(deadline_); 67 result = waiter_.Wait(deadline_);
69 elapsed_micros = stopwatch.Elapsed(); 68 elapsed = stopwatch.Elapsed();
70 69
71 { 70 {
72 base::AutoLock locker(lock_); 71 base::AutoLock locker(lock_);
73 done_ = true; 72 done_ = true;
74 result_ = result; 73 result_ = result;
75 elapsed_micros_ = elapsed_micros; 74 elapsed_ = elapsed;
76 } 75 }
77 } 76 }
78 77
79 const MojoDeadline deadline_; 78 const MojoDeadline deadline_;
80 Waiter waiter_; // Thread-safe. 79 Waiter waiter_; // Thread-safe.
81 80
82 base::Lock lock_; // Protects the following members. 81 base::Lock lock_; // Protects the following members.
83 bool done_; 82 bool done_;
84 MojoResult result_; 83 MojoResult result_;
85 int64_t elapsed_micros_; 84 base::TimeDelta elapsed_;
86 85
87 DISALLOW_COPY_AND_ASSIGN(WaitingThread); 86 DISALLOW_COPY_AND_ASSIGN(WaitingThread);
88 }; 87 };
89 88
90 TEST(WaiterTest, Basic) { 89 TEST(WaiterTest, Basic) {
91 MojoResult result; 90 MojoResult result;
92 int64_t elapsed_micros; 91 base::TimeDelta elapsed;
93 92
94 // Finite deadline. 93 // Finite deadline.
95 94
96 // Awake immediately after thread start. 95 // Awake immediately after thread start.
97 { 96 {
98 WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 97 WaitingThread thread(10 * test::EpsilonTimeout().InMicroseconds());
99 thread.Start(); 98 thread.Start();
100 thread.waiter()->Awake(0); 99 thread.waiter()->Awake(0);
101 thread.WaitUntilDone(&result, &elapsed_micros); 100 thread.WaitUntilDone(&result, &elapsed);
102 EXPECT_EQ(0, result); 101 EXPECT_EQ(0, result);
103 EXPECT_LT(elapsed_micros, kEpsilonMicros); 102 EXPECT_LT(elapsed, test::EpsilonTimeout());
104 } 103 }
105 104
106 // Awake before after thread start. 105 // Awake before after thread start.
107 { 106 {
108 WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 107 WaitingThread thread(10 * test::EpsilonTimeout().InMicroseconds());
109 thread.waiter()->Awake(MOJO_RESULT_CANCELLED); 108 thread.waiter()->Awake(MOJO_RESULT_CANCELLED);
110 thread.Start(); 109 thread.Start();
111 thread.WaitUntilDone(&result, &elapsed_micros); 110 thread.WaitUntilDone(&result, &elapsed);
112 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); 111 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
113 EXPECT_LT(elapsed_micros, kEpsilonMicros); 112 EXPECT_LT(elapsed, test::EpsilonTimeout());
114 } 113 }
115 114
116 // Awake some time after thread start. 115 // Awake some time after thread start.
117 { 116 {
118 WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 117 WaitingThread thread(10 * test::EpsilonTimeout().InMicroseconds());
119 thread.Start(); 118 thread.Start();
120 base::PlatformThread::Sleep( 119 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
121 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
122 thread.waiter()->Awake(1); 120 thread.waiter()->Awake(1);
123 thread.WaitUntilDone(&result, &elapsed_micros); 121 thread.WaitUntilDone(&result, &elapsed);
124 EXPECT_EQ(1, result); 122 EXPECT_EQ(1, result);
125 EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros); 123 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
126 EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros); 124 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
127 } 125 }
128 126
129 // Awake some longer time after thread start. 127 // Awake some longer time after thread start.
130 { 128 {
131 WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 129 WaitingThread thread(10 * test::EpsilonTimeout().InMicroseconds());
132 thread.Start(); 130 thread.Start();
133 base::PlatformThread::Sleep( 131 base::PlatformThread::Sleep(5 * test::EpsilonTimeout());
134 base::TimeDelta::FromMicroseconds(5 * kEpsilonMicros));
135 thread.waiter()->Awake(1); 132 thread.waiter()->Awake(1);
136 thread.WaitUntilDone(&result, &elapsed_micros); 133 thread.WaitUntilDone(&result, &elapsed);
137 EXPECT_EQ(1, result); 134 EXPECT_EQ(1, result);
138 EXPECT_GT(elapsed_micros, (5-1) * kEpsilonMicros); 135 EXPECT_GT(elapsed, (5-1) * test::EpsilonTimeout());
139 EXPECT_LT(elapsed_micros, (5+1) * kEpsilonMicros); 136 EXPECT_LT(elapsed, (5+1) * test::EpsilonTimeout());
140 } 137 }
141 138
142 // Don't awake -- time out (on another thread). 139 // Don't awake -- time out (on another thread).
143 { 140 {
144 WaitingThread thread(static_cast<MojoDeadline>(2 * kEpsilonMicros)); 141 WaitingThread thread(2 * test::EpsilonTimeout().InMicroseconds());
145 thread.Start(); 142 thread.Start();
146 thread.WaitUntilDone(&result, &elapsed_micros); 143 thread.WaitUntilDone(&result, &elapsed);
147 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result); 144 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result);
148 EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros); 145 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
149 EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros); 146 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
150 } 147 }
151 148
152 // No (indefinite) deadline. 149 // No (indefinite) deadline.
153 150
154 // Awake immediately after thread start. 151 // Awake immediately after thread start.
155 { 152 {
156 WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 153 WaitingThread thread(MOJO_DEADLINE_INDEFINITE);
157 thread.Start(); 154 thread.Start();
158 thread.waiter()->Awake(0); 155 thread.waiter()->Awake(0);
159 thread.WaitUntilDone(&result, &elapsed_micros); 156 thread.WaitUntilDone(&result, &elapsed);
160 EXPECT_EQ(0, result); 157 EXPECT_EQ(0, result);
161 EXPECT_LT(elapsed_micros, kEpsilonMicros); 158 EXPECT_LT(elapsed, test::EpsilonTimeout());
162 } 159 }
163 160
164 // Awake before after thread start. 161 // Awake before after thread start.
165 { 162 {
166 WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 163 WaitingThread thread(MOJO_DEADLINE_INDEFINITE);
167 thread.waiter()->Awake(MOJO_RESULT_CANCELLED); 164 thread.waiter()->Awake(MOJO_RESULT_CANCELLED);
168 thread.Start(); 165 thread.Start();
169 thread.WaitUntilDone(&result, &elapsed_micros); 166 thread.WaitUntilDone(&result, &elapsed);
170 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); 167 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
171 EXPECT_LT(elapsed_micros, kEpsilonMicros); 168 EXPECT_LT(elapsed, test::EpsilonTimeout());
172 } 169 }
173 170
174 // Awake some time after thread start. 171 // Awake some time after thread start.
175 { 172 {
176 WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 173 WaitingThread thread(MOJO_DEADLINE_INDEFINITE);
177 thread.Start(); 174 thread.Start();
178 base::PlatformThread::Sleep( 175 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
179 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
180 thread.waiter()->Awake(1); 176 thread.waiter()->Awake(1);
181 thread.WaitUntilDone(&result, &elapsed_micros); 177 thread.WaitUntilDone(&result, &elapsed);
182 EXPECT_EQ(1, result); 178 EXPECT_EQ(1, result);
183 EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros); 179 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
184 EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros); 180 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
185 } 181 }
186 182
187 // Awake some longer time after thread start. 183 // Awake some longer time after thread start.
188 { 184 {
189 WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 185 WaitingThread thread(MOJO_DEADLINE_INDEFINITE);
190 thread.Start(); 186 thread.Start();
191 base::PlatformThread::Sleep( 187 base::PlatformThread::Sleep(5 * test::EpsilonTimeout());
192 base::TimeDelta::FromMicroseconds(5 * kEpsilonMicros));
193 thread.waiter()->Awake(1); 188 thread.waiter()->Awake(1);
194 thread.WaitUntilDone(&result, &elapsed_micros); 189 thread.WaitUntilDone(&result, &elapsed);
195 EXPECT_EQ(1, result); 190 EXPECT_EQ(1, result);
196 EXPECT_GT(elapsed_micros, (5-1) * kEpsilonMicros); 191 EXPECT_GT(elapsed, (5-1) * test::EpsilonTimeout());
197 EXPECT_LT(elapsed_micros, (5+1) * kEpsilonMicros); 192 EXPECT_LT(elapsed, (5+1) * test::EpsilonTimeout());
198 } 193 }
199 } 194 }
200 195
201 TEST(WaiterTest, TimeOut) { 196 TEST(WaiterTest, TimeOut) {
202 test::Stopwatch stopwatch; 197 test::Stopwatch stopwatch;
203 int64_t elapsed_micros; 198 base::TimeDelta elapsed;
204 199
205 Waiter waiter; 200 Waiter waiter;
206 201
207 waiter.Init(); 202 waiter.Init();
208 stopwatch.Start(); 203 stopwatch.Start();
209 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0)); 204 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
210 elapsed_micros = stopwatch.Elapsed(); 205 elapsed = stopwatch.Elapsed();
211 EXPECT_LT(elapsed_micros, kEpsilonMicros); 206 EXPECT_LT(elapsed, test::EpsilonTimeout());
212 207
213 waiter.Init(); 208 waiter.Init();
214 stopwatch.Start(); 209 stopwatch.Start();
215 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, 210 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
216 waiter.Wait(static_cast<MojoDeadline>(2 * kEpsilonMicros))); 211 waiter.Wait(2 * test::EpsilonTimeout().InMicroseconds()));
217 elapsed_micros = stopwatch.Elapsed(); 212 elapsed = stopwatch.Elapsed();
218 EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros); 213 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
219 EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros); 214 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
220 215
221 waiter.Init(); 216 waiter.Init();
222 stopwatch.Start(); 217 stopwatch.Start();
223 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, 218 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
224 waiter.Wait(static_cast<MojoDeadline>(5 * kEpsilonMicros))); 219 waiter.Wait(5 * test::EpsilonTimeout().InMicroseconds()));
225 elapsed_micros = stopwatch.Elapsed(); 220 elapsed = stopwatch.Elapsed();
226 EXPECT_GT(elapsed_micros, (5-1) * kEpsilonMicros); 221 EXPECT_GT(elapsed, (5-1) * test::EpsilonTimeout());
227 EXPECT_LT(elapsed_micros, (5+1) * kEpsilonMicros); 222 EXPECT_LT(elapsed, (5+1) * test::EpsilonTimeout());
228 } 223 }
229 224
230 // The first |Awake()| should always win. 225 // The first |Awake()| should always win.
231 TEST(WaiterTest, MultipleAwakes) { 226 TEST(WaiterTest, MultipleAwakes) {
232 MojoResult result; 227 MojoResult result;
233 int64_t elapsed_micros; 228 base::TimeDelta elapsed;
234 229
235 { 230 {
236 WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 231 WaitingThread thread(MOJO_DEADLINE_INDEFINITE);
237 thread.Start(); 232 thread.Start();
238 thread.waiter()->Awake(0); 233 thread.waiter()->Awake(0);
239 thread.waiter()->Awake(1); 234 thread.waiter()->Awake(1);
240 thread.WaitUntilDone(&result, &elapsed_micros); 235 thread.WaitUntilDone(&result, &elapsed);
241 EXPECT_EQ(0, result); 236 EXPECT_EQ(0, result);
242 EXPECT_LT(elapsed_micros, kEpsilonMicros); 237 EXPECT_LT(elapsed, test::EpsilonTimeout());
243 } 238 }
244 239
245 { 240 {
246 WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 241 WaitingThread thread(MOJO_DEADLINE_INDEFINITE);
247 thread.waiter()->Awake(1); 242 thread.waiter()->Awake(1);
248 thread.Start(); 243 thread.Start();
249 thread.waiter()->Awake(0); 244 thread.waiter()->Awake(0);
250 thread.WaitUntilDone(&result, &elapsed_micros); 245 thread.WaitUntilDone(&result, &elapsed);
251 EXPECT_EQ(1, result); 246 EXPECT_EQ(1, result);
252 EXPECT_LT(elapsed_micros, kEpsilonMicros); 247 EXPECT_LT(elapsed, test::EpsilonTimeout());
253 } 248 }
254 249
255 { 250 {
256 WaitingThread thread(MOJO_DEADLINE_INDEFINITE); 251 WaitingThread thread(MOJO_DEADLINE_INDEFINITE);
257 thread.Start(); 252 thread.Start();
258 thread.waiter()->Awake(10); 253 thread.waiter()->Awake(10);
259 base::PlatformThread::Sleep( 254 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
260 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
261 thread.waiter()->Awake(20); 255 thread.waiter()->Awake(20);
262 thread.WaitUntilDone(&result, &elapsed_micros); 256 thread.WaitUntilDone(&result, &elapsed);
263 EXPECT_EQ(10, result); 257 EXPECT_EQ(10, result);
264 EXPECT_LT(elapsed_micros, kEpsilonMicros); 258 EXPECT_LT(elapsed, test::EpsilonTimeout());
265 } 259 }
266 260
267 { 261 {
268 WaitingThread thread(static_cast<MojoDeadline>(10 * kEpsilonMicros)); 262 WaitingThread thread(10 * test::EpsilonTimeout().InMicroseconds());
269 thread.Start(); 263 thread.Start();
270 base::PlatformThread::Sleep( 264 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
271 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
272 thread.waiter()->Awake(MOJO_RESULT_FAILED_PRECONDITION); 265 thread.waiter()->Awake(MOJO_RESULT_FAILED_PRECONDITION);
273 base::PlatformThread::Sleep( 266 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
274 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
275 thread.waiter()->Awake(0); 267 thread.waiter()->Awake(0);
276 thread.WaitUntilDone(&result, &elapsed_micros); 268 thread.WaitUntilDone(&result, &elapsed);
277 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); 269 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
278 EXPECT_GT(elapsed_micros, (1-1) * kEpsilonMicros); 270 EXPECT_GT(elapsed, (1-1) * test::EpsilonTimeout());
279 EXPECT_LT(elapsed_micros, (1+1) * kEpsilonMicros); 271 EXPECT_LT(elapsed, (1+1) * test::EpsilonTimeout());
280 } 272 }
281 } 273 }
282 274
283 } // namespace 275 } // namespace
284 } // namespace system 276 } // namespace system
285 } // namespace mojo 277 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/waiter_list_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698