| 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 #include "mojo/public/cpp/bindings/lib/connector.h" | 5 #include "mojo/public/cpp/bindings/lib/connector.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/run_loop.h" |
| 13 #include "mojo/message_pump/message_pump_mojo.h" | 14 #include "mojo/message_pump/message_pump_mojo.h" |
| 14 #include "mojo/public/cpp/bindings/lib/message_builder.h" | 15 #include "mojo/public/cpp/bindings/lib/message_builder.h" |
| 15 #include "mojo/public/cpp/bindings/tests/message_queue.h" | 16 #include "mojo/public/cpp/bindings/tests/message_queue.h" |
| 16 #include "mojo/public/cpp/system/macros.h" | 17 #include "mojo/public/cpp/system/macros.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 19 |
| 19 namespace mojo { | 20 namespace mojo { |
| 20 namespace test { | 21 namespace test { |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 23 class MessageAccumulator : public MessageReceiver { | 24 class MessageAccumulator : public MessageReceiver { |
| 24 public: | 25 public: |
| 25 MessageAccumulator() {} | 26 MessageAccumulator() {} |
| 27 explicit MessageAccumulator(const base::Closure& closure) |
| 28 : closure_(closure) {} |
| 26 | 29 |
| 27 bool Accept(Message* message) override { | 30 bool Accept(Message* message) override { |
| 28 queue_.Push(message); | 31 queue_.Push(message); |
| 32 if (!closure_.is_null()) |
| 33 closure_.Run(); |
| 34 closure_.Reset(); |
| 29 return true; | 35 return true; |
| 30 } | 36 } |
| 31 | 37 |
| 32 bool IsEmpty() const { return queue_.IsEmpty(); } | 38 bool IsEmpty() const { return queue_.IsEmpty(); } |
| 33 | 39 |
| 34 void Pop(Message* message) { queue_.Pop(message); } | 40 void Pop(Message* message) { queue_.Pop(message); } |
| 35 | 41 |
| 42 void set_closure(const base::Closure& closure) { |
| 43 closure_ = closure; |
| 44 } |
| 45 |
| 36 private: | 46 private: |
| 37 MessageQueue queue_; | 47 MessageQueue queue_; |
| 48 base::Closure closure_; |
| 38 }; | 49 }; |
| 39 | 50 |
| 40 class ConnectorDeletingMessageAccumulator : public MessageAccumulator { | 51 class ConnectorDeletingMessageAccumulator : public MessageAccumulator { |
| 41 public: | 52 public: |
| 42 ConnectorDeletingMessageAccumulator(internal::Connector** connector) | 53 ConnectorDeletingMessageAccumulator(internal::Connector** connector) |
| 43 : connector_(connector) {} | 54 : connector_(connector) {} |
| 44 | 55 |
| 45 bool Accept(Message* message) override { | 56 bool Accept(Message* message) override { |
| 46 delete *connector_; | 57 delete *connector_; |
| 47 *connector_ = nullptr; | 58 *connector_ = nullptr; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 void TearDown() override {} | 96 void TearDown() override {} |
| 86 | 97 |
| 87 void AllocMessage(const char* text, Message* message) { | 98 void AllocMessage(const char* text, Message* message) { |
| 88 size_t payload_size = strlen(text) + 1; // Plus null terminator. | 99 size_t payload_size = strlen(text) + 1; // Plus null terminator. |
| 89 internal::MessageBuilder builder(1, payload_size); | 100 internal::MessageBuilder builder(1, payload_size); |
| 90 memcpy(builder.buffer()->Allocate(payload_size), text, payload_size); | 101 memcpy(builder.buffer()->Allocate(payload_size), text, payload_size); |
| 91 | 102 |
| 92 builder.message()->MoveTo(message); | 103 builder.message()->MoveTo(message); |
| 93 } | 104 } |
| 94 | 105 |
| 95 void PumpMessages() { loop_.RunUntilIdle(); } | |
| 96 | |
| 97 protected: | 106 protected: |
| 98 ScopedMessagePipeHandle handle0_; | 107 ScopedMessagePipeHandle handle0_; |
| 99 ScopedMessagePipeHandle handle1_; | 108 ScopedMessagePipeHandle handle1_; |
| 100 | 109 |
| 101 private: | 110 private: |
| 102 base::MessageLoop loop_; | 111 base::MessageLoop loop_; |
| 103 }; | 112 }; |
| 104 | 113 |
| 105 TEST_F(ConnectorTest, Basic) { | 114 TEST_F(ConnectorTest, Basic) { |
| 106 internal::Connector connector0(std::move(handle0_), | 115 internal::Connector connector0(std::move(handle0_), |
| 107 internal::Connector::SINGLE_THREADED_SEND); | 116 internal::Connector::SINGLE_THREADED_SEND); |
| 108 internal::Connector connector1(std::move(handle1_), | 117 internal::Connector connector1(std::move(handle1_), |
| 109 internal::Connector::SINGLE_THREADED_SEND); | 118 internal::Connector::SINGLE_THREADED_SEND); |
| 110 | 119 |
| 111 const char kText[] = "hello world"; | 120 const char kText[] = "hello world"; |
| 112 | 121 |
| 113 Message message; | 122 Message message; |
| 114 AllocMessage(kText, &message); | 123 AllocMessage(kText, &message); |
| 115 | 124 |
| 116 connector0.Accept(&message); | 125 connector0.Accept(&message); |
| 117 | 126 |
| 118 MessageAccumulator accumulator; | 127 base::RunLoop run_loop; |
| 128 MessageAccumulator accumulator(run_loop.QuitClosure()); |
| 119 connector1.set_incoming_receiver(&accumulator); | 129 connector1.set_incoming_receiver(&accumulator); |
| 120 | 130 |
| 121 PumpMessages(); | 131 run_loop.Run(); |
| 122 | 132 |
| 123 ASSERT_FALSE(accumulator.IsEmpty()); | 133 ASSERT_FALSE(accumulator.IsEmpty()); |
| 124 | 134 |
| 125 Message message_received; | 135 Message message_received; |
| 126 accumulator.Pop(&message_received); | 136 accumulator.Pop(&message_received); |
| 127 | 137 |
| 128 EXPECT_EQ( | 138 EXPECT_EQ( |
| 129 std::string(kText), | 139 std::string(kText), |
| 130 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 140 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 131 } | 141 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 157 std::string(kText), | 167 std::string(kText), |
| 158 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 168 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 159 } | 169 } |
| 160 | 170 |
| 161 TEST_F(ConnectorTest, Basic_EarlyIncomingReceiver) { | 171 TEST_F(ConnectorTest, Basic_EarlyIncomingReceiver) { |
| 162 internal::Connector connector0(std::move(handle0_), | 172 internal::Connector connector0(std::move(handle0_), |
| 163 internal::Connector::SINGLE_THREADED_SEND); | 173 internal::Connector::SINGLE_THREADED_SEND); |
| 164 internal::Connector connector1(std::move(handle1_), | 174 internal::Connector connector1(std::move(handle1_), |
| 165 internal::Connector::SINGLE_THREADED_SEND); | 175 internal::Connector::SINGLE_THREADED_SEND); |
| 166 | 176 |
| 167 MessageAccumulator accumulator; | 177 base::RunLoop run_loop; |
| 178 MessageAccumulator accumulator(run_loop.QuitClosure()); |
| 168 connector1.set_incoming_receiver(&accumulator); | 179 connector1.set_incoming_receiver(&accumulator); |
| 169 | 180 |
| 170 const char kText[] = "hello world"; | 181 const char kText[] = "hello world"; |
| 171 | 182 |
| 172 Message message; | 183 Message message; |
| 173 AllocMessage(kText, &message); | 184 AllocMessage(kText, &message); |
| 174 | 185 |
| 175 connector0.Accept(&message); | 186 connector0.Accept(&message); |
| 176 | 187 |
| 177 PumpMessages(); | 188 run_loop.Run(); |
| 178 | 189 |
| 179 ASSERT_FALSE(accumulator.IsEmpty()); | 190 ASSERT_FALSE(accumulator.IsEmpty()); |
| 180 | 191 |
| 181 Message message_received; | 192 Message message_received; |
| 182 accumulator.Pop(&message_received); | 193 accumulator.Pop(&message_received); |
| 183 | 194 |
| 184 EXPECT_EQ( | 195 EXPECT_EQ( |
| 185 std::string(kText), | 196 std::string(kText), |
| 186 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 197 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 187 } | 198 } |
| 188 | 199 |
| 189 TEST_F(ConnectorTest, Basic_TwoMessages) { | 200 TEST_F(ConnectorTest, Basic_TwoMessages) { |
| 190 internal::Connector connector0(std::move(handle0_), | 201 internal::Connector connector0(std::move(handle0_), |
| 191 internal::Connector::SINGLE_THREADED_SEND); | 202 internal::Connector::SINGLE_THREADED_SEND); |
| 192 internal::Connector connector1(std::move(handle1_), | 203 internal::Connector connector1(std::move(handle1_), |
| 193 internal::Connector::SINGLE_THREADED_SEND); | 204 internal::Connector::SINGLE_THREADED_SEND); |
| 194 | 205 |
| 195 const char* kText[] = {"hello", "world"}; | 206 const char* kText[] = {"hello", "world"}; |
| 196 | 207 |
| 197 for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) { | 208 for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) { |
| 198 Message message; | 209 Message message; |
| 199 AllocMessage(kText[i], &message); | 210 AllocMessage(kText[i], &message); |
| 200 | 211 |
| 201 connector0.Accept(&message); | 212 connector0.Accept(&message); |
| 202 } | 213 } |
| 203 | 214 |
| 204 MessageAccumulator accumulator; | 215 MessageAccumulator accumulator; |
| 205 connector1.set_incoming_receiver(&accumulator); | 216 connector1.set_incoming_receiver(&accumulator); |
| 206 | 217 |
| 207 PumpMessages(); | |
| 208 | |
| 209 for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) { | 218 for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) { |
| 219 if (accumulator.IsEmpty()) { |
| 220 base::RunLoop run_loop; |
| 221 accumulator.set_closure(run_loop.QuitClosure()); |
| 222 run_loop.Run(); |
| 223 } |
| 210 ASSERT_FALSE(accumulator.IsEmpty()); | 224 ASSERT_FALSE(accumulator.IsEmpty()); |
| 211 | 225 |
| 212 Message message_received; | 226 Message message_received; |
| 213 accumulator.Pop(&message_received); | 227 accumulator.Pop(&message_received); |
| 214 | 228 |
| 215 EXPECT_EQ( | 229 EXPECT_EQ( |
| 216 std::string(kText[i]), | 230 std::string(kText[i]), |
| 217 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 231 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 218 } | 232 } |
| 219 } | 233 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 EXPECT_FALSE(connector0.encountered_error()); | 280 EXPECT_FALSE(connector0.encountered_error()); |
| 267 | 281 |
| 268 // Write failures are not reported. | 282 // Write failures are not reported. |
| 269 bool ok = connector0.Accept(&message); | 283 bool ok = connector0.Accept(&message); |
| 270 EXPECT_TRUE(ok); | 284 EXPECT_TRUE(ok); |
| 271 | 285 |
| 272 // Still not observed. | 286 // Still not observed. |
| 273 EXPECT_FALSE(connector0.encountered_error()); | 287 EXPECT_FALSE(connector0.encountered_error()); |
| 274 | 288 |
| 275 // Spin the message loop, and then we should start observing the closed pipe. | 289 // Spin the message loop, and then we should start observing the closed pipe. |
| 276 PumpMessages(); | 290 base::RunLoop run_loop; |
| 291 connector0.set_connection_error_handler(run_loop.QuitClosure()); |
| 292 run_loop.Run(); |
| 277 | 293 |
| 278 EXPECT_TRUE(connector0.encountered_error()); | 294 EXPECT_TRUE(connector0.encountered_error()); |
| 279 } | 295 } |
| 280 | 296 |
| 281 TEST_F(ConnectorTest, MessageWithHandles) { | 297 TEST_F(ConnectorTest, MessageWithHandles) { |
| 282 internal::Connector connector0(std::move(handle0_), | 298 internal::Connector connector0(std::move(handle0_), |
| 283 internal::Connector::SINGLE_THREADED_SEND); | 299 internal::Connector::SINGLE_THREADED_SEND); |
| 284 internal::Connector connector1(std::move(handle1_), | 300 internal::Connector connector1(std::move(handle1_), |
| 285 internal::Connector::SINGLE_THREADED_SEND); | 301 internal::Connector::SINGLE_THREADED_SEND); |
| 286 | 302 |
| 287 const char kText[] = "hello world"; | 303 const char kText[] = "hello world"; |
| 288 | 304 |
| 289 Message message1; | 305 Message message1; |
| 290 AllocMessage(kText, &message1); | 306 AllocMessage(kText, &message1); |
| 291 | 307 |
| 292 MessagePipe pipe; | 308 MessagePipe pipe; |
| 293 message1.mutable_handles()->push_back(pipe.handle0.release()); | 309 message1.mutable_handles()->push_back(pipe.handle0.release()); |
| 294 | 310 |
| 295 connector0.Accept(&message1); | 311 connector0.Accept(&message1); |
| 296 | 312 |
| 297 // The message should have been transferred, releasing the handles. | 313 // The message should have been transferred, releasing the handles. |
| 298 EXPECT_TRUE(message1.handles()->empty()); | 314 EXPECT_TRUE(message1.handles()->empty()); |
| 299 | 315 |
| 300 MessageAccumulator accumulator; | 316 base::RunLoop run_loop; |
| 317 MessageAccumulator accumulator(run_loop.QuitClosure()); |
| 301 connector1.set_incoming_receiver(&accumulator); | 318 connector1.set_incoming_receiver(&accumulator); |
| 302 | 319 |
| 303 PumpMessages(); | 320 run_loop.Run(); |
| 304 | 321 |
| 305 ASSERT_FALSE(accumulator.IsEmpty()); | 322 ASSERT_FALSE(accumulator.IsEmpty()); |
| 306 | 323 |
| 307 Message message_received; | 324 Message message_received; |
| 308 accumulator.Pop(&message_received); | 325 accumulator.Pop(&message_received); |
| 309 | 326 |
| 310 EXPECT_EQ( | 327 EXPECT_EQ( |
| 311 std::string(kText), | 328 std::string(kText), |
| 312 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 329 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 313 ASSERT_EQ(1U, message_received.handles()->size()); | 330 ASSERT_EQ(1U, message_received.handles()->size()); |
| 314 | 331 |
| 315 // Now send a message to the transferred handle and confirm it's sent through | 332 // Now send a message to the transferred handle and confirm it's sent through |
| 316 // to the orginal pipe. | 333 // to the orginal pipe. |
| 317 // TODO(vtl): Do we need a better way of "downcasting" the handle types? | 334 // TODO(vtl): Do we need a better way of "downcasting" the handle types? |
| 318 ScopedMessagePipeHandle smph; | 335 ScopedMessagePipeHandle smph; |
| 319 smph.reset(MessagePipeHandle(message_received.handles()->front().value())); | 336 smph.reset(MessagePipeHandle(message_received.handles()->front().value())); |
| 320 message_received.mutable_handles()->front() = Handle(); | 337 message_received.mutable_handles()->front() = Handle(); |
| 321 // |smph| now owns this handle. | 338 // |smph| now owns this handle. |
| 322 | 339 |
| 323 internal::Connector connector_received( | 340 internal::Connector connector_received( |
| 324 std::move(smph), internal::Connector::SINGLE_THREADED_SEND); | 341 std::move(smph), internal::Connector::SINGLE_THREADED_SEND); |
| 325 internal::Connector connector_original( | 342 internal::Connector connector_original( |
| 326 std::move(pipe.handle1), internal::Connector::SINGLE_THREADED_SEND); | 343 std::move(pipe.handle1), internal::Connector::SINGLE_THREADED_SEND); |
| 327 | 344 |
| 328 Message message2; | 345 Message message2; |
| 329 AllocMessage(kText, &message2); | 346 AllocMessage(kText, &message2); |
| 330 | 347 |
| 331 connector_received.Accept(&message2); | 348 connector_received.Accept(&message2); |
| 332 connector_original.set_incoming_receiver(&accumulator); | 349 base::RunLoop run_loop2; |
| 333 PumpMessages(); | 350 MessageAccumulator accumulator2(run_loop2.QuitClosure()); |
| 351 connector_original.set_incoming_receiver(&accumulator2); |
| 352 run_loop2.Run(); |
| 334 | 353 |
| 335 ASSERT_FALSE(accumulator.IsEmpty()); | 354 ASSERT_FALSE(accumulator2.IsEmpty()); |
| 336 | 355 |
| 337 accumulator.Pop(&message_received); | 356 accumulator2.Pop(&message_received); |
| 338 | 357 |
| 339 EXPECT_EQ( | 358 EXPECT_EQ( |
| 340 std::string(kText), | 359 std::string(kText), |
| 341 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 360 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 342 } | 361 } |
| 343 | 362 |
| 344 TEST_F(ConnectorTest, WaitForIncomingMessageWithError) { | 363 TEST_F(ConnectorTest, WaitForIncomingMessageWithError) { |
| 345 internal::Connector connector0(std::move(handle0_), | 364 internal::Connector connector0(std::move(handle0_), |
| 346 internal::Connector::SINGLE_THREADED_SEND); | 365 internal::Connector::SINGLE_THREADED_SEND); |
| 347 // Close the other end of the pipe. | 366 // Close the other end of the pipe. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) { | 408 for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) { |
| 390 Message message; | 409 Message message; |
| 391 AllocMessage(kText[i], &message); | 410 AllocMessage(kText[i], &message); |
| 392 | 411 |
| 393 connector0.Accept(&message); | 412 connector0.Accept(&message); |
| 394 } | 413 } |
| 395 | 414 |
| 396 ReentrantMessageAccumulator accumulator(&connector1); | 415 ReentrantMessageAccumulator accumulator(&connector1); |
| 397 connector1.set_incoming_receiver(&accumulator); | 416 connector1.set_incoming_receiver(&accumulator); |
| 398 | 417 |
| 399 PumpMessages(); | |
| 400 | |
| 401 for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) { | 418 for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) { |
| 419 if (accumulator.IsEmpty()) { |
| 420 base::RunLoop run_loop; |
| 421 accumulator.set_closure(run_loop.QuitClosure()); |
| 422 run_loop.Run(); |
| 423 } |
| 402 ASSERT_FALSE(accumulator.IsEmpty()); | 424 ASSERT_FALSE(accumulator.IsEmpty()); |
| 403 | 425 |
| 404 Message message_received; | 426 Message message_received; |
| 405 accumulator.Pop(&message_received); | 427 accumulator.Pop(&message_received); |
| 406 | 428 |
| 407 EXPECT_EQ( | 429 EXPECT_EQ( |
| 408 std::string(kText[i]), | 430 std::string(kText[i]), |
| 409 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 431 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 410 } | 432 } |
| 411 | 433 |
| 412 ASSERT_EQ(2, accumulator.number_of_calls()); | 434 ASSERT_EQ(2, accumulator.number_of_calls()); |
| 413 } | 435 } |
| 414 | 436 |
| 415 TEST_F(ConnectorTest, RaiseError) { | 437 TEST_F(ConnectorTest, RaiseError) { |
| 438 base::RunLoop run_loop, run_loop2; |
| 416 internal::Connector connector0(std::move(handle0_), | 439 internal::Connector connector0(std::move(handle0_), |
| 417 internal::Connector::SINGLE_THREADED_SEND); | 440 internal::Connector::SINGLE_THREADED_SEND); |
| 418 bool error_handler_called0 = false; | 441 bool error_handler_called0 = false; |
| 419 connector0.set_connection_error_handler( | 442 connector0.set_connection_error_handler( |
| 420 [&error_handler_called0]() { error_handler_called0 = true; }); | 443 [&error_handler_called0, &run_loop]() { |
| 444 error_handler_called0 = true; |
| 445 run_loop.Quit(); |
| 446 }); |
| 421 | 447 |
| 422 internal::Connector connector1(std::move(handle1_), | 448 internal::Connector connector1(std::move(handle1_), |
| 423 internal::Connector::SINGLE_THREADED_SEND); | 449 internal::Connector::SINGLE_THREADED_SEND); |
| 424 bool error_handler_called1 = false; | 450 bool error_handler_called1 = false; |
| 425 connector1.set_connection_error_handler( | 451 connector1.set_connection_error_handler( |
| 426 [&error_handler_called1]() { error_handler_called1 = true; }); | 452 [&error_handler_called1, &run_loop2]() { |
| 453 error_handler_called1 = true; |
| 454 run_loop2.Quit(); |
| 455 }); |
| 427 | 456 |
| 428 const char kText[] = "hello world"; | 457 const char kText[] = "hello world"; |
| 429 | 458 |
| 430 Message message; | 459 Message message; |
| 431 AllocMessage(kText, &message); | 460 AllocMessage(kText, &message); |
| 432 | 461 |
| 433 connector0.Accept(&message); | 462 connector0.Accept(&message); |
| 434 connector0.RaiseError(); | 463 connector0.RaiseError(); |
| 435 | 464 |
| 436 MessageAccumulator accumulator; | 465 base::RunLoop run_loop3; |
| 466 MessageAccumulator accumulator(run_loop3.QuitClosure()); |
| 437 connector1.set_incoming_receiver(&accumulator); | 467 connector1.set_incoming_receiver(&accumulator); |
| 438 | 468 |
| 439 PumpMessages(); | 469 run_loop3.Run(); |
| 440 | 470 |
| 441 // Messages sent prior to RaiseError() still arrive at the other end. | 471 // Messages sent prior to RaiseError() still arrive at the other end. |
| 442 ASSERT_FALSE(accumulator.IsEmpty()); | 472 ASSERT_FALSE(accumulator.IsEmpty()); |
| 443 | 473 |
| 444 Message message_received; | 474 Message message_received; |
| 445 accumulator.Pop(&message_received); | 475 accumulator.Pop(&message_received); |
| 446 | 476 |
| 447 EXPECT_EQ( | 477 EXPECT_EQ( |
| 448 std::string(kText), | 478 std::string(kText), |
| 449 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 479 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 450 | 480 |
| 451 PumpMessages(); | 481 run_loop.Run(); |
| 482 run_loop2.Run(); |
| 452 | 483 |
| 453 // Connection error handler is called at both sides. | 484 // Connection error handler is called at both sides. |
| 454 EXPECT_TRUE(error_handler_called0); | 485 EXPECT_TRUE(error_handler_called0); |
| 455 EXPECT_TRUE(error_handler_called1); | 486 EXPECT_TRUE(error_handler_called1); |
| 456 | 487 |
| 457 // The error flag is set at both sides. | 488 // The error flag is set at both sides. |
| 458 EXPECT_TRUE(connector0.encountered_error()); | 489 EXPECT_TRUE(connector0.encountered_error()); |
| 459 EXPECT_TRUE(connector1.encountered_error()); | 490 EXPECT_TRUE(connector1.encountered_error()); |
| 460 | 491 |
| 461 // The message pipe handle is valid at both sides. | 492 // The message pipe handle is valid at both sides. |
| 462 EXPECT_TRUE(connector0.is_valid()); | 493 EXPECT_TRUE(connector0.is_valid()); |
| 463 EXPECT_TRUE(connector1.is_valid()); | 494 EXPECT_TRUE(connector1.is_valid()); |
| 464 } | 495 } |
| 465 | 496 |
| 466 } // namespace | 497 } // namespace |
| 467 } // namespace test | 498 } // namespace test |
| 468 } // namespace mojo | 499 } // namespace mojo |
| OLD | NEW |