| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/logging.h" | 6 #include "base/logging.h" |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
| 11 #include "mojo/message_pump/message_pump_mojo.h" | 11 #include "mojo/message_pump/message_pump_mojo.h" |
| 12 #include "mojo/public/cpp/bindings/binding.h" | 12 #include "mojo/public/cpp/bindings/binding.h" |
| 13 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" | 13 #include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 15 |
| 16 namespace mojo { | 16 namespace mojo { |
| 17 namespace test { | 17 namespace test { |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 class SyncMethodTest : public testing::Test { | 20 class TestSyncCommonImpl { |
| 21 public: | 21 public: |
| 22 SyncMethodTest() : loop_(common::MessagePumpMojo::Create()) {} | 22 TestSyncCommonImpl() {} |
| 23 ~SyncMethodTest() override { loop_.RunUntilIdle(); } | |
| 24 | 23 |
| 25 private: | 24 using PingHandler = Callback<void(const Callback<void()>&)>; |
| 26 base::MessageLoop loop_; | |
| 27 }; | |
| 28 | |
| 29 class TestSyncImpl : public TestSync { | |
| 30 public: | |
| 31 TestSyncImpl(TestSyncRequest request) : binding_(this, std::move(request)) {} | |
| 32 | |
| 33 using PingHandler = Callback<void(const PingCallback&)>; | |
| 34 void set_ping_handler(const PingHandler& handler) { ping_handler_ = handler; } | 25 void set_ping_handler(const PingHandler& handler) { ping_handler_ = handler; } |
| 35 | 26 |
| 36 using EchoHandler = Callback<void(int32_t, const EchoCallback&)>; | 27 using EchoHandler = Callback<void(int32_t, const Callback<void(int32_t)>&)>; |
| 37 void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; } | 28 void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; } |
| 38 | 29 |
| 39 using AsyncEchoHandler = Callback<void(int32_t, const AsyncEchoCallback&)>; | 30 using AsyncEchoHandler = |
| 31 Callback<void(int32_t, const Callback<void(int32_t)>&)>; |
| 40 void set_async_echo_handler(const AsyncEchoHandler& handler) { | 32 void set_async_echo_handler(const AsyncEchoHandler& handler) { |
| 41 async_echo_handler_ = handler; | 33 async_echo_handler_ = handler; |
| 42 } | 34 } |
| 43 | 35 |
| 44 // TestSync implementation: | 36 void PingImpl(const Callback<void()>& callback) { |
| 45 void Ping(const PingCallback& callback) override { | |
| 46 if (ping_handler_.is_null()) { | 37 if (ping_handler_.is_null()) { |
| 47 callback.Run(); | 38 callback.Run(); |
| 48 return; | 39 return; |
| 49 } | 40 } |
| 50 ping_handler_.Run(callback); | 41 ping_handler_.Run(callback); |
| 51 } | 42 } |
| 52 void Echo(int32_t value, const EchoCallback& callback) override { | 43 void EchoImpl(int32_t value, const Callback<void(int32_t)>& callback) { |
| 53 if (echo_handler_.is_null()) { | 44 if (echo_handler_.is_null()) { |
| 54 callback.Run(value); | 45 callback.Run(value); |
| 55 return; | 46 return; |
| 56 } | 47 } |
| 57 echo_handler_.Run(value, callback); | 48 echo_handler_.Run(value, callback); |
| 58 } | 49 } |
| 59 void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override { | 50 void AsyncEchoImpl(int32_t value, const Callback<void(int32_t)>& callback) { |
| 60 if (async_echo_handler_.is_null()) { | 51 if (async_echo_handler_.is_null()) { |
| 61 callback.Run(value); | 52 callback.Run(value); |
| 62 return; | 53 return; |
| 63 } | 54 } |
| 64 async_echo_handler_.Run(value, callback); | 55 async_echo_handler_.Run(value, callback); |
| 65 } | 56 } |
| 66 | 57 |
| 58 private: |
| 59 PingHandler ping_handler_; |
| 60 EchoHandler echo_handler_; |
| 61 AsyncEchoHandler async_echo_handler_; |
| 62 |
| 63 DISALLOW_COPY_AND_ASSIGN(TestSyncCommonImpl); |
| 64 }; |
| 65 |
| 66 class TestSyncImpl : public TestSync, public TestSyncCommonImpl { |
| 67 public: |
| 68 explicit TestSyncImpl(TestSyncRequest request) |
| 69 : binding_(this, std::move(request)) {} |
| 70 |
| 71 // TestSync implementation: |
| 72 void Ping(const PingCallback& callback) override { PingImpl(callback); } |
| 73 void Echo(int32_t value, const EchoCallback& callback) override { |
| 74 EchoImpl(value, callback); |
| 75 } |
| 76 void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override { |
| 77 AsyncEchoImpl(value, callback); |
| 78 } |
| 79 |
| 67 Binding<TestSync>* binding() { return &binding_; } | 80 Binding<TestSync>* binding() { return &binding_; } |
| 68 | 81 |
| 69 private: | 82 private: |
| 70 Binding<TestSync> binding_; | 83 Binding<TestSync> binding_; |
| 71 PingHandler ping_handler_; | |
| 72 EchoHandler echo_handler_; | |
| 73 AsyncEchoHandler async_echo_handler_; | |
| 74 | 84 |
| 75 DISALLOW_COPY_AND_ASSIGN(TestSyncImpl); | 85 DISALLOW_COPY_AND_ASSIGN(TestSyncImpl); |
| 76 }; | 86 }; |
| 77 | 87 |
| 88 template <typename Interface> |
| 89 struct ImplTraits; |
| 90 |
| 91 template <> |
| 92 struct ImplTraits<TestSync> { |
| 93 using Type = TestSyncImpl; |
| 94 }; |
| 95 |
| 96 template <typename Interface> |
| 78 class TestSyncServiceThread { | 97 class TestSyncServiceThread { |
| 79 public: | 98 public: |
| 80 TestSyncServiceThread() | 99 TestSyncServiceThread() |
| 81 : thread_("TestSyncServiceThread"), ping_called_(false) { | 100 : thread_("TestSyncServiceThread"), ping_called_(false) { |
| 82 base::Thread::Options thread_options; | 101 base::Thread::Options thread_options; |
| 83 thread_options.message_pump_factory = | 102 thread_options.message_pump_factory = |
| 84 base::Bind(&common::MessagePumpMojo::Create); | 103 base::Bind(&common::MessagePumpMojo::Create); |
| 85 thread_.StartWithOptions(thread_options); | 104 thread_.StartWithOptions(thread_options); |
| 86 } | 105 } |
| 87 | 106 |
| 88 void SetUp(TestSyncRequest request) { | 107 void SetUp(InterfaceRequest<Interface> request) { |
| 89 CHECK(thread_.task_runner()->BelongsToCurrentThread()); | 108 CHECK(thread_.task_runner()->BelongsToCurrentThread()); |
| 90 impl_.reset(new TestSyncImpl(std::move(request))); | 109 impl_.reset(new typename ImplTraits<Interface>::Type(std::move(request))); |
| 91 impl_->set_ping_handler([this](const TestSync::PingCallback& callback) { | 110 impl_->set_ping_handler( |
| 92 { | 111 [this](const typename Interface::PingCallback& callback) { |
| 93 base::AutoLock locker(lock_); | 112 { |
| 94 ping_called_ = true; | 113 base::AutoLock locker(lock_); |
| 95 } | 114 ping_called_ = true; |
| 96 callback.Run(); | 115 } |
| 97 }); | 116 callback.Run(); |
| 117 }); |
| 98 } | 118 } |
| 99 | 119 |
| 100 void TearDown() { | 120 void TearDown() { |
| 101 CHECK(thread_.task_runner()->BelongsToCurrentThread()); | 121 CHECK(thread_.task_runner()->BelongsToCurrentThread()); |
| 102 impl_.reset(); | 122 impl_.reset(); |
| 103 } | 123 } |
| 104 | 124 |
| 105 base::Thread* thread() { return &thread_; } | 125 base::Thread* thread() { return &thread_; } |
| 106 bool ping_called() const { | 126 bool ping_called() const { |
| 107 base::AutoLock locker(lock_); | 127 base::AutoLock locker(lock_); |
| 108 return ping_called_; | 128 return ping_called_; |
| 109 } | 129 } |
| 110 | 130 |
| 111 private: | 131 private: |
| 112 base::Thread thread_; | 132 base::Thread thread_; |
| 113 | 133 |
| 114 scoped_ptr<TestSyncImpl> impl_; | 134 scoped_ptr<typename ImplTraits<Interface>::Type> impl_; |
| 115 | 135 |
| 116 mutable base::Lock lock_; | 136 mutable base::Lock lock_; |
| 117 bool ping_called_; | 137 bool ping_called_; |
| 118 | 138 |
| 119 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); | 139 DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); |
| 120 }; | 140 }; |
| 121 | 141 |
| 122 TEST_F(SyncMethodTest, CallSyncMethodAsynchronously) { | 142 template <typename T> |
| 123 TestSyncPtr ptr; | 143 class SyncMethodCommonTest : public testing::Test { |
| 124 TestSyncImpl impl(GetProxy(&ptr)); | 144 public: |
| 145 SyncMethodCommonTest() : loop_(common::MessagePumpMojo::Create()) {} |
| 146 ~SyncMethodCommonTest() override { loop_.RunUntilIdle(); } |
| 147 |
| 148 private: |
| 149 base::MessageLoop loop_; |
| 150 }; |
| 151 |
| 152 using InterfaceTypes = testing::Types<TestSync>; |
| 153 TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); |
| 154 |
| 155 TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { |
| 156 InterfacePtr<TypeParam> ptr; |
| 157 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
| 125 | 158 |
| 126 base::RunLoop run_loop; | 159 base::RunLoop run_loop; |
| 127 ptr->Echo(123, [&run_loop](int32_t result) { | 160 ptr->Echo(123, [&run_loop](int32_t result) { |
| 128 EXPECT_EQ(123, result); | 161 EXPECT_EQ(123, result); |
| 129 run_loop.Quit(); | 162 run_loop.Quit(); |
| 130 }); | 163 }); |
| 131 run_loop.Run(); | 164 run_loop.Run(); |
| 132 } | 165 } |
| 133 | 166 |
| 134 TEST_F(SyncMethodTest, BasicSyncCalls) { | 167 TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { |
| 135 TestSyncPtr ptr; | 168 InterfacePtr<TypeParam> ptr; |
| 136 | 169 |
| 137 TestSyncServiceThread service_thread; | 170 TestSyncServiceThread<TypeParam> service_thread; |
| 138 service_thread.thread()->task_runner()->PostTask( | 171 service_thread.thread()->task_runner()->PostTask( |
| 139 FROM_HERE, base::Bind(&TestSyncServiceThread::SetUp, | 172 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp, |
| 140 base::Unretained(&service_thread), | 173 base::Unretained(&service_thread), |
| 141 base::Passed(GetProxy(&ptr)))); | 174 base::Passed(GetProxy(&ptr)))); |
| 142 ASSERT_TRUE(ptr->Ping()); | 175 ASSERT_TRUE(ptr->Ping()); |
| 143 ASSERT_TRUE(service_thread.ping_called()); | 176 ASSERT_TRUE(service_thread.ping_called()); |
| 144 | 177 |
| 145 int32_t output_value = -1; | 178 int32_t output_value = -1; |
| 146 ASSERT_TRUE(ptr->Echo(42, &output_value)); | 179 ASSERT_TRUE(ptr->Echo(42, &output_value)); |
| 147 ASSERT_EQ(42, output_value); | 180 ASSERT_EQ(42, output_value); |
| 148 | 181 |
| 149 base::RunLoop run_loop; | 182 base::RunLoop run_loop; |
| 150 service_thread.thread()->task_runner()->PostTaskAndReply( | 183 service_thread.thread()->task_runner()->PostTaskAndReply( |
| 151 FROM_HERE, base::Bind(&TestSyncServiceThread::TearDown, | 184 FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::TearDown, |
| 152 base::Unretained(&service_thread)), | 185 base::Unretained(&service_thread)), |
| 153 run_loop.QuitClosure()); | 186 run_loop.QuitClosure()); |
| 154 run_loop.Run(); | 187 run_loop.Run(); |
| 155 } | 188 } |
| 156 | 189 |
| 157 TEST_F(SyncMethodTest, ReenteredBySyncMethodBinding) { | 190 TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) { |
| 158 // Test that an interface pointer waiting for a sync call response can be | 191 // Test that an interface pointer waiting for a sync call response can be |
| 159 // reentered by a binding serving sync methods on the same thread. | 192 // reentered by a binding serving sync methods on the same thread. |
| 160 | 193 |
| 161 TestSyncPtr ptr; | 194 InterfacePtr<TypeParam> ptr; |
| 162 // The binding lives on the same thread as the interface pointer. | 195 // The binding lives on the same thread as the interface pointer. |
| 163 TestSyncImpl impl(GetProxy(&ptr)); | 196 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
| 164 int32_t output_value = -1; | 197 int32_t output_value = -1; |
| 165 ASSERT_TRUE(ptr->Echo(42, &output_value)); | 198 ASSERT_TRUE(ptr->Echo(42, &output_value)); |
| 166 EXPECT_EQ(42, output_value); | 199 EXPECT_EQ(42, output_value); |
| 167 } | 200 } |
| 168 | 201 |
| 169 TEST_F(SyncMethodTest, InterefacePtrDestroyedDuringSyncCall) { | 202 TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) { |
| 170 // Test that it won't result in crash or hang if an interface pointer is | 203 // Test that it won't result in crash or hang if an interface pointer is |
| 171 // destroyed while it is waiting for a sync call response. | 204 // destroyed while it is waiting for a sync call response. |
| 172 | 205 |
| 173 TestSyncPtr ptr; | 206 InterfacePtr<TypeParam> ptr; |
| 174 TestSyncImpl impl(GetProxy(&ptr)); | 207 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
| 175 impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) { | 208 impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) { |
| 176 ptr.reset(); | 209 ptr.reset(); |
| 177 callback.Run(); | 210 callback.Run(); |
| 178 }); | 211 }); |
| 179 ASSERT_FALSE(ptr->Ping()); | 212 ASSERT_FALSE(ptr->Ping()); |
| 180 } | 213 } |
| 181 | 214 |
| 182 TEST_F(SyncMethodTest, BindingDestroyedDuringSyncCall) { | 215 TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) { |
| 183 // Test that it won't result in crash or hang if a binding is | 216 // Test that it won't result in crash or hang if a binding is |
| 184 // closed (and therefore the message pipe handle is closed) while the | 217 // closed (and therefore the message pipe handle is closed) while the |
| 185 // corresponding interface pointer is waiting for a sync call response. | 218 // corresponding interface pointer is waiting for a sync call response. |
| 186 | 219 |
| 187 TestSyncPtr ptr; | 220 InterfacePtr<TypeParam> ptr; |
| 188 TestSyncImpl impl(GetProxy(&ptr)); | 221 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
| 189 impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) { | 222 impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) { |
| 190 impl.binding()->Close(); | 223 impl.binding()->Close(); |
| 191 callback.Run(); | 224 callback.Run(); |
| 192 }); | 225 }); |
| 193 ASSERT_FALSE(ptr->Ping()); | 226 ASSERT_FALSE(ptr->Ping()); |
| 194 } | 227 } |
| 195 | 228 |
| 196 TEST_F(SyncMethodTest, NestedSyncCallsWithInOrderResponses) { | 229 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) { |
| 197 // Test that we can call a sync method on an interface ptr, while there is | 230 // Test that we can call a sync method on an interface ptr, while there is |
| 198 // already a sync call ongoing. The responses arrive in order. | 231 // already a sync call ongoing. The responses arrive in order. |
| 199 | 232 |
| 200 TestSyncPtr ptr; | 233 InterfacePtr<TypeParam> ptr; |
| 201 TestSyncImpl impl(GetProxy(&ptr)); | 234 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
| 202 | 235 |
| 203 // The same variable is used to store the output of the two sync calls, in | 236 // The same variable is used to store the output of the two sync calls, in |
| 204 // order to test that responses are handled in the correct order. | 237 // order to test that responses are handled in the correct order. |
| 205 int32_t result_value = -1; | 238 int32_t result_value = -1; |
| 206 | 239 |
| 207 bool first_call = true; | 240 bool first_call = true; |
| 208 impl.set_echo_handler([&first_call, &ptr, &result_value]( | 241 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
| 209 int32_t value, const TestSync::EchoCallback& callback) { | 242 int32_t value, const TestSync::EchoCallback& callback) { |
| 210 if (first_call) { | 243 if (first_call) { |
| 211 first_call = false; | 244 first_call = false; |
| 212 ASSERT_TRUE(ptr->Echo(456, &result_value)); | 245 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
| 213 EXPECT_EQ(456, result_value); | 246 EXPECT_EQ(456, result_value); |
| 214 } | 247 } |
| 215 callback.Run(value); | 248 callback.Run(value); |
| 216 }); | 249 }); |
| 217 | 250 |
| 218 ASSERT_TRUE(ptr->Echo(123, &result_value)); | 251 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
| 219 EXPECT_EQ(123, result_value); | 252 EXPECT_EQ(123, result_value); |
| 220 } | 253 } |
| 221 | 254 |
| 222 TEST_F(SyncMethodTest, NestedSyncCallsWithOutOfOrderResponses) { | 255 TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) { |
| 223 // Test that we can call a sync method on an interface ptr, while there is | 256 // Test that we can call a sync method on an interface ptr, while there is |
| 224 // already a sync call ongoing. The responses arrive out of order. | 257 // already a sync call ongoing. The responses arrive out of order. |
| 225 | 258 |
| 226 TestSyncPtr ptr; | 259 InterfacePtr<TypeParam> ptr; |
| 227 TestSyncImpl impl(GetProxy(&ptr)); | 260 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
| 228 | 261 |
| 229 // The same variable is used to store the output of the two sync calls, in | 262 // The same variable is used to store the output of the two sync calls, in |
| 230 // order to test that responses are handled in the correct order. | 263 // order to test that responses are handled in the correct order. |
| 231 int32_t result_value = -1; | 264 int32_t result_value = -1; |
| 232 | 265 |
| 233 bool first_call = true; | 266 bool first_call = true; |
| 234 impl.set_echo_handler([&first_call, &ptr, &result_value]( | 267 impl.set_echo_handler([&first_call, &ptr, &result_value]( |
| 235 int32_t value, const TestSync::EchoCallback& callback) { | 268 int32_t value, const TestSync::EchoCallback& callback) { |
| 236 callback.Run(value); | 269 callback.Run(value); |
| 237 if (first_call) { | 270 if (first_call) { |
| 238 first_call = false; | 271 first_call = false; |
| 239 ASSERT_TRUE(ptr->Echo(456, &result_value)); | 272 ASSERT_TRUE(ptr->Echo(456, &result_value)); |
| 240 EXPECT_EQ(456, result_value); | 273 EXPECT_EQ(456, result_value); |
| 241 } | 274 } |
| 242 }); | 275 }); |
| 243 | 276 |
| 244 ASSERT_TRUE(ptr->Echo(123, &result_value)); | 277 ASSERT_TRUE(ptr->Echo(123, &result_value)); |
| 245 EXPECT_EQ(123, result_value); | 278 EXPECT_EQ(123, result_value); |
| 246 } | 279 } |
| 247 | 280 |
| 248 TEST_F(SyncMethodTest, AsyncResponseQueuedDuringSyncCall) { | 281 TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) { |
| 249 // Test that while an interface pointer is waiting for the response to a sync | 282 // Test that while an interface pointer is waiting for the response to a sync |
| 250 // call, async responses are queued until the sync call completes. | 283 // call, async responses are queued until the sync call completes. |
| 251 | 284 |
| 252 TestSyncPtr ptr; | 285 InterfacePtr<TypeParam> ptr; |
| 253 TestSyncImpl impl(GetProxy(&ptr)); | 286 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
| 254 | 287 |
| 255 int32_t async_echo_request_value = -1; | 288 int32_t async_echo_request_value = -1; |
| 256 TestSync::AsyncEchoCallback async_echo_request_callback; | 289 TestSync::AsyncEchoCallback async_echo_request_callback; |
| 257 base::RunLoop run_loop1; | 290 base::RunLoop run_loop1; |
| 258 impl.set_async_echo_handler( | 291 impl.set_async_echo_handler( |
| 259 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( | 292 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( |
| 260 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 293 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
| 261 async_echo_request_value = value; | 294 async_echo_request_value = value; |
| 262 async_echo_request_callback = callback; | 295 async_echo_request_callback = callback; |
| 263 run_loop1.Quit(); | 296 run_loop1.Quit(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 291 // Although the AsyncEcho response arrives before the Echo response, it should | 324 // Although the AsyncEcho response arrives before the Echo response, it should |
| 292 // be queued and not yet dispatched. | 325 // be queued and not yet dispatched. |
| 293 EXPECT_FALSE(async_echo_response_dispatched); | 326 EXPECT_FALSE(async_echo_response_dispatched); |
| 294 | 327 |
| 295 // Run until the AsyncEcho response is dispatched. | 328 // Run until the AsyncEcho response is dispatched. |
| 296 run_loop2.Run(); | 329 run_loop2.Run(); |
| 297 | 330 |
| 298 EXPECT_TRUE(async_echo_response_dispatched); | 331 EXPECT_TRUE(async_echo_response_dispatched); |
| 299 } | 332 } |
| 300 | 333 |
| 301 TEST_F(SyncMethodTest, AsyncRequestQueuedDuringSyncCall) { | 334 TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) { |
| 302 // Test that while an interface pointer is waiting for the response to a sync | 335 // Test that while an interface pointer is waiting for the response to a sync |
| 303 // call, async requests for a binding running on the same thread are queued | 336 // call, async requests for a binding running on the same thread are queued |
| 304 // until the sync call completes. | 337 // until the sync call completes. |
| 305 | 338 |
| 306 TestSyncPtr ptr; | 339 InterfacePtr<TypeParam> ptr; |
| 307 TestSyncImpl impl(GetProxy(&ptr)); | 340 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
| 308 | 341 |
| 309 bool async_echo_request_dispatched = false; | 342 bool async_echo_request_dispatched = false; |
| 310 impl.set_async_echo_handler([&async_echo_request_dispatched]( | 343 impl.set_async_echo_handler([&async_echo_request_dispatched]( |
| 311 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 344 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
| 312 async_echo_request_dispatched = true; | 345 async_echo_request_dispatched = true; |
| 313 callback.Run(value); | 346 callback.Run(value); |
| 314 }); | 347 }); |
| 315 | 348 |
| 316 bool async_echo_response_dispatched = false; | 349 bool async_echo_response_dispatched = false; |
| 317 base::RunLoop run_loop; | 350 base::RunLoop run_loop; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 338 // Although the AsyncEcho request is sent before the Echo request, it | 371 // Although the AsyncEcho request is sent before the Echo request, it |
| 339 // shouldn't be dispatched yet. | 372 // shouldn't be dispatched yet. |
| 340 EXPECT_FALSE(async_echo_request_dispatched); | 373 EXPECT_FALSE(async_echo_request_dispatched); |
| 341 | 374 |
| 342 // Run until the AsyncEcho response is dispatched. | 375 // Run until the AsyncEcho response is dispatched. |
| 343 run_loop.Run(); | 376 run_loop.Run(); |
| 344 | 377 |
| 345 EXPECT_TRUE(async_echo_response_dispatched); | 378 EXPECT_TRUE(async_echo_response_dispatched); |
| 346 } | 379 } |
| 347 | 380 |
| 348 TEST_F(SyncMethodTest, QueuedMessagesProcessedBeforeErrorNotification) { | 381 TYPED_TEST(SyncMethodCommonTest, |
| 382 QueuedMessagesProcessedBeforeErrorNotification) { |
| 349 // Test that while an interface pointer is waiting for the response to a sync | 383 // Test that while an interface pointer is waiting for the response to a sync |
| 350 // call, async responses are queued. If the message pipe is disconnected | 384 // call, async responses are queued. If the message pipe is disconnected |
| 351 // before the queued messages are processed, the connection error | 385 // before the queued messages are processed, the connection error |
| 352 // notification is delayed until all the queued messages are processed. | 386 // notification is delayed until all the queued messages are processed. |
| 353 | 387 |
| 354 TestSyncPtr ptr; | 388 InterfacePtr<TypeParam> ptr; |
| 355 TestSyncImpl impl(GetProxy(&ptr)); | 389 typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr)); |
| 356 | 390 |
| 357 int32_t async_echo_request_value = -1; | 391 int32_t async_echo_request_value = -1; |
| 358 TestSync::AsyncEchoCallback async_echo_request_callback; | 392 TestSync::AsyncEchoCallback async_echo_request_callback; |
| 359 base::RunLoop run_loop1; | 393 base::RunLoop run_loop1; |
| 360 impl.set_async_echo_handler( | 394 impl.set_async_echo_handler( |
| 361 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( | 395 [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( |
| 362 int32_t value, const TestSync::AsyncEchoCallback& callback) { | 396 int32_t value, const TestSync::AsyncEchoCallback& callback) { |
| 363 async_echo_request_value = value; | 397 async_echo_request_value = value; |
| 364 async_echo_request_callback = callback; | 398 async_echo_request_callback = callback; |
| 365 run_loop1.Quit(); | 399 run_loop1.Quit(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 | 448 |
| 415 EXPECT_TRUE(async_echo_response_dispatched); | 449 EXPECT_TRUE(async_echo_response_dispatched); |
| 416 | 450 |
| 417 // Run until the error notification is dispatched. | 451 // Run until the error notification is dispatched. |
| 418 run_loop3.Run(); | 452 run_loop3.Run(); |
| 419 | 453 |
| 420 ASSERT_TRUE(connection_error_dispatched); | 454 ASSERT_TRUE(connection_error_dispatched); |
| 421 EXPECT_TRUE(ptr.encountered_error()); | 455 EXPECT_TRUE(ptr.encountered_error()); |
| 422 } | 456 } |
| 423 | 457 |
| 424 TEST_F(SyncMethodTest, InvalidMessageDuringSyncCall) { | 458 TYPED_TEST(SyncMethodCommonTest, InvalidMessageDuringSyncCall) { |
| 425 // Test that while an interface pointer is waiting for the response to a sync | 459 // Test that while an interface pointer is waiting for the response to a sync |
| 426 // call, an invalid incoming message will disconnect the message pipe, cause | 460 // call, an invalid incoming message will disconnect the message pipe, cause |
| 427 // the sync call to return false, and run the connection error handler | 461 // the sync call to return false, and run the connection error handler |
| 428 // asynchronously. | 462 // asynchronously. |
| 429 | 463 |
| 430 MessagePipe pipe; | 464 MessagePipe pipe; |
| 431 | 465 |
| 432 TestSyncPtr ptr; | 466 InterfacePtr<TypeParam> ptr; |
| 433 ptr.Bind(TestSyncPtrInfo(std::move(pipe.handle0), 0u)); | 467 ptr.Bind(InterfacePtrInfo<TypeParam>(std::move(pipe.handle0), 0u)); |
| 434 | 468 |
| 435 MessagePipeHandle raw_binding_handle = pipe.handle1.get(); | 469 MessagePipeHandle raw_binding_handle = pipe.handle1.get(); |
| 436 TestSyncImpl impl(MakeRequest<TestSync>(std::move(pipe.handle1))); | 470 typename ImplTraits<TypeParam>::Type impl( |
| 471 MakeRequest<TypeParam>(std::move(pipe.handle1))); |
| 437 | 472 |
| 438 impl.set_echo_handler([&raw_binding_handle]( | 473 impl.set_echo_handler([&raw_binding_handle]( |
| 439 int32_t value, const TestSync::EchoCallback& callback) { | 474 int32_t value, const TestSync::EchoCallback& callback) { |
| 440 // Write a 1-byte message, which is considered invalid. | 475 // Write a 1-byte message, which is considered invalid. |
| 441 char invalid_message = 0; | 476 char invalid_message = 0; |
| 442 MojoResult result = | 477 MojoResult result = |
| 443 WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, | 478 WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, |
| 444 MOJO_WRITE_MESSAGE_FLAG_NONE); | 479 MOJO_WRITE_MESSAGE_FLAG_NONE); |
| 445 ASSERT_EQ(MOJO_RESULT_OK, result); | 480 ASSERT_EQ(MOJO_RESULT_OK, result); |
| 446 callback.Run(value); | 481 callback.Run(value); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 458 EXPECT_EQ(-1, result_value); | 493 EXPECT_EQ(-1, result_value); |
| 459 ASSERT_FALSE(connection_error_dispatched); | 494 ASSERT_FALSE(connection_error_dispatched); |
| 460 | 495 |
| 461 run_loop.Run(); | 496 run_loop.Run(); |
| 462 ASSERT_TRUE(connection_error_dispatched); | 497 ASSERT_TRUE(connection_error_dispatched); |
| 463 } | 498 } |
| 464 | 499 |
| 465 } // namespace | 500 } // namespace |
| 466 } // namespace test | 501 } // namespace test |
| 467 } // namespace mojo | 502 } // namespace mojo |
| OLD | NEW |