OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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 // This file tests the C++ Mojo system core wrappers. | |
6 // TODO(vtl): Split this test into more reasonable units/files. | |
7 | |
8 #include <stddef.h> | |
9 | |
10 #include <map> | |
11 #include <vector> | |
12 | |
13 #include "mojo/public/cpp/system/buffer.h" | |
14 #include "mojo/public/cpp/system/data_pipe.h" | |
15 #include "mojo/public/cpp/system/handle.h" | |
16 #include "mojo/public/cpp/system/macros.h" | |
17 #include "mojo/public/cpp/system/message_pipe.h" | |
18 #include "mojo/public/cpp/system/time.h" | |
19 #include "mojo/public/cpp/system/wait.h" | |
20 #include "mojo/public/cpp/system/wait_set.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | |
22 | |
23 namespace mojo { | |
24 namespace { | |
25 | |
26 TEST(CoreTest, Basic) { | |
27 // |Wait|/|WaitMany|: | |
28 { | |
29 ScopedHandle h; | |
30 | |
31 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
32 Wait(h.get(), ~MOJO_HANDLE_SIGNAL_NONE, 1000000, nullptr)); | |
33 | |
34 std::vector<Handle> wh; | |
35 wh.push_back(h.get()); | |
36 std::vector<MojoHandleSignals> sigs; | |
37 sigs.push_back(~MOJO_HANDLE_SIGNAL_NONE); | |
38 WaitManyResult wait_many_result = | |
39 WaitMany(wh, sigs, MOJO_DEADLINE_INDEFINITE, nullptr); | |
40 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, wait_many_result.result); | |
41 EXPECT_TRUE(wait_many_result.IsIndexValid()); | |
42 EXPECT_FALSE(wait_many_result.AreSignalsStatesValid()); | |
43 | |
44 // Make sure that our specialized template correctly handles |NULL| as well | |
viettrungluu
2016/06/29 17:56:21
I got rid of this bit because of https://coderevie
| |
45 // as |nullptr|. | |
46 wait_many_result = WaitMany(wh, sigs, MOJO_DEADLINE_INDEFINITE, NULL); | |
47 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, wait_many_result.result); | |
48 EXPECT_EQ(0u, wait_many_result.index); | |
49 EXPECT_TRUE(wait_many_result.IsIndexValid()); | |
50 EXPECT_FALSE(wait_many_result.AreSignalsStatesValid()); | |
51 } | |
52 | |
53 // |MakeScopedHandle| (just compilation tests): | |
54 { | |
55 EXPECT_FALSE(MakeScopedHandle(MessagePipeHandle()).is_valid()); | |
56 EXPECT_FALSE(MakeScopedHandle(SharedBufferHandle()).is_valid()); | |
57 } | |
58 | |
59 // |MessagePipeHandle|/|ScopedMessagePipeHandle| functions: | |
60 { | |
61 MessagePipeHandle h_invalid; | |
62 EXPECT_FALSE(h_invalid.is_valid()); | |
63 EXPECT_EQ( | |
64 MOJO_RESULT_INVALID_ARGUMENT, | |
65 WriteMessageRaw( | |
66 h_invalid, nullptr, 0, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
67 char buffer[10] = {0}; | |
68 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
69 WriteMessageRaw(h_invalid, | |
70 buffer, | |
71 sizeof(buffer), | |
72 nullptr, | |
73 0, | |
74 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
75 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
76 ReadMessageRaw(h_invalid, | |
77 nullptr, | |
78 nullptr, | |
79 nullptr, | |
80 nullptr, | |
81 MOJO_READ_MESSAGE_FLAG_NONE)); | |
82 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
83 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
84 ReadMessageRaw(h_invalid, | |
85 buffer, | |
86 &buffer_size, | |
87 nullptr, | |
88 nullptr, | |
89 MOJO_READ_MESSAGE_FLAG_NONE)); | |
90 | |
91 // Basic tests of waiting and closing. | |
92 MojoHandle hv0 = kInvalidHandleValue; | |
93 { | |
94 ScopedMessagePipeHandle h0; | |
95 ScopedMessagePipeHandle h1; | |
96 EXPECT_FALSE(h0.get().is_valid()); | |
97 EXPECT_FALSE(h1.get().is_valid()); | |
98 | |
99 ASSERT_EQ(MOJO_RESULT_OK, CreateMessagePipe(nullptr, &h0, &h1)); | |
100 EXPECT_TRUE(h0.get().is_valid()); | |
101 EXPECT_TRUE(h1.get().is_valid()); | |
102 EXPECT_NE(h0.get().value(), h1.get().value()); | |
103 // Save the handle values, so we can check that things got closed | |
104 // correctly. | |
105 hv0 = h0.get().value(); | |
106 MojoHandle hv1 = h1.get().value(); | |
107 MojoHandleSignalsState state; | |
108 | |
109 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
110 Wait(h0.get(), MOJO_HANDLE_SIGNAL_READABLE, 0, &state)); | |
111 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals); | |
112 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE | | |
113 MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
114 state.satisfiable_signals); | |
115 | |
116 std::vector<Handle> wh; | |
117 wh.push_back(h0.get()); | |
118 wh.push_back(h1.get()); | |
119 std::vector<MojoHandleSignals> sigs; | |
120 sigs.push_back(MOJO_HANDLE_SIGNAL_READABLE); | |
121 sigs.push_back(MOJO_HANDLE_SIGNAL_WRITABLE); | |
122 std::vector<MojoHandleSignalsState> states(sigs.size()); | |
123 WaitManyResult wait_many_result = WaitMany(wh, sigs, 1000, &states); | |
124 EXPECT_EQ(MOJO_RESULT_OK, wait_many_result.result); | |
125 EXPECT_EQ(1u, wait_many_result.index); | |
126 EXPECT_TRUE(wait_many_result.IsIndexValid()); | |
127 EXPECT_TRUE(wait_many_result.AreSignalsStatesValid()); | |
128 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, states[0].satisfied_signals); | |
129 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE | | |
130 MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
131 states[0].satisfiable_signals); | |
132 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, states[1].satisfied_signals); | |
133 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE | | |
134 MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
135 states[1].satisfiable_signals); | |
136 | |
137 // Test closing |h1| explicitly. | |
138 Close(h1.Pass()); | |
139 EXPECT_FALSE(h1.get().is_valid()); | |
140 | |
141 // Make sure |h1| is closed. | |
142 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
143 Wait(Handle(hv1), ~MOJO_HANDLE_SIGNAL_NONE, | |
144 MOJO_DEADLINE_INDEFINITE, nullptr)); | |
145 | |
146 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
147 Wait(h0.get(), MOJO_HANDLE_SIGNAL_READABLE, | |
148 MOJO_DEADLINE_INDEFINITE, &state)); | |
149 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); | |
150 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); | |
151 } | |
152 // |hv0| should have been closed when |h0| went out of scope, so this close | |
153 // should fail. | |
154 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv0)); | |
155 | |
156 // Actually test writing/reading messages. | |
157 { | |
158 ScopedMessagePipeHandle h0; | |
159 ScopedMessagePipeHandle h1; | |
160 ASSERT_EQ(MOJO_RESULT_OK, CreateMessagePipe(nullptr, &h0, &h1)); | |
161 | |
162 const char kHello[] = "hello"; | |
163 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); | |
164 EXPECT_EQ(MOJO_RESULT_OK, | |
165 WriteMessageRaw(h0.get(), | |
166 kHello, | |
167 kHelloSize, | |
168 nullptr, | |
169 0, | |
170 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
171 | |
172 MojoHandleSignalsState state; | |
173 EXPECT_EQ(MOJO_RESULT_OK, Wait(h1.get(), MOJO_HANDLE_SIGNAL_READABLE, | |
174 MOJO_DEADLINE_INDEFINITE, &state)); | |
175 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
176 state.satisfied_signals); | |
177 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE | | |
178 MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
179 state.satisfiable_signals); | |
180 | |
181 char buffer[10] = {0}; | |
182 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
183 EXPECT_EQ(MOJO_RESULT_OK, | |
184 ReadMessageRaw(h1.get(), | |
185 buffer, | |
186 &buffer_size, | |
187 nullptr, | |
188 nullptr, | |
189 MOJO_READ_MESSAGE_FLAG_NONE)); | |
190 EXPECT_EQ(kHelloSize, buffer_size); | |
191 EXPECT_STREQ(kHello, buffer); | |
192 | |
193 // Send a handle over the previously-establish message pipe. Use the | |
194 // |MessagePipe| wrapper (to test it), which automatically creates a | |
195 // message pipe. | |
196 MessagePipe mp; | |
197 | |
198 // Write a message to |mp.handle0|, before we send |mp.handle1|. | |
199 const char kWorld[] = "world!"; | |
200 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); | |
201 EXPECT_EQ(MOJO_RESULT_OK, | |
202 WriteMessageRaw(mp.handle0.get(), | |
203 kWorld, | |
204 kWorldSize, | |
205 nullptr, | |
206 0, | |
207 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
208 | |
209 // Send |mp.handle1| over |h1| to |h0|. | |
210 MojoHandle handles[5]; | |
211 handles[0] = mp.handle1.release().value(); | |
212 EXPECT_NE(kInvalidHandleValue, handles[0]); | |
213 EXPECT_FALSE(mp.handle1.get().is_valid()); | |
214 uint32_t handles_count = 1; | |
215 EXPECT_EQ(MOJO_RESULT_OK, | |
216 WriteMessageRaw(h1.get(), | |
217 kHello, | |
218 kHelloSize, | |
219 handles, | |
220 handles_count, | |
221 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
222 // |handles[0]| should actually be invalid now. | |
223 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handles[0])); | |
224 | |
225 // Read "hello" and the sent handle. | |
226 EXPECT_EQ(MOJO_RESULT_OK, Wait(h0.get(), MOJO_HANDLE_SIGNAL_READABLE, | |
227 MOJO_DEADLINE_INDEFINITE, &state)); | |
228 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
229 state.satisfied_signals); | |
230 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE | | |
231 MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
232 state.satisfiable_signals); | |
233 | |
234 memset(buffer, 0, sizeof(buffer)); | |
235 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
236 for (size_t i = 0; i < MOJO_ARRAYSIZE(handles); i++) | |
237 handles[i] = kInvalidHandleValue; | |
238 handles_count = static_cast<uint32_t>(MOJO_ARRAYSIZE(handles)); | |
239 EXPECT_EQ(MOJO_RESULT_OK, | |
240 ReadMessageRaw(h0.get(), | |
241 buffer, | |
242 &buffer_size, | |
243 handles, | |
244 &handles_count, | |
245 MOJO_READ_MESSAGE_FLAG_NONE)); | |
246 EXPECT_EQ(kHelloSize, buffer_size); | |
247 EXPECT_STREQ(kHello, buffer); | |
248 EXPECT_EQ(1u, handles_count); | |
249 EXPECT_NE(kInvalidHandleValue, handles[0]); | |
250 | |
251 // Read from the sent/received handle. | |
252 mp.handle1.reset(MessagePipeHandle(handles[0])); | |
253 // Save |handles[0]| to check that it gets properly closed. | |
254 hv0 = handles[0]; | |
255 | |
256 EXPECT_EQ(MOJO_RESULT_OK, | |
257 Wait(mp.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE, | |
258 MOJO_DEADLINE_INDEFINITE, &state)); | |
259 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
260 state.satisfied_signals); | |
261 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE | | |
262 MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
263 state.satisfiable_signals); | |
264 | |
265 memset(buffer, 0, sizeof(buffer)); | |
266 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
267 for (size_t i = 0; i < MOJO_ARRAYSIZE(handles); i++) | |
268 handles[i] = kInvalidHandleValue; | |
269 handles_count = static_cast<uint32_t>(MOJO_ARRAYSIZE(handles)); | |
270 EXPECT_EQ(MOJO_RESULT_OK, | |
271 ReadMessageRaw(mp.handle1.get(), | |
272 buffer, | |
273 &buffer_size, | |
274 handles, | |
275 &handles_count, | |
276 MOJO_READ_MESSAGE_FLAG_NONE)); | |
277 EXPECT_EQ(kWorldSize, buffer_size); | |
278 EXPECT_STREQ(kWorld, buffer); | |
279 EXPECT_EQ(0u, handles_count); | |
280 } | |
281 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv0)); | |
282 } | |
283 | |
284 // TODO(vtl): Test |CloseRaw()|. | |
285 // TODO(vtl): Test |reset()| more thoroughly? | |
286 } | |
287 | |
288 TEST(CoreTest, TearDownWithMessagesEnqueued) { | |
289 // Tear down a message pipe which still has a message enqueued, with the | |
290 // message also having a valid message pipe handle. | |
291 { | |
292 ScopedMessagePipeHandle h0; | |
293 ScopedMessagePipeHandle h1; | |
294 ASSERT_EQ(MOJO_RESULT_OK, CreateMessagePipe(nullptr, &h0, &h1)); | |
295 | |
296 // Send a handle over the previously-establish message pipe. | |
297 ScopedMessagePipeHandle h2; | |
298 ScopedMessagePipeHandle h3; | |
299 ASSERT_EQ(MOJO_RESULT_OK, CreateMessagePipe(nullptr, &h2, &h3)); | |
300 | |
301 // Write a message to |h2|, before we send |h3|. | |
302 const char kWorld[] = "world!"; | |
303 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); | |
304 EXPECT_EQ(MOJO_RESULT_OK, | |
305 WriteMessageRaw(h2.get(), | |
306 kWorld, | |
307 kWorldSize, | |
308 nullptr, | |
309 0, | |
310 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
311 // And also a message to |h3|. | |
312 EXPECT_EQ(MOJO_RESULT_OK, | |
313 WriteMessageRaw(h3.get(), | |
314 kWorld, | |
315 kWorldSize, | |
316 nullptr, | |
317 0, | |
318 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
319 | |
320 // Send |h3| over |h1| to |h0|. | |
321 const char kHello[] = "hello"; | |
322 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); | |
323 MojoHandle h3_value; | |
324 h3_value = h3.release().value(); | |
325 EXPECT_NE(kInvalidHandleValue, h3_value); | |
326 EXPECT_FALSE(h3.get().is_valid()); | |
327 EXPECT_EQ(MOJO_RESULT_OK, | |
328 WriteMessageRaw(h1.get(), | |
329 kHello, | |
330 kHelloSize, | |
331 &h3_value, | |
332 1, | |
333 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
334 // |h3_value| should actually be invalid now. | |
335 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value)); | |
336 | |
337 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value())); | |
338 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value())); | |
339 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value())); | |
340 } | |
341 | |
342 // Do this in a different order: make the enqueued message pipe handle only | |
343 // half-alive. | |
344 { | |
345 ScopedMessagePipeHandle h0; | |
346 ScopedMessagePipeHandle h1; | |
347 ASSERT_EQ(MOJO_RESULT_OK, CreateMessagePipe(nullptr, &h0, &h1)); | |
348 | |
349 // Send a handle over the previously-establish message pipe. | |
350 ScopedMessagePipeHandle h2; | |
351 ScopedMessagePipeHandle h3; | |
352 ASSERT_EQ(MOJO_RESULT_OK, CreateMessagePipe(nullptr, &h2, &h3)); | |
353 | |
354 // Write a message to |h2|, before we send |h3|. | |
355 const char kWorld[] = "world!"; | |
356 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); | |
357 EXPECT_EQ(MOJO_RESULT_OK, | |
358 WriteMessageRaw(h2.get(), | |
359 kWorld, | |
360 kWorldSize, | |
361 nullptr, | |
362 0, | |
363 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
364 // And also a message to |h3|. | |
365 EXPECT_EQ(MOJO_RESULT_OK, | |
366 WriteMessageRaw(h3.get(), | |
367 kWorld, | |
368 kWorldSize, | |
369 nullptr, | |
370 0, | |
371 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
372 | |
373 // Send |h3| over |h1| to |h0|. | |
374 const char kHello[] = "hello"; | |
375 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); | |
376 MojoHandle h3_value; | |
377 h3_value = h3.release().value(); | |
378 EXPECT_NE(kInvalidHandleValue, h3_value); | |
379 EXPECT_FALSE(h3.get().is_valid()); | |
380 EXPECT_EQ(MOJO_RESULT_OK, | |
381 WriteMessageRaw(h1.get(), | |
382 kHello, | |
383 kHelloSize, | |
384 &h3_value, | |
385 1, | |
386 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
387 // |h3_value| should actually be invalid now. | |
388 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value)); | |
389 | |
390 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value())); | |
391 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value())); | |
392 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value())); | |
393 } | |
394 } | |
395 | |
396 TEST(CoreTest, WaitManyResult) { | |
397 { | |
398 WaitManyResult wmr(MOJO_RESULT_OK); | |
399 EXPECT_FALSE(wmr.IsIndexValid()); | |
400 EXPECT_TRUE(wmr.AreSignalsStatesValid()); | |
401 EXPECT_EQ(MOJO_RESULT_OK, wmr.result); | |
402 } | |
403 | |
404 { | |
405 WaitManyResult wmr(MOJO_RESULT_FAILED_PRECONDITION); | |
406 EXPECT_FALSE(wmr.IsIndexValid()); | |
407 EXPECT_TRUE(wmr.AreSignalsStatesValid()); | |
408 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, wmr.result); | |
409 } | |
410 | |
411 { | |
412 WaitManyResult wmr(MOJO_RESULT_INVALID_ARGUMENT); | |
413 EXPECT_FALSE(wmr.IsIndexValid()); | |
414 EXPECT_FALSE(wmr.AreSignalsStatesValid()); | |
415 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, wmr.result); | |
416 } | |
417 | |
418 // These should be like "invalid argument". | |
419 EXPECT_FALSE( | |
420 WaitManyResult(MOJO_RESULT_RESOURCE_EXHAUSTED).AreSignalsStatesValid()); | |
421 EXPECT_FALSE(WaitManyResult(MOJO_RESULT_BUSY).AreSignalsStatesValid()); | |
422 | |
423 { | |
424 WaitManyResult wmr(MOJO_RESULT_OK, 5u); | |
425 EXPECT_TRUE(wmr.IsIndexValid()); | |
426 EXPECT_TRUE(wmr.AreSignalsStatesValid()); | |
427 EXPECT_EQ(MOJO_RESULT_OK, wmr.result); | |
428 EXPECT_EQ(5u, wmr.index); | |
429 } | |
430 | |
431 { | |
432 WaitManyResult wmr(MOJO_RESULT_FAILED_PRECONDITION, 5u); | |
433 EXPECT_TRUE(wmr.IsIndexValid()); | |
434 EXPECT_TRUE(wmr.AreSignalsStatesValid()); | |
435 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, wmr.result); | |
436 EXPECT_EQ(5u, wmr.index); | |
437 } | |
438 } | |
439 | |
440 } // namespace | |
441 } // namespace mojo | |
OLD | NEW |