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 HWTEST_F(UtilsTimerTest, testTimer001, TestSize.Level1)
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.Level1)
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.Level1)
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.Level1)
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() {data_ -= 1;};
154 int data_;
155 Utils::Timer timer_;
156 };
157
Init()158 bool A::Init()
159 {
160 return timer_.Setup() == Utils::TIMER_ERR_OK;
161 }
162
StartTimer(int milliseconds,bool once)163 bool A::StartTimer(int milliseconds, bool once)
164 {
165 uint32_t timerId = timer_.Register(std::bind(&A::TimeOutProc, this), milliseconds, once);
166 return timerId != Utils::TIMER_ERR_DEAL_FAILED;
167 }
168
StopTimer()169 void A::StopTimer()
170 {
171 timer_.Shutdown();
172 }
173
174 /*
175 * @tc.name: testTimer005
176 * @tc.desc: timer unit test
177 */
178 HWTEST_F(UtilsTimerTest, testTimer005, TestSize.Level1)
179 {
180 A a(10);
181 EXPECT_TRUE(a.Init());
182 EXPECT_TRUE(a.StartTimer(1, false));
183 std::this_thread::sleep_for(std::chrono::milliseconds(10));
184 a.StopTimer();
185 EXPECT_GE(8, a.GetData());
186 }
187
188 /*
189 * @tc.name: testTimer006
190 * @tc.desc: timer unit test
191 */
192 HWTEST_F(UtilsTimerTest, testTimer006, TestSize.Level1)
193 {
194 A a(10);
195 EXPECT_TRUE(a.Init());
196 EXPECT_TRUE(a.StartTimer(1, true));
197 std::this_thread::sleep_for(std::chrono::milliseconds(20));
198 a.StopTimer();
199 EXPECT_EQ(9, a.GetData());
200 }
201
202 /*
203 * @tc.name: testTimer007
204 * @tc.desc: abnormal case
205 */
206 HWTEST_F(UtilsTimerTest, testTimer007, TestSize.Level1)
207 {
208 g_data1 = 0;
209 Utils::Timer timer("test_timer", -1);
210 uint32_t ret = timer.Setup();
211 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
212
213 uint32_t timerId = 0;
214 for (uint32_t i = 0; i < 10; i++) {
215 timerId = timer.Register(TimeOutCallback1, 7, true);
216 std::this_thread::sleep_for(std::chrono::milliseconds(10));
217 }
218 timer.Unregister(timerId);
219 timer.Unregister(timerId);
220
221 timer.Shutdown();
222 timer.Shutdown(false);
223 EXPECT_GE(g_data1, 5);
224 }
225
226 /*
227 * @tc.name: testTimer008
228 * @tc.desc: timer sleep test for ivi
229 */
230 HWTEST_F(UtilsTimerTest, testTimer008, TestSize.Level1)
231 {
232 g_data1 = 0;
233 Utils::Timer timer("test_timer");
234 uint32_t ret = timer.Setup();
235 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
236 timer.Register(TimeOutCallback1, 10);
237
238 for (int i = 0; i < 11; i++) {
239 int64_t pre = CurMs();
240 std::this_thread::sleep_for(std::chrono::milliseconds(10));
241 int64_t cur = CurMs();
242 EXPECT_GE(cur - pre, 10);
243 }
244 timer.Shutdown();
245 EXPECT_GE(g_data1, 10);
246 }
247
248 /*
249 * @tc.name: testTimer009
250 * @tc.desc: recursive test
251 */
DoFunc(Utils::Timer & timer,int & count)252 void DoFunc(Utils::Timer &timer, int &count)
253 {
254 (void)timer.Register(
255 [&timer, &count]() {
256 count += 1;
257 if (count > 9) {
258 return;
259 }
260 DoFunc(timer, count);
261 },
262 10, true);
263 g_data1++;
264 }
265
DoFunc2(Utils::Timer & timer,int & count)266 void DoFunc2(Utils::Timer &timer, int &count)
267 {
268 (void)timer.Register(
269 [&timer, &count]() {
270 count += 1;
271 if (count > 9) {
272 return;
273 }
274 DoFunc2(timer, count);
275 },
276 10, true);
277 g_data1++;
278 }
279
280 HWTEST_F(UtilsTimerTest, testTimer009, TestSize.Level1)
281 {
282 g_data1 = 0;
283 Utils::Timer timer("test_timer");
284 uint32_t ret = timer.Setup();
285 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
286
287 int cnt = 0, cnt1 = 0;
288 DoFunc(timer, cnt);
289 DoFunc2(timer, cnt1);
290 std::this_thread::sleep_for(std::chrono::milliseconds(50));
291 EXPECT_GE(g_data1, 5); /* 8 for max */
292 EXPECT_GE(14, g_data1); /* 10 for min */
293 std::this_thread::sleep_for(std::chrono::milliseconds(50));
294 timer.Shutdown();
295 EXPECT_GE(g_data1, 10); /* 18 for max */
296 }
297
298 /*
299 * @tc.name: testTimer010
300 * @tc.desc: once timer register
301 */
302 HWTEST_F(UtilsTimerTest, testTimer010, TestSize.Level1)
303 {
304 g_data1 = 0;
305 Utils::Timer timer("test_timer");
306 uint32_t ret = timer.Setup();
307 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
308 timer.Register(TimeOutCallback1, 10, true);
309 timer.Register(TimeOutCallback1, 10);
310 timer.Register(TimeOutCallback1, 10, true);
311 timer.Register(TimeOutCallback1, 10);
312 std::this_thread::sleep_for(std::chrono::milliseconds(52));
313 timer.Shutdown();
314 EXPECT_GE(g_data1, 8); /* 12 for max */
315 }
316
317 /*
318 * @tc.name: testTimer011
319 * @tc.desc: once timer register
320 */
321 HWTEST_F(UtilsTimerTest, testTimer011, TestSize.Level1)
322 {
323 g_data1 = 0;
324 Utils::Timer timer("test_timer");
325 uint32_t ret = timer.Setup();
326 EXPECT_EQ(Utils::TIMER_ERR_OK, ret);
327 timer.Register(TimeOutCallback1, 10);
328 timer.Register(TimeOutCallback1, 10, true);
329 timer.Register(TimeOutCallback1, 10);
330 timer.Register(TimeOutCallback1, 10, true);
331 std::this_thread::sleep_for(std::chrono::milliseconds(52));
332 timer.Shutdown();
333 EXPECT_GE(g_data1, 8); /* 12 for max */
334 }
335
336