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
14namespace mojo {
15namespace edk {
16namespace {
17
18const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE |
19                                      MOJO_HANDLE_SIGNAL_WRITABLE |
20                                      MOJO_HANDLE_SIGNAL_PEER_CLOSED;
21static const char kHelloWorld[] = "hello world";
22
23class 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
58using FuseMessagePipeTest = test::MojoTestBase;
59
60TEST_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
77TEST_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
206TEST_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
233TEST_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
319TEST_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
413TEST_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
428TEST_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
438TEST_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
481const size_t kPingPongHandlesPerIteration = 50;
482const size_t kPingPongIterations = 500;
483
484DEFINE_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
500TEST_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
519TEST_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
537TEST_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
555TEST_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
581TEST_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
606TEST_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
624TEST_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
637TEST_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
664TEST_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
684TEST_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}  // namespace
710}  // namespace edk
711}  // namespace mojo
712