Home | History | Annotate | Download | only in system
      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 <stddef.h>
      6 #include <stdint.h>
      7 #include <stdio.h>
      8 #include <string.h>
      9 
     10 #include <string>
     11 #include <utility>
     12 #include <vector>
     13 
     14 #include "base/bind.h"
     15 #include "base/containers/hash_tables.h"
     16 #include "base/files/file_path.h"
     17 #include "base/files/file_util.h"
     18 #include "base/files/scoped_file.h"
     19 #include "base/files/scoped_temp_dir.h"
     20 #include "base/logging.h"
     21 #include "base/message_loop/message_loop.h"
     22 #include "base/run_loop.h"
     23 #include "base/strings/string_split.h"
     24 #include "build/build_config.h"
     25 #include "mojo/edk/embedder/platform_channel_pair.h"
     26 #include "mojo/edk/embedder/scoped_platform_handle.h"
     27 #include "mojo/edk/system/handle_signals_state.h"
     28 #include "mojo/edk/system/test_utils.h"
     29 #include "mojo/edk/test/mojo_test_base.h"
     30 #include "mojo/edk/test/test_utils.h"
     31 #include "mojo/public/c/system/buffer.h"
     32 #include "mojo/public/c/system/functions.h"
     33 #include "mojo/public/c/system/types.h"
     34 #include "mojo/public/cpp/system/watcher.h"
     35 #include "testing/gtest/include/gtest/gtest.h"
     36 
     37 
     38 namespace mojo {
     39 namespace edk {
     40 namespace {
     41 
     42 class MultiprocessMessagePipeTest : public test::MojoTestBase {
     43  protected:
     44   // Convenience class for tests which will control command-driven children.
     45   // See the CommandDrivenClient definition below.
     46   class CommandDrivenClientController {
     47    public:
     48     explicit CommandDrivenClientController(MojoHandle h) : h_(h) {}
     49 
     50     void Send(const std::string& command) {
     51       WriteMessage(h_, command);
     52       EXPECT_EQ("ok", ReadMessage(h_));
     53     }
     54 
     55     void SendHandle(const std::string& name, MojoHandle p) {
     56       WriteMessageWithHandles(h_, "take:" + name, &p, 1);
     57       EXPECT_EQ("ok", ReadMessage(h_));
     58     }
     59 
     60     MojoHandle RetrieveHandle(const std::string& name) {
     61       WriteMessage(h_, "return:" + name);
     62       MojoHandle p;
     63       EXPECT_EQ("ok", ReadMessageWithHandles(h_, &p, 1));
     64       return p;
     65     }
     66 
     67     void Exit() { WriteMessage(h_, "exit"); }
     68 
     69    private:
     70     MojoHandle h_;
     71   };
     72 };
     73 
     74 class MultiprocessMessagePipeTestWithPeerSupport
     75     : public MultiprocessMessagePipeTest,
     76       public testing::WithParamInterface<test::MojoTestBase::LaunchType> {
     77  protected:
     78   void SetUp() override {
     79     test::MojoTestBase::SetUp();
     80     set_launch_type(GetParam());
     81   }
     82 };
     83 
     84 // For each message received, sends a reply message with the same contents
     85 // repeated twice, until the other end is closed or it receives "quitquitquit"
     86 // (which it doesn't reply to). It'll return the number of messages received,
     87 // not including any "quitquitquit" message, modulo 100.
     88 DEFINE_TEST_CLIENT_WITH_PIPE(EchoEcho, MultiprocessMessagePipeTest, h) {
     89   const std::string quitquitquit("quitquitquit");
     90   int rv = 0;
     91   for (;; rv = (rv + 1) % 100) {
     92     // Wait for our end of the message pipe to be readable.
     93     HandleSignalsState hss;
     94     MojoResult result =
     95         MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
     96                  MOJO_DEADLINE_INDEFINITE, &hss);
     97     if (result != MOJO_RESULT_OK) {
     98       // It was closed, probably.
     99       CHECK_EQ(result, MOJO_RESULT_FAILED_PRECONDITION);
    100       CHECK_EQ(hss.satisfied_signals, MOJO_HANDLE_SIGNAL_PEER_CLOSED);
    101       CHECK_EQ(hss.satisfiable_signals, MOJO_HANDLE_SIGNAL_PEER_CLOSED);
    102       break;
    103     } else {
    104       CHECK((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
    105       CHECK((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
    106     }
    107 
    108     std::string read_buffer(1000, '\0');
    109     uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
    110     CHECK_EQ(MojoReadMessage(h, &read_buffer[0],
    111                              &read_buffer_size, nullptr,
    112                              0, MOJO_READ_MESSAGE_FLAG_NONE),
    113              MOJO_RESULT_OK);
    114     read_buffer.resize(read_buffer_size);
    115     VLOG(2) << "Child got: " << read_buffer;
    116 
    117     if (read_buffer == quitquitquit) {
    118       VLOG(2) << "Child quitting.";
    119       break;
    120     }
    121 
    122     std::string write_buffer = read_buffer + read_buffer;
    123     CHECK_EQ(MojoWriteMessage(h, write_buffer.data(),
    124                               static_cast<uint32_t>(write_buffer.size()),
    125                               nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE),
    126              MOJO_RESULT_OK);
    127   }
    128 
    129   return rv;
    130 }
    131 
    132 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, Basic) {
    133   RUN_CHILD_ON_PIPE(EchoEcho, h)
    134     std::string hello("hello");
    135     ASSERT_EQ(MOJO_RESULT_OK,
    136               MojoWriteMessage(h, hello.data(),
    137                                static_cast<uint32_t>(hello.size()), nullptr, 0u,
    138                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    139 
    140     HandleSignalsState hss;
    141     ASSERT_EQ(MOJO_RESULT_OK,
    142               MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    143                        MOJO_DEADLINE_INDEFINITE, &hss));
    144     // The child may or may not have closed its end of the message pipe and died
    145     // (and we may or may not know it yet), so our end may or may not appear as
    146     // writable.
    147     EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
    148     EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
    149 
    150     std::string read_buffer(1000, '\0');
    151     uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
    152     CHECK_EQ(MojoReadMessage(h, &read_buffer[0],
    153                              &read_buffer_size, nullptr, 0,
    154                              MOJO_READ_MESSAGE_FLAG_NONE),
    155              MOJO_RESULT_OK);
    156     read_buffer.resize(read_buffer_size);
    157     VLOG(2) << "Parent got: " << read_buffer;
    158     ASSERT_EQ(hello + hello, read_buffer);
    159 
    160     std::string quitquitquit("quitquitquit");
    161     CHECK_EQ(MojoWriteMessage(h, quitquitquit.data(),
    162                               static_cast<uint32_t>(quitquitquit.size()),
    163                               nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE),
    164              MOJO_RESULT_OK);
    165   END_CHILD_AND_EXPECT_EXIT_CODE(1 % 100);
    166 }
    167 
    168 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, QueueMessages) {
    169   static const size_t kNumMessages = 1001;
    170   RUN_CHILD_ON_PIPE(EchoEcho, h)
    171     for (size_t i = 0; i < kNumMessages; i++) {
    172       std::string write_buffer(i, 'A' + (i % 26));
    173       ASSERT_EQ(MOJO_RESULT_OK,
    174               MojoWriteMessage(h, write_buffer.data(),
    175                                static_cast<uint32_t>(write_buffer.size()),
    176                                nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE));
    177     }
    178 
    179     for (size_t i = 0; i < kNumMessages; i++) {
    180       HandleSignalsState hss;
    181       ASSERT_EQ(MOJO_RESULT_OK,
    182                 MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    183                          MOJO_DEADLINE_INDEFINITE, &hss));
    184       // The child may or may not have closed its end of the message pipe and
    185       // died (and we may or may not know it yet), so our end may or may not
    186       // appear as writable.
    187       ASSERT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
    188       ASSERT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
    189 
    190       std::string read_buffer(kNumMessages * 2, '\0');
    191       uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
    192       ASSERT_EQ(MojoReadMessage(h, &read_buffer[0],
    193                                 &read_buffer_size, nullptr, 0,
    194                                 MOJO_READ_MESSAGE_FLAG_NONE),
    195                MOJO_RESULT_OK);
    196       read_buffer.resize(read_buffer_size);
    197 
    198       ASSERT_EQ(std::string(i * 2, 'A' + (i % 26)), read_buffer);
    199     }
    200 
    201     const std::string quitquitquit("quitquitquit");
    202     ASSERT_EQ(MOJO_RESULT_OK,
    203               MojoWriteMessage(h, quitquitquit.data(),
    204                                static_cast<uint32_t>(quitquitquit.size()),
    205                                nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE));
    206 
    207     // Wait for it to become readable, which should fail (since we sent
    208     // "quitquitquit").
    209     HandleSignalsState hss;
    210     ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
    211               MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    212                        MOJO_DEADLINE_INDEFINITE, &hss));
    213     ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
    214     ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
    215   END_CHILD_AND_EXPECT_EXIT_CODE(static_cast<int>(kNumMessages % 100));
    216 }
    217 
    218 DEFINE_TEST_CLIENT_WITH_PIPE(CheckSharedBuffer, MultiprocessMessagePipeTest,
    219                              h) {
    220   // Wait for the first message from our parent.
    221   HandleSignalsState hss;
    222   CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    223                MOJO_DEADLINE_INDEFINITE, &hss),
    224            MOJO_RESULT_OK);
    225   // In this test, the parent definitely doesn't close its end of the message
    226   // pipe before we do.
    227   CHECK_EQ(hss.satisfied_signals,
    228            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
    229   CHECK_EQ(hss.satisfiable_signals, MOJO_HANDLE_SIGNAL_READABLE |
    230                                     MOJO_HANDLE_SIGNAL_WRITABLE |
    231                                     MOJO_HANDLE_SIGNAL_PEER_CLOSED);
    232 
    233   // It should have a shared buffer.
    234   std::string read_buffer(100, '\0');
    235   uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
    236   MojoHandle handles[10];
    237   uint32_t num_handlers = arraysize(handles);  // Maximum number to receive
    238   CHECK_EQ(MojoReadMessage(h, &read_buffer[0],
    239                            &num_bytes, &handles[0],
    240                            &num_handlers, MOJO_READ_MESSAGE_FLAG_NONE),
    241            MOJO_RESULT_OK);
    242   read_buffer.resize(num_bytes);
    243   CHECK_EQ(read_buffer, std::string("go 1"));
    244   CHECK_EQ(num_handlers, 1u);
    245 
    246   // Make a mapping.
    247   void* buffer;
    248   CHECK_EQ(MojoMapBuffer(handles[0], 0, 100, &buffer,
    249                          MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE),
    250            MOJO_RESULT_OK);
    251 
    252   // Write some stuff to the shared buffer.
    253   static const char kHello[] = "hello";
    254   memcpy(buffer, kHello, sizeof(kHello));
    255 
    256   // We should be able to close the dispatcher now.
    257   MojoClose(handles[0]);
    258 
    259   // And send a message to signal that we've written stuff.
    260   const std::string go2("go 2");
    261   CHECK_EQ(MojoWriteMessage(h, go2.data(),
    262                             static_cast<uint32_t>(go2.size()), nullptr, 0u,
    263                             MOJO_WRITE_MESSAGE_FLAG_NONE),
    264            MOJO_RESULT_OK);
    265 
    266   // Now wait for our parent to send us a message.
    267   hss = HandleSignalsState();
    268   CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    269                     MOJO_DEADLINE_INDEFINITE, &hss),
    270            MOJO_RESULT_OK);
    271   CHECK_EQ(hss.satisfied_signals,
    272            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
    273   CHECK_EQ(hss.satisfiable_signals, MOJO_HANDLE_SIGNAL_READABLE |
    274                                         MOJO_HANDLE_SIGNAL_WRITABLE |
    275                                         MOJO_HANDLE_SIGNAL_PEER_CLOSED);
    276 
    277   read_buffer = std::string(100, '\0');
    278   num_bytes = static_cast<uint32_t>(read_buffer.size());
    279   CHECK_EQ(MojoReadMessage(h, &read_buffer[0], &num_bytes,
    280                            nullptr, 0, MOJO_READ_MESSAGE_FLAG_NONE),
    281            MOJO_RESULT_OK);
    282   read_buffer.resize(num_bytes);
    283   CHECK_EQ(read_buffer, std::string("go 3"));
    284 
    285   // It should have written something to the shared buffer.
    286   static const char kWorld[] = "world!!!";
    287   CHECK_EQ(memcmp(buffer, kWorld, sizeof(kWorld)), 0);
    288 
    289   // And we're done.
    290 
    291   return 0;
    292 }
    293 
    294 TEST_F(MultiprocessMessagePipeTest, SharedBufferPassing) {
    295   RUN_CHILD_ON_PIPE(CheckSharedBuffer, h)
    296     // Make a shared buffer.
    297     MojoCreateSharedBufferOptions options;
    298     options.struct_size = sizeof(options);
    299     options.flags = MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE;
    300 
    301     MojoHandle shared_buffer;
    302     ASSERT_EQ(MOJO_RESULT_OK,
    303               MojoCreateSharedBuffer(&options, 100, &shared_buffer));
    304 
    305     // Send the shared buffer.
    306     const std::string go1("go 1");
    307 
    308     MojoHandle duplicated_shared_buffer;
    309     ASSERT_EQ(MOJO_RESULT_OK,
    310               MojoDuplicateBufferHandle(
    311                   shared_buffer,
    312                   nullptr,
    313                   &duplicated_shared_buffer));
    314     MojoHandle handles[1];
    315     handles[0] = duplicated_shared_buffer;
    316     ASSERT_EQ(MOJO_RESULT_OK,
    317               MojoWriteMessage(h, &go1[0],
    318                                static_cast<uint32_t>(go1.size()), &handles[0],
    319                                arraysize(handles),
    320                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    321 
    322     // Wait for a message from the child.
    323     HandleSignalsState hss;
    324     ASSERT_EQ(MOJO_RESULT_OK,
    325               MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    326                        MOJO_DEADLINE_INDEFINITE, &hss));
    327     EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
    328     EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
    329 
    330     std::string read_buffer(100, '\0');
    331     uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
    332     ASSERT_EQ(MOJO_RESULT_OK,
    333               MojoReadMessage(h, &read_buffer[0],
    334                               &num_bytes, nullptr, 0,
    335                               MOJO_READ_MESSAGE_FLAG_NONE));
    336     read_buffer.resize(num_bytes);
    337     ASSERT_EQ(std::string("go 2"), read_buffer);
    338 
    339     // After we get it, the child should have written something to the shared
    340     // buffer.
    341     static const char kHello[] = "hello";
    342     void* buffer;
    343     CHECK_EQ(MojoMapBuffer(shared_buffer, 0, 100, &buffer,
    344                            MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE),
    345              MOJO_RESULT_OK);
    346     ASSERT_EQ(0, memcmp(buffer, kHello, sizeof(kHello)));
    347 
    348     // Now we'll write some stuff to the shared buffer.
    349     static const char kWorld[] = "world!!!";
    350     memcpy(buffer, kWorld, sizeof(kWorld));
    351 
    352     // And send a message to signal that we've written stuff.
    353     const std::string go3("go 3");
    354     ASSERT_EQ(MOJO_RESULT_OK,
    355               MojoWriteMessage(h, &go3[0],
    356                                static_cast<uint32_t>(go3.size()), nullptr, 0u,
    357                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    358 
    359     // Wait for |h| to become readable, which should fail.
    360     hss = HandleSignalsState();
    361     ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
    362               MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    363                        MOJO_DEADLINE_INDEFINITE, &hss));
    364     ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
    365     ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
    366   END_CHILD()
    367 }
    368 
    369 DEFINE_TEST_CLIENT_WITH_PIPE(CheckPlatformHandleFile,
    370                              MultiprocessMessagePipeTest, h) {
    371   HandleSignalsState hss;
    372   CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    373                     MOJO_DEADLINE_INDEFINITE, &hss),
    374            MOJO_RESULT_OK);
    375   CHECK_EQ(hss.satisfied_signals,
    376            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
    377   CHECK_EQ(hss.satisfiable_signals, MOJO_HANDLE_SIGNAL_READABLE |
    378                                         MOJO_HANDLE_SIGNAL_WRITABLE |
    379                                         MOJO_HANDLE_SIGNAL_PEER_CLOSED);
    380 
    381   std::string read_buffer(100, '\0');
    382   uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
    383   MojoHandle handles[255];  // Maximum number to receive.
    384   uint32_t num_handlers = arraysize(handles);
    385 
    386   CHECK_EQ(MojoReadMessage(h, &read_buffer[0],
    387                            &num_bytes, &handles[0],
    388                            &num_handlers, MOJO_READ_MESSAGE_FLAG_NONE),
    389            MOJO_RESULT_OK);
    390 
    391   read_buffer.resize(num_bytes);
    392   char hello[32];
    393   int num_handles = 0;
    394   sscanf(read_buffer.c_str(), "%s %d", hello, &num_handles);
    395   CHECK_EQ(std::string("hello"), std::string(hello));
    396   CHECK_GT(num_handles, 0);
    397 
    398   for (int i = 0; i < num_handles; ++i) {
    399     ScopedPlatformHandle h;
    400     CHECK_EQ(PassWrappedPlatformHandle(handles[i], &h), MOJO_RESULT_OK);
    401     CHECK(h.is_valid());
    402     MojoClose(handles[i]);
    403 
    404     base::ScopedFILE fp(test::FILEFromPlatformHandle(std::move(h), "r"));
    405     CHECK(fp);
    406     std::string fread_buffer(100, '\0');
    407     size_t bytes_read =
    408         fread(&fread_buffer[0], 1, fread_buffer.size(), fp.get());
    409     fread_buffer.resize(bytes_read);
    410     CHECK_EQ(fread_buffer, "world");
    411   }
    412 
    413   return 0;
    414 }
    415 
    416 class MultiprocessMessagePipeTestWithPipeCount
    417     : public MultiprocessMessagePipeTest,
    418       public testing::WithParamInterface<size_t> {};
    419 
    420 TEST_P(MultiprocessMessagePipeTestWithPipeCount, PlatformHandlePassing) {
    421   base::ScopedTempDir temp_dir;
    422   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    423 
    424   RUN_CHILD_ON_PIPE(CheckPlatformHandleFile, h)
    425     std::vector<MojoHandle> handles;
    426 
    427     size_t pipe_count = GetParam();
    428     for (size_t i = 0; i < pipe_count; ++i) {
    429       base::FilePath unused;
    430       base::ScopedFILE fp(
    431           CreateAndOpenTemporaryFileInDir(temp_dir.GetPath(), &unused));
    432       const std::string world("world");
    433       CHECK_EQ(fwrite(&world[0], 1, world.size(), fp.get()), world.size());
    434       fflush(fp.get());
    435       rewind(fp.get());
    436       MojoHandle handle;
    437       ASSERT_EQ(
    438           CreatePlatformHandleWrapper(
    439               ScopedPlatformHandle(test::PlatformHandleFromFILE(std::move(fp))),
    440               &handle),
    441           MOJO_RESULT_OK);
    442       handles.push_back(handle);
    443     }
    444 
    445     char message[128];
    446     snprintf(message, sizeof(message), "hello %d",
    447              static_cast<int>(pipe_count));
    448     ASSERT_EQ(MOJO_RESULT_OK,
    449               MojoWriteMessage(h, message,
    450                                static_cast<uint32_t>(strlen(message)),
    451                                &handles[0],
    452                                static_cast<uint32_t>(handles.size()),
    453                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    454 
    455     // Wait for it to become readable, which should fail.
    456     HandleSignalsState hss;
    457     ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
    458               MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    459                        MOJO_DEADLINE_INDEFINITE, &hss));
    460     ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
    461     ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
    462   END_CHILD()
    463 }
    464 
    465 // Android multi-process tests are not executing the new process. This is flaky.
    466 #if !defined(OS_ANDROID)
    467 INSTANTIATE_TEST_CASE_P(PipeCount,
    468                         MultiprocessMessagePipeTestWithPipeCount,
    469                         // TODO(rockot): Re-enable the 140-pipe case when
    470                         // ChannelPosix has support for sending lots of handles.
    471                         testing::Values(1u, 128u /*, 140u*/));
    472 #endif
    473 
    474 DEFINE_TEST_CLIENT_WITH_PIPE(CheckMessagePipe, MultiprocessMessagePipeTest, h) {
    475   // Wait for the first message from our parent.
    476   HandleSignalsState hss;
    477   CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    478                     MOJO_DEADLINE_INDEFINITE, &hss),
    479            MOJO_RESULT_OK);
    480   // In this test, the parent definitely doesn't close its end of the message
    481   // pipe before we do.
    482   CHECK_EQ(hss.satisfied_signals,
    483            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
    484   CHECK_EQ(hss.satisfiable_signals, MOJO_HANDLE_SIGNAL_READABLE |
    485                                     MOJO_HANDLE_SIGNAL_WRITABLE |
    486                                     MOJO_HANDLE_SIGNAL_PEER_CLOSED);
    487 
    488   // It should have a message pipe.
    489   MojoHandle handles[10];
    490   uint32_t num_handlers = arraysize(handles);
    491   CHECK_EQ(MojoReadMessage(h, nullptr,
    492                            nullptr, &handles[0],
    493                            &num_handlers, MOJO_READ_MESSAGE_FLAG_NONE),
    494            MOJO_RESULT_OK);
    495   CHECK_EQ(num_handlers, 1u);
    496 
    497   // Read data from the received message pipe.
    498   CHECK_EQ(MojoWait(handles[0], MOJO_HANDLE_SIGNAL_READABLE,
    499                MOJO_DEADLINE_INDEFINITE, &hss),
    500            MOJO_RESULT_OK);
    501   CHECK_EQ(hss.satisfied_signals,
    502            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
    503   CHECK_EQ(hss.satisfiable_signals, MOJO_HANDLE_SIGNAL_READABLE |
    504                                     MOJO_HANDLE_SIGNAL_WRITABLE |
    505                                     MOJO_HANDLE_SIGNAL_PEER_CLOSED);
    506 
    507   std::string read_buffer(100, '\0');
    508   uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
    509   CHECK_EQ(MojoReadMessage(handles[0], &read_buffer[0],
    510                            &read_buffer_size, nullptr,
    511                            0, MOJO_READ_MESSAGE_FLAG_NONE),
    512            MOJO_RESULT_OK);
    513   read_buffer.resize(read_buffer_size);
    514   CHECK_EQ(read_buffer, std::string("hello"));
    515 
    516   // Now write some data into the message pipe.
    517   std::string write_buffer = "world";
    518   CHECK_EQ(MojoWriteMessage(handles[0], write_buffer.data(),
    519                             static_cast<uint32_t>(write_buffer.size()), nullptr,
    520                             0u, MOJO_WRITE_MESSAGE_FLAG_NONE),
    521            MOJO_RESULT_OK);
    522   MojoClose(handles[0]);
    523   return 0;
    524 }
    525 
    526 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, MessagePipePassing) {
    527   RUN_CHILD_ON_PIPE(CheckMessagePipe, h)
    528     MojoCreateSharedBufferOptions options;
    529     options.struct_size = sizeof(options);
    530     options.flags = MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE;
    531 
    532     MojoHandle mp1, mp2;
    533     ASSERT_EQ(MOJO_RESULT_OK,
    534               MojoCreateMessagePipe(nullptr, &mp1, &mp2));
    535 
    536     // Write a string into one end of the new message pipe and send the other
    537     // end.
    538     const std::string hello("hello");
    539     ASSERT_EQ(MOJO_RESULT_OK,
    540               MojoWriteMessage(mp1, &hello[0],
    541                                static_cast<uint32_t>(hello.size()), nullptr, 0,
    542                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    543     ASSERT_EQ(MOJO_RESULT_OK,
    544               MojoWriteMessage(h, nullptr, 0, &mp2, 1,
    545                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    546 
    547     // Wait for a message from the child.
    548     HandleSignalsState hss;
    549     ASSERT_EQ(MOJO_RESULT_OK,
    550               MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
    551                        MOJO_DEADLINE_INDEFINITE, &hss));
    552     EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
    553     EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
    554 
    555     std::string read_buffer(100, '\0');
    556     uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
    557     CHECK_EQ(MojoReadMessage(mp1, &read_buffer[0],
    558                              &read_buffer_size, nullptr,
    559                              0, MOJO_READ_MESSAGE_FLAG_NONE),
    560              MOJO_RESULT_OK);
    561     read_buffer.resize(read_buffer_size);
    562     CHECK_EQ(read_buffer, std::string("world"));
    563 
    564     MojoClose(mp1);
    565   END_CHILD()
    566 }
    567 
    568 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, MessagePipeTwoPassing) {
    569   RUN_CHILD_ON_PIPE(CheckMessagePipe, h)
    570     MojoHandle mp1, mp2;
    571     ASSERT_EQ(MOJO_RESULT_OK,
    572               MojoCreateMessagePipe(nullptr, &mp2, &mp1));
    573 
    574     // Write a string into one end of the new message pipe and send the other
    575     // end.
    576     const std::string hello("hello");
    577     ASSERT_EQ(MOJO_RESULT_OK,
    578               MojoWriteMessage(mp1, &hello[0],
    579                                static_cast<uint32_t>(hello.size()), nullptr, 0u,
    580                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    581     ASSERT_EQ(MOJO_RESULT_OK,
    582               MojoWriteMessage(h, nullptr, 0u, &mp2, 1u,
    583                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    584 
    585     // Wait for a message from the child.
    586     HandleSignalsState hss;
    587     ASSERT_EQ(MOJO_RESULT_OK,
    588               MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
    589                        MOJO_DEADLINE_INDEFINITE, &hss));
    590     EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
    591     EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
    592 
    593     std::string read_buffer(100, '\0');
    594     uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
    595     CHECK_EQ(MojoReadMessage(mp1, &read_buffer[0],
    596                              &read_buffer_size, nullptr,
    597                              0, MOJO_READ_MESSAGE_FLAG_NONE),
    598              MOJO_RESULT_OK);
    599     read_buffer.resize(read_buffer_size);
    600     CHECK_EQ(read_buffer, std::string("world"));
    601   END_CHILD();
    602 }
    603 
    604 DEFINE_TEST_CLIENT_WITH_PIPE(DataPipeConsumer, MultiprocessMessagePipeTest, h) {
    605   // Wait for the first message from our parent.
    606   HandleSignalsState hss;
    607   CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    608                     MOJO_DEADLINE_INDEFINITE, &hss),
    609            MOJO_RESULT_OK);
    610   // In this test, the parent definitely doesn't close its end of the message
    611   // pipe before we do.
    612   CHECK_EQ(hss.satisfied_signals,
    613            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
    614   CHECK_EQ(hss.satisfiable_signals, MOJO_HANDLE_SIGNAL_READABLE |
    615                                     MOJO_HANDLE_SIGNAL_WRITABLE |
    616                                     MOJO_HANDLE_SIGNAL_PEER_CLOSED);
    617 
    618   // It should have a message pipe.
    619   MojoHandle handles[10];
    620   uint32_t num_handlers = arraysize(handles);
    621   CHECK_EQ(MojoReadMessage(h, nullptr,
    622                            nullptr, &handles[0],
    623                            &num_handlers, MOJO_READ_MESSAGE_FLAG_NONE),
    624            MOJO_RESULT_OK);
    625   CHECK_EQ(num_handlers, 1u);
    626 
    627   // Read data from the received message pipe.
    628   CHECK_EQ(MojoWait(handles[0], MOJO_HANDLE_SIGNAL_READABLE,
    629                MOJO_DEADLINE_INDEFINITE, &hss),
    630            MOJO_RESULT_OK);
    631   CHECK_EQ(hss.satisfied_signals,
    632            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
    633   CHECK_EQ(hss.satisfiable_signals, MOJO_HANDLE_SIGNAL_READABLE |
    634                                     MOJO_HANDLE_SIGNAL_WRITABLE |
    635                                     MOJO_HANDLE_SIGNAL_PEER_CLOSED);
    636 
    637   std::string read_buffer(100, '\0');
    638   uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
    639   CHECK_EQ(MojoReadMessage(handles[0], &read_buffer[0],
    640                            &read_buffer_size, nullptr,
    641                            0, MOJO_READ_MESSAGE_FLAG_NONE),
    642            MOJO_RESULT_OK);
    643   read_buffer.resize(read_buffer_size);
    644   CHECK_EQ(read_buffer, std::string("hello"));
    645 
    646   // Now write some data into the message pipe.
    647   std::string write_buffer = "world";
    648   CHECK_EQ(MojoWriteMessage(handles[0], write_buffer.data(),
    649                             static_cast<uint32_t>(write_buffer.size()),
    650                             nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE),
    651             MOJO_RESULT_OK);
    652   MojoClose(handles[0]);
    653   return 0;
    654 }
    655 
    656 TEST_F(MultiprocessMessagePipeTest, DataPipeConsumer) {
    657   RUN_CHILD_ON_PIPE(DataPipeConsumer, h)
    658     MojoCreateSharedBufferOptions options;
    659     options.struct_size = sizeof(options);
    660     options.flags = MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE;
    661 
    662     MojoHandle mp1, mp2;
    663     ASSERT_EQ(MOJO_RESULT_OK,
    664               MojoCreateMessagePipe(nullptr, &mp2, &mp1));
    665 
    666     // Write a string into one end of the new message pipe and send the other
    667     // end.
    668     const std::string hello("hello");
    669     ASSERT_EQ(MOJO_RESULT_OK,
    670               MojoWriteMessage(mp1, &hello[0],
    671                                static_cast<uint32_t>(hello.size()), nullptr, 0u,
    672                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    673     ASSERT_EQ(MOJO_RESULT_OK,
    674               MojoWriteMessage(h, nullptr, 0, &mp2, 1u,
    675                                MOJO_WRITE_MESSAGE_FLAG_NONE));
    676 
    677     // Wait for a message from the child.
    678     HandleSignalsState hss;
    679     ASSERT_EQ(MOJO_RESULT_OK,
    680               MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
    681                        MOJO_DEADLINE_INDEFINITE, &hss));
    682     EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
    683     EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
    684 
    685     std::string read_buffer(100, '\0');
    686     uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
    687     CHECK_EQ(MojoReadMessage(mp1, &read_buffer[0],
    688                              &read_buffer_size, nullptr,
    689                              0, MOJO_READ_MESSAGE_FLAG_NONE),
    690              MOJO_RESULT_OK);
    691     read_buffer.resize(read_buffer_size);
    692     CHECK_EQ(read_buffer, std::string("world"));
    693 
    694     MojoClose(mp1);
    695   END_CHILD();
    696 }
    697 
    698 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, CreateMessagePipe) {
    699   MojoHandle p0, p1;
    700   CreateMessagePipe(&p0, &p1);
    701   VerifyTransmission(p0, p1, std::string(10 * 1024 * 1024, 'a'));
    702   VerifyTransmission(p1, p0, std::string(10 * 1024 * 1024, 'e'));
    703 
    704   CloseHandle(p0);
    705   CloseHandle(p1);
    706 }
    707 
    708 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, PassMessagePipeLocal) {
    709   MojoHandle p0, p1;
    710   CreateMessagePipe(&p0, &p1);
    711   VerifyTransmission(p0, p1, "testing testing");
    712   VerifyTransmission(p1, p0, "one two three");
    713 
    714   MojoHandle p2, p3;
    715 
    716   CreateMessagePipe(&p2, &p3);
    717   VerifyTransmission(p2, p3, "testing testing");
    718   VerifyTransmission(p3, p2, "one two three");
    719 
    720   // Pass p2 over p0 to p1.
    721   const std::string message = "ceci n'est pas une pipe";
    722   WriteMessageWithHandles(p0, message, &p2, 1);
    723   EXPECT_EQ(message, ReadMessageWithHandles(p1, &p2, 1));
    724 
    725   CloseHandle(p0);
    726   CloseHandle(p1);
    727 
    728   // Verify that the received handle (now in p2) still works.
    729   VerifyTransmission(p2, p3, "Easy come, easy go; will you let me go?");
    730   VerifyTransmission(p3, p2, "Bismillah! NO! We will not let you go!");
    731 
    732   CloseHandle(p2);
    733   CloseHandle(p3);
    734 }
    735 
    736 // Echos the primordial channel until "exit".
    737 DEFINE_TEST_CLIENT_WITH_PIPE(ChannelEchoClient, MultiprocessMessagePipeTest,
    738                              h) {
    739   for (;;) {
    740     std::string message = ReadMessage(h);
    741     if (message == "exit")
    742       break;
    743     WriteMessage(h, message);
    744   }
    745   return 0;
    746 }
    747 
    748 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, MultiprocessChannelPipe) {
    749   RUN_CHILD_ON_PIPE(ChannelEchoClient, h)
    750     VerifyEcho(h, "in an interstellar burst");
    751     VerifyEcho(h, "i am back to save the universe");
    752     VerifyEcho(h, std::string(10 * 1024 * 1024, 'o'));
    753 
    754     WriteMessage(h, "exit");
    755   END_CHILD()
    756 }
    757 
    758 // Receives a pipe handle from the primordial channel and echos on it until
    759 // "exit". Used to test simple pipe transfer across processes via channels.
    760 DEFINE_TEST_CLIENT_WITH_PIPE(EchoServiceClient, MultiprocessMessagePipeTest,
    761                              h) {
    762   MojoHandle p;
    763   ReadMessageWithHandles(h, &p, 1);
    764   for (;;) {
    765     std::string message = ReadMessage(p);
    766     if (message == "exit")
    767       break;
    768     WriteMessage(p, message);
    769   }
    770   return 0;
    771 }
    772 
    773 TEST_P(MultiprocessMessagePipeTestWithPeerSupport,
    774        PassMessagePipeCrossProcess) {
    775   MojoHandle p0, p1;
    776   CreateMessagePipe(&p0, &p1);
    777   RUN_CHILD_ON_PIPE(EchoServiceClient, h)
    778 
    779     // Pass one end of the pipe to the other process.
    780     WriteMessageWithHandles(h, "here take this", &p1, 1);
    781 
    782     VerifyEcho(p0, "and you may ask yourself");
    783     VerifyEcho(p0, "where does that highway go?");
    784     VerifyEcho(p0, std::string(20 * 1024 * 1024, 'i'));
    785 
    786     WriteMessage(p0, "exit");
    787   END_CHILD()
    788   CloseHandle(p0);
    789 }
    790 
    791 // Receives a pipe handle from the primordial channel and reads new handles
    792 // from it. Each read handle establishes a new echo channel.
    793 DEFINE_TEST_CLIENT_WITH_PIPE(EchoServiceFactoryClient,
    794                              MultiprocessMessagePipeTest, h) {
    795   MojoHandle p;
    796   ReadMessageWithHandles(h, &p, 1);
    797 
    798   std::vector<MojoHandle> handles(2);
    799   handles[0] = h;
    800   handles[1] = p;
    801   std::vector<MojoHandleSignals> signals(2, MOJO_HANDLE_SIGNAL_READABLE);
    802   for (;;) {
    803     uint32_t index;
    804     CHECK_EQ(MojoWaitMany(handles.data(), signals.data(),
    805                           static_cast<uint32_t>(handles.size()),
    806                           MOJO_DEADLINE_INDEFINITE, &index, nullptr),
    807              MOJO_RESULT_OK);
    808     DCHECK_LE(index, handles.size());
    809     if (index == 0) {
    810       // If data is available on the first pipe, it should be an exit command.
    811       EXPECT_EQ(std::string("exit"), ReadMessage(h));
    812       break;
    813     } else if (index == 1) {
    814       // If the second pipe, it should be a new handle requesting echo service.
    815       MojoHandle echo_request;
    816       ReadMessageWithHandles(p, &echo_request, 1);
    817       handles.push_back(echo_request);
    818       signals.push_back(MOJO_HANDLE_SIGNAL_READABLE);
    819     } else {
    820       // Otherwise it was one of our established echo pipes. Echo!
    821       WriteMessage(handles[index], ReadMessage(handles[index]));
    822     }
    823   }
    824 
    825   for (size_t i = 1; i < handles.size(); ++i)
    826     CloseHandle(handles[i]);
    827 
    828   return 0;
    829 }
    830 
    831 TEST_P(MultiprocessMessagePipeTestWithPeerSupport,
    832        PassMoarMessagePipesCrossProcess) {
    833   MojoHandle echo_factory_proxy, echo_factory_request;
    834   CreateMessagePipe(&echo_factory_proxy, &echo_factory_request);
    835 
    836   MojoHandle echo_proxy_a, echo_request_a;
    837   CreateMessagePipe(&echo_proxy_a, &echo_request_a);
    838 
    839   MojoHandle echo_proxy_b, echo_request_b;
    840   CreateMessagePipe(&echo_proxy_b, &echo_request_b);
    841 
    842   MojoHandle echo_proxy_c, echo_request_c;
    843   CreateMessagePipe(&echo_proxy_c, &echo_request_c);
    844 
    845   RUN_CHILD_ON_PIPE(EchoServiceFactoryClient, h)
    846     WriteMessageWithHandles(
    847         h, "gief factory naow plz", &echo_factory_request, 1);
    848 
    849     WriteMessageWithHandles(echo_factory_proxy, "give me an echo service plz!",
    850                            &echo_request_a, 1);
    851     WriteMessageWithHandles(echo_factory_proxy, "give me one too!",
    852                            &echo_request_b, 1);
    853 
    854     VerifyEcho(echo_proxy_a, "i came here for an argument");
    855     VerifyEcho(echo_proxy_a, "shut your festering gob");
    856     VerifyEcho(echo_proxy_a, "mumble mumble mumble");
    857 
    858     VerifyEcho(echo_proxy_b, "wubalubadubdub");
    859     VerifyEcho(echo_proxy_b, "wubalubadubdub");
    860 
    861     WriteMessageWithHandles(echo_factory_proxy, "hook me up also thanks",
    862                            &echo_request_c, 1);
    863 
    864     VerifyEcho(echo_proxy_a, "the frobinators taste like frobinators");
    865     VerifyEcho(echo_proxy_b, "beep bop boop");
    866     VerifyEcho(echo_proxy_c, "zzzzzzzzzzzzzzzzzzzzzzzzzz");
    867 
    868     WriteMessage(h, "exit");
    869   END_CHILD()
    870 
    871   CloseHandle(echo_factory_proxy);
    872   CloseHandle(echo_proxy_a);
    873   CloseHandle(echo_proxy_b);
    874   CloseHandle(echo_proxy_c);
    875 }
    876 
    877 TEST_P(MultiprocessMessagePipeTestWithPeerSupport,
    878        ChannelPipesWithMultipleChildren) {
    879   RUN_CHILD_ON_PIPE(ChannelEchoClient, a)
    880     RUN_CHILD_ON_PIPE(ChannelEchoClient, b)
    881       VerifyEcho(a, "hello child 0");
    882       VerifyEcho(b, "hello child 1");
    883 
    884       WriteMessage(a, "exit");
    885       WriteMessage(b, "exit");
    886     END_CHILD()
    887   END_CHILD()
    888 }
    889 
    890 // Reads and turns a pipe handle some number of times to create lots of
    891 // transient proxies.
    892 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(PingPongPipeClient,
    893                                   MultiprocessMessagePipeTest, h) {
    894   const size_t kNumBounces = 50;
    895   MojoHandle p0, p1;
    896   ReadMessageWithHandles(h, &p0, 1);
    897   ReadMessageWithHandles(h, &p1, 1);
    898   for (size_t i = 0; i < kNumBounces; ++i) {
    899     WriteMessageWithHandles(h, "", &p1, 1);
    900     ReadMessageWithHandles(h, &p1, 1);
    901   }
    902   WriteMessageWithHandles(h, "", &p0, 1);
    903   WriteMessage(p1, "bye");
    904   MojoClose(p1);
    905   EXPECT_EQ("quit", ReadMessage(h));
    906 }
    907 
    908 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, PingPongPipe) {
    909   MojoHandle p0, p1;
    910   CreateMessagePipe(&p0, &p1);
    911 
    912   RUN_CHILD_ON_PIPE(PingPongPipeClient, h)
    913     const size_t kNumBounces = 50;
    914     WriteMessageWithHandles(h, "", &p0, 1);
    915     WriteMessageWithHandles(h, "", &p1, 1);
    916     for (size_t i = 0; i < kNumBounces; ++i) {
    917       ReadMessageWithHandles(h, &p1, 1);
    918       WriteMessageWithHandles(h, "", &p1, 1);
    919     }
    920     ReadMessageWithHandles(h, &p0, 1);
    921     WriteMessage(h, "quit");
    922   END_CHILD()
    923 
    924   EXPECT_EQ("bye", ReadMessage(p0));
    925 
    926   // We should still be able to observe peer closure from the other end.
    927   EXPECT_EQ(MOJO_RESULT_OK,
    928             MojoWait(p0, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    929                      MOJO_DEADLINE_INDEFINITE, nullptr));
    930 }
    931 
    932 // Parses commands from the parent pipe and does whatever it's asked to do.
    933 DEFINE_TEST_CLIENT_WITH_PIPE(CommandDrivenClient, MultiprocessMessagePipeTest,
    934                              h) {
    935   base::hash_map<std::string, MojoHandle> named_pipes;
    936   for (;;) {
    937     MojoHandle p;
    938     auto parts = base::SplitString(ReadMessageWithOptionalHandle(h, &p), ":",
    939                                    base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    940     CHECK(!parts.empty());
    941     std::string command = parts[0];
    942     if (command == "take") {
    943       // Take a pipe.
    944       CHECK_EQ(parts.size(), 2u);
    945       CHECK_NE(p, MOJO_HANDLE_INVALID);
    946       named_pipes[parts[1]] = p;
    947       WriteMessage(h, "ok");
    948     } else if (command == "return") {
    949       // Return a pipe.
    950       CHECK_EQ(parts.size(), 2u);
    951       CHECK_EQ(p, MOJO_HANDLE_INVALID);
    952       p = named_pipes[parts[1]];
    953       CHECK_NE(p, MOJO_HANDLE_INVALID);
    954       named_pipes.erase(parts[1]);
    955       WriteMessageWithHandles(h, "ok", &p, 1);
    956     } else if (command == "say") {
    957       // Say something to a named pipe.
    958       CHECK_EQ(parts.size(), 3u);
    959       CHECK_EQ(p, MOJO_HANDLE_INVALID);
    960       p = named_pipes[parts[1]];
    961       CHECK_NE(p, MOJO_HANDLE_INVALID);
    962       CHECK(!parts[2].empty());
    963       WriteMessage(p, parts[2]);
    964       WriteMessage(h, "ok");
    965     } else if (command == "hear") {
    966       // Expect to read something from a named pipe.
    967       CHECK_EQ(parts.size(), 3u);
    968       CHECK_EQ(p, MOJO_HANDLE_INVALID);
    969       p = named_pipes[parts[1]];
    970       CHECK_NE(p, MOJO_HANDLE_INVALID);
    971       CHECK(!parts[2].empty());
    972       CHECK_EQ(parts[2], ReadMessage(p));
    973       WriteMessage(h, "ok");
    974     } else if (command == "pass") {
    975       // Pass one named pipe over another named pipe.
    976       CHECK_EQ(parts.size(), 3u);
    977       CHECK_EQ(p, MOJO_HANDLE_INVALID);
    978       p = named_pipes[parts[1]];
    979       MojoHandle carrier = named_pipes[parts[2]];
    980       CHECK_NE(p, MOJO_HANDLE_INVALID);
    981       CHECK_NE(carrier, MOJO_HANDLE_INVALID);
    982       named_pipes.erase(parts[1]);
    983       WriteMessageWithHandles(carrier, "got a pipe for ya", &p, 1);
    984       WriteMessage(h, "ok");
    985     } else if (command == "catch") {
    986       // Expect to receive one named pipe from another named pipe.
    987       CHECK_EQ(parts.size(), 3u);
    988       CHECK_EQ(p, MOJO_HANDLE_INVALID);
    989       MojoHandle carrier = named_pipes[parts[2]];
    990       CHECK_NE(carrier, MOJO_HANDLE_INVALID);
    991       ReadMessageWithHandles(carrier, &p, 1);
    992       CHECK_NE(p, MOJO_HANDLE_INVALID);
    993       named_pipes[parts[1]] = p;
    994       WriteMessage(h, "ok");
    995     } else if (command == "exit") {
    996       CHECK_EQ(parts.size(), 1u);
    997       break;
    998     }
    999   }
   1000 
   1001   for (auto& pipe : named_pipes)
   1002     CloseHandle(pipe.second);
   1003 
   1004   return 0;
   1005 }
   1006 
   1007 TEST_F(MultiprocessMessagePipeTest, ChildToChildPipes) {
   1008   RUN_CHILD_ON_PIPE(CommandDrivenClient, h0)
   1009     RUN_CHILD_ON_PIPE(CommandDrivenClient, h1)
   1010       CommandDrivenClientController a(h0);
   1011       CommandDrivenClientController b(h1);
   1012 
   1013       // Create a pipe and pass each end to a different client.
   1014       MojoHandle p0, p1;
   1015       CreateMessagePipe(&p0, &p1);
   1016       a.SendHandle("x", p0);
   1017       b.SendHandle("y", p1);
   1018 
   1019       // Make sure they can talk.
   1020       a.Send("say:x:hello");
   1021       b.Send("hear:y:hello");
   1022 
   1023       b.Send("say:y:i love multiprocess pipes!");
   1024       a.Send("hear:x:i love multiprocess pipes!");
   1025 
   1026       a.Exit();
   1027       b.Exit();
   1028     END_CHILD()
   1029   END_CHILD()
   1030 }
   1031 
   1032 TEST_F(MultiprocessMessagePipeTest, MoreChildToChildPipes) {
   1033   RUN_CHILD_ON_PIPE(CommandDrivenClient, h0)
   1034     RUN_CHILD_ON_PIPE(CommandDrivenClient, h1)
   1035       RUN_CHILD_ON_PIPE(CommandDrivenClient, h2)
   1036         RUN_CHILD_ON_PIPE(CommandDrivenClient, h3)
   1037           CommandDrivenClientController a(h0), b(h1), c(h2), d(h3);
   1038 
   1039           // Connect a to b and c to d
   1040 
   1041           MojoHandle p0, p1;
   1042 
   1043           CreateMessagePipe(&p0, &p1);
   1044           a.SendHandle("b_pipe", p0);
   1045           b.SendHandle("a_pipe", p1);
   1046 
   1047           MojoHandle p2, p3;
   1048 
   1049           CreateMessagePipe(&p2, &p3);
   1050           c.SendHandle("d_pipe", p2);
   1051           d.SendHandle("c_pipe", p3);
   1052 
   1053           // Connect b to c via a and d
   1054           MojoHandle p4, p5;
   1055           CreateMessagePipe(&p4, &p5);
   1056           a.SendHandle("d_pipe", p4);
   1057           d.SendHandle("a_pipe", p5);
   1058 
   1059           // Have |a| pass its new |d|-pipe to |b|. It will eventually connect
   1060           // to |c|.
   1061           a.Send("pass:d_pipe:b_pipe");
   1062           b.Send("catch:c_pipe:a_pipe");
   1063 
   1064           // Have |d| pass its new |a|-pipe to |c|. It will now be connected to
   1065           // |b|.
   1066           d.Send("pass:a_pipe:c_pipe");
   1067           c.Send("catch:b_pipe:d_pipe");
   1068 
   1069           // Make sure b and c and talk.
   1070           b.Send("say:c_pipe:it's a beautiful day");
   1071           c.Send("hear:b_pipe:it's a beautiful day");
   1072 
   1073           // Create x and y and have b and c exchange them.
   1074           MojoHandle x, y;
   1075           CreateMessagePipe(&x, &y);
   1076           b.SendHandle("x", x);
   1077           c.SendHandle("y", y);
   1078           b.Send("pass:x:c_pipe");
   1079           c.Send("pass:y:b_pipe");
   1080           b.Send("catch:y:c_pipe");
   1081           c.Send("catch:x:b_pipe");
   1082 
   1083           // Make sure the pipe still works in both directions.
   1084           b.Send("say:y:hello");
   1085           c.Send("hear:x:hello");
   1086           c.Send("say:x:goodbye");
   1087           b.Send("hear:y:goodbye");
   1088 
   1089           // Take both pipes back.
   1090           y = c.RetrieveHandle("x");
   1091           x = b.RetrieveHandle("y");
   1092 
   1093           VerifyTransmission(x, y, "still works");
   1094           VerifyTransmission(y, x, "in both directions");
   1095 
   1096           CloseHandle(x);
   1097           CloseHandle(y);
   1098 
   1099           a.Exit();
   1100           b.Exit();
   1101           c.Exit();
   1102           d.Exit();
   1103         END_CHILD()
   1104       END_CHILD()
   1105     END_CHILD()
   1106   END_CHILD()
   1107 }
   1108 
   1109 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(ReceivePipeWithClosedPeer,
   1110                                   MultiprocessMessagePipeTest, h) {
   1111   MojoHandle p;
   1112   EXPECT_EQ("foo", ReadMessageWithHandles(h, &p, 1));
   1113 
   1114   auto result = MojoWait(p, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
   1115                          MOJO_DEADLINE_INDEFINITE, nullptr);
   1116   EXPECT_EQ(MOJO_RESULT_OK, result);
   1117 }
   1118 
   1119 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, SendPipeThenClosePeer) {
   1120   RUN_CHILD_ON_PIPE(ReceivePipeWithClosedPeer, h)
   1121     MojoHandle a, b;
   1122     CreateMessagePipe(&a, &b);
   1123 
   1124     // Send |a| and immediately close |b|. The child should observe closure.
   1125     WriteMessageWithHandles(h, "foo", &a, 1);
   1126     MojoClose(b);
   1127   END_CHILD()
   1128 }
   1129 
   1130 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(SendOtherChildPipeWithClosedPeer,
   1131                                   MultiprocessMessagePipeTest, h) {
   1132   // Create a new pipe and send one end to the parent, who will connect it to
   1133   // a client running ReceivePipeWithClosedPeerFromOtherChild.
   1134   MojoHandle application_proxy, application_request;
   1135   CreateMessagePipe(&application_proxy, &application_request);
   1136   WriteMessageWithHandles(h, "c2a plz", &application_request, 1);
   1137 
   1138   // Create another pipe and send one end to the remote "application".
   1139   MojoHandle service_proxy, service_request;
   1140   CreateMessagePipe(&service_proxy, &service_request);
   1141   WriteMessageWithHandles(application_proxy, "c2s lol", &service_request, 1);
   1142 
   1143   // Immediately close the service proxy. The "application" should detect this.
   1144   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(service_proxy));
   1145 
   1146   // Wait for quit.
   1147   EXPECT_EQ("quit", ReadMessage(h));
   1148 }
   1149 
   1150 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(ReceivePipeWithClosedPeerFromOtherChild,
   1151                                   MultiprocessMessagePipeTest, h) {
   1152   // Receive a pipe from the parent. This is akin to an "application request".
   1153   MojoHandle application_client;
   1154   EXPECT_EQ("c2a", ReadMessageWithHandles(h, &application_client, 1));
   1155 
   1156   // Receive a pipe from the "application" "client".
   1157   MojoHandle service_client;
   1158   EXPECT_EQ("c2s lol",
   1159             ReadMessageWithHandles(application_client, &service_client, 1));
   1160 
   1161   // Wait for the service client to signal closure.
   1162   EXPECT_EQ(MOJO_RESULT_OK, MojoWait(service_client,
   1163                                      MOJO_HANDLE_SIGNAL_PEER_CLOSED,
   1164                                      MOJO_DEADLINE_INDEFINITE, nullptr));
   1165 
   1166   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(service_client));
   1167   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(application_client));
   1168 }
   1169 
   1170 #if defined(OS_ANDROID)
   1171 // Android multi-process tests are not executing the new process. This is flaky.
   1172 #define MAYBE_SendPipeWithClosedPeerBetweenChildren \
   1173     DISABLED_SendPipeWithClosedPeerBetweenChildren
   1174 #else
   1175 #define MAYBE_SendPipeWithClosedPeerBetweenChildren \
   1176     SendPipeWithClosedPeerBetweenChildren
   1177 #endif
   1178 TEST_F(MultiprocessMessagePipeTest,
   1179        MAYBE_SendPipeWithClosedPeerBetweenChildren) {
   1180   RUN_CHILD_ON_PIPE(SendOtherChildPipeWithClosedPeer, kid_a)
   1181     RUN_CHILD_ON_PIPE(ReceivePipeWithClosedPeerFromOtherChild, kid_b)
   1182       // Receive an "application request" from the first child and forward it
   1183       // to the second child.
   1184       MojoHandle application_request;
   1185       EXPECT_EQ("c2a plz",
   1186                 ReadMessageWithHandles(kid_a, &application_request, 1));
   1187 
   1188       WriteMessageWithHandles(kid_b, "c2a", &application_request, 1);
   1189     END_CHILD()
   1190 
   1191     WriteMessage(kid_a, "quit");
   1192   END_CHILD()
   1193 }
   1194 
   1195 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, SendClosePeerSend) {
   1196   MojoHandle a, b;
   1197   CreateMessagePipe(&a, &b);
   1198 
   1199   MojoHandle c, d;
   1200   CreateMessagePipe(&c, &d);
   1201 
   1202   // Send |a| over |c|, immediately close |b|, then send |a| back over |d|.
   1203   WriteMessageWithHandles(c, "foo", &a, 1);
   1204   EXPECT_EQ("foo", ReadMessageWithHandles(d, &a, 1));
   1205   WriteMessageWithHandles(d, "bar", &a, 1);
   1206   EXPECT_EQ("bar", ReadMessageWithHandles(c, &a, 1));
   1207   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(b));
   1208 
   1209   // We should be able to detect peer closure on |a|.
   1210   EXPECT_EQ(MOJO_RESULT_OK, MojoWait(a, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
   1211                                      MOJO_DEADLINE_INDEFINITE, nullptr));
   1212 }
   1213 
   1214 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(WriteCloseSendPeerClient,
   1215                                   MultiprocessMessagePipeTest, h) {
   1216   MojoHandle pipe[2];
   1217   EXPECT_EQ("foo", ReadMessageWithHandles(h, pipe, 2));
   1218 
   1219   // Write some messages to the first endpoint and then close it.
   1220   WriteMessage(pipe[0], "baz");
   1221   WriteMessage(pipe[0], "qux");
   1222   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(pipe[0]));
   1223 
   1224   MojoHandle c, d;
   1225   CreateMessagePipe(&c, &d);
   1226 
   1227   // Pass the orphaned endpoint over another pipe before passing it back to
   1228   // the parent, just for some extra proxying goodness.
   1229   WriteMessageWithHandles(c, "foo", &pipe[1], 1);
   1230   EXPECT_EQ("foo", ReadMessageWithHandles(d, &pipe[1], 1));
   1231 
   1232   // And finally pass it back to the parent.
   1233   WriteMessageWithHandles(h, "bar", &pipe[1], 1);
   1234 
   1235   EXPECT_EQ("quit", ReadMessage(h));
   1236 }
   1237 
   1238 TEST_P(MultiprocessMessagePipeTestWithPeerSupport, WriteCloseSendPeer) {
   1239   MojoHandle pipe[2];
   1240   CreateMessagePipe(&pipe[0], &pipe[1]);
   1241 
   1242   RUN_CHILD_ON_PIPE(WriteCloseSendPeerClient, h)
   1243     // Pass the pipe to the child.
   1244     WriteMessageWithHandles(h, "foo", pipe, 2);
   1245 
   1246     // Read back an endpoint which should have messages on it.
   1247     MojoHandle p;
   1248     EXPECT_EQ("bar", ReadMessageWithHandles(h, &p, 1));
   1249 
   1250     EXPECT_EQ("baz", ReadMessage(p));
   1251     EXPECT_EQ("qux", ReadMessage(p));
   1252 
   1253     // Expect to have peer closure signaled.
   1254     EXPECT_EQ(MOJO_RESULT_OK, MojoWait(p, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
   1255                                        MOJO_DEADLINE_INDEFINITE, nullptr));
   1256 
   1257     WriteMessage(h, "quit");
   1258   END_CHILD()
   1259 }
   1260 
   1261 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MessagePipeStatusChangeInTransitClient,
   1262                                   MultiprocessMessagePipeTest, parent) {
   1263   // This test verifies that peer closure is detectable through various
   1264   // mechanisms when it races with handle transfer.
   1265   MojoHandle handles[4];
   1266   EXPECT_EQ("o_O", ReadMessageWithHandles(parent, handles, 4));
   1267 
   1268   // Wait on handle 0 using MojoWait.
   1269   EXPECT_EQ(MOJO_RESULT_OK, MojoWait(handles[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED,
   1270                                      MOJO_DEADLINE_INDEFINITE, nullptr));
   1271 
   1272   base::MessageLoop message_loop;
   1273 
   1274   // Wait on handle 1 using a Watcher.
   1275   {
   1276     base::RunLoop run_loop;
   1277     Watcher watcher(FROM_HERE);
   1278     watcher.Start(Handle(handles[1]), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
   1279                   base::Bind([] (base::RunLoop* loop, MojoResult result) {
   1280                     EXPECT_EQ(MOJO_RESULT_OK, result);
   1281                     loop->Quit();
   1282                   }, &run_loop));
   1283     run_loop.Run();
   1284   }
   1285 
   1286   // Wait on handle 2 by polling with MojoReadMessage.
   1287   MojoResult result;
   1288   do {
   1289     result = MojoReadMessage(handles[2], nullptr, nullptr, nullptr, nullptr,
   1290                              MOJO_READ_MESSAGE_FLAG_NONE);
   1291   } while (result == MOJO_RESULT_SHOULD_WAIT);
   1292   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
   1293 
   1294   // Wait on handle 3 by polling with MojoWriteMessage.
   1295   do {
   1296     result = MojoWriteMessage(handles[3], nullptr, 0, nullptr, 0,
   1297                               MOJO_WRITE_MESSAGE_FLAG_NONE);
   1298   } while (result == MOJO_RESULT_OK);
   1299   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
   1300 
   1301   for (size_t i = 0; i < 4; ++i)
   1302     CloseHandle(handles[i]);
   1303 }
   1304 
   1305 TEST_F(MultiprocessMessagePipeTest, MessagePipeStatusChangeInTransit) {
   1306   MojoHandle local_handles[4];
   1307   MojoHandle sent_handles[4];
   1308   for (size_t i = 0; i < 4; ++i)
   1309     CreateMessagePipe(&local_handles[i], &sent_handles[i]);
   1310 
   1311   RUN_CHILD_ON_PIPE(MessagePipeStatusChangeInTransitClient, child)
   1312     // Send 4 handles and let their transfer race with their peers' closure.
   1313     WriteMessageWithHandles(child, "o_O", sent_handles, 4);
   1314     for (size_t i = 0; i < 4; ++i)
   1315       CloseHandle(local_handles[i]);
   1316   END_CHILD()
   1317 }
   1318 
   1319 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(BadMessageClient, MultiprocessMessagePipeTest,
   1320                                   parent) {
   1321   MojoHandle pipe;
   1322   EXPECT_EQ("hi", ReadMessageWithHandles(parent, &pipe, 1));
   1323   WriteMessage(pipe, "derp");
   1324   EXPECT_EQ("bye", ReadMessage(parent));
   1325 }
   1326 
   1327 void OnProcessError(std::string* out_error, const std::string& error) {
   1328   *out_error = error;
   1329 }
   1330 
   1331 TEST_F(MultiprocessMessagePipeTest, NotifyBadMessage) {
   1332   const std::string kFirstErrorMessage = "everything is terrible!";
   1333   const std::string kSecondErrorMessage = "not the bits you're looking for";
   1334 
   1335   std::string first_process_error;
   1336   std::string second_process_error;
   1337 
   1338   set_process_error_callback(base::Bind(&OnProcessError, &first_process_error));
   1339   RUN_CHILD_ON_PIPE(BadMessageClient, child1)
   1340     set_process_error_callback(base::Bind(&OnProcessError,
   1341                                           &second_process_error));
   1342     RUN_CHILD_ON_PIPE(BadMessageClient, child2)
   1343       MojoHandle a, b, c, d;
   1344       CreateMessagePipe(&a, &b);
   1345       CreateMessagePipe(&c, &d);
   1346       WriteMessageWithHandles(child1, "hi", &b, 1);
   1347       WriteMessageWithHandles(child2, "hi", &d, 1);
   1348 
   1349       // Read a message from the pipe we sent to child1 and flag it as bad.
   1350       ASSERT_EQ(MOJO_RESULT_OK, MojoWait(a, MOJO_HANDLE_SIGNAL_READABLE,
   1351                                          MOJO_DEADLINE_INDEFINITE, nullptr));
   1352       uint32_t num_bytes = 0;
   1353       MojoMessageHandle message;
   1354       ASSERT_EQ(MOJO_RESULT_OK,
   1355                 MojoReadMessageNew(a, &message, &num_bytes, nullptr, 0,
   1356                                    MOJO_READ_MESSAGE_FLAG_NONE));
   1357       EXPECT_EQ(MOJO_RESULT_OK,
   1358                 MojoNotifyBadMessage(message, kFirstErrorMessage.data(),
   1359                                      kFirstErrorMessage.size()));
   1360       EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message));
   1361 
   1362       // Read a message from the pipe we sent to child2 and flag it as bad.
   1363       ASSERT_EQ(MOJO_RESULT_OK, MojoWait(c, MOJO_HANDLE_SIGNAL_READABLE,
   1364                                          MOJO_DEADLINE_INDEFINITE, nullptr));
   1365       ASSERT_EQ(MOJO_RESULT_OK,
   1366                 MojoReadMessageNew(c, &message, &num_bytes, nullptr, 0,
   1367                                    MOJO_READ_MESSAGE_FLAG_NONE));
   1368       EXPECT_EQ(MOJO_RESULT_OK,
   1369                 MojoNotifyBadMessage(message, kSecondErrorMessage.data(),
   1370                                      kSecondErrorMessage.size()));
   1371       EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message));
   1372 
   1373       WriteMessage(child2, "bye");
   1374     END_CHILD();
   1375 
   1376     WriteMessage(child1, "bye");
   1377   END_CHILD()
   1378 
   1379   // The error messages should match the processes which triggered them.
   1380   EXPECT_NE(std::string::npos, first_process_error.find(kFirstErrorMessage));
   1381   EXPECT_NE(std::string::npos, second_process_error.find(kSecondErrorMessage));
   1382 }
   1383 INSTANTIATE_TEST_CASE_P(
   1384     ,
   1385     MultiprocessMessagePipeTestWithPeerSupport,
   1386     testing::Values(test::MojoTestBase::LaunchType::CHILD,
   1387                     test::MojoTestBase::LaunchType::PEER,
   1388                     test::MojoTestBase::LaunchType::NAMED_CHILD,
   1389                     test::MojoTestBase::LaunchType::NAMED_PEER));
   1390 }  // namespace
   1391 }  // namespace edk
   1392 }  // namespace mojo
   1393