Home | History | Annotate | Download | only in test
      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