| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 // TODO(vtl): Factor out the remaining POSIX-specific bits of this test (once we | 5 // TODO(vtl): Factor out the remaining POSIX-specific bits of this test (once we |
| 6 // have a non-POSIX implementation). | 6 // have a non-POSIX implementation). |
| 7 | 7 |
| 8 #include "mojo/system/raw_channel.h" | 8 #include "mojo/system/raw_channel.h" |
| 9 | 9 |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "base/message_loop/message_loop.h" | 24 #include "base/message_loop/message_loop.h" |
| 25 #include "base/posix/eintr_wrapper.h" | 25 #include "base/posix/eintr_wrapper.h" |
| 26 #include "base/rand_util.h" | 26 #include "base/rand_util.h" |
| 27 #include "base/synchronization/lock.h" | 27 #include "base/synchronization/lock.h" |
| 28 #include "base/synchronization/waitable_event.h" | 28 #include "base/synchronization/waitable_event.h" |
| 29 #include "base/threading/platform_thread.h" // For |Sleep()|. | 29 #include "base/threading/platform_thread.h" // For |Sleep()|. |
| 30 #include "base/threading/simple_thread.h" | 30 #include "base/threading/simple_thread.h" |
| 31 #include "base/threading/thread.h" | 31 #include "base/threading/thread.h" |
| 32 #include "base/time/time.h" | 32 #include "base/time/time.h" |
| 33 #include "mojo/system/message_in_transit.h" | 33 #include "mojo/system/message_in_transit.h" |
| 34 #include "mojo/system/platform_channel.h" | |
| 35 #include "mojo/system/platform_channel_handle.h" | |
| 36 #include "mojo/system/platform_channel_pair.h" | 34 #include "mojo/system/platform_channel_pair.h" |
| 35 #include "mojo/system/platform_handle.h" |
| 36 #include "mojo/system/scoped_platform_handle.h" |
| 37 #include "mojo/system/test_utils.h" | 37 #include "mojo/system/test_utils.h" |
| 38 #include "testing/gtest/include/gtest/gtest.h" | 38 #include "testing/gtest/include/gtest/gtest.h" |
| 39 | 39 |
| 40 namespace mojo { | 40 namespace mojo { |
| 41 namespace system { | 41 namespace system { |
| 42 namespace { | 42 namespace { |
| 43 | 43 |
| 44 MessageInTransit* MakeTestMessage(uint32_t num_bytes) { | 44 MessageInTransit* MakeTestMessage(uint32_t num_bytes) { |
| 45 std::vector<unsigned char> bytes(num_bytes, 0); | 45 std::vector<unsigned char> bytes(num_bytes, 0); |
| 46 for (size_t i = 0; i < num_bytes; i++) | 46 for (size_t i = 0; i < num_bytes; i++) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 72 } | 72 } |
| 73 | 73 |
| 74 virtual ~RawChannelPosixTest() { | 74 virtual ~RawChannelPosixTest() { |
| 75 } | 75 } |
| 76 | 76 |
| 77 virtual void SetUp() OVERRIDE { | 77 virtual void SetUp() OVERRIDE { |
| 78 io_thread_.StartWithOptions( | 78 io_thread_.StartWithOptions( |
| 79 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | 79 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); |
| 80 | 80 |
| 81 PlatformChannelPair channel_pair; | 81 PlatformChannelPair channel_pair; |
| 82 scoped_ptr<PlatformChannel> server_channel( | 82 handles[0] = channel_pair.PassServerHandle(); |
| 83 channel_pair.CreateServerChannel()); | 83 handles[1] = channel_pair.PassClientHandle(); |
| 84 CHECK(server_channel.get()); | |
| 85 CHECK(server_channel->is_valid()); | |
| 86 scoped_ptr<PlatformChannel> client_channel( | |
| 87 channel_pair.CreateClientChannel()); | |
| 88 CHECK(client_channel.get()); | |
| 89 CHECK(client_channel->is_valid()); | |
| 90 | |
| 91 handles_[0] = server_channel->PassHandle(); | |
| 92 handles_[1] = client_channel->PassHandle(); | |
| 93 } | 84 } |
| 94 | 85 |
| 95 virtual void TearDown() OVERRIDE { | 86 virtual void TearDown() OVERRIDE { |
| 96 if (handles_[0].is_valid()) | 87 handles[0].reset(); |
| 97 close(handles_[0].fd); | 88 handles[1].reset(); |
| 98 if (handles_[1].is_valid()) | |
| 99 close(handles_[1].fd); | |
| 100 | 89 |
| 101 io_thread_.Stop(); | 90 io_thread_.Stop(); |
| 102 } | 91 } |
| 103 | 92 |
| 104 protected: | 93 protected: |
| 105 int fd(size_t i) { return handles_[i].fd; } | |
| 106 void clear_fd(size_t i) { handles_[i] = PlatformChannelHandle(); } | |
| 107 | |
| 108 base::MessageLoop* io_thread_message_loop() { | 94 base::MessageLoop* io_thread_message_loop() { |
| 109 return io_thread_.message_loop(); | 95 return io_thread_.message_loop(); |
| 110 } | 96 } |
| 111 | 97 |
| 112 scoped_refptr<base::TaskRunner> io_thread_task_runner() { | 98 scoped_refptr<base::TaskRunner> io_thread_task_runner() { |
| 113 return io_thread_message_loop()->message_loop_proxy(); | 99 return io_thread_message_loop()->message_loop_proxy(); |
| 114 } | 100 } |
| 115 | 101 |
| 102 ScopedPlatformHandle handles[2]; |
| 103 |
| 116 private: | 104 private: |
| 117 base::Thread io_thread_; | 105 base::Thread io_thread_; |
| 118 PlatformChannelHandle handles_[2]; | |
| 119 | 106 |
| 120 DISALLOW_COPY_AND_ASSIGN(RawChannelPosixTest); | 107 DISALLOW_COPY_AND_ASSIGN(RawChannelPosixTest); |
| 121 }; | 108 }; |
| 122 | 109 |
| 123 // RawChannelPosixTest.WriteMessage -------------------------------------------- | 110 // RawChannelPosixTest.WriteMessage -------------------------------------------- |
| 124 | 111 |
| 125 class WriteOnlyRawChannelDelegate : public RawChannel::Delegate { | 112 class WriteOnlyRawChannelDelegate : public RawChannel::Delegate { |
| 126 public: | 113 public: |
| 127 WriteOnlyRawChannelDelegate() {} | 114 WriteOnlyRawChannelDelegate() {} |
| 128 virtual ~WriteOnlyRawChannelDelegate() {} | 115 virtual ~WriteOnlyRawChannelDelegate() {} |
| 129 | 116 |
| 130 // |RawChannel::Delegate| implementation: | 117 // |RawChannel::Delegate| implementation: |
| 131 virtual void OnReadMessage(const MessageInTransit& /*message*/) OVERRIDE { | 118 virtual void OnReadMessage(const MessageInTransit& /*message*/) OVERRIDE { |
| 132 NOTREACHED(); | 119 NOTREACHED(); |
| 133 } | 120 } |
| 134 virtual void OnFatalError(FatalError /*fatal_error*/) OVERRIDE { | 121 virtual void OnFatalError(FatalError /*fatal_error*/) OVERRIDE { |
| 135 NOTREACHED(); | 122 NOTREACHED(); |
| 136 } | 123 } |
| 137 | 124 |
| 138 private: | 125 private: |
| 139 DISALLOW_COPY_AND_ASSIGN(WriteOnlyRawChannelDelegate); | 126 DISALLOW_COPY_AND_ASSIGN(WriteOnlyRawChannelDelegate); |
| 140 }; | 127 }; |
| 141 | 128 |
| 142 static const int64_t kMessageReaderSleepMs = 1; | 129 static const int64_t kMessageReaderSleepMs = 1; |
| 143 static const size_t kMessageReaderMaxPollIterations = 3000; | 130 static const size_t kMessageReaderMaxPollIterations = 3000; |
| 144 | 131 |
| 145 class TestMessageReaderAndChecker { | 132 class TestMessageReaderAndChecker { |
| 146 public: | 133 public: |
| 147 explicit TestMessageReaderAndChecker(int fd) : fd_(fd) {} | 134 explicit TestMessageReaderAndChecker(PlatformHandle handle) |
| 135 : handle_(handle) {} |
| 148 ~TestMessageReaderAndChecker() { CHECK(bytes_.empty()); } | 136 ~TestMessageReaderAndChecker() { CHECK(bytes_.empty()); } |
| 149 | 137 |
| 150 bool ReadAndCheckNextMessage(uint32_t expected_size) { | 138 bool ReadAndCheckNextMessage(uint32_t expected_size) { |
| 151 unsigned char buffer[4096]; | 139 unsigned char buffer[4096]; |
| 152 | 140 |
| 153 for (size_t i = 0; i < kMessageReaderMaxPollIterations;) { | 141 for (size_t i = 0; i < kMessageReaderMaxPollIterations;) { |
| 154 ssize_t read_size = HANDLE_EINTR(read(fd_, buffer, sizeof(buffer))); | 142 ssize_t read_size = HANDLE_EINTR( |
| 143 read(handle_.fd, buffer, sizeof(buffer))); |
| 155 if (read_size < 0) { | 144 if (read_size < 0) { |
| 156 PCHECK(errno == EAGAIN || errno == EWOULDBLOCK); | 145 PCHECK(errno == EAGAIN || errno == EWOULDBLOCK); |
| 157 read_size = 0; | 146 read_size = 0; |
| 158 } | 147 } |
| 159 | 148 |
| 160 // Append newly-read data to |bytes_|. | 149 // Append newly-read data to |bytes_|. |
| 161 bytes_.insert(bytes_.end(), buffer, buffer + read_size); | 150 bytes_.insert(bytes_.end(), buffer, buffer + read_size); |
| 162 | 151 |
| 163 // If we have the header.... | 152 // If we have the header.... |
| 164 if (bytes_.size() >= sizeof(MessageInTransit)) { | 153 if (bytes_.size() >= sizeof(MessageInTransit)) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 193 base::PlatformThread::Sleep( | 182 base::PlatformThread::Sleep( |
| 194 base::TimeDelta::FromMilliseconds(kMessageReaderSleepMs)); | 183 base::TimeDelta::FromMilliseconds(kMessageReaderSleepMs)); |
| 195 } | 184 } |
| 196 } | 185 } |
| 197 | 186 |
| 198 LOG(ERROR) << "Too many iterations."; | 187 LOG(ERROR) << "Too many iterations."; |
| 199 return false; | 188 return false; |
| 200 } | 189 } |
| 201 | 190 |
| 202 private: | 191 private: |
| 203 const int fd_; | 192 const PlatformHandle handle_; |
| 204 | 193 |
| 205 // The start of the received data should always be on a message boundary. | 194 // The start of the received data should always be on a message boundary. |
| 206 std::vector<unsigned char> bytes_; | 195 std::vector<unsigned char> bytes_; |
| 207 | 196 |
| 208 DISALLOW_COPY_AND_ASSIGN(TestMessageReaderAndChecker); | 197 DISALLOW_COPY_AND_ASSIGN(TestMessageReaderAndChecker); |
| 209 }; | 198 }; |
| 210 | 199 |
| 211 // Tests writing (and verifies reading using our own custom reader). | 200 // Tests writing (and verifies reading using our own custom reader). |
| 212 TEST_F(RawChannelPosixTest, WriteMessage) { | 201 TEST_F(RawChannelPosixTest, WriteMessage) { |
| 213 WriteOnlyRawChannelDelegate delegate; | 202 WriteOnlyRawChannelDelegate delegate; |
| 214 scoped_ptr<RawChannel> rc(RawChannel::Create(PlatformChannelHandle(fd(0)), | 203 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), |
| 215 &delegate, | 204 &delegate, |
| 216 io_thread_message_loop())); | 205 io_thread_message_loop())); |
| 217 // |RawChannel::Create()| takes ownership of the FD. | |
| 218 clear_fd(0); | |
| 219 | 206 |
| 220 TestMessageReaderAndChecker checker(fd(1)); | 207 TestMessageReaderAndChecker checker(handles[1].get()); |
| 221 | 208 |
| 222 test::PostTaskAndWait(io_thread_task_runner(), | 209 test::PostTaskAndWait(io_thread_task_runner(), |
| 223 FROM_HERE, | 210 FROM_HERE, |
| 224 base::Bind(&InitOnIOThread, rc.get())); | 211 base::Bind(&InitOnIOThread, rc.get())); |
| 225 | 212 |
| 226 // Write and read, for a variety of sizes. | 213 // Write and read, for a variety of sizes. |
| 227 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { | 214 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { |
| 228 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); | 215 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); |
| 229 EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size; | 216 EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size; |
| 230 } | 217 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 base::Lock lock_; // Protects the following members. | 283 base::Lock lock_; // Protects the following members. |
| 297 std::vector<uint32_t> expected_sizes_; | 284 std::vector<uint32_t> expected_sizes_; |
| 298 size_t position_; | 285 size_t position_; |
| 299 | 286 |
| 300 DISALLOW_COPY_AND_ASSIGN(ReadCheckerRawChannelDelegate); | 287 DISALLOW_COPY_AND_ASSIGN(ReadCheckerRawChannelDelegate); |
| 301 }; | 288 }; |
| 302 | 289 |
| 303 // Tests reading (writing using our own custom writer). | 290 // Tests reading (writing using our own custom writer). |
| 304 TEST_F(RawChannelPosixTest, OnReadMessage) { | 291 TEST_F(RawChannelPosixTest, OnReadMessage) { |
| 305 // We're going to write to |fd(1)|. We'll do so in a blocking manner. | 292 // We're going to write to |fd(1)|. We'll do so in a blocking manner. |
| 306 PCHECK(fcntl(fd(1), F_SETFL, 0) == 0); | 293 PCHECK(fcntl(handles[1].get().fd, F_SETFL, 0) == 0); |
| 307 | 294 |
| 308 ReadCheckerRawChannelDelegate delegate; | 295 ReadCheckerRawChannelDelegate delegate; |
| 309 scoped_ptr<RawChannel> rc(RawChannel::Create(PlatformChannelHandle(fd(0)), | 296 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), |
| 310 &delegate, | 297 &delegate, |
| 311 io_thread_message_loop())); | 298 io_thread_message_loop())); |
| 312 // |RawChannel::Create()| takes ownership of the FD. | |
| 313 clear_fd(0); | |
| 314 | 299 |
| 315 test::PostTaskAndWait(io_thread_task_runner(), | 300 test::PostTaskAndWait(io_thread_task_runner(), |
| 316 FROM_HERE, | 301 FROM_HERE, |
| 317 base::Bind(&InitOnIOThread, rc.get())); | 302 base::Bind(&InitOnIOThread, rc.get())); |
| 318 | 303 |
| 319 // Write and read, for a variety of sizes. | 304 // Write and read, for a variety of sizes. |
| 320 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { | 305 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { |
| 321 delegate.SetExpectedSizes(std::vector<uint32_t>(1, size)); | 306 delegate.SetExpectedSizes(std::vector<uint32_t>(1, size)); |
| 322 MessageInTransit* message = MakeTestMessage(size); | 307 MessageInTransit* message = MakeTestMessage(size); |
| 323 | 308 |
| 324 ssize_t write_size = HANDLE_EINTR( | 309 ssize_t write_size = HANDLE_EINTR( |
| 325 write(fd(1), message, message->size_with_header_and_padding())); | 310 write(handles[1].get().fd, message, |
| 311 message->size_with_header_and_padding())); |
| 326 EXPECT_EQ(static_cast<ssize_t>(message->size_with_header_and_padding()), | 312 EXPECT_EQ(static_cast<ssize_t>(message->size_with_header_and_padding()), |
| 327 write_size); | 313 write_size); |
| 328 message->Destroy(); | 314 message->Destroy(); |
| 329 delegate.Wait(); | 315 delegate.Wait(); |
| 330 } | 316 } |
| 331 | 317 |
| 332 // Set up reader and write as fast as we can. | 318 // Set up reader and write as fast as we can. |
| 333 // Write/queue and read afterwards, for a variety of sizes. | 319 // Write/queue and read afterwards, for a variety of sizes. |
| 334 std::vector<uint32_t> expected_sizes; | 320 std::vector<uint32_t> expected_sizes; |
| 335 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) | 321 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) |
| 336 expected_sizes.push_back(size); | 322 expected_sizes.push_back(size); |
| 337 delegate.SetExpectedSizes(expected_sizes); | 323 delegate.SetExpectedSizes(expected_sizes); |
| 338 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { | 324 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { |
| 339 MessageInTransit* message = MakeTestMessage(size); | 325 MessageInTransit* message = MakeTestMessage(size); |
| 340 ssize_t write_size = HANDLE_EINTR( | 326 ssize_t write_size = HANDLE_EINTR( |
| 341 write(fd(1), message, message->size_with_header_and_padding())); | 327 write(handles[1].get().fd, message, |
| 328 message->size_with_header_and_padding())); |
| 342 EXPECT_EQ(static_cast<ssize_t>(message->size_with_header_and_padding()), | 329 EXPECT_EQ(static_cast<ssize_t>(message->size_with_header_and_padding()), |
| 343 write_size); | 330 write_size); |
| 344 message->Destroy(); | 331 message->Destroy(); |
| 345 } | 332 } |
| 346 delegate.Wait(); | 333 delegate.Wait(); |
| 347 | 334 |
| 348 test::PostTaskAndWait(io_thread_task_runner(), | 335 test::PostTaskAndWait(io_thread_task_runner(), |
| 349 FROM_HERE, | 336 FROM_HERE, |
| 350 base::Bind(&RawChannel::Shutdown, | 337 base::Bind(&RawChannel::Shutdown, |
| 351 base::Unretained(rc.get()))); | 338 base::Unretained(rc.get()))); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 | 402 |
| 416 DISALLOW_COPY_AND_ASSIGN(ReadCountdownRawChannelDelegate); | 403 DISALLOW_COPY_AND_ASSIGN(ReadCountdownRawChannelDelegate); |
| 417 }; | 404 }; |
| 418 | 405 |
| 419 TEST_F(RawChannelPosixTest, WriteMessageAndOnReadMessage) { | 406 TEST_F(RawChannelPosixTest, WriteMessageAndOnReadMessage) { |
| 420 static const size_t kNumWriterThreads = 10; | 407 static const size_t kNumWriterThreads = 10; |
| 421 static const size_t kNumWriteMessagesPerThread = 4000; | 408 static const size_t kNumWriteMessagesPerThread = 4000; |
| 422 | 409 |
| 423 WriteOnlyRawChannelDelegate writer_delegate; | 410 WriteOnlyRawChannelDelegate writer_delegate; |
| 424 scoped_ptr<RawChannel> writer_rc( | 411 scoped_ptr<RawChannel> writer_rc( |
| 425 RawChannel::Create(PlatformChannelHandle(fd(0)), | 412 RawChannel::Create(handles[0].Pass(), |
| 426 &writer_delegate, | 413 &writer_delegate, |
| 427 io_thread_message_loop())); | 414 io_thread_message_loop())); |
| 428 // |RawChannel::Create()| takes ownership of the FD. | |
| 429 clear_fd(0); | |
| 430 | 415 |
| 431 test::PostTaskAndWait(io_thread_task_runner(), | 416 test::PostTaskAndWait(io_thread_task_runner(), |
| 432 FROM_HERE, | 417 FROM_HERE, |
| 433 base::Bind(&InitOnIOThread, writer_rc.get())); | 418 base::Bind(&InitOnIOThread, writer_rc.get())); |
| 434 | 419 |
| 435 ReadCountdownRawChannelDelegate reader_delegate( | 420 ReadCountdownRawChannelDelegate reader_delegate( |
| 436 kNumWriterThreads * kNumWriteMessagesPerThread); | 421 kNumWriterThreads * kNumWriteMessagesPerThread); |
| 437 scoped_ptr<RawChannel> reader_rc( | 422 scoped_ptr<RawChannel> reader_rc( |
| 438 RawChannel::Create(PlatformChannelHandle(fd(1)), | 423 RawChannel::Create(handles[1].Pass(), |
| 439 &reader_delegate, | 424 &reader_delegate, |
| 440 io_thread_message_loop())); | 425 io_thread_message_loop())); |
| 441 // |RawChannel::Create()| takes ownership of the FD. | |
| 442 clear_fd(1); | |
| 443 | 426 |
| 444 test::PostTaskAndWait(io_thread_task_runner(), | 427 test::PostTaskAndWait(io_thread_task_runner(), |
| 445 FROM_HERE, | 428 FROM_HERE, |
| 446 base::Bind(&InitOnIOThread, reader_rc.get())); | 429 base::Bind(&InitOnIOThread, reader_rc.get())); |
| 447 | 430 |
| 448 { | 431 { |
| 449 ScopedVector<RawChannelWriterThread> writer_threads; | 432 ScopedVector<RawChannelWriterThread> writer_threads; |
| 450 for (size_t i = 0; i < kNumWriterThreads; i++) { | 433 for (size_t i = 0; i < kNumWriterThreads; i++) { |
| 451 writer_threads.push_back(new RawChannelWriterThread( | 434 writer_threads.push_back(new RawChannelWriterThread( |
| 452 writer_rc.get(), kNumWriteMessagesPerThread)); | 435 writer_rc.get(), kNumWriteMessagesPerThread)); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 FatalError last_fatal_error_; | 490 FatalError last_fatal_error_; |
| 508 | 491 |
| 509 DISALLOW_COPY_AND_ASSIGN(FatalErrorRecordingRawChannelDelegate); | 492 DISALLOW_COPY_AND_ASSIGN(FatalErrorRecordingRawChannelDelegate); |
| 510 }; | 493 }; |
| 511 | 494 |
| 512 // Tests fatal errors. | 495 // Tests fatal errors. |
| 513 // TODO(vtl): Figure out how to make reading fail reliably. (I'm not convinced | 496 // TODO(vtl): Figure out how to make reading fail reliably. (I'm not convinced |
| 514 // that it does.) | 497 // that it does.) |
| 515 TEST_F(RawChannelPosixTest, OnFatalError) { | 498 TEST_F(RawChannelPosixTest, OnFatalError) { |
| 516 FatalErrorRecordingRawChannelDelegate delegate; | 499 FatalErrorRecordingRawChannelDelegate delegate; |
| 517 scoped_ptr<RawChannel> rc(RawChannel::Create(PlatformChannelHandle(fd(0)), | 500 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), |
| 518 &delegate, | 501 &delegate, |
| 519 io_thread_message_loop())); | 502 io_thread_message_loop())); |
| 520 // |RawChannel::Create()| takes ownership of the FD. | |
| 521 clear_fd(0); | |
| 522 | 503 |
| 523 test::PostTaskAndWait(io_thread_task_runner(), | 504 test::PostTaskAndWait(io_thread_task_runner(), |
| 524 FROM_HERE, | 505 FROM_HERE, |
| 525 base::Bind(&InitOnIOThread, rc.get())); | 506 base::Bind(&InitOnIOThread, rc.get())); |
| 526 | 507 |
| 527 // Close the other end, which should make writing fail. | 508 // Close the other end, which should make writing fail. |
| 528 CHECK_EQ(close(fd(1)), 0); | 509 handles[1].reset(); |
| 529 clear_fd(1); | |
| 530 | 510 |
| 531 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | 511 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); |
| 532 | 512 |
| 533 // TODO(vtl): In theory, it's conceivable that closing the other end might | 513 // TODO(vtl): In theory, it's conceivable that closing the other end might |
| 534 // lead to read failing. In practice, it doesn't seem to. | 514 // lead to read failing. In practice, it doesn't seem to. |
| 535 EXPECT_EQ(RawChannel::Delegate::FATAL_ERROR_FAILED_WRITE, | 515 EXPECT_EQ(RawChannel::Delegate::FATAL_ERROR_FAILED_WRITE, |
| 536 delegate.WaitForFatalError()); | 516 delegate.WaitForFatalError()); |
| 537 | 517 |
| 538 test::PostTaskAndWait(io_thread_task_runner(), | 518 test::PostTaskAndWait(io_thread_task_runner(), |
| 539 FROM_HERE, | 519 FROM_HERE, |
| 540 base::Bind(&RawChannel::Shutdown, | 520 base::Bind(&RawChannel::Shutdown, |
| 541 base::Unretained(rc.get()))); | 521 base::Unretained(rc.get()))); |
| 542 | 522 |
| 543 } | 523 } |
| 544 | 524 |
| 545 // RawChannelPosixTest.WriteMessageAfterShutdown ------------------------------- | 525 // RawChannelPosixTest.WriteMessageAfterShutdown ------------------------------- |
| 546 | 526 |
| 547 // Makes sure that calling |WriteMessage()| after |Shutdown()| behaves | 527 // Makes sure that calling |WriteMessage()| after |Shutdown()| behaves |
| 548 // correctly. | 528 // correctly. |
| 549 TEST_F(RawChannelPosixTest, WriteMessageAfterShutdown) { | 529 TEST_F(RawChannelPosixTest, WriteMessageAfterShutdown) { |
| 550 WriteOnlyRawChannelDelegate delegate; | 530 WriteOnlyRawChannelDelegate delegate; |
| 551 scoped_ptr<RawChannel> rc(RawChannel::Create(PlatformChannelHandle(fd(0)), | 531 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), |
| 552 &delegate, | 532 &delegate, |
| 553 io_thread_message_loop())); | 533 io_thread_message_loop())); |
| 554 // |RawChannel::Create()| takes ownership of the FD. | |
| 555 clear_fd(0); | |
| 556 | 534 |
| 557 test::PostTaskAndWait(io_thread_task_runner(), | 535 test::PostTaskAndWait(io_thread_task_runner(), |
| 558 FROM_HERE, | 536 FROM_HERE, |
| 559 base::Bind(&InitOnIOThread, rc.get())); | 537 base::Bind(&InitOnIOThread, rc.get())); |
| 560 test::PostTaskAndWait(io_thread_task_runner(), | 538 test::PostTaskAndWait(io_thread_task_runner(), |
| 561 FROM_HERE, | 539 FROM_HERE, |
| 562 base::Bind(&RawChannel::Shutdown, | 540 base::Bind(&RawChannel::Shutdown, |
| 563 base::Unretained(rc.get()))); | 541 base::Unretained(rc.get()))); |
| 564 | 542 |
| 565 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | 543 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); |
| 566 } | 544 } |
| 567 | 545 |
| 568 } // namespace | 546 } // namespace |
| 569 } // namespace system | 547 } // namespace system |
| 570 } // namespace mojo | 548 } // namespace mojo |
| OLD | NEW |