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

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

Issue 1488853002: Add multiplexing of message pipes in the new EDK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: tsepez review comments Created 5 years 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/edk/embedder/embedder.cc ('k') | mojo/edk/system/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 #include "mojo/edk/embedder/embedder.h" 5 #include "mojo/edk/embedder/embedder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 16 matching lines...) Expand all
27 namespace edk { 27 namespace edk {
28 namespace { 28 namespace {
29 29
30 const MojoHandleSignals kSignalReadadableWritable = 30 const MojoHandleSignals kSignalReadadableWritable =
31 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE; 31 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE;
32 32
33 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE | 33 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE |
34 MOJO_HANDLE_SIGNAL_WRITABLE | 34 MOJO_HANDLE_SIGNAL_WRITABLE |
35 MOJO_HANDLE_SIGNAL_PEER_CLOSED; 35 MOJO_HANDLE_SIGNAL_PEER_CLOSED;
36 36
37 class EmbedderTest : public test::MojoSystemTest { 37 typedef testing::Test EmbedderTest;
38 public:
39 EmbedderTest() {}
40 ~EmbedderTest() override {}
41
42 private:
43 MOJO_DISALLOW_COPY_AND_ASSIGN(EmbedderTest);
44 };
45 38
46 TEST_F(EmbedderTest, ChannelBasic) { 39 TEST_F(EmbedderTest, ChannelBasic) {
47 MojoHandle server_mp, client_mp; 40 MojoHandle server_mp, client_mp;
48 ASSERT_EQ(MOJO_RESULT_OK, 41 ASSERT_EQ(MOJO_RESULT_OK,
49 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); 42 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp));
50 43
51 // We can write to a message pipe handle immediately. 44 // We can write to a message pipe handle immediately.
52 const char kHello[] = "hello"; 45 const char kHello[] = "hello";
53 46
54 size_t write_size = sizeof(kHello); 47 size_t write_size = sizeof(kHello);
(...skipping 23 matching lines...) Expand all
78 } 71 }
79 72
80 // Test sending a MP which has read messages out of the OS pipe but which have 73 // Test sending a MP which has read messages out of the OS pipe but which have
81 // not been consumed using MojoReadMessage yet. 74 // not been consumed using MojoReadMessage yet.
82 TEST_F(EmbedderTest, SendReadableMessagePipe) { 75 TEST_F(EmbedderTest, SendReadableMessagePipe) {
83 MojoHandle server_mp, client_mp; 76 MojoHandle server_mp, client_mp;
84 ASSERT_EQ(MOJO_RESULT_OK, 77 ASSERT_EQ(MOJO_RESULT_OK,
85 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); 78 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp));
86 79
87 MojoHandle server_mp2, client_mp2; 80 MojoHandle server_mp2, client_mp2;
81 MojoCreateMessagePipeOptions options;
82 options.struct_size = sizeof(MojoCreateMessagePipeOptions);
83 options.flags = MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE;
88 ASSERT_EQ(MOJO_RESULT_OK, 84 ASSERT_EQ(MOJO_RESULT_OK,
89 MojoCreateMessagePipe(nullptr, &server_mp2, &client_mp2)); 85 MojoCreateMessagePipe(&options, &server_mp2, &client_mp2));
90 86
91 // Write to server2 and wait for client2 to be readable before sending it. 87 // Write to server2 and wait for client2 to be readable before sending it.
92 // client2's MessagePipeDispatcher will have the message below in its 88 // client2's MessagePipeDispatcher will have the message below in its
93 // message_queue_. For extra measures, also verify that this pending message 89 // message_queue_. For extra measures, also verify that this pending message
94 // can contain a message pipe. 90 // can contain a message pipe.
95 MojoHandle server_mp3, client_mp3; 91 MojoHandle server_mp3, client_mp3;
96 ASSERT_EQ(MOJO_RESULT_OK, 92 ASSERT_EQ(MOJO_RESULT_OK,
97 MojoCreateMessagePipe(nullptr, &server_mp3, &client_mp3)); 93 MojoCreateMessagePipe(nullptr, &server_mp3, &client_mp3));
98 const char kHello[] = "hello"; 94 const char kHello[] = "hello";
99 size_t write_size; 95 size_t write_size;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); 154 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
159 } 155 }
160 156
161 // Verifies that a MP with pending messages to be written can be sent and the 157 // Verifies that a MP with pending messages to be written can be sent and the
162 // pending messages aren't dropped. 158 // pending messages aren't dropped.
163 TEST_F(EmbedderTest, SendMessagePipeWithWriteQueue) { 159 TEST_F(EmbedderTest, SendMessagePipeWithWriteQueue) {
164 MojoHandle server_mp, client_mp; 160 MojoHandle server_mp, client_mp;
165 ASSERT_EQ(MOJO_RESULT_OK, 161 ASSERT_EQ(MOJO_RESULT_OK,
166 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); 162 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp));
167 163
164 MojoCreateMessagePipeOptions options;
165 options.struct_size = sizeof(MojoCreateMessagePipeOptions);
166 options.flags = MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE;
168 MojoHandle server_mp2, client_mp2; 167 MojoHandle server_mp2, client_mp2;
169 ASSERT_EQ(MOJO_RESULT_OK, 168 ASSERT_EQ(MOJO_RESULT_OK,
170 MojoCreateMessagePipe(nullptr, &server_mp2, &client_mp2)); 169 MojoCreateMessagePipe(&options, &server_mp2, &client_mp2));
171 170
172 static const size_t kNumMessages = 1001; 171 static const size_t kNumMessages = 1001;
173 for (size_t i = 0; i < kNumMessages; i++) { 172 for (size_t i = 0; i < kNumMessages; i++) {
174 std::string write_buffer(i, 'A' + (i % 26)); 173 std::string write_buffer(i, 'A' + (i % 26));
175 ASSERT_EQ(MOJO_RESULT_OK, 174 ASSERT_EQ(MOJO_RESULT_OK,
176 MojoWriteMessage(client_mp2, write_buffer.data(), 175 MojoWriteMessage(client_mp2, write_buffer.data(),
177 static_cast<uint32_t>(write_buffer.size()), 176 static_cast<uint32_t>(write_buffer.size()),
178 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); 177 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
179 } 178 }
180 179
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfied_signals); 457 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfied_signals);
459 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfiable_signals); 458 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfiable_signals);
460 #endif 459 #endif
461 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp2)); 460 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp2));
462 } 461 }
463 462
464 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown()); 463 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown());
465 } 464 }
466 465
467 MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) { 466 MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) {
468 base::MessageLoop message_loop;
469 ScopedPlatformHandle client_platform_handle = 467 ScopedPlatformHandle client_platform_handle =
470 test::MultiprocessTestHelper::client_platform_handle.Pass(); 468 test::MultiprocessTestHelper::client_platform_handle.Pass();
471 EXPECT_TRUE(client_platform_handle.is_valid()); 469 EXPECT_TRUE(client_platform_handle.is_valid());
472 470
473 base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart); 471 MojoHandle client_mp = CreateMessagePipe(
472 client_platform_handle.Pass()).release().value();
474 473
475 { 474 // 1. Read the first message from |client_mp|.
476 test::ScopedIPCSupport ipc_support(test_io_thread.task_runner()); 475 MojoHandleSignalsState state;
477 MojoHandle client_mp = CreateMessagePipe( 476 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
478 client_platform_handle.Pass()).release().value(); 477 MOJO_DEADLINE_INDEFINITE, &state));
478 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals);
479 ASSERT_EQ(kSignalAll, state.satisfiable_signals);
479 480
480 // 1. Read the first message from |client_mp|. 481 char buffer[1000] = {};
481 MojoHandleSignalsState state; 482 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
482 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, 483 ASSERT_EQ(MOJO_RESULT_OK,
483 MOJO_DEADLINE_INDEFINITE, &state)); 484 MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr,
484 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); 485 MOJO_READ_MESSAGE_FLAG_NONE));
485 ASSERT_EQ(kSignalAll, state.satisfiable_signals); 486 const char kHello[] = "hello";
487 ASSERT_EQ(sizeof(kHello), num_bytes);
488 EXPECT_STREQ(kHello, buffer);
486 489
487 char buffer[1000] = {}; 490 // 2. Write a message to |client_mp| (attaching nothing).
488 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); 491 const char kWorld[] = "world!";
489 ASSERT_EQ(MOJO_RESULT_OK, 492 ASSERT_EQ(MOJO_RESULT_OK,
490 MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr, 493 MojoWriteMessage(client_mp, kWorld,
491 MOJO_READ_MESSAGE_FLAG_NONE)); 494 static_cast<uint32_t>(sizeof(kWorld)), nullptr,
492 const char kHello[] = "hello"; 495 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
493 ASSERT_EQ(sizeof(kHello), num_bytes);
494 EXPECT_STREQ(kHello, buffer);
495 496
496 // 2. Write a message to |client_mp| (attaching nothing). 497 // 4. Read a message from |client_mp|, which should have |mp1| attached.
497 const char kWorld[] = "world!"; 498 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
498 ASSERT_EQ(MOJO_RESULT_OK, 499 MOJO_DEADLINE_INDEFINITE, &state));
499 MojoWriteMessage(client_mp, kWorld, 500 // The other end of the handle may or may not be closed at this point, so we
500 static_cast<uint32_t>(sizeof(kWorld)), nullptr, 501 // can't test MOJO_HANDLE_SIGNAL_WRITABLE or MOJO_HANDLE_SIGNAL_PEER_CLOSED.
501 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); 502 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
503 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
504 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
505 state.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
506 // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd
507 // die (again due to |Channel::HandleLocalError()|).
508 memset(buffer, 0, sizeof(buffer));
509 num_bytes = static_cast<uint32_t>(sizeof(buffer));
510 MojoHandle mp1 = MOJO_HANDLE_INVALID;
511 uint32_t num_handles = 1;
512 ASSERT_EQ(MOJO_RESULT_OK,
513 MojoReadMessage(client_mp, buffer, &num_bytes, &mp1, &num_handles,
514 MOJO_READ_MESSAGE_FLAG_NONE));
515 const char kBar[] = "Bar";
516 ASSERT_EQ(sizeof(kBar), num_bytes);
517 EXPECT_STREQ(kBar, buffer);
518 ASSERT_EQ(1u, num_handles);
519 EXPECT_NE(mp1, MOJO_HANDLE_INVALID);
520 // TODO(vtl): If the scope were to end here (and the two handles closed),
521 // we'd die due to |Channel::RunRemoteMessagePipeEndpoint()| not handling
522 // write errors (assuming the parent had closed the pipe).
502 523
503 // 4. Read a message from |client_mp|, which should have |mp1| attached. 524 // 6. Close |client_mp|.
504 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, 525 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
505 MOJO_DEADLINE_INDEFINITE, &state));
506 // The other end of the handle may or may not be closed at this point, so we
507 // can't test MOJO_HANDLE_SIGNAL_WRITABLE or MOJO_HANDLE_SIGNAL_PEER_CLOSED.
508 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
509 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
510 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
511 state.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
512 // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd
513 // die (again due to |Channel::HandleLocalError()|).
514 memset(buffer, 0, sizeof(buffer));
515 num_bytes = static_cast<uint32_t>(sizeof(buffer));
516 MojoHandle mp1 = MOJO_HANDLE_INVALID;
517 uint32_t num_handles = 1;
518 ASSERT_EQ(MOJO_RESULT_OK,
519 MojoReadMessage(client_mp, buffer, &num_bytes, &mp1, &num_handles,
520 MOJO_READ_MESSAGE_FLAG_NONE));
521 const char kBar[] = "Bar";
522 ASSERT_EQ(sizeof(kBar), num_bytes);
523 EXPECT_STREQ(kBar, buffer);
524 ASSERT_EQ(1u, num_handles);
525 EXPECT_NE(mp1, MOJO_HANDLE_INVALID);
526 // TODO(vtl): If the scope were to end here (and the two handles closed),
527 // we'd die due to |Channel::RunRemoteMessagePipeEndpoint()| not handling
528 // write errors (assuming the parent had closed the pipe).
529 526
530 // 6. Close |client_mp|. 527 // Create a new message pipe (endpoints |mp2| and |mp3|).
531 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); 528 MojoHandle mp2, mp3;
529 ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp3));
532 530
533 // Create a new message pipe (endpoints |mp2| and |mp3|). 531 // 7. Write a message to |mp3|.
534 MojoHandle mp2, mp3; 532 const char kBaz[] = "baz";
535 ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp3)); 533 ASSERT_EQ(MOJO_RESULT_OK,
534 MojoWriteMessage(mp3, kBaz, static_cast<uint32_t>(sizeof(kBaz)),
535 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
536 536
537 // 7. Write a message to |mp3|. 537 // 8. Close |mp3|.
538 const char kBaz[] = "baz"; 538 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp3));
539 ASSERT_EQ(MOJO_RESULT_OK,
540 MojoWriteMessage(mp3, kBaz, static_cast<uint32_t>(sizeof(kBaz)),
541 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
542 539
543 // 8. Close |mp3|. 540 // 9. Write a message to |mp1|, attaching |mp2|.
544 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp3)); 541 const char kQuux[] = "quux";
542 ASSERT_EQ(MOJO_RESULT_OK,
543 MojoWriteMessage(mp1, kQuux, static_cast<uint32_t>(sizeof(kQuux)),
544 &mp2, 1, MOJO_WRITE_MESSAGE_FLAG_NONE));
545 mp2 = MOJO_HANDLE_INVALID;
545 546
546 // 9. Write a message to |mp1|, attaching |mp2|. 547 // 3. Read a message from |mp1|.
547 const char kQuux[] = "quux"; 548 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
548 ASSERT_EQ(MOJO_RESULT_OK, 549 MOJO_DEADLINE_INDEFINITE, &state));
549 MojoWriteMessage(mp1, kQuux, static_cast<uint32_t>(sizeof(kQuux)), 550 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals);
550 &mp2, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); 551 ASSERT_EQ(kSignalAll, state.satisfiable_signals);
551 mp2 = MOJO_HANDLE_INVALID;
552 552
553 // 3. Read a message from |mp1|. 553 memset(buffer, 0, sizeof(buffer));
554 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, 554 num_bytes = static_cast<uint32_t>(sizeof(buffer));
555 MOJO_DEADLINE_INDEFINITE, &state)); 555 ASSERT_EQ(MOJO_RESULT_OK,
556 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); 556 MojoReadMessage(mp1, buffer, &num_bytes, nullptr, nullptr,
557 ASSERT_EQ(kSignalAll, state.satisfiable_signals); 557 MOJO_READ_MESSAGE_FLAG_NONE));
558 const char kFoo[] = "FOO";
559 ASSERT_EQ(sizeof(kFoo), num_bytes);
560 EXPECT_STREQ(kFoo, buffer);
558 561
559 memset(buffer, 0, sizeof(buffer)); 562 // 11. Wait on |mp1| (which should eventually fail) and then close it.
560 num_bytes = static_cast<uint32_t>(sizeof(buffer)); 563 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
561 ASSERT_EQ(MOJO_RESULT_OK, 564 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
562 MojoReadMessage(mp1, buffer, &num_bytes, nullptr, nullptr, 565 MOJO_DEADLINE_INDEFINITE, &state));
563 MOJO_READ_MESSAGE_FLAG_NONE)); 566 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals);
564 const char kFoo[] = "FOO"; 567 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals);
565 ASSERT_EQ(sizeof(kFoo), num_bytes); 568 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp1));
566 EXPECT_STREQ(kFoo, buffer);
567
568 // 11. Wait on |mp1| (which should eventually fail) and then close it.
569 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
570 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
571 MOJO_DEADLINE_INDEFINITE, &state));
572 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals);
573 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals);
574 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp1));
575 }
576 } 569 }
577 570
578 // TODO(vtl): Test immediate write & close. 571 // TODO(vtl): Test immediate write & close.
579 // TODO(vtl): Test broken-connection cases. 572 // TODO(vtl): Test broken-connection cases.
580 573
581 } // namespace 574 } // namespace
582 } // namespace edk 575 } // namespace edk
583 } // namespace mojo 576 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/embedder/embedder.cc ('k') | mojo/edk/system/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698