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 #include "mojo/edk/system/core.h"
6
7 #include <stdint.h>
8
9 #include <limits>
10
11 #include "base/bind.h"
12 #include "mojo/edk/embedder/embedder_internal.h"
13 #include "mojo/edk/system/awakable.h"
14 #include "mojo/edk/system/core_test_base.h"
15 #include "mojo/edk/system/test_utils.h"
16
17 #if defined(OS_WIN)
18 #include "base/win/windows_version.h"
19 #endif
20
21 namespace mojo {
22 namespace edk {
23 namespace {
24
25 const MojoHandleSignalsState kEmptyMojoHandleSignalsState = {0u, 0u};
26 const MojoHandleSignalsState kFullMojoHandleSignalsState = {~0u, ~0u};
27 const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE |
28 MOJO_HANDLE_SIGNAL_WRITABLE |
29 MOJO_HANDLE_SIGNAL_PEER_CLOSED;
30
31 using CoreTest = test::CoreTestBase;
32
TEST_F(CoreTest,GetTimeTicksNow)33 TEST_F(CoreTest, GetTimeTicksNow) {
34 const MojoTimeTicks start = core()->GetTimeTicksNow();
35 ASSERT_NE(static_cast<MojoTimeTicks>(0), start)
36 << "GetTimeTicksNow should return nonzero value";
37 test::Sleep(test::DeadlineFromMilliseconds(15));
38 const MojoTimeTicks finish = core()->GetTimeTicksNow();
39 // Allow for some fuzz in sleep.
40 ASSERT_GE((finish - start), static_cast<MojoTimeTicks>(8000))
41 << "Sleeping should result in increasing time ticks";
42 }
43
TEST_F(CoreTest,Basic)44 TEST_F(CoreTest, Basic) {
45 MockHandleInfo info;
46
47 ASSERT_EQ(0u, info.GetCtorCallCount());
48 MojoHandle h = CreateMockHandle(&info);
49 ASSERT_EQ(1u, info.GetCtorCallCount());
50 ASSERT_NE(h, MOJO_HANDLE_INVALID);
51
52 ASSERT_EQ(0u, info.GetWriteMessageCallCount());
53 ASSERT_EQ(MOJO_RESULT_OK,
54 core()->WriteMessage(h, nullptr, 0, nullptr, 0,
55 MOJO_WRITE_MESSAGE_FLAG_NONE));
56 ASSERT_EQ(1u, info.GetWriteMessageCallCount());
57
58 ASSERT_EQ(0u, info.GetReadMessageCallCount());
59 uint32_t num_bytes = 0;
60 ASSERT_EQ(
61 MOJO_RESULT_OK,
62 core()->ReadMessage(h, nullptr, &num_bytes, nullptr, nullptr,
63 MOJO_READ_MESSAGE_FLAG_NONE));
64 ASSERT_EQ(1u, info.GetReadMessageCallCount());
65 ASSERT_EQ(MOJO_RESULT_OK,
66 core()->ReadMessage(h, nullptr, nullptr, nullptr, nullptr,
67 MOJO_READ_MESSAGE_FLAG_NONE));
68 ASSERT_EQ(2u, info.GetReadMessageCallCount());
69
70 ASSERT_EQ(0u, info.GetWriteDataCallCount());
71 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
72 core()->WriteData(h, nullptr, nullptr, MOJO_WRITE_DATA_FLAG_NONE));
73 ASSERT_EQ(1u, info.GetWriteDataCallCount());
74
75 ASSERT_EQ(0u, info.GetBeginWriteDataCallCount());
76 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
77 core()->BeginWriteData(h, nullptr, nullptr,
78 MOJO_WRITE_DATA_FLAG_NONE));
79 ASSERT_EQ(1u, info.GetBeginWriteDataCallCount());
80
81 ASSERT_EQ(0u, info.GetEndWriteDataCallCount());
82 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndWriteData(h, 0));
83 ASSERT_EQ(1u, info.GetEndWriteDataCallCount());
84
85 ASSERT_EQ(0u, info.GetReadDataCallCount());
86 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
87 core()->ReadData(h, nullptr, nullptr, MOJO_READ_DATA_FLAG_NONE));
88 ASSERT_EQ(1u, info.GetReadDataCallCount());
89
90 ASSERT_EQ(0u, info.GetBeginReadDataCallCount());
91 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
92 core()->BeginReadData(h, nullptr, nullptr,
93 MOJO_READ_DATA_FLAG_NONE));
94 ASSERT_EQ(1u, info.GetBeginReadDataCallCount());
95
96 ASSERT_EQ(0u, info.GetEndReadDataCallCount());
97 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndReadData(h, 0));
98 ASSERT_EQ(1u, info.GetEndReadDataCallCount());
99
100 ASSERT_EQ(0u, info.GetAddAwakableCallCount());
101 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
102 core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE,
103 nullptr));
104 ASSERT_EQ(1u, info.GetAddAwakableCallCount());
105 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
106 core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 0, nullptr));
107 ASSERT_EQ(2u, info.GetAddAwakableCallCount());
108 MojoHandleSignalsState hss = kFullMojoHandleSignalsState;
109 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
110 core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE,
111 &hss));
112 ASSERT_EQ(3u, info.GetAddAwakableCallCount());
113 ASSERT_EQ(0u, hss.satisfied_signals);
114 ASSERT_EQ(0u, hss.satisfiable_signals);
115 ASSERT_EQ(
116 MOJO_RESULT_FAILED_PRECONDITION,
117 core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, nullptr));
118 ASSERT_EQ(4u, info.GetAddAwakableCallCount());
119 hss = kFullMojoHandleSignalsState;
120 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
121 core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, &hss));
122 ASSERT_EQ(5u, info.GetAddAwakableCallCount());
123 ASSERT_EQ(0u, hss.satisfied_signals);
124 ASSERT_EQ(0u, hss.satisfiable_signals);
125
126 MojoHandleSignals handle_signals = ~MOJO_HANDLE_SIGNAL_NONE;
127 ASSERT_EQ(
128 MOJO_RESULT_FAILED_PRECONDITION,
129 core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE,
130 nullptr, nullptr));
131 ASSERT_EQ(6u, info.GetAddAwakableCallCount());
132 uint32_t result_index = static_cast<uint32_t>(-1);
133 ASSERT_EQ(
134 MOJO_RESULT_FAILED_PRECONDITION,
135 core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE,
136 &result_index, nullptr));
137 ASSERT_EQ(7u, info.GetAddAwakableCallCount());
138 ASSERT_EQ(0u, result_index);
139 hss = kFullMojoHandleSignalsState;
140 ASSERT_EQ(
141 MOJO_RESULT_FAILED_PRECONDITION,
142 core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE,
143 nullptr, &hss));
144 ASSERT_EQ(8u, info.GetAddAwakableCallCount());
145 ASSERT_EQ(0u, hss.satisfied_signals);
146 ASSERT_EQ(0u, hss.satisfiable_signals);
147 result_index = static_cast<uint32_t>(-1);
148 hss = kFullMojoHandleSignalsState;
149 ASSERT_EQ(
150 MOJO_RESULT_FAILED_PRECONDITION,
151 core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE,
152 &result_index, &hss));
153 ASSERT_EQ(9u, info.GetAddAwakableCallCount());
154 ASSERT_EQ(0u, result_index);
155 ASSERT_EQ(0u, hss.satisfied_signals);
156 ASSERT_EQ(0u, hss.satisfiable_signals);
157
158 ASSERT_EQ(0u, info.GetDtorCallCount());
159 ASSERT_EQ(0u, info.GetCloseCallCount());
160 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
161 ASSERT_EQ(1u, info.GetCloseCallCount());
162 ASSERT_EQ(1u, info.GetDtorCallCount());
163
164 // No awakables should ever have ever been added.
165 ASSERT_EQ(0u, info.GetRemoveAwakableCallCount());
166 }
167
TEST_F(CoreTest,InvalidArguments)168 TEST_F(CoreTest, InvalidArguments) {
169 // |Close()|:
170 {
171 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(MOJO_HANDLE_INVALID));
172 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(10));
173 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(1000000000));
174
175 // Test a double-close.
176 MockHandleInfo info;
177 MojoHandle h = CreateMockHandle(&info);
178 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
179 ASSERT_EQ(1u, info.GetCloseCallCount());
180 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h));
181 ASSERT_EQ(1u, info.GetCloseCallCount());
182 }
183
184 // |Wait()|:
185 {
186 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
187 core()->Wait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE,
188 MOJO_DEADLINE_INDEFINITE, nullptr));
189 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
190 core()->Wait(10, ~MOJO_HANDLE_SIGNAL_NONE,
191 MOJO_DEADLINE_INDEFINITE, nullptr));
192
193 MojoHandleSignalsState hss = kFullMojoHandleSignalsState;
194 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
195 core()->Wait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE,
196 MOJO_DEADLINE_INDEFINITE, &hss));
197 // On invalid argument, it shouldn't modify the handle signals state.
198 ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
199 hss.satisfied_signals);
200 ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
201 hss.satisfiable_signals);
202 hss = kFullMojoHandleSignalsState;
203 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
204 core()->Wait(10, ~MOJO_HANDLE_SIGNAL_NONE,
205 MOJO_DEADLINE_INDEFINITE, &hss));
206 // On invalid argument, it shouldn't modify the handle signals state.
207 ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
208 hss.satisfied_signals);
209 ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
210 hss.satisfiable_signals);
211 }
212
213 // |WaitMany()|:
214 {
215 MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID};
216 MojoHandleSignals signals[2] = {~MOJO_HANDLE_SIGNAL_NONE,
217 ~MOJO_HANDLE_SIGNAL_NONE};
218 ASSERT_EQ(
219 MOJO_RESULT_INVALID_ARGUMENT,
220 core()->WaitMany(handles, signals, 0, MOJO_DEADLINE_INDEFINITE,
221 nullptr, nullptr));
222 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
223 core()->WaitMany(nullptr, signals, 0, MOJO_DEADLINE_INDEFINITE,
224 nullptr, nullptr));
225 // If |num_handles| is invalid, it should leave |result_index| and
226 // |signals_states| alone.
227 // (We use -1 internally; make sure that doesn't leak.)
228 uint32_t result_index = 123;
229 MojoHandleSignalsState hss = kFullMojoHandleSignalsState;
230 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
231 core()->WaitMany(nullptr, signals, 0, MOJO_DEADLINE_INDEFINITE,
232 &result_index, &hss));
233 ASSERT_EQ(123u, result_index);
234 ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
235 hss.satisfied_signals);
236 ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
237 hss.satisfiable_signals);
238
239 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
240 core()->WaitMany(handles, nullptr, 0, MOJO_DEADLINE_INDEFINITE,
241 nullptr, nullptr));
242 ASSERT_EQ(
243 MOJO_RESULT_INVALID_ARGUMENT,
244 core()->WaitMany(handles, signals, 1, MOJO_DEADLINE_INDEFINITE, nullptr,
245 nullptr));
246 // But if a handle is bad, then it should set |result_index| but still leave
247 // |signals_states| alone.
248 result_index = static_cast<uint32_t>(-1);
249 hss = kFullMojoHandleSignalsState;
250 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
251 core()->WaitMany(
252 handles, signals, 1, MOJO_DEADLINE_INDEFINITE, &result_index,
253 &hss));
254 ASSERT_EQ(0u, result_index);
255 ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
256 hss.satisfied_signals);
257 ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
258 hss.satisfiable_signals);
259
260 MockHandleInfo info[2];
261 handles[0] = CreateMockHandle(&info[0]);
262
263 result_index = static_cast<uint32_t>(-1);
264 hss = kFullMojoHandleSignalsState;
265 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
266 core()->WaitMany(
267 handles, signals, 1, MOJO_DEADLINE_INDEFINITE, &result_index,
268 &hss));
269 ASSERT_EQ(0u, result_index);
270 ASSERT_EQ(0u, hss.satisfied_signals);
271 ASSERT_EQ(0u, hss.satisfiable_signals);
272
273 // On invalid argument, it'll leave |signals_states| alone.
274 result_index = static_cast<uint32_t>(-1);
275 hss = kFullMojoHandleSignalsState;
276 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
277 core()->WaitMany(
278 handles, signals, 2, MOJO_DEADLINE_INDEFINITE, &result_index,
279 &hss));
280 ASSERT_EQ(1u, result_index);
281 ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
282 hss.satisfied_signals);
283 ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
284 hss.satisfiable_signals);
285 handles[1] = handles[0] + 1; // Invalid handle.
286 ASSERT_EQ(
287 MOJO_RESULT_INVALID_ARGUMENT,
288 core()->WaitMany(handles, signals, 2, MOJO_DEADLINE_INDEFINITE, nullptr,
289 nullptr));
290 handles[1] = CreateMockHandle(&info[1]);
291 ASSERT_EQ(
292 MOJO_RESULT_FAILED_PRECONDITION,
293 core()->WaitMany(handles, signals, 2, MOJO_DEADLINE_INDEFINITE, nullptr,
294 nullptr));
295
296 // TODO(vtl): Test one where we get "failed precondition" only for the
297 // second handle (and the first one is valid to wait on).
298
299 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(handles[0]));
300 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(handles[1]));
301 }
302
303 // |CreateMessagePipe()|: Nothing to check (apart from things that cause
304 // death).
305
306 // |WriteMessage()|:
307 // Only check arguments checked by |Core|, namely |handle|, |handles|, and
308 // |num_handles|.
309 {
310 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
311 core()->WriteMessage(MOJO_HANDLE_INVALID, nullptr, 0,
312 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
313
314 MockHandleInfo info;
315 MojoHandle h = CreateMockHandle(&info);
316 MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID};
317
318 // Huge handle count (implausibly big on some systems -- more than can be
319 // stored in a 32-bit address space).
320 // Note: This may return either |MOJO_RESULT_INVALID_ARGUMENT| or
321 // |MOJO_RESULT_RESOURCE_EXHAUSTED|, depending on whether it's plausible or
322 // not.
323 ASSERT_NE(
324 MOJO_RESULT_OK,
325 core()->WriteMessage(h, nullptr, 0, handles,
326 std::numeric_limits<uint32_t>::max(),
327 MOJO_WRITE_MESSAGE_FLAG_NONE));
328 ASSERT_EQ(0u, info.GetWriteMessageCallCount());
329
330 // Null |bytes| with non-zero message size.
331 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
332 core()->WriteMessage(h, nullptr, 1, nullptr, 0,
333 MOJO_WRITE_MESSAGE_FLAG_NONE));
334 ASSERT_EQ(0u, info.GetWriteMessageCallCount());
335
336 // Null |handles| with non-zero handle count.
337 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
338 core()->WriteMessage(h, nullptr, 0, nullptr, 1,
339 MOJO_WRITE_MESSAGE_FLAG_NONE));
340 ASSERT_EQ(0u, info.GetWriteMessageCallCount());
341
342 // Huge handle count (plausibly big).
343 ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
344 core()->WriteMessage(
345 h, nullptr, 0, handles,
346 std::numeric_limits<uint32_t>::max() / sizeof(handles[0]),
347 MOJO_WRITE_MESSAGE_FLAG_NONE));
348 ASSERT_EQ(0u, info.GetWriteMessageCallCount());
349
350 // Invalid handle in |handles|.
351 ASSERT_EQ(
352 MOJO_RESULT_INVALID_ARGUMENT,
353 core()->WriteMessage(h, nullptr, 0, handles, 1,
354 MOJO_WRITE_MESSAGE_FLAG_NONE));
355 ASSERT_EQ(0u, info.GetWriteMessageCallCount());
356
357 // Two invalid handles in |handles|.
358 ASSERT_EQ(
359 MOJO_RESULT_INVALID_ARGUMENT,
360 core()->WriteMessage(h, nullptr, 0, handles, 2,
361 MOJO_WRITE_MESSAGE_FLAG_NONE));
362 ASSERT_EQ(0u, info.GetWriteMessageCallCount());
363
364 // Can't send a handle over itself. Note that this will also cause |h| to be
365 // closed.
366 handles[0] = h;
367 ASSERT_EQ(
368 MOJO_RESULT_INVALID_ARGUMENT,
369 core()->WriteMessage(h, nullptr, 0, handles, 1,
370 MOJO_WRITE_MESSAGE_FLAG_NONE));
371 ASSERT_EQ(0u, info.GetWriteMessageCallCount());
372
373 h = CreateMockHandle(&info);
374
375 MockHandleInfo info2;
376
377 // This is "okay", but |MockDispatcher| doesn't implement it.
378 handles[0] = CreateMockHandle(&info2);
379 ASSERT_EQ(
380 MOJO_RESULT_UNIMPLEMENTED,
381 core()->WriteMessage(h, nullptr, 0, handles, 1,
382 MOJO_WRITE_MESSAGE_FLAG_NONE));
383 ASSERT_EQ(1u, info.GetWriteMessageCallCount());
384
385 // One of the |handles| is still invalid.
386 handles[0] = CreateMockHandle(&info2);
387 ASSERT_EQ(
388 MOJO_RESULT_INVALID_ARGUMENT,
389 core()->WriteMessage(h, nullptr, 0, handles, 2,
390 MOJO_WRITE_MESSAGE_FLAG_NONE));
391 ASSERT_EQ(1u, info.GetWriteMessageCallCount());
392
393 // One of the |handles| is the same as |h|. Both handles are closed.
394 handles[0] = CreateMockHandle(&info2);
395 handles[1] = h;
396 ASSERT_EQ(
397 MOJO_RESULT_INVALID_ARGUMENT,
398 core()->WriteMessage(h, nullptr, 0, handles, 2,
399 MOJO_WRITE_MESSAGE_FLAG_NONE));
400 ASSERT_EQ(1u, info.GetWriteMessageCallCount());
401
402 h = CreateMockHandle(&info);
403
404 // Can't send a handle twice in the same message.
405 handles[0] = CreateMockHandle(&info2);
406 handles[1] = handles[0];
407 ASSERT_EQ(
408 MOJO_RESULT_BUSY,
409 core()->WriteMessage(h, nullptr, 0, handles, 2,
410 MOJO_WRITE_MESSAGE_FLAG_NONE));
411 ASSERT_EQ(1u, info.GetWriteMessageCallCount());
412
413 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
414 }
415
416 // |ReadMessage()|:
417 // Only check arguments checked by |Core|, namely |handle|, |handles|, and
418 // |num_handles|.
419 {
420 ASSERT_EQ(
421 MOJO_RESULT_INVALID_ARGUMENT,
422 core()->ReadMessage(MOJO_HANDLE_INVALID, nullptr, nullptr, nullptr,
423 nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
424
425 MockHandleInfo info;
426 MojoHandle h = CreateMockHandle(&info);
427
428 // Okay.
429 uint32_t handle_count = 0;
430 ASSERT_EQ(MOJO_RESULT_OK,
431 core()->ReadMessage(
432 h, nullptr, nullptr, nullptr, &handle_count,
433 MOJO_READ_MESSAGE_FLAG_NONE));
434 // Checked by |Core|, shouldn't go through to the dispatcher.
435 ASSERT_EQ(1u, info.GetReadMessageCallCount());
436
437 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
438 }
439 }
440
441 // These test invalid arguments that should cause death if we're being paranoid
442 // about checking arguments (which we would want to do if, e.g., we were in a
443 // true "kernel" situation, but we might not want to do otherwise for
444 // performance reasons). Probably blatant errors like passing in null pointers
445 // (for required pointer arguments) will still cause death, but perhaps not
446 // predictably.
TEST_F(CoreTest,InvalidArgumentsDeath)447 TEST_F(CoreTest, InvalidArgumentsDeath) {
448 #if defined(OFFICIAL_BUILD)
449 const char kMemoryCheckFailedRegex[] = "";
450 #else
451 const char kMemoryCheckFailedRegex[] = "Check failed";
452 #endif
453
454 // |WaitMany()|:
455 {
456 MojoHandle handle = MOJO_HANDLE_INVALID;
457 MojoHandleSignals signals = ~MOJO_HANDLE_SIGNAL_NONE;
458 ASSERT_DEATH_IF_SUPPORTED(
459 core()->WaitMany(nullptr, &signals, 1, MOJO_DEADLINE_INDEFINITE,
460 nullptr, nullptr),
461 kMemoryCheckFailedRegex);
462 ASSERT_DEATH_IF_SUPPORTED(
463 core()->WaitMany(&handle, nullptr, 1, MOJO_DEADLINE_INDEFINITE, nullptr,
464 nullptr),
465 kMemoryCheckFailedRegex);
466 // TODO(vtl): |result_index| and |signals_states| are optional. Test them
467 // with non-null invalid pointers?
468 }
469
470 // |CreateMessagePipe()|:
471 {
472 MojoHandle h;
473 ASSERT_DEATH_IF_SUPPORTED(
474 core()->CreateMessagePipe(nullptr, nullptr, nullptr),
475 kMemoryCheckFailedRegex);
476 ASSERT_DEATH_IF_SUPPORTED(
477 core()->CreateMessagePipe(nullptr, &h, nullptr),
478 kMemoryCheckFailedRegex);
479 ASSERT_DEATH_IF_SUPPORTED(
480 core()->CreateMessagePipe(nullptr, nullptr, &h),
481 kMemoryCheckFailedRegex);
482 }
483
484 // |ReadMessage()|:
485 // Only check arguments checked by |Core|, namely |handle|, |handles|, and
486 // |num_handles|.
487 {
488 MockHandleInfo info;
489 MojoHandle h = CreateMockHandle(&info);
490
491 uint32_t handle_count = 1;
492 ASSERT_DEATH_IF_SUPPORTED(
493 core()->ReadMessage(h, nullptr, nullptr, nullptr, &handle_count,
494 MOJO_READ_MESSAGE_FLAG_NONE),
495 kMemoryCheckFailedRegex);
496
497 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
498 }
499 }
500
501 // TODO(vtl): test |Wait()| and |WaitMany()| properly
502 // - including |WaitMany()| with the same handle more than once (with
503 // same/different signals)
504
TEST_F(CoreTest,MessagePipe)505 TEST_F(CoreTest, MessagePipe) {
506 MojoHandle h[2];
507 MojoHandleSignalsState hss[2];
508 uint32_t result_index;
509
510 ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h[0], &h[1]));
511 // Should get two distinct, valid handles.
512 ASSERT_NE(h[0], MOJO_HANDLE_INVALID);
513 ASSERT_NE(h[1], MOJO_HANDLE_INVALID);
514 ASSERT_NE(h[0], h[1]);
515
516 // Neither should be readable.
517 MojoHandleSignals signals[2] = {MOJO_HANDLE_SIGNAL_READABLE,
518 MOJO_HANDLE_SIGNAL_READABLE};
519 result_index = static_cast<uint32_t>(-1);
520 hss[0] = kEmptyMojoHandleSignalsState;
521 hss[1] = kEmptyMojoHandleSignalsState;
522 ASSERT_EQ(
523 MOJO_RESULT_DEADLINE_EXCEEDED,
524 core()->WaitMany(h, signals, 2, 0, &result_index, hss));
525 ASSERT_EQ(static_cast<uint32_t>(-1), result_index);
526 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
527 ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
528 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals);
529 ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals);
530
531 // Try to read anyway.
532 char buffer[1] = {'a'};
533 uint32_t buffer_size = 1;
534 ASSERT_EQ(
535 MOJO_RESULT_SHOULD_WAIT,
536 core()->ReadMessage(h[0], buffer, &buffer_size, nullptr, nullptr,
537 MOJO_READ_MESSAGE_FLAG_NONE));
538 // Check that it left its inputs alone.
539 ASSERT_EQ('a', buffer[0]);
540 ASSERT_EQ(1u, buffer_size);
541
542 // Both should be writable.
543 hss[0] = kEmptyMojoHandleSignalsState;
544 ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[0], MOJO_HANDLE_SIGNAL_WRITABLE,
545 1000000000, &hss[0]));
546 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
547 ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
548 hss[0] = kEmptyMojoHandleSignalsState;
549 ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_WRITABLE,
550 1000000000, &hss[0]));
551 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
552 ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
553
554 // Also check that |h[1]| is writable using |WaitMany()|.
555 signals[0] = MOJO_HANDLE_SIGNAL_READABLE;
556 signals[1] = MOJO_HANDLE_SIGNAL_WRITABLE;
557 result_index = static_cast<uint32_t>(-1);
558 hss[0] = kEmptyMojoHandleSignalsState;
559 hss[1] = kEmptyMojoHandleSignalsState;
560 ASSERT_EQ(
561 MOJO_RESULT_OK,
562 core()->WaitMany(h, signals, 2, MOJO_DEADLINE_INDEFINITE, &result_index,
563 hss));
564 ASSERT_EQ(1u, result_index);
565 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
566 ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
567 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals);
568 ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals);
569
570 // Write to |h[1]|.
571 buffer[0] = 'b';
572 ASSERT_EQ(
573 MOJO_RESULT_OK,
574 core()->WriteMessage(h[1], buffer, 1, nullptr, 0,
575 MOJO_WRITE_MESSAGE_FLAG_NONE));
576
577 // Check that |h[0]| is now readable.
578 signals[0] = MOJO_HANDLE_SIGNAL_READABLE;
579 signals[1] = MOJO_HANDLE_SIGNAL_READABLE;
580 result_index = static_cast<uint32_t>(-1);
581 hss[0] = kEmptyMojoHandleSignalsState;
582 hss[1] = kEmptyMojoHandleSignalsState;
583 ASSERT_EQ(
584 MOJO_RESULT_OK,
585 core()->WaitMany(h, signals, 2, MOJO_DEADLINE_INDEFINITE, &result_index,
586 hss));
587 ASSERT_EQ(0u, result_index);
588 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
589 hss[0].satisfied_signals);
590 ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
591 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals);
592 ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals);
593
594 // Read from |h[0]|.
595 // First, get only the size.
596 buffer_size = 0;
597 ASSERT_EQ(
598 MOJO_RESULT_RESOURCE_EXHAUSTED,
599 core()->ReadMessage(h[0], nullptr, &buffer_size, nullptr, nullptr,
600 MOJO_READ_MESSAGE_FLAG_NONE));
601 ASSERT_EQ(1u, buffer_size);
602 // Then actually read it.
603 buffer[0] = 'c';
604 buffer_size = 1;
605 ASSERT_EQ(
606 MOJO_RESULT_OK,
607 core()->ReadMessage(h[0], buffer, &buffer_size, nullptr, nullptr,
608 MOJO_READ_MESSAGE_FLAG_NONE));
609 ASSERT_EQ('b', buffer[0]);
610 ASSERT_EQ(1u, buffer_size);
611
612 // |h[0]| should no longer be readable.
613 hss[0] = kEmptyMojoHandleSignalsState;
614 ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
615 core()->Wait(h[0], MOJO_HANDLE_SIGNAL_READABLE, 0, &hss[0]));
616 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
617 ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
618
619 // Write to |h[0]|.
620 buffer[0] = 'd';
621 ASSERT_EQ(
622 MOJO_RESULT_OK,
623 core()->WriteMessage(h[0], buffer, 1, nullptr, 0,
624 MOJO_WRITE_MESSAGE_FLAG_NONE));
625
626 // Close |h[0]|.
627 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[0]));
628
629 // Wait for |h[1]| to learn about the other end's closure.
630 ASSERT_EQ(MOJO_RESULT_OK,
631 core()->Wait(h[1], MOJO_HANDLE_SIGNAL_PEER_CLOSED, 1000000000,
632 &hss[0]));
633
634 // Check that |h[1]| is no longer writable (and will never be).
635 hss[0] = kEmptyMojoHandleSignalsState;
636 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
637 core()->Wait(h[1], MOJO_HANDLE_SIGNAL_WRITABLE, 1000000000,
638 &hss[0]));
639 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
640 hss[0].satisfied_signals);
641 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
642 hss[0].satisfiable_signals);
643
644 // Check that |h[1]| is still readable (for the moment).
645 hss[0] = kEmptyMojoHandleSignalsState;
646 ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_READABLE,
647 1000000000, &hss[0]));
648 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
649 hss[0].satisfied_signals);
650 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
651 hss[0].satisfiable_signals);
652
653 // Discard a message from |h[1]|.
654 ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
655 core()->ReadMessage(h[1], nullptr, nullptr, nullptr, nullptr,
656 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
657
658 // |h[1]| is no longer readable (and will never be).
659 hss[0] = kFullMojoHandleSignalsState;
660 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
661 core()->Wait(h[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
662 &hss[0]));
663 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfied_signals);
664 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfiable_signals);
665
666 // Try writing to |h[1]|.
667 buffer[0] = 'e';
668 ASSERT_EQ(
669 MOJO_RESULT_FAILED_PRECONDITION,
670 core()->WriteMessage(h[1], buffer, 1, nullptr, 0,
671 MOJO_WRITE_MESSAGE_FLAG_NONE));
672
673 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[1]));
674 }
675
676 // Tests passing a message pipe handle.
TEST_F(CoreTest,MessagePipeBasicLocalHandlePassing1)677 TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing1) {
678 const char kHello[] = "hello";
679 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
680 const char kWorld[] = "world!!!";
681 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
682 char buffer[100];
683 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
684 uint32_t num_bytes;
685 MojoHandle handles[10];
686 uint32_t num_handles;
687 MojoHandleSignalsState hss;
688 MojoHandle h_received;
689
690 MojoHandle h_passing[2];
691 ASSERT_EQ(MOJO_RESULT_OK,
692 core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
693
694 // Make sure that |h_passing[]| work properly.
695 ASSERT_EQ(MOJO_RESULT_OK,
696 core()->WriteMessage(h_passing[0], kHello, kHelloSize, nullptr, 0,
697 MOJO_WRITE_MESSAGE_FLAG_NONE));
698 hss = kEmptyMojoHandleSignalsState;
699 ASSERT_EQ(MOJO_RESULT_OK,
700 core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
701 &hss));
702 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
703 hss.satisfied_signals);
704 ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
705 num_bytes = kBufferSize;
706 num_handles = arraysize(handles);
707 ASSERT_EQ(MOJO_RESULT_OK,
708 core()->ReadMessage(
709 h_passing[1], buffer, &num_bytes, handles, &num_handles,
710 MOJO_READ_MESSAGE_FLAG_NONE));
711 ASSERT_EQ(kHelloSize, num_bytes);
712 ASSERT_STREQ(kHello, buffer);
713 ASSERT_EQ(0u, num_handles);
714
715 // Make sure that you can't pass either of the message pipe's handles over
716 // itself.
717 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
718 core()->WriteMessage(h_passing[0], kHello, kHelloSize,
719 &h_passing[0], 1,
720 MOJO_WRITE_MESSAGE_FLAG_NONE));
721 ASSERT_EQ(MOJO_RESULT_OK,
722 core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
723
724 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
725 core()->WriteMessage(h_passing[0], kHello, kHelloSize,
726 &h_passing[1], 1,
727 MOJO_WRITE_MESSAGE_FLAG_NONE));
728 ASSERT_EQ(MOJO_RESULT_OK,
729 core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
730
731 MojoHandle h_passed[2];
732 ASSERT_EQ(MOJO_RESULT_OK,
733 core()->CreateMessagePipe(nullptr, &h_passed[0], &h_passed[1]));
734
735 // Make sure that |h_passed[]| work properly.
736 ASSERT_EQ(MOJO_RESULT_OK,
737 core()->WriteMessage(h_passed[0], kHello, kHelloSize, nullptr, 0,
738 MOJO_WRITE_MESSAGE_FLAG_NONE));
739 hss = kEmptyMojoHandleSignalsState;
740 ASSERT_EQ(MOJO_RESULT_OK,
741 core()->Wait(h_passed[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
742 &hss));
743 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
744 hss.satisfied_signals);
745 ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
746 num_bytes = kBufferSize;
747 num_handles = arraysize(handles);
748 ASSERT_EQ(MOJO_RESULT_OK,
749 core()->ReadMessage(
750 h_passed[1], buffer, &num_bytes, handles, &num_handles,
751 MOJO_READ_MESSAGE_FLAG_NONE));
752 ASSERT_EQ(kHelloSize, num_bytes);
753 ASSERT_STREQ(kHello, buffer);
754 ASSERT_EQ(0u, num_handles);
755
756 // Send |h_passed[1]| from |h_passing[0]| to |h_passing[1]|.
757 ASSERT_EQ(MOJO_RESULT_OK,
758 core()->WriteMessage(h_passing[0], kWorld, kWorldSize,
759 &h_passed[1], 1,
760 MOJO_WRITE_MESSAGE_FLAG_NONE));
761 hss = kEmptyMojoHandleSignalsState;
762 ASSERT_EQ(MOJO_RESULT_OK,
763 core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
764 &hss));
765 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
766 hss.satisfied_signals);
767 ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
768 num_bytes = kBufferSize;
769 num_handles = arraysize(handles);
770 ASSERT_EQ(MOJO_RESULT_OK,
771 core()->ReadMessage(
772 h_passing[1], buffer, &num_bytes, handles, &num_handles,
773 MOJO_READ_MESSAGE_FLAG_NONE));
774 ASSERT_EQ(kWorldSize, num_bytes);
775 ASSERT_STREQ(kWorld, buffer);
776 ASSERT_EQ(1u, num_handles);
777 h_received = handles[0];
778 ASSERT_NE(h_received, MOJO_HANDLE_INVALID);
779 ASSERT_NE(h_received, h_passing[0]);
780 ASSERT_NE(h_received, h_passing[1]);
781 ASSERT_NE(h_received, h_passed[0]);
782
783 // Note: We rely on the Mojo system not re-using handle values very often.
784 ASSERT_NE(h_received, h_passed[1]);
785
786 // |h_passed[1]| should no longer be valid; check that trying to close it
787 // fails. See above note.
788 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h_passed[1]));
789
790 // Write to |h_passed[0]|. Should receive on |h_received|.
791 ASSERT_EQ(MOJO_RESULT_OK,
792 core()->WriteMessage(h_passed[0], kHello, kHelloSize, nullptr, 0,
793 MOJO_WRITE_MESSAGE_FLAG_NONE));
794 hss = kEmptyMojoHandleSignalsState;
795 ASSERT_EQ(MOJO_RESULT_OK,
796 core()->Wait(h_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
797 &hss));
798 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
799 hss.satisfied_signals);
800 ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
801 num_bytes = kBufferSize;
802 num_handles = arraysize(handles);
803 ASSERT_EQ(MOJO_RESULT_OK,
804 core()->ReadMessage(
805 h_received, buffer, &num_bytes, handles, &num_handles,
806 MOJO_READ_MESSAGE_FLAG_NONE));
807 ASSERT_EQ(kHelloSize, num_bytes);
808 ASSERT_STREQ(kHello, buffer);
809 ASSERT_EQ(0u, num_handles);
810
811 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0]));
812 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1]));
813 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passed[0]));
814 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_received));
815 }
816
TEST_F(CoreTest,DataPipe)817 TEST_F(CoreTest, DataPipe) {
818 MojoHandle ph, ch; // p is for producer and c is for consumer.
819 MojoHandleSignalsState hss;
820
821 ASSERT_EQ(MOJO_RESULT_OK,
822 core()->CreateDataPipe(nullptr, &ph, &ch));
823 // Should get two distinct, valid handles.
824 ASSERT_NE(ph, MOJO_HANDLE_INVALID);
825 ASSERT_NE(ch, MOJO_HANDLE_INVALID);
826 ASSERT_NE(ph, ch);
827
828 // Producer should be never-readable, but already writable.
829 hss = kEmptyMojoHandleSignalsState;
830 ASSERT_EQ(
831 MOJO_RESULT_FAILED_PRECONDITION,
832 core()->Wait(ph, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
833 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
834 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
835 hss.satisfiable_signals);
836 hss = kEmptyMojoHandleSignalsState;
837 ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ph, MOJO_HANDLE_SIGNAL_WRITABLE, 0,
838 &hss));
839 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
840 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
841 hss.satisfiable_signals);
842
843 // Consumer should be never-writable, and not yet readable.
844 hss = kFullMojoHandleSignalsState;
845 ASSERT_EQ(
846 MOJO_RESULT_FAILED_PRECONDITION,
847 core()->Wait(ch, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
848 ASSERT_EQ(0u, hss.satisfied_signals);
849 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
850 hss.satisfiable_signals);
851 hss = kFullMojoHandleSignalsState;
852 ASSERT_EQ(
853 MOJO_RESULT_DEADLINE_EXCEEDED,
854 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
855 ASSERT_EQ(0u, hss.satisfied_signals);
856 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
857 hss.satisfiable_signals);
858
859 // Write.
860 signed char elements[2] = {'A', 'B'};
861 uint32_t num_bytes = 2u;
862 ASSERT_EQ(MOJO_RESULT_OK,
863 core()->WriteData(ph, elements, &num_bytes,
864 MOJO_WRITE_DATA_FLAG_NONE));
865 ASSERT_EQ(2u, num_bytes);
866
867 // Wait for the data to arrive to the consumer.
868 ASSERT_EQ(MOJO_RESULT_OK,
869 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss));
870
871 // Consumer should now be readable.
872 hss = kEmptyMojoHandleSignalsState;
873 ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0,
874 &hss));
875 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
876 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
877 hss.satisfiable_signals);
878
879 // Peek one character.
880 elements[0] = -1;
881 elements[1] = -1;
882 num_bytes = 1u;
883 ASSERT_EQ(MOJO_RESULT_OK,
884 core()->ReadData(
885 ch, elements, &num_bytes,
886 MOJO_READ_DATA_FLAG_NONE | MOJO_READ_DATA_FLAG_PEEK));
887 ASSERT_EQ('A', elements[0]);
888 ASSERT_EQ(-1, elements[1]);
889
890 // Read one character.
891 elements[0] = -1;
892 elements[1] = -1;
893 num_bytes = 1u;
894 ASSERT_EQ(MOJO_RESULT_OK, core()->ReadData(ch, elements, &num_bytes,
895 MOJO_READ_DATA_FLAG_NONE));
896 ASSERT_EQ('A', elements[0]);
897 ASSERT_EQ(-1, elements[1]);
898
899 // Two-phase write.
900 void* write_ptr = nullptr;
901 num_bytes = 0u;
902 ASSERT_EQ(MOJO_RESULT_OK,
903 core()->BeginWriteData(ph, &write_ptr, &num_bytes,
904 MOJO_WRITE_DATA_FLAG_NONE));
905 // We count on the default options providing a decent buffer size.
906 ASSERT_GE(num_bytes, 3u);
907
908 // Trying to do a normal write during a two-phase write should fail.
909 elements[0] = 'X';
910 num_bytes = 1u;
911 ASSERT_EQ(MOJO_RESULT_BUSY,
912 core()->WriteData(ph, elements, &num_bytes,
913 MOJO_WRITE_DATA_FLAG_NONE));
914
915 // Actually write the data, and complete it now.
916 static_cast<char*>(write_ptr)[0] = 'C';
917 static_cast<char*>(write_ptr)[1] = 'D';
918 static_cast<char*>(write_ptr)[2] = 'E';
919 ASSERT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 3u));
920
921 // Wait for the data to arrive to the consumer.
922 ASSERT_EQ(MOJO_RESULT_OK,
923 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss));
924
925 // Query how much data we have.
926 num_bytes = 0;
927 ASSERT_EQ(MOJO_RESULT_OK,
928 core()->ReadData(ch, nullptr, &num_bytes,
929 MOJO_READ_DATA_FLAG_QUERY));
930 ASSERT_GE(num_bytes, 1u);
931
932 // Try to query with peek. Should fail.
933 num_bytes = 0;
934 ASSERT_EQ(
935 MOJO_RESULT_INVALID_ARGUMENT,
936 core()->ReadData(ch, nullptr, &num_bytes,
937 MOJO_READ_DATA_FLAG_QUERY | MOJO_READ_DATA_FLAG_PEEK));
938 ASSERT_EQ(0u, num_bytes);
939
940 // Try to discard ten characters, in all-or-none mode. Should fail.
941 num_bytes = 10;
942 ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE,
943 core()->ReadData(
944 ch, nullptr, &num_bytes,
945 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE));
946
947 // Try to discard two characters, in peek mode. Should fail.
948 num_bytes = 2;
949 ASSERT_EQ(
950 MOJO_RESULT_INVALID_ARGUMENT,
951 core()->ReadData(ch, nullptr, &num_bytes,
952 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_PEEK));
953
954 // Discard a character.
955 num_bytes = 1;
956 ASSERT_EQ(MOJO_RESULT_OK,
957 core()->ReadData(
958 ch, nullptr, &num_bytes,
959 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE));
960
961 // Ensure the 3 bytes were read.
962 ASSERT_EQ(MOJO_RESULT_OK,
963 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss));
964
965 // Try a two-phase read of the remaining three bytes with peek. Should fail.
966 const void* read_ptr = nullptr;
967 num_bytes = 3;
968 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
969 core()->BeginReadData(ch, &read_ptr, &num_bytes,
970 MOJO_READ_DATA_FLAG_PEEK));
971
972 // Read the remaining two characters, in two-phase mode (all-or-none).
973 num_bytes = 3;
974 ASSERT_EQ(MOJO_RESULT_OK,
975 core()->BeginReadData(ch, &read_ptr, &num_bytes,
976 MOJO_READ_DATA_FLAG_ALL_OR_NONE));
977 // Note: Count on still being able to do the contiguous read here.
978 ASSERT_EQ(3u, num_bytes);
979
980 // Discarding right now should fail.
981 num_bytes = 1;
982 ASSERT_EQ(MOJO_RESULT_BUSY,
983 core()->ReadData(ch, nullptr, &num_bytes,
984 MOJO_READ_DATA_FLAG_DISCARD));
985
986 // Actually check our data and end the two-phase read.
987 ASSERT_EQ('C', static_cast<const char*>(read_ptr)[0]);
988 ASSERT_EQ('D', static_cast<const char*>(read_ptr)[1]);
989 ASSERT_EQ('E', static_cast<const char*>(read_ptr)[2]);
990 ASSERT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 3u));
991
992 // Consumer should now be no longer readable.
993 hss = kFullMojoHandleSignalsState;
994 ASSERT_EQ(
995 MOJO_RESULT_DEADLINE_EXCEEDED,
996 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
997 ASSERT_EQ(0u, hss.satisfied_signals);
998 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
999 hss.satisfiable_signals);
1000
1001 // TODO(vtl): More.
1002
1003 // Close the producer.
1004 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ph));
1005
1006 // Wait for this to get to the consumer.
1007 ASSERT_EQ(MOJO_RESULT_OK,
1008 core()->Wait(ch, MOJO_HANDLE_SIGNAL_PEER_CLOSED, 1000000000, &hss));
1009
1010 // The consumer should now be never-readable.
1011 hss = kFullMojoHandleSignalsState;
1012 ASSERT_EQ(
1013 MOJO_RESULT_FAILED_PRECONDITION,
1014 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
1015 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
1016 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
1017
1018 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ch));
1019 }
1020
1021 // Tests passing data pipe producer and consumer handles.
TEST_F(CoreTest,MessagePipeBasicLocalHandlePassing2)1022 TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing2) {
1023 const char kHello[] = "hello";
1024 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
1025 const char kWorld[] = "world!!!";
1026 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
1027 char buffer[100];
1028 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
1029 uint32_t num_bytes;
1030 MojoHandle handles[10];
1031 uint32_t num_handles;
1032 MojoHandleSignalsState hss;
1033
1034 MojoHandle h_passing[2];
1035 ASSERT_EQ(MOJO_RESULT_OK,
1036 core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
1037
1038 MojoHandle ph, ch;
1039 ASSERT_EQ(MOJO_RESULT_OK,
1040 core()->CreateDataPipe(nullptr, &ph, &ch));
1041
1042 // Send |ch| from |h_passing[0]| to |h_passing[1]|.
1043 ASSERT_EQ(MOJO_RESULT_OK,
1044 core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ch, 1,
1045 MOJO_WRITE_MESSAGE_FLAG_NONE));
1046 hss = kEmptyMojoHandleSignalsState;
1047 ASSERT_EQ(MOJO_RESULT_OK,
1048 core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1049 &hss));
1050 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1051 hss.satisfied_signals);
1052 ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
1053 num_bytes = kBufferSize;
1054 num_handles = arraysize(handles);
1055 ASSERT_EQ(MOJO_RESULT_OK,
1056 core()->ReadMessage(
1057 h_passing[1], buffer, &num_bytes, handles, &num_handles,
1058 MOJO_READ_MESSAGE_FLAG_NONE));
1059 ASSERT_EQ(kHelloSize, num_bytes);
1060 ASSERT_STREQ(kHello, buffer);
1061 ASSERT_EQ(1u, num_handles);
1062 MojoHandle ch_received = handles[0];
1063 ASSERT_NE(ch_received, MOJO_HANDLE_INVALID);
1064 ASSERT_NE(ch_received, h_passing[0]);
1065 ASSERT_NE(ch_received, h_passing[1]);
1066 ASSERT_NE(ch_received, ph);
1067
1068 // Note: We rely on the Mojo system not re-using handle values very often.
1069 ASSERT_NE(ch_received, ch);
1070
1071 // |ch| should no longer be valid; check that trying to close it fails. See
1072 // above note.
1073 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ch));
1074
1075 // Write to |ph|. Should receive on |ch_received|.
1076 num_bytes = kWorldSize;
1077 ASSERT_EQ(MOJO_RESULT_OK,
1078 core()->WriteData(ph, kWorld, &num_bytes,
1079 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
1080 hss = kEmptyMojoHandleSignalsState;
1081 ASSERT_EQ(MOJO_RESULT_OK,
1082 core()->Wait(ch_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1083 &hss));
1084 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
1085 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
1086 hss.satisfiable_signals);
1087 num_bytes = kBufferSize;
1088 ASSERT_EQ(MOJO_RESULT_OK,
1089 core()->ReadData(ch_received, buffer, &num_bytes,
1090 MOJO_READ_MESSAGE_FLAG_NONE));
1091 ASSERT_EQ(kWorldSize, num_bytes);
1092 ASSERT_STREQ(kWorld, buffer);
1093
1094 // Now pass |ph| in the same direction.
1095 ASSERT_EQ(MOJO_RESULT_OK,
1096 core()->WriteMessage(h_passing[0], kWorld, kWorldSize, &ph, 1,
1097 MOJO_WRITE_MESSAGE_FLAG_NONE));
1098 hss = kEmptyMojoHandleSignalsState;
1099 ASSERT_EQ(MOJO_RESULT_OK,
1100 core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1101 &hss));
1102 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1103 hss.satisfied_signals);
1104 ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
1105 num_bytes = kBufferSize;
1106 num_handles = arraysize(handles);
1107 ASSERT_EQ(MOJO_RESULT_OK,
1108 core()->ReadMessage(
1109 h_passing[1], buffer, &num_bytes, handles, &num_handles,
1110 MOJO_READ_MESSAGE_FLAG_NONE));
1111 ASSERT_EQ(kWorldSize, num_bytes);
1112 ASSERT_STREQ(kWorld, buffer);
1113 ASSERT_EQ(1u, num_handles);
1114 MojoHandle ph_received = handles[0];
1115 ASSERT_NE(ph_received, MOJO_HANDLE_INVALID);
1116 ASSERT_NE(ph_received, h_passing[0]);
1117 ASSERT_NE(ph_received, h_passing[1]);
1118 ASSERT_NE(ph_received, ch_received);
1119
1120 // Again, rely on the Mojo system not re-using handle values very often.
1121 ASSERT_NE(ph_received, ph);
1122
1123 // |ph| should no longer be valid; check that trying to close it fails. See
1124 // above note.
1125 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ph));
1126
1127 // Write to |ph_received|. Should receive on |ch_received|.
1128 num_bytes = kHelloSize;
1129 ASSERT_EQ(MOJO_RESULT_OK,
1130 core()->WriteData(ph_received, kHello, &num_bytes,
1131 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
1132 hss = kEmptyMojoHandleSignalsState;
1133 ASSERT_EQ(MOJO_RESULT_OK,
1134 core()->Wait(ch_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1135 &hss));
1136 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
1137 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
1138 hss.satisfiable_signals);
1139 num_bytes = kBufferSize;
1140 ASSERT_EQ(MOJO_RESULT_OK,
1141 core()->ReadData(ch_received, buffer, &num_bytes,
1142 MOJO_READ_MESSAGE_FLAG_NONE));
1143 ASSERT_EQ(kHelloSize, num_bytes);
1144 ASSERT_STREQ(kHello, buffer);
1145
1146 ph = ph_received;
1147 ph_received = MOJO_HANDLE_INVALID;
1148 ch = ch_received;
1149 ch_received = MOJO_HANDLE_INVALID;
1150
1151 // Make sure that |ph| can't be sent if it's in a two-phase write.
1152 void* write_ptr = nullptr;
1153 num_bytes = 0;
1154 ASSERT_EQ(MOJO_RESULT_OK,
1155 core()->BeginWriteData(ph, &write_ptr, &num_bytes,
1156 MOJO_WRITE_DATA_FLAG_NONE));
1157 ASSERT_GE(num_bytes, 1u);
1158 ASSERT_EQ(MOJO_RESULT_BUSY,
1159 core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ph, 1,
1160 MOJO_WRITE_MESSAGE_FLAG_NONE));
1161
1162 // But |ch| can, even if |ph| is in a two-phase write.
1163 ASSERT_EQ(MOJO_RESULT_OK,
1164 core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ch, 1,
1165 MOJO_WRITE_MESSAGE_FLAG_NONE));
1166 ch = MOJO_HANDLE_INVALID;
1167 ASSERT_EQ(MOJO_RESULT_OK,
1168 core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1169 nullptr));
1170 num_bytes = kBufferSize;
1171 num_handles = arraysize(handles);
1172 ASSERT_EQ(MOJO_RESULT_OK,
1173 core()->ReadMessage(
1174 h_passing[1], buffer, &num_bytes, handles, &num_handles,
1175 MOJO_READ_MESSAGE_FLAG_NONE));
1176 ASSERT_EQ(kHelloSize, num_bytes);
1177 ASSERT_STREQ(kHello, buffer);
1178 ASSERT_EQ(1u, num_handles);
1179 ch = handles[0];
1180 ASSERT_NE(ch, MOJO_HANDLE_INVALID);
1181
1182 // Complete the two-phase write.
1183 static_cast<char*>(write_ptr)[0] = 'x';
1184 ASSERT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 1));
1185
1186 // Wait for |ch| to be readable.
1187 hss = kEmptyMojoHandleSignalsState;
1188 ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE,
1189 1000000000, &hss));
1190 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
1191 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
1192 hss.satisfiable_signals);
1193
1194 // Make sure that |ch| can't be sent if it's in a two-phase read.
1195 const void* read_ptr = nullptr;
1196 num_bytes = 1;
1197 ASSERT_EQ(MOJO_RESULT_OK,
1198 core()->BeginReadData(ch, &read_ptr, &num_bytes,
1199 MOJO_READ_DATA_FLAG_ALL_OR_NONE));
1200 ASSERT_EQ(MOJO_RESULT_BUSY,
1201 core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ch, 1,
1202 MOJO_WRITE_MESSAGE_FLAG_NONE));
1203
1204 // But |ph| can, even if |ch| is in a two-phase read.
1205 ASSERT_EQ(MOJO_RESULT_OK,
1206 core()->WriteMessage(h_passing[0], kWorld, kWorldSize, &ph, 1,
1207 MOJO_WRITE_MESSAGE_FLAG_NONE));
1208 ph = MOJO_HANDLE_INVALID;
1209 hss = kEmptyMojoHandleSignalsState;
1210 ASSERT_EQ(MOJO_RESULT_OK,
1211 core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1212 &hss));
1213 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1214 hss.satisfied_signals);
1215 ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
1216 num_bytes = kBufferSize;
1217 num_handles = arraysize(handles);
1218 ASSERT_EQ(MOJO_RESULT_OK,
1219 core()->ReadMessage(
1220 h_passing[1], buffer, &num_bytes, handles, &num_handles,
1221 MOJO_READ_MESSAGE_FLAG_NONE));
1222 ASSERT_EQ(kWorldSize, num_bytes);
1223 ASSERT_STREQ(kWorld, buffer);
1224 ASSERT_EQ(1u, num_handles);
1225 ph = handles[0];
1226 ASSERT_NE(ph, MOJO_HANDLE_INVALID);
1227
1228 // Complete the two-phase read.
1229 ASSERT_EQ('x', static_cast<const char*>(read_ptr)[0]);
1230 ASSERT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 1));
1231
1232 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0]));
1233 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1]));
1234 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ph));
1235 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ch));
1236 }
1237
1238 struct TestAsyncWaiter {
TestAsyncWaitermojo::edk::__anond6dcb7e30111::TestAsyncWaiter1239 TestAsyncWaiter() : result(MOJO_RESULT_UNKNOWN) {}
1240
Awakemojo::edk::__anond6dcb7e30111::TestAsyncWaiter1241 void Awake(MojoResult r) { result = r; }
1242
1243 MojoResult result;
1244 };
1245
1246 // TODO(vtl): Test |DuplicateBufferHandle()| and |MapBuffer()|.
1247
1248 } // namespace
1249 } // namespace edk
1250 } // namespace mojo
1251