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 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_007, TestSize.Level1)
81 {
82 printf("WatchdogHandlerCheckerTest_007 begin\n");
83 Watchdog::GetInstance().InitFfrtWatchdog();
84 ffrt::queue* testQueue = new ffrt::queue("test_queue");
__anonc7fc96150102null85 auto t = testQueue->submit_h([] { sleep(70); }, {});
86 testQueue->wait(t);
87 delete testQueue;
88 }
89
90 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_006, TestSize.Level1)
91 {
92 constexpr int BLOCK_TIME = 6;
__anonc7fc96150202() 93 auto blockFunc = []() {
94 printf("start verify kickWatchdog in tid %d\n", gettid());
95 };
96 auto runner =EventRunner::Create(true);
97 auto handler =std::make_shared<TestEventHandler>(runner);
98 bool ret = handler->PostTask(blockFunc, "kickWatchdog", 0, EventQueue::Priority::LOW);
99 ASSERT_EQ(ret, true);
100
__anonc7fc96150302(const std::string &name, int waitState) 101 auto timeOutCallback = [](const std::string &name, int waitState) {
102 printf("verify kickWatchdog in %d, name is %s, waitstate in %d\n", gettid(), name.c_str(), waitState);
103 };
104 int result = Watchdog::GetInstance().AddThread("WindowManagerService", handler, timeOutCallback);
105 ASSERT_EQ(result, 0);
106 Sleep(BLOCK_TIME);
107 }
108
109
110 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_003, TestSize.Level1)
111 {
112 constexpr int blockTime = 10;
113 constexpr int maxThread = 5;
114 std::vector<std::thread> threads(maxThread);
115 for (int i = 0; i < maxThread; i++) {
116 threads[i] = std::thread(&WatchdogInterfaceTest::DoAddWatchThread, this);
117 }
118
119 for (auto& th : threads) {
120 th.join();
121 }
122 ASSERT_EQ(g_ret, -4); // -4 : -1 * 4
123 Sleep(blockTime);
124 }
125
126 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_004, TestSize.Level1)
127 {
128 constexpr int blockTime = 10;
129 constexpr int checkPeriod = 2000;
130 auto runner = EventRunner::Create("test_thread");
131 auto handler = std::make_shared<TestEventHandler>(runner);
132 int ret = Watchdog::GetInstance().AddThread("BLOCK2S", handler, checkPeriod);
133 ASSERT_EQ(ret, 0);
134
__anonc7fc96150402() 135 auto taskFunc = []() { Sleep(blockTime); };
136 Watchdog::GetInstance().RunOneShotTask("block", taskFunc);
137 Sleep(blockTime);
138 }
139
140 /**
141 * @tc.name: Watchdog handler checker with default timeout
142 * @tc.desc: Verify default timeout in handler checker interface
143 * @tc.type: FUNC
144 */
145 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_001, TestSize.Level1)
146 {
147 /**
148 * @tc.steps: step1. post one task to handler
149 * @tc.expected: step1. post task successfully
150 */
151 constexpr int blockTime = 70;
__anonc7fc96150502() 152 auto blockFunc = []() {
153 printf("before block 70s in %d\n", gettid());
154 Sleep(blockTime);
155 printf("after block 70s in %d\n", gettid());
156 };
157 auto runner = EventRunner::Create(true);
158 auto handler = std::make_shared<TestEventHandler>(runner);
159 bool ret = handler->PostTask(blockFunc, "Block70s", 0, EventQueue::Priority::LOW);
160 ASSERT_EQ(ret, true);
161
162 /**
163 * @tc.steps: step2. add handler to watchdog and check the hisysevent result
164 * @tc.expected: step2. add handler to watchdog successfully
165 */
__anonc7fc96150602(const std::string &name, int waitState) 166 auto timeOutCallback = [](const std::string &name, int waitState) {
167 printf("TestBlock70s time out in %d, name is %s, waitState is %d\n", gettid(), name.c_str(), waitState);
168 };
169 int result = Watchdog::GetInstance().AddThread("TestBlock70s", handler, timeOutCallback);
170 ASSERT_EQ(result, 0);
171
172 /**
173 * @tc.steps: step3. sleep a while until timeout
174 * @tc.expected: step3. SERVICE_BLOCK event has been created and fired
175 */
176 Sleep(blockTime);
177 }
178
179 /**
180 * @tc.name: Watchdog handler checker with customized timeout
181 * @tc.desc: Verify customized timeout in handler checker interface
182 * @tc.type: FUNC
183 */
184 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_002, TestSize.Level1)
185 {
186 /**
187 * @tc.steps: step1. post one task to handler
188 * @tc.expected: step1. post task successfully
189 */
190 constexpr int blockTime = 30;
191 constexpr int checkPeriod = 3000;
__anonc7fc96150702() 192 auto blockFunc = []() {
193 printf("before block 30s in %d\n", gettid());
194 Sleep(blockTime);
195 printf("after block 30s in %d\n", gettid());
196 };
197 auto runner = EventRunner::Create(true);
198 auto handler = std::make_shared<TestEventHandler>(runner);
199 bool ret = handler->PostTask(blockFunc, "Block30", 0, EventQueue::Priority::LOW);
200 ASSERT_EQ(ret, true);
201
202 /**
203 * @tc.steps: step2. add handler to watchdog and check the hisysevent result
204 * @tc.expected: step2. add handler to watchdog successfully
205 */
__anonc7fc96150802(const std::string &name, int waitState) 206 auto timeOutCallback = [](const std::string &name, int waitState) {
207 printf("TestBlock20 time out in %d, name is %s, waitState is %d\n", gettid(), name.c_str(), waitState);
208 };
209 int result = Watchdog::GetInstance().AddThread("TestBlock20", handler, timeOutCallback, checkPeriod);
210
__anonc7fc96150902(const std::string &name, int waitState) 211 auto timeOutCallback1 = [](const std::string &name, int waitState) {
212 printf("TestBlock20_1 time out in %d, name is %s, waitState is %d\n", gettid(), name.c_str(), waitState);
213 };
214 int result2 = Watchdog::GetInstance().AddThread("TestBlock20_1", handler, timeOutCallback1, checkPeriod);
215 ASSERT_EQ(result, 0);
216 ASSERT_EQ(result2, 0);
217
218 /**
219 * @tc.steps: step3. sleep a while until timeout
220 * @tc.expected: step3. SERVICE_BLOCK event has been created and fired
221 */
222 Sleep(blockTime);
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;
__anonc7fc96150a02() 234 auto blockFunc = []() {
235 printf("before block 5s in %d\n", gettid());
236 Sleep(blockTime);
237 printf("after block 5s in %d\n", gettid());
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 /**
253 * @tc.name: Watchdog thread run a oneshot task
254 * @tc.desc: Verify whether the task has been executed successfully
255 * @tc.type: FUNC
256 */
257 HWTEST_F(WatchdogInterfaceTest, WatchdogRunTaskTest_001, TestSize.Level1)
258 {
259 /**
260 * @tc.steps: step1. create 2 oneshot task and add to watchdog
261 * @tc.expected: step1. task has been executed
262 */
263 constexpr int oneshotTaskTime = 1;
264 constexpr int delayedTaskTime = 3;
265 constexpr int delayedTaskTimeMillisecond = 3000;
266 int task1Result = 0;
__anonc7fc96150b02() 267 auto task1Func = [&task1Result]() { task1Result = 1; };
268 int task2Result = 0;
__anonc7fc96150c02() 269 auto task2Func = [&task2Result]() { task2Result = 1; };
270 Watchdog::GetInstance().RunOneShotTask("task1", task1Func);
271 Watchdog::GetInstance().RunOneShotTask("task2", task2Func);
272 Sleep(oneshotTaskTime);
273 ASSERT_EQ(task1Result, 1);
274 ASSERT_EQ(task2Result, 1);
275
276 /**
277 * @tc.steps: step2. create a delayed oneshot task and add to watchdog
278 * @tc.expected: step2. task has been executed
279 */
280 int delayedTaskResult = 0;
__anonc7fc96150d02() 281 auto delayedTaskFunc = [&delayedTaskResult]() { delayedTaskResult = 1; };
282 Watchdog::GetInstance().RunOneShotTask("task3", delayedTaskFunc, delayedTaskTimeMillisecond);
283 ASSERT_EQ(delayedTaskResult, 0);
284 Sleep(oneshotTaskTime + delayedTaskTime);
285 ASSERT_EQ(delayedTaskResult, 1);
286 }
287
288 /**
289 * @tc.name: Watchdog thread run a periodical task
290 * @tc.desc: Verify whether the task has been executed successfully
291 * @tc.type: FUNC
292 */
293 HWTEST_F(WatchdogInterfaceTest, WatchdogRunTaskTest_002, TestSize.Level1)
294 {
295 /**
296 * @tc.steps: step1. create periodical task and add to watchdog
297 * @tc.expected: step1. task has been executed
298 */
299 int taskResult = 0;
__anonc7fc96150e02() 300 auto taskFunc = [&taskResult]() { taskResult += 1; };
301 Watchdog::GetInstance().RunPeriodicalTask("periodicalTask", taskFunc, PERIODICAL_TASK_TIME);
302 Sleep(TOTAL_WAIT_TIME);
303 ASSERT_GT(taskResult, EXPECT_RUN_TIMES);
304 }
305
306 /**
307 * @tc.name: Watchdog thread run a periodical task and stop the watchdog
308 * @tc.desc: Verify whether the task has been executed
309 * @tc.type: FUNC
310 */
311 HWTEST_F(WatchdogInterfaceTest, WatchdogStopTest_001, TestSize.Level1)
312 {
313 /**
314 * @tc.steps: step1. create periodical task and add to watchdog
315 * @tc.expected: step1. task has not been executed
316 */
317 int taskResult = 0;
__anonc7fc96150f02() 318 auto taskFunc = [&taskResult]() { taskResult += 1; };
319 Watchdog::GetInstance().RunPeriodicalTask("periodicalTask2", taskFunc, PERIODICAL_TASK_TIME);
320 ASSERT_EQ(taskResult, 0);
321 Watchdog::GetInstance().StopWatchdog();
322 Sleep(TOTAL_WAIT_TIME);
323 ASSERT_EQ(taskResult, 0);
324 }
325 } // namespace HiviewDFX
326 } // namespace OHOS
327