1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gtest/gtest.h>
17 #include "timer.h"
18 #include "common_timer_errors.h"
19 #include <iostream>
20 #include <thread>
21 #include <chrono>
22 #include <stdatomic.h>
23 #include <sys/time.h>
24
25 using namespace testing::ext;
26 using namespace OHOS;
27 using namespace std;
28
29 namespace {
CurMs()30 int64_t CurMs()
31 {
32 struct timeval tpend;
33 gettimeofday(&tpend, nullptr);
34 return (tpend.tv_sec * 1000000 + tpend.tv_usec) / 1000;
35 }
36 }
37 class UtilsTimerTest : public testing::Test {
38 public :
39 static void SetUpTestCase(void);
40 static void TearDownTestCase(void);
41 void SetUp();
42 void TearDown();
43 };
44
SetUpTestCase(void)45 void UtilsTimerTest::SetUpTestCase(void)
46 {
47 }
48
TearDownTestCase(void)49 void UtilsTimerTest::TearDownTestCase(void)
50 {
51 }
52
SetUp(void)53 void UtilsTimerTest::SetUp(void)
54 {
55 }
56
TearDown(void)57 void UtilsTimerTest::TearDown(void)
58 {
59 }
60
61 std::atomic<int> g_data1(0);
TimeOutCallback1()62 void TimeOutCallback1()
63 {
64 g_data1 += 1;
65 }
66
67 std::atomic<int> g_data2(0);
TimeOutCallback2()68 void TimeOutCallback2()
69 {
70 g_data2 += 1;
71 }
72
73 /*
74 * @tc.name: testTimer001
75 * @tc.desc: timer unit test
76 *
77 * temporarily offline for kernel difference
78 HWTEST_F(UtilsTimerTest, testTimer001, TestSize.Level0)
79 {
80 g_data1 = 0;
81 Utils::Timer timer("test_timer");
82 uint32_t ret = timer.Setup();
83 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
84 uint32_t timerId = timer.Register(TimeOutCallback1, 1);
85 std::this_thread::sleep_for(std::chrono::milliseconds(8));
86 timer.Unregister(timerId);
87 std::this_thread::sleep_for(std::chrono::milliseconds(10));
88 timer.Shutdown();
89 EXPECT_GE(g_data1, 2);
90 EXPECT_GE(10, g_data1);
91 }
92 */
93
94 /*
95 * @tc.name: testTimer002
96 * @tc.desc: timer unit test
97 */
98 HWTEST_F(UtilsTimerTest, testTimer002, TestSize.Level0)
99 {
100 g_data1 = 0;
101 Utils::Timer timer("test_timer");
102 uint32_t ret = timer.Setup();
103 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
104 timer.Register(TimeOutCallback1, 1, true);
105 std::this_thread::sleep_for(std::chrono::milliseconds(15));
106 timer.Shutdown();
107 EXPECT_EQ(1, g_data1);
108 }
109
110 /*
111 * @tc.name: testTimer003
112 * @tc.desc: timer unit test
113 */
114 HWTEST_F(UtilsTimerTest, testTimer003, TestSize.Level0)
115 {
116 g_data1 = 0;
117 g_data2 = 0;
118 Utils::Timer timer("test_timer");
119 uint32_t ret = timer.Setup();
120 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
121 timer.Register(TimeOutCallback1, 1);
122 timer.Register(TimeOutCallback2, 50);
123 std::this_thread::sleep_for(std::chrono::milliseconds(500));
124 timer.Shutdown();
125 EXPECT_GE(g_data1, 8);
126 EXPECT_GE(g_data2, 2);
127 }
128
129 /*
130 * @tc.name: testTimer004
131 * @tc.desc: timer unit test
132 */
133 HWTEST_F(UtilsTimerTest, testTimer004, TestSize.Level0)
134 {
135 g_data1 = 0;
136 Utils::Timer timer("test_timer");
137 uint32_t ret = timer.Setup();
138 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
139 timer.Register(TimeOutCallback1, 1);
140 timer.Register(TimeOutCallback1, 2);
141 std::this_thread::sleep_for(std::chrono::milliseconds(30));
142 timer.Shutdown();
143 EXPECT_GE(g_data1, 5);
144 }
145
146 class A {
147 public:
A(int data)148 explicit A(int data) : data_(data), timer_("ATimer") {}
149 ~A() = default;
150 bool Init();
151 bool StartTimer(int milliseconds, bool once);
152 void StopTimer();
GetData() const153 int GetData() const {return data_;}
154 private:
TimeOutProc()155 void TimeOutProc() {data_ -= 1;};
156 int data_;
157 Utils::Timer timer_;
158 };
159
Init()160 bool A::Init()
161 {
162 return timer_.Setup() == Utils::TIMER_ERR_OK;
163 }
164
StartTimer(int milliseconds,bool once)165 bool A::StartTimer(int milliseconds, bool once)
166 {
167 uint32_t timerId = timer_.Register(std::bind(&A::TimeOutProc, this), milliseconds, once);
168 return timerId != Utils::TIMER_ERR_DEAL_FAILED;
169 }
170
StopTimer()171 void A::StopTimer()
172 {
173 timer_.Shutdown();
174 }
175
176 /*
177 * @tc.name: testTimer005
178 * @tc.desc: timer unit test
179 *
180 * temporarily offline for kernel difference
181 HWTEST_F(UtilsTimerTest, testTimer005, TestSize.Level0)
182 {
183 A a(10);
184 EXPECT_TRUE(a.Init());
185 EXPECT_TRUE(a.StartTimer(1, false));
186 std::this_thread::sleep_for(std::chrono::milliseconds(10));
187 a.StopTimer();
188 EXPECT_GE(8, a.GetData());
189 }
190 */
191
192 /*
193 * @tc.name: testTimer006
194 * @tc.desc: timer unit test
195 */
196 HWTEST_F(UtilsTimerTest, testTimer006, TestSize.Level0)
197 {
198 A a(10);
199 EXPECT_TRUE(a.Init());
200 EXPECT_TRUE(a.StartTimer(1, true));
201 std::this_thread::sleep_for(std::chrono::milliseconds(20));
202 a.StopTimer();
203 EXPECT_EQ(9, a.GetData());
204 }
205
206 /*
207 * @tc.name: testTimer007
208 * @tc.desc: abnormal case
209 */
210 HWTEST_F(UtilsTimerTest, testTimer007, TestSize.Level0)
211 {
212 g_data1 = 0;
213 Utils::Timer timer("test_timer", -1);
214 uint32_t ret = timer.Setup();
215 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
216
217 uint32_t timerId = 0;
218 for (uint32_t i = 0; i < 10; i++) {
219 timerId = timer.Register(TimeOutCallback1, 7, true);
220 std::this_thread::sleep_for(std::chrono::milliseconds(10));
221 }
222 timer.Unregister(timerId);
223 timer.Unregister(timerId);
224
225 timer.Shutdown();
226 timer.Shutdown(false);
227 EXPECT_GE(g_data1, 5);
228 }
229
230 /*
231 * @tc.name: testTimer008
232 * @tc.desc: timer sleep test for ivi
233 */
234 HWTEST_F(UtilsTimerTest, testTimer008, TestSize.Level0)
235 {
236 g_data1 = 0;
237 Utils::Timer timer("test_timer");
238 uint32_t ret = timer.Setup();
239 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
240 timer.Register(TimeOutCallback1, 10);
241
242 for (int i = 0; i < 11; i++) {
243 int64_t pre = CurMs();
244 std::this_thread::sleep_for(std::chrono::milliseconds(10));
245 int64_t cur = CurMs();
246 EXPECT_GE(cur - pre, 10);
247 }
248 timer.Shutdown();
249 EXPECT_GE(g_data1, 10);
250 }
251
252 /*
253 * @tc.name: testTimer009
254 * @tc.desc: recursive test
255 */
DoFunc(Utils::Timer & timer,int & count)256 void DoFunc(Utils::Timer &timer, int &count)
257 {
258 (void)timer.Register(
259 [&timer, &count]() {
260 count += 1;
261 if (count > 9) {
262 return;
263 }
264 DoFunc(timer, count);
265 },
266 10, true);
267 g_data1++;
268 }
269
DoFunc2(Utils::Timer & timer,int & count)270 void DoFunc2(Utils::Timer &timer, int &count)
271 {
272 (void)timer.Register(
273 [&timer, &count]() {
274 count += 1;
275 if (count > 9) {
276 return;
277 }
278 DoFunc2(timer, count);
279 },
280 10, true);
281 g_data1++;
282 }
283
284 HWTEST_F(UtilsTimerTest, testTimer009, TestSize.Level0)
285 {
286 g_data1 = 0;
287 Utils::Timer timer("test_timer");
288 uint32_t ret = timer.Setup();
289 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
290
291 int cnt = 0, cnt1 = 0;
292 DoFunc(timer, cnt);
293 DoFunc2(timer, cnt1);
294 std::this_thread::sleep_for(std::chrono::milliseconds(50));
295 EXPECT_GE(g_data1, 5); /* 8 for max */
296 EXPECT_GE(14, g_data1); /* 10 for min */
297 std::this_thread::sleep_for(std::chrono::milliseconds(50));
298 timer.Shutdown();
299 EXPECT_GE(g_data1, 10); /* 18 for max */
300 }
301
302 /*
303 * @tc.name: testTimer010
304 * @tc.desc: once timer register
305 */
306 HWTEST_F(UtilsTimerTest, testTimer010, TestSize.Level0)
307 {
308 g_data1 = 0;
309 Utils::Timer timer("test_timer");
310 uint32_t ret = timer.Setup();
311 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
312 timer.Register(TimeOutCallback1, 10, true);
313 timer.Register(TimeOutCallback1, 10);
314 timer.Register(TimeOutCallback1, 10, true);
315 timer.Register(TimeOutCallback1, 10);
316 std::this_thread::sleep_for(std::chrono::milliseconds(52));
317 timer.Shutdown();
318 EXPECT_GE(g_data1, 8); /* 12 for max */
319 }
320
321 /*
322 * @tc.name: testTimer011
323 * @tc.desc: once timer register
324 */
325 HWTEST_F(UtilsTimerTest, testTimer011, TestSize.Level0)
326 {
327 g_data1 = 0;
328 Utils::Timer timer("test_timer");
329 uint32_t ret = timer.Setup();
330 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
331 timer.Register(TimeOutCallback1, 10);
332 timer.Register(TimeOutCallback1, 10, true);
333 timer.Register(TimeOutCallback1, 10);
334 timer.Register(TimeOutCallback1, 10, true);
335 std::this_thread::sleep_for(std::chrono::milliseconds(52));
336 timer.Shutdown();
337 EXPECT_GE(g_data1, 8); /* 12 for max */
338 }
339
340