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 |