xref: /aosp_15_r20/frameworks/av/media/utils/tests/TimerThread-test.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #include <chrono>
18*ec779b8eSAndroid Build Coastguard Worker #include <thread>
19*ec779b8eSAndroid Build Coastguard Worker #include <gtest/gtest.h>
20*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/TimerThread.h>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker using namespace std::chrono_literals;
23*ec779b8eSAndroid Build Coastguard Worker using namespace android::mediautils;
24*ec779b8eSAndroid Build Coastguard Worker 
25*ec779b8eSAndroid Build Coastguard Worker namespace {
26*ec779b8eSAndroid Build Coastguard Worker 
27*ec779b8eSAndroid Build Coastguard Worker constexpr auto kJitter = 10ms;
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker // Each task written by *ToString() will start with a left brace.
30*ec779b8eSAndroid Build Coastguard Worker constexpr char REQUEST_START = '{';
31*ec779b8eSAndroid Build Coastguard Worker 
countChars(std::string_view s,char c)32*ec779b8eSAndroid Build Coastguard Worker inline size_t countChars(std::string_view s, char c) {
33*ec779b8eSAndroid Build Coastguard Worker     return std::count(s.begin(), s.end(), c);
34*ec779b8eSAndroid Build Coastguard Worker }
35*ec779b8eSAndroid Build Coastguard Worker 
36*ec779b8eSAndroid Build Coastguard Worker 
37*ec779b8eSAndroid Build Coastguard Worker // Split msec time between timeout and second chance time
38*ec779b8eSAndroid Build Coastguard Worker // This tests expiration times weighted between timeout and the second chance time.
39*ec779b8eSAndroid Build Coastguard Worker #define DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(msec, frac) \
40*ec779b8eSAndroid Build Coastguard Worker     std::chrono::milliseconds(int((msec) * (frac)) + 1), \
41*ec779b8eSAndroid Build Coastguard Worker     std::chrono::milliseconds(int((msec) * (1.f - (frac))))
42*ec779b8eSAndroid Build Coastguard Worker 
43*ec779b8eSAndroid Build Coastguard Worker // The TimerThreadTest is parameterized on a fraction between 0.f and 1.f which
44*ec779b8eSAndroid Build Coastguard Worker // is how the total timeout time is split between the first timeout and the second chance time.
45*ec779b8eSAndroid Build Coastguard Worker //
46*ec779b8eSAndroid Build Coastguard Worker class TimerThreadTest : public ::testing::TestWithParam<float> {
47*ec779b8eSAndroid Build Coastguard Worker protected:
48*ec779b8eSAndroid Build Coastguard Worker 
testBasic()49*ec779b8eSAndroid Build Coastguard Worker static void testBasic() {
50*ec779b8eSAndroid Build Coastguard Worker     const auto frac = GetParam();
51*ec779b8eSAndroid Build Coastguard Worker 
52*ec779b8eSAndroid Build Coastguard Worker     std::atomic<bool> taskRan = false;
53*ec779b8eSAndroid Build Coastguard Worker     TimerThread thread;
54*ec779b8eSAndroid Build Coastguard Worker     TimerThread::Handle handle =
55*ec779b8eSAndroid Build Coastguard Worker             thread.scheduleTask("Basic", [&taskRan](TimerThread::Handle) {
56*ec779b8eSAndroid Build Coastguard Worker                     taskRan = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(100, frac));
57*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(TimerThread::isTimeoutHandle(handle));
58*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_for(100ms - kJitter);
59*ec779b8eSAndroid Build Coastguard Worker     ASSERT_FALSE(taskRan);
60*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_for(2 * kJitter);
61*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(taskRan); // timed-out called.
62*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.timeoutToString(), REQUEST_START));
63*ec779b8eSAndroid Build Coastguard Worker     // nothing cancelled
64*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(0ul, countChars(thread.retiredToString(), REQUEST_START));
65*ec779b8eSAndroid Build Coastguard Worker }
66*ec779b8eSAndroid Build Coastguard Worker 
testCancel()67*ec779b8eSAndroid Build Coastguard Worker static void testCancel() {
68*ec779b8eSAndroid Build Coastguard Worker     const auto frac = GetParam();
69*ec779b8eSAndroid Build Coastguard Worker 
70*ec779b8eSAndroid Build Coastguard Worker     std::atomic<bool> taskRan = false;
71*ec779b8eSAndroid Build Coastguard Worker     TimerThread thread;
72*ec779b8eSAndroid Build Coastguard Worker     TimerThread::Handle handle =
73*ec779b8eSAndroid Build Coastguard Worker             thread.scheduleTask("Cancel", [&taskRan](TimerThread::Handle) {
74*ec779b8eSAndroid Build Coastguard Worker                     taskRan = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(100, frac));
75*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(TimerThread::isTimeoutHandle(handle));
76*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_for(100ms - kJitter);
77*ec779b8eSAndroid Build Coastguard Worker     ASSERT_FALSE(taskRan);
78*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(thread.cancelTask(handle));
79*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_for(2 * kJitter);
80*ec779b8eSAndroid Build Coastguard Worker     ASSERT_FALSE(taskRan); // timed-out did not call.
81*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(0ul, countChars(thread.timeoutToString(), REQUEST_START));
82*ec779b8eSAndroid Build Coastguard Worker     // task cancelled.
83*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.retiredToString(), REQUEST_START));
84*ec779b8eSAndroid Build Coastguard Worker }
85*ec779b8eSAndroid Build Coastguard Worker 
testCancelAfterRun()86*ec779b8eSAndroid Build Coastguard Worker static void testCancelAfterRun() {
87*ec779b8eSAndroid Build Coastguard Worker     const auto frac = GetParam();
88*ec779b8eSAndroid Build Coastguard Worker 
89*ec779b8eSAndroid Build Coastguard Worker     std::atomic<bool> taskRan = false;
90*ec779b8eSAndroid Build Coastguard Worker     TimerThread thread;
91*ec779b8eSAndroid Build Coastguard Worker     TimerThread::Handle handle =
92*ec779b8eSAndroid Build Coastguard Worker             thread.scheduleTask("CancelAfterRun",
93*ec779b8eSAndroid Build Coastguard Worker                     [&taskRan](TimerThread::Handle) {
94*ec779b8eSAndroid Build Coastguard Worker                             taskRan = true; },
95*ec779b8eSAndroid Build Coastguard Worker                             DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(100, frac));
96*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(TimerThread::isTimeoutHandle(handle));
97*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_for(100ms + kJitter);
98*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(taskRan); //  timed-out called.
99*ec779b8eSAndroid Build Coastguard Worker     ASSERT_FALSE(thread.cancelTask(handle));
100*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.timeoutToString(), REQUEST_START));
101*ec779b8eSAndroid Build Coastguard Worker     // nothing actually cancelled
102*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(0ul, countChars(thread.retiredToString(), REQUEST_START));
103*ec779b8eSAndroid Build Coastguard Worker }
104*ec779b8eSAndroid Build Coastguard Worker 
testMultipleTasks()105*ec779b8eSAndroid Build Coastguard Worker static void testMultipleTasks() {
106*ec779b8eSAndroid Build Coastguard Worker     const auto frac = GetParam();
107*ec779b8eSAndroid Build Coastguard Worker 
108*ec779b8eSAndroid Build Coastguard Worker     std::array<std::atomic<bool>, 6> taskRan{};
109*ec779b8eSAndroid Build Coastguard Worker     TimerThread thread;
110*ec779b8eSAndroid Build Coastguard Worker 
111*ec779b8eSAndroid Build Coastguard Worker     auto startTime = std::chrono::steady_clock::now();
112*ec779b8eSAndroid Build Coastguard Worker 
113*ec779b8eSAndroid Build Coastguard Worker     thread.scheduleTask("0", [&taskRan](TimerThread::Handle) {
114*ec779b8eSAndroid Build Coastguard Worker             taskRan[0] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(300, frac));
115*ec779b8eSAndroid Build Coastguard Worker     thread.scheduleTask("1", [&taskRan](TimerThread::Handle) {
116*ec779b8eSAndroid Build Coastguard Worker             taskRan[1] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(100, frac));
117*ec779b8eSAndroid Build Coastguard Worker     thread.scheduleTask("2", [&taskRan](TimerThread::Handle) {
118*ec779b8eSAndroid Build Coastguard Worker             taskRan[2] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(200, frac));
119*ec779b8eSAndroid Build Coastguard Worker     thread.scheduleTask("3", [&taskRan](TimerThread::Handle) {
120*ec779b8eSAndroid Build Coastguard Worker             taskRan[3] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(400, frac));
121*ec779b8eSAndroid Build Coastguard Worker     auto handle4 = thread.scheduleTask("4", [&taskRan](TimerThread::Handle) {
122*ec779b8eSAndroid Build Coastguard Worker             taskRan[4] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(200, frac));
123*ec779b8eSAndroid Build Coastguard Worker     thread.scheduleTask("5", [&taskRan](TimerThread::Handle) {
124*ec779b8eSAndroid Build Coastguard Worker             taskRan[5] = true; }, DISTRIBUTE_TIMEOUT_SECONDCHANCE_MS_FRAC(200, frac));
125*ec779b8eSAndroid Build Coastguard Worker 
126*ec779b8eSAndroid Build Coastguard Worker     // 6 tasks pending
127*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(6ul, countChars(thread.pendingToString(), REQUEST_START));
128*ec779b8eSAndroid Build Coastguard Worker     // 0 tasks completed
129*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(0ul, countChars(thread.retiredToString(), REQUEST_START));
130*ec779b8eSAndroid Build Coastguard Worker 
131*ec779b8eSAndroid Build Coastguard Worker     // None of the tasks are expected to have finished at the start.
132*ec779b8eSAndroid Build Coastguard Worker     std::array<std::atomic<bool>, 6> expected{};
133*ec779b8eSAndroid Build Coastguard Worker 
134*ec779b8eSAndroid Build Coastguard Worker     // Task 1 should trigger around 100ms.
135*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_until(startTime + 100ms - kJitter);
136*ec779b8eSAndroid Build Coastguard Worker 
137*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(expected, taskRan);
138*ec779b8eSAndroid Build Coastguard Worker 
139*ec779b8eSAndroid Build Coastguard Worker 
140*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_until(startTime + 100ms + kJitter);
141*ec779b8eSAndroid Build Coastguard Worker 
142*ec779b8eSAndroid Build Coastguard Worker     expected[1] = true;
143*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(expected, taskRan);
144*ec779b8eSAndroid Build Coastguard Worker 
145*ec779b8eSAndroid Build Coastguard Worker     // Cancel task 4 before it gets a chance to run.
146*ec779b8eSAndroid Build Coastguard Worker     thread.cancelTask(handle4);
147*ec779b8eSAndroid Build Coastguard Worker 
148*ec779b8eSAndroid Build Coastguard Worker     // Tasks 2 and 5 should trigger around 200ms.
149*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_until(startTime + 200ms - kJitter);
150*ec779b8eSAndroid Build Coastguard Worker 
151*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(expected, taskRan);
152*ec779b8eSAndroid Build Coastguard Worker 
153*ec779b8eSAndroid Build Coastguard Worker 
154*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_until(startTime + 200ms + kJitter);
155*ec779b8eSAndroid Build Coastguard Worker 
156*ec779b8eSAndroid Build Coastguard Worker     expected[2] = true;
157*ec779b8eSAndroid Build Coastguard Worker     expected[5] = true;
158*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(expected, taskRan);
159*ec779b8eSAndroid Build Coastguard Worker 
160*ec779b8eSAndroid Build Coastguard Worker     // Task 0 should trigger around 300ms.
161*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_until(startTime + 300ms - kJitter);
162*ec779b8eSAndroid Build Coastguard Worker 
163*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(expected, taskRan);
164*ec779b8eSAndroid Build Coastguard Worker 
165*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_until(startTime + 300ms + kJitter);
166*ec779b8eSAndroid Build Coastguard Worker 
167*ec779b8eSAndroid Build Coastguard Worker     expected[0] = true;
168*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(expected, taskRan);
169*ec779b8eSAndroid Build Coastguard Worker 
170*ec779b8eSAndroid Build Coastguard Worker     // 1 task pending
171*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.pendingToString(), REQUEST_START));
172*ec779b8eSAndroid Build Coastguard Worker     // 4 tasks called on timeout,  and 1 cancelled
173*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(4ul, countChars(thread.timeoutToString(), REQUEST_START));
174*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.retiredToString(), REQUEST_START));
175*ec779b8eSAndroid Build Coastguard Worker 
176*ec779b8eSAndroid Build Coastguard Worker     // Task 3 should trigger around 400ms.
177*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_until(startTime + 400ms - kJitter);
178*ec779b8eSAndroid Build Coastguard Worker 
179*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(expected, taskRan);
180*ec779b8eSAndroid Build Coastguard Worker 
181*ec779b8eSAndroid Build Coastguard Worker     // 4 tasks called on timeout and 1 cancelled
182*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(4ul, countChars(thread.timeoutToString(), REQUEST_START));
183*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.retiredToString(), REQUEST_START));
184*ec779b8eSAndroid Build Coastguard Worker 
185*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_until(startTime + 400ms + kJitter);
186*ec779b8eSAndroid Build Coastguard Worker 
187*ec779b8eSAndroid Build Coastguard Worker     expected[3] = true;
188*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(expected, taskRan);
189*ec779b8eSAndroid Build Coastguard Worker 
190*ec779b8eSAndroid Build Coastguard Worker     // 0 tasks pending
191*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(0ul, countChars(thread.pendingToString(), REQUEST_START));
192*ec779b8eSAndroid Build Coastguard Worker     // 5 tasks called on timeout and 1 cancelled
193*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(5ul, countChars(thread.timeoutToString(), REQUEST_START));
194*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.retiredToString(), REQUEST_START));
195*ec779b8eSAndroid Build Coastguard Worker }
196*ec779b8eSAndroid Build Coastguard Worker 
197*ec779b8eSAndroid Build Coastguard Worker }; // class TimerThreadTest
198*ec779b8eSAndroid Build Coastguard Worker 
TEST_P(TimerThreadTest,Basic)199*ec779b8eSAndroid Build Coastguard Worker TEST_P(TimerThreadTest, Basic) {
200*ec779b8eSAndroid Build Coastguard Worker     testBasic();
201*ec779b8eSAndroid Build Coastguard Worker }
202*ec779b8eSAndroid Build Coastguard Worker 
TEST_P(TimerThreadTest,Cancel)203*ec779b8eSAndroid Build Coastguard Worker TEST_P(TimerThreadTest, Cancel) {
204*ec779b8eSAndroid Build Coastguard Worker     testCancel();
205*ec779b8eSAndroid Build Coastguard Worker }
206*ec779b8eSAndroid Build Coastguard Worker 
TEST_P(TimerThreadTest,CancelAfterRun)207*ec779b8eSAndroid Build Coastguard Worker TEST_P(TimerThreadTest, CancelAfterRun) {
208*ec779b8eSAndroid Build Coastguard Worker     testCancelAfterRun();
209*ec779b8eSAndroid Build Coastguard Worker }
210*ec779b8eSAndroid Build Coastguard Worker 
TEST_P(TimerThreadTest,MultipleTasks)211*ec779b8eSAndroid Build Coastguard Worker TEST_P(TimerThreadTest, MultipleTasks) {
212*ec779b8eSAndroid Build Coastguard Worker     testMultipleTasks();
213*ec779b8eSAndroid Build Coastguard Worker }
214*ec779b8eSAndroid Build Coastguard Worker 
215*ec779b8eSAndroid Build Coastguard Worker INSTANTIATE_TEST_CASE_P(
216*ec779b8eSAndroid Build Coastguard Worker         TimerThread,
217*ec779b8eSAndroid Build Coastguard Worker         TimerThreadTest,
218*ec779b8eSAndroid Build Coastguard Worker         ::testing::Values(0.f, 0.5f, 1.f)
219*ec779b8eSAndroid Build Coastguard Worker         );
220*ec779b8eSAndroid Build Coastguard Worker 
TEST(TimerThread,TrackedTasks)221*ec779b8eSAndroid Build Coastguard Worker TEST(TimerThread, TrackedTasks) {
222*ec779b8eSAndroid Build Coastguard Worker     TimerThread thread;
223*ec779b8eSAndroid Build Coastguard Worker 
224*ec779b8eSAndroid Build Coastguard Worker     auto handle0 = thread.trackTask("0");
225*ec779b8eSAndroid Build Coastguard Worker     auto handle1 = thread.trackTask("1");
226*ec779b8eSAndroid Build Coastguard Worker     auto handle2 = thread.trackTask("2");
227*ec779b8eSAndroid Build Coastguard Worker 
228*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(TimerThread::isNoTimeoutHandle(handle0));
229*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(TimerThread::isNoTimeoutHandle(handle1));
230*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(TimerThread::isNoTimeoutHandle(handle2));
231*ec779b8eSAndroid Build Coastguard Worker 
232*ec779b8eSAndroid Build Coastguard Worker     // 3 tasks pending
233*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(3ul, countChars(thread.pendingToString(), REQUEST_START));
234*ec779b8eSAndroid Build Coastguard Worker     // 0 tasks retired
235*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(0ul, countChars(thread.retiredToString(), REQUEST_START));
236*ec779b8eSAndroid Build Coastguard Worker 
237*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(thread.cancelTask(handle0));
238*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(thread.cancelTask(handle1));
239*ec779b8eSAndroid Build Coastguard Worker 
240*ec779b8eSAndroid Build Coastguard Worker     // 1 task pending
241*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.pendingToString(), REQUEST_START));
242*ec779b8eSAndroid Build Coastguard Worker     // 2 tasks retired
243*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(2ul, countChars(thread.retiredToString(), REQUEST_START));
244*ec779b8eSAndroid Build Coastguard Worker 
245*ec779b8eSAndroid Build Coastguard Worker     // handle1 is stale, cancel returns false.
246*ec779b8eSAndroid Build Coastguard Worker     ASSERT_FALSE(thread.cancelTask(handle1));
247*ec779b8eSAndroid Build Coastguard Worker 
248*ec779b8eSAndroid Build Coastguard Worker     // 1 task pending
249*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.pendingToString(), REQUEST_START));
250*ec779b8eSAndroid Build Coastguard Worker     // 2 tasks retired
251*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(2ul, countChars(thread.retiredToString(), REQUEST_START));
252*ec779b8eSAndroid Build Coastguard Worker 
253*ec779b8eSAndroid Build Coastguard Worker     // Add another tracked task.
254*ec779b8eSAndroid Build Coastguard Worker     auto handle3 = thread.trackTask("3");
255*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(TimerThread::isNoTimeoutHandle(handle3));
256*ec779b8eSAndroid Build Coastguard Worker 
257*ec779b8eSAndroid Build Coastguard Worker     // 2 tasks pending
258*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(2ul, countChars(thread.pendingToString(), REQUEST_START));
259*ec779b8eSAndroid Build Coastguard Worker     // 2 tasks retired
260*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(2ul, countChars(thread.retiredToString(), REQUEST_START));
261*ec779b8eSAndroid Build Coastguard Worker 
262*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(thread.cancelTask(handle2));
263*ec779b8eSAndroid Build Coastguard Worker 
264*ec779b8eSAndroid Build Coastguard Worker     // 1 tasks pending
265*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(1ul, countChars(thread.pendingToString(), REQUEST_START));
266*ec779b8eSAndroid Build Coastguard Worker     // 3 tasks retired
267*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(3ul, countChars(thread.retiredToString(), REQUEST_START));
268*ec779b8eSAndroid Build Coastguard Worker 
269*ec779b8eSAndroid Build Coastguard Worker     ASSERT_TRUE(thread.cancelTask(handle3));
270*ec779b8eSAndroid Build Coastguard Worker 
271*ec779b8eSAndroid Build Coastguard Worker     // 0 tasks pending
272*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(0ul, countChars(thread.pendingToString(), REQUEST_START));
273*ec779b8eSAndroid Build Coastguard Worker     // 4 tasks retired
274*ec779b8eSAndroid Build Coastguard Worker     ASSERT_EQ(4ul, countChars(thread.retiredToString(), REQUEST_START));
275*ec779b8eSAndroid Build Coastguard Worker }
276*ec779b8eSAndroid Build Coastguard Worker 
277*ec779b8eSAndroid Build Coastguard Worker }  // namespace
278