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

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

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

Powered by Google App Engine
This is Rietveld 408576698