thread_wrapper_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  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.
  4. #include "components/webrtc/thread_wrapper.h"
  5. #include <stdint.h>
  6. #include "base/bind.h"
  7. #include "base/compiler_specific.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/run_loop.h"
  10. #include "base/synchronization/waitable_event.h"
  11. #include "base/task/single_thread_task_runner.h"
  12. #include "base/task/thread_pool.h"
  13. #include "base/test/task_environment.h"
  14. #include "base/threading/thread.h"
  15. #include "testing/gmock/include/gmock/gmock.h"
  16. #include "testing/gtest/include/gtest/gtest.h"
  17. #include "third_party/webrtc_overrides/metronome_source.h"
  18. #include "third_party/webrtc_overrides/test/metronome_like_task_queue_test.h"
  19. using ::blink::MetronomeLikeTaskQueueTest;
  20. using ::testing::DoAll;
  21. using ::testing::InSequence;
  22. using ::testing::InvokeWithoutArgs;
  23. using ::testing::Mock;
  24. namespace webrtc {
  25. static const uint32_t kTestMessage1 = 1;
  26. static const uint32_t kTestMessage2 = 2;
  27. static const int kTestDelayMs1 = 10;
  28. static const int kTestDelayMs2 = 20;
  29. static const int kTestDelayMs3 = 30;
  30. static const int kTestDelayMs4 = 40;
  31. static const int kMaxTestDelay = 40;
  32. namespace {
  33. class MockMessageHandler : public rtc::MessageHandlerAutoCleanup {
  34. public:
  35. MOCK_METHOD1(OnMessage, void(rtc::Message* msg));
  36. };
  37. MATCHER_P3(MatchMessage, handler, message_id, data, "") {
  38. return arg->phandler == handler && arg->message_id == message_id &&
  39. arg->pdata == data;
  40. }
  41. ACTION(DeleteMessageData) {
  42. delete arg0->pdata;
  43. }
  44. // Helper class used in the Dispose test.
  45. class DeletableObject {
  46. public:
  47. DeletableObject(bool* deleted) : deleted_(deleted) { *deleted = false; }
  48. ~DeletableObject() { *deleted_ = true; }
  49. private:
  50. raw_ptr<bool> deleted_;
  51. };
  52. class ThreadWrapperTest : public testing::Test {
  53. public:
  54. // This method is used by the SendDuringSend test. It sends message to the
  55. // main thread synchronously using Send().
  56. void PingMainThread() {
  57. rtc::MessageData* data = new rtc::MessageData();
  58. MockMessageHandler handler;
  59. EXPECT_CALL(handler, OnMessage(MatchMessage(&handler, kTestMessage2, data)))
  60. .WillOnce(DeleteMessageData());
  61. thread_->Send(RTC_FROM_HERE, &handler, kTestMessage2, data);
  62. }
  63. protected:
  64. ThreadWrapperTest() : thread_(nullptr) {}
  65. void SetUp() override {
  66. ThreadWrapper::EnsureForCurrentMessageLoop();
  67. thread_ = rtc::Thread::Current();
  68. }
  69. // ThreadWrapper destroys itself when |message_loop_| is destroyed.
  70. base::test::SingleThreadTaskEnvironment task_environment_;
  71. raw_ptr<rtc::Thread> thread_;
  72. MockMessageHandler handler1_;
  73. MockMessageHandler handler2_;
  74. };
  75. TEST_F(ThreadWrapperTest, Post) {
  76. rtc::MessageData* data1 = new rtc::MessageData();
  77. rtc::MessageData* data2 = new rtc::MessageData();
  78. rtc::MessageData* data3 = new rtc::MessageData();
  79. rtc::MessageData* data4 = new rtc::MessageData();
  80. thread_->Post(RTC_FROM_HERE, &handler1_, kTestMessage1, data1);
  81. thread_->Post(RTC_FROM_HERE, &handler1_, kTestMessage2, data2);
  82. thread_->Post(RTC_FROM_HERE, &handler2_, kTestMessage1, data3);
  83. thread_->Post(RTC_FROM_HERE, &handler2_, kTestMessage1, data4);
  84. InSequence in_seq;
  85. EXPECT_CALL(handler1_,
  86. OnMessage(MatchMessage(&handler1_, kTestMessage1, data1)))
  87. .WillOnce(DeleteMessageData());
  88. EXPECT_CALL(handler1_,
  89. OnMessage(MatchMessage(&handler1_, kTestMessage2, data2)))
  90. .WillOnce(DeleteMessageData());
  91. EXPECT_CALL(handler2_,
  92. OnMessage(MatchMessage(&handler2_, kTestMessage1, data3)))
  93. .WillOnce(DeleteMessageData());
  94. EXPECT_CALL(handler2_,
  95. OnMessage(MatchMessage(&handler2_, kTestMessage1, data4)))
  96. .WillOnce(DeleteMessageData());
  97. base::RunLoop().RunUntilIdle();
  98. }
  99. TEST_F(ThreadWrapperTest, PostDelayed) {
  100. rtc::MessageData* data1 = new rtc::MessageData();
  101. rtc::MessageData* data2 = new rtc::MessageData();
  102. rtc::MessageData* data3 = new rtc::MessageData();
  103. rtc::MessageData* data4 = new rtc::MessageData();
  104. thread_->PostDelayed(RTC_FROM_HERE, kTestDelayMs1, &handler1_, kTestMessage1,
  105. data1);
  106. thread_->PostDelayed(RTC_FROM_HERE, kTestDelayMs2, &handler1_, kTestMessage2,
  107. data2);
  108. thread_->PostDelayed(RTC_FROM_HERE, kTestDelayMs3, &handler2_, kTestMessage1,
  109. data3);
  110. thread_->PostDelayed(RTC_FROM_HERE, kTestDelayMs4, &handler2_, kTestMessage1,
  111. data4);
  112. InSequence in_seq;
  113. EXPECT_CALL(handler1_,
  114. OnMessage(MatchMessage(&handler1_, kTestMessage1, data1)))
  115. .WillOnce(DeleteMessageData());
  116. EXPECT_CALL(handler1_,
  117. OnMessage(MatchMessage(&handler1_, kTestMessage2, data2)))
  118. .WillOnce(DeleteMessageData());
  119. EXPECT_CALL(handler2_,
  120. OnMessage(MatchMessage(&handler2_, kTestMessage1, data3)))
  121. .WillOnce(DeleteMessageData());
  122. EXPECT_CALL(handler2_,
  123. OnMessage(MatchMessage(&handler2_, kTestMessage1, data4)))
  124. .WillOnce(DeleteMessageData());
  125. base::RunLoop run_loop;
  126. task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
  127. FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(kMaxTestDelay));
  128. run_loop.Run();
  129. }
  130. TEST_F(ThreadWrapperTest, Clear) {
  131. thread_->Post(RTC_FROM_HERE, &handler1_, kTestMessage1, NULL);
  132. thread_->Post(RTC_FROM_HERE, &handler1_, kTestMessage2, NULL);
  133. thread_->Post(RTC_FROM_HERE, &handler2_, kTestMessage1, NULL);
  134. thread_->Post(RTC_FROM_HERE, &handler2_, kTestMessage2, NULL);
  135. thread_->Clear(&handler1_, kTestMessage2);
  136. InSequence in_seq;
  137. rtc::MessageData* null_data = NULL;
  138. EXPECT_CALL(handler1_,
  139. OnMessage(MatchMessage(&handler1_, kTestMessage1, null_data)))
  140. .WillOnce(DeleteMessageData());
  141. EXPECT_CALL(handler2_,
  142. OnMessage(MatchMessage(&handler2_, kTestMessage1, null_data)))
  143. .WillOnce(DeleteMessageData());
  144. EXPECT_CALL(handler2_,
  145. OnMessage(MatchMessage(&handler2_, kTestMessage2, null_data)))
  146. .WillOnce(DeleteMessageData());
  147. base::RunLoop().RunUntilIdle();
  148. }
  149. TEST_F(ThreadWrapperTest, ClearDelayed) {
  150. thread_->PostDelayed(RTC_FROM_HERE, kTestDelayMs1, &handler1_, kTestMessage1,
  151. NULL);
  152. thread_->PostDelayed(RTC_FROM_HERE, kTestDelayMs2, &handler1_, kTestMessage2,
  153. NULL);
  154. thread_->PostDelayed(RTC_FROM_HERE, kTestDelayMs3, &handler2_, kTestMessage1,
  155. NULL);
  156. thread_->PostDelayed(RTC_FROM_HERE, kTestDelayMs4, &handler2_, kTestMessage1,
  157. NULL);
  158. thread_->Clear(&handler1_, kTestMessage2);
  159. InSequence in_seq;
  160. rtc::MessageData* null_data = NULL;
  161. EXPECT_CALL(handler1_,
  162. OnMessage(MatchMessage(&handler1_, kTestMessage1, null_data)))
  163. .WillOnce(DeleteMessageData());
  164. EXPECT_CALL(handler2_,
  165. OnMessage(MatchMessage(&handler2_, kTestMessage1, null_data)))
  166. .WillOnce(DeleteMessageData());
  167. EXPECT_CALL(handler2_,
  168. OnMessage(MatchMessage(&handler2_, kTestMessage1, null_data)))
  169. .WillOnce(DeleteMessageData());
  170. base::RunLoop run_loop;
  171. task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
  172. FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(kMaxTestDelay));
  173. run_loop.Run();
  174. }
  175. // Verify that the queue is cleared when a handler is destroyed.
  176. TEST_F(ThreadWrapperTest, ClearDestroyed) {
  177. MockMessageHandler* handler_ptr;
  178. {
  179. MockMessageHandler handler;
  180. handler_ptr = &handler;
  181. thread_->Post(RTC_FROM_HERE, &handler, kTestMessage1, NULL);
  182. }
  183. rtc::MessageList removed;
  184. thread_->Clear(handler_ptr, rtc::MQID_ANY, &removed);
  185. DCHECK_EQ(0U, removed.size());
  186. }
  187. // Verify that Send() calls handler synchronously when called on the
  188. // same thread.
  189. TEST_F(ThreadWrapperTest, SendSameThread) {
  190. rtc::MessageData* data = new rtc::MessageData();
  191. EXPECT_CALL(handler1_,
  192. OnMessage(MatchMessage(&handler1_, kTestMessage1, data)))
  193. .WillOnce(DeleteMessageData());
  194. thread_->Send(RTC_FROM_HERE, &handler1_, kTestMessage1, data);
  195. }
  196. void InitializeWrapperForNewThread(rtc::Thread** thread,
  197. base::WaitableEvent* done_event) {
  198. ThreadWrapper::EnsureForCurrentMessageLoop();
  199. ThreadWrapper::current()->set_send_allowed(true);
  200. *thread = ThreadWrapper::current();
  201. done_event->Signal();
  202. }
  203. // Verify that Send() calls handler synchronously when called for a
  204. // different thread.
  205. TEST_F(ThreadWrapperTest, SendToOtherThread) {
  206. ThreadWrapper::current()->set_send_allowed(true);
  207. base::Thread second_thread("adWrapperTest");
  208. second_thread.Start();
  209. base::WaitableEvent initialized_event(
  210. base::WaitableEvent::ResetPolicy::MANUAL,
  211. base::WaitableEvent::InitialState::NOT_SIGNALED);
  212. rtc::Thread* target;
  213. second_thread.task_runner()->PostTask(
  214. FROM_HERE, base::BindOnce(&InitializeWrapperForNewThread, &target,
  215. &initialized_event));
  216. initialized_event.Wait();
  217. ASSERT_TRUE(target != NULL);
  218. rtc::MessageData* data = new rtc::MessageData();
  219. EXPECT_CALL(handler1_,
  220. OnMessage(MatchMessage(&handler1_, kTestMessage1, data)))
  221. .WillOnce(DeleteMessageData());
  222. target->Send(RTC_FROM_HERE, &handler1_, kTestMessage1, data);
  223. Mock::VerifyAndClearExpectations(&handler1_);
  224. }
  225. // Verify that thread handles Send() while another Send() is
  226. // pending. The test creates second thread and Send()s kTestMessage1
  227. // to that thread. kTestMessage1 handler calls PingMainThread() which
  228. // tries to Send() kTestMessage2 to the main thread.
  229. TEST_F(ThreadWrapperTest, SendDuringSend) {
  230. ThreadWrapper::current()->set_send_allowed(true);
  231. base::Thread second_thread("adWrapperTest");
  232. second_thread.Start();
  233. base::WaitableEvent initialized_event(
  234. base::WaitableEvent::ResetPolicy::MANUAL,
  235. base::WaitableEvent::InitialState::NOT_SIGNALED);
  236. rtc::Thread* target;
  237. second_thread.task_runner()->PostTask(
  238. FROM_HERE, base::BindOnce(&InitializeWrapperForNewThread, &target,
  239. &initialized_event));
  240. initialized_event.Wait();
  241. ASSERT_TRUE(target != NULL);
  242. rtc::MessageData* data = new rtc::MessageData();
  243. EXPECT_CALL(handler1_,
  244. OnMessage(MatchMessage(&handler1_, kTestMessage1, data)))
  245. .WillOnce(
  246. DoAll(InvokeWithoutArgs(this, &ThreadWrapperTest::PingMainThread),
  247. DeleteMessageData()));
  248. target->Send(RTC_FROM_HERE, &handler1_, kTestMessage1, data);
  249. Mock::VerifyAndClearExpectations(&handler1_);
  250. }
  251. TEST_F(ThreadWrapperTest, Dispose) {
  252. bool deleted_ = false;
  253. thread_->Dispose(new DeletableObject(&deleted_));
  254. EXPECT_FALSE(deleted_);
  255. base::RunLoop().RunUntilIdle();
  256. EXPECT_TRUE(deleted_);
  257. }
  258. // Provider needed for the MetronomeLikeTaskQueueTest suite.
  259. class ThreadWrapperProvider : public blink::MetronomeLikeTaskQueueProvider {
  260. public:
  261. void Initialize() override {
  262. ThreadWrapper::EnsureForCurrentMessageLoop();
  263. thread_ = rtc::Thread::Current();
  264. }
  265. base::TimeDelta DeltaToNextTick() const override {
  266. base::TimeTicks now = base::TimeTicks::Now();
  267. return blink::MetronomeSource::TimeSnappedToNextTick(now) - now;
  268. }
  269. base::TimeDelta MetronomeTick() const override {
  270. return blink::MetronomeSource::Tick();
  271. }
  272. webrtc::TaskQueueBase* TaskQueue() const override { return thread_; }
  273. private:
  274. // ThreadWrapper destroys itself when |message_loop_| is destroyed.
  275. raw_ptr<rtc::Thread> thread_;
  276. };
  277. // Instantiate suite to run all tests defined in
  278. // third_party/webrtc_overrides/test/metronome_like_task_queue_test.h
  279. INSTANTIATE_TEST_SUITE_P(
  280. ThreadWrapper,
  281. MetronomeLikeTaskQueueTest,
  282. ::testing::Values(std::make_unique<ThreadWrapperProvider>));
  283. } // namespace
  284. } // namespace webrtc