| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdint.h> | 5 #include <stdint.h> |
| 6 #include <stdio.h> | 6 #include <stdio.h> |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
| 15 #include "base/files/scoped_file.h" | 15 #include "base/files/scoped_file.h" |
| 16 #include "base/files/scoped_temp_dir.h" | 16 #include "base/files/scoped_temp_dir.h" |
| 17 #include "base/location.h" | 17 #include "base/location.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/macros.h" | 19 #include "base/macros.h" |
| 20 #include "base/threading/platform_thread.h" // For |Sleep()|. | 20 #include "base/threading/platform_thread.h" // For |Sleep()|. |
| 21 #include "build/build_config.h" // TODO(vtl): Remove this. | 21 #include "build/build_config.h" // TODO(vtl): Remove this. |
| 22 #include "mojo/common/test/multiprocess_test_helper.h" | 22 #include "mojo/common/test/multiprocess_test_helper.h" |
| 23 #include "mojo/common/test/test_utils.h" | 23 #include "mojo/common/test/test_utils.h" |
| 24 #include "mojo/embedder/platform_shared_buffer.h" | 24 #include "mojo/embedder/platform_shared_buffer.h" |
| 25 #include "mojo/embedder/scoped_platform_handle.h" | 25 #include "mojo/embedder/scoped_platform_handle.h" |
| 26 #include "mojo/embedder/simple_platform_support.h" | 26 #include "mojo/embedder/simple_platform_support.h" |
| 27 #include "mojo/system/channel.h" | 27 #include "mojo/system/channel.h" |
| 28 #include "mojo/system/dispatcher.h" | 28 #include "mojo/system/dispatcher.h" |
| 29 #include "mojo/system/local_message_pipe_endpoint.h" | |
| 30 #include "mojo/system/message_pipe.h" | 29 #include "mojo/system/message_pipe.h" |
| 31 #include "mojo/system/platform_handle_dispatcher.h" | 30 #include "mojo/system/platform_handle_dispatcher.h" |
| 32 #include "mojo/system/proxy_message_pipe_endpoint.h" | |
| 33 #include "mojo/system/raw_channel.h" | 31 #include "mojo/system/raw_channel.h" |
| 34 #include "mojo/system/shared_buffer_dispatcher.h" | 32 #include "mojo/system/shared_buffer_dispatcher.h" |
| 35 #include "mojo/system/test_utils.h" | 33 #include "mojo/system/test_utils.h" |
| 36 #include "mojo/system/waiter.h" | 34 #include "mojo/system/waiter.h" |
| 37 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
| 38 | 36 |
| 39 namespace mojo { | 37 namespace mojo { |
| 40 namespace system { | 38 namespace system { |
| 41 namespace { | 39 namespace { |
| 42 | 40 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 // For each message received, sends a reply message with the same contents | 149 // For each message received, sends a reply message with the same contents |
| 152 // repeated twice, until the other end is closed or it receives "quitquitquit" | 150 // repeated twice, until the other end is closed or it receives "quitquitquit" |
| 153 // (which it doesn't reply to). It'll return the number of messages received, | 151 // (which it doesn't reply to). It'll return the number of messages received, |
| 154 // not including any "quitquitquit" message, modulo 100. | 152 // not including any "quitquitquit" message, modulo 100. |
| 155 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(EchoEcho) { | 153 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(EchoEcho) { |
| 156 embedder::SimplePlatformSupport platform_support; | 154 embedder::SimplePlatformSupport platform_support; |
| 157 ChannelThread channel_thread(&platform_support); | 155 ChannelThread channel_thread(&platform_support); |
| 158 embedder::ScopedPlatformHandle client_platform_handle = | 156 embedder::ScopedPlatformHandle client_platform_handle = |
| 159 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); | 157 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); |
| 160 CHECK(client_platform_handle.is_valid()); | 158 CHECK(client_platform_handle.is_valid()); |
| 161 scoped_refptr<MessagePipe> mp(new MessagePipe( | 159 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy()); |
| 162 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | |
| 163 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | |
| 164 channel_thread.Start(client_platform_handle.Pass(), mp); | 160 channel_thread.Start(client_platform_handle.Pass(), mp); |
| 165 | 161 |
| 166 const std::string quitquitquit("quitquitquit"); | 162 const std::string quitquitquit("quitquitquit"); |
| 167 int rv = 0; | 163 int rv = 0; |
| 168 for (;; rv = (rv + 1) % 100) { | 164 for (;; rv = (rv + 1) % 100) { |
| 169 // Wait for our end of the message pipe to be readable. | 165 // Wait for our end of the message pipe to be readable. |
| 170 HandleSignalsState hss; | 166 HandleSignalsState hss; |
| 171 MojoResult result = WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss); | 167 MojoResult result = WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss); |
| 172 if (result != MOJO_RESULT_OK) { | 168 if (result != MOJO_RESULT_OK) { |
| 173 // It was closed, probably. | 169 // It was closed, probably. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 } | 203 } |
| 208 | 204 |
| 209 mp->Close(0); | 205 mp->Close(0); |
| 210 return rv; | 206 return rv; |
| 211 } | 207 } |
| 212 | 208 |
| 213 // Sends "hello" to child, and expects "hellohello" back. | 209 // Sends "hello" to child, and expects "hellohello" back. |
| 214 TEST_F(MultiprocessMessagePipeTest, Basic) { | 210 TEST_F(MultiprocessMessagePipeTest, Basic) { |
| 215 helper()->StartChild("EchoEcho"); | 211 helper()->StartChild("EchoEcho"); |
| 216 | 212 |
| 217 scoped_refptr<MessagePipe> mp(new MessagePipe( | 213 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy()); |
| 218 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | |
| 219 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | |
| 220 Init(mp); | 214 Init(mp); |
| 221 | 215 |
| 222 std::string hello("hello"); | 216 std::string hello("hello"); |
| 223 EXPECT_EQ(MOJO_RESULT_OK, | 217 EXPECT_EQ(MOJO_RESULT_OK, |
| 224 mp->WriteMessage(0, | 218 mp->WriteMessage(0, |
| 225 UserPointer<const void>(hello.data()), | 219 UserPointer<const void>(hello.data()), |
| 226 static_cast<uint32_t>(hello.size()), | 220 static_cast<uint32_t>(hello.size()), |
| 227 NULL, | 221 NULL, |
| 228 MOJO_WRITE_MESSAGE_FLAG_NONE)); | 222 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 229 | 223 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 253 | 247 |
| 254 // We sent one message. | 248 // We sent one message. |
| 255 EXPECT_EQ(1 % 100, helper()->WaitForChildShutdown()); | 249 EXPECT_EQ(1 % 100, helper()->WaitForChildShutdown()); |
| 256 } | 250 } |
| 257 | 251 |
| 258 // Sends a bunch of messages to the child. Expects them "repeated" back. Waits | 252 // Sends a bunch of messages to the child. Expects them "repeated" back. Waits |
| 259 // for the child to close its end before quitting. | 253 // for the child to close its end before quitting. |
| 260 TEST_F(MultiprocessMessagePipeTest, QueueMessages) { | 254 TEST_F(MultiprocessMessagePipeTest, QueueMessages) { |
| 261 helper()->StartChild("EchoEcho"); | 255 helper()->StartChild("EchoEcho"); |
| 262 | 256 |
| 263 scoped_refptr<MessagePipe> mp(new MessagePipe( | 257 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy()); |
| 264 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | |
| 265 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | |
| 266 Init(mp); | 258 Init(mp); |
| 267 | 259 |
| 268 static const size_t kNumMessages = 1001; | 260 static const size_t kNumMessages = 1001; |
| 269 for (size_t i = 0; i < kNumMessages; i++) { | 261 for (size_t i = 0; i < kNumMessages; i++) { |
| 270 std::string write_buffer(i, 'A' + (i % 26)); | 262 std::string write_buffer(i, 'A' + (i % 26)); |
| 271 EXPECT_EQ(MOJO_RESULT_OK, | 263 EXPECT_EQ(MOJO_RESULT_OK, |
| 272 mp->WriteMessage(0, | 264 mp->WriteMessage(0, |
| 273 UserPointer<const void>(write_buffer.data()), | 265 UserPointer<const void>(write_buffer.data()), |
| 274 static_cast<uint32_t>(write_buffer.size()), | 266 static_cast<uint32_t>(write_buffer.size()), |
| 275 NULL, | 267 NULL, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 EXPECT_EQ(static_cast<int>(kNumMessages % 100), | 313 EXPECT_EQ(static_cast<int>(kNumMessages % 100), |
| 322 helper()->WaitForChildShutdown()); | 314 helper()->WaitForChildShutdown()); |
| 323 } | 315 } |
| 324 | 316 |
| 325 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(CheckSharedBuffer) { | 317 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(CheckSharedBuffer) { |
| 326 embedder::SimplePlatformSupport platform_support; | 318 embedder::SimplePlatformSupport platform_support; |
| 327 ChannelThread channel_thread(&platform_support); | 319 ChannelThread channel_thread(&platform_support); |
| 328 embedder::ScopedPlatformHandle client_platform_handle = | 320 embedder::ScopedPlatformHandle client_platform_handle = |
| 329 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); | 321 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); |
| 330 CHECK(client_platform_handle.is_valid()); | 322 CHECK(client_platform_handle.is_valid()); |
| 331 scoped_refptr<MessagePipe> mp(new MessagePipe( | 323 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy()); |
| 332 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | |
| 333 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | |
| 334 channel_thread.Start(client_platform_handle.Pass(), mp); | 324 channel_thread.Start(client_platform_handle.Pass(), mp); |
| 335 | 325 |
| 336 // Wait for the first message from our parent. | 326 // Wait for the first message from our parent. |
| 337 HandleSignalsState hss; | 327 HandleSignalsState hss; |
| 338 CHECK_EQ(WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss), | 328 CHECK_EQ(WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss), |
| 339 MOJO_RESULT_OK); | 329 MOJO_RESULT_OK); |
| 340 // In this test, the parent definitely doesn't close its end of the message | 330 // In this test, the parent definitely doesn't close its end of the message |
| 341 // pipe before we do. | 331 // pipe before we do. |
| 342 CHECK_EQ(hss.satisfied_signals, | 332 CHECK_EQ(hss.satisfied_signals, |
| 343 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE); | 333 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 | 412 |
| 423 #if defined(OS_POSIX) | 413 #if defined(OS_POSIX) |
| 424 #define MAYBE_SharedBufferPassing SharedBufferPassing | 414 #define MAYBE_SharedBufferPassing SharedBufferPassing |
| 425 #else | 415 #else |
| 426 // Not yet implemented (on Windows). | 416 // Not yet implemented (on Windows). |
| 427 #define MAYBE_SharedBufferPassing DISABLED_SharedBufferPassing | 417 #define MAYBE_SharedBufferPassing DISABLED_SharedBufferPassing |
| 428 #endif | 418 #endif |
| 429 TEST_F(MultiprocessMessagePipeTest, MAYBE_SharedBufferPassing) { | 419 TEST_F(MultiprocessMessagePipeTest, MAYBE_SharedBufferPassing) { |
| 430 helper()->StartChild("CheckSharedBuffer"); | 420 helper()->StartChild("CheckSharedBuffer"); |
| 431 | 421 |
| 432 scoped_refptr<MessagePipe> mp(new MessagePipe( | 422 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy()); |
| 433 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | |
| 434 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | |
| 435 Init(mp); | 423 Init(mp); |
| 436 | 424 |
| 437 // Make a shared buffer. | 425 // Make a shared buffer. |
| 438 scoped_refptr<SharedBufferDispatcher> dispatcher; | 426 scoped_refptr<SharedBufferDispatcher> dispatcher; |
| 439 EXPECT_EQ(MOJO_RESULT_OK, | 427 EXPECT_EQ(MOJO_RESULT_OK, |
| 440 SharedBufferDispatcher::Create( | 428 SharedBufferDispatcher::Create( |
| 441 platform_support(), | 429 platform_support(), |
| 442 SharedBufferDispatcher::kDefaultCreateOptions, | 430 SharedBufferDispatcher::kDefaultCreateOptions, |
| 443 100, | 431 100, |
| 444 &dispatcher)); | 432 &dispatcher)); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 | 507 |
| 520 EXPECT_EQ(0, helper()->WaitForChildShutdown()); | 508 EXPECT_EQ(0, helper()->WaitForChildShutdown()); |
| 521 } | 509 } |
| 522 | 510 |
| 523 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(CheckPlatformHandleFile) { | 511 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(CheckPlatformHandleFile) { |
| 524 embedder::SimplePlatformSupport platform_support; | 512 embedder::SimplePlatformSupport platform_support; |
| 525 ChannelThread channel_thread(&platform_support); | 513 ChannelThread channel_thread(&platform_support); |
| 526 embedder::ScopedPlatformHandle client_platform_handle = | 514 embedder::ScopedPlatformHandle client_platform_handle = |
| 527 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); | 515 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); |
| 528 CHECK(client_platform_handle.is_valid()); | 516 CHECK(client_platform_handle.is_valid()); |
| 529 scoped_refptr<MessagePipe> mp(new MessagePipe( | 517 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy()); |
| 530 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | |
| 531 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | |
| 532 channel_thread.Start(client_platform_handle.Pass(), mp); | 518 channel_thread.Start(client_platform_handle.Pass(), mp); |
| 533 | 519 |
| 534 HandleSignalsState hss; | 520 HandleSignalsState hss; |
| 535 CHECK_EQ(WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss), | 521 CHECK_EQ(WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss), |
| 536 MOJO_RESULT_OK); | 522 MOJO_RESULT_OK); |
| 537 CHECK_EQ(hss.satisfied_signals, | 523 CHECK_EQ(hss.satisfied_signals, |
| 538 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE); | 524 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE); |
| 539 CHECK_EQ(hss.satisfiable_signals, | 525 CHECK_EQ(hss.satisfiable_signals, |
| 540 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE); | 526 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE); |
| 541 | 527 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 #else | 565 #else |
| 580 // Not yet implemented (on Windows). | 566 // Not yet implemented (on Windows). |
| 581 #define MAYBE_PlatformHandlePassing DISABLED_PlatformHandlePassing | 567 #define MAYBE_PlatformHandlePassing DISABLED_PlatformHandlePassing |
| 582 #endif | 568 #endif |
| 583 TEST_F(MultiprocessMessagePipeTest, MAYBE_PlatformHandlePassing) { | 569 TEST_F(MultiprocessMessagePipeTest, MAYBE_PlatformHandlePassing) { |
| 584 base::ScopedTempDir temp_dir; | 570 base::ScopedTempDir temp_dir; |
| 585 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 571 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 586 | 572 |
| 587 helper()->StartChild("CheckPlatformHandleFile"); | 573 helper()->StartChild("CheckPlatformHandleFile"); |
| 588 | 574 |
| 589 scoped_refptr<MessagePipe> mp(new MessagePipe( | 575 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy()); |
| 590 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | |
| 591 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | |
| 592 Init(mp); | 576 Init(mp); |
| 593 | 577 |
| 594 base::FilePath unused; | 578 base::FilePath unused; |
| 595 base::ScopedFILE fp( | 579 base::ScopedFILE fp( |
| 596 CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused)); | 580 CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused)); |
| 597 const std::string world("world"); | 581 const std::string world("world"); |
| 598 ASSERT_EQ(fwrite(&world[0], 1, world.size(), fp.get()), world.size()); | 582 ASSERT_EQ(fwrite(&world[0], 1, world.size(), fp.get()), world.size()); |
| 599 fflush(fp.get()); | 583 fflush(fp.get()); |
| 600 rewind(fp.get()); | 584 rewind(fp.get()); |
| 601 | 585 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 630 EXPECT_EQ(0u, hss.satisfiable_signals); | 614 EXPECT_EQ(0u, hss.satisfiable_signals); |
| 631 | 615 |
| 632 mp->Close(0); | 616 mp->Close(0); |
| 633 | 617 |
| 634 EXPECT_EQ(0, helper()->WaitForChildShutdown()); | 618 EXPECT_EQ(0, helper()->WaitForChildShutdown()); |
| 635 } | 619 } |
| 636 | 620 |
| 637 } // namespace | 621 } // namespace |
| 638 } // namespace system | 622 } // namespace system |
| 639 } // namespace mojo | 623 } // namespace mojo |
| OLD | NEW |