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 using namespace testing::ext;
25 using namespace std;
26
27 namespace OHOS {
28 namespace {
CurMs()29 int64_t CurMs()
30 {
31 struct timeval tpend;
32 gettimeofday(&tpend, nullptr);
33 return (tpend.tv_sec * 1000000 + tpend.tv_usec) / 1000;
34 }
35
36 class UtilsTimerTest : public testing::Test {
37 public :
38 static void SetUpTestCase(void);
39 static void TearDownTestCase(void);
40 void SetUp();
41 void TearDown();
42 };
43
SetUpTestCase(void)44 void UtilsTimerTest::SetUpTestCase(void)
45 {
46 }
47
TearDownTestCase(void)48 void UtilsTimerTest::TearDownTestCase(void)
49 {
50 }
51
SetUp(void)52 void UtilsTimerTest::SetUp(void)
53 {
54 }
55
TearDown(void)56 void UtilsTimerTest::TearDown(void)
57 {
58 }
59
60 std::atomic<int> g_data1(0);
TimeOutCallback1()61 void TimeOutCallback1()
62 {
63 g_data1 = g_data1 + 1;
64 }
65
66 std::atomic<int> g_data2(0);
TimeOutCallback2()67 void TimeOutCallback2()
68 {
69 g_data2 = g_data2 + 1;
70 }
71
72 /*
73 * @tc.name: testTimer001
74 * @tc.desc: timer unit test
75 *
76 * temporarily offline for kernel difference
77 HWTEST_F(UtilsTimerTest, testTimer001, TestSize.Level0)
78 {
79 g_data1 = 0;
80 Utils::Timer timer("test_timer");
81 uint32_t ret = timer.Setup();
82 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
83 uint32_t timerId = timer.Register(TimeOutCallback1, 1);
84 std::this_thread::sleep_for(std::chrono::milliseconds(8));
85 timer.Unregister(timerId);
86 std::this_thread::sleep_for(std::chrono::milliseconds(10));
87 timer.Shutdown();
88 EXPECT_GE(g_data1, 2);
89 EXPECT_GE(10, g_data1);
90 */
91
92 /*
93 * @tc.name: testTimer002
94 * @tc.desc: timer unit test
95 */
96 HWTEST_F(UtilsTimerTest, testTimer002, TestSize.Level0)
97 {
98 g_data1 = 0;
99 Utils::Timer timer("test_timer");
100 uint32_t ret = timer.Setup();
101 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
102 timer.Register(TimeOutCallback1, 1, true);
103 std::this_thread::sleep_for(std::chrono::milliseconds(15));
104 timer.Shutdown();
105 EXPECT_EQ(1, g_data1);
106 }
107
108 /*
109 * @tc.name: testTimer003
110 * @tc.desc: timer unit test
111 */
112 HWTEST_F(UtilsTimerTest, testTimer003, TestSize.Level0)
113 {
114 g_data1 = 0;
115 g_data2 = 0;
116 Utils::Timer timer("test_timer");
117 uint32_t ret = timer.Setup();
118 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
119 timer.Register(TimeOutCallback1, 1);
120 timer.Register(TimeOutCallback2, 50);
121 std::this_thread::sleep_for(std::chrono::milliseconds(500));
122 timer.Shutdown();
123 EXPECT_GE(g_data1, 8);
124 EXPECT_GE(g_data2, 2);
125 }
126
TestTimerEvent(Utils::Timer & timer)127 static void TestTimerEvent(Utils::Timer& timer)
128 {
129 uint32_t interval = 1;
130 timer.Register(TimeOutCallback1, interval);
131 uint32_t interval2 = 2;
132 timer.Register(TimeOutCallback1, interval2);
133 int sleepTime = 30;
134 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
135 timer.Shutdown();
136 }
137
138 /*
139 * @tc.name: testTimer004
140 * @tc.desc: timer unit test
141 */
142 HWTEST_F(UtilsTimerTest, testTimer004, TestSize.Level0)
143 {
144 g_data1 = 0;
145 Utils::Timer timer("test_timer");
146 uint32_t ret = timer.Setup();
147 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
148 TestTimerEvent(timer);
149 EXPECT_GE(g_data1, 5);
150 }
151
152 class A {
153 public:
A(int data)154 explicit A(int data) : data_(data), timer_("ATimer") {}
155 ~A() = default;
156 bool Init();
157 bool StartTimer(int milliseconds, bool once);
158 void StopTimer();
GetData() const159 int GetData() const
160 {
161 return data_;
162 }
163 private:
TimeOutProc()164 void TimeOutProc()
165 {
166 data_ -= 1;
167 };
168 int data_;
169 Utils::Timer timer_;
170 };
171
Init()172 bool A::Init()
173 {
174 return timer_.Setup() == Utils::TIMER_ERR_OK;
175 }
176
StartTimer(int milliseconds,bool once)177 bool A::StartTimer(int milliseconds, bool once)
178 {
179 uint32_t timerId = timer_.Register(std::bind(&A::TimeOutProc, this), milliseconds, once);
180 return timerId != Utils::TIMER_ERR_DEAL_FAILED;
181 }
182
StopTimer()183 void A::StopTimer()
184 {
185 timer_.Shutdown();
186 }
187
188 /*
189 * @tc.name: testTimer005
190 * @tc.desc: timer unit test
191 *
192 * temporarily offline for kernel difference
193 HWTEST_F(UtilsTimerTest, testTimer005, TestSize.Level0)
194 {
195 A a(10);
196 EXPECT_TRUE(a.Init());
197 EXPECT_TRUE(a.StartTimer(1, false));
198 std::this_thread::sleep_for(std::chrono::milliseconds(10));
199 a.StopTimer();
200 EXPECT_GE(8, a.GetData());
201 }
202 */
203
204 /*
205 * @tc.name: testTimer006
206 * @tc.desc: timer unit test
207 */
208 HWTEST_F(UtilsTimerTest, testTimer006, TestSize.Level0)
209 {
210 A a(10);
211 EXPECT_TRUE(a.Init());
212 EXPECT_TRUE(a.StartTimer(1, true));
213 std::this_thread::sleep_for(std::chrono::milliseconds(20));
214 a.StopTimer();
215 EXPECT_EQ(9, a.GetData());
216 }
217
TimerEventFun(Utils::Timer & timer)218 static void TimerEventFun(Utils::Timer& timer)
219 {
220 uint32_t timerId = 0;
221 uint32_t loops = 10;
222 uint32_t interval = 7;
223 int sleepTime = 10;
224 for (uint32_t i = 0; i < loops; i++) {
225 timerId = timer.Register(TimeOutCallback1, interval, true);
226 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
227 }
228 timer.Unregister(timerId);
229 timer.Unregister(timerId);
230 }
231
232 /*
233 * @tc.name: testTimer007
234 * @tc.desc: abnormal case
235 */
236 HWTEST_F(UtilsTimerTest, testTimer007, TestSize.Level0)
237 {
238 g_data1 = 0;
239 Utils::Timer timer("test_timer");
240 uint32_t ret = timer.Setup();
241 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
242 TimerEventFun(timer);
243 timer.Shutdown();
244 timer.Shutdown(false);
245 EXPECT_GE(g_data1, 5);
246 }
247
SleepLoopFunc()248 static void SleepLoopFunc()
249 {
250 int loops = 11;
251 int sleepTime = 10;
252 int64_t desiredVal = 10;
253 for (int i = 0; i < loops; i++) {
254 int64_t pre = CurMs();
255 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
256 int64_t cur = CurMs();
257 EXPECT_GE(cur - pre, desiredVal);
258 }
259 }
260
261 /*
262 * @tc.name: testTimer008
263 * @tc.desc: timer sleep test for ivi
264 */
265 HWTEST_F(UtilsTimerTest, testTimer008, TestSize.Level0)
266 {
267 g_data1 = 0;
268 Utils::Timer timer("test_timer");
269 uint32_t ret = timer.Setup();
270 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
271 timer.Register(TimeOutCallback1, 10);
272
273 SleepLoopFunc();
274 timer.Shutdown();
275 EXPECT_GE(g_data1, 10);
276 }
277
278 /*
279 * @tc.name: testTimer009
280 * @tc.desc: recursive test
281 */
DoFunc(Utils::Timer & timer,int & count)282 void DoFunc(Utils::Timer &timer, int &count)
283 {
284 (void)timer.Register(
285 [&timer, &count]() {
286 count += 1;
287 if (count > 9) {
288 return;
289 }
290 DoFunc(timer, count);
291 },
292 10, true);
293 g_data1++;
294 }
295
DoFunc2(Utils::Timer & timer,int & count)296 void DoFunc2(Utils::Timer &timer, int &count)
297 {
298 (void)timer.Register(
299 [&timer, &count]() {
300 count += 1;
301 if (count > 9) {
302 return;
303 }
304 DoFunc2(timer, count);
305 },
306 10, true);
307 g_data1++;
308 }
309
310 HWTEST_F(UtilsTimerTest, testTimer009, TestSize.Level0)
311 {
312 g_data1 = 0;
313 Utils::Timer timer("test_timer");
314 uint32_t ret = timer.Setup();
315 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
316
317 int cnt = 0, cnt1 = 0;
318 DoFunc(timer, cnt);
319 DoFunc2(timer, cnt1);
320 std::this_thread::sleep_for(std::chrono::milliseconds(50));
321 EXPECT_GE(g_data1, 5); /* 8 for max */
322 EXPECT_GE(14, g_data1); /* 10 for min */
323 std::this_thread::sleep_for(std::chrono::milliseconds(50));
324 timer.Shutdown();
325 EXPECT_GE(g_data1, 10); /* 18 for max */
326 }
327
TimerRegisterMechanism(Utils::Timer & timer,bool once)328 static void TimerRegisterMechanism(Utils::Timer& timer, bool once)
329 {
330 uint32_t interval = 10;
331 timer.Register(TimeOutCallback1, interval, once);
332 timer.Register(TimeOutCallback1, interval, !once);
333 timer.Register(TimeOutCallback1, interval, once);
334 timer.Register(TimeOutCallback1, interval, !once);
335 }
336
337 /*
338 * @tc.name: testTimer010
339 * @tc.desc: once timer register
340 */
341 HWTEST_F(UtilsTimerTest, testTimer010, TestSize.Level0)
342 {
343 g_data1 = 0;
344 Utils::Timer timer("test_timer");
345 uint32_t ret = timer.Setup();
346 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
347 bool once = true;
348 TimerRegisterMechanism(timer, once);
349 std::this_thread::sleep_for(std::chrono::milliseconds(52));
350 timer.Shutdown();
351 EXPECT_GE(g_data1, 8); /* 12 for max */
352 }
353
354 /*
355 * @tc.name: testTimer011
356 * @tc.desc: once timer register
357 */
358 HWTEST_F(UtilsTimerTest, testTimer011, TestSize.Level0)
359 {
360 g_data1 = 0;
361 Utils::Timer timer("test_timer");
362 uint32_t ret = timer.Setup();
363 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
364 bool once = false;
365 TimerRegisterMechanism(timer, once);
366 std::this_thread::sleep_for(std::chrono::milliseconds(52));
367 timer.Shutdown();
368 EXPECT_GE(g_data1, 8); /* 12 for max */
369 }
370
371 /*
372 * @tc.name: testTimer012
373 * @tc.desc: Test double setup.
374 */
375 HWTEST_F(UtilsTimerTest, testTimer012, TestSize.Level0)
376 {
377 g_data1 = 0;
378 Utils::Timer timer("test_timer");
379 uint32_t ret = timer.Setup();
380 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
381 ret = timer.Setup();
382 EXPECT_EQ(Utils::TIMER_ERR_INVALID_VALUE, ret);
383
384 timer.Shutdown();
385 }
386
387 /*
388 * @tc.name: testTimer013
389 * @tc.desc: Test uncommon operations.
390 */
391 HWTEST_F(UtilsTimerTest, testTimer013, TestSize.Level0)
392 {
393 g_data1 = 0;
394 Utils::Timer timer("test_timer", -1);
395 uint32_t ret = timer.Setup();
396 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
397 std::this_thread::sleep_for(std::chrono::milliseconds(1));
398 timer.Shutdown();
399
400 Utils::Timer timer1("test_timer_1");
401 ret = timer1.Setup();
402 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
403 std::this_thread::sleep_for(std::chrono::milliseconds(1));
404 timer1.Shutdown(false);
405 }
406 } // namespace
407 } // namespace OHOS