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