Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(688)

Side by Side Diff: webrtc/base/sequenced_task_checker_unittest.cc

Issue 2125113003: Implement SequencedTaskChecker. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Added support for annotations and fixed tommis review comments. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/sequenced_task_checker_impl.cc ('k') | webrtc/webrtc_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "webrtc/base/checks.h"
12 #include "webrtc/base/constructormagic.h"
13 #include "webrtc/base/platform_thread.h"
14 #include "webrtc/base/sequenced_task_checker.h"
15 #include "webrtc/base/task_queue.h"
16
17 namespace rtc {
18
19 namespace {
20 // Calls SequencedCheckerClass::PlatformThread on another thread.
21 class CallCalledSequentiallyOnThread {
22 public:
23 CallCalledSequentiallyOnThread(bool expect_true,
24 SequencedTaskChecker* sequenced_task_checker)
25 : expect_true_(expect_true),
26 thread_(&Run, this, "call_do_stuff_on_thread"),
27 sequenced_task_checker_(sequenced_task_checker) {
28 thread_.Start();
29 thread_.Stop();
tommi 2016/07/12 17:19:23 call Stop() in the dtor? (same below) How do you g
perkj_webrtc 2016/07/12 20:50:57 Done but why would calling stop in the dtor be any
tommi 2016/07/12 21:11:06 Ah, that's great. If that's the contract, then it
30 }
31
32 private:
33 static bool Run(void* obj) {
34 CallCalledSequentiallyOnThread* call_stuff_on_thread =
35 static_cast<CallCalledSequentiallyOnThread*>(obj);
36 EXPECT_EQ(
37 call_stuff_on_thread->sequenced_task_checker_->CalledSequentially(),
38 call_stuff_on_thread->expect_true_);
tommi 2016/07/12 17:19:23 nit: expectation first
perkj_webrtc 2016/07/12 20:50:57 Done.
39 return false;
40 }
41
42 const bool expect_true_;
43 PlatformThread thread_;
44 SequencedTaskChecker* const sequenced_task_checker_;
45
46 RTC_DISALLOW_COPY_AND_ASSIGN(CallCalledSequentiallyOnThread);
47 };
48
49 // Deletes SequencedTaskChecker on a different thread.
50 class DeleteThreadCheckerOnThread {
51 public:
52 explicit DeleteThreadCheckerOnThread(
53 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker)
54 : thread_(&Run, this, "delete_sequenced_task_checker_on_thread"),
55 sequenced_task_checker_(std::move(sequenced_task_checker)) {
56 thread_.Start();
57 thread_.Stop();
58 }
59
60 private:
61 static bool Run(void* obj) {
62 static_cast<DeleteThreadCheckerOnThread*>(obj)
63 ->sequenced_task_checker_.reset();
64 return false;
65 }
66
67 private:
68 PlatformThread thread_;
69 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker_;
70
71 RTC_DISALLOW_COPY_AND_ASSIGN(DeleteThreadCheckerOnThread);
72 };
73
74 void RunMethodOnDifferentThread(bool expect_true) {
75 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker(
76 new SequencedTaskChecker());
77
78 CallCalledSequentiallyOnThread call_on_thread(expect_true,
79 sequenced_task_checker.get());
80 }
81
82 void RunMethodOnDifferentTaskQueue(bool expect_true) {
83 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker(
84 new SequencedTaskChecker());
85
86 static const char kQueueName[] = "MethodNotAllowedOnDifferentTq";
87 TaskQueue queue(kQueueName);
88 Event done_event(false, false);
89 queue.PostTask([&sequenced_task_checker, &done_event, expect_true] {
90 if (expect_true)
91 EXPECT_TRUE(sequenced_task_checker->CalledSequentially());
92 else
93 EXPECT_FALSE(sequenced_task_checker->CalledSequentially());
94 done_event.Set();
95 });
96 EXPECT_TRUE(done_event.Wait(1000));
97 }
98
99 void DetachThenCallFromDifferentTaskQueue(bool expect_true) {
100 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker(
101 new SequencedTaskChecker());
102
103 sequenced_task_checker->Detach();
104
105 Event done_event(false, false);
106 TaskQueue queue1("DetachThenCallFromDifferentTaskQueueImpl1");
107 queue1.PostTask([&sequenced_task_checker, &done_event] {
108 EXPECT_TRUE(sequenced_task_checker->CalledSequentially());
109 done_event.Set();
110 });
111 EXPECT_TRUE(done_event.Wait(1000));
112
113 // CalledSequentially should return false in debug builds after moving to
114 // another task queue.
115 TaskQueue queue2("DetachThenCallFromDifferentTaskQueueImpl2");
116 queue2.PostTask([&sequenced_task_checker, &done_event, expect_true] {
117 if (expect_true)
118 EXPECT_TRUE(sequenced_task_checker->CalledSequentially());
119 else
120 EXPECT_FALSE(sequenced_task_checker->CalledSequentially());
121 done_event.Set();
122 });
123 done_event.Wait(1000);
124 }
125 } // namespace
126
127 TEST(SequencedTaskCheckerTest, CallsAllowedOnSameThread) {
128 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker(
129 new SequencedTaskChecker());
130
131 EXPECT_TRUE(sequenced_task_checker->CalledSequentially());
132
133 // Verify that the destructor doesn't assert.
134 sequenced_task_checker.reset();
135 }
136
137 TEST(SequencedTaskCheckerTest, DestructorAllowedOnDifferentThread) {
138 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker(
139 new SequencedTaskChecker());
140
141 // Verify that the destructor doesn't assert when called on a different
142 // thread.
143 DeleteThreadCheckerOnThread delete_on_thread(
144 std::move(sequenced_task_checker));
145 }
146
147 TEST(SequencedTaskCheckerTest, DetachFromThread) {
148 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker(
149 new SequencedTaskChecker());
150
151 sequenced_task_checker->Detach();
152 CallCalledSequentiallyOnThread call_on_thread(true,
153 sequenced_task_checker.get());
154 }
155
156 TEST(SequencedTaskCheckerTest, DetachFromThreadAndUseOnTaskQueue) {
157 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker(
158 new SequencedTaskChecker());
159
160 sequenced_task_checker->Detach();
161 static const char kQueueName[] = "DetachFromThreadAndUseOnTaskQueue";
162 TaskQueue queue(kQueueName);
163 Event done_event(false, false);
164 queue.PostTask([&sequenced_task_checker, &done_event] {
165 EXPECT_TRUE(sequenced_task_checker->CalledSequentially());
166 done_event.Set();
167 });
168 EXPECT_TRUE(done_event.Wait(1000));
169 }
170
171 TEST(SequencedTaskCheckerTest, DetachFromTaskQueueAndUseOnThread) {
172 TaskQueue queue("DetachFromTaskQueueAndUseOnThread");
173 Event done_event(false, false);
174 queue.PostTask([&done_event] {
175 std::unique_ptr<SequencedTaskChecker> sequenced_task_checker(
176 new SequencedTaskChecker());
177
178 sequenced_task_checker->Detach();
179 CallCalledSequentiallyOnThread call_on_thread(true,
180 sequenced_task_checker.get());
181 done_event.Set();
182 });
183 EXPECT_TRUE(done_event.Wait(1000));
184 }
185
186 #if !NDEBUG || DCHECK_ALWAYS_ON
187 TEST(SequencedTaskCheckerTest, MethodNotAllowedOnDifferentThreadInDebug) {
188 RunMethodOnDifferentThread(false);
189 }
190 #else
191 TEST(SequencedTaskCheckerTest, MethodAllowedOnDifferentThreadInRelease) {
192 RunMethodOnDifferentThread(true);
193 }
194 #endif
195
196 #if !NDEBUG || DCHECK_ALWAYS_ON
197 TEST(SequencedTaskCheckerTest, MethodNotAllowedOnDifferentTaskQueueInDebug) {
198 RunMethodOnDifferentTaskQueue(false);
199 }
200 #else
201 TEST(SequencedTaskCheckerTest, MethodAllowedOnDifferentTaskQueueInRelease) {
202 RunMethodOnDifferentTaskQueue(true);
203 }
204 #endif
205
206 #if !NDEBUG || DCHECK_ALWAYS_ON
207 TEST(SequencedTaskCheckerTest, DetachFromTaskQueueInDebug) {
208 DetachThenCallFromDifferentTaskQueue(false);
209 }
210 #else
211 TEST(SequencedTaskCheckerTest, DetachFromTaskQueueInRelease) {
212 DetachThenCallFromDifferentTaskQueue(true);
213 }
214 #endif
215
216 class TestAnnotations {
217 public:
218 TestAnnotations() : test_var_(false) {}
219
220 void ModifyTestVar() {
221 RTC_DCHECK_CALLED_SEQUENTIALLY(&checker_);
222 test_var_ = true;
223 }
224
225 private:
226 bool test_var_ GUARDED_BY(&checker_);
227 SequencedTaskChecker checker_;
228 };
229
230 TEST(SequencedTaskCheckerTest, TestAnnotations) {
231 TestAnnotations annotations;
232 annotations.ModifyTestVar();
233 }
234
235 #if GTEST_HAS_DEATH_TEST
tommi 2016/07/12 17:19:22 check the source code for where we use this. There
perkj_webrtc 2016/07/12 20:50:57 do not run on android it looks like.
236
237 void TestAnnotationsOnWrongQueue() {
238 TestAnnotations annotations;
239 static const char kQueueName[] = "TestAnnotationsOnWrongQueueDebug";
240 TaskQueue queue(kQueueName);
241 Event done_event(false, false);
242 queue.PostTask([&annotations, &done_event] {
243 annotations.ModifyTestVar();
244 done_event.Set();
245 });
246 EXPECT_TRUE(done_event.Wait(1000));
247 }
248
249 #if !NDEBUG || DCHECK_ALWAYS_ON
250 TEST(SequencedTaskCheckerTest, TestAnnotationsOnWrongQueueDebug) {
251 ASSERT_DEATH({ TestAnnotationsOnWrongQueue(); }, "");
252 }
253 #else
254 TEST(SequencedTaskCheckerTest, TestAnnotationsOnWrongQueueRelease) {
255 TestAnnotationsOnWrongQueue();
256 }
257 #endif
258 #endif // GTEST_HAS_DEATH_TEST
259 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/sequenced_task_checker_impl.cc ('k') | webrtc/webrtc_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698