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

Side by Side Diff: mojo/edk/system/awakable_list_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/awakable_list.cc ('k') | mojo/edk/system/configuration.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/awakable_list.h"
11
12 #include "mojo/edk/system/handle_signals_state.h"
13 #include "mojo/edk/system/test_utils.h"
14 #include "mojo/edk/system/waiter.h"
15 #include "mojo/edk/system/waiter_test_utils.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace mojo {
19 namespace edk {
20 namespace {
21
22 TEST(AwakableListTest, BasicCancel) {
23 MojoResult result;
24 uintptr_t context;
25
26 // Cancel immediately after thread start.
27 {
28 AwakableList awakable_list;
29 test::SimpleWaiterThread thread(&result, &context);
30 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
31 thread.Start();
32 awakable_list.CancelAll();
33 // Double-remove okay:
34 awakable_list.Remove(thread.waiter());
35 } // Join |thread|.
36 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
37 EXPECT_EQ(1u, context);
38
39 // Cancel before after thread start.
40 {
41 AwakableList awakable_list;
42 test::SimpleWaiterThread thread(&result, &context);
43 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
44 awakable_list.CancelAll();
45 thread.Start();
46 } // Join |thread|.
47 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
48 EXPECT_EQ(2u, context);
49
50 // Cancel some time after thread start.
51 {
52 AwakableList awakable_list;
53 test::SimpleWaiterThread thread(&result, &context);
54 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
55 thread.Start();
56 test::Sleep(2 * test::EpsilonDeadline());
57 awakable_list.CancelAll();
58 } // Join |thread|.
59 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
60 EXPECT_EQ(3u, context);
61 }
62
63 TEST(AwakableListTest, BasicAwakeSatisfied) {
64 MojoResult result;
65 uintptr_t context;
66
67 // Awake immediately after thread start.
68 {
69 AwakableList awakable_list;
70 test::SimpleWaiterThread thread(&result, &context);
71 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
72 thread.Start();
73 awakable_list.AwakeForStateChange(HandleSignalsState(
74 MOJO_HANDLE_SIGNAL_READABLE,
75 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
76 awakable_list.Remove(thread.waiter());
77 } // Join |thread|.
78 EXPECT_EQ(MOJO_RESULT_OK, result);
79 EXPECT_EQ(1u, context);
80
81 // Awake before after thread start.
82 {
83 AwakableList awakable_list;
84 test::SimpleWaiterThread thread(&result, &context);
85 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
86 awakable_list.AwakeForStateChange(HandleSignalsState(
87 MOJO_HANDLE_SIGNAL_WRITABLE,
88 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
89 awakable_list.Remove(thread.waiter());
90 // Double-remove okay:
91 awakable_list.Remove(thread.waiter());
92 thread.Start();
93 } // Join |thread|.
94 EXPECT_EQ(MOJO_RESULT_OK, result);
95 EXPECT_EQ(2u, context);
96
97 // Awake some time after thread start.
98 {
99 AwakableList awakable_list;
100 test::SimpleWaiterThread thread(&result, &context);
101 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
102 thread.Start();
103 test::Sleep(2 * test::EpsilonDeadline());
104 awakable_list.AwakeForStateChange(HandleSignalsState(
105 MOJO_HANDLE_SIGNAL_READABLE,
106 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
107 awakable_list.Remove(thread.waiter());
108 } // Join |thread|.
109 EXPECT_EQ(MOJO_RESULT_OK, result);
110 EXPECT_EQ(3u, context);
111 }
112
113 TEST(AwakableListTest, BasicAwakeUnsatisfiable) {
114 MojoResult result;
115 uintptr_t context;
116
117 // Awake (for unsatisfiability) immediately after thread start.
118 {
119 AwakableList awakable_list;
120 test::SimpleWaiterThread thread(&result, &context);
121 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
122 thread.Start();
123 awakable_list.AwakeForStateChange(HandleSignalsState(
124 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE));
125 awakable_list.Remove(thread.waiter());
126 } // Join |thread|.
127 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
128 EXPECT_EQ(1u, context);
129
130 // Awake (for unsatisfiability) before after thread start.
131 {
132 AwakableList awakable_list;
133 test::SimpleWaiterThread thread(&result, &context);
134 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
135 awakable_list.AwakeForStateChange(HandleSignalsState(
136 MOJO_HANDLE_SIGNAL_READABLE, MOJO_HANDLE_SIGNAL_READABLE));
137 awakable_list.Remove(thread.waiter());
138 thread.Start();
139 } // Join |thread|.
140 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
141 EXPECT_EQ(2u, context);
142
143 // Awake (for unsatisfiability) some time after thread start.
144 {
145 AwakableList awakable_list;
146 test::SimpleWaiterThread thread(&result, &context);
147 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
148 thread.Start();
149 test::Sleep(2 * test::EpsilonDeadline());
150 awakable_list.AwakeForStateChange(HandleSignalsState(
151 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE));
152 awakable_list.Remove(thread.waiter());
153 // Double-remove okay:
154 awakable_list.Remove(thread.waiter());
155 } // Join |thread|.
156 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
157 EXPECT_EQ(3u, context);
158 }
159
160 TEST(AwakableListTest, MultipleAwakables) {
161 MojoResult result1;
162 MojoResult result2;
163 MojoResult result3;
164 MojoResult result4;
165 uintptr_t context1;
166 uintptr_t context2;
167 uintptr_t context3;
168 uintptr_t context4;
169
170 // Cancel two awakables.
171 {
172 AwakableList awakable_list;
173 test::SimpleWaiterThread thread1(&result1, &context1);
174 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
175 thread1.Start();
176 test::SimpleWaiterThread thread2(&result2, &context2);
177 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
178 thread2.Start();
179 test::Sleep(2 * test::EpsilonDeadline());
180 awakable_list.CancelAll();
181 } // Join threads.
182 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1);
183 EXPECT_EQ(1u, context1);
184 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2);
185 EXPECT_EQ(2u, context2);
186
187 // Awake one awakable, cancel other.
188 {
189 AwakableList awakable_list;
190 test::SimpleWaiterThread thread1(&result1, &context1);
191 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
192 thread1.Start();
193 test::SimpleWaiterThread thread2(&result2, &context2);
194 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 4);
195 thread2.Start();
196 test::Sleep(2 * test::EpsilonDeadline());
197 awakable_list.AwakeForStateChange(HandleSignalsState(
198 MOJO_HANDLE_SIGNAL_READABLE,
199 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
200 awakable_list.Remove(thread1.waiter());
201 awakable_list.CancelAll();
202 } // Join threads.
203 EXPECT_EQ(MOJO_RESULT_OK, result1);
204 EXPECT_EQ(3u, context1);
205 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2);
206 EXPECT_EQ(4u, context2);
207
208 // Cancel one awakable, awake other for unsatisfiability.
209 {
210 AwakableList awakable_list;
211 test::SimpleWaiterThread thread1(&result1, &context1);
212 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 5);
213 thread1.Start();
214 test::SimpleWaiterThread thread2(&result2, &context2);
215 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 6);
216 thread2.Start();
217 test::Sleep(2 * test::EpsilonDeadline());
218 awakable_list.AwakeForStateChange(HandleSignalsState(
219 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE));
220 awakable_list.Remove(thread2.waiter());
221 awakable_list.CancelAll();
222 } // Join threads.
223 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1);
224 EXPECT_EQ(5u, context1);
225 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2);
226 EXPECT_EQ(6u, context2);
227
228 // Cancel one awakable, awake other for unsatisfiability.
229 {
230 AwakableList awakable_list;
231 test::SimpleWaiterThread thread1(&result1, &context1);
232 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 7);
233 thread1.Start();
234
235 test::Sleep(1 * test::EpsilonDeadline());
236
237 // Should do nothing.
238 awakable_list.AwakeForStateChange(HandleSignalsState(
239 MOJO_HANDLE_SIGNAL_NONE,
240 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
241
242 test::SimpleWaiterThread thread2(&result2, &context2);
243 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 8);
244 thread2.Start();
245
246 test::Sleep(1 * test::EpsilonDeadline());
247
248 // Awake #1.
249 awakable_list.AwakeForStateChange(HandleSignalsState(
250 MOJO_HANDLE_SIGNAL_READABLE,
251 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
252 awakable_list.Remove(thread1.waiter());
253
254 test::Sleep(1 * test::EpsilonDeadline());
255
256 test::SimpleWaiterThread thread3(&result3, &context3);
257 awakable_list.Add(thread3.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 9);
258 thread3.Start();
259
260 test::SimpleWaiterThread thread4(&result4, &context4);
261 awakable_list.Add(thread4.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 10);
262 thread4.Start();
263
264 test::Sleep(1 * test::EpsilonDeadline());
265
266 // Awake #2 and #3 for unsatisfiability.
267 awakable_list.AwakeForStateChange(HandleSignalsState(
268 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE));
269 awakable_list.Remove(thread2.waiter());
270 awakable_list.Remove(thread3.waiter());
271
272 // Cancel #4.
273 awakable_list.CancelAll();
274 } // Join threads.
275 EXPECT_EQ(MOJO_RESULT_OK, result1);
276 EXPECT_EQ(7u, context1);
277 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2);
278 EXPECT_EQ(8u, context2);
279 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3);
280 EXPECT_EQ(9u, context3);
281 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4);
282 EXPECT_EQ(10u, context4);
283 }
284
285 class KeepAwakable : public Awakable {
286 public:
287 KeepAwakable() : awake_count(0) {}
288
289 bool Awake(MojoResult result, uintptr_t context) override {
290 awake_count++;
291 return true;
292 }
293
294 int awake_count;
295
296 DISALLOW_COPY_AND_ASSIGN(KeepAwakable);
297 };
298
299 class RemoveAwakable : public Awakable {
300 public:
301 RemoveAwakable() : awake_count(0) {}
302
303 bool Awake(MojoResult result, uintptr_t context) override {
304 awake_count++;
305 return false;
306 }
307
308 int awake_count;
309
310 DISALLOW_COPY_AND_ASSIGN(RemoveAwakable);
311 };
312
313 TEST(AwakableListTest, KeepAwakablesReturningTrue) {
314 KeepAwakable keep0;
315 KeepAwakable keep1;
316 RemoveAwakable remove0;
317 RemoveAwakable remove1;
318 RemoveAwakable remove2;
319
320 HandleSignalsState hss(MOJO_HANDLE_SIGNAL_WRITABLE,
321 MOJO_HANDLE_SIGNAL_WRITABLE);
322
323 AwakableList remove_all;
324 remove_all.Add(&remove0, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
325 remove_all.Add(&remove1, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
326
327 remove_all.AwakeForStateChange(hss);
328 EXPECT_EQ(remove0.awake_count, 1);
329 EXPECT_EQ(remove1.awake_count, 1);
330
331 remove_all.AwakeForStateChange(hss);
332 EXPECT_EQ(remove0.awake_count, 1);
333 EXPECT_EQ(remove1.awake_count, 1);
334
335 AwakableList remove_first;
336 remove_first.Add(&remove2, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
337 remove_first.Add(&keep0, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
338 remove_first.Add(&keep1, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
339
340 remove_first.AwakeForStateChange(hss);
341 EXPECT_EQ(keep0.awake_count, 1);
342 EXPECT_EQ(keep1.awake_count, 1);
343 EXPECT_EQ(remove2.awake_count, 1);
344
345 remove_first.AwakeForStateChange(hss);
346 EXPECT_EQ(keep0.awake_count, 2);
347 EXPECT_EQ(keep1.awake_count, 2);
348 EXPECT_EQ(remove2.awake_count, 1);
349
350 remove_first.Remove(&keep0);
351 remove_first.Remove(&keep1);
352 }
353
354 } // namespace
355 } // namespace edk
356 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/awakable_list.cc ('k') | mojo/edk/system/configuration.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698