// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/edk/test/multiprocess_test_helper.h"

#include <stddef.h>

#include <utility>

#include "base/logging.h"
#include "build/build_config.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "mojo/edk/system/test_utils.h"
#include "mojo/edk/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_POSIX)
#include <fcntl.h>
#endif

namespace mojo {
namespace edk {
namespace test {
namespace {

bool IsNonBlocking(const PlatformHandle& handle) {
#if defined(OS_WIN)
  // Haven't figured out a way to query whether a HANDLE was created with
  // FILE_FLAG_OVERLAPPED.
  return true;
#else
  return fcntl(handle.handle, F_GETFL) & O_NONBLOCK;
#endif
}

bool WriteByte(const PlatformHandle& handle, char c) {
  size_t bytes_written = 0;
  BlockingWrite(handle, &c, 1, &bytes_written);
  return bytes_written == 1;
}

bool ReadByte(const PlatformHandle& handle, char* c) {
  size_t bytes_read = 0;
  BlockingRead(handle, c, 1, &bytes_read);
  return bytes_read == 1;
}

using MultiprocessTestHelperTest = testing::Test;

TEST_F(MultiprocessTestHelperTest, RunChild) {
  MultiprocessTestHelper helper;
  EXPECT_TRUE(helper.server_platform_handle.is_valid());

  helper.StartChild("RunChild");
  EXPECT_EQ(123, helper.WaitForChildShutdown());
}

MOJO_MULTIPROCESS_TEST_CHILD_MAIN(RunChild) {
  CHECK(MultiprocessTestHelper::client_platform_handle.is_valid());
  return 123;
}

TEST_F(MultiprocessTestHelperTest, TestChildMainNotFound) {
  MultiprocessTestHelper helper;
  helper.StartChild("NoSuchTestChildMain");
  int result = helper.WaitForChildShutdown();
  EXPECT_FALSE(result >= 0 && result <= 127);
}

TEST_F(MultiprocessTestHelperTest, PassedChannel) {
  MultiprocessTestHelper helper;
  EXPECT_TRUE(helper.server_platform_handle.is_valid());
  helper.StartChild("PassedChannel");

  // Take ownership of the handle.
  ScopedPlatformHandle handle = std::move(helper.server_platform_handle);

  // The handle should be non-blocking.
  EXPECT_TRUE(IsNonBlocking(handle.get()));

  // Write a byte.
  const char c = 'X';
  EXPECT_TRUE(WriteByte(handle.get(), c));

  // It'll echo it back to us, incremented.
  char d = 0;
  EXPECT_TRUE(ReadByte(handle.get(), &d));
  EXPECT_EQ(c + 1, d);

  // And return it, incremented again.
  EXPECT_EQ(c + 2, helper.WaitForChildShutdown());
}

MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PassedChannel) {
  CHECK(MultiprocessTestHelper::client_platform_handle.is_valid());

  // Take ownership of the handle.
  ScopedPlatformHandle handle =
      std::move(MultiprocessTestHelper::client_platform_handle);

  // The handle should be non-blocking.
  EXPECT_TRUE(IsNonBlocking(handle.get()));

  // Read a byte.
  char c = 0;
  EXPECT_TRUE(ReadByte(handle.get(), &c));

  // Write it back, incremented.
  c++;
  EXPECT_TRUE(WriteByte(handle.get(), c));

  // And return it, incremented again.
  c++;
  return static_cast<int>(c);
}

TEST_F(MultiprocessTestHelperTest, ChildTestPasses) {
  MultiprocessTestHelper helper;
  EXPECT_TRUE(helper.server_platform_handle.is_valid());
  helper.StartChild("ChildTestPasses");
  EXPECT_TRUE(helper.WaitForChildTestShutdown());
}

MOJO_MULTIPROCESS_TEST_CHILD_TEST(ChildTestPasses) {
  ASSERT_TRUE(MultiprocessTestHelper::client_platform_handle.is_valid());
  EXPECT_TRUE(
      IsNonBlocking(MultiprocessTestHelper::client_platform_handle.get()));
}

TEST_F(MultiprocessTestHelperTest, ChildTestFailsAssert) {
  MultiprocessTestHelper helper;
  EXPECT_TRUE(helper.server_platform_handle.is_valid());
  helper.StartChild("ChildTestFailsAssert");
  EXPECT_FALSE(helper.WaitForChildTestShutdown());
}

MOJO_MULTIPROCESS_TEST_CHILD_TEST(ChildTestFailsAssert) {
  ASSERT_FALSE(MultiprocessTestHelper::client_platform_handle.is_valid())
      << "DISREGARD: Expected failure in child process";
  ASSERT_FALSE(
      IsNonBlocking(MultiprocessTestHelper::client_platform_handle.get()))
      << "Not reached";
  CHECK(false) << "Not reached";
}

TEST_F(MultiprocessTestHelperTest, ChildTestFailsExpect) {
  MultiprocessTestHelper helper;
  EXPECT_TRUE(helper.server_platform_handle.is_valid());
  helper.StartChild("ChildTestFailsExpect");
  EXPECT_FALSE(helper.WaitForChildTestShutdown());
}

MOJO_MULTIPROCESS_TEST_CHILD_TEST(ChildTestFailsExpect) {
  EXPECT_FALSE(MultiprocessTestHelper::client_platform_handle.is_valid())
      << "DISREGARD: Expected failure #1 in child process";
  EXPECT_FALSE(
      IsNonBlocking(MultiprocessTestHelper::client_platform_handle.get()))
      << "DISREGARD: Expected failure #2 in child process";
}

}  // namespace
}  // namespace test
}  // namespace edk
}  // namespace mojo
