OLD | NEW |
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_list.h" | 10 #include "mojo/system/waiter_list.h" |
10 | 11 |
11 #include "base/threading/platform_thread.h" // For |Sleep()|. | 12 #include "base/threading/platform_thread.h" // For |Sleep()|. |
12 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "mojo/system/test_utils.h" |
13 #include "mojo/system/waiter.h" | 15 #include "mojo/system/waiter.h" |
14 #include "mojo/system/waiter_test_utils.h" | 16 #include "mojo/system/waiter_test_utils.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
16 | 18 |
17 namespace mojo { | 19 namespace mojo { |
18 namespace system { | 20 namespace system { |
19 namespace { | 21 namespace { |
20 | 22 |
21 const int64_t kMicrosPerMs = 1000; | |
22 const int64_t kEpsilonMicros = 30 * kMicrosPerMs; // 30 ms. | |
23 | |
24 TEST(WaiterListTest, BasicCancel) { | 23 TEST(WaiterListTest, BasicCancel) { |
25 MojoResult result; | 24 MojoResult result; |
26 | 25 |
27 // Cancel immediately after thread start. | 26 // Cancel immediately after thread start. |
28 { | 27 { |
29 WaiterList waiter_list; | 28 WaiterList waiter_list; |
30 test::SimpleWaiterThread thread(&result); | 29 test::SimpleWaiterThread thread(&result); |
31 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0); | 30 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0); |
32 thread.Start(); | 31 thread.Start(); |
33 waiter_list.CancelAllWaiters(); | 32 waiter_list.CancelAllWaiters(); |
(...skipping 10 matching lines...) Expand all Loading... |
44 thread.Start(); | 43 thread.Start(); |
45 } // Join |thread|. | 44 } // Join |thread|. |
46 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 45 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
47 | 46 |
48 // Cancel some time after thread start. | 47 // Cancel some time after thread start. |
49 { | 48 { |
50 WaiterList waiter_list; | 49 WaiterList waiter_list; |
51 test::SimpleWaiterThread thread(&result); | 50 test::SimpleWaiterThread thread(&result); |
52 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); | 51 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); |
53 thread.Start(); | 52 thread.Start(); |
54 base::PlatformThread::Sleep( | 53 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
55 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); | |
56 waiter_list.CancelAllWaiters(); | 54 waiter_list.CancelAllWaiters(); |
57 } // Join |thread|. | 55 } // Join |thread|. |
58 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 56 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
59 } | 57 } |
60 | 58 |
61 TEST(WaiterListTest, BasicAwakeSatisfied) { | 59 TEST(WaiterListTest, BasicAwakeSatisfied) { |
62 MojoResult result; | 60 MojoResult result; |
63 | 61 |
64 // Awake immediately after thread start. | 62 // Awake immediately after thread start. |
65 { | 63 { |
(...skipping 21 matching lines...) Expand all Loading... |
87 thread.Start(); | 85 thread.Start(); |
88 } // Join |thread|. | 86 } // Join |thread|. |
89 EXPECT_EQ(1, result); | 87 EXPECT_EQ(1, result); |
90 | 88 |
91 // Awake some time after thread start. | 89 // Awake some time after thread start. |
92 { | 90 { |
93 WaiterList waiter_list; | 91 WaiterList waiter_list; |
94 test::SimpleWaiterThread thread(&result); | 92 test::SimpleWaiterThread thread(&result); |
95 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); | 93 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); |
96 thread.Start(); | 94 thread.Start(); |
97 base::PlatformThread::Sleep( | 95 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
98 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); | |
99 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, | 96 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, |
100 MOJO_WAIT_FLAG_READABLE | | 97 MOJO_WAIT_FLAG_READABLE | |
101 MOJO_WAIT_FLAG_WRITABLE); | 98 MOJO_WAIT_FLAG_WRITABLE); |
102 waiter_list.RemoveWaiter(thread.waiter()); | 99 waiter_list.RemoveWaiter(thread.waiter()); |
103 } // Join |thread|. | 100 } // Join |thread|. |
104 EXPECT_EQ(2, result); | 101 EXPECT_EQ(2, result); |
105 } | 102 } |
106 | 103 |
107 TEST(WaiterListTest, BasicAwakeUnsatisfiable) { | 104 TEST(WaiterListTest, BasicAwakeUnsatisfiable) { |
108 MojoResult result; | 105 MojoResult result; |
(...skipping 20 matching lines...) Expand all Loading... |
129 thread.Start(); | 126 thread.Start(); |
130 } // Join |thread|. | 127 } // Join |thread|. |
131 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 128 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
132 | 129 |
133 // Awake (for unsatisfiability) some time after thread start. | 130 // Awake (for unsatisfiability) some time after thread start. |
134 { | 131 { |
135 WaiterList waiter_list; | 132 WaiterList waiter_list; |
136 test::SimpleWaiterThread thread(&result); | 133 test::SimpleWaiterThread thread(&result); |
137 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); | 134 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); |
138 thread.Start(); | 135 thread.Start(); |
139 base::PlatformThread::Sleep( | 136 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
140 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); | |
141 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_WRITABLE); | 137 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_WRITABLE); |
142 waiter_list.RemoveWaiter(thread.waiter()); | 138 waiter_list.RemoveWaiter(thread.waiter()); |
143 waiter_list.RemoveWaiter(thread.waiter()); // Double-remove okay. | 139 waiter_list.RemoveWaiter(thread.waiter()); // Double-remove okay. |
144 } // Join |thread|. | 140 } // Join |thread|. |
145 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 141 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
146 } | 142 } |
147 | 143 |
148 TEST(WaiterListTest, MultipleWaiters) { | 144 TEST(WaiterListTest, MultipleWaiters) { |
149 MojoResult result1; | 145 MojoResult result1; |
150 MojoResult result2; | 146 MojoResult result2; |
151 MojoResult result3; | 147 MojoResult result3; |
152 MojoResult result4; | 148 MojoResult result4; |
153 | 149 |
154 // Cancel two waiters. | 150 // Cancel two waiters. |
155 { | 151 { |
156 WaiterList waiter_list; | 152 WaiterList waiter_list; |
157 test::SimpleWaiterThread thread1(&result1); | 153 test::SimpleWaiterThread thread1(&result1); |
158 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 0); | 154 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 0); |
159 thread1.Start(); | 155 thread1.Start(); |
160 test::SimpleWaiterThread thread2(&result2); | 156 test::SimpleWaiterThread thread2(&result2); |
161 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1); | 157 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1); |
162 thread2.Start(); | 158 thread2.Start(); |
163 base::PlatformThread::Sleep( | 159 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
164 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); | |
165 waiter_list.CancelAllWaiters(); | 160 waiter_list.CancelAllWaiters(); |
166 } // Join threads. | 161 } // Join threads. |
167 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); | 162 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); |
168 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); | 163 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); |
169 | 164 |
170 // Awake one waiter, cancel other. | 165 // Awake one waiter, cancel other. |
171 { | 166 { |
172 WaiterList waiter_list; | 167 WaiterList waiter_list; |
173 test::SimpleWaiterThread thread1(&result1); | 168 test::SimpleWaiterThread thread1(&result1); |
174 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 2); | 169 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 2); |
175 thread1.Start(); | 170 thread1.Start(); |
176 test::SimpleWaiterThread thread2(&result2); | 171 test::SimpleWaiterThread thread2(&result2); |
177 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 3); | 172 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 3); |
178 thread2.Start(); | 173 thread2.Start(); |
179 base::PlatformThread::Sleep( | 174 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
180 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); | |
181 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, | 175 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, |
182 MOJO_WAIT_FLAG_READABLE | | 176 MOJO_WAIT_FLAG_READABLE | |
183 MOJO_WAIT_FLAG_WRITABLE); | 177 MOJO_WAIT_FLAG_WRITABLE); |
184 waiter_list.RemoveWaiter(thread1.waiter()); | 178 waiter_list.RemoveWaiter(thread1.waiter()); |
185 waiter_list.CancelAllWaiters(); | 179 waiter_list.CancelAllWaiters(); |
186 } // Join threads. | 180 } // Join threads. |
187 EXPECT_EQ(2, result1); | 181 EXPECT_EQ(2, result1); |
188 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); | 182 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); |
189 | 183 |
190 // Cancel one waiter, awake other for unsatisfiability. | 184 // Cancel one waiter, awake other for unsatisfiability. |
191 { | 185 { |
192 WaiterList waiter_list; | 186 WaiterList waiter_list; |
193 test::SimpleWaiterThread thread1(&result1); | 187 test::SimpleWaiterThread thread1(&result1); |
194 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 4); | 188 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 4); |
195 thread1.Start(); | 189 thread1.Start(); |
196 test::SimpleWaiterThread thread2(&result2); | 190 test::SimpleWaiterThread thread2(&result2); |
197 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 5); | 191 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 5); |
198 thread2.Start(); | 192 thread2.Start(); |
199 base::PlatformThread::Sleep( | 193 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
200 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros)); | |
201 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE); | 194 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE); |
202 waiter_list.RemoveWaiter(thread2.waiter()); | 195 waiter_list.RemoveWaiter(thread2.waiter()); |
203 waiter_list.CancelAllWaiters(); | 196 waiter_list.CancelAllWaiters(); |
204 } // Join threads. | 197 } // Join threads. |
205 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); | 198 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); |
206 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); | 199 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); |
207 | 200 |
208 // Cancel one waiter, awake other for unsatisfiability. | 201 // Cancel one waiter, awake other for unsatisfiability. |
209 { | 202 { |
210 WaiterList waiter_list; | 203 WaiterList waiter_list; |
211 test::SimpleWaiterThread thread1(&result1); | 204 test::SimpleWaiterThread thread1(&result1); |
212 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 6); | 205 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 6); |
213 thread1.Start(); | 206 thread1.Start(); |
214 | 207 |
215 base::PlatformThread::Sleep( | 208 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); |
216 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros)); | |
217 | 209 |
218 // Should do nothing. | 210 // Should do nothing. |
219 waiter_list.AwakeWaitersForStateChange(0, | 211 waiter_list.AwakeWaitersForStateChange(0, |
220 MOJO_WAIT_FLAG_READABLE | | 212 MOJO_WAIT_FLAG_READABLE | |
221 MOJO_WAIT_FLAG_WRITABLE); | 213 MOJO_WAIT_FLAG_WRITABLE); |
222 | 214 |
223 test::SimpleWaiterThread thread2(&result2); | 215 test::SimpleWaiterThread thread2(&result2); |
224 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 7); | 216 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 7); |
225 thread2.Start(); | 217 thread2.Start(); |
226 | 218 |
227 base::PlatformThread::Sleep( | 219 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); |
228 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros)); | |
229 | 220 |
230 // Awake #1. | 221 // Awake #1. |
231 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, | 222 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, |
232 MOJO_WAIT_FLAG_READABLE | | 223 MOJO_WAIT_FLAG_READABLE | |
233 MOJO_WAIT_FLAG_WRITABLE); | 224 MOJO_WAIT_FLAG_WRITABLE); |
234 waiter_list.RemoveWaiter(thread1.waiter()); | 225 waiter_list.RemoveWaiter(thread1.waiter()); |
235 | 226 |
236 base::PlatformThread::Sleep( | 227 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); |
237 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros)); | |
238 | 228 |
239 test::SimpleWaiterThread thread3(&result3); | 229 test::SimpleWaiterThread thread3(&result3); |
240 waiter_list.AddWaiter(thread3.waiter(), MOJO_WAIT_FLAG_WRITABLE, 8); | 230 waiter_list.AddWaiter(thread3.waiter(), MOJO_WAIT_FLAG_WRITABLE, 8); |
241 thread3.Start(); | 231 thread3.Start(); |
242 | 232 |
243 test::SimpleWaiterThread thread4(&result4); | 233 test::SimpleWaiterThread thread4(&result4); |
244 waiter_list.AddWaiter(thread4.waiter(), MOJO_WAIT_FLAG_READABLE, 9); | 234 waiter_list.AddWaiter(thread4.waiter(), MOJO_WAIT_FLAG_READABLE, 9); |
245 thread4.Start(); | 235 thread4.Start(); |
246 | 236 |
247 base::PlatformThread::Sleep( | 237 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); |
248 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros)); | |
249 | 238 |
250 // Awake #2 and #3 for unsatisfiability. | 239 // Awake #2 and #3 for unsatisfiability. |
251 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE); | 240 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE); |
252 waiter_list.RemoveWaiter(thread2.waiter()); | 241 waiter_list.RemoveWaiter(thread2.waiter()); |
253 waiter_list.RemoveWaiter(thread3.waiter()); | 242 waiter_list.RemoveWaiter(thread3.waiter()); |
254 | 243 |
255 // Cancel #4. | 244 // Cancel #4. |
256 waiter_list.CancelAllWaiters(); | 245 waiter_list.CancelAllWaiters(); |
257 } // Join threads. | 246 } // Join threads. |
258 EXPECT_EQ(6, result1); | 247 EXPECT_EQ(6, result1); |
259 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); | 248 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); |
260 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3); | 249 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3); |
261 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4); | 250 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4); |
262 } | 251 } |
263 | 252 |
264 } // namespace | 253 } // namespace |
265 } // namespace system | 254 } // namespace system |
266 } // namespace mojo | 255 } // namespace mojo |
OLD | NEW |