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 += 1;
64 }
65
66 std::atomic<int> g_data2(0);
TimeOutCallback2()67 void TimeOutCallback2()
68 {
69 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
127 /*
128 * @tc.name: testTimer004
129 * @tc.desc: timer unit test
130 */
131 HWTEST_F(UtilsTimerTest, testTimer004, TestSize.Level0)
132 {
133 g_data1 = 0;
134 Utils::Timer timer("test_timer");
135 uint32_t ret = timer.Setup();
136 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
137 timer.Register(TimeOutCallback1, 1);
138 timer.Register(TimeOutCallback1, 2);
139 std::this_thread::sleep_for(std::chrono::milliseconds(30));
140 timer.Shutdown();
141 EXPECT_GE(g_data1, 5);
142 }
143
144 class A {
145 public:
A(int data)146 explicit A(int data) : data_(data), timer_("ATimer") {}
147 ~A() = default;
148 bool Init();
149 bool StartTimer(int milliseconds, bool once);
150 void StopTimer();
GetData() const151 int GetData() const {return data_;}
152 private:
TimeOutProc()153 void TimeOutProc()
154 {
155 data_ -= 1;
156 };
157 int data_;
158 Utils::Timer timer_;
159 };
160
Init()161 bool A::Init()
162 {
163 return timer_.Setup() == Utils::TIMER_ERR_OK;
164 }
165
StartTimer(int milliseconds,bool once)166 bool A::StartTimer(int milliseconds, bool once)
167 {
168 uint32_t timerId = timer_.Register(std::bind(&A::TimeOutProc, this), milliseconds, once);
169 return timerId != Utils::TIMER_ERR_DEAL_FAILED;
170 }
171
StopTimer()172 void A::StopTimer()
173 {
174 timer_.Shutdown();
175 }
176
177 /*
178 * @tc.name: testTimer005
179 * @tc.desc: timer unit test
180 *
181 * temporarily offline for kernel difference
182 HWTEST_F(UtilsTimerTest, testTimer005, TestSize.Level0)
183 {
184 A a(10);
185 EXPECT_TRUE(a.Init());
186 EXPECT_TRUE(a.StartTimer(1, false));
187 std::this_thread::sleep_for(std::chrono::milliseconds(10));
188 a.StopTimer();
189 EXPECT_GE(8, a.GetData());
190 }
191 */
192
193 /*
194 * @tc.name: testTimer006
195 * @tc.desc: timer unit test
196 */
197 HWTEST_F(UtilsTimerTest, testTimer006, TestSize.Level0)
198 {
199 A a(10);
200 EXPECT_TRUE(a.Init());
201 EXPECT_TRUE(a.StartTimer(1, true));
202 std::this_thread::sleep_for(std::chrono::milliseconds(20));
203 a.StopTimer();
204 EXPECT_EQ(9, a.GetData());
205 }
206
207 /*
208 * @tc.name: testTimer007
209 * @tc.desc: abnormal case
210 */
211 HWTEST_F(UtilsTimerTest, testTimer007, TestSize.Level0)
212 {
213 g_data1 = 0;
214 Utils::Timer timer("test_timer", -1);
215 uint32_t ret = timer.Setup();
216 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
217
218 uint32_t timerId = 0;
219 for (uint32_t i = 0; i < 10; i++) {
220 timerId = timer.Register(TimeOutCallback1, 7, true);
221 std::this_thread::sleep_for(std::chrono::milliseconds(10));
222 }
223 timer.Unregister(timerId);
224 timer.Unregister(timerId);
225
226 timer.Shutdown();
227 timer.Shutdown(false);
228 EXPECT_GE(g_data1, 5);
229 }
230
231 /*
232 * @tc.name: testTimer008
233 * @tc.desc: timer sleep test for ivi
234 */
235 HWTEST_F(UtilsTimerTest, testTimer008, TestSize.Level0)
236 {
237 g_data1 = 0;
238 Utils::Timer timer("test_timer");
239 uint32_t ret = timer.Setup();
240 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
241 timer.Register(TimeOutCallback1, 10);
242
243 for (int i = 0; i < 11; i++) {
244 int64_t pre = CurMs();
245 std::this_thread::sleep_for(std::chrono::milliseconds(10));
246 int64_t cur = CurMs();
247 EXPECT_GE(cur - pre, 10);
248 }
249 timer.Shutdown();
250 EXPECT_GE(g_data1, 10);
251 }
252
253 /*
254 * @tc.name: testTimer009
255 * @tc.desc: recursive test
256 */
DoFunc(Utils::Timer & timer,int & count)257 void DoFunc(Utils::Timer &timer, int &count)
258 {
259 (void)timer.Register(
260 [&timer, &count]() {
261 count += 1;
262 if (count > 9) {
263 return;
264 }
265 DoFunc(timer, count);
266 },
267 10, true);
268 g_data1++;
269 }
270
DoFunc2(Utils::Timer & timer,int & count)271 void DoFunc2(Utils::Timer &timer, int &count)
272 {
273 (void)timer.Register(
274 [&timer, &count]() {
275 count += 1;
276 if (count > 9) {
277 return;
278 }
279 DoFunc2(timer, count);
280 },
281 10, true);
282 g_data1++;
283 }
284
285 HWTEST_F(UtilsTimerTest, testTimer009, TestSize.Level0)
286 {
287 g_data1 = 0;
288 Utils::Timer timer("test_timer");
289 uint32_t ret = timer.Setup();
290 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
291
292 int cnt = 0, cnt1 = 0;
293 DoFunc(timer, cnt);
294 DoFunc2(timer, cnt1);
295 std::this_thread::sleep_for(std::chrono::milliseconds(50));
296 EXPECT_GE(g_data1, 5); /* 8 for max */
297 EXPECT_GE(14, g_data1); /* 10 for min */
298 std::this_thread::sleep_for(std::chrono::milliseconds(50));
299 timer.Shutdown();
300 EXPECT_GE(g_data1, 10); /* 18 for max */
301 }
302
303 /*
304 * @tc.name: testTimer010
305 * @tc.desc: once timer register
306 */
307 HWTEST_F(UtilsTimerTest, testTimer010, TestSize.Level0)
308 {
309 g_data1 = 0;
310 Utils::Timer timer("test_timer");
311 uint32_t ret = timer.Setup();
312 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
313 timer.Register(TimeOutCallback1, 10, true);
314 timer.Register(TimeOutCallback1, 10);
315 timer.Register(TimeOutCallback1, 10, true);
316 timer.Register(TimeOutCallback1, 10);
317 std::this_thread::sleep_for(std::chrono::milliseconds(52));
318 timer.Shutdown();
319 EXPECT_GE(g_data1, 8); /* 12 for max */
320 }
321
322 /*
323 * @tc.name: testTimer011
324 * @tc.desc: once timer register
325 */
326 HWTEST_F(UtilsTimerTest, testTimer011, TestSize.Level0)
327 {
328 g_data1 = 0;
329 Utils::Timer timer("test_timer");
330 uint32_t ret = timer.Setup();
331 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
332 timer.Register(TimeOutCallback1, 10);
333 timer.Register(TimeOutCallback1, 10, true);
334 timer.Register(TimeOutCallback1, 10);
335 timer.Register(TimeOutCallback1, 10, true);
336 std::this_thread::sleep_for(std::chrono::milliseconds(52));
337 timer.Shutdown();
338 EXPECT_GE(g_data1, 8); /* 12 for max */
339 }
340
341 /*
342 * @tc.name: testTimer012
343 * @tc.desc: Test double setup.
344 */
345 HWTEST_F(UtilsTimerTest, testTimer012, TestSize.Level0)
346 {
347 g_data1 = 0;
348 Utils::Timer timer("test_timer");
349 uint32_t ret = timer.Setup();
350 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
351 ret = timer.Setup();
352 EXPECT_EQ(Utils::TIMER_ERR_INVALID_VALUE, ret);
353
354 timer.Shutdown();
355 }
356
357 /*
358 * @tc.name: testTimer013
359 * @tc.desc: Test uncommon operations.
360 */
361 HWTEST_F(UtilsTimerTest, testTimer013, TestSize.Level0)
362 {
363 g_data1 = 0;
364 Utils::Timer timer("test_timer", -1);
365 uint32_t ret = timer.Setup();
366 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
367 std::this_thread::sleep_for(std::chrono::milliseconds(1));
368 timer.Shutdown();
369
370 Utils::Timer timer1("test_timer_1");
371 ret = timer1.Setup();
372 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
373 std::this_thread::sleep_for(std::chrono::milliseconds(1));
374 timer1.Shutdown(false);
375 }
376 } // namespace
377 } // namespace OHOS