| 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 f64ba2da0f93a865fe9daabef4f89ed2e1d4d722..3d212051b82b3edaa7dd3c10e573ad32056ff45e 100644
|
| --- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
|
| +++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
|
| @@ -17,46 +17,37 @@ namespace mojo {
|
| namespace test {
|
| namespace {
|
|
|
| -class SyncMethodTest : public testing::Test {
|
| +class TestSyncCommonImpl {
|
| public:
|
| - SyncMethodTest() : loop_(common::MessagePumpMojo::Create()) {}
|
| - ~SyncMethodTest() override { loop_.RunUntilIdle(); }
|
| + TestSyncCommonImpl() {}
|
|
|
| - private:
|
| - base::MessageLoop loop_;
|
| -};
|
| -
|
| -class TestSyncImpl : public TestSync {
|
| - public:
|
| - TestSyncImpl(TestSyncRequest request) : binding_(this, std::move(request)) {}
|
| -
|
| - using PingHandler = Callback<void(const PingCallback&)>;
|
| + using PingHandler = Callback<void(const Callback<void()>&)>;
|
| void set_ping_handler(const PingHandler& handler) { ping_handler_ = handler; }
|
|
|
| - using EchoHandler = Callback<void(int32_t, const EchoCallback&)>;
|
| + using EchoHandler = Callback<void(int32_t, const Callback<void(int32_t)>&)>;
|
| void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; }
|
|
|
| - using AsyncEchoHandler = Callback<void(int32_t, const AsyncEchoCallback&)>;
|
| + using AsyncEchoHandler =
|
| + Callback<void(int32_t, const Callback<void(int32_t)>&)>;
|
| void set_async_echo_handler(const AsyncEchoHandler& handler) {
|
| async_echo_handler_ = handler;
|
| }
|
|
|
| - // TestSync implementation:
|
| - void Ping(const PingCallback& callback) override {
|
| + void PingImpl(const Callback<void()>& callback) {
|
| if (ping_handler_.is_null()) {
|
| callback.Run();
|
| return;
|
| }
|
| ping_handler_.Run(callback);
|
| }
|
| - void Echo(int32_t value, const EchoCallback& callback) override {
|
| + void EchoImpl(int32_t value, const Callback<void(int32_t)>& callback) {
|
| if (echo_handler_.is_null()) {
|
| callback.Run(value);
|
| return;
|
| }
|
| echo_handler_.Run(value, callback);
|
| }
|
| - void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override {
|
| + void AsyncEchoImpl(int32_t value, const Callback<void(int32_t)>& callback) {
|
| if (async_echo_handler_.is_null()) {
|
| callback.Run(value);
|
| return;
|
| @@ -64,17 +55,45 @@ class TestSyncImpl : public TestSync {
|
| async_echo_handler_.Run(value, callback);
|
| }
|
|
|
| - Binding<TestSync>* binding() { return &binding_; }
|
| -
|
| private:
|
| - Binding<TestSync> binding_;
|
| PingHandler ping_handler_;
|
| EchoHandler echo_handler_;
|
| AsyncEchoHandler async_echo_handler_;
|
|
|
| + DISALLOW_COPY_AND_ASSIGN(TestSyncCommonImpl);
|
| +};
|
| +
|
| +class TestSyncImpl : public TestSync, public TestSyncCommonImpl {
|
| + public:
|
| + explicit TestSyncImpl(TestSyncRequest request)
|
| + : binding_(this, std::move(request)) {}
|
| +
|
| + // TestSync implementation:
|
| + void Ping(const PingCallback& callback) override { PingImpl(callback); }
|
| + void Echo(int32_t value, const EchoCallback& callback) override {
|
| + EchoImpl(value, callback);
|
| + }
|
| + void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override {
|
| + AsyncEchoImpl(value, callback);
|
| + }
|
| +
|
| + Binding<TestSync>* binding() { return &binding_; }
|
| +
|
| + private:
|
| + Binding<TestSync> binding_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(TestSyncImpl);
|
| };
|
|
|
| +template <typename Interface>
|
| +struct ImplTraits;
|
| +
|
| +template <>
|
| +struct ImplTraits<TestSync> {
|
| + using Type = TestSyncImpl;
|
| +};
|
| +
|
| +template <typename Interface>
|
| class TestSyncServiceThread {
|
| public:
|
| TestSyncServiceThread()
|
| @@ -85,16 +104,17 @@ class TestSyncServiceThread {
|
| thread_.StartWithOptions(thread_options);
|
| }
|
|
|
| - void SetUp(TestSyncRequest request) {
|
| + void SetUp(InterfaceRequest<Interface> request) {
|
| CHECK(thread_.task_runner()->BelongsToCurrentThread());
|
| - impl_.reset(new TestSyncImpl(std::move(request)));
|
| - impl_->set_ping_handler([this](const TestSync::PingCallback& callback) {
|
| - {
|
| - base::AutoLock locker(lock_);
|
| - ping_called_ = true;
|
| - }
|
| - callback.Run();
|
| - });
|
| + impl_.reset(new typename ImplTraits<Interface>::Type(std::move(request)));
|
| + impl_->set_ping_handler(
|
| + [this](const typename Interface::PingCallback& callback) {
|
| + {
|
| + base::AutoLock locker(lock_);
|
| + ping_called_ = true;
|
| + }
|
| + callback.Run();
|
| + });
|
| }
|
|
|
| void TearDown() {
|
| @@ -111,7 +131,7 @@ class TestSyncServiceThread {
|
| private:
|
| base::Thread thread_;
|
|
|
| - scoped_ptr<TestSyncImpl> impl_;
|
| + scoped_ptr<typename ImplTraits<Interface>::Type> impl_;
|
|
|
| mutable base::Lock lock_;
|
| bool ping_called_;
|
| @@ -119,9 +139,22 @@ class TestSyncServiceThread {
|
| DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread);
|
| };
|
|
|
| -TEST_F(SyncMethodTest, CallSyncMethodAsynchronously) {
|
| - TestSyncPtr ptr;
|
| - TestSyncImpl impl(GetProxy(&ptr));
|
| +template <typename T>
|
| +class SyncMethodCommonTest : public testing::Test {
|
| + public:
|
| + SyncMethodCommonTest() : loop_(common::MessagePumpMojo::Create()) {}
|
| + ~SyncMethodCommonTest() override { loop_.RunUntilIdle(); }
|
| +
|
| + private:
|
| + base::MessageLoop loop_;
|
| +};
|
| +
|
| +using InterfaceTypes = testing::Types<TestSync>;
|
| +TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes);
|
| +
|
| +TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) {
|
| + InterfacePtr<TypeParam> ptr;
|
| + typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
|
|
|
| base::RunLoop run_loop;
|
| ptr->Echo(123, [&run_loop](int32_t result) {
|
| @@ -131,12 +164,12 @@ TEST_F(SyncMethodTest, CallSyncMethodAsynchronously) {
|
| run_loop.Run();
|
| }
|
|
|
| -TEST_F(SyncMethodTest, BasicSyncCalls) {
|
| - TestSyncPtr ptr;
|
| +TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) {
|
| + InterfacePtr<TypeParam> ptr;
|
|
|
| - TestSyncServiceThread service_thread;
|
| + TestSyncServiceThread<TypeParam> service_thread;
|
| service_thread.thread()->task_runner()->PostTask(
|
| - FROM_HERE, base::Bind(&TestSyncServiceThread::SetUp,
|
| + FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp,
|
| base::Unretained(&service_thread),
|
| base::Passed(GetProxy(&ptr))));
|
| ASSERT_TRUE(ptr->Ping());
|
| @@ -148,30 +181,30 @@ TEST_F(SyncMethodTest, BasicSyncCalls) {
|
|
|
| base::RunLoop run_loop;
|
| service_thread.thread()->task_runner()->PostTaskAndReply(
|
| - FROM_HERE, base::Bind(&TestSyncServiceThread::TearDown,
|
| + FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::TearDown,
|
| base::Unretained(&service_thread)),
|
| run_loop.QuitClosure());
|
| run_loop.Run();
|
| }
|
|
|
| -TEST_F(SyncMethodTest, ReenteredBySyncMethodBinding) {
|
| +TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) {
|
| // Test that an interface pointer waiting for a sync call response can be
|
| // reentered by a binding serving sync methods on the same thread.
|
|
|
| - TestSyncPtr ptr;
|
| + InterfacePtr<TypeParam> ptr;
|
| // The binding lives on the same thread as the interface pointer.
|
| - TestSyncImpl impl(GetProxy(&ptr));
|
| + typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
|
| int32_t output_value = -1;
|
| ASSERT_TRUE(ptr->Echo(42, &output_value));
|
| EXPECT_EQ(42, output_value);
|
| }
|
|
|
| -TEST_F(SyncMethodTest, InterefacePtrDestroyedDuringSyncCall) {
|
| +TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) {
|
| // Test that it won't result in crash or hang if an interface pointer is
|
| // destroyed while it is waiting for a sync call response.
|
|
|
| - TestSyncPtr ptr;
|
| - TestSyncImpl impl(GetProxy(&ptr));
|
| + InterfacePtr<TypeParam> ptr;
|
| + typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
|
| impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) {
|
| ptr.reset();
|
| callback.Run();
|
| @@ -179,13 +212,13 @@ TEST_F(SyncMethodTest, InterefacePtrDestroyedDuringSyncCall) {
|
| ASSERT_FALSE(ptr->Ping());
|
| }
|
|
|
| -TEST_F(SyncMethodTest, BindingDestroyedDuringSyncCall) {
|
| +TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) {
|
| // Test that it won't result in crash or hang if a binding is
|
| // closed (and therefore the message pipe handle is closed) while the
|
| // corresponding interface pointer is waiting for a sync call response.
|
|
|
| - TestSyncPtr ptr;
|
| - TestSyncImpl impl(GetProxy(&ptr));
|
| + InterfacePtr<TypeParam> ptr;
|
| + typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
|
| impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) {
|
| impl.binding()->Close();
|
| callback.Run();
|
| @@ -193,12 +226,12 @@ TEST_F(SyncMethodTest, BindingDestroyedDuringSyncCall) {
|
| ASSERT_FALSE(ptr->Ping());
|
| }
|
|
|
| -TEST_F(SyncMethodTest, NestedSyncCallsWithInOrderResponses) {
|
| +TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) {
|
| // Test that we can call a sync method on an interface ptr, while there is
|
| // already a sync call ongoing. The responses arrive in order.
|
|
|
| - TestSyncPtr ptr;
|
| - TestSyncImpl impl(GetProxy(&ptr));
|
| + InterfacePtr<TypeParam> ptr;
|
| + typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
|
|
|
| // The same variable is used to store the output of the two sync calls, in
|
| // order to test that responses are handled in the correct order.
|
| @@ -219,12 +252,12 @@ TEST_F(SyncMethodTest, NestedSyncCallsWithInOrderResponses) {
|
| EXPECT_EQ(123, result_value);
|
| }
|
|
|
| -TEST_F(SyncMethodTest, NestedSyncCallsWithOutOfOrderResponses) {
|
| +TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) {
|
| // Test that we can call a sync method on an interface ptr, while there is
|
| // already a sync call ongoing. The responses arrive out of order.
|
|
|
| - TestSyncPtr ptr;
|
| - TestSyncImpl impl(GetProxy(&ptr));
|
| + InterfacePtr<TypeParam> ptr;
|
| + typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
|
|
|
| // The same variable is used to store the output of the two sync calls, in
|
| // order to test that responses are handled in the correct order.
|
| @@ -245,12 +278,12 @@ TEST_F(SyncMethodTest, NestedSyncCallsWithOutOfOrderResponses) {
|
| EXPECT_EQ(123, result_value);
|
| }
|
|
|
| -TEST_F(SyncMethodTest, AsyncResponseQueuedDuringSyncCall) {
|
| +TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) {
|
| // Test that while an interface pointer is waiting for the response to a sync
|
| // call, async responses are queued until the sync call completes.
|
|
|
| - TestSyncPtr ptr;
|
| - TestSyncImpl impl(GetProxy(&ptr));
|
| + InterfacePtr<TypeParam> ptr;
|
| + typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
|
|
|
| int32_t async_echo_request_value = -1;
|
| TestSync::AsyncEchoCallback async_echo_request_callback;
|
| @@ -298,13 +331,13 @@ TEST_F(SyncMethodTest, AsyncResponseQueuedDuringSyncCall) {
|
| EXPECT_TRUE(async_echo_response_dispatched);
|
| }
|
|
|
| -TEST_F(SyncMethodTest, AsyncRequestQueuedDuringSyncCall) {
|
| +TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) {
|
| // Test that while an interface pointer is waiting for the response to a sync
|
| // call, async requests for a binding running on the same thread are queued
|
| // until the sync call completes.
|
|
|
| - TestSyncPtr ptr;
|
| - TestSyncImpl impl(GetProxy(&ptr));
|
| + InterfacePtr<TypeParam> ptr;
|
| + typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
|
|
|
| bool async_echo_request_dispatched = false;
|
| impl.set_async_echo_handler([&async_echo_request_dispatched](
|
| @@ -345,14 +378,15 @@ TEST_F(SyncMethodTest, AsyncRequestQueuedDuringSyncCall) {
|
| EXPECT_TRUE(async_echo_response_dispatched);
|
| }
|
|
|
| -TEST_F(SyncMethodTest, QueuedMessagesProcessedBeforeErrorNotification) {
|
| +TYPED_TEST(SyncMethodCommonTest,
|
| + 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));
|
| + InterfacePtr<TypeParam> ptr;
|
| + typename ImplTraits<TypeParam>::Type impl(GetProxy(&ptr));
|
|
|
| int32_t async_echo_request_value = -1;
|
| TestSync::AsyncEchoCallback async_echo_request_callback;
|
| @@ -421,7 +455,7 @@ TEST_F(SyncMethodTest, QueuedMessagesProcessedBeforeErrorNotification) {
|
| EXPECT_TRUE(ptr.encountered_error());
|
| }
|
|
|
| -TEST_F(SyncMethodTest, InvalidMessageDuringSyncCall) {
|
| +TYPED_TEST(SyncMethodCommonTest, 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
|
| @@ -429,11 +463,12 @@ TEST_F(SyncMethodTest, InvalidMessageDuringSyncCall) {
|
|
|
| MessagePipe pipe;
|
|
|
| - TestSyncPtr ptr;
|
| - ptr.Bind(TestSyncPtrInfo(std::move(pipe.handle0), 0u));
|
| + InterfacePtr<TypeParam> ptr;
|
| + ptr.Bind(InterfacePtrInfo<TypeParam>(std::move(pipe.handle0), 0u));
|
|
|
| MessagePipeHandle raw_binding_handle = pipe.handle1.get();
|
| - TestSyncImpl impl(MakeRequest<TestSync>(std::move(pipe.handle1)));
|
| + typename ImplTraits<TypeParam>::Type impl(
|
| + MakeRequest<TypeParam>(std::move(pipe.handle1)));
|
|
|
| impl.set_echo_handler([&raw_binding_handle](
|
| int32_t value, const TestSync::EchoCallback& callback) {
|
|
|