| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/edk/system/channel.h" | 5 #include "mojo/edk/system/channel.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/test/test_io_thread.h" | 10 #include "base/test/test_io_thread.h" |
| 11 #include "mojo/edk/embedder/platform_channel_pair.h" | 11 #include "mojo/edk/embedder/platform_channel_pair.h" |
| 12 #include "mojo/edk/embedder/simple_platform_support.h" | 12 #include "mojo/edk/embedder/simple_platform_support.h" |
| 13 #include "mojo/edk/system/channel_endpoint.h" | 13 #include "mojo/edk/system/channel_endpoint.h" |
| 14 #include "mojo/edk/system/channel_endpoint_id.h" | 14 #include "mojo/edk/system/channel_endpoint_id.h" |
| 15 #include "mojo/edk/system/message_pipe.h" | 15 #include "mojo/edk/system/message_pipe.h" |
| 16 #include "mojo/edk/system/raw_channel.h" | 16 #include "mojo/edk/system/raw_channel.h" |
| 17 #include "mojo/edk/system/test_utils.h" | 17 #include "mojo/edk/system/test_utils.h" |
| 18 #include "mojo/edk/system/waiter.h" | 18 #include "mojo/edk/system/waiter.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 20 |
| 21 namespace mojo { | 21 namespace mojo { |
| 22 namespace system { | 22 namespace system { |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 enum Tristate { TRISTATE_UNKNOWN = -1, TRISTATE_FALSE = 0, TRISTATE_TRUE = 1 }; | |
| 26 | |
| 27 Tristate BoolToTristate(bool b) { | |
| 28 return b ? TRISTATE_TRUE : TRISTATE_FALSE; | |
| 29 } | |
| 30 | |
| 31 class ChannelTest : public testing::Test { | 25 class ChannelTest : public testing::Test { |
| 32 public: | 26 public: |
| 33 ChannelTest() | 27 ChannelTest() : io_thread_(base::TestIOThread::kAutoStart) {} |
| 34 : io_thread_(base::TestIOThread::kAutoStart), | |
| 35 init_result_(TRISTATE_UNKNOWN) {} | |
| 36 ~ChannelTest() override {} | 28 ~ChannelTest() override {} |
| 37 | 29 |
| 38 void SetUp() override { | 30 void SetUp() override { |
| 39 io_thread_.PostTaskAndWait( | 31 io_thread_.PostTaskAndWait( |
| 40 FROM_HERE, | 32 FROM_HERE, |
| 41 base::Bind(&ChannelTest::SetUpOnIOThread, base::Unretained(this))); | 33 base::Bind(&ChannelTest::SetUpOnIOThread, base::Unretained(this))); |
| 42 } | 34 } |
| 43 | 35 |
| 44 void CreateChannelOnIOThread() { | 36 void CreateChannelOnIOThread() { |
| 45 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); | 37 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); |
| 46 channel_ = new Channel(&platform_support_); | 38 channel_ = new Channel(&platform_support_); |
| 47 } | 39 } |
| 48 | 40 |
| 49 void InitChannelOnIOThread() { | 41 void InitChannelOnIOThread() { |
| 50 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); | 42 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); |
| 51 | 43 |
| 52 CHECK(raw_channel_); | 44 CHECK(raw_channel_); |
| 53 CHECK(channel_); | 45 CHECK(channel_); |
| 54 CHECK_EQ(init_result_, TRISTATE_UNKNOWN); | 46 channel_->Init(raw_channel_.Pass()); |
| 55 | |
| 56 init_result_ = BoolToTristate(channel_->Init(raw_channel_.Pass())); | |
| 57 } | 47 } |
| 58 | 48 |
| 59 void ShutdownChannelOnIOThread() { | 49 void ShutdownChannelOnIOThread() { |
| 60 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); | 50 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); |
| 61 | 51 |
| 62 CHECK(channel_); | 52 CHECK(channel_); |
| 63 channel_->Shutdown(); | 53 channel_->Shutdown(); |
| 64 } | 54 } |
| 65 | 55 |
| 66 base::TestIOThread* io_thread() { return &io_thread_; } | 56 base::TestIOThread* io_thread() { return &io_thread_; } |
| 67 RawChannel* raw_channel() { return raw_channel_.get(); } | 57 RawChannel* raw_channel() { return raw_channel_.get(); } |
| 68 scoped_ptr<RawChannel>* mutable_raw_channel() { return &raw_channel_; } | 58 scoped_ptr<RawChannel>* mutable_raw_channel() { return &raw_channel_; } |
| 69 Channel* channel() { return channel_.get(); } | 59 Channel* channel() { return channel_.get(); } |
| 70 scoped_refptr<Channel>* mutable_channel() { return &channel_; } | 60 scoped_refptr<Channel>* mutable_channel() { return &channel_; } |
| 71 Tristate init_result() const { return init_result_; } | |
| 72 | 61 |
| 73 private: | 62 private: |
| 74 void SetUpOnIOThread() { | 63 void SetUpOnIOThread() { |
| 75 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); | 64 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop()); |
| 76 | 65 |
| 77 embedder::PlatformChannelPair channel_pair; | 66 embedder::PlatformChannelPair channel_pair; |
| 78 raw_channel_ = RawChannel::Create(channel_pair.PassServerHandle()).Pass(); | 67 raw_channel_ = RawChannel::Create(channel_pair.PassServerHandle()).Pass(); |
| 79 other_platform_handle_ = channel_pair.PassClientHandle(); | 68 other_platform_handle_ = channel_pair.PassClientHandle(); |
| 80 } | 69 } |
| 81 | 70 |
| 82 embedder::SimplePlatformSupport platform_support_; | 71 embedder::SimplePlatformSupport platform_support_; |
| 83 base::TestIOThread io_thread_; | 72 base::TestIOThread io_thread_; |
| 84 scoped_ptr<RawChannel> raw_channel_; | 73 scoped_ptr<RawChannel> raw_channel_; |
| 85 embedder::ScopedPlatformHandle other_platform_handle_; | 74 embedder::ScopedPlatformHandle other_platform_handle_; |
| 86 scoped_refptr<Channel> channel_; | 75 scoped_refptr<Channel> channel_; |
| 87 | 76 |
| 88 Tristate init_result_; | |
| 89 | |
| 90 DISALLOW_COPY_AND_ASSIGN(ChannelTest); | 77 DISALLOW_COPY_AND_ASSIGN(ChannelTest); |
| 91 }; | 78 }; |
| 92 | 79 |
| 93 // ChannelTest.InitShutdown ---------------------------------------------------- | 80 // ChannelTest.InitShutdown ---------------------------------------------------- |
| 94 | 81 |
| 95 TEST_F(ChannelTest, InitShutdown) { | 82 TEST_F(ChannelTest, InitShutdown) { |
| 96 io_thread()->PostTaskAndWait(FROM_HERE, | 83 io_thread()->PostTaskAndWait(FROM_HERE, |
| 97 base::Bind(&ChannelTest::CreateChannelOnIOThread, | 84 base::Bind(&ChannelTest::CreateChannelOnIOThread, |
| 98 base::Unretained(this))); | 85 base::Unretained(this))); |
| 99 ASSERT_TRUE(channel()); | 86 ASSERT_TRUE(channel()); |
| 100 | 87 |
| 101 io_thread()->PostTaskAndWait( | 88 io_thread()->PostTaskAndWait( |
| 102 FROM_HERE, | 89 FROM_HERE, |
| 103 base::Bind(&ChannelTest::InitChannelOnIOThread, base::Unretained(this))); | 90 base::Bind(&ChannelTest::InitChannelOnIOThread, base::Unretained(this))); |
| 104 EXPECT_EQ(TRISTATE_TRUE, init_result()); | |
| 105 | 91 |
| 106 io_thread()->PostTaskAndWait( | 92 io_thread()->PostTaskAndWait( |
| 107 FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread, | 93 FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread, |
| 108 base::Unretained(this))); | 94 base::Unretained(this))); |
| 109 | 95 |
| 110 // Okay to destroy |Channel| on not-the-I/O-thread. | 96 // Okay to destroy |Channel| on not-the-I/O-thread. |
| 111 EXPECT_TRUE(channel()->HasOneRef()); | 97 EXPECT_TRUE(channel()->HasOneRef()); |
| 112 *mutable_channel() = nullptr; | 98 *mutable_channel() = nullptr; |
| 113 } | 99 } |
| 114 | 100 |
| 115 // ChannelTest.InitFails ------------------------------------------------------- | |
| 116 | |
| 117 class MockRawChannelOnInitFails : public RawChannel { | |
| 118 public: | |
| 119 MockRawChannelOnInitFails() : on_init_called_(false) {} | |
| 120 ~MockRawChannelOnInitFails() override {} | |
| 121 | |
| 122 // |RawChannel| public methods: | |
| 123 size_t GetSerializedPlatformHandleSize() const override { return 0; } | |
| 124 | |
| 125 private: | |
| 126 // |RawChannel| protected methods: | |
| 127 IOResult Read(size_t*) override { | |
| 128 CHECK(false); | |
| 129 return IO_FAILED_UNKNOWN; | |
| 130 } | |
| 131 IOResult ScheduleRead() override { | |
| 132 CHECK(false); | |
| 133 return IO_FAILED_UNKNOWN; | |
| 134 } | |
| 135 embedder::ScopedPlatformHandleVectorPtr GetReadPlatformHandles( | |
| 136 size_t, | |
| 137 const void*) override { | |
| 138 CHECK(false); | |
| 139 return embedder::ScopedPlatformHandleVectorPtr(); | |
| 140 } | |
| 141 IOResult WriteNoLock(size_t*, size_t*) override { | |
| 142 CHECK(false); | |
| 143 return IO_FAILED_UNKNOWN; | |
| 144 } | |
| 145 IOResult ScheduleWriteNoLock() override { | |
| 146 CHECK(false); | |
| 147 return IO_FAILED_UNKNOWN; | |
| 148 } | |
| 149 bool OnInit() override { | |
| 150 EXPECT_FALSE(on_init_called_); | |
| 151 on_init_called_ = true; | |
| 152 return false; | |
| 153 } | |
| 154 void OnShutdownNoLock(scoped_ptr<ReadBuffer>, | |
| 155 scoped_ptr<WriteBuffer>) override { | |
| 156 CHECK(false); | |
| 157 } | |
| 158 | |
| 159 bool on_init_called_; | |
| 160 | |
| 161 DISALLOW_COPY_AND_ASSIGN(MockRawChannelOnInitFails); | |
| 162 }; | |
| 163 | |
| 164 TEST_F(ChannelTest, InitFails) { | |
| 165 io_thread()->PostTaskAndWait(FROM_HERE, | |
| 166 base::Bind(&ChannelTest::CreateChannelOnIOThread, | |
| 167 base::Unretained(this))); | |
| 168 ASSERT_TRUE(channel()); | |
| 169 | |
| 170 ASSERT_TRUE(raw_channel()); | |
| 171 mutable_raw_channel()->reset(new MockRawChannelOnInitFails()); | |
| 172 | |
| 173 io_thread()->PostTaskAndWait( | |
| 174 FROM_HERE, | |
| 175 base::Bind(&ChannelTest::InitChannelOnIOThread, base::Unretained(this))); | |
| 176 EXPECT_EQ(TRISTATE_FALSE, init_result()); | |
| 177 | |
| 178 // Should destroy |Channel| with no |Shutdown()| (on not-the-I/O-thread). | |
| 179 EXPECT_TRUE(channel()->HasOneRef()); | |
| 180 *mutable_channel() = nullptr; | |
| 181 } | |
| 182 | |
| 183 // ChannelTest.CloseBeforeAttachAndRun ----------------------------------------- | 101 // ChannelTest.CloseBeforeAttachAndRun ----------------------------------------- |
| 184 | 102 |
| 185 TEST_F(ChannelTest, CloseBeforeRun) { | 103 TEST_F(ChannelTest, CloseBeforeRun) { |
| 186 io_thread()->PostTaskAndWait(FROM_HERE, | 104 io_thread()->PostTaskAndWait(FROM_HERE, |
| 187 base::Bind(&ChannelTest::CreateChannelOnIOThread, | 105 base::Bind(&ChannelTest::CreateChannelOnIOThread, |
| 188 base::Unretained(this))); | 106 base::Unretained(this))); |
| 189 ASSERT_TRUE(channel()); | 107 ASSERT_TRUE(channel()); |
| 190 | 108 |
| 191 io_thread()->PostTaskAndWait( | 109 io_thread()->PostTaskAndWait( |
| 192 FROM_HERE, | 110 FROM_HERE, |
| 193 base::Bind(&ChannelTest::InitChannelOnIOThread, base::Unretained(this))); | 111 base::Bind(&ChannelTest::InitChannelOnIOThread, base::Unretained(this))); |
| 194 EXPECT_EQ(TRISTATE_TRUE, init_result()); | |
| 195 | 112 |
| 196 scoped_refptr<ChannelEndpoint> channel_endpoint; | 113 scoped_refptr<ChannelEndpoint> channel_endpoint; |
| 197 scoped_refptr<MessagePipe> mp( | 114 scoped_refptr<MessagePipe> mp( |
| 198 MessagePipe::CreateLocalProxy(&channel_endpoint)); | 115 MessagePipe::CreateLocalProxy(&channel_endpoint)); |
| 199 | 116 |
| 200 mp->Close(0); | 117 mp->Close(0); |
| 201 | 118 |
| 202 channel()->SetBootstrapEndpoint(channel_endpoint); | 119 channel()->SetBootstrapEndpoint(channel_endpoint); |
| 203 | 120 |
| 204 io_thread()->PostTaskAndWait( | 121 io_thread()->PostTaskAndWait( |
| 205 FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread, | 122 FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread, |
| 206 base::Unretained(this))); | 123 base::Unretained(this))); |
| 207 | 124 |
| 208 EXPECT_TRUE(channel()->HasOneRef()); | 125 EXPECT_TRUE(channel()->HasOneRef()); |
| 209 } | 126 } |
| 210 | 127 |
| 211 // ChannelTest.ShutdownAfterAttachAndRun --------------------------------------- | 128 // ChannelTest.ShutdownAfterAttachAndRun --------------------------------------- |
| 212 | 129 |
| 213 TEST_F(ChannelTest, ShutdownAfterAttach) { | 130 TEST_F(ChannelTest, ShutdownAfterAttach) { |
| 214 io_thread()->PostTaskAndWait(FROM_HERE, | 131 io_thread()->PostTaskAndWait(FROM_HERE, |
| 215 base::Bind(&ChannelTest::CreateChannelOnIOThread, | 132 base::Bind(&ChannelTest::CreateChannelOnIOThread, |
| 216 base::Unretained(this))); | 133 base::Unretained(this))); |
| 217 ASSERT_TRUE(channel()); | 134 ASSERT_TRUE(channel()); |
| 218 | 135 |
| 219 io_thread()->PostTaskAndWait( | 136 io_thread()->PostTaskAndWait( |
| 220 FROM_HERE, | 137 FROM_HERE, |
| 221 base::Bind(&ChannelTest::InitChannelOnIOThread, base::Unretained(this))); | 138 base::Bind(&ChannelTest::InitChannelOnIOThread, base::Unretained(this))); |
| 222 EXPECT_EQ(TRISTATE_TRUE, init_result()); | |
| 223 | 139 |
| 224 scoped_refptr<ChannelEndpoint> channel_endpoint; | 140 scoped_refptr<ChannelEndpoint> channel_endpoint; |
| 225 scoped_refptr<MessagePipe> mp( | 141 scoped_refptr<MessagePipe> mp( |
| 226 MessagePipe::CreateLocalProxy(&channel_endpoint)); | 142 MessagePipe::CreateLocalProxy(&channel_endpoint)); |
| 227 | 143 |
| 228 channel()->SetBootstrapEndpoint(channel_endpoint); | 144 channel()->SetBootstrapEndpoint(channel_endpoint); |
| 229 | 145 |
| 230 Waiter waiter; | 146 Waiter waiter; |
| 231 waiter.Init(); | 147 waiter.Init(); |
| 232 ASSERT_EQ( | 148 ASSERT_EQ( |
| (...skipping 22 matching lines...) Expand all Loading... |
| 255 | 171 |
| 256 TEST_F(ChannelTest, WaitAfterAttachRunAndShutdown) { | 172 TEST_F(ChannelTest, WaitAfterAttachRunAndShutdown) { |
| 257 io_thread()->PostTaskAndWait(FROM_HERE, | 173 io_thread()->PostTaskAndWait(FROM_HERE, |
| 258 base::Bind(&ChannelTest::CreateChannelOnIOThread, | 174 base::Bind(&ChannelTest::CreateChannelOnIOThread, |
| 259 base::Unretained(this))); | 175 base::Unretained(this))); |
| 260 ASSERT_TRUE(channel()); | 176 ASSERT_TRUE(channel()); |
| 261 | 177 |
| 262 io_thread()->PostTaskAndWait( | 178 io_thread()->PostTaskAndWait( |
| 263 FROM_HERE, | 179 FROM_HERE, |
| 264 base::Bind(&ChannelTest::InitChannelOnIOThread, base::Unretained(this))); | 180 base::Bind(&ChannelTest::InitChannelOnIOThread, base::Unretained(this))); |
| 265 EXPECT_EQ(TRISTATE_TRUE, init_result()); | |
| 266 | 181 |
| 267 scoped_refptr<ChannelEndpoint> channel_endpoint; | 182 scoped_refptr<ChannelEndpoint> channel_endpoint; |
| 268 scoped_refptr<MessagePipe> mp( | 183 scoped_refptr<MessagePipe> mp( |
| 269 MessagePipe::CreateLocalProxy(&channel_endpoint)); | 184 MessagePipe::CreateLocalProxy(&channel_endpoint)); |
| 270 | 185 |
| 271 channel()->SetBootstrapEndpoint(channel_endpoint); | 186 channel()->SetBootstrapEndpoint(channel_endpoint); |
| 272 | 187 |
| 273 io_thread()->PostTaskAndWait( | 188 io_thread()->PostTaskAndWait( |
| 274 FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread, | 189 FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread, |
| 275 base::Unretained(this))); | 190 base::Unretained(this))); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 286 mp->Close(0); | 201 mp->Close(0); |
| 287 | 202 |
| 288 EXPECT_TRUE(channel()->HasOneRef()); | 203 EXPECT_TRUE(channel()->HasOneRef()); |
| 289 } | 204 } |
| 290 | 205 |
| 291 // TODO(vtl): More. ------------------------------------------------------------ | 206 // TODO(vtl): More. ------------------------------------------------------------ |
| 292 | 207 |
| 293 } // namespace | 208 } // namespace |
| 294 } // namespace system | 209 } // namespace system |
| 295 } // namespace mojo | 210 } // namespace mojo |
| OLD | NEW |