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) { |