| 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 "third_party/mojo/src/mojo/edk/system/raw_channel.h" | 5 #include "mojo/edk/system/raw_channel.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <stdio.h> | 8 #include <stdio.h> |
| 9 | 9 |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 14 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
| 15 #include "base/files/scoped_file.h" | 15 #include "base/files/scoped_file.h" |
| 16 #include "base/files/scoped_temp_dir.h" | 16 #include "base/files/scoped_temp_dir.h" |
| 17 #include "base/location.h" | 17 #include "base/location.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/memory/scoped_ptr.h" | 19 #include "base/memory/scoped_ptr.h" |
| 20 #include "base/memory/scoped_vector.h" | 20 #include "base/memory/scoped_vector.h" |
| 21 #include "base/rand_util.h" | 21 #include "base/rand_util.h" |
| 22 #include "base/synchronization/lock.h" |
| 22 #include "base/synchronization/waitable_event.h" | 23 #include "base/synchronization/waitable_event.h" |
| 23 #include "base/test/test_io_thread.h" | 24 #include "base/test/test_io_thread.h" |
| 24 #include "base/threading/simple_thread.h" | 25 #include "base/threading/simple_thread.h" |
| 25 #include "build/build_config.h" // TODO(vtl): Remove this. | 26 #include "build/build_config.h" // TODO(vtl): Remove this. |
| 27 #include "mojo/edk/embedder/platform_channel_pair.h" |
| 28 #include "mojo/edk/embedder/platform_handle.h" |
| 29 #include "mojo/edk/embedder/scoped_platform_handle.h" |
| 30 #include "mojo/edk/system/message_in_transit.h" |
| 31 #include "mojo/edk/system/test_utils.h" |
| 32 #include "mojo/edk/system/transport_data.h" |
| 33 #include "mojo/edk/test/test_utils.h" |
| 26 #include "mojo/public/cpp/system/macros.h" | 34 #include "mojo/public/cpp/system/macros.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
| 28 #include "third_party/mojo/src/mojo/edk/embedder/platform_channel_pair.h" | |
| 29 #include "third_party/mojo/src/mojo/edk/embedder/platform_handle.h" | |
| 30 #include "third_party/mojo/src/mojo/edk/embedder/scoped_platform_handle.h" | |
| 31 #include "third_party/mojo/src/mojo/edk/system/message_in_transit.h" | |
| 32 #include "third_party/mojo/src/mojo/edk/system/mutex.h" | |
| 33 #include "third_party/mojo/src/mojo/edk/system/test_utils.h" | |
| 34 #include "third_party/mojo/src/mojo/edk/system/transport_data.h" | |
| 35 #include "third_party/mojo/src/mojo/edk/test/test_utils.h" | |
| 36 | 36 |
| 37 namespace mojo { | 37 namespace mojo { |
| 38 namespace system { | 38 namespace edk { |
| 39 namespace { | 39 namespace { |
| 40 | 40 |
| 41 scoped_ptr<MessageInTransit> MakeTestMessage(uint32_t num_bytes) { | 41 scoped_ptr<MessageInTransit> MakeTestMessage(uint32_t num_bytes) { |
| 42 std::vector<unsigned char> bytes(num_bytes, 0); | 42 std::vector<unsigned char> bytes(num_bytes, 0); |
| 43 for (size_t i = 0; i < num_bytes; i++) | 43 for (size_t i = 0; i < num_bytes; i++) |
| 44 bytes[i] = static_cast<unsigned char>(i + num_bytes); | 44 bytes[i] = static_cast<unsigned char>(i + num_bytes); |
| 45 return make_scoped_ptr( | 45 return make_scoped_ptr( |
| 46 new MessageInTransit(MessageInTransit::Type::ENDPOINT_CLIENT, | 46 new MessageInTransit(MessageInTransit::Type::MESSAGE, |
| 47 MessageInTransit::Subtype::ENDPOINT_CLIENT_DATA, | |
| 48 num_bytes, bytes.empty() ? nullptr : &bytes[0])); | 47 num_bytes, bytes.empty() ? nullptr : &bytes[0])); |
| 49 } | 48 } |
| 50 | 49 |
| 51 bool CheckMessageData(const void* bytes, uint32_t num_bytes) { | 50 bool CheckMessageData(const void* bytes, uint32_t num_bytes) { |
| 52 const unsigned char* b = static_cast<const unsigned char*>(bytes); | 51 const unsigned char* b = static_cast<const unsigned char*>(bytes); |
| 53 for (uint32_t i = 0; i < num_bytes; i++) { | 52 for (uint32_t i = 0; i < num_bytes; i++) { |
| 54 if (b[i] != static_cast<unsigned char>(i + num_bytes)) | 53 if (b[i] != static_cast<unsigned char>(i + num_bytes)) |
| 55 return false; | 54 return false; |
| 56 } | 55 } |
| 57 return true; | 56 return true; |
| 58 } | 57 } |
| 59 | 58 |
| 60 void InitOnIOThread(RawChannel* raw_channel, RawChannel::Delegate* delegate) { | 59 void InitOnIOThread(RawChannel* raw_channel, RawChannel::Delegate* delegate) { |
| 61 raw_channel->Init(delegate); | 60 raw_channel->Init(delegate); |
| 62 } | 61 } |
| 63 | 62 |
| 64 bool WriteTestMessageToHandle(const embedder::PlatformHandle& handle, | 63 bool WriteTestMessageToHandle(const PlatformHandle& handle, |
| 65 uint32_t num_bytes) { | 64 uint32_t num_bytes) { |
| 66 scoped_ptr<MessageInTransit> message(MakeTestMessage(num_bytes)); | 65 scoped_ptr<MessageInTransit> message(MakeTestMessage(num_bytes)); |
| 67 | 66 |
| 68 size_t write_size = 0; | 67 size_t write_size = 0; |
| 69 mojo::test::BlockingWrite(handle, message->main_buffer(), | 68 test::BlockingWrite(handle, message->main_buffer(), |
| 70 message->main_buffer_size(), &write_size); | 69 message->main_buffer_size(), &write_size); |
| 71 return write_size == message->main_buffer_size(); | 70 return write_size == message->main_buffer_size(); |
| 72 } | 71 } |
| 73 | 72 |
| 74 // ----------------------------------------------------------------------------- | 73 // ----------------------------------------------------------------------------- |
| 75 | 74 |
| 76 class RawChannelTest : public testing::Test { | 75 class RawChannelTest : public test::MojoSystemTest { |
| 77 public: | 76 public: |
| 78 RawChannelTest() : io_thread_(base::TestIOThread::kManualStart) {} | 77 RawChannelTest() {} |
| 79 ~RawChannelTest() override {} | 78 ~RawChannelTest() override {} |
| 80 | 79 |
| 81 void SetUp() override { | 80 void SetUp() override { |
| 82 embedder::PlatformChannelPair channel_pair; | 81 PlatformChannelPair channel_pair; |
| 83 handles[0] = channel_pair.PassServerHandle(); | 82 handles[0] = channel_pair.PassServerHandle(); |
| 84 handles[1] = channel_pair.PassClientHandle(); | 83 handles[1] = channel_pair.PassClientHandle();\ |
| 85 io_thread_.Start(); | |
| 86 } | 84 } |
| 87 | 85 |
| 88 void TearDown() override { | 86 void TearDown() override { |
| 89 io_thread_.Stop(); | |
| 90 handles[0].reset(); | 87 handles[0].reset(); |
| 91 handles[1].reset(); | 88 handles[1].reset(); |
| 92 } | 89 } |
| 93 | 90 |
| 94 protected: | 91 protected: |
| 95 base::TestIOThread* io_thread() { return &io_thread_; } | 92 ScopedPlatformHandle handles[2]; |
| 96 | |
| 97 embedder::ScopedPlatformHandle handles[2]; | |
| 98 | 93 |
| 99 private: | 94 private: |
| 100 base::TestIOThread io_thread_; | |
| 101 | |
| 102 MOJO_DISALLOW_COPY_AND_ASSIGN(RawChannelTest); | 95 MOJO_DISALLOW_COPY_AND_ASSIGN(RawChannelTest); |
| 103 }; | 96 }; |
| 104 | 97 |
| 105 // RawChannelTest.WriteMessage ------------------------------------------------- | 98 // RawChannelTest.WriteMessage ------------------------------------------------- |
| 106 | 99 |
| 107 class WriteOnlyRawChannelDelegate : public RawChannel::Delegate { | 100 class WriteOnlyRawChannelDelegate : public RawChannel::Delegate { |
| 108 public: | 101 public: |
| 109 WriteOnlyRawChannelDelegate() {} | 102 WriteOnlyRawChannelDelegate() {} |
| 110 ~WriteOnlyRawChannelDelegate() override {} | 103 ~WriteOnlyRawChannelDelegate() override {} |
| 111 | 104 |
| 112 // |RawChannel::Delegate| implementation: | 105 // |RawChannel::Delegate| implementation: |
| 113 void OnReadMessage( | 106 void OnReadMessage( |
| 114 const MessageInTransit::View& /*message_view*/, | 107 const MessageInTransit::View& /*message_view*/, |
| 115 embedder::ScopedPlatformHandleVectorPtr /*platform_handles*/) override { | 108 ScopedPlatformHandleVectorPtr /*platform_handles*/) override { |
| 116 CHECK(false); // Should not get called. | 109 CHECK(false); // Should not get called. |
| 117 } | 110 } |
| 118 void OnError(Error error) override { | 111 void OnError(Error error) override { |
| 119 // We'll get a read (shutdown) error when the connection is closed. | 112 // We'll get a read (shutdown) error when the connection is closed. |
| 120 CHECK_EQ(error, ERROR_READ_SHUTDOWN); | 113 CHECK_EQ(error, ERROR_READ_SHUTDOWN); |
| 121 } | 114 } |
| 122 | 115 |
| 123 private: | 116 private: |
| 124 MOJO_DISALLOW_COPY_AND_ASSIGN(WriteOnlyRawChannelDelegate); | 117 MOJO_DISALLOW_COPY_AND_ASSIGN(WriteOnlyRawChannelDelegate); |
| 125 }; | 118 }; |
| 126 | 119 |
| 127 static const unsigned kMessageReaderSleepMs = 1; | 120 static const unsigned kMessageReaderSleepMs = 1; |
| 128 static const size_t kMessageReaderMaxPollIterations = 3000; | 121 static const size_t kMessageReaderMaxPollIterations = 3000; |
| 129 | 122 |
| 130 class TestMessageReaderAndChecker { | 123 class TestMessageReaderAndChecker { |
| 131 public: | 124 public: |
| 132 explicit TestMessageReaderAndChecker(embedder::PlatformHandle handle) | 125 explicit TestMessageReaderAndChecker(PlatformHandle handle) |
| 133 : handle_(handle) {} | 126 : handle_(handle) {} |
| 134 ~TestMessageReaderAndChecker() { CHECK(bytes_.empty()); } | 127 ~TestMessageReaderAndChecker() { CHECK(bytes_.empty()); } |
| 135 | 128 |
| 136 bool ReadAndCheckNextMessage(uint32_t expected_size) { | 129 bool ReadAndCheckNextMessage(uint32_t expected_size) { |
| 137 unsigned char buffer[4096]; | 130 unsigned char buffer[4096]; |
| 138 | 131 |
| 139 for (size_t i = 0; i < kMessageReaderMaxPollIterations;) { | 132 for (size_t i = 0; i < kMessageReaderMaxPollIterations;) { |
| 140 size_t read_size = 0; | 133 size_t read_size = 0; |
| 141 CHECK(mojo::test::NonBlockingRead(handle_, buffer, sizeof(buffer), | 134 CHECK(test::NonBlockingRead(handle_, buffer, sizeof(buffer), &read_size)); |
| 142 &read_size)); | |
| 143 | 135 |
| 144 // Append newly-read data to |bytes_|. | 136 // Append newly-read data to |bytes_|. |
| 145 bytes_.insert(bytes_.end(), buffer, buffer + read_size); | 137 bytes_.insert(bytes_.end(), buffer, buffer + read_size); |
| 146 | 138 |
| 147 // If we have the header.... | 139 // If we have the header.... |
| 148 size_t message_size; | 140 size_t message_size; |
| 149 if (MessageInTransit::GetNextMessageSize( | 141 if (MessageInTransit::GetNextMessageSize( |
| 150 bytes_.empty() ? nullptr : &bytes_[0], bytes_.size(), | 142 bytes_.empty() ? nullptr : &bytes_[0], bytes_.size(), |
| 151 &message_size)) { | 143 &message_size)) { |
| 152 // If we've read the whole message.... | 144 // If we've read the whole message.... |
| (...skipping 23 matching lines...) Expand all Loading... |
| 176 i++; | 168 i++; |
| 177 test::Sleep(test::DeadlineFromMilliseconds(kMessageReaderSleepMs)); | 169 test::Sleep(test::DeadlineFromMilliseconds(kMessageReaderSleepMs)); |
| 178 } | 170 } |
| 179 } | 171 } |
| 180 | 172 |
| 181 LOG(ERROR) << "Too many iterations."; | 173 LOG(ERROR) << "Too many iterations."; |
| 182 return false; | 174 return false; |
| 183 } | 175 } |
| 184 | 176 |
| 185 private: | 177 private: |
| 186 const embedder::PlatformHandle handle_; | 178 const PlatformHandle handle_; |
| 187 | 179 |
| 188 // The start of the received data should always be on a message boundary. | 180 // The start of the received data should always be on a message boundary. |
| 189 std::vector<unsigned char> bytes_; | 181 std::vector<unsigned char> bytes_; |
| 190 | 182 |
| 191 MOJO_DISALLOW_COPY_AND_ASSIGN(TestMessageReaderAndChecker); | 183 MOJO_DISALLOW_COPY_AND_ASSIGN(TestMessageReaderAndChecker); |
| 192 }; | 184 }; |
| 193 | 185 |
| 194 // Tests writing (and verifies reading using our own custom reader). | 186 // Tests writing (and verifies reading using our own custom reader). |
| 195 TEST_F(RawChannelTest, WriteMessage) { | 187 TEST_F(RawChannelTest, WriteMessage) { |
| 196 WriteOnlyRawChannelDelegate delegate; | 188 WriteOnlyRawChannelDelegate delegate; |
| 197 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); | 189 RawChannel* rc = RawChannel::Create(handles[0].Pass()); |
| 198 TestMessageReaderAndChecker checker(handles[1].get()); | 190 TestMessageReaderAndChecker checker(handles[1].get()); |
| 199 io_thread()->PostTaskAndWait( | 191 test_io_thread()->PostTaskAndWait( |
| 200 FROM_HERE, | 192 FROM_HERE, |
| 201 base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate))); | 193 base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate))); |
| 202 | 194 |
| 203 // Write and read, for a variety of sizes. | 195 // Write and read, for a variety of sizes. |
| 204 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { | 196 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { |
| 205 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); | 197 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); |
| 206 EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size; | 198 EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size; |
| 207 } | 199 } |
| 208 | 200 |
| 209 // Write/queue and read afterwards, for a variety of sizes. | 201 // Write/queue and read afterwards, for a variety of sizes. |
| 210 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) | 202 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) |
| 211 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); | 203 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); |
| 212 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) | 204 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) |
| 213 EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size; | 205 EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size; |
| 214 | 206 |
| 215 io_thread()->PostTaskAndWait( | 207 test_io_thread()->PostTaskAndWait( |
| 216 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get()))); | 208 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc))); |
| 217 } | 209 } |
| 218 | 210 |
| 219 // RawChannelTest.OnReadMessage ------------------------------------------------ | 211 // RawChannelTest.OnReadMessage ------------------------------------------------ |
| 220 | 212 |
| 221 class ReadCheckerRawChannelDelegate : public RawChannel::Delegate { | 213 class ReadCheckerRawChannelDelegate : public RawChannel::Delegate { |
| 222 public: | 214 public: |
| 223 ReadCheckerRawChannelDelegate() : done_event_(false, false), position_(0) {} | 215 ReadCheckerRawChannelDelegate() : done_event_(false, false), position_(0) {} |
| 224 ~ReadCheckerRawChannelDelegate() override {} | 216 ~ReadCheckerRawChannelDelegate() override {} |
| 225 | 217 |
| 226 // |RawChannel::Delegate| implementation (called on the I/O thread): | 218 // |RawChannel::Delegate| implementation (called on the I/O thread): |
| 227 void OnReadMessage( | 219 void OnReadMessage( |
| 228 const MessageInTransit::View& message_view, | 220 const MessageInTransit::View& message_view, |
| 229 embedder::ScopedPlatformHandleVectorPtr platform_handles) override { | 221 ScopedPlatformHandleVectorPtr platform_handles) override { |
| 230 EXPECT_FALSE(platform_handles); | 222 EXPECT_FALSE(platform_handles); |
| 231 | 223 |
| 232 size_t position; | 224 size_t position; |
| 233 size_t expected_size; | 225 size_t expected_size; |
| 234 bool should_signal = false; | 226 bool should_signal = false; |
| 235 { | 227 { |
| 236 MutexLocker locker(&mutex_); | 228 base::AutoLock locker(lock_); |
| 237 CHECK_LT(position_, expected_sizes_.size()); | 229 CHECK_LT(position_, expected_sizes_.size()); |
| 238 position = position_; | 230 position = position_; |
| 239 expected_size = expected_sizes_[position]; | 231 expected_size = expected_sizes_[position]; |
| 240 position_++; | 232 position_++; |
| 241 if (position_ >= expected_sizes_.size()) | 233 if (position_ >= expected_sizes_.size()) |
| 242 should_signal = true; | 234 should_signal = true; |
| 243 } | 235 } |
| 244 | 236 |
| 245 EXPECT_EQ(expected_size, message_view.num_bytes()) << position; | 237 EXPECT_EQ(expected_size, message_view.num_bytes()) << position; |
| 246 if (message_view.num_bytes() == expected_size) { | 238 if (message_view.num_bytes() == expected_size) { |
| 247 EXPECT_TRUE( | 239 EXPECT_TRUE( |
| 248 CheckMessageData(message_view.bytes(), message_view.num_bytes())) | 240 CheckMessageData(message_view.bytes(), message_view.num_bytes())) |
| 249 << position; | 241 << position; |
| 250 } | 242 } |
| 251 | 243 |
| 252 if (should_signal) | 244 if (should_signal) |
| 253 done_event_.Signal(); | 245 done_event_.Signal(); |
| 254 } | 246 } |
| 255 void OnError(Error error) override { | 247 void OnError(Error error) override { |
| 256 // We'll get a read (shutdown) error when the connection is closed. | 248 // We'll get a read (shutdown) error when the connection is closed. |
| 257 CHECK_EQ(error, ERROR_READ_SHUTDOWN); | 249 CHECK_EQ(error, ERROR_READ_SHUTDOWN); |
| 258 } | 250 } |
| 259 | 251 |
| 260 // Waits for all the messages (of sizes |expected_sizes_|) to be seen. | 252 // Waits for all the messages (of sizes |expected_sizes_|) to be seen. |
| 261 void Wait() { done_event_.Wait(); } | 253 void Wait() { done_event_.Wait(); } |
| 262 | 254 |
| 263 void SetExpectedSizes(const std::vector<uint32_t>& expected_sizes) { | 255 void SetExpectedSizes(const std::vector<uint32_t>& expected_sizes) { |
| 264 MutexLocker locker(&mutex_); | 256 base::AutoLock locker(lock_); |
| 265 CHECK_EQ(position_, expected_sizes_.size()); | 257 CHECK_EQ(position_, expected_sizes_.size()); |
| 266 expected_sizes_ = expected_sizes; | 258 expected_sizes_ = expected_sizes; |
| 267 position_ = 0; | 259 position_ = 0; |
| 268 } | 260 } |
| 269 | 261 |
| 270 private: | 262 private: |
| 271 base::WaitableEvent done_event_; | 263 base::WaitableEvent done_event_; |
| 272 | 264 |
| 273 Mutex mutex_; | 265 base::Lock lock_; // Protects the following members. |
| 274 std::vector<uint32_t> expected_sizes_ MOJO_GUARDED_BY(mutex_); | 266 std::vector<uint32_t> expected_sizes_; |
| 275 size_t position_ MOJO_GUARDED_BY(mutex_); | 267 size_t position_; |
| 276 | 268 |
| 277 MOJO_DISALLOW_COPY_AND_ASSIGN(ReadCheckerRawChannelDelegate); | 269 MOJO_DISALLOW_COPY_AND_ASSIGN(ReadCheckerRawChannelDelegate); |
| 278 }; | 270 }; |
| 279 | 271 |
| 280 // Tests reading (writing using our own custom writer). | 272 // Tests reading (writing using our own custom writer). |
| 281 TEST_F(RawChannelTest, OnReadMessage) { | 273 TEST_F(RawChannelTest, OnReadMessage) { |
| 282 ReadCheckerRawChannelDelegate delegate; | 274 ReadCheckerRawChannelDelegate delegate; |
| 283 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); | 275 RawChannel* rc = RawChannel::Create(handles[0].Pass()); |
| 284 io_thread()->PostTaskAndWait( | 276 test_io_thread()->PostTaskAndWait( |
| 285 FROM_HERE, | 277 FROM_HERE, |
| 286 base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate))); | 278 base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate))); |
| 287 | 279 |
| 288 // Write and read, for a variety of sizes. | 280 // Write and read, for a variety of sizes. |
| 289 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { | 281 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { |
| 290 delegate.SetExpectedSizes(std::vector<uint32_t>(1, size)); | 282 delegate.SetExpectedSizes(std::vector<uint32_t>(1, size)); |
| 291 | 283 |
| 292 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), size)); | 284 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), size)); |
| 293 | 285 |
| 294 delegate.Wait(); | 286 delegate.Wait(); |
| 295 } | 287 } |
| 296 | 288 |
| 297 // Set up reader and write as fast as we can. | 289 // Set up reader and write as fast as we can. |
| 298 // Write/queue and read afterwards, for a variety of sizes. | 290 // Write/queue and read afterwards, for a variety of sizes. |
| 299 std::vector<uint32_t> expected_sizes; | 291 std::vector<uint32_t> expected_sizes; |
| 300 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) | 292 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) |
| 301 expected_sizes.push_back(size); | 293 expected_sizes.push_back(size); |
| 302 delegate.SetExpectedSizes(expected_sizes); | 294 delegate.SetExpectedSizes(expected_sizes); |
| 303 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) | 295 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) |
| 304 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), size)); | 296 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), size)); |
| 305 delegate.Wait(); | 297 delegate.Wait(); |
| 306 | 298 |
| 307 io_thread()->PostTaskAndWait( | 299 test_io_thread()->PostTaskAndWait( |
| 308 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get()))); | 300 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc))); |
| 309 } | 301 } |
| 310 | 302 |
| 311 // RawChannelTest.WriteMessageAndOnReadMessage --------------------------------- | 303 // RawChannelTest.WriteMessageAndOnReadMessage --------------------------------- |
| 312 | 304 |
| 313 class RawChannelWriterThread : public base::SimpleThread { | 305 class RawChannelWriterThread : public base::SimpleThread { |
| 314 public: | 306 public: |
| 315 RawChannelWriterThread(RawChannel* raw_channel, size_t write_count) | 307 RawChannelWriterThread(RawChannel* raw_channel, size_t write_count) |
| 316 : base::SimpleThread("raw_channel_writer_thread"), | 308 : base::SimpleThread("raw_channel_writer_thread"), |
| 317 raw_channel_(raw_channel), | 309 raw_channel_(raw_channel), |
| 318 left_to_write_(write_count) {} | 310 left_to_write_(write_count) {} |
| (...skipping 18 matching lines...) Expand all Loading... |
| 337 | 329 |
| 338 class ReadCountdownRawChannelDelegate : public RawChannel::Delegate { | 330 class ReadCountdownRawChannelDelegate : public RawChannel::Delegate { |
| 339 public: | 331 public: |
| 340 explicit ReadCountdownRawChannelDelegate(size_t expected_count) | 332 explicit ReadCountdownRawChannelDelegate(size_t expected_count) |
| 341 : done_event_(false, false), expected_count_(expected_count), count_(0) {} | 333 : done_event_(false, false), expected_count_(expected_count), count_(0) {} |
| 342 ~ReadCountdownRawChannelDelegate() override {} | 334 ~ReadCountdownRawChannelDelegate() override {} |
| 343 | 335 |
| 344 // |RawChannel::Delegate| implementation (called on the I/O thread): | 336 // |RawChannel::Delegate| implementation (called on the I/O thread): |
| 345 void OnReadMessage( | 337 void OnReadMessage( |
| 346 const MessageInTransit::View& message_view, | 338 const MessageInTransit::View& message_view, |
| 347 embedder::ScopedPlatformHandleVectorPtr platform_handles) override { | 339 ScopedPlatformHandleVectorPtr platform_handles) override { |
| 348 EXPECT_FALSE(platform_handles); | 340 EXPECT_FALSE(platform_handles); |
| 349 | 341 |
| 350 EXPECT_LT(count_, expected_count_); | 342 EXPECT_LT(count_, expected_count_); |
| 351 count_++; | 343 count_++; |
| 352 | 344 |
| 353 EXPECT_TRUE( | 345 EXPECT_TRUE( |
| 354 CheckMessageData(message_view.bytes(), message_view.num_bytes())); | 346 CheckMessageData(message_view.bytes(), message_view.num_bytes())); |
| 355 | 347 |
| 356 if (count_ >= expected_count_) | 348 if (count_ >= expected_count_) |
| 357 done_event_.Signal(); | 349 done_event_.Signal(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 370 size_t count_; | 362 size_t count_; |
| 371 | 363 |
| 372 MOJO_DISALLOW_COPY_AND_ASSIGN(ReadCountdownRawChannelDelegate); | 364 MOJO_DISALLOW_COPY_AND_ASSIGN(ReadCountdownRawChannelDelegate); |
| 373 }; | 365 }; |
| 374 | 366 |
| 375 TEST_F(RawChannelTest, WriteMessageAndOnReadMessage) { | 367 TEST_F(RawChannelTest, WriteMessageAndOnReadMessage) { |
| 376 static const size_t kNumWriterThreads = 10; | 368 static const size_t kNumWriterThreads = 10; |
| 377 static const size_t kNumWriteMessagesPerThread = 4000; | 369 static const size_t kNumWriteMessagesPerThread = 4000; |
| 378 | 370 |
| 379 WriteOnlyRawChannelDelegate writer_delegate; | 371 WriteOnlyRawChannelDelegate writer_delegate; |
| 380 scoped_ptr<RawChannel> writer_rc(RawChannel::Create(handles[0].Pass())); | 372 RawChannel* writer_rc = RawChannel::Create(handles[0].Pass()); |
| 381 io_thread()->PostTaskAndWait(FROM_HERE, | 373 test_io_thread()->PostTaskAndWait( |
| 382 base::Bind(&InitOnIOThread, writer_rc.get(), | 374 FROM_HERE, |
| 383 base::Unretained(&writer_delegate))); | 375 base::Bind(&InitOnIOThread, writer_rc, |
| 376 base::Unretained(&writer_delegate))); |
| 384 | 377 |
| 385 ReadCountdownRawChannelDelegate reader_delegate(kNumWriterThreads * | 378 ReadCountdownRawChannelDelegate reader_delegate(kNumWriterThreads * |
| 386 kNumWriteMessagesPerThread); | 379 kNumWriteMessagesPerThread); |
| 387 scoped_ptr<RawChannel> reader_rc(RawChannel::Create(handles[1].Pass())); | 380 RawChannel* reader_rc = RawChannel::Create(handles[1].Pass()); |
| 388 io_thread()->PostTaskAndWait(FROM_HERE, | 381 test_io_thread()->PostTaskAndWait( |
| 389 base::Bind(&InitOnIOThread, reader_rc.get(), | 382 FROM_HERE, |
| 390 base::Unretained(&reader_delegate))); | 383 base::Bind(&InitOnIOThread, reader_rc, |
| 384 base::Unretained(&reader_delegate))); |
| 391 | 385 |
| 392 { | 386 { |
| 393 ScopedVector<RawChannelWriterThread> writer_threads; | 387 ScopedVector<RawChannelWriterThread> writer_threads; |
| 394 for (size_t i = 0; i < kNumWriterThreads; i++) { | 388 for (size_t i = 0; i < kNumWriterThreads; i++) { |
| 395 writer_threads.push_back(new RawChannelWriterThread( | 389 writer_threads.push_back(new RawChannelWriterThread( |
| 396 writer_rc.get(), kNumWriteMessagesPerThread)); | 390 writer_rc, kNumWriteMessagesPerThread)); |
| 397 } | 391 } |
| 398 for (size_t i = 0; i < writer_threads.size(); i++) | 392 for (size_t i = 0; i < writer_threads.size(); i++) |
| 399 writer_threads[i]->Start(); | 393 writer_threads[i]->Start(); |
| 400 } // Joins all the writer threads. | 394 } // Joins all the writer threads. |
| 401 | 395 |
| 402 // Sleep a bit, to let any extraneous reads be processed. (There shouldn't be | 396 // Sleep a bit, to let any extraneous reads be processed. (There shouldn't be |
| 403 // any, but we want to know about them.) | 397 // any, but we want to know about them.) |
| 404 test::Sleep(test::DeadlineFromMilliseconds(100)); | 398 test::Sleep(test::DeadlineFromMilliseconds(100)); |
| 405 | 399 |
| 406 // Wait for reading to finish. | 400 // Wait for reading to finish. |
| 407 reader_delegate.Wait(); | 401 reader_delegate.Wait(); |
| 408 | 402 |
| 409 io_thread()->PostTaskAndWait( | 403 test_io_thread()->PostTaskAndWait( |
| 410 FROM_HERE, | 404 FROM_HERE, |
| 411 base::Bind(&RawChannel::Shutdown, base::Unretained(reader_rc.get()))); | 405 base::Bind(&RawChannel::Shutdown, base::Unretained(reader_rc))); |
| 412 | 406 |
| 413 io_thread()->PostTaskAndWait( | 407 test_io_thread()->PostTaskAndWait( |
| 414 FROM_HERE, | 408 FROM_HERE, |
| 415 base::Bind(&RawChannel::Shutdown, base::Unretained(writer_rc.get()))); | 409 base::Bind(&RawChannel::Shutdown, base::Unretained(writer_rc))); |
| 416 } | 410 } |
| 417 | 411 |
| 418 // RawChannelTest.OnError ------------------------------------------------------ | 412 // RawChannelTest.OnError ------------------------------------------------------ |
| 419 | 413 |
| 420 class ErrorRecordingRawChannelDelegate | 414 class ErrorRecordingRawChannelDelegate |
| 421 : public ReadCountdownRawChannelDelegate { | 415 : public ReadCountdownRawChannelDelegate { |
| 422 public: | 416 public: |
| 423 ErrorRecordingRawChannelDelegate(size_t expected_read_count, | 417 ErrorRecordingRawChannelDelegate(size_t expected_read_count, |
| 424 bool expect_read_error, | 418 bool expect_read_error, |
| 425 bool expect_write_error) | 419 bool expect_write_error) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 | 461 |
| 468 bool expecting_read_error_; | 462 bool expecting_read_error_; |
| 469 bool expecting_write_error_; | 463 bool expecting_write_error_; |
| 470 | 464 |
| 471 MOJO_DISALLOW_COPY_AND_ASSIGN(ErrorRecordingRawChannelDelegate); | 465 MOJO_DISALLOW_COPY_AND_ASSIGN(ErrorRecordingRawChannelDelegate); |
| 472 }; | 466 }; |
| 473 | 467 |
| 474 // Tests (fatal) errors. | 468 // Tests (fatal) errors. |
| 475 TEST_F(RawChannelTest, OnError) { | 469 TEST_F(RawChannelTest, OnError) { |
| 476 ErrorRecordingRawChannelDelegate delegate(0, true, true); | 470 ErrorRecordingRawChannelDelegate delegate(0, true, true); |
| 477 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); | 471 RawChannel* rc = RawChannel::Create(handles[0].Pass()); |
| 478 io_thread()->PostTaskAndWait( | 472 test_io_thread()->PostTaskAndWait( |
| 479 FROM_HERE, | 473 FROM_HERE, |
| 480 base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate))); | 474 base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate))); |
| 481 | 475 |
| 482 // Close the handle of the other end, which should make writing fail. | 476 // Close the handle of the other end, which should make writing fail. |
| 483 handles[1].reset(); | 477 handles[1].reset(); |
| 484 | 478 |
| 485 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | 479 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); |
| 486 | 480 |
| 487 // We should get a write error. | 481 // We should get a write error. |
| 488 delegate.WaitForWriteError(); | 482 delegate.WaitForWriteError(); |
| 489 | 483 |
| 490 // We should also get a read error. | 484 // We should also get a read error. |
| 491 delegate.WaitForReadError(); | 485 delegate.WaitForReadError(); |
| 492 | 486 |
| 493 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(2))); | 487 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(2))); |
| 494 | 488 |
| 495 // Sleep a bit, to make sure we don't get another |OnError()| | 489 // Sleep a bit, to make sure we don't get another |OnError()| |
| 496 // notification. (If we actually get another one, |OnError()| crashes.) | 490 // notification. (If we actually get another one, |OnError()| crashes.) |
| 497 test::Sleep(test::DeadlineFromMilliseconds(20)); | 491 test::Sleep(test::DeadlineFromMilliseconds(20)); |
| 498 | 492 |
| 499 io_thread()->PostTaskAndWait( | 493 test_io_thread()->PostTaskAndWait( |
| 500 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get()))); | 494 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc))); |
| 501 } | 495 } |
| 502 | 496 |
| 503 // RawChannelTest.ReadUnaffectedByWriteError ----------------------------------- | 497 // RawChannelTest.ReadUnaffectedByWriteError ----------------------------------- |
| 504 | 498 |
| 505 TEST_F(RawChannelTest, ReadUnaffectedByWriteError) { | 499 TEST_F(RawChannelTest, ReadUnaffectedByWriteError) { |
| 506 const size_t kMessageCount = 5; | 500 const size_t kMessageCount = 5; |
| 507 | 501 |
| 508 // Write a few messages into the other end. | 502 // Write a few messages into the other end. |
| 509 uint32_t message_size = 1; | 503 uint32_t message_size = 1; |
| 510 for (size_t i = 0; i < kMessageCount; | 504 for (size_t i = 0; i < kMessageCount; |
| 511 i++, message_size += message_size / 2 + 1) | 505 i++, message_size += message_size / 2 + 1) |
| 512 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), message_size)); | 506 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), message_size)); |
| 513 | 507 |
| 514 // Close the other end, which should make writing fail. | 508 // Close the other end, which should make writing fail. |
| 515 handles[1].reset(); | 509 handles[1].reset(); |
| 516 | 510 |
| 517 // Only start up reading here. The system buffer should still contain the | 511 // Only start up reading here. The system buffer should still contain the |
| 518 // messages that were written. | 512 // messages that were written. |
| 519 ErrorRecordingRawChannelDelegate delegate(kMessageCount, true, true); | 513 ErrorRecordingRawChannelDelegate delegate(kMessageCount, true, true); |
| 520 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); | 514 RawChannel* rc = RawChannel::Create(handles[0].Pass()); |
| 521 io_thread()->PostTaskAndWait( | 515 test_io_thread()->PostTaskAndWait( |
| 522 FROM_HERE, | 516 FROM_HERE, |
| 523 base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate))); | 517 base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate))); |
| 524 | 518 |
| 525 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | 519 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); |
| 526 | 520 |
| 527 // We should definitely get a write error. | 521 // We should definitely get a write error. |
| 528 delegate.WaitForWriteError(); | 522 delegate.WaitForWriteError(); |
| 529 | 523 |
| 530 // Wait for reading to finish. A writing failure shouldn't affect reading. | 524 // Wait for reading to finish. A writing failure shouldn't affect reading. |
| 531 delegate.Wait(); | 525 delegate.Wait(); |
| 532 | 526 |
| 533 // And then we should get a read error. | 527 // And then we should get a read error. |
| 534 delegate.WaitForReadError(); | 528 delegate.WaitForReadError(); |
| 535 | 529 |
| 536 io_thread()->PostTaskAndWait( | 530 test_io_thread()->PostTaskAndWait( |
| 537 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get()))); | 531 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc))); |
| 538 } | 532 } |
| 539 | 533 |
| 540 // RawChannelTest.WriteMessageAfterShutdown ------------------------------------ | 534 // RawChannelTest.WriteMessageAfterShutdown ------------------------------------ |
| 541 | 535 |
| 542 // Makes sure that calling |WriteMessage()| after |Shutdown()| behaves | 536 // Makes sure that calling |WriteMessage()| after |Shutdown()| behaves |
| 543 // correctly. | 537 // correctly. |
| 544 TEST_F(RawChannelTest, WriteMessageAfterShutdown) { | 538 TEST_F(RawChannelTest, WriteMessageAfterShutdown) { |
| 545 WriteOnlyRawChannelDelegate delegate; | 539 WriteOnlyRawChannelDelegate delegate; |
| 546 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); | 540 RawChannel* rc = RawChannel::Create(handles[0].Pass()); |
| 547 io_thread()->PostTaskAndWait( | 541 test_io_thread()->PostTaskAndWait( |
| 548 FROM_HERE, | 542 FROM_HERE, |
| 549 base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate))); | 543 base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate))); |
| 550 io_thread()->PostTaskAndWait( | 544 test_io_thread()->PostTaskAndWait( |
| 551 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc.get()))); | 545 FROM_HERE, base::Bind(&RawChannel::Shutdown, base::Unretained(rc))); |
| 552 | 546 |
| 553 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | 547 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); |
| 554 } | 548 } |
| 555 | 549 |
| 556 // RawChannelTest.{Shutdown, ShutdownAndDestroy}OnReadMessage ------------------ | |
| 557 | |
| 558 class ShutdownOnReadMessageRawChannelDelegate : public RawChannel::Delegate { | |
| 559 public: | |
| 560 explicit ShutdownOnReadMessageRawChannelDelegate(RawChannel* raw_channel, | |
| 561 bool should_destroy) | |
| 562 : raw_channel_(raw_channel), | |
| 563 should_destroy_(should_destroy), | |
| 564 done_event_(false, false), | |
| 565 did_shutdown_(false) {} | |
| 566 ~ShutdownOnReadMessageRawChannelDelegate() override {} | |
| 567 | |
| 568 // |RawChannel::Delegate| implementation (called on the I/O thread): | |
| 569 void OnReadMessage( | |
| 570 const MessageInTransit::View& message_view, | |
| 571 embedder::ScopedPlatformHandleVectorPtr platform_handles) override { | |
| 572 EXPECT_FALSE(platform_handles); | |
| 573 EXPECT_FALSE(did_shutdown_); | |
| 574 EXPECT_TRUE( | |
| 575 CheckMessageData(message_view.bytes(), message_view.num_bytes())); | |
| 576 raw_channel_->Shutdown(); | |
| 577 if (should_destroy_) | |
| 578 delete raw_channel_; | |
| 579 did_shutdown_ = true; | |
| 580 done_event_.Signal(); | |
| 581 } | |
| 582 void OnError(Error /*error*/) override { | |
| 583 CHECK(false); // Should not get called. | |
| 584 } | |
| 585 | |
| 586 // Waits for shutdown. | |
| 587 void Wait() { | |
| 588 done_event_.Wait(); | |
| 589 EXPECT_TRUE(did_shutdown_); | |
| 590 } | |
| 591 | |
| 592 private: | |
| 593 RawChannel* const raw_channel_; | |
| 594 const bool should_destroy_; | |
| 595 base::WaitableEvent done_event_; | |
| 596 bool did_shutdown_; | |
| 597 | |
| 598 MOJO_DISALLOW_COPY_AND_ASSIGN(ShutdownOnReadMessageRawChannelDelegate); | |
| 599 }; | |
| 600 | |
| 601 TEST_F(RawChannelTest, ShutdownOnReadMessage) { | |
| 602 // Write a few messages into the other end. | |
| 603 for (size_t count = 0; count < 5; count++) | |
| 604 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), 10)); | |
| 605 | |
| 606 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); | |
| 607 ShutdownOnReadMessageRawChannelDelegate delegate(rc.get(), false); | |
| 608 io_thread()->PostTaskAndWait( | |
| 609 FROM_HERE, | |
| 610 base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate))); | |
| 611 | |
| 612 // Wait for the delegate, which will shut the |RawChannel| down. | |
| 613 delegate.Wait(); | |
| 614 } | |
| 615 | |
| 616 TEST_F(RawChannelTest, ShutdownAndDestroyOnReadMessage) { | |
| 617 // Write a message into the other end. | |
| 618 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), 10)); | |
| 619 | |
| 620 // The delegate will destroy |rc|. | |
| 621 RawChannel* rc = RawChannel::Create(handles[0].Pass()).release(); | |
| 622 ShutdownOnReadMessageRawChannelDelegate delegate(rc, true); | |
| 623 io_thread()->PostTaskAndWait( | |
| 624 FROM_HERE, base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate))); | |
| 625 | |
| 626 // Wait for the delegate, which will shut the |RawChannel| down. | |
| 627 delegate.Wait(); | |
| 628 } | |
| 629 | |
| 630 // RawChannelTest.{Shutdown, ShutdownAndDestroy}OnError{Read, Write} ----------- | |
| 631 | |
| 632 class ShutdownOnErrorRawChannelDelegate : public RawChannel::Delegate { | |
| 633 public: | |
| 634 ShutdownOnErrorRawChannelDelegate(RawChannel* raw_channel, | |
| 635 bool should_destroy, | |
| 636 Error shutdown_on_error_type) | |
| 637 : raw_channel_(raw_channel), | |
| 638 should_destroy_(should_destroy), | |
| 639 shutdown_on_error_type_(shutdown_on_error_type), | |
| 640 done_event_(false, false), | |
| 641 did_shutdown_(false) {} | |
| 642 ~ShutdownOnErrorRawChannelDelegate() override {} | |
| 643 | |
| 644 // |RawChannel::Delegate| implementation (called on the I/O thread): | |
| 645 void OnReadMessage( | |
| 646 const MessageInTransit::View& /*message_view*/, | |
| 647 embedder::ScopedPlatformHandleVectorPtr /*platform_handles*/) override { | |
| 648 CHECK(false); // Should not get called. | |
| 649 } | |
| 650 void OnError(Error error) override { | |
| 651 EXPECT_FALSE(did_shutdown_); | |
| 652 if (error != shutdown_on_error_type_) | |
| 653 return; | |
| 654 raw_channel_->Shutdown(); | |
| 655 if (should_destroy_) | |
| 656 delete raw_channel_; | |
| 657 did_shutdown_ = true; | |
| 658 done_event_.Signal(); | |
| 659 } | |
| 660 | |
| 661 // Waits for shutdown. | |
| 662 void Wait() { | |
| 663 done_event_.Wait(); | |
| 664 EXPECT_TRUE(did_shutdown_); | |
| 665 } | |
| 666 | |
| 667 private: | |
| 668 RawChannel* const raw_channel_; | |
| 669 const bool should_destroy_; | |
| 670 const Error shutdown_on_error_type_; | |
| 671 base::WaitableEvent done_event_; | |
| 672 bool did_shutdown_; | |
| 673 | |
| 674 MOJO_DISALLOW_COPY_AND_ASSIGN(ShutdownOnErrorRawChannelDelegate); | |
| 675 }; | |
| 676 | |
| 677 TEST_F(RawChannelTest, ShutdownOnErrorRead) { | |
| 678 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); | |
| 679 ShutdownOnErrorRawChannelDelegate delegate( | |
| 680 rc.get(), false, RawChannel::Delegate::ERROR_READ_SHUTDOWN); | |
| 681 io_thread()->PostTaskAndWait( | |
| 682 FROM_HERE, | |
| 683 base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate))); | |
| 684 | |
| 685 // Close the handle of the other end, which should stuff fail. | |
| 686 handles[1].reset(); | |
| 687 | |
| 688 // Wait for the delegate, which will shut the |RawChannel| down. | |
| 689 delegate.Wait(); | |
| 690 } | |
| 691 | |
| 692 TEST_F(RawChannelTest, ShutdownAndDestroyOnErrorRead) { | |
| 693 RawChannel* rc = RawChannel::Create(handles[0].Pass()).release(); | |
| 694 ShutdownOnErrorRawChannelDelegate delegate( | |
| 695 rc, true, RawChannel::Delegate::ERROR_READ_SHUTDOWN); | |
| 696 io_thread()->PostTaskAndWait( | |
| 697 FROM_HERE, base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate))); | |
| 698 | |
| 699 // Close the handle of the other end, which should stuff fail. | |
| 700 handles[1].reset(); | |
| 701 | |
| 702 // Wait for the delegate, which will shut the |RawChannel| down. | |
| 703 delegate.Wait(); | |
| 704 } | |
| 705 | |
| 706 TEST_F(RawChannelTest, ShutdownOnErrorWrite) { | |
| 707 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); | |
| 708 ShutdownOnErrorRawChannelDelegate delegate(rc.get(), false, | |
| 709 RawChannel::Delegate::ERROR_WRITE); | |
| 710 io_thread()->PostTaskAndWait( | |
| 711 FROM_HERE, | |
| 712 base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate))); | |
| 713 | |
| 714 // Close the handle of the other end, which should stuff fail. | |
| 715 handles[1].reset(); | |
| 716 | |
| 717 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | |
| 718 | |
| 719 // Wait for the delegate, which will shut the |RawChannel| down. | |
| 720 delegate.Wait(); | |
| 721 } | |
| 722 | |
| 723 TEST_F(RawChannelTest, ShutdownAndDestroyOnErrorWrite) { | |
| 724 RawChannel* rc = RawChannel::Create(handles[0].Pass()).release(); | |
| 725 ShutdownOnErrorRawChannelDelegate delegate(rc, true, | |
| 726 RawChannel::Delegate::ERROR_WRITE); | |
| 727 io_thread()->PostTaskAndWait( | |
| 728 FROM_HERE, base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate))); | |
| 729 | |
| 730 // Close the handle of the other end, which should stuff fail. | |
| 731 handles[1].reset(); | |
| 732 | |
| 733 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | |
| 734 | |
| 735 // Wait for the delegate, which will shut the |RawChannel| down. | |
| 736 delegate.Wait(); | |
| 737 } | |
| 738 | |
| 739 // RawChannelTest.ReadWritePlatformHandles ------------------------------------- | 550 // RawChannelTest.ReadWritePlatformHandles ------------------------------------- |
| 740 | 551 |
| 741 class ReadPlatformHandlesCheckerRawChannelDelegate | 552 class ReadPlatformHandlesCheckerRawChannelDelegate |
| 742 : public RawChannel::Delegate { | 553 : public RawChannel::Delegate { |
| 743 public: | 554 public: |
| 744 ReadPlatformHandlesCheckerRawChannelDelegate() : done_event_(false, false) {} | 555 ReadPlatformHandlesCheckerRawChannelDelegate() : done_event_(false, false) {} |
| 745 ~ReadPlatformHandlesCheckerRawChannelDelegate() override {} | 556 ~ReadPlatformHandlesCheckerRawChannelDelegate() override {} |
| 746 | 557 |
| 747 // |RawChannel::Delegate| implementation (called on the I/O thread): | 558 // |RawChannel::Delegate| implementation (called on the I/O thread): |
| 748 void OnReadMessage( | 559 void OnReadMessage( |
| 749 const MessageInTransit::View& message_view, | 560 const MessageInTransit::View& message_view, |
| 750 embedder::ScopedPlatformHandleVectorPtr platform_handles) override { | 561 ScopedPlatformHandleVectorPtr platform_handles) override { |
| 751 const char kHello[] = "hello"; | 562 const char kHello[] = "hello"; |
| 752 | 563 |
| 753 EXPECT_EQ(sizeof(kHello), message_view.num_bytes()); | 564 EXPECT_EQ(sizeof(kHello), message_view.num_bytes()); |
| 754 EXPECT_STREQ(kHello, static_cast<const char*>(message_view.bytes())); | 565 EXPECT_STREQ(kHello, static_cast<const char*>(message_view.bytes())); |
| 755 | 566 |
| 756 ASSERT_TRUE(platform_handles); | 567 ASSERT_TRUE(platform_handles); |
| 757 ASSERT_EQ(2u, platform_handles->size()); | 568 ASSERT_EQ(2u, platform_handles->size()); |
| 758 embedder::ScopedPlatformHandle h1(platform_handles->at(0)); | 569 ScopedPlatformHandle h1(platform_handles->at(0)); |
| 759 EXPECT_TRUE(h1.is_valid()); | 570 EXPECT_TRUE(h1.is_valid()); |
| 760 embedder::ScopedPlatformHandle h2(platform_handles->at(1)); | 571 ScopedPlatformHandle h2(platform_handles->at(1)); |
| 761 EXPECT_TRUE(h2.is_valid()); | 572 EXPECT_TRUE(h2.is_valid()); |
| 762 platform_handles->clear(); | 573 platform_handles->clear(); |
| 763 | 574 |
| 764 { | 575 { |
| 765 char buffer[100] = {}; | 576 char buffer[100] = {}; |
| 766 | 577 |
| 767 base::ScopedFILE fp(mojo::test::FILEFromPlatformHandle(h1.Pass(), "rb")); | 578 base::ScopedFILE fp(test::FILEFromPlatformHandle(h1.Pass(), "rb")); |
| 768 EXPECT_TRUE(fp); | 579 EXPECT_TRUE(fp); |
| 769 rewind(fp.get()); | 580 rewind(fp.get()); |
| 770 EXPECT_EQ(1u, fread(buffer, 1, sizeof(buffer), fp.get())); | 581 EXPECT_EQ(1u, fread(buffer, 1, sizeof(buffer), fp.get())); |
| 771 EXPECT_EQ('1', buffer[0]); | 582 EXPECT_EQ('1', buffer[0]); |
| 772 } | 583 } |
| 773 | 584 |
| 774 { | 585 { |
| 775 char buffer[100] = {}; | 586 char buffer[100] = {}; |
| 776 base::ScopedFILE fp(mojo::test::FILEFromPlatformHandle(h2.Pass(), "rb")); | 587 base::ScopedFILE fp(test::FILEFromPlatformHandle(h2.Pass(), "rb")); |
| 777 EXPECT_TRUE(fp); | 588 EXPECT_TRUE(fp); |
| 778 rewind(fp.get()); | 589 rewind(fp.get()); |
| 779 EXPECT_EQ(1u, fread(buffer, 1, sizeof(buffer), fp.get())); | 590 EXPECT_EQ(1u, fread(buffer, 1, sizeof(buffer), fp.get())); |
| 780 EXPECT_EQ('2', buffer[0]); | 591 EXPECT_EQ('2', buffer[0]); |
| 781 } | 592 } |
| 782 | 593 |
| 783 done_event_.Signal(); | 594 done_event_.Signal(); |
| 784 } | 595 } |
| 785 void OnError(Error error) override { | 596 void OnError(Error error) override { |
| 786 // We'll get a read (shutdown) error when the connection is closed. | 597 // We'll get a read (shutdown) error when the connection is closed. |
| 787 CHECK_EQ(error, ERROR_READ_SHUTDOWN); | 598 CHECK_EQ(error, ERROR_READ_SHUTDOWN); |
| 788 } | 599 } |
| 789 | 600 |
| 790 void Wait() { done_event_.Wait(); } | 601 void Wait() { done_event_.Wait(); } |
| 791 | 602 |
| 792 private: | 603 private: |
| 793 base::WaitableEvent done_event_; | 604 base::WaitableEvent done_event_; |
| 794 | 605 |
| 795 MOJO_DISALLOW_COPY_AND_ASSIGN(ReadPlatformHandlesCheckerRawChannelDelegate); | 606 MOJO_DISALLOW_COPY_AND_ASSIGN(ReadPlatformHandlesCheckerRawChannelDelegate); |
| 796 }; | 607 }; |
| 797 | 608 |
| 798 #if defined(OS_POSIX) | 609 TEST_F(RawChannelTest, ReadWritePlatformHandles) { |
| 799 #define MAYBE_ReadWritePlatformHandles ReadWritePlatformHandles | |
| 800 #else | |
| 801 // Not yet implemented (on Windows). | |
| 802 #define MAYBE_ReadWritePlatformHandles DISABLED_ReadWritePlatformHandles | |
| 803 #endif | |
| 804 TEST_F(RawChannelTest, MAYBE_ReadWritePlatformHandles) { | |
| 805 base::ScopedTempDir temp_dir; | 610 base::ScopedTempDir temp_dir; |
| 806 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 611 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 807 | 612 |
| 808 WriteOnlyRawChannelDelegate write_delegate; | 613 WriteOnlyRawChannelDelegate write_delegate; |
| 809 scoped_ptr<RawChannel> rc_write(RawChannel::Create(handles[0].Pass())); | 614 RawChannel* rc_write = RawChannel::Create(handles[0].Pass()); |
| 810 io_thread()->PostTaskAndWait(FROM_HERE, | 615 test_io_thread()->PostTaskAndWait( |
| 811 base::Bind(&InitOnIOThread, rc_write.get(), | 616 FROM_HERE, |
| 812 base::Unretained(&write_delegate))); | 617 base::Bind(&InitOnIOThread, rc_write, base::Unretained(&write_delegate))); |
| 813 | 618 |
| 814 ReadPlatformHandlesCheckerRawChannelDelegate read_delegate; | 619 ReadPlatformHandlesCheckerRawChannelDelegate read_delegate; |
| 815 scoped_ptr<RawChannel> rc_read(RawChannel::Create(handles[1].Pass())); | 620 RawChannel* rc_read = RawChannel::Create(handles[1].Pass()); |
| 816 io_thread()->PostTaskAndWait(FROM_HERE, | 621 test_io_thread()->PostTaskAndWait( |
| 817 base::Bind(&InitOnIOThread, rc_read.get(), | 622 FROM_HERE, |
| 818 base::Unretained(&read_delegate))); | 623 base::Bind(&InitOnIOThread, rc_read, base::Unretained(&read_delegate))); |
| 819 | 624 |
| 820 base::FilePath unused; | 625 base::FilePath unused; |
| 821 base::ScopedFILE fp1( | 626 base::ScopedFILE fp1( |
| 822 base::CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused)); | 627 base::CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused)); |
| 823 EXPECT_EQ(1u, fwrite("1", 1, 1, fp1.get())); | 628 EXPECT_EQ(1u, fwrite("1", 1, 1, fp1.get())); |
| 824 base::ScopedFILE fp2( | 629 base::ScopedFILE fp2( |
| 825 base::CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused)); | 630 base::CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused)); |
| 826 EXPECT_EQ(1u, fwrite("2", 1, 1, fp2.get())); | 631 EXPECT_EQ(1u, fwrite("2", 1, 1, fp2.get())); |
| 827 | 632 |
| 828 { | 633 { |
| 829 const char kHello[] = "hello"; | 634 const char kHello[] = "hello"; |
| 830 embedder::ScopedPlatformHandleVectorPtr platform_handles( | 635 ScopedPlatformHandleVectorPtr platform_handles(new PlatformHandleVector()); |
| 831 new embedder::PlatformHandleVector()); | |
| 832 platform_handles->push_back( | 636 platform_handles->push_back( |
| 833 mojo::test::PlatformHandleFromFILE(fp1.Pass()).release()); | 637 test::PlatformHandleFromFILE(fp1.Pass()).release()); |
| 834 platform_handles->push_back( | 638 platform_handles->push_back( |
| 835 mojo::test::PlatformHandleFromFILE(fp2.Pass()).release()); | 639 test::PlatformHandleFromFILE(fp2.Pass()).release()); |
| 836 | 640 |
| 837 scoped_ptr<MessageInTransit> message( | 641 scoped_ptr<MessageInTransit> message( |
| 838 new MessageInTransit(MessageInTransit::Type::ENDPOINT_CLIENT, | 642 new MessageInTransit(MessageInTransit::Type::MESSAGE, |
| 839 MessageInTransit::Subtype::ENDPOINT_CLIENT_DATA, | |
| 840 sizeof(kHello), kHello)); | 643 sizeof(kHello), kHello)); |
| 841 message->SetTransportData(make_scoped_ptr(new TransportData( | 644 message->SetTransportData(make_scoped_ptr(new TransportData( |
| 842 platform_handles.Pass(), rc_write->GetSerializedPlatformHandleSize()))); | 645 platform_handles.Pass(), rc_write->GetSerializedPlatformHandleSize()))); |
| 843 EXPECT_TRUE(rc_write->WriteMessage(message.Pass())); | 646 EXPECT_TRUE(rc_write->WriteMessage(message.Pass())); |
| 844 } | 647 } |
| 845 | 648 |
| 846 read_delegate.Wait(); | 649 read_delegate.Wait(); |
| 847 | 650 |
| 848 io_thread()->PostTaskAndWait( | 651 test_io_thread()->PostTaskAndWait( |
| 849 FROM_HERE, | 652 FROM_HERE, |
| 850 base::Bind(&RawChannel::Shutdown, base::Unretained(rc_read.get()))); | 653 base::Bind(&RawChannel::Shutdown, base::Unretained(rc_read))); |
| 851 io_thread()->PostTaskAndWait( | 654 test_io_thread()->PostTaskAndWait( |
| 852 FROM_HERE, | 655 FROM_HERE, |
| 853 base::Bind(&RawChannel::Shutdown, base::Unretained(rc_write.get()))); | 656 base::Bind(&RawChannel::Shutdown, base::Unretained(rc_write))); |
| 854 } | 657 } |
| 855 | 658 |
| 856 } // namespace | 659 } // namespace |
| 857 } // namespace system | 660 } // namespace edk |
| 858 } // namespace mojo | 661 } // namespace mojo |
| OLD | NEW |