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 "mojo/common/test/multiprocess_test_base.h" 6 7 #include "base/logging.h" 8 #include "build/build_config.h" 9 #include "mojo/system/platform_channel_handle.h" 10 11 #if defined(OS_POSIX) 12 #include <fcntl.h> 13 #include <unistd.h> 14 15 #include "base/posix/eintr_wrapper.h" 16 #endif 17 18 namespace mojo { 19 namespace { 20 21 class MultiprocessTestBaseTest : public test::MultiprocessTestBase { 22 }; 23 24 TEST_F(MultiprocessTestBaseTest, RunChild) { 25 // TODO(vtl): Not implemented on Windows yet. 26 #if defined(OS_POSIX) 27 EXPECT_TRUE(platform_server_channel.get()); 28 EXPECT_TRUE(platform_server_channel->is_valid()); 29 #endif 30 StartChild("RunChild"); 31 EXPECT_EQ(123, WaitForChildShutdown()); 32 } 33 34 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(RunChild) { 35 // TODO(vtl): Not implemented on Windows yet. 36 #if defined(OS_POSIX) 37 CHECK(MultiprocessTestBaseTest::platform_client_channel.get()); 38 CHECK(MultiprocessTestBaseTest::platform_client_channel->is_valid()); 39 #endif 40 return 123; 41 } 42 43 TEST_F(MultiprocessTestBaseTest, TestChildMainNotFound) { 44 StartChild("NoSuchTestChildMain"); 45 int result = WaitForChildShutdown(); 46 EXPECT_FALSE(result >= 0 && result <= 127); 47 } 48 49 // POSIX-specific test of passed channel --------------------------------------- 50 51 #if defined(OS_POSIX) 52 TEST_F(MultiprocessTestBaseTest, PassedChannelPosix) { 53 EXPECT_TRUE(platform_server_channel.get()); 54 EXPECT_TRUE(platform_server_channel->is_valid()); 55 StartChild("PassedChannelPosix"); 56 57 // Take ownership of the FD. 58 mojo::system::PlatformChannelHandle channel = 59 platform_server_channel->PassHandle(); 60 platform_server_channel.reset(); 61 int fd = channel.fd; 62 63 // The FD should be non-blocking. Check this. 64 CHECK((fcntl(fd, F_GETFL) & O_NONBLOCK)); 65 // We're lazy. Set it to block. 66 PCHECK(fcntl(fd, F_SETFL, 0) == 0); 67 68 // Write a byte. 69 const char c = 'X'; 70 ssize_t write_size = HANDLE_EINTR(write(fd, &c, 1)); 71 EXPECT_EQ(1, write_size); 72 73 // It'll echo it back to us, incremented. 74 char d = 0; 75 ssize_t read_size = HANDLE_EINTR(read(fd, &d, 1)); 76 EXPECT_EQ(1, read_size); 77 EXPECT_EQ(c + 1, d); 78 79 // And return it, incremented again. 80 EXPECT_EQ(c + 2, WaitForChildShutdown()); 81 } 82 83 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PassedChannelPosix) { 84 CHECK(MultiprocessTestBaseTest::platform_client_channel.get()); 85 CHECK(MultiprocessTestBaseTest::platform_client_channel->is_valid()); 86 87 // Take ownership of the FD. 88 mojo::system::PlatformChannelHandle channel = 89 MultiprocessTestBaseTest::platform_client_channel->PassHandle(); 90 MultiprocessTestBaseTest::platform_client_channel.reset(); 91 int fd = channel.fd; 92 93 // The FD should still be non-blocking. Check this. 94 CHECK((fcntl(fd, F_GETFL) & O_NONBLOCK)); 95 // We're lazy. Set it to block. 96 PCHECK(fcntl(fd, F_SETFL, 0) == 0); 97 98 // Read a byte. 99 char c = 0; 100 ssize_t read_size = HANDLE_EINTR(read(fd, &c, 1)); 101 CHECK_EQ(read_size, 1); 102 103 // Write it back, incremented. 104 c++; 105 ssize_t write_size = HANDLE_EINTR(write(fd, &c, 1)); 106 CHECK_EQ(write_size, 1); 107 108 PCHECK(close(fd) == 0); 109 110 // And return it, incremented again. 111 c++; 112 return static_cast<int>(c); 113 } 114 #endif // defined(OS_POSIX) 115 116 } // namespace 117 } // namespace mojo 118