Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Unified Diff: mojo/public/cpp/bindings/tests/sync_method_unittest.cc

Issue 1781573004: Mojo C++ bindings: error notification behavior related to sync calls. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/public/cpp/bindings/lib/router.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/public/cpp/bindings/tests/sync_method_unittest.cc
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
index 207a6e2bd6843def5589bb21e9e6eec44576ee43..f1a47674f5c5baa13afd86c0c1f42fb17d74bfe2 100644
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
@@ -345,6 +345,120 @@ TEST_F(SyncMethodTest, AsyncRequestQueuedDuringSyncCall) {
EXPECT_TRUE(async_echo_response_dispatched);
}
+TEST_F(SyncMethodTest, QueuedMessagesProcessedBeforeErrorNotification) {
+ // Test that while an interface pointer is waiting for the response to a sync
+ // call, async responses are queued. If the message pipe is disconnected
+ // before the queued messages are processed, the connection error
+ // notification is delayed until all the queued messages are processed.
+
+ TestSyncPtr ptr;
+ TestSyncImpl impl(GetProxy(&ptr));
+
+ int32_t async_echo_request_value = -1;
+ TestSync::AsyncEchoCallback async_echo_request_callback;
+ base::RunLoop run_loop1;
+ impl.set_async_echo_handler(
+ [&async_echo_request_value, &async_echo_request_callback, &run_loop1](
+ int32_t value, const TestSync::AsyncEchoCallback& callback) {
+ async_echo_request_value = value;
+ async_echo_request_callback = callback;
+ run_loop1.Quit();
+ });
+
+ bool async_echo_response_dispatched = false;
+ base::RunLoop run_loop2;
+ ptr->AsyncEcho(123,
+ [&async_echo_response_dispatched, &run_loop2](int32_t result) {
+ async_echo_response_dispatched = true;
+ EXPECT_EQ(123, result);
+ run_loop2.Quit();
+ });
+ // Run until the AsyncEcho request reaches the service side.
+ run_loop1.Run();
+
+ impl.set_echo_handler(
+ [&impl, &async_echo_request_value, &async_echo_request_callback](
+ int32_t value, const TestSync::EchoCallback& callback) {
+ // Send back the async response first.
+ EXPECT_FALSE(async_echo_request_callback.is_null());
+ async_echo_request_callback.Run(async_echo_request_value);
+
+ impl.binding()->Close();
+ });
+
+ bool connection_error_dispatched = false;
+ base::RunLoop run_loop3;
+ ptr.set_connection_error_handler(
+ [&connection_error_dispatched, &run_loop3]() {
+ connection_error_dispatched = true;
+ run_loop3.Quit();
+ });
+
+ int32_t result_value = -1;
+ ASSERT_FALSE(ptr->Echo(456, &result_value));
+ EXPECT_EQ(-1, result_value);
+ ASSERT_FALSE(connection_error_dispatched);
+ EXPECT_FALSE(ptr.encountered_error());
+
+ // Although the AsyncEcho response arrives before the Echo response, it should
+ // be queued and not yet dispatched.
+ EXPECT_FALSE(async_echo_response_dispatched);
+
+ // Run until the AsyncEcho response is dispatched.
+ run_loop2.Run();
+
+ EXPECT_TRUE(async_echo_response_dispatched);
+ ASSERT_FALSE(connection_error_dispatched);
+ EXPECT_FALSE(ptr.encountered_error());
+
+ // Run until the error notification is dispatched.
+ run_loop3.Run();
+
+ ASSERT_TRUE(connection_error_dispatched);
+ EXPECT_TRUE(ptr.encountered_error());
+}
+
+TEST_F(SyncMethodTest, InvalidMessageDuringSyncCall) {
+ // Test that while an interface pointer is waiting for the response to a sync
+ // call, an invalid incoming message will disconnect the message pipe, cause
+ // the sync call to return false, and run the connection error handler
+ // asynchronously.
+
+ MessagePipe pipe;
+
+ TestSyncPtr ptr;
+ ptr.Bind(TestSyncPtrInfo(std::move(pipe.handle0), 0u));
+
+ MessagePipeHandle raw_binding_handle = pipe.handle1.get();
+ TestSyncImpl impl(MakeRequest<TestSync>(std::move(pipe.handle1)));
+
+ impl.set_echo_handler([&raw_binding_handle](
+ int32_t value, const TestSync::EchoCallback& callback) {
+ // Write a 1-byte message, which is considered invalid.
+ char invalid_message = 0;
+ MojoResult result =
+ WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u,
+ MOJO_WRITE_MESSAGE_FLAG_NONE);
+ ASSERT_EQ(MOJO_RESULT_OK, result);
+ callback.Run(value);
+ });
+
+ bool connection_error_dispatched = false;
+ base::RunLoop run_loop;
+ ptr.set_connection_error_handler([&connection_error_dispatched, &run_loop]() {
+ connection_error_dispatched = true;
+ run_loop.Quit();
+ });
+
+ int32_t result_value = -1;
+ ASSERT_FALSE(ptr->Echo(456, &result_value));
+ EXPECT_EQ(-1, result_value);
+ ASSERT_FALSE(connection_error_dispatched);
+
+ run_loop.Run();
+ ASSERT_TRUE(connection_error_dispatched);
+}
+
} // namespace
} // namespace test
} // namespace mojo
« no previous file with comments | « mojo/public/cpp/bindings/lib/router.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698