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