Update mojo sdk to rev 59145288bae55b0fce4276b017df6a1117bcf00f
[chromium-blink-merge.git] / mojo / edk / system / awakable_list_unittest.cc
blob0ef6a7a0a09f3e423b4177ec201260bbbded7dac
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.
5 // NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a
6 // heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to
7 // increase tolerance and reduce observed flakiness (though doing so reduces the
8 // meaningfulness of the test).
10 #include "mojo/edk/system/awakable_list.h"
12 #include "base/threading/platform_thread.h" // For |Sleep()|.
13 #include "base/time/time.h"
14 #include "mojo/edk/system/handle_signals_state.h"
15 #include "mojo/edk/system/test_utils.h"
16 #include "mojo/edk/system/waiter.h"
17 #include "mojo/edk/system/waiter_test_utils.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace mojo {
21 namespace system {
22 namespace {
24 TEST(AwakableListTest, BasicCancel) {
25 MojoResult result;
26 uint32_t context;
28 // Cancel immediately after thread start.
30 AwakableList awakable_list;
31 test::SimpleWaiterThread thread(&result, &context);
32 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
33 thread.Start();
34 awakable_list.CancelAll();
35 // Double-remove okay:
36 awakable_list.Remove(thread.waiter());
37 } // Join |thread|.
38 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
39 EXPECT_EQ(1u, context);
41 // Cancel before after thread start.
43 AwakableList awakable_list;
44 test::SimpleWaiterThread thread(&result, &context);
45 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
46 awakable_list.CancelAll();
47 thread.Start();
48 } // Join |thread|.
49 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
50 EXPECT_EQ(2u, context);
52 // Cancel some time after thread start.
54 AwakableList awakable_list;
55 test::SimpleWaiterThread thread(&result, &context);
56 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
57 thread.Start();
58 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
59 awakable_list.CancelAll();
60 } // Join |thread|.
61 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
62 EXPECT_EQ(3u, context);
65 TEST(AwakableListTest, BasicAwakeSatisfied) {
66 MojoResult result;
67 uint32_t context;
69 // Awake immediately after thread start.
71 AwakableList awakable_list;
72 test::SimpleWaiterThread thread(&result, &context);
73 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
74 thread.Start();
75 awakable_list.AwakeForStateChange(HandleSignalsState(
76 MOJO_HANDLE_SIGNAL_READABLE,
77 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
78 awakable_list.Remove(thread.waiter());
79 } // Join |thread|.
80 EXPECT_EQ(MOJO_RESULT_OK, result);
81 EXPECT_EQ(1u, context);
83 // Awake before after thread start.
85 AwakableList awakable_list;
86 test::SimpleWaiterThread thread(&result, &context);
87 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
88 awakable_list.AwakeForStateChange(HandleSignalsState(
89 MOJO_HANDLE_SIGNAL_WRITABLE,
90 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
91 awakable_list.Remove(thread.waiter());
92 // Double-remove okay:
93 awakable_list.Remove(thread.waiter());
94 thread.Start();
95 } // Join |thread|.
96 EXPECT_EQ(MOJO_RESULT_OK, result);
97 EXPECT_EQ(2u, context);
99 // Awake some time after thread start.
101 AwakableList awakable_list;
102 test::SimpleWaiterThread thread(&result, &context);
103 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
104 thread.Start();
105 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
106 awakable_list.AwakeForStateChange(HandleSignalsState(
107 MOJO_HANDLE_SIGNAL_READABLE,
108 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
109 awakable_list.Remove(thread.waiter());
110 } // Join |thread|.
111 EXPECT_EQ(MOJO_RESULT_OK, result);
112 EXPECT_EQ(3u, context);
115 TEST(AwakableListTest, BasicAwakeUnsatisfiable) {
116 MojoResult result;
117 uint32_t context;
119 // Awake (for unsatisfiability) immediately after thread start.
121 AwakableList awakable_list;
122 test::SimpleWaiterThread thread(&result, &context);
123 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
124 thread.Start();
125 awakable_list.AwakeForStateChange(HandleSignalsState(
126 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE));
127 awakable_list.Remove(thread.waiter());
128 } // Join |thread|.
129 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
130 EXPECT_EQ(1u, context);
132 // Awake (for unsatisfiability) before after thread start.
134 AwakableList awakable_list;
135 test::SimpleWaiterThread thread(&result, &context);
136 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
137 awakable_list.AwakeForStateChange(HandleSignalsState(
138 MOJO_HANDLE_SIGNAL_READABLE, MOJO_HANDLE_SIGNAL_READABLE));
139 awakable_list.Remove(thread.waiter());
140 thread.Start();
141 } // Join |thread|.
142 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
143 EXPECT_EQ(2u, context);
145 // Awake (for unsatisfiability) some time after thread start.
147 AwakableList awakable_list;
148 test::SimpleWaiterThread thread(&result, &context);
149 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
150 thread.Start();
151 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
152 awakable_list.AwakeForStateChange(HandleSignalsState(
153 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE));
154 awakable_list.Remove(thread.waiter());
155 // Double-remove okay:
156 awakable_list.Remove(thread.waiter());
157 } // Join |thread|.
158 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
159 EXPECT_EQ(3u, context);
162 TEST(AwakableListTest, MultipleAwakables) {
163 MojoResult result1;
164 MojoResult result2;
165 MojoResult result3;
166 MojoResult result4;
167 uint32_t context1;
168 uint32_t context2;
169 uint32_t context3;
170 uint32_t context4;
172 // Cancel two awakables.
174 AwakableList awakable_list;
175 test::SimpleWaiterThread thread1(&result1, &context1);
176 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
177 thread1.Start();
178 test::SimpleWaiterThread thread2(&result2, &context2);
179 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
180 thread2.Start();
181 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
182 awakable_list.CancelAll();
183 } // Join threads.
184 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1);
185 EXPECT_EQ(1u, context1);
186 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2);
187 EXPECT_EQ(2u, context2);
189 // Awake one awakable, cancel other.
191 AwakableList awakable_list;
192 test::SimpleWaiterThread thread1(&result1, &context1);
193 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
194 thread1.Start();
195 test::SimpleWaiterThread thread2(&result2, &context2);
196 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 4);
197 thread2.Start();
198 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
199 awakable_list.AwakeForStateChange(HandleSignalsState(
200 MOJO_HANDLE_SIGNAL_READABLE,
201 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
202 awakable_list.Remove(thread1.waiter());
203 awakable_list.CancelAll();
204 } // Join threads.
205 EXPECT_EQ(MOJO_RESULT_OK, result1);
206 EXPECT_EQ(3u, context1);
207 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2);
208 EXPECT_EQ(4u, context2);
210 // Cancel one awakable, awake other for unsatisfiability.
212 AwakableList awakable_list;
213 test::SimpleWaiterThread thread1(&result1, &context1);
214 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 5);
215 thread1.Start();
216 test::SimpleWaiterThread thread2(&result2, &context2);
217 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 6);
218 thread2.Start();
219 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
220 awakable_list.AwakeForStateChange(HandleSignalsState(
221 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE));
222 awakable_list.Remove(thread2.waiter());
223 awakable_list.CancelAll();
224 } // Join threads.
225 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1);
226 EXPECT_EQ(5u, context1);
227 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2);
228 EXPECT_EQ(6u, context2);
230 // Cancel one awakable, awake other for unsatisfiability.
232 AwakableList awakable_list;
233 test::SimpleWaiterThread thread1(&result1, &context1);
234 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 7);
235 thread1.Start();
237 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
239 // Should do nothing.
240 awakable_list.AwakeForStateChange(HandleSignalsState(
241 MOJO_HANDLE_SIGNAL_NONE,
242 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
244 test::SimpleWaiterThread thread2(&result2, &context2);
245 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 8);
246 thread2.Start();
248 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
250 // Awake #1.
251 awakable_list.AwakeForStateChange(HandleSignalsState(
252 MOJO_HANDLE_SIGNAL_READABLE,
253 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
254 awakable_list.Remove(thread1.waiter());
256 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
258 test::SimpleWaiterThread thread3(&result3, &context3);
259 awakable_list.Add(thread3.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 9);
260 thread3.Start();
262 test::SimpleWaiterThread thread4(&result4, &context4);
263 awakable_list.Add(thread4.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 10);
264 thread4.Start();
266 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
268 // Awake #2 and #3 for unsatisfiability.
269 awakable_list.AwakeForStateChange(HandleSignalsState(
270 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE));
271 awakable_list.Remove(thread2.waiter());
272 awakable_list.Remove(thread3.waiter());
274 // Cancel #4.
275 awakable_list.CancelAll();
276 } // Join threads.
277 EXPECT_EQ(MOJO_RESULT_OK, result1);
278 EXPECT_EQ(7u, context1);
279 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2);
280 EXPECT_EQ(8u, context2);
281 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3);
282 EXPECT_EQ(9u, context3);
283 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4);
284 EXPECT_EQ(10u, context4);
287 class KeepAwakable : public Awakable {
288 public:
289 KeepAwakable() : awake_count(0) {}
291 bool Awake(MojoResult result, uintptr_t context) override {
292 awake_count++;
293 return true;
296 int awake_count;
298 DISALLOW_COPY_AND_ASSIGN(KeepAwakable);
301 class RemoveAwakable : public Awakable {
302 public:
303 RemoveAwakable() : awake_count(0) {}
305 bool Awake(MojoResult result, uintptr_t context) override {
306 awake_count++;
307 return false;
310 int awake_count;
312 DISALLOW_COPY_AND_ASSIGN(RemoveAwakable);
315 TEST(AwakableListTest, KeepAwakablesReturningTrue) {
316 KeepAwakable keep0;
317 KeepAwakable keep1;
318 RemoveAwakable remove0;
319 RemoveAwakable remove1;
320 RemoveAwakable remove2;
322 HandleSignalsState hss(MOJO_HANDLE_SIGNAL_WRITABLE,
323 MOJO_HANDLE_SIGNAL_WRITABLE);
325 AwakableList remove_all;
326 remove_all.Add(&remove0, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
327 remove_all.Add(&remove1, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
329 remove_all.AwakeForStateChange(hss);
330 EXPECT_EQ(remove0.awake_count, 1);
331 EXPECT_EQ(remove1.awake_count, 1);
333 remove_all.AwakeForStateChange(hss);
334 EXPECT_EQ(remove0.awake_count, 1);
335 EXPECT_EQ(remove1.awake_count, 1);
337 AwakableList remove_first;
338 remove_first.Add(&remove2, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
339 remove_first.Add(&keep0, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
340 remove_first.Add(&keep1, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
342 remove_first.AwakeForStateChange(hss);
343 EXPECT_EQ(keep0.awake_count, 1);
344 EXPECT_EQ(keep1.awake_count, 1);
345 EXPECT_EQ(remove2.awake_count, 1);
347 remove_first.AwakeForStateChange(hss);
348 EXPECT_EQ(keep0.awake_count, 2);
349 EXPECT_EQ(keep1.awake_count, 2);
350 EXPECT_EQ(remove2.awake_count, 1);
352 remove_first.Remove(&keep0);
353 remove_first.Remove(&keep1);
356 } // namespace
357 } // namespace system
358 } // namespace mojo