• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
MessagePipeTest()25   MessagePipeTest() {
26     CHECK_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &pipe0_, &pipe1_));
27   }
28 
~MessagePipeTest()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 
WriteMessage(MojoHandle message_pipe_handle,const void * bytes,uint32_t num_bytes)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 
ReadMessage(MojoHandle message_pipe_handle,void * bytes,uint32_t * num_bytes,bool may_discard=false)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 
TEST_F(MessagePipeTest,WriteData)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
TEST_F(MessagePipeTest,Basic)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 
TEST_F(MessagePipeTest,CloseWithQueuedIncomingMessages)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 
TEST_F(MessagePipeTest,DiscardMode)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 
TEST_F(MessagePipeTest,BasicWaiting)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 
TEST_F(MessagePipeTest,InvalidMessageObjects)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 
TEST_F(MessagePipeTest,AllocAndFreeMessage)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 
TEST_F(MessagePipeTest,WriteAndReadMessageObject)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 
DEFINE_TEST_CLIENT_TEST_WITH_PIPE(HandlePingPong,MessagePipeTest,h)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
TEST_F(MessagePipeTest,DISABLED_DataPipeConsumerHandlePingPong)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
TEST_F(MessagePipeTest,DISABLED_DataPipeProducerHandlePingPong)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 
TEST_F(MessagePipeTest,SharedBufferHandlePingPong)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 
TEST_F(FuseMessagePipeTest,Basic)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 
TEST_F(FuseMessagePipeTest,FuseAfterPeerWrite)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 
TEST_F(FuseMessagePipeTest,NoFuseAfterWrite)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 
TEST_F(FuseMessagePipeTest,NoFuseSelf)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 
TEST_F(FuseMessagePipeTest,FuseInvalidArguments)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 
TEST_F(FuseMessagePipeTest,FuseAfterPeerClosure)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 
TEST_F(FuseMessagePipeTest,FuseAfterPeerWriteAndClosure)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 
TEST_F(MessagePipeTest,ClosePipesStressTest)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