blob: ee8a8115a348b1ece9db007e69cef875db2452e1 [file] [log] [blame]
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -08001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <chrono>
18#include <thread>
19#include <gtest/gtest.h>
20#include <mediautils/TimerThread.h>
21
22using namespace std::chrono_literals;
23
24namespace android {
25namespace {
26
27constexpr auto kJitter = 10ms;
28
29TEST(TimerThread, Basic) {
30 std::atomic<bool> taskRan = false;
31 TimerThread thread;
32 thread.scheduleTask([&taskRan] { taskRan = true; }, 100ms);
33 std::this_thread::sleep_for(100ms - kJitter);
34 ASSERT_FALSE(taskRan);
35 std::this_thread::sleep_for(2 * kJitter);
36 ASSERT_TRUE(taskRan);
37}
38
39TEST(TimerThread, Cancel) {
40 std::atomic<bool> taskRan = false;
41 TimerThread thread;
42 TimerThread::Handle handle = thread.scheduleTask([&taskRan] { taskRan = true; }, 100ms);
43 std::this_thread::sleep_for(100ms - kJitter);
44 ASSERT_FALSE(taskRan);
45 thread.cancelTask(handle);
46 std::this_thread::sleep_for(2 * kJitter);
47 ASSERT_FALSE(taskRan);
48}
49
50TEST(TimerThread, CancelAfterRun) {
51 std::atomic<bool> taskRan = false;
52 TimerThread thread;
53 TimerThread::Handle handle = thread.scheduleTask([&taskRan] { taskRan = true; }, 100ms);
54 std::this_thread::sleep_for(100ms + kJitter);
55 ASSERT_TRUE(taskRan);
56 thread.cancelTask(handle);
57}
58
59TEST(TimerThread, MultipleTasks) {
60 std::array<std::atomic<bool>, 6> taskRan;
61 TimerThread thread;
62
63 auto startTime = std::chrono::steady_clock::now();
64
65 thread.scheduleTask([&taskRan] { taskRan[0] = true; }, 300ms);
66 thread.scheduleTask([&taskRan] { taskRan[1] = true; }, 100ms);
67 thread.scheduleTask([&taskRan] { taskRan[2] = true; }, 200ms);
68 thread.scheduleTask([&taskRan] { taskRan[3] = true; }, 400ms);
69 auto handle4 = thread.scheduleTask([&taskRan] { taskRan[4] = true; }, 200ms);
70 thread.scheduleTask([&taskRan] { taskRan[5] = true; }, 200ms);
71
72 // Task 1 should trigger around 100ms.
73 std::this_thread::sleep_until(startTime + 100ms - kJitter);
74 ASSERT_FALSE(taskRan[0]);
75 ASSERT_FALSE(taskRan[1]);
76 ASSERT_FALSE(taskRan[2]);
77 ASSERT_FALSE(taskRan[3]);
78 ASSERT_FALSE(taskRan[4]);
79 ASSERT_FALSE(taskRan[5]);
80
81 std::this_thread::sleep_until(startTime + 100ms + kJitter);
82 ASSERT_FALSE(taskRan[0]);
83 ASSERT_TRUE(taskRan[1]);
84 ASSERT_FALSE(taskRan[2]);
85 ASSERT_FALSE(taskRan[3]);
86 ASSERT_FALSE(taskRan[4]);
87 ASSERT_FALSE(taskRan[5]);
88
89 // Cancel task 4 before it gets a chance to run.
90 thread.cancelTask(handle4);
91
92 // Tasks 2 and 5 should trigger around 200ms.
93 std::this_thread::sleep_until(startTime + 200ms - kJitter);
94 ASSERT_FALSE(taskRan[0]);
95 ASSERT_TRUE(taskRan[1]);
96 ASSERT_FALSE(taskRan[2]);
97 ASSERT_FALSE(taskRan[3]);
98 ASSERT_FALSE(taskRan[4]);
99 ASSERT_FALSE(taskRan[5]);
100
101 std::this_thread::sleep_until(startTime + 200ms + kJitter);
102 ASSERT_FALSE(taskRan[0]);
103 ASSERT_TRUE(taskRan[1]);
104 ASSERT_TRUE(taskRan[2]);
105 ASSERT_FALSE(taskRan[3]);
106 ASSERT_FALSE(taskRan[4]);
107 ASSERT_TRUE(taskRan[5]);
108
109 // Task 0 should trigger around 300ms.
110 std::this_thread::sleep_until(startTime + 300ms - kJitter);
111 ASSERT_FALSE(taskRan[0]);
112 ASSERT_TRUE(taskRan[1]);
113 ASSERT_TRUE(taskRan[2]);
114 ASSERT_FALSE(taskRan[3]);
115 ASSERT_FALSE(taskRan[4]);
116 ASSERT_TRUE(taskRan[5]);
117
118 std::this_thread::sleep_until(startTime + 300ms + kJitter);
119 ASSERT_TRUE(taskRan[0]);
120 ASSERT_TRUE(taskRan[1]);
121 ASSERT_TRUE(taskRan[2]);
122 ASSERT_FALSE(taskRan[3]);
123 ASSERT_FALSE(taskRan[4]);
124 ASSERT_TRUE(taskRan[5]);
125
126 // Task 3 should trigger around 400ms.
127 std::this_thread::sleep_until(startTime + 400ms - kJitter);
128 ASSERT_TRUE(taskRan[0]);
129 ASSERT_TRUE(taskRan[1]);
130 ASSERT_TRUE(taskRan[2]);
131 ASSERT_FALSE(taskRan[3]);
132 ASSERT_FALSE(taskRan[4]);
133 ASSERT_TRUE(taskRan[5]);
134
135 std::this_thread::sleep_until(startTime + 400ms + kJitter);
136 ASSERT_TRUE(taskRan[0]);
137 ASSERT_TRUE(taskRan[1]);
138 ASSERT_TRUE(taskRan[2]);
139 ASSERT_TRUE(taskRan[3]);
140 ASSERT_FALSE(taskRan[4]);
141 ASSERT_TRUE(taskRan[5]);
142}
143
144
145} // namespace
146} // namespace android