1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/common/test/multiprocess_test_helper.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "build/build_config.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/common/test/test_utils.h" 1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "mojo/embedder/scoped_platform_handle.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_POSIX) 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <fcntl.h> 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace mojo { 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace test { 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool IsNonBlocking(const embedder::PlatformHandle& handle) { 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_WIN) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Haven't figured out a way to query whether a HANDLE was created with 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // FILE_FLAG_OVERLAPPED. 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return fcntl(handle.fd, F_GETFL) & O_NONBLOCK; 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool WriteByte(const embedder::PlatformHandle& handle, char c) { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t bytes_written = 0; 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BlockingWrite(handle, &c, 1, &bytes_written); 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return bytes_written == 1; 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ReadByte(const embedder::PlatformHandle& handle, char* c) { 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t bytes_read = 0; 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BlockingRead(handle, c, 1, &bytes_read); 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return bytes_read == 1; 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)typedef testing::Test MultiprocessTestHelperTest; 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(MultiprocessTestHelperTest, RunChild) { 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper helper; 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(helper.server_platform_handle.is_valid()); 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) helper.StartChild("RunChild"); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(123, helper.WaitForChildShutdown()); 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MOJO_MULTIPROCESS_TEST_CHILD_MAIN(RunChild) { 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(MultiprocessTestHelper::client_platform_handle.is_valid()); 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 123; 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(MultiprocessTestHelperTest, TestChildMainNotFound) { 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper helper; 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) helper.StartChild("NoSuchTestChildMain"); 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int result = helper.WaitForChildShutdown(); 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(result >= 0 && result <= 127); 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(MultiprocessTestHelperTest, PassedChannel) { 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper helper; 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(helper.server_platform_handle.is_valid()); 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) helper.StartChild("PassedChannel"); 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Take ownership of the handle. 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) embedder::ScopedPlatformHandle handle = helper.server_platform_handle.Pass(); 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The handle should be non-blocking. 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(IsNonBlocking(handle.get())); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Write a byte. 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char c = 'X'; 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(WriteByte(handle.get(), c)); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // It'll echo it back to us, incremented. 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) char d = 0; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(ReadByte(handle.get(), &d)); 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(c + 1, d); 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // And return it, incremented again. 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(c + 2, helper.WaitForChildShutdown()); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PassedChannel) { 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(MultiprocessTestHelper::client_platform_handle.is_valid()); 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Take ownership of the handle. 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) embedder::ScopedPlatformHandle handle = 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper::client_platform_handle.Pass(); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The handle should be non-blocking. 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(IsNonBlocking(handle.get())); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Read a byte. 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) char c = 0; 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(ReadByte(handle.get(), &c)); 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Write it back, incremented. 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) c++; 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(WriteByte(handle.get(), c)); 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // And return it, incremented again. 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) c++; 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return static_cast<int>(c); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(MultiprocessTestHelperTest, ChildTestPasses) { 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper helper; 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(helper.server_platform_handle.is_valid()); 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) helper.StartChild("ChildTestPasses"); 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(helper.WaitForChildTestShutdown()); 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MOJO_MULTIPROCESS_TEST_CHILD_TEST(ChildTestPasses) { 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(MultiprocessTestHelper::client_platform_handle.is_valid()); 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(IsNonBlocking( 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper::client_platform_handle.get())); 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(MultiprocessTestHelperTest, ChildTestFailsAssert) { 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper helper; 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(helper.server_platform_handle.is_valid()); 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) helper.StartChild("ChildTestFailsAssert"); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(helper.WaitForChildTestShutdown()); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MOJO_MULTIPROCESS_TEST_CHILD_TEST(ChildTestFailsAssert) { 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_FALSE(MultiprocessTestHelper::client_platform_handle.is_valid()) 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "DISREGARD: Expected failure in child process"; 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_FALSE(IsNonBlocking( 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper::client_platform_handle.get())) << "Not reached"; 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(false) << "Not reached"; 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(MultiprocessTestHelperTest, ChildTestFailsExpect) { 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper helper; 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(helper.server_platform_handle.is_valid()); 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) helper.StartChild("ChildTestFailsExpect"); 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(helper.WaitForChildTestShutdown()); 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MOJO_MULTIPROCESS_TEST_CHILD_TEST(ChildTestFailsExpect) { 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(MultiprocessTestHelper::client_platform_handle.is_valid()) 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "DISREGARD: Expected failure #1 in child process"; 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(IsNonBlocking( 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MultiprocessTestHelper::client_platform_handle.get())) 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "DISREGARD: Expected failure #2 in child process"; 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace test 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace mojo 158