1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/compiler_specific.h"
7 #include "base/message_loop.h"
8 #include "base/threading/thread.h"
9 #include "jingle/glue/thread_wrapper.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 using ::testing::DoAll
;
14 using ::testing::InSequence
;
15 using ::testing::InvokeWithoutArgs
;
16 using ::testing::Mock
;
18 namespace jingle_glue
{
20 static const uint32 kTestMessage1
= 1;
21 static const uint32 kTestMessage2
= 2;
23 static const int kTestDelayMs1
= 10;
24 static const int kTestDelayMs2
= 20;
25 static const int kTestDelayMs3
= 30;
26 static const int kTestDelayMs4
= 40;
27 static const int kMaxTestDelay
= 40;
31 class MockMessageHandler
: public talk_base::MessageHandler
{
33 MOCK_METHOD1(OnMessage
, void(talk_base::Message
* msg
));
36 MATCHER_P3(MatchMessage
, handler
, message_id
, data
, "") {
37 return arg
->phandler
== handler
&&
38 arg
->message_id
== message_id
&&
42 ACTION(DeleteMessageData
) {
46 // Helper class used in the Dispose test.
47 class DeletableObject
{
49 DeletableObject(bool* deleted
)
64 class ThreadWrapperTest
: public testing::Test
{
66 // This method is used by the SendDuringSend test. It sends message to the
67 // main thread synchronously using Send().
68 void PingMainThread() {
69 talk_base::MessageData
* data
= new talk_base::MessageData();
70 MockMessageHandler handler
;
72 EXPECT_CALL(handler
, OnMessage(
73 MatchMessage(&handler
, kTestMessage2
, data
)))
74 .WillOnce(DeleteMessageData());
75 thread_
->Send(&handler
, kTestMessage2
, data
);
83 virtual void SetUp() OVERRIDE
{
84 JingleThreadWrapper::EnsureForCurrentMessageLoop();
85 thread_
= talk_base::Thread::Current();
88 // ThreadWrapper destroyes itself when |message_loop_| is destroyed.
89 base::MessageLoop message_loop_
;
90 talk_base::Thread
* thread_
;
91 MockMessageHandler handler1_
;
92 MockMessageHandler handler2_
;
95 TEST_F(ThreadWrapperTest
, Post
) {
96 talk_base::MessageData
* data1
= new talk_base::MessageData();
97 talk_base::MessageData
* data2
= new talk_base::MessageData();
98 talk_base::MessageData
* data3
= new talk_base::MessageData();
99 talk_base::MessageData
* data4
= new talk_base::MessageData();
101 thread_
->Post(&handler1_
, kTestMessage1
, data1
);
102 thread_
->Post(&handler1_
, kTestMessage2
, data2
);
103 thread_
->Post(&handler2_
, kTestMessage1
, data3
);
104 thread_
->Post(&handler2_
, kTestMessage1
, data4
);
108 EXPECT_CALL(handler1_
, OnMessage(
109 MatchMessage(&handler1_
, kTestMessage1
, data1
)))
110 .WillOnce(DeleteMessageData());
111 EXPECT_CALL(handler1_
, OnMessage(
112 MatchMessage(&handler1_
, kTestMessage2
, data2
)))
113 .WillOnce(DeleteMessageData());
114 EXPECT_CALL(handler2_
, OnMessage(
115 MatchMessage(&handler2_
, kTestMessage1
, data3
)))
116 .WillOnce(DeleteMessageData());
117 EXPECT_CALL(handler2_
, OnMessage(
118 MatchMessage(&handler2_
, kTestMessage1
, data4
)))
119 .WillOnce(DeleteMessageData());
121 message_loop_
.RunUntilIdle();
124 TEST_F(ThreadWrapperTest
, PostDelayed
) {
125 talk_base::MessageData
* data1
= new talk_base::MessageData();
126 talk_base::MessageData
* data2
= new talk_base::MessageData();
127 talk_base::MessageData
* data3
= new talk_base::MessageData();
128 talk_base::MessageData
* data4
= new talk_base::MessageData();
130 thread_
->PostDelayed(kTestDelayMs1
, &handler1_
, kTestMessage1
, data1
);
131 thread_
->PostDelayed(kTestDelayMs2
, &handler1_
, kTestMessage2
, data2
);
132 thread_
->PostDelayed(kTestDelayMs3
, &handler2_
, kTestMessage1
, data3
);
133 thread_
->PostDelayed(kTestDelayMs4
, &handler2_
, kTestMessage1
, data4
);
137 EXPECT_CALL(handler1_
, OnMessage(
138 MatchMessage(&handler1_
, kTestMessage1
, data1
)))
139 .WillOnce(DeleteMessageData());
140 EXPECT_CALL(handler1_
, OnMessage(
141 MatchMessage(&handler1_
, kTestMessage2
, data2
)))
142 .WillOnce(DeleteMessageData());
143 EXPECT_CALL(handler2_
, OnMessage(
144 MatchMessage(&handler2_
, kTestMessage1
, data3
)))
145 .WillOnce(DeleteMessageData());
146 EXPECT_CALL(handler2_
, OnMessage(
147 MatchMessage(&handler2_
, kTestMessage1
, data4
)))
148 .WillOnce(DeleteMessageData());
150 message_loop_
.PostDelayedTask(
152 base::MessageLoop::QuitClosure(),
153 base::TimeDelta::FromMilliseconds(kMaxTestDelay
));
157 TEST_F(ThreadWrapperTest
, Clear
) {
158 thread_
->Post(&handler1_
, kTestMessage1
, NULL
);
159 thread_
->Post(&handler1_
, kTestMessage2
, NULL
);
160 thread_
->Post(&handler2_
, kTestMessage1
, NULL
);
161 thread_
->Post(&handler2_
, kTestMessage2
, NULL
);
163 thread_
->Clear(&handler1_
, kTestMessage2
);
167 talk_base::MessageData
* null_data
= NULL
;
168 EXPECT_CALL(handler1_
, OnMessage(
169 MatchMessage(&handler1_
, kTestMessage1
, null_data
)))
170 .WillOnce(DeleteMessageData());
171 EXPECT_CALL(handler2_
, OnMessage(
172 MatchMessage(&handler2_
, kTestMessage1
, null_data
)))
173 .WillOnce(DeleteMessageData());
174 EXPECT_CALL(handler2_
, OnMessage(
175 MatchMessage(&handler2_
, kTestMessage2
, null_data
)))
176 .WillOnce(DeleteMessageData());
178 message_loop_
.RunUntilIdle();
181 TEST_F(ThreadWrapperTest
, ClearDelayed
) {
182 thread_
->PostDelayed(kTestDelayMs1
, &handler1_
, kTestMessage1
, NULL
);
183 thread_
->PostDelayed(kTestDelayMs2
, &handler1_
, kTestMessage2
, NULL
);
184 thread_
->PostDelayed(kTestDelayMs3
, &handler2_
, kTestMessage1
, NULL
);
185 thread_
->PostDelayed(kTestDelayMs4
, &handler2_
, kTestMessage1
, NULL
);
187 thread_
->Clear(&handler1_
, kTestMessage2
);
191 talk_base::MessageData
* null_data
= NULL
;
192 EXPECT_CALL(handler1_
, OnMessage(
193 MatchMessage(&handler1_
, kTestMessage1
, null_data
)))
194 .WillOnce(DeleteMessageData());
195 EXPECT_CALL(handler2_
, OnMessage(
196 MatchMessage(&handler2_
, kTestMessage1
, null_data
)))
197 .WillOnce(DeleteMessageData());
198 EXPECT_CALL(handler2_
, OnMessage(
199 MatchMessage(&handler2_
, kTestMessage1
, null_data
)))
200 .WillOnce(DeleteMessageData());
202 message_loop_
.PostDelayedTask(
204 base::MessageLoop::QuitClosure(),
205 base::TimeDelta::FromMilliseconds(kMaxTestDelay
));
209 // Verify that the queue is cleared when a handler is destroyed.
210 TEST_F(ThreadWrapperTest
, ClearDestoroyed
) {
211 MockMessageHandler
* handler_ptr
;
213 MockMessageHandler handler
;
214 handler_ptr
= &handler
;
215 thread_
->Post(&handler
, kTestMessage1
, NULL
);
217 talk_base::MessageList removed
;
218 thread_
->Clear(handler_ptr
, talk_base::MQID_ANY
, &removed
);
219 DCHECK_EQ(0U, removed
.size());
222 // Verify that Send() calls handler synchronously when called on the
224 TEST_F(ThreadWrapperTest
, SendSameThread
) {
225 talk_base::MessageData
* data
= new talk_base::MessageData();
227 EXPECT_CALL(handler1_
, OnMessage(
228 MatchMessage(&handler1_
, kTestMessage1
, data
)))
229 .WillOnce(DeleteMessageData());
230 thread_
->Send(&handler1_
, kTestMessage1
, data
);
233 void InitializeWrapperForNewThread(talk_base::Thread
** thread
,
234 base::WaitableEvent
* done_event
) {
235 JingleThreadWrapper::EnsureForCurrentMessageLoop();
236 JingleThreadWrapper::current()->set_send_allowed(true);
237 *thread
= JingleThreadWrapper::current();
238 done_event
->Signal();
241 // Verify that Send() calls handler synchronously when called for a
243 TEST_F(ThreadWrapperTest
, SendToOtherThread
) {
244 JingleThreadWrapper::current()->set_send_allowed(true);
246 base::Thread
second_thread("JingleThreadWrapperTest");
247 second_thread
.Start();
249 base::WaitableEvent
initialized_event(true, false);
250 talk_base::Thread
* target
;
251 second_thread
.message_loop()->PostTask(
252 FROM_HERE
, base::Bind(&InitializeWrapperForNewThread
,
253 &target
, &initialized_event
));
254 initialized_event
.Wait();
256 ASSERT_TRUE(target
!= NULL
);
258 talk_base::MessageData
* data
= new talk_base::MessageData();
260 EXPECT_CALL(handler1_
, OnMessage(
261 MatchMessage(&handler1_
, kTestMessage1
, data
)))
262 .WillOnce(DeleteMessageData());
263 target
->Send(&handler1_
, kTestMessage1
, data
);
265 Mock::VerifyAndClearExpectations(&handler1_
);
268 // Verify that thread handles Send() while another Send() is
269 // pending. The test creates second thread and Send()s kTestMessage1
270 // to that thread. kTestMessage1 handler calls PingMainThread() which
271 // tries to Send() kTestMessage2 to the main thread.
272 TEST_F(ThreadWrapperTest
, SendDuringSend
) {
273 JingleThreadWrapper::current()->set_send_allowed(true);
275 base::Thread
second_thread("JingleThreadWrapperTest");
276 second_thread
.Start();
278 base::WaitableEvent
initialized_event(true, false);
279 talk_base::Thread
* target
;
280 second_thread
.message_loop()->PostTask(
281 FROM_HERE
, base::Bind(&InitializeWrapperForNewThread
,
282 &target
, &initialized_event
));
283 initialized_event
.Wait();
285 ASSERT_TRUE(target
!= NULL
);
287 talk_base::MessageData
* data
= new talk_base::MessageData();
289 EXPECT_CALL(handler1_
, OnMessage(
290 MatchMessage(&handler1_
, kTestMessage1
, data
)))
293 this, &ThreadWrapperTest::PingMainThread
),
294 DeleteMessageData()));
295 target
->Send(&handler1_
, kTestMessage1
, data
);
297 Mock::VerifyAndClearExpectations(&handler1_
);
300 TEST_F(ThreadWrapperTest
, Dispose
) {
302 thread_
->Dispose(new DeletableObject(&deleted_
));
303 EXPECT_FALSE(deleted_
);
304 message_loop_
.RunUntilIdle();
305 EXPECT_TRUE(deleted_
);
308 } // namespace jingle_glue