diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-25 15:19:32 +0000 |
---|---|---|
committer | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-25 15:19:32 +0000 |
commit | c1531f596f449c011cfdcbf053714af0385374c7 (patch) | |
tree | ca6c4f11a8fcdba75e3a704595b16c289df5f4fb /mojo/system | |
parent | 69c5739740ec74ce3adc7c477f191a674f9bdd89 (diff) | |
download | chromium_src-c1531f596f449c011cfdcbf053714af0385374c7.zip chromium_src-c1531f596f449c011cfdcbf053714af0385374c7.tar.gz chromium_src-c1531f596f449c011cfdcbf053714af0385374c7.tar.bz2 |
Mojo: Start writing some unit tests for mojo::system::Channel.
Also make RawChannels destroyable without DCHECK failures if OnInit()
fails.
R=yzshen@chromium.org
Review URL: https://codereview.chromium.org/251483007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266193 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/system')
-rw-r--r-- | mojo/system/channel_unittest.cc | 179 | ||||
-rw-r--r-- | mojo/system/raw_channel.cc | 7 | ||||
-rw-r--r-- | mojo/system/raw_channel.h | 4 |
3 files changed, 187 insertions, 3 deletions
diff --git a/mojo/system/channel_unittest.cc b/mojo/system/channel_unittest.cc new file mode 100644 index 0000000..3d676e7 --- /dev/null +++ b/mojo/system/channel_unittest.cc @@ -0,0 +1,179 @@ +// 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/system/channel.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/message_loop/message_loop.h" +#include "mojo/embedder/platform_channel_pair.h" +#include "mojo/system/raw_channel.h" +#include "mojo/system/test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { +namespace system { +namespace { + +enum Tristate { + TRISTATE_UNKNOWN = -1, + TRISTATE_FALSE = 0, + TRISTATE_TRUE = 1 +}; + +Tristate BoolToTristate(bool b) { + return b ? TRISTATE_TRUE : TRISTATE_FALSE; +} + +class ChannelTest : public testing::Test { + public: + ChannelTest() + : io_thread_(test::TestIOThread::kAutoStart), + init_result_(TRISTATE_UNKNOWN) {} + virtual ~ChannelTest() {} + + virtual void SetUp() OVERRIDE { + io_thread_.PostTaskAndWait( + FROM_HERE, + base::Bind(&ChannelTest::SetUpOnIOThread, base::Unretained(this))); + } + + void CreateChannelOnIOThread() { + CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); + channel_ = new Channel(); + } + + void InitChannelOnIOThread() { + CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); + + CHECK(raw_channel_); + CHECK(channel_); + CHECK_EQ(init_result_, TRISTATE_UNKNOWN); + + init_result_ = BoolToTristate(channel_->Init(raw_channel_.Pass())); + } + + void ShutdownChannelOnIOThread() { + CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); + + CHECK(channel_); + channel_->Shutdown(); + } + + test::TestIOThread* io_thread() { return &io_thread_; } + RawChannel* raw_channel() { return raw_channel_.get(); } + scoped_ptr<RawChannel>* mutable_raw_channel() { return &raw_channel_; } + Channel* channel() { return channel_.get(); } + scoped_refptr<Channel>* mutable_channel() { return &channel_; } + Tristate init_result() const { return init_result_; } + + private: + void SetUpOnIOThread() { + CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); + + embedder::PlatformChannelPair channel_pair; + raw_channel_ = RawChannel::Create(channel_pair.PassServerHandle()).Pass(); + other_platform_handle_ = channel_pair.PassClientHandle(); + } + + test::TestIOThread io_thread_; + scoped_ptr<RawChannel> raw_channel_; + embedder::ScopedPlatformHandle other_platform_handle_; + scoped_refptr<Channel> channel_; + + Tristate init_result_; + + DISALLOW_COPY_AND_ASSIGN(ChannelTest); +}; + +// ChannelTest.InitShutdown ---------------------------------------------------- + +TEST_F(ChannelTest, InitShutdown) { + io_thread()->PostTaskAndWait( + FROM_HERE, + base::Bind(&ChannelTest::CreateChannelOnIOThread, + base::Unretained(this))); + ASSERT_TRUE(channel()); + + io_thread()->PostTaskAndWait( + FROM_HERE, + base::Bind(&ChannelTest::InitChannelOnIOThread, + base::Unretained(this))); + EXPECT_EQ(TRISTATE_TRUE, init_result()); + + io_thread()->PostTaskAndWait( + FROM_HERE, + base::Bind(&ChannelTest::ShutdownChannelOnIOThread, + base::Unretained(this))); + + // Okay to destroy |Channel| on not-the-I/O-thread. + EXPECT_TRUE(channel()->HasOneRef()); + *mutable_channel() = NULL; +} + +// ChannelTest.InitFails ------------------------------------------------------- + +class MockRawChannelOnInitFails : public RawChannel { + public: + MockRawChannelOnInitFails() : on_init_called_(false) {} + virtual ~MockRawChannelOnInitFails() {} + + virtual IOResult Read(size_t*) OVERRIDE { + CHECK(false); + return IO_FAILED; + } + virtual IOResult ScheduleRead() OVERRIDE { + CHECK(false); + return IO_FAILED; + } + virtual IOResult WriteNoLock(size_t*) OVERRIDE { + CHECK(false); + return IO_FAILED; + } + virtual IOResult ScheduleWriteNoLock() OVERRIDE { + CHECK(false); + return IO_FAILED; + } + virtual bool OnInit() OVERRIDE { + EXPECT_FALSE(on_init_called_); + on_init_called_ = true; + return false; + } + virtual void OnShutdownNoLock(scoped_ptr<ReadBuffer>, + scoped_ptr<WriteBuffer>) OVERRIDE { + CHECK(false); + } + + private: + bool on_init_called_; + + DISALLOW_COPY_AND_ASSIGN(MockRawChannelOnInitFails); +}; + +TEST_F(ChannelTest, InitFails) { + io_thread()->PostTaskAndWait( + FROM_HERE, + base::Bind(&ChannelTest::CreateChannelOnIOThread, + base::Unretained(this))); + ASSERT_TRUE(channel()); + + ASSERT_TRUE(raw_channel()); + mutable_raw_channel()->reset(new MockRawChannelOnInitFails()); + + io_thread()->PostTaskAndWait( + FROM_HERE, + base::Bind(&ChannelTest::InitChannelOnIOThread, + base::Unretained(this))); + EXPECT_EQ(TRISTATE_FALSE, init_result()); + + // Should destroy |Channel| with no |Shutdown()| (on not-the-I/O-thread). + EXPECT_TRUE(channel()->HasOneRef()); + *mutable_channel() = NULL; +} + +// TODO(vtl): More. + +} // namespace +} // namespace system +} // namespace mojo diff --git a/mojo/system/raw_channel.cc b/mojo/system/raw_channel.cc index d9febeb..92b9a3d 100644 --- a/mojo/system/raw_channel.cc +++ b/mojo/system/raw_channel.cc @@ -126,8 +126,13 @@ bool RawChannel::Init(Delegate* delegate) { DCHECK(!write_buffer_); write_buffer_.reset(new WriteBuffer); - if (!OnInit()) + if (!OnInit()) { + delegate_ = NULL; + message_loop_for_io_ = NULL; + read_buffer_.reset(); + write_buffer_.reset(); return false; + } return ScheduleRead() == IO_PENDING; } diff --git a/mojo/system/raw_channel.h b/mojo/system/raw_channel.h index b4571f8..607a776 100644 --- a/mojo/system/raw_channel.h +++ b/mojo/system/raw_channel.h @@ -104,7 +104,7 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel { IO_PENDING }; - class ReadBuffer { + class MOJO_SYSTEM_IMPL_EXPORT ReadBuffer { public: ReadBuffer(); ~ReadBuffer(); @@ -124,7 +124,7 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel { DISALLOW_COPY_AND_ASSIGN(ReadBuffer); }; - class WriteBuffer { + class MOJO_SYSTEM_IMPL_EXPORT WriteBuffer { public: struct Buffer { const char* addr; |