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