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 <stdint.h>
      6 #include <string.h>
      7 
      8 #include "base/memory/ref_counted.h"
      9 #include "mojo/edk/system/test_utils.h"
     10 #include "mojo/edk/test/mojo_test_base.h"
     11 #include "mojo/public/c/system/core.h"
     12 #include "mojo/public/c/system/types.h"
     13 
     14 namespace mojo {
     15 namespace edk {
     16 namespace {
     17 
     18 const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE |
     19                                       MOJO_HANDLE_SIGNAL_WRITABLE |
     20                                       MOJO_HANDLE_SIGNAL_PEER_CLOSED;
     21 static const char kHelloWorld[] = "hello world";
     22 
     23 class MessagePipeTest : public test::MojoTestBase {
     24  public:
     25   MessagePipeTest() {
     26     CHECK_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &pipe0_, &pipe1_));
     27   }
     28 
     29   ~MessagePipeTest() override {
     30     if (pipe0_ != MOJO_HANDLE_INVALID)
     31       CHECK_EQ(MOJO_RESULT_OK, MojoClose(pipe0_));
     32     if (pipe1_ != MOJO_HANDLE_INVALID)
     33       CHECK_EQ(MOJO_RESULT_OK, MojoClose(pipe1_));
     34   }
     35 
     36   MojoResult WriteMessage(MojoHandle message_pipe_handle,
     37                           const void* bytes,
     38                           uint32_t num_bytes) {
     39     return MojoWriteMessage(message_pipe_handle, bytes, num_bytes, nullptr, 0,
     40                             MOJO_WRITE_MESSAGE_FLAG_NONE);
     41   }
     42 
     43   MojoResult ReadMessage(MojoHandle message_pipe_handle,
     44                          void* bytes,
     45                          uint32_t* num_bytes,
     46                          bool may_discard = false) {
     47     return MojoReadMessage(message_pipe_handle, bytes, num_bytes, nullptr, 0,
     48                            may_discard ? MOJO_READ_MESSAGE_FLAG_MAY_DISCARD :
     49                                          MOJO_READ_MESSAGE_FLAG_NONE);
     50   }
     51 
     52   MojoHandle pipe0_, pipe1_;
     53 
     54  private:
     55   DISALLOW_COPY_AND_ASSIGN(MessagePipeTest);
     56 };
     57 
     58 using FuseMessagePipeTest = test::MojoTestBase;
     59 
     60 TEST_F(MessagePipeTest, WriteData) {
     61   ASSERT_EQ(MOJO_RESULT_OK,
     62             WriteMessage(pipe0_, kHelloWorld, sizeof(kHelloWorld)));
     63 }
     64 
     65 // Tests:
     66 //  - only default flags
     67 //  - reading messages from a port
     68 //    - when there are no/one/two messages available for that port
     69 //    - with buffer size 0 (and null buffer) -- should get size
     70 //    - with too-small buffer -- should get size
     71 //    - also verify that buffers aren't modified when/where they shouldn't be
     72 //  - writing messages to a port
     73 //    - in the obvious scenarios (as above)
     74 //    - to a port that's been closed
     75 //  - writing a message to a port, closing the other (would be the source) port,
     76 //    and reading it
     77 TEST_F(MessagePipeTest, Basic) {
     78   int32_t buffer[2];
     79   const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
     80   uint32_t buffer_size;
     81 
     82   // Nothing to read yet on port 0.
     83   buffer[0] = 123;
     84   buffer[1] = 456;
     85   buffer_size = kBufferSize;
     86   ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, ReadMessage(pipe0_, buffer, &buffer_size));
     87   ASSERT_EQ(kBufferSize, buffer_size);
     88   ASSERT_EQ(123, buffer[0]);
     89   ASSERT_EQ(456, buffer[1]);
     90 
     91   // Ditto for port 1.
     92   buffer[0] = 123;
     93   buffer[1] = 456;
     94   buffer_size = kBufferSize;
     95   ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, ReadMessage(pipe1_, buffer, &buffer_size));
     96 
     97   // Write from port 1 (to port 0).
     98   buffer[0] = 789012345;
     99   buffer[1] = 0;
    100   ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
    101 
    102   MojoHandleSignalsState state;
    103   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
    104                                      MOJO_DEADLINE_INDEFINITE, &state));
    105 
    106   // Read from port 0.
    107   buffer[0] = 123;
    108   buffer[1] = 456;
    109   buffer_size = kBufferSize;
    110   ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe0_, buffer, &buffer_size));
    111   ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
    112   ASSERT_EQ(789012345, buffer[0]);
    113   ASSERT_EQ(456, buffer[1]);
    114 
    115   // Read again from port 0 -- it should be empty.
    116   buffer_size = kBufferSize;
    117   ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, ReadMessage(pipe0_, buffer, &buffer_size));
    118 
    119   // Write two messages from port 0 (to port 1).
    120   buffer[0] = 123456789;
    121   buffer[1] = 0;
    122   ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, sizeof(buffer[0])));
    123   buffer[0] = 234567890;
    124   buffer[1] = 0;
    125   ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, sizeof(buffer[0])));
    126 
    127   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
    128                                      MOJO_DEADLINE_INDEFINITE, &state));
    129 
    130   // Read from port 1 with buffer size 0 (should get the size of next message).
    131   // Also test that giving a null buffer is okay when the buffer size is 0.
    132   buffer_size = 0;
    133   ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
    134             ReadMessage(pipe1_, nullptr, &buffer_size));
    135   ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
    136 
    137   // Read from port 1 with buffer size 1 (too small; should get the size of next
    138   // message).
    139   buffer[0] = 123;
    140   buffer[1] = 456;
    141   buffer_size = 1;
    142   ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
    143             ReadMessage(pipe1_, buffer, &buffer_size));
    144   ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
    145   ASSERT_EQ(123, buffer[0]);
    146   ASSERT_EQ(456, buffer[1]);
    147 
    148   // Read from port 1.
    149   buffer[0] = 123;
    150   buffer[1] = 456;
    151   buffer_size = kBufferSize;
    152   ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe1_, buffer, &buffer_size));
    153   ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
    154   ASSERT_EQ(123456789, buffer[0]);
    155   ASSERT_EQ(456, buffer[1]);
    156 
    157   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
    158                                      MOJO_DEADLINE_INDEFINITE, &state));
    159 
    160   // Read again from port 1.
    161   buffer[0] = 123;
    162   buffer[1] = 456;
    163   buffer_size = kBufferSize;
    164   ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe1_, buffer, &buffer_size));
    165   ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
    166   ASSERT_EQ(234567890, buffer[0]);
    167   ASSERT_EQ(456, buffer[1]);
    168 
    169   // Read again from port 1 -- it should be empty.
    170   buffer_size = kBufferSize;
    171   ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, ReadMessage(pipe1_, buffer, &buffer_size));
    172 
    173   // Write from port 0 (to port 1).
    174   buffer[0] = 345678901;
    175   buffer[1] = 0;
    176   ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, sizeof(buffer[0])));
    177 
    178   // Close port 0.
    179   MojoClose(pipe0_);
    180   pipe0_ = MOJO_HANDLE_INVALID;
    181 
    182   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    183                                      MOJO_DEADLINE_INDEFINITE, &state));
    184 
    185   // Try to write from port 1 (to port 0).
    186   buffer[0] = 456789012;
    187   buffer[1] = 0;
    188   ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
    189             WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
    190 
    191   // Read from port 1; should still get message (even though port 0 was closed).
    192   buffer[0] = 123;
    193   buffer[1] = 456;
    194   buffer_size = kBufferSize;
    195   ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe1_, buffer, &buffer_size));
    196   ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
    197   ASSERT_EQ(345678901, buffer[0]);
    198   ASSERT_EQ(456, buffer[1]);
    199 
    200   // Read again from port 1 -- it should be empty (and port 0 is closed).
    201   buffer_size = kBufferSize;
    202   ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
    203             ReadMessage(pipe1_, buffer, &buffer_size));
    204 }
    205 
    206 TEST_F(MessagePipeTest, CloseWithQueuedIncomingMessages) {
    207   int32_t buffer[1];
    208   const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
    209   uint32_t buffer_size;
    210 
    211   // Write some messages from port 1 (to port 0).
    212   for (int32_t i = 0; i < 5; i++) {
    213     buffer[0] = i;
    214     ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, kBufferSize));
    215   }
    216 
    217   MojoHandleSignalsState state;
    218   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
    219                                      MOJO_DEADLINE_INDEFINITE, &state));
    220 
    221   // Port 0 shouldn't be empty.
    222   buffer_size = 0;
    223   ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
    224             ReadMessage(pipe0_, nullptr, &buffer_size));
    225   ASSERT_EQ(kBufferSize, buffer_size);
    226 
    227   // Close port 0 first, which should have outstanding (incoming) messages.
    228   MojoClose(pipe0_);
    229   MojoClose(pipe1_);
    230   pipe0_ = pipe1_ = MOJO_HANDLE_INVALID;
    231 }
    232 
    233 TEST_F(MessagePipeTest, DiscardMode) {
    234   int32_t buffer[2];
    235   const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
    236   uint32_t buffer_size;
    237 
    238   // Write from port 1 (to port 0).
    239   buffer[0] = 789012345;
    240   buffer[1] = 0;
    241   ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
    242 
    243   MojoHandleSignalsState state;
    244   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
    245                                      MOJO_DEADLINE_INDEFINITE, &state));
    246 
    247   // Read/discard from port 0 (no buffer); get size.
    248   buffer_size = 0;
    249   ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
    250             ReadMessage(pipe0_, nullptr, &buffer_size, true));
    251   ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
    252 
    253   // Read again from port 0 -- it should be empty.
    254   buffer_size = kBufferSize;
    255   ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT,
    256             ReadMessage(pipe0_, buffer, &buffer_size, true));
    257 
    258   // Write from port 1 (to port 0).
    259   buffer[0] = 890123456;
    260   buffer[1] = 0;
    261   ASSERT_EQ(MOJO_RESULT_OK,
    262             WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
    263 
    264   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
    265                                      MOJO_DEADLINE_INDEFINITE, &state));
    266 
    267   // Read from port 0 (buffer big enough).
    268   buffer[0] = 123;
    269   buffer[1] = 456;
    270   buffer_size = kBufferSize;
    271   ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe0_, buffer, &buffer_size, true));
    272   ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
    273   ASSERT_EQ(890123456, buffer[0]);
    274   ASSERT_EQ(456, buffer[1]);
    275 
    276   // Read again from port 0 -- it should be empty.
    277   buffer_size = kBufferSize;
    278   ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT,
    279             ReadMessage(pipe0_, buffer, &buffer_size, true));
    280 
    281   // Write from port 1 (to port 0).
    282   buffer[0] = 901234567;
    283   buffer[1] = 0;
    284   ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
    285 
    286   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
    287                                      MOJO_DEADLINE_INDEFINITE, &state));
    288 
    289   // Read/discard from port 0 (buffer too small); get size.
    290   buffer_size = 1;
    291   ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
    292             ReadMessage(pipe0_, buffer, &buffer_size, true));
    293   ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
    294 
    295   // Read again from port 0 -- it should be empty.
    296   buffer_size = kBufferSize;
    297   ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT,
    298             ReadMessage(pipe0_, buffer, &buffer_size, true));
    299 
    300   // Write from port 1 (to port 0).
    301   buffer[0] = 123456789;
    302   buffer[1] = 0;
    303   ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
    304 
    305   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
    306                                      MOJO_DEADLINE_INDEFINITE, &state));
    307 
    308   // Discard from port 0.
    309   buffer_size = 1;
    310   ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
    311             ReadMessage(pipe0_, nullptr, 0, true));
    312 
    313   // Read again from port 0 -- it should be empty.
    314   buffer_size = kBufferSize;
    315   ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT,
    316             ReadMessage(pipe0_, buffer, &buffer_size, true));
    317 }
    318 
    319 TEST_F(MessagePipeTest, BasicWaiting) {
    320   MojoHandleSignalsState hss;
    321 
    322   int32_t buffer[1];
    323   const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
    324   uint32_t buffer_size;
    325 
    326   // Always writable (until the other port is closed).
    327   hss = MojoHandleSignalsState();
    328   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_WRITABLE, 0,
    329                                      &hss));
    330   ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
    331   ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
    332   hss = MojoHandleSignalsState();
    333 
    334   // Not yet readable.
    335   ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
    336             MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
    337   ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
    338   ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
    339 
    340   // The peer is not closed.
    341   hss = MojoHandleSignalsState();
    342   ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
    343             MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, 0, &hss));
    344   ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
    345   ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
    346 
    347   // Write from port 0 (to port 1), to make port 1 readable.
    348   buffer[0] = 123456789;
    349   ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, kBufferSize));
    350 
    351   // Port 1 should already be readable now.
    352   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
    353                                      MOJO_DEADLINE_INDEFINITE, &hss));
    354   ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
    355             hss.satisfied_signals);
    356   ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
    357   // ... and still writable.
    358   hss = MojoHandleSignalsState();
    359   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_WRITABLE,
    360                                      MOJO_DEADLINE_INDEFINITE, &hss));
    361   ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
    362             hss.satisfied_signals);
    363   ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
    364 
    365   // Close port 0.
    366   MojoClose(pipe0_);
    367   pipe0_ = MOJO_HANDLE_INVALID;
    368 
    369   // Port 1 should be signaled with peer closed.
    370   hss = MojoHandleSignalsState();
    371   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    372                                      MOJO_DEADLINE_INDEFINITE, &hss));
    373   ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    374             hss.satisfied_signals);
    375   ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    376             hss.satisfiable_signals);
    377 
    378   // Port 1 should not be writable.
    379   hss = MojoHandleSignalsState();
    380 
    381   ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
    382             MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_WRITABLE,
    383                      MOJO_DEADLINE_INDEFINITE, &hss));
    384   ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    385             hss.satisfied_signals);
    386   ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    387             hss.satisfiable_signals);
    388 
    389   // But it should still be readable.
    390   hss = MojoHandleSignalsState();
    391   ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
    392                                      MOJO_DEADLINE_INDEFINITE, &hss));
    393   ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    394             hss.satisfied_signals);
    395   ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    396             hss.satisfiable_signals);
    397 
    398   // Read from port 1.
    399   buffer[0] = 0;
    400   buffer_size = kBufferSize;
    401   ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe1_, buffer, &buffer_size));
    402   ASSERT_EQ(123456789, buffer[0]);
    403 
    404   // Now port 1 should no longer be readable.
    405   hss = MojoHandleSignalsState();
    406   ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
    407             MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
    408                      MOJO_DEADLINE_INDEFINITE, &hss));
    409   ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
    410   ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
    411 }
    412 
    413 TEST_F(MessagePipeTest, InvalidMessageObjects) {
    414   // null message
    415   ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
    416             MojoFreeMessage(MOJO_MESSAGE_HANDLE_INVALID));
    417 
    418   // null message
    419   ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
    420             MojoGetMessageBuffer(MOJO_MESSAGE_HANDLE_INVALID, nullptr));
    421 
    422   // Non-zero num_handles with null handles array.
    423   ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
    424             MojoAllocMessage(0, nullptr, 1, MOJO_ALLOC_MESSAGE_FLAG_NONE,
    425                              nullptr));
    426 }
    427 
    428 TEST_F(MessagePipeTest, AllocAndFreeMessage) {
    429   const std::string kMessage = "Hello, world.";
    430   MojoMessageHandle message = MOJO_MESSAGE_HANDLE_INVALID;
    431   ASSERT_EQ(MOJO_RESULT_OK,
    432             MojoAllocMessage(static_cast<uint32_t>(kMessage.size()), nullptr, 0,
    433                              MOJO_ALLOC_MESSAGE_FLAG_NONE, &message));
    434   ASSERT_NE(MOJO_MESSAGE_HANDLE_INVALID, message);
    435   ASSERT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message));
    436 }
    437 
    438 TEST_F(MessagePipeTest, WriteAndReadMessageObject) {
    439   const std::string kMessage = "Hello, world.";
    440   MojoMessageHandle message = MOJO_MESSAGE_HANDLE_INVALID;
    441   EXPECT_EQ(MOJO_RESULT_OK,
    442             MojoAllocMessage(static_cast<uint32_t>(kMessage.size()), nullptr, 0,
    443                              MOJO_ALLOC_MESSAGE_FLAG_NONE, &message));
    444   ASSERT_NE(MOJO_MESSAGE_HANDLE_INVALID, message);
    445 
    446   void* buffer = nullptr;
    447   EXPECT_EQ(MOJO_RESULT_OK, MojoGetMessageBuffer(message, &buffer));
    448   ASSERT_TRUE(buffer);
    449   memcpy(buffer, kMessage.data(), kMessage.size());
    450 
    451   MojoHandle a, b;
    452   CreateMessagePipe(&a, &b);
    453   EXPECT_EQ(MOJO_RESULT_OK,
    454             MojoWriteMessageNew(a, message, MOJO_WRITE_MESSAGE_FLAG_NONE));
    455 
    456   EXPECT_EQ(MOJO_RESULT_OK,
    457             MojoWait(b, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
    458                      nullptr));
    459   uint32_t num_bytes = 0;
    460   uint32_t num_handles = 0;
    461   EXPECT_EQ(MOJO_RESULT_OK,
    462             MojoReadMessageNew(b, &message, &num_bytes, nullptr, &num_handles,
    463                                MOJO_READ_MESSAGE_FLAG_NONE));
    464   ASSERT_NE(MOJO_MESSAGE_HANDLE_INVALID, message);
    465   EXPECT_EQ(static_cast<uint32_t>(kMessage.size()), num_bytes);
    466   EXPECT_EQ(0u, num_handles);
    467 
    468   EXPECT_EQ(MOJO_RESULT_OK, MojoGetMessageBuffer(message, &buffer));
    469   ASSERT_TRUE(buffer);
    470 
    471   EXPECT_EQ(0, strncmp(static_cast<const char*>(buffer), kMessage.data(),
    472                        num_bytes));
    473 
    474   EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message));
    475   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a));
    476   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(b));
    477 }
    478 
    479 #if !defined(OS_IOS)
    480 
    481 const size_t kPingPongHandlesPerIteration = 50;
    482 const size_t kPingPongIterations = 500;
    483 
    484 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(HandlePingPong, MessagePipeTest, h) {
    485   // Waits for a handle to become readable and writes it back to the sender.
    486   for (size_t i = 0; i < kPingPongIterations; i++) {
    487     MojoHandle handles[kPingPongHandlesPerIteration];
    488     ReadMessageWithHandles(h, handles, kPingPongHandlesPerIteration);
    489     WriteMessageWithHandles(h, "", handles, kPingPongHandlesPerIteration);
    490   }
    491 
    492   EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
    493                                      MOJO_DEADLINE_INDEFINITE, nullptr));
    494   char msg[4];
    495   uint32_t num_bytes = 4;
    496   EXPECT_EQ(MOJO_RESULT_OK, ReadMessage(h, msg, &num_bytes));
    497 }
    498 
    499 // This test is flaky: http://crbug.com/585784
    500 TEST_F(MessagePipeTest, DISABLED_DataPipeConsumerHandlePingPong) {
    501   MojoHandle p, c[kPingPongHandlesPerIteration];
    502   for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i) {
    503     EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(nullptr, &p, &c[i]));
    504     MojoClose(p);
    505   }
    506 
    507   RUN_CHILD_ON_PIPE(HandlePingPong, h)
    508     for (size_t i = 0; i < kPingPongIterations; i++) {
    509       WriteMessageWithHandles(h, "", c, kPingPongHandlesPerIteration);
    510       ReadMessageWithHandles(h, c, kPingPongHandlesPerIteration);
    511     }
    512     WriteMessage(h, "quit", 4);
    513   END_CHILD()
    514   for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i)
    515     MojoClose(c[i]);
    516 }
    517 
    518 // This test is flaky: http://crbug.com/585784
    519 TEST_F(MessagePipeTest, DISABLED_DataPipeProducerHandlePingPong) {
    520   MojoHandle p[kPingPongHandlesPerIteration], c;
    521   for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i) {
    522     EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(nullptr, &p[i], &c));
    523     MojoClose(c);
    524   }
    525 
    526   RUN_CHILD_ON_PIPE(HandlePingPong, h)
    527     for (size_t i = 0; i < kPingPongIterations; i++) {
    528       WriteMessageWithHandles(h, "", p, kPingPongHandlesPerIteration);
    529       ReadMessageWithHandles(h, p, kPingPongHandlesPerIteration);
    530     }
    531     WriteMessage(h, "quit", 4);
    532   END_CHILD()
    533   for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i)
    534     MojoClose(p[i]);
    535 }
    536 
    537 TEST_F(MessagePipeTest, SharedBufferHandlePingPong) {
    538   MojoHandle buffers[kPingPongHandlesPerIteration];
    539   for (size_t i = 0; i <kPingPongHandlesPerIteration; ++i)
    540     EXPECT_EQ(MOJO_RESULT_OK, MojoCreateSharedBuffer(nullptr, 1, &buffers[i]));
    541 
    542   RUN_CHILD_ON_PIPE(HandlePingPong, h)
    543     for (size_t i = 0; i < kPingPongIterations; i++) {
    544       WriteMessageWithHandles(h, "", buffers, kPingPongHandlesPerIteration);
    545       ReadMessageWithHandles(h, buffers, kPingPongHandlesPerIteration);
    546     }
    547     WriteMessage(h, "quit", 4);
    548   END_CHILD()
    549   for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i)
    550     MojoClose(buffers[i]);
    551 }
    552 
    553 #endif  // !defined(OS_IOS)
    554 
    555 TEST_F(FuseMessagePipeTest, Basic) {
    556   // Test that we can fuse pipes and they still work.
    557 
    558   MojoHandle a, b, c, d;
    559   CreateMessagePipe(&a, &b);
    560   CreateMessagePipe(&c, &d);
    561 
    562   EXPECT_EQ(MOJO_RESULT_OK, MojoFuseMessagePipes(b, c));
    563 
    564   // Handles b and c should be closed.
    565   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b));
    566   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c));
    567 
    568   const std::string kTestMessage1 = "Hello, world!";
    569   const std::string kTestMessage2 = "Goodbye, world!";
    570 
    571   WriteMessage(a, kTestMessage1);
    572   EXPECT_EQ(kTestMessage1, ReadMessage(d));
    573 
    574   WriteMessage(d, kTestMessage2);
    575   EXPECT_EQ(kTestMessage2, ReadMessage(a));
    576 
    577   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a));
    578   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d));
    579 }
    580 
    581 TEST_F(FuseMessagePipeTest, FuseAfterPeerWrite) {
    582   // Test that messages written before fusion are eventually delivered.
    583 
    584   MojoHandle a, b, c, d;
    585   CreateMessagePipe(&a, &b);
    586   CreateMessagePipe(&c, &d);
    587 
    588   const std::string kTestMessage1 = "Hello, world!";
    589   const std::string kTestMessage2 = "Goodbye, world!";
    590   WriteMessage(a, kTestMessage1);
    591   WriteMessage(d, kTestMessage2);
    592 
    593   EXPECT_EQ(MOJO_RESULT_OK, MojoFuseMessagePipes(b, c));
    594 
    595   // Handles b and c should be closed.
    596   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b));
    597   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c));
    598 
    599   EXPECT_EQ(kTestMessage1, ReadMessage(d));
    600   EXPECT_EQ(kTestMessage2, ReadMessage(a));
    601 
    602   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a));
    603   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d));
    604 }
    605 
    606 TEST_F(FuseMessagePipeTest, NoFuseAfterWrite) {
    607   // Test that a pipe endpoint which has been written to cannot be fused.
    608 
    609   MojoHandle a, b, c, d;
    610   CreateMessagePipe(&a, &b);
    611   CreateMessagePipe(&c, &d);
    612 
    613   WriteMessage(b, "shouldn't have done that!");
    614   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, MojoFuseMessagePipes(b, c));
    615 
    616   // Handles b and c should be closed.
    617   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b));
    618   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c));
    619 
    620   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a));
    621   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d));
    622 }
    623 
    624 TEST_F(FuseMessagePipeTest, NoFuseSelf) {
    625   // Test that a pipe's own endpoints can't be fused together.
    626 
    627   MojoHandle a, b;
    628   CreateMessagePipe(&a, &b);
    629 
    630   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, MojoFuseMessagePipes(a, b));
    631 
    632   // Handles a and b should be closed.
    633   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(a));
    634   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b));
    635 }
    636 
    637 TEST_F(FuseMessagePipeTest, FuseInvalidArguments) {
    638   MojoHandle a, b, c, d;
    639   CreateMessagePipe(&a, &b);
    640   CreateMessagePipe(&c, &d);
    641 
    642   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(b));
    643 
    644   // Can't fuse an invalid handle.
    645   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoFuseMessagePipes(b, c));
    646 
    647   // Handle c should be closed.
    648   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c));
    649 
    650   // Can't fuse a non-message pipe handle.
    651   MojoHandle e, f;
    652   CreateDataPipe(&e, &f, 16);
    653 
    654   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoFuseMessagePipes(e, d));
    655 
    656   // Handles d and e should be closed.
    657   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(d));
    658   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(e));
    659 
    660   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a));
    661   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(f));
    662 }
    663 
    664 TEST_F(FuseMessagePipeTest, FuseAfterPeerClosure) {
    665   // Test that peer closure prior to fusion can still be detected after fusion.
    666 
    667   MojoHandle a, b, c, d;
    668   CreateMessagePipe(&a, &b);
    669   CreateMessagePipe(&c, &d);
    670 
    671   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a));
    672   EXPECT_EQ(MOJO_RESULT_OK, MojoFuseMessagePipes(b, c));
    673 
    674   // Handles b and c should be closed.
    675   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b));
    676   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c));
    677 
    678   EXPECT_EQ(MOJO_RESULT_OK, MojoWait(d, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    679                                      MOJO_DEADLINE_INDEFINITE, nullptr));
    680 
    681   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d));
    682 }
    683 
    684 TEST_F(FuseMessagePipeTest, FuseAfterPeerWriteAndClosure) {
    685   // Test that peer write and closure prior to fusion still results in the
    686   // both message arrival and awareness of peer closure.
    687 
    688   MojoHandle a, b, c, d;
    689   CreateMessagePipe(&a, &b);
    690   CreateMessagePipe(&c, &d);
    691 
    692   const std::string kTestMessage = "ayyy lmao";
    693   WriteMessage(a, kTestMessage);
    694   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a));
    695 
    696   EXPECT_EQ(MOJO_RESULT_OK, MojoFuseMessagePipes(b, c));
    697 
    698   // Handles b and c should be closed.
    699   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b));
    700   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c));
    701 
    702   EXPECT_EQ(kTestMessage, ReadMessage(d));
    703   EXPECT_EQ(MOJO_RESULT_OK, MojoWait(d, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
    704                                      MOJO_DEADLINE_INDEFINITE, nullptr));
    705 
    706   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d));
    707 }
    708 
    709 TEST_F(MessagePipeTest, ClosePipesStressTest) {
    710   // Stress test to exercise https://crbug.com/665869.
    711   const size_t kNumPipes = 100000;
    712   for (size_t i = 0; i < kNumPipes; ++i) {
    713     MojoHandle a, b;
    714     CreateMessagePipe(&a, &b);
    715     MojoClose(a);
    716     MojoClose(b);
    717   }
    718 }
    719 
    720 }  // namespace
    721 }  // namespace edk
    722 }  // namespace mojo
    723