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

Side by Side Diff: mojo/embedder/embedder_unittest.cc

Issue 621153003: Move mojo edk into mojo/edk (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix checkdeps Created 6 years, 2 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/embedder/embedder.cc ('k') | mojo/embedder/platform_channel_pair.h » ('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 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 #include "mojo/embedder/embedder.h"
6
7 #include <string.h>
8
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/test/test_io_thread.h"
16 #include "mojo/common/test/multiprocess_test_helper.h"
17 #include "mojo/embedder/platform_channel_pair.h"
18 #include "mojo/embedder/test_embedder.h"
19 #include "mojo/public/c/system/core.h"
20 #include "mojo/system/test_utils.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace mojo {
24 namespace embedder {
25 namespace {
26
27 class ScopedTestChannel {
28 public:
29 // Creates a channel that lives on a given I/O thread (determined by the given
30 // |TaskRunner|) attached to the given |platform_handle|. After construction,
31 // |bootstrap_message_pipe()| gives the Mojo handle for the bootstrap message
32 // pipe on this channel; it is up to the caller to close this handle.
33 // Note: The I/O thread must outlive this object (and its message loop must
34 // continue pumping messages while this object is alive).
35 ScopedTestChannel(scoped_refptr<base::TaskRunner> io_thread_task_runner,
36 ScopedPlatformHandle platform_handle)
37 : io_thread_task_runner_(io_thread_task_runner),
38 bootstrap_message_pipe_(MOJO_HANDLE_INVALID),
39 did_create_channel_event_(true, false),
40 channel_info_(nullptr) {
41 bootstrap_message_pipe_ =
42 CreateChannel(platform_handle.Pass(),
43 io_thread_task_runner_,
44 base::Bind(&ScopedTestChannel::DidCreateChannel,
45 base::Unretained(this)),
46 nullptr)
47 .release()
48 .value();
49 CHECK_NE(bootstrap_message_pipe_, MOJO_HANDLE_INVALID);
50 }
51
52 // Destructor: Shuts down the channel. (As noted above, for this to happen,
53 // the I/O thread must be alive and pumping messages.)
54 ~ScopedTestChannel() {
55 system::test::PostTaskAndWait(
56 io_thread_task_runner_,
57 FROM_HERE,
58 base::Bind(&ScopedTestChannel::DestroyChannel, base::Unretained(this)));
59 }
60
61 // Waits for channel creation to be completed.
62 void WaitForChannelCreationCompletion() { did_create_channel_event_.Wait(); }
63
64 MojoHandle bootstrap_message_pipe() const { return bootstrap_message_pipe_; }
65
66 // Call only after |WaitForChannelCreationCompletion()|. Use only to check
67 // that it's not null.
68 const ChannelInfo* channel_info() const { return channel_info_; }
69
70 private:
71 void DidCreateChannel(ChannelInfo* channel_info) {
72 CHECK(channel_info);
73 CHECK(!channel_info_);
74 channel_info_ = channel_info;
75 did_create_channel_event_.Signal();
76 }
77
78 void DestroyChannel() {
79 CHECK(channel_info_);
80 DestroyChannelOnIOThread(channel_info_);
81 channel_info_ = nullptr;
82 }
83
84 scoped_refptr<base::TaskRunner> io_thread_task_runner_;
85
86 // Valid from creation until whenever it gets closed (by the "owner" of this
87 // object).
88 // Note: We don't want use the C++ wrappers here, since we want to test the
89 // API at the lowest level.
90 MojoHandle bootstrap_message_pipe_;
91
92 // Set after channel creation has been completed (i.e., the callback to
93 // |CreateChannel()| has been called).
94 base::WaitableEvent did_create_channel_event_;
95
96 // Valid after channel creation completion until destruction.
97 ChannelInfo* channel_info_;
98
99 DISALLOW_COPY_AND_ASSIGN(ScopedTestChannel);
100 };
101
102 class EmbedderTest : public testing::Test {
103 public:
104 EmbedderTest() : test_io_thread_(base::TestIOThread::kAutoStart) {}
105 virtual ~EmbedderTest() {}
106
107 protected:
108 base::TestIOThread* test_io_thread() { return &test_io_thread_; }
109
110 private:
111 base::TestIOThread test_io_thread_;
112
113 DISALLOW_COPY_AND_ASSIGN(EmbedderTest);
114 };
115
116 TEST_F(EmbedderTest, ChannelsBasic) {
117 mojo::embedder::test::InitWithSimplePlatformSupport();
118
119 {
120 PlatformChannelPair channel_pair;
121 ScopedTestChannel server_channel(test_io_thread()->task_runner(),
122 channel_pair.PassServerHandle());
123 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
124 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
125 ScopedTestChannel client_channel(test_io_thread()->task_runner(),
126 channel_pair.PassClientHandle());
127 MojoHandle client_mp = client_channel.bootstrap_message_pipe();
128 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
129
130 // We can write to a message pipe handle immediately.
131 const char kHello[] = "hello";
132 EXPECT_EQ(MOJO_RESULT_OK,
133 MojoWriteMessage(server_mp,
134 kHello,
135 static_cast<uint32_t>(sizeof(kHello)),
136 nullptr,
137 0,
138 MOJO_WRITE_MESSAGE_FLAG_NONE));
139
140 // Now wait for the other side to become readable.
141 EXPECT_EQ(
142 MOJO_RESULT_OK,
143 MojoWait(
144 client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
145
146 char buffer[1000] = {};
147 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
148 EXPECT_EQ(MOJO_RESULT_OK,
149 MojoReadMessage(client_mp,
150 buffer,
151 &num_bytes,
152 nullptr,
153 nullptr,
154 MOJO_READ_MESSAGE_FLAG_NONE));
155 EXPECT_EQ(sizeof(kHello), num_bytes);
156 EXPECT_STREQ(kHello, buffer);
157
158 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
159 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
160
161 // By this point, these waits should basically be no-ops (since we've waited
162 // for the client message pipe to become readable, which implies that both
163 // the server and client channels were completely created).
164 server_channel.WaitForChannelCreationCompletion();
165 client_channel.WaitForChannelCreationCompletion();
166 EXPECT_TRUE(server_channel.channel_info());
167 EXPECT_TRUE(client_channel.channel_info());
168 }
169
170 EXPECT_TRUE(test::Shutdown());
171 }
172
173 TEST_F(EmbedderTest, ChannelsHandlePassing) {
174 mojo::embedder::test::InitWithSimplePlatformSupport();
175
176 {
177 PlatformChannelPair channel_pair;
178 ScopedTestChannel server_channel(test_io_thread()->task_runner(),
179 channel_pair.PassServerHandle());
180 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
181 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
182 ScopedTestChannel client_channel(test_io_thread()->task_runner(),
183 channel_pair.PassClientHandle());
184 MojoHandle client_mp = client_channel.bootstrap_message_pipe();
185 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
186
187 MojoHandle h0, h1;
188 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &h0, &h1));
189
190 // Write a message to |h0| (attaching nothing).
191 const char kHello[] = "hello";
192 EXPECT_EQ(MOJO_RESULT_OK,
193 MojoWriteMessage(h0,
194 kHello,
195 static_cast<uint32_t>(sizeof(kHello)),
196 nullptr,
197 0,
198 MOJO_WRITE_MESSAGE_FLAG_NONE));
199
200 // Write one message to |server_mp|, attaching |h1|.
201 const char kWorld[] = "world!!!";
202 EXPECT_EQ(MOJO_RESULT_OK,
203 MojoWriteMessage(server_mp,
204 kWorld,
205 static_cast<uint32_t>(sizeof(kWorld)),
206 &h1,
207 1,
208 MOJO_WRITE_MESSAGE_FLAG_NONE));
209 h1 = MOJO_HANDLE_INVALID;
210
211 // Write another message to |h0|.
212 const char kFoo[] = "foo";
213 EXPECT_EQ(MOJO_RESULT_OK,
214 MojoWriteMessage(h0,
215 kFoo,
216 static_cast<uint32_t>(sizeof(kFoo)),
217 nullptr,
218 0,
219 MOJO_WRITE_MESSAGE_FLAG_NONE));
220
221 // Wait for |client_mp| to become readable.
222 EXPECT_EQ(
223 MOJO_RESULT_OK,
224 MojoWait(
225 client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
226
227 // Read a message from |client_mp|.
228 char buffer[1000] = {};
229 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
230 MojoHandle handles[10] = {};
231 uint32_t num_handles = arraysize(handles);
232 EXPECT_EQ(MOJO_RESULT_OK,
233 MojoReadMessage(client_mp,
234 buffer,
235 &num_bytes,
236 handles,
237 &num_handles,
238 MOJO_READ_MESSAGE_FLAG_NONE));
239 EXPECT_EQ(sizeof(kWorld), num_bytes);
240 EXPECT_STREQ(kWorld, buffer);
241 EXPECT_EQ(1u, num_handles);
242 EXPECT_NE(handles[0], MOJO_HANDLE_INVALID);
243 h1 = handles[0];
244
245 // Wait for |h1| to become readable.
246 EXPECT_EQ(
247 MOJO_RESULT_OK,
248 MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
249
250 // Read a message from |h1|.
251 memset(buffer, 0, sizeof(buffer));
252 num_bytes = static_cast<uint32_t>(sizeof(buffer));
253 memset(handles, 0, sizeof(handles));
254 num_handles = arraysize(handles);
255 EXPECT_EQ(MOJO_RESULT_OK,
256 MojoReadMessage(h1,
257 buffer,
258 &num_bytes,
259 handles,
260 &num_handles,
261 MOJO_READ_MESSAGE_FLAG_NONE));
262 EXPECT_EQ(sizeof(kHello), num_bytes);
263 EXPECT_STREQ(kHello, buffer);
264 EXPECT_EQ(0u, num_handles);
265
266 // Wait for |h1| to become readable (again).
267 EXPECT_EQ(
268 MOJO_RESULT_OK,
269 MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
270
271 // Read the second message from |h1|.
272 memset(buffer, 0, sizeof(buffer));
273 num_bytes = static_cast<uint32_t>(sizeof(buffer));
274 EXPECT_EQ(MOJO_RESULT_OK,
275 MojoReadMessage(h1,
276 buffer,
277 &num_bytes,
278 nullptr,
279 nullptr,
280 MOJO_READ_MESSAGE_FLAG_NONE));
281 EXPECT_EQ(sizeof(kFoo), num_bytes);
282 EXPECT_STREQ(kFoo, buffer);
283
284 // Write a message to |h1|.
285 const char kBarBaz[] = "barbaz";
286 EXPECT_EQ(MOJO_RESULT_OK,
287 MojoWriteMessage(h1,
288 kBarBaz,
289 static_cast<uint32_t>(sizeof(kBarBaz)),
290 nullptr,
291 0,
292 MOJO_WRITE_MESSAGE_FLAG_NONE));
293
294 // Wait for |h0| to become readable.
295 EXPECT_EQ(
296 MOJO_RESULT_OK,
297 MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
298
299 // Read a message from |h0|.
300 memset(buffer, 0, sizeof(buffer));
301 num_bytes = static_cast<uint32_t>(sizeof(buffer));
302 EXPECT_EQ(MOJO_RESULT_OK,
303 MojoReadMessage(h0,
304 buffer,
305 &num_bytes,
306 nullptr,
307 nullptr,
308 MOJO_READ_MESSAGE_FLAG_NONE));
309 EXPECT_EQ(sizeof(kBarBaz), num_bytes);
310 EXPECT_STREQ(kBarBaz, buffer);
311
312 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
313 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
314 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0));
315 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1));
316
317 server_channel.WaitForChannelCreationCompletion();
318 client_channel.WaitForChannelCreationCompletion();
319 EXPECT_TRUE(server_channel.channel_info());
320 EXPECT_TRUE(client_channel.channel_info());
321 }
322
323 EXPECT_TRUE(test::Shutdown());
324 }
325
326 // The sequence of messages sent is:
327 // server_mp client_mp mp0 mp1 mp2 mp3
328 // 1. "hello"
329 // 2. "world!"
330 // 3. "FOO"
331 // 4. "Bar"+mp1
332 // 5. (close)
333 // 6. (close)
334 // 7. "baz"
335 // 8. (closed)
336 // 9. "quux"+mp2
337 // 10. (close)
338 // 11. (wait/cl.)
339 // 12. (wait/cl.)
340 TEST_F(EmbedderTest, MultiprocessChannels) {
341 mojo::embedder::test::InitWithSimplePlatformSupport();
342 mojo::test::MultiprocessTestHelper multiprocess_test_helper;
343 multiprocess_test_helper.StartChild("MultiprocessChannelsClient");
344
345 {
346 ScopedTestChannel server_channel(
347 test_io_thread()->task_runner(),
348 multiprocess_test_helper.server_platform_handle.Pass());
349 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
350 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
351 server_channel.WaitForChannelCreationCompletion();
352 EXPECT_TRUE(server_channel.channel_info());
353
354 // 1. Write a message to |server_mp| (attaching nothing).
355 const char kHello[] = "hello";
356 EXPECT_EQ(MOJO_RESULT_OK,
357 MojoWriteMessage(server_mp,
358 kHello,
359 static_cast<uint32_t>(sizeof(kHello)),
360 nullptr,
361 0,
362 MOJO_WRITE_MESSAGE_FLAG_NONE));
363
364 // TODO(vtl): If the scope were ended immediately here (maybe after closing
365 // |server_mp|), we die with a fatal error in |Channel::HandleLocalError()|.
366
367 // 2. Read a message from |server_mp|.
368 EXPECT_EQ(
369 MOJO_RESULT_OK,
370 MojoWait(
371 server_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
372 char buffer[1000] = {};
373 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
374 EXPECT_EQ(MOJO_RESULT_OK,
375 MojoReadMessage(server_mp,
376 buffer,
377 &num_bytes,
378 nullptr,
379 nullptr,
380 MOJO_READ_MESSAGE_FLAG_NONE));
381 const char kWorld[] = "world!";
382 EXPECT_EQ(sizeof(kWorld), num_bytes);
383 EXPECT_STREQ(kWorld, buffer);
384
385 // Create a new message pipe (endpoints |mp0| and |mp1|).
386 MojoHandle mp0, mp1;
387 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp0, &mp1));
388
389 // 3. Write something to |mp0|.
390 const char kFoo[] = "FOO";
391 EXPECT_EQ(MOJO_RESULT_OK,
392 MojoWriteMessage(mp0,
393 kFoo,
394 static_cast<uint32_t>(sizeof(kFoo)),
395 nullptr,
396 0,
397 MOJO_WRITE_MESSAGE_FLAG_NONE));
398
399 // 4. Write a message to |server_mp|, attaching |mp1|.
400 const char kBar[] = "Bar";
401 EXPECT_EQ(MOJO_RESULT_OK,
402 MojoWriteMessage(server_mp,
403 kBar,
404 static_cast<uint32_t>(sizeof(kBar)),
405 &mp1,
406 1,
407 MOJO_WRITE_MESSAGE_FLAG_NONE));
408 mp1 = MOJO_HANDLE_INVALID;
409
410 // 5. Close |server_mp|.
411 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
412
413 // 9. Read a message from |mp0|, which should have |mp2| attached.
414 EXPECT_EQ(
415 MOJO_RESULT_OK,
416 MojoWait(mp0, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
417 memset(buffer, 0, sizeof(buffer));
418 num_bytes = static_cast<uint32_t>(sizeof(buffer));
419 MojoHandle mp2 = MOJO_HANDLE_INVALID;
420 uint32_t num_handles = 1;
421 EXPECT_EQ(MOJO_RESULT_OK,
422 MojoReadMessage(mp0,
423 buffer,
424 &num_bytes,
425 &mp2,
426 &num_handles,
427 MOJO_READ_MESSAGE_FLAG_NONE));
428 const char kQuux[] = "quux";
429 EXPECT_EQ(sizeof(kQuux), num_bytes);
430 EXPECT_STREQ(kQuux, buffer);
431 EXPECT_EQ(1u, num_handles);
432 EXPECT_NE(mp2, MOJO_HANDLE_INVALID);
433
434 // 7. Read a message from |mp2|.
435 EXPECT_EQ(
436 MOJO_RESULT_OK,
437 MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
438 memset(buffer, 0, sizeof(buffer));
439 num_bytes = static_cast<uint32_t>(sizeof(buffer));
440 EXPECT_EQ(MOJO_RESULT_OK,
441 MojoReadMessage(mp2,
442 buffer,
443 &num_bytes,
444 nullptr,
445 nullptr,
446 MOJO_READ_MESSAGE_FLAG_NONE));
447 const char kBaz[] = "baz";
448 EXPECT_EQ(sizeof(kBaz), num_bytes);
449 EXPECT_STREQ(kBaz, buffer);
450
451 // 10. Close |mp0|.
452 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp0));
453
454 // 12. Wait on |mp2| (which should eventually fail) and then close it.
455 // TODO(vtl): crbug.com/351768
456 #if 0
457 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
458 MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE,
459 MOJO_DEADLINE_INDEFINITE));
460 #endif
461 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp2));
462 }
463
464 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown());
465 EXPECT_TRUE(test::Shutdown());
466 }
467
468 MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) {
469 ScopedPlatformHandle client_platform_handle =
470 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
471 EXPECT_TRUE(client_platform_handle.is_valid());
472
473 base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
474 mojo::embedder::test::InitWithSimplePlatformSupport();
475
476 {
477 ScopedTestChannel client_channel(test_io_thread.task_runner(),
478 client_platform_handle.Pass());
479 MojoHandle client_mp = client_channel.bootstrap_message_pipe();
480 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
481 client_channel.WaitForChannelCreationCompletion();
482 CHECK(client_channel.channel_info() != nullptr);
483
484 // 1. Read the first message from |client_mp|.
485 EXPECT_EQ(
486 MOJO_RESULT_OK,
487 MojoWait(
488 client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
489 char buffer[1000] = {};
490 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
491 EXPECT_EQ(MOJO_RESULT_OK,
492 MojoReadMessage(client_mp,
493 buffer,
494 &num_bytes,
495 nullptr,
496 nullptr,
497 MOJO_READ_MESSAGE_FLAG_NONE));
498 const char kHello[] = "hello";
499 EXPECT_EQ(sizeof(kHello), num_bytes);
500 EXPECT_STREQ(kHello, buffer);
501
502 // 2. Write a message to |client_mp| (attaching nothing).
503 const char kWorld[] = "world!";
504 EXPECT_EQ(MOJO_RESULT_OK,
505 MojoWriteMessage(client_mp,
506 kWorld,
507 static_cast<uint32_t>(sizeof(kWorld)),
508 nullptr,
509 0,
510 MOJO_WRITE_MESSAGE_FLAG_NONE));
511
512 // 4. Read a message from |client_mp|, which should have |mp1| attached.
513 EXPECT_EQ(
514 MOJO_RESULT_OK,
515 MojoWait(
516 client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
517 // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd
518 // die (again due to |Channel::HandleLocalError()|).
519 memset(buffer, 0, sizeof(buffer));
520 num_bytes = static_cast<uint32_t>(sizeof(buffer));
521 MojoHandle mp1 = MOJO_HANDLE_INVALID;
522 uint32_t num_handles = 1;
523 EXPECT_EQ(MOJO_RESULT_OK,
524 MojoReadMessage(client_mp,
525 buffer,
526 &num_bytes,
527 &mp1,
528 &num_handles,
529 MOJO_READ_MESSAGE_FLAG_NONE));
530 const char kBar[] = "Bar";
531 EXPECT_EQ(sizeof(kBar), num_bytes);
532 EXPECT_STREQ(kBar, buffer);
533 EXPECT_EQ(1u, num_handles);
534 EXPECT_NE(mp1, MOJO_HANDLE_INVALID);
535 // TODO(vtl): If the scope were to end here (and the two handles closed),
536 // we'd die due to |Channel::RunRemoteMessagePipeEndpoint()| not handling
537 // write errors (assuming the parent had closed the pipe).
538
539 // 6. Close |client_mp|.
540 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
541
542 // Create a new message pipe (endpoints |mp2| and |mp3|).
543 MojoHandle mp2, mp3;
544 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp3));
545
546 // 7. Write a message to |mp3|.
547 const char kBaz[] = "baz";
548 EXPECT_EQ(MOJO_RESULT_OK,
549 MojoWriteMessage(mp3,
550 kBaz,
551 static_cast<uint32_t>(sizeof(kBaz)),
552 nullptr,
553 0,
554 MOJO_WRITE_MESSAGE_FLAG_NONE));
555
556 // 8. Close |mp3|.
557 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp3));
558
559 // 9. Write a message to |mp1|, attaching |mp2|.
560 const char kQuux[] = "quux";
561 EXPECT_EQ(MOJO_RESULT_OK,
562 MojoWriteMessage(mp1,
563 kQuux,
564 static_cast<uint32_t>(sizeof(kQuux)),
565 &mp2,
566 1,
567 MOJO_WRITE_MESSAGE_FLAG_NONE));
568 mp2 = MOJO_HANDLE_INVALID;
569
570 // 3. Read a message from |mp1|.
571 EXPECT_EQ(
572 MOJO_RESULT_OK,
573 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
574 memset(buffer, 0, sizeof(buffer));
575 num_bytes = static_cast<uint32_t>(sizeof(buffer));
576 EXPECT_EQ(MOJO_RESULT_OK,
577 MojoReadMessage(mp1,
578 buffer,
579 &num_bytes,
580 nullptr,
581 nullptr,
582 MOJO_READ_MESSAGE_FLAG_NONE));
583 const char kFoo[] = "FOO";
584 EXPECT_EQ(sizeof(kFoo), num_bytes);
585 EXPECT_STREQ(kFoo, buffer);
586
587 // 11. Wait on |mp1| (which should eventually fail) and then close it.
588 EXPECT_EQ(
589 MOJO_RESULT_FAILED_PRECONDITION,
590 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
591 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp1));
592 }
593
594 EXPECT_TRUE(test::Shutdown());
595 }
596
597 // TODO(vtl): Test immediate write & close.
598 // TODO(vtl): Test broken-connection cases.
599
600 } // namespace
601 } // namespace embedder
602 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/embedder/embedder.cc ('k') | mojo/embedder/platform_channel_pair.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698