| Index: mojo/edk/system/raw_channel_unittest.cc
 | 
| diff --git a/mojo/edk/system/raw_channel_unittest.cc b/mojo/edk/system/raw_channel_unittest.cc
 | 
| deleted file mode 100644
 | 
| index a8cbcba7d7b5d3d4cb93c110bd716d55c272d321..0000000000000000000000000000000000000000
 | 
| --- a/mojo/edk/system/raw_channel_unittest.cc
 | 
| +++ /dev/null
 | 
| @@ -1,805 +0,0 @@
 | 
| -// Copyright 2014 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/system/raw_channel.h"
 | 
| -
 | 
| -#include <stdint.h>
 | 
| -#include <stdio.h>
 | 
| -
 | 
| -#include <vector>
 | 
| -
 | 
| -#include "base/bind.h"
 | 
| -#include "base/files/file_path.h"
 | 
| -#include "base/files/file_util.h"
 | 
| -#include "base/files/scoped_file.h"
 | 
| -#include "base/files/scoped_temp_dir.h"
 | 
| -#include "base/location.h"
 | 
| -#include "base/logging.h"
 | 
| -#include "base/macros.h"
 | 
| -#include "base/memory/scoped_ptr.h"
 | 
| -#include "base/memory/scoped_vector.h"
 | 
| -#include "base/rand_util.h"
 | 
| -#include "base/synchronization/lock.h"
 | 
| -#include "base/synchronization/waitable_event.h"
 | 
| -#include "base/test/test_io_thread.h"
 | 
| -#include "base/threading/platform_thread.h"  // For |Sleep()|.
 | 
| -#include "base/threading/simple_thread.h"
 | 
| -#include "base/time/time.h"
 | 
| -#include "build/build_config.h"  // TODO(vtl): Remove this.
 | 
| -#include "mojo/edk/embedder/platform_channel_pair.h"
 | 
| -#include "mojo/edk/embedder/platform_handle.h"
 | 
| -#include "mojo/edk/embedder/scoped_platform_handle.h"
 | 
| -#include "mojo/edk/system/message_in_transit.h"
 | 
| -#include "mojo/edk/system/test_utils.h"
 | 
| -#include "mojo/edk/system/transport_data.h"
 | 
| -#include "mojo/edk/test/test_utils.h"
 | 
| -#include "testing/gtest/include/gtest/gtest.h"
 | 
| -
 | 
| -namespace mojo {
 | 
| -namespace system {
 | 
| -namespace {
 | 
| -
 | 
| -scoped_ptr<MessageInTransit> MakeTestMessage(uint32_t num_bytes) {
 | 
| -  std::vector<unsigned char> bytes(num_bytes, 0);
 | 
| -  for (size_t i = 0; i < num_bytes; i++)
 | 
| -    bytes[i] = static_cast<unsigned char>(i + num_bytes);
 | 
| -  return make_scoped_ptr(new MessageInTransit(
 | 
| -      MessageInTransit::kTypeEndpoint, MessageInTransit::kSubtypeEndpointData,
 | 
| -      num_bytes, bytes.empty() ? nullptr : &bytes[0]));
 | 
| -}
 | 
| -
 | 
| -bool CheckMessageData(const void* bytes, uint32_t num_bytes) {
 | 
| -  const unsigned char* b = static_cast<const unsigned char*>(bytes);
 | 
| -  for (uint32_t i = 0; i < num_bytes; i++) {
 | 
| -    if (b[i] != static_cast<unsigned char>(i + num_bytes))
 | 
| -      return false;
 | 
| -  }
 | 
| -  return true;
 | 
| -}
 | 
| -
 | 
| -void InitOnIOThread(RawChannel* raw_channel, RawChannel::Delegate* delegate) {
 | 
| -  raw_channel->Init(delegate);
 | 
| -}
 | 
| -
 | 
| -bool WriteTestMessageToHandle(const embedder::PlatformHandle& handle,
 | 
| -                              uint32_t num_bytes) {
 | 
| -  scoped_ptr<MessageInTransit> message(MakeTestMessage(num_bytes));
 | 
| -
 | 
| -  size_t write_size = 0;
 | 
| -  mojo::test::BlockingWrite(handle, message->main_buffer(),
 | 
| -                            message->main_buffer_size(), &write_size);
 | 
| -  return write_size == message->main_buffer_size();
 | 
| -}
 | 
| -
 | 
| -// -----------------------------------------------------------------------------
 | 
| -
 | 
| -class RawChannelTest : public testing::Test {
 | 
| - public:
 | 
| -  RawChannelTest() : io_thread_(base::TestIOThread::kManualStart) {}
 | 
| -  ~RawChannelTest() override {}
 | 
| -
 | 
| -  void SetUp() override {
 | 
| -    embedder::PlatformChannelPair channel_pair;
 | 
| -    handles[0] = channel_pair.PassServerHandle();
 | 
| -    handles[1] = channel_pair.PassClientHandle();
 | 
| -    io_thread_.Start();
 | 
| -  }
 | 
| -
 | 
| -  void TearDown() override {
 | 
| -    io_thread_.Stop();
 | 
| -    handles[0].reset();
 | 
| -    handles[1].reset();
 | 
| -  }
 | 
| -
 | 
| - protected:
 | 
| -  base::TestIOThread* io_thread() { return &io_thread_; }
 | 
| -
 | 
| -  embedder::ScopedPlatformHandle handles[2];
 | 
| -
 | 
| - private:
 | 
| -  base::TestIOThread io_thread_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(RawChannelTest);
 | 
| -};
 | 
| -
 | 
| -// RawChannelTest.WriteMessage -------------------------------------------------
 | 
| -
 | 
| -class WriteOnlyRawChannelDelegate : public RawChannel::Delegate {
 | 
| - public:
 | 
| -  WriteOnlyRawChannelDelegate() {}
 | 
| -  ~WriteOnlyRawChannelDelegate() override {}
 | 
| -
 | 
| -  // |RawChannel::Delegate| implementation:
 | 
| -  void OnReadMessage(
 | 
| -      const MessageInTransit::View& /*message_view*/,
 | 
| -      embedder::ScopedPlatformHandleVectorPtr /*platform_handles*/) override {
 | 
| -    CHECK(false);  // Should not get called.
 | 
| -  }
 | 
| -  void OnError(Error error) override {
 | 
| -    // We'll get a read (shutdown) error when the connection is closed.
 | 
| -    CHECK_EQ(error, ERROR_READ_SHUTDOWN);
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  DISALLOW_COPY_AND_ASSIGN(WriteOnlyRawChannelDelegate);
 | 
| -};
 | 
| -
 | 
| -static const int64_t kMessageReaderSleepMs = 1;
 | 
| -static const size_t kMessageReaderMaxPollIterations = 3000;
 | 
| -
 | 
| -class TestMessageReaderAndChecker {
 | 
| - public:
 | 
| -  explicit TestMessageReaderAndChecker(embedder::PlatformHandle handle)
 | 
| -      : handle_(handle) {}
 | 
| -  ~TestMessageReaderAndChecker() { CHECK(bytes_.empty()); }
 | 
| -
 | 
| -  bool ReadAndCheckNextMessage(uint32_t expected_size) {
 | 
| -    unsigned char buffer[4096];
 | 
| -
 | 
| -    for (size_t i = 0; i < kMessageReaderMaxPollIterations;) {
 | 
| -      size_t read_size = 0;
 | 
| -      CHECK(mojo::test::NonBlockingRead(handle_, buffer, sizeof(buffer),
 | 
| -                                        &read_size));
 | 
| -
 | 
| -      // Append newly-read data to |bytes_|.
 | 
| -      bytes_.insert(bytes_.end(), buffer, buffer + read_size);
 | 
| -
 | 
| -      // If we have the header....
 | 
| -      size_t message_size;
 | 
| -      if (MessageInTransit::GetNextMessageSize(
 | 
| -              bytes_.empty() ? nullptr : &bytes_[0], bytes_.size(),
 | 
| -              &message_size)) {
 | 
| -        // If we've read the whole message....
 | 
| -        if (bytes_.size() >= message_size) {
 | 
| -          bool rv = true;
 | 
| -          MessageInTransit::View message_view(message_size, &bytes_[0]);
 | 
| -          CHECK_EQ(message_view.main_buffer_size(), message_size);
 | 
| -
 | 
| -          if (message_view.num_bytes() != expected_size) {
 | 
| -            LOG(ERROR) << "Wrong size: " << message_size << " instead of "
 | 
| -                       << expected_size << " bytes.";
 | 
| -            rv = false;
 | 
| -          } else if (!CheckMessageData(message_view.bytes(),
 | 
| -                                       message_view.num_bytes())) {
 | 
| -            LOG(ERROR) << "Incorrect message bytes.";
 | 
| -            rv = false;
 | 
| -          }
 | 
| -
 | 
| -          // Erase message data.
 | 
| -          bytes_.erase(bytes_.begin(),
 | 
| -                       bytes_.begin() + message_view.main_buffer_size());
 | 
| -          return rv;
 | 
| -        }
 | 
| -      }
 | 
| -
 | 
| -      if (static_cast<size_t>(read_size) < sizeof(buffer)) {
 | 
| -        i++;
 | 
| -        base::PlatformThread::Sleep(
 | 
| -            base::TimeDelta::FromMilliseconds(kMessageReaderSleepMs));
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    LOG(ERROR) << "Too many iterations.";
 | 
| -    return false;
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  const embedder::PlatformHandle handle_;
 | 
| -
 | 
| -  // The start of the received data should always be on a message boundary.
 | 
| -  std::vector<unsigned char> bytes_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(TestMessageReaderAndChecker);
 | 
| -};
 | 
| -
 | 
| -// Tests writing (and verifies reading using our own custom reader).
 | 
| -TEST_F(RawChannelTest, WriteMessage) {
 | 
| -  WriteOnlyRawChannelDelegate delegate;
 | 
| -  scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
 | 
| -  TestMessageReaderAndChecker checker(handles[1].get());
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
 | 
| -
 | 
| -  // Write and read, for a variety of sizes.
 | 
| -  for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) {
 | 
| -    EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size)));
 | 
| -    EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size;
 | 
| -  }
 | 
| -
 | 
| -  // Write/queue and read afterwards, for a variety of sizes.
 | 
| -  for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1)
 | 
| -    EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size)));
 | 
| -  for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1)
 | 
| -    EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size;
 | 
| -
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get())));
 | 
| -}
 | 
| -
 | 
| -// RawChannelTest.OnReadMessage ------------------------------------------------
 | 
| -
 | 
| -class ReadCheckerRawChannelDelegate : public RawChannel::Delegate {
 | 
| - public:
 | 
| -  ReadCheckerRawChannelDelegate() : done_event_(false, false), position_(0) {}
 | 
| -  ~ReadCheckerRawChannelDelegate() override {}
 | 
| -
 | 
| -  // |RawChannel::Delegate| implementation (called on the I/O thread):
 | 
| -  void OnReadMessage(
 | 
| -      const MessageInTransit::View& message_view,
 | 
| -      embedder::ScopedPlatformHandleVectorPtr platform_handles) override {
 | 
| -    EXPECT_FALSE(platform_handles);
 | 
| -
 | 
| -    size_t position;
 | 
| -    size_t expected_size;
 | 
| -    bool should_signal = false;
 | 
| -    {
 | 
| -      base::AutoLock locker(lock_);
 | 
| -      CHECK_LT(position_, expected_sizes_.size());
 | 
| -      position = position_;
 | 
| -      expected_size = expected_sizes_[position];
 | 
| -      position_++;
 | 
| -      if (position_ >= expected_sizes_.size())
 | 
| -        should_signal = true;
 | 
| -    }
 | 
| -
 | 
| -    EXPECT_EQ(expected_size, message_view.num_bytes()) << position;
 | 
| -    if (message_view.num_bytes() == expected_size) {
 | 
| -      EXPECT_TRUE(
 | 
| -          CheckMessageData(message_view.bytes(), message_view.num_bytes()))
 | 
| -          << position;
 | 
| -    }
 | 
| -
 | 
| -    if (should_signal)
 | 
| -      done_event_.Signal();
 | 
| -  }
 | 
| -  void OnError(Error error) override {
 | 
| -    // We'll get a read (shutdown) error when the connection is closed.
 | 
| -    CHECK_EQ(error, ERROR_READ_SHUTDOWN);
 | 
| -  }
 | 
| -
 | 
| -  // Waits for all the messages (of sizes |expected_sizes_|) to be seen.
 | 
| -  void Wait() { done_event_.Wait(); }
 | 
| -
 | 
| -  void SetExpectedSizes(const std::vector<uint32_t>& expected_sizes) {
 | 
| -    base::AutoLock locker(lock_);
 | 
| -    CHECK_EQ(position_, expected_sizes_.size());
 | 
| -    expected_sizes_ = expected_sizes;
 | 
| -    position_ = 0;
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  base::WaitableEvent done_event_;
 | 
| -
 | 
| -  base::Lock lock_;  // Protects the following members.
 | 
| -  std::vector<uint32_t> expected_sizes_;
 | 
| -  size_t position_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(ReadCheckerRawChannelDelegate);
 | 
| -};
 | 
| -
 | 
| -// Tests reading (writing using our own custom writer).
 | 
| -TEST_F(RawChannelTest, OnReadMessage) {
 | 
| -  ReadCheckerRawChannelDelegate delegate;
 | 
| -  scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
 | 
| -
 | 
| -  // Write and read, for a variety of sizes.
 | 
| -  for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) {
 | 
| -    delegate.SetExpectedSizes(std::vector<uint32_t>(1, size));
 | 
| -
 | 
| -    EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), size));
 | 
| -
 | 
| -    delegate.Wait();
 | 
| -  }
 | 
| -
 | 
| -  // Set up reader and write as fast as we can.
 | 
| -  // Write/queue and read afterwards, for a variety of sizes.
 | 
| -  std::vector<uint32_t> expected_sizes;
 | 
| -  for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1)
 | 
| -    expected_sizes.push_back(size);
 | 
| -  delegate.SetExpectedSizes(expected_sizes);
 | 
| -  for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1)
 | 
| -    EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), size));
 | 
| -  delegate.Wait();
 | 
| -
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get())));
 | 
| -}
 | 
| -
 | 
| -// RawChannelTest.WriteMessageAndOnReadMessage ---------------------------------
 | 
| -
 | 
| -class RawChannelWriterThread : public base::SimpleThread {
 | 
| - public:
 | 
| -  RawChannelWriterThread(RawChannel* raw_channel, size_t write_count)
 | 
| -      : base::SimpleThread("raw_channel_writer_thread"),
 | 
| -        raw_channel_(raw_channel),
 | 
| -        left_to_write_(write_count) {}
 | 
| -
 | 
| -  ~RawChannelWriterThread() override { Join(); }
 | 
| -
 | 
| - private:
 | 
| -  void Run() override {
 | 
| -    static const int kMaxRandomMessageSize = 25000;
 | 
| -
 | 
| -    while (left_to_write_-- > 0) {
 | 
| -      EXPECT_TRUE(raw_channel_->WriteMessage(MakeTestMessage(
 | 
| -          static_cast<uint32_t>(base::RandInt(1, kMaxRandomMessageSize)))));
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  RawChannel* const raw_channel_;
 | 
| -  size_t left_to_write_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(RawChannelWriterThread);
 | 
| -};
 | 
| -
 | 
| -class ReadCountdownRawChannelDelegate : public RawChannel::Delegate {
 | 
| - public:
 | 
| -  explicit ReadCountdownRawChannelDelegate(size_t expected_count)
 | 
| -      : done_event_(false, false), expected_count_(expected_count), count_(0) {}
 | 
| -  ~ReadCountdownRawChannelDelegate() override {}
 | 
| -
 | 
| -  // |RawChannel::Delegate| implementation (called on the I/O thread):
 | 
| -  void OnReadMessage(
 | 
| -      const MessageInTransit::View& message_view,
 | 
| -      embedder::ScopedPlatformHandleVectorPtr platform_handles) override {
 | 
| -    EXPECT_FALSE(platform_handles);
 | 
| -
 | 
| -    EXPECT_LT(count_, expected_count_);
 | 
| -    count_++;
 | 
| -
 | 
| -    EXPECT_TRUE(
 | 
| -        CheckMessageData(message_view.bytes(), message_view.num_bytes()));
 | 
| -
 | 
| -    if (count_ >= expected_count_)
 | 
| -      done_event_.Signal();
 | 
| -  }
 | 
| -  void OnError(Error error) override {
 | 
| -    // We'll get a read (shutdown) error when the connection is closed.
 | 
| -    CHECK_EQ(error, ERROR_READ_SHUTDOWN);
 | 
| -  }
 | 
| -
 | 
| -  // Waits for all the messages to have been seen.
 | 
| -  void Wait() { done_event_.Wait(); }
 | 
| -
 | 
| - private:
 | 
| -  base::WaitableEvent done_event_;
 | 
| -  size_t expected_count_;
 | 
| -  size_t count_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(ReadCountdownRawChannelDelegate);
 | 
| -};
 | 
| -
 | 
| -TEST_F(RawChannelTest, WriteMessageAndOnReadMessage) {
 | 
| -  static const size_t kNumWriterThreads = 10;
 | 
| -  static const size_t kNumWriteMessagesPerThread = 4000;
 | 
| -
 | 
| -  WriteOnlyRawChannelDelegate writer_delegate;
 | 
| -  scoped_ptr<RawChannel> writer_rc(RawChannel::Create(handles[0].Pass()));
 | 
| -  io_thread()->PostTaskAndWait(FROM_HERE,
 | 
| -                               base::Bind(&InitOnIOThread, writer_rc.get(),
 | 
| -                                          base::Unretained(&writer_delegate)));
 | 
| -
 | 
| -  ReadCountdownRawChannelDelegate reader_delegate(kNumWriterThreads *
 | 
| -                                                  kNumWriteMessagesPerThread);
 | 
| -  scoped_ptr<RawChannel> reader_rc(RawChannel::Create(handles[1].Pass()));
 | 
| -  io_thread()->PostTaskAndWait(FROM_HERE,
 | 
| -                               base::Bind(&InitOnIOThread, reader_rc.get(),
 | 
| -                                          base::Unretained(&reader_delegate)));
 | 
| -
 | 
| -  {
 | 
| -    ScopedVector<RawChannelWriterThread> writer_threads;
 | 
| -    for (size_t i = 0; i < kNumWriterThreads; i++) {
 | 
| -      writer_threads.push_back(new RawChannelWriterThread(
 | 
| -          writer_rc.get(), kNumWriteMessagesPerThread));
 | 
| -    }
 | 
| -    for (size_t i = 0; i < writer_threads.size(); i++)
 | 
| -      writer_threads[i]->Start();
 | 
| -  }  // Joins all the writer threads.
 | 
| -
 | 
| -  // Sleep a bit, to let any extraneous reads be processed. (There shouldn't be
 | 
| -  // any, but we want to know about them.)
 | 
| -  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
 | 
| -
 | 
| -  // Wait for reading to finish.
 | 
| -  reader_delegate.Wait();
 | 
| -
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&RawChannel::Shutdown, base::Unretained(reader_rc.get())));
 | 
| -
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&RawChannel::Shutdown, base::Unretained(writer_rc.get())));
 | 
| -}
 | 
| -
 | 
| -// RawChannelTest.OnError ------------------------------------------------------
 | 
| -
 | 
| -class ErrorRecordingRawChannelDelegate
 | 
| -    : public ReadCountdownRawChannelDelegate {
 | 
| - public:
 | 
| -  ErrorRecordingRawChannelDelegate(size_t expected_read_count,
 | 
| -                                   bool expect_read_error,
 | 
| -                                   bool expect_write_error)
 | 
| -      : ReadCountdownRawChannelDelegate(expected_read_count),
 | 
| -        got_read_error_event_(false, false),
 | 
| -        got_write_error_event_(false, false),
 | 
| -        expecting_read_error_(expect_read_error),
 | 
| -        expecting_write_error_(expect_write_error) {}
 | 
| -
 | 
| -  ~ErrorRecordingRawChannelDelegate() override {}
 | 
| -
 | 
| -  void OnError(Error error) override {
 | 
| -    switch (error) {
 | 
| -      case ERROR_READ_SHUTDOWN:
 | 
| -        ASSERT_TRUE(expecting_read_error_);
 | 
| -        expecting_read_error_ = false;
 | 
| -        got_read_error_event_.Signal();
 | 
| -        break;
 | 
| -      case ERROR_READ_BROKEN:
 | 
| -        // TODO(vtl): Test broken connections.
 | 
| -        CHECK(false);
 | 
| -        break;
 | 
| -      case ERROR_READ_BAD_MESSAGE:
 | 
| -        // TODO(vtl): Test reception/detection of bad messages.
 | 
| -        CHECK(false);
 | 
| -        break;
 | 
| -      case ERROR_READ_UNKNOWN:
 | 
| -        // TODO(vtl): Test however it is we might get here.
 | 
| -        CHECK(false);
 | 
| -        break;
 | 
| -      case ERROR_WRITE:
 | 
| -        ASSERT_TRUE(expecting_write_error_);
 | 
| -        expecting_write_error_ = false;
 | 
| -        got_write_error_event_.Signal();
 | 
| -        break;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void WaitForReadError() { got_read_error_event_.Wait(); }
 | 
| -  void WaitForWriteError() { got_write_error_event_.Wait(); }
 | 
| -
 | 
| - private:
 | 
| -  base::WaitableEvent got_read_error_event_;
 | 
| -  base::WaitableEvent got_write_error_event_;
 | 
| -
 | 
| -  bool expecting_read_error_;
 | 
| -  bool expecting_write_error_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(ErrorRecordingRawChannelDelegate);
 | 
| -};
 | 
| -
 | 
| -// Tests (fatal) errors.
 | 
| -TEST_F(RawChannelTest, OnError) {
 | 
| -  ErrorRecordingRawChannelDelegate delegate(0, true, true);
 | 
| -  scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
 | 
| -
 | 
| -  // Close the handle of the other end, which should make writing fail.
 | 
| -  handles[1].reset();
 | 
| -
 | 
| -  EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1)));
 | 
| -
 | 
| -  // We should get a write error.
 | 
| -  delegate.WaitForWriteError();
 | 
| -
 | 
| -  // We should also get a read error.
 | 
| -  delegate.WaitForReadError();
 | 
| -
 | 
| -  EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(2)));
 | 
| -
 | 
| -  // Sleep a bit, to make sure we don't get another |OnError()|
 | 
| -  // notification. (If we actually get another one, |OnError()| crashes.)
 | 
| -  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
 | 
| -
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get())));
 | 
| -}
 | 
| -
 | 
| -// RawChannelTest.ReadUnaffectedByWriteError -----------------------------------
 | 
| -
 | 
| -TEST_F(RawChannelTest, ReadUnaffectedByWriteError) {
 | 
| -  const size_t kMessageCount = 5;
 | 
| -
 | 
| -  // Write a few messages into the other end.
 | 
| -  uint32_t message_size = 1;
 | 
| -  for (size_t i = 0; i < kMessageCount;
 | 
| -       i++, message_size += message_size / 2 + 1)
 | 
| -    EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), message_size));
 | 
| -
 | 
| -  // Close the other end, which should make writing fail.
 | 
| -  handles[1].reset();
 | 
| -
 | 
| -  // Only start up reading here. The system buffer should still contain the
 | 
| -  // messages that were written.
 | 
| -  ErrorRecordingRawChannelDelegate delegate(kMessageCount, true, true);
 | 
| -  scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
 | 
| -
 | 
| -  EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1)));
 | 
| -
 | 
| -  // We should definitely get a write error.
 | 
| -  delegate.WaitForWriteError();
 | 
| -
 | 
| -  // Wait for reading to finish. A writing failure shouldn't affect reading.
 | 
| -  delegate.Wait();
 | 
| -
 | 
| -  // And then we should get a read error.
 | 
| -  delegate.WaitForReadError();
 | 
| -
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get())));
 | 
| -}
 | 
| -
 | 
| -// RawChannelTest.WriteMessageAfterShutdown ------------------------------------
 | 
| -
 | 
| -// Makes sure that calling |WriteMessage()| after |Shutdown()| behaves
 | 
| -// correctly.
 | 
| -TEST_F(RawChannelTest, WriteMessageAfterShutdown) {
 | 
| -  WriteOnlyRawChannelDelegate delegate;
 | 
| -  scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get())));
 | 
| -
 | 
| -  EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1)));
 | 
| -}
 | 
| -
 | 
| -// RawChannelTest.ShutdownOnReadMessage ----------------------------------------
 | 
| -
 | 
| -class ShutdownOnReadMessageRawChannelDelegate : public RawChannel::Delegate {
 | 
| - public:
 | 
| -  explicit ShutdownOnReadMessageRawChannelDelegate(RawChannel* raw_channel)
 | 
| -      : raw_channel_(raw_channel),
 | 
| -        done_event_(false, false),
 | 
| -        did_shutdown_(false) {}
 | 
| -  ~ShutdownOnReadMessageRawChannelDelegate() override {}
 | 
| -
 | 
| -  // |RawChannel::Delegate| implementation (called on the I/O thread):
 | 
| -  void OnReadMessage(
 | 
| -      const MessageInTransit::View& message_view,
 | 
| -      embedder::ScopedPlatformHandleVectorPtr platform_handles) override {
 | 
| -    EXPECT_FALSE(platform_handles);
 | 
| -    EXPECT_FALSE(did_shutdown_);
 | 
| -    EXPECT_TRUE(
 | 
| -        CheckMessageData(message_view.bytes(), message_view.num_bytes()));
 | 
| -    raw_channel_->Shutdown();
 | 
| -    did_shutdown_ = true;
 | 
| -    done_event_.Signal();
 | 
| -  }
 | 
| -  void OnError(Error /*error*/) override {
 | 
| -    CHECK(false);  // Should not get called.
 | 
| -  }
 | 
| -
 | 
| -  // Waits for shutdown.
 | 
| -  void Wait() {
 | 
| -    done_event_.Wait();
 | 
| -    EXPECT_TRUE(did_shutdown_);
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  RawChannel* const raw_channel_;
 | 
| -  base::WaitableEvent done_event_;
 | 
| -  bool did_shutdown_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(ShutdownOnReadMessageRawChannelDelegate);
 | 
| -};
 | 
| -
 | 
| -TEST_F(RawChannelTest, ShutdownOnReadMessage) {
 | 
| -  // Write a few messages into the other end.
 | 
| -  for (size_t count = 0; count < 5; count++)
 | 
| -    EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), 10));
 | 
| -
 | 
| -  scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
 | 
| -  ShutdownOnReadMessageRawChannelDelegate delegate(rc.get());
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
 | 
| -
 | 
| -  // Wait for the delegate, which will shut the |RawChannel| down.
 | 
| -  delegate.Wait();
 | 
| -}
 | 
| -
 | 
| -// RawChannelTest.ShutdownOnError{Read, Write} ---------------------------------
 | 
| -
 | 
| -class ShutdownOnErrorRawChannelDelegate : public RawChannel::Delegate {
 | 
| - public:
 | 
| -  ShutdownOnErrorRawChannelDelegate(RawChannel* raw_channel,
 | 
| -                                    Error shutdown_on_error_type)
 | 
| -      : raw_channel_(raw_channel),
 | 
| -        shutdown_on_error_type_(shutdown_on_error_type),
 | 
| -        done_event_(false, false),
 | 
| -        did_shutdown_(false) {}
 | 
| -  ~ShutdownOnErrorRawChannelDelegate() override {}
 | 
| -
 | 
| -  // |RawChannel::Delegate| implementation (called on the I/O thread):
 | 
| -  void OnReadMessage(
 | 
| -      const MessageInTransit::View& /*message_view*/,
 | 
| -      embedder::ScopedPlatformHandleVectorPtr /*platform_handles*/) override {
 | 
| -    CHECK(false);  // Should not get called.
 | 
| -  }
 | 
| -  void OnError(Error error) override {
 | 
| -    EXPECT_FALSE(did_shutdown_);
 | 
| -    if (error != shutdown_on_error_type_)
 | 
| -      return;
 | 
| -    raw_channel_->Shutdown();
 | 
| -    did_shutdown_ = true;
 | 
| -    done_event_.Signal();
 | 
| -  }
 | 
| -
 | 
| -  // Waits for shutdown.
 | 
| -  void Wait() {
 | 
| -    done_event_.Wait();
 | 
| -    EXPECT_TRUE(did_shutdown_);
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  RawChannel* const raw_channel_;
 | 
| -  const Error shutdown_on_error_type_;
 | 
| -  base::WaitableEvent done_event_;
 | 
| -  bool did_shutdown_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(ShutdownOnErrorRawChannelDelegate);
 | 
| -};
 | 
| -
 | 
| -TEST_F(RawChannelTest, ShutdownOnErrorRead) {
 | 
| -  scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
 | 
| -  ShutdownOnErrorRawChannelDelegate delegate(
 | 
| -      rc.get(), RawChannel::Delegate::ERROR_READ_SHUTDOWN);
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
 | 
| -
 | 
| -  // Close the handle of the other end, which should stuff fail.
 | 
| -  handles[1].reset();
 | 
| -
 | 
| -  // Wait for the delegate, which will shut the |RawChannel| down.
 | 
| -  delegate.Wait();
 | 
| -}
 | 
| -
 | 
| -TEST_F(RawChannelTest, ShutdownOnErrorWrite) {
 | 
| -  scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
 | 
| -  ShutdownOnErrorRawChannelDelegate delegate(rc.get(),
 | 
| -                                             RawChannel::Delegate::ERROR_WRITE);
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
 | 
| -
 | 
| -  // Close the handle of the other end, which should stuff fail.
 | 
| -  handles[1].reset();
 | 
| -
 | 
| -  EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1)));
 | 
| -
 | 
| -  // Wait for the delegate, which will shut the |RawChannel| down.
 | 
| -  delegate.Wait();
 | 
| -}
 | 
| -
 | 
| -// RawChannelTest.ReadWritePlatformHandles -------------------------------------
 | 
| -
 | 
| -class ReadPlatformHandlesCheckerRawChannelDelegate
 | 
| -    : public RawChannel::Delegate {
 | 
| - public:
 | 
| -  ReadPlatformHandlesCheckerRawChannelDelegate() : done_event_(false, false) {}
 | 
| -  ~ReadPlatformHandlesCheckerRawChannelDelegate() override {}
 | 
| -
 | 
| -  // |RawChannel::Delegate| implementation (called on the I/O thread):
 | 
| -  void OnReadMessage(
 | 
| -      const MessageInTransit::View& message_view,
 | 
| -      embedder::ScopedPlatformHandleVectorPtr platform_handles) override {
 | 
| -    const char kHello[] = "hello";
 | 
| -
 | 
| -    EXPECT_EQ(sizeof(kHello), message_view.num_bytes());
 | 
| -    EXPECT_STREQ(kHello, static_cast<const char*>(message_view.bytes()));
 | 
| -
 | 
| -    ASSERT_TRUE(platform_handles);
 | 
| -    ASSERT_EQ(2u, platform_handles->size());
 | 
| -    embedder::ScopedPlatformHandle h1(platform_handles->at(0));
 | 
| -    EXPECT_TRUE(h1.is_valid());
 | 
| -    embedder::ScopedPlatformHandle h2(platform_handles->at(1));
 | 
| -    EXPECT_TRUE(h2.is_valid());
 | 
| -    platform_handles->clear();
 | 
| -
 | 
| -    {
 | 
| -      char buffer[100] = {};
 | 
| -
 | 
| -      base::ScopedFILE fp(mojo::test::FILEFromPlatformHandle(h1.Pass(), "rb"));
 | 
| -      EXPECT_TRUE(fp);
 | 
| -      rewind(fp.get());
 | 
| -      EXPECT_EQ(1u, fread(buffer, 1, sizeof(buffer), fp.get()));
 | 
| -      EXPECT_EQ('1', buffer[0]);
 | 
| -    }
 | 
| -
 | 
| -    {
 | 
| -      char buffer[100] = {};
 | 
| -      base::ScopedFILE fp(mojo::test::FILEFromPlatformHandle(h2.Pass(), "rb"));
 | 
| -      EXPECT_TRUE(fp);
 | 
| -      rewind(fp.get());
 | 
| -      EXPECT_EQ(1u, fread(buffer, 1, sizeof(buffer), fp.get()));
 | 
| -      EXPECT_EQ('2', buffer[0]);
 | 
| -    }
 | 
| -
 | 
| -    done_event_.Signal();
 | 
| -  }
 | 
| -  void OnError(Error error) override {
 | 
| -    // We'll get a read (shutdown) error when the connection is closed.
 | 
| -    CHECK_EQ(error, ERROR_READ_SHUTDOWN);
 | 
| -  }
 | 
| -
 | 
| -  void Wait() { done_event_.Wait(); }
 | 
| -
 | 
| - private:
 | 
| -  base::WaitableEvent done_event_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(ReadPlatformHandlesCheckerRawChannelDelegate);
 | 
| -};
 | 
| -
 | 
| -#if defined(OS_POSIX)
 | 
| -#define MAYBE_ReadWritePlatformHandles ReadWritePlatformHandles
 | 
| -#else
 | 
| -// Not yet implemented (on Windows).
 | 
| -#define MAYBE_ReadWritePlatformHandles DISABLED_ReadWritePlatformHandles
 | 
| -#endif
 | 
| -TEST_F(RawChannelTest, MAYBE_ReadWritePlatformHandles) {
 | 
| -  base::ScopedTempDir temp_dir;
 | 
| -  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
 | 
| -
 | 
| -  WriteOnlyRawChannelDelegate write_delegate;
 | 
| -  scoped_ptr<RawChannel> rc_write(RawChannel::Create(handles[0].Pass()));
 | 
| -  io_thread()->PostTaskAndWait(FROM_HERE,
 | 
| -                               base::Bind(&InitOnIOThread, rc_write.get(),
 | 
| -                                          base::Unretained(&write_delegate)));
 | 
| -
 | 
| -  ReadPlatformHandlesCheckerRawChannelDelegate read_delegate;
 | 
| -  scoped_ptr<RawChannel> rc_read(RawChannel::Create(handles[1].Pass()));
 | 
| -  io_thread()->PostTaskAndWait(FROM_HERE,
 | 
| -                               base::Bind(&InitOnIOThread, rc_read.get(),
 | 
| -                                          base::Unretained(&read_delegate)));
 | 
| -
 | 
| -  base::FilePath unused;
 | 
| -  base::ScopedFILE fp1(
 | 
| -      base::CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused));
 | 
| -  EXPECT_EQ(1u, fwrite("1", 1, 1, fp1.get()));
 | 
| -  base::ScopedFILE fp2(
 | 
| -      base::CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused));
 | 
| -  EXPECT_EQ(1u, fwrite("2", 1, 1, fp2.get()));
 | 
| -
 | 
| -  {
 | 
| -    const char kHello[] = "hello";
 | 
| -    embedder::ScopedPlatformHandleVectorPtr platform_handles(
 | 
| -        new embedder::PlatformHandleVector());
 | 
| -    platform_handles->push_back(
 | 
| -        mojo::test::PlatformHandleFromFILE(fp1.Pass()).release());
 | 
| -    platform_handles->push_back(
 | 
| -        mojo::test::PlatformHandleFromFILE(fp2.Pass()).release());
 | 
| -
 | 
| -    scoped_ptr<MessageInTransit> message(new MessageInTransit(
 | 
| -        MessageInTransit::kTypeEndpoint, MessageInTransit::kSubtypeEndpointData,
 | 
| -        sizeof(kHello), kHello));
 | 
| -    message->SetTransportData(
 | 
| -        make_scoped_ptr(new TransportData(platform_handles.Pass())));
 | 
| -    EXPECT_TRUE(rc_write->WriteMessage(message.Pass()));
 | 
| -  }
 | 
| -
 | 
| -  read_delegate.Wait();
 | 
| -
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&RawChannel::Shutdown, base::Unretained(rc_read.get())));
 | 
| -  io_thread()->PostTaskAndWait(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&RawChannel::Shutdown, base::Unretained(rc_write.get())));
 | 
| -}
 | 
| -
 | 
| -}  // namespace
 | 
| -}  // namespace system
 | 
| -}  // namespace mojo
 | 
| 
 |