1 /*
2 * Copyright (c) 2022 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 "watchdog_interface_test.h"
17
18 #include <gtest/gtest.h>
19 #include <string>
20 #include <thread>
21
22 #include "directory_ex.h"
23 #include "file_ex.h"
24 #include "event_handler.h"
25 #include "ffrt_inner.h"
26 #include "watchdog.h"
27
28 using namespace testing::ext;
29 using namespace OHOS::AppExecFwk;
30 namespace OHOS {
31 namespace HiviewDFX {
32 class TestEventHandler : public EventHandler {
33 public:
TestEventHandler(const std::shared_ptr<EventRunner> & runner)34 explicit TestEventHandler(const std::shared_ptr<EventRunner> &runner)
35 : EventHandler(runner) {};
~TestEventHandler()36 ~TestEventHandler() {};
ProcessEvent(const InnerEvent::Pointer & event)37 void ProcessEvent(const InnerEvent::Pointer &event)
38 {
39 count++;
40 }
41 int count;
42 };
43
44 constexpr int PERIODICAL_TASK_TIME = 2000;
45 constexpr int TOTAL_WAIT_TIME = 11;
46 constexpr int EXPECT_RUN_TIMES = 5;
SetUpTestCase(void)47 void WatchdogInterfaceTest::SetUpTestCase(void)
48 {
49 }
50
TearDownTestCase(void)51 void WatchdogInterfaceTest::TearDownTestCase(void)
52 {
53 }
54
SetUp(void)55 void WatchdogInterfaceTest::SetUp(void)
56 {
57 }
58
TearDown(void)59 void WatchdogInterfaceTest::TearDown(void)
60 {
61 }
62
63 int g_ret = 0;
DoAddWatchThread()64 void WatchdogInterfaceTest::DoAddWatchThread()
65 {
66 auto runner = EventRunner::Create("test_thread");
67 auto handler = std::make_shared<TestEventHandler>(runner);
68 g_ret += Watchdog::GetInstance().AddThread("DoAddWatchThread", handler);
69 handler.reset();
70 }
71
Sleep(int second)72 static inline void Sleep(int second)
73 {
74 int left = second;
75 while (left > 0) {
76 left = sleep(left);
77 }
78 }
79
80 /**
81 * @tc.name: Watchdog handler checker with default timeout
82 * @tc.desc: Verify default timeout in handler checker interface
83 * @tc.type: FUNC
84 */
85 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_001, TestSize.Level1)
86 {
87 /**
88 * @tc.steps: step1. post one task to handler
89 * @tc.expected: step1. post task successfully
90 */
91 constexpr int blockTime = 70;
__anon95347f570102() 92 auto blockFunc = []() {
93 printf("before block 70s in %d\n", getproctid());
94 Sleep(blockTime);
95 printf("after block 70s in %d\n", getproctid());
96 };
97 auto runner = EventRunner::Create(true);
98 auto handler = std::make_shared<TestEventHandler>(runner);
99 bool ret = handler->PostTask(blockFunc, "Block70s", 0, EventQueue::Priority::LOW);
100 ASSERT_EQ(ret, true);
101
102 /**
103 * @tc.steps: step2. add handler to watchdog and check the hisysevent result
104 * @tc.expected: step2. add handler to watchdog successfully
105 */
__anon95347f570202(const std::string &name, int waitState) 106 auto timeOutCallback = [](const std::string &name, int waitState) {
107 printf("TestBlock70s time out in %d, name is %s, waitState is %d\n", getproctid(), name.c_str(), waitState);
108 };
109 int result = Watchdog::GetInstance().AddThread("TestBlock70s", handler, timeOutCallback);
110 ASSERT_EQ(result, 0);
111
112 /**
113 * @tc.steps: step3. sleep a while until timeout
114 * @tc.expected: step3. SERVICE_BLOCK event has been created and fired
115 */
116 Sleep(blockTime);
117 }
118
119 /**
120 * @tc.name: Watchdog handler checker with customized timeout
121 * @tc.desc: Verify customized timeout in handler checker interface
122 * @tc.type: FUNC
123 */
124 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_002, TestSize.Level1)
125 {
126 /**
127 * @tc.steps: step1. post one task to handler
128 * @tc.expected: step1. post task successfully
129 */
130 constexpr int blockTime = 30;
131 constexpr int checkPeriod = 3000;
__anon95347f570302() 132 auto blockFunc = []() {
133 printf("before block 30s in %d\n", getproctid());
134 Sleep(blockTime);
135 printf("after block 30s in %d\n", getproctid());
136 };
137 auto runner = EventRunner::Create(true);
138 auto handler = std::make_shared<TestEventHandler>(runner);
139 bool ret = handler->PostTask(blockFunc, "Block30", 0, EventQueue::Priority::LOW);
140 ASSERT_EQ(ret, true);
141
142 /**
143 * @tc.steps: step2. add handler to watchdog and check the hisysevent result
144 * @tc.expected: step2. add handler to watchdog successfully
145 */
__anon95347f570402(const std::string &name, int waitState) 146 auto timeOutCallback = [](const std::string &name, int waitState) {
147 printf("TestBlock20 time out in %d, name is %s, waitState is %d\n", getproctid(), name.c_str(), waitState);
148 };
149 int result = Watchdog::GetInstance().AddThread("TestBlock20", handler, timeOutCallback, checkPeriod);
150
__anon95347f570502(const std::string &name, int waitState) 151 auto timeOutCallback1 = [](const std::string &name, int waitState) {
152 printf("TestBlock20_1 time out in %d, name is %s, waitState is %d\n", getproctid(), name.c_str(), waitState);
153 };
154 int result2 = Watchdog::GetInstance().AddThread("TestBlock20_1", handler, timeOutCallback1, checkPeriod);
155 ASSERT_EQ(result, 0);
156 ASSERT_EQ(result2, 0);
157
158 /**
159 * @tc.steps: step3. sleep a while until timeout
160 * @tc.expected: step3. SERVICE_BLOCK event has been created and fired
161 */
162 Sleep(blockTime);
163 }
164
165 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_003, TestSize.Level1)
166 {
167 constexpr int blockTime = 10;
168 constexpr int maxThread = 5;
169 std::vector<std::thread> threads(maxThread);
170 for (int i = 0; i < maxThread; i++) {
171 threads[i] = std::thread(&WatchdogInterfaceTest::DoAddWatchThread, this);
172 }
173
174 for (auto& th : threads) {
175 th.join();
176 }
177 ASSERT_EQ(g_ret, -4); // -4 : -1 * 4
178 Sleep(blockTime);
179 }
180
181 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_004, TestSize.Level1)
182 {
183 constexpr int blockTime = 10;
184 constexpr int checkPeriod = 2000;
185 auto runner = EventRunner::Create("test_thread");
186 auto handler = std::make_shared<TestEventHandler>(runner);
187 int ret = Watchdog::GetInstance().AddThread("BLOCK2S", handler, checkPeriod);
188 ASSERT_EQ(ret, 0);
189
__anon95347f570602() 190 auto taskFunc = []() { Sleep(blockTime); };
191 Watchdog::GetInstance().RunOneShotTask("block", taskFunc);
192 Sleep(blockTime);
193 }
194
195 /**
196 * @tc.name: Watchdog add thread without timeout callback
197 * @tc.desc: Remove thread, not occurred SERVICE_BLOCK.
198 * @tc.type: FUNC
199 */
200 HWTEST_F(WatchdogInterfaceTest, Watchdog_RemoveTreadTest_001, TestSize.Level1)
201 {
202 constexpr int blockTime = 2;
203 constexpr int checkPeriod = 1000;
__anon95347f570702() 204 auto blockFunc = []() {
205 printf("before block 2s in %d\n", getproctid());
206 Sleep(blockTime);
207 printf("after block 2s in %d\n", getproctid());
208 };
209 auto runner = EventRunner::Create(true);
210 auto handler = std::make_shared<TestEventHandler>(runner);
211 bool ret = handler->PostTask(blockFunc, "Block002", 0, EventQueue::Priority::LOW);
212 ASSERT_EQ(ret, true);
213
214 int result = Watchdog::GetInstance().AddThread("RemoveTest001", handler, nullptr, checkPeriod);
215 Watchdog::GetInstance().RemoveThread("RemoveTest001");
216 ASSERT_EQ(result, 0);
217 Sleep(blockTime);
218 result = Watchdog::GetInstance().AddThread("RemoveTest002", handler, nullptr, checkPeriod);
219 ASSERT_EQ(result, 0);
220 result = Watchdog::GetInstance().AddThread("RemoveTest003", handler, nullptr, checkPeriod);
221 ASSERT_EQ(result, 0);
222 Watchdog::GetInstance().RemoveThread("RemoveTest001");
223 }
224
225 /**
226 * @tc.name: Watchdog handler checker without timeout callback
227 * @tc.desc: Check whether SERVICE_BLOCK hisysevent is fired
228 * @tc.type: FUNC
229 */
230 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_005, TestSize.Level1)
231 {
232 constexpr int blockTime = 5;
233 constexpr int checkPeriod = 3000;
__anon95347f570802() 234 auto blockFunc = []() {
235 printf("before block 5s in %d\n", getproctid());
236 Sleep(blockTime);
237 printf("after block 5s in %d\n", getproctid());
238 };
239 auto runner = EventRunner::Create(true);
240 auto handler = std::make_shared<TestEventHandler>(runner);
241 bool ret = handler->PostTask(blockFunc, "Block10", 0, EventQueue::Priority::LOW);
242 ASSERT_EQ(ret, true);
243
244 int result = Watchdog::GetInstance().AddThread("HiCollieTestBlock10_0", handler, nullptr, checkPeriod);
245 int result2 = Watchdog::GetInstance().AddThread("HiCollieTestBlock10_2", handler, nullptr, checkPeriod);
246 ASSERT_EQ(result, 0);
247 ASSERT_EQ(result2, 0);
248
249 Sleep(blockTime);
250 }
251
252 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_006, TestSize.Level1)
253 {
254 printf("WatchdogHandlerCheckerTest_007 begin\n");
255 Watchdog::GetInstance().InitFfrtWatchdog();
256 ffrt::queue* testQueue = new ffrt::queue("test_queue");
257 ASSERT_TRUE(testQueue != nullptr);
__anon95347f570902null258 auto t = testQueue->submit_h([] {
259 ffrt::mutex lock;
260 lock.lock();
261 lock.unlock();
262 }, {});
263 ASSERT_TRUE(t != nullptr);
264 testQueue->wait(t);
265 delete testQueue;
266 }
267
268 /**
269 * @tc.name: Watchdog thread run a oneshot task
270 * @tc.desc: Verify whether the task has been executed successfully
271 * @tc.type: FUNC
272 */
273 HWTEST_F(WatchdogInterfaceTest, WatchdogRunTaskTest_001, TestSize.Level1)
274 {
275 /**
276 * @tc.steps: step1. create 2 oneshot task and add to watchdog
277 * @tc.expected: step1. task has been executed
278 */
279 constexpr int oneshotTaskTime = 1;
280 constexpr int delayedTaskTime = 3;
281 constexpr int delayedTaskTimeMillisecond = 3000;
282 int task1Result = 0;
__anon95347f570a02() 283 auto task1Func = [&task1Result]() { task1Result = 1; };
284 int task2Result = 0;
__anon95347f570b02() 285 auto task2Func = [&task2Result]() { task2Result = 1; };
286 Watchdog::GetInstance().RunOneShotTask("task1", task1Func);
287 Watchdog::GetInstance().RunOneShotTask("task2", task2Func);
288 Sleep(oneshotTaskTime);
289 ASSERT_EQ(task1Result, 1);
290 ASSERT_EQ(task2Result, 1);
291
292 /**
293 * @tc.steps: step2. create a delayed oneshot task and add to watchdog
294 * @tc.expected: step2. task has been executed
295 */
296 int delayedTaskResult = 0;
__anon95347f570c02() 297 auto delayedTaskFunc = [&delayedTaskResult]() { delayedTaskResult = 1; };
298 Watchdog::GetInstance().RunOneShotTask("task3", delayedTaskFunc, delayedTaskTimeMillisecond);
299 ASSERT_EQ(delayedTaskResult, 0);
300 Sleep(oneshotTaskTime + delayedTaskTime);
301 ASSERT_EQ(delayedTaskResult, 1);
302 }
303
304 /**
305 * @tc.name: Watchdog thread run a periodical task
306 * @tc.desc: Verify whether the task has been executed successfully
307 * @tc.type: FUNC
308 */
309 HWTEST_F(WatchdogInterfaceTest, WatchdogRunTaskTest_002, TestSize.Level1)
310 {
311 /**
312 * @tc.steps: step1. create periodical task and add to watchdog
313 * @tc.expected: step1. task has been executed
314 */
315 int taskResult = 0;
__anon95347f570d02() 316 auto taskFunc = [&taskResult]() { taskResult += 1; };
317 Watchdog::GetInstance().RunPeriodicalTask("periodicalTask", taskFunc, PERIODICAL_TASK_TIME);
318 Sleep(TOTAL_WAIT_TIME);
319 ASSERT_GT(taskResult, EXPECT_RUN_TIMES);
320 }
321
322 /**
323 * @tc.name: Watchdog thread run a periodical task and stop the watchdog
324 * @tc.desc: Verify whether the task has been executed
325 * @tc.type: FUNC
326 */
327 HWTEST_F(WatchdogInterfaceTest, WatchdogStopTest_001, TestSize.Level1)
328 {
329 /**
330 * @tc.steps: step1. create periodical task and add to watchdog
331 * @tc.expected: step1. task has not been executed
332 */
333 int taskResult = 0;
__anon95347f570e02() 334 auto taskFunc = [&taskResult]() { taskResult += 1; };
335 Watchdog::GetInstance().RunPeriodicalTask("periodicalTask2", taskFunc, PERIODICAL_TASK_TIME);
336 ASSERT_EQ(taskResult, 0);
337 Watchdog::GetInstance().StopWatchdog();
338 Sleep(TOTAL_WAIT_TIME);
339 }
340
341 /**
342 * @tc.name: Watchdog Set Or Get isAppDebug.
343 * @tc.desc: Verify isAppDebug is true
344 * @tc.type: FUNC
345 */
346 HWTEST_F(WatchdogInterfaceTest, WatchdogAppDebugTest_001, TestSize.Level1)
347 {
348 Watchdog::GetInstance().SetAppDebug(true);
349 ASSERT_TRUE(Watchdog::GetInstance().GetAppDebug());
350 }
351
352 /**
353 * @tc.name: Watchdog add thread without timeout callback
354 * @tc.desc: Occurred SERVICE_BLOCK.
355 * @tc.type: FUNC
356 */
357 HWTEST_F(WatchdogInterfaceTest, Watchdog_AddTreadTest_001, TestSize.Level1)
358 {
359 Watchdog::GetInstance().SetForeground(true);
360 Watchdog::GetInstance().SetBundleInfo("test", "1.1.0");
361 constexpr int blockTime = 2;
362 constexpr int checkPeriod = 1000;
__anon95347f570f02() 363 auto blockFunc = []() {
364 printf("before block 2s in %d\n", getproctid());
365 Sleep(blockTime);
366 printf("after block 2s in %d\n", getproctid());
367 };
368 auto runner = EventRunner::Create(true);
369 auto handler = std::make_shared<TestEventHandler>(runner);
370 bool ret = handler->PostTask(blockFunc, "Block001", 0, EventQueue::Priority::LOW);
371 ASSERT_EQ(ret, true);
372
373 int result = Watchdog::GetInstance().AddThread("AddTreadTest_001", handler, nullptr, checkPeriod);
374 ASSERT_EQ(result, 0);
375
376 Sleep(blockTime);
377 }
378
379 /**
380 * @tc.name: Watchdog SetSpecifiedProcessName test;
381 * @tc.desc: add testcase
382 * @tc.type: FUNC
383 */
384 HWTEST_F(WatchdogInterfaceTest, Watchdog_SetSpecifiedProcessNameTest_001, TestSize.Level1)
385 {
386 std::string testStr = "Watchdog_SetSpecifiedProcessNameTest_001";
387 Watchdog::GetInstance().SetSpecifiedProcessName(testStr);
388 EXPECT_TRUE(!testStr.empty());
389 }
390
391 /**
392 * @tc.name: Watchdog SetScrollState test;
393 * @tc.desc: add testcase
394 * @tc.type: FUNC
395 */
396 HWTEST_F(WatchdogInterfaceTest, Watchdog_SetScrollState_001, TestSize.Level1)
397 {
398 bool isScroll = true;
399 Watchdog::GetInstance().SetScrollState(isScroll);
400 EXPECT_EQ(isScroll, true);
401 }
402 } // namespace HiviewDFX
403 } // namespace OHOS
404