• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
__anon9420ee760102() 92     auto blockFunc = []() {
93         printf("before block 70s in %d\n", gettid());
94         Sleep(blockTime);
95         printf("after block 70s in %d\n", gettid());
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      */
__anon9420ee760202(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", gettid(), 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;
__anon9420ee760302() 132     auto blockFunc = []() {
133         printf("before block 30s in %d\n", gettid());
134         Sleep(blockTime);
135         printf("after block 30s in %d\n", gettid());
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      */
__anon9420ee760402(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", gettid(), name.c_str(), waitState);
148     };
149     int result = Watchdog::GetInstance().AddThread("TestBlock20", handler, timeOutCallback, checkPeriod);
150 
__anon9420ee760502(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", gettid(), 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 
__anon9420ee760602() 190     auto taskFunc = []() { Sleep(blockTime); };
191     Watchdog::GetInstance().RunOneShotTask("block", taskFunc);
192     Sleep(blockTime);
193 }
194 
195 /**
196  * @tc.name: Watchdog handler checker without timeout callback
197  * @tc.desc: Check whether SERVICE_BLOCK hisysevent is fired
198  * @tc.type: FUNC
199  */
200 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_005, TestSize.Level1)
201 {
202     constexpr int blockTime = 5;
203     constexpr int checkPeriod = 3000;
__anon9420ee760702() 204     auto blockFunc = []() {
205         printf("before block 5s in %d\n", gettid());
206         Sleep(blockTime);
207         printf("after block 5s in %d\n", gettid());
208     };
209     auto runner = EventRunner::Create(true);
210     auto handler = std::make_shared<TestEventHandler>(runner);
211     bool ret = handler->PostTask(blockFunc, "Block10", 0, EventQueue::Priority::LOW);
212     ASSERT_EQ(ret, true);
213 
214     int result = Watchdog::GetInstance().AddThread("HiCollieTestBlock10_0", handler, nullptr, checkPeriod);
215     int result2 = Watchdog::GetInstance().AddThread("HiCollieTestBlock10_2", handler, nullptr, checkPeriod);
216     ASSERT_EQ(result, 0);
217     ASSERT_EQ(result2, 0);
218 
219     Sleep(blockTime);
220 }
221 
222 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_006, TestSize.Level1)
223 {
224     printf("WatchdogHandlerCheckerTest_007 begin\n");
225     Watchdog::GetInstance().InitFfrtWatchdog();
226     ffrt::queue* testQueue = new ffrt::queue("test_queue");
__anon9420ee760802null227     auto t = testQueue->submit_h([] {
228         ffrt::mutex lock;
229         lock.lock();
230         lock.unlock();
231     }, {});
232     testQueue->wait(t);
233     delete testQueue;
234 }
235 
236 /**
237  * @tc.name: Watchdog thread run a oneshot task
238  * @tc.desc: Verify whether the task has been executed successfully
239  * @tc.type: FUNC
240  */
241 HWTEST_F(WatchdogInterfaceTest, WatchdogRunTaskTest_001, TestSize.Level1)
242 {
243     /**
244      * @tc.steps: step1. create 2 oneshot task and add to watchdog
245      * @tc.expected: step1. task has been executed
246      */
247     constexpr int oneshotTaskTime = 1;
248     constexpr int delayedTaskTime = 3;
249     constexpr int delayedTaskTimeMillisecond = 3000;
250     int task1Result = 0;
__anon9420ee760902() 251     auto task1Func = [&task1Result]() { task1Result = 1; };
252     int task2Result = 0;
__anon9420ee760a02() 253     auto task2Func = [&task2Result]() { task2Result = 1; };
254     Watchdog::GetInstance().RunOneShotTask("task1", task1Func);
255     Watchdog::GetInstance().RunOneShotTask("task2", task2Func);
256     Sleep(oneshotTaskTime);
257     ASSERT_EQ(task1Result, 1);
258     ASSERT_EQ(task2Result, 1);
259 
260     /**
261      * @tc.steps: step2. create a delayed oneshot task and add to watchdog
262      * @tc.expected: step2. task has been executed
263      */
264     int delayedTaskResult = 0;
__anon9420ee760b02() 265     auto delayedTaskFunc = [&delayedTaskResult]() { delayedTaskResult = 1; };
266     Watchdog::GetInstance().RunOneShotTask("task3", delayedTaskFunc, delayedTaskTimeMillisecond);
267     ASSERT_EQ(delayedTaskResult, 0);
268     Sleep(oneshotTaskTime + delayedTaskTime);
269     ASSERT_EQ(delayedTaskResult, 1);
270 }
271 
272 /**
273  * @tc.name: Watchdog thread run a periodical task
274  * @tc.desc: Verify whether the task has been executed successfully
275  * @tc.type: FUNC
276  */
277 HWTEST_F(WatchdogInterfaceTest, WatchdogRunTaskTest_002, TestSize.Level1)
278 {
279     /**
280      * @tc.steps: step1. create periodical task and add to watchdog
281      * @tc.expected: step1. task has been executed
282      */
283     int taskResult = 0;
__anon9420ee760c02() 284     auto taskFunc = [&taskResult]() { taskResult += 1; };
285     Watchdog::GetInstance().RunPeriodicalTask("periodicalTask", taskFunc, PERIODICAL_TASK_TIME);
286     Sleep(TOTAL_WAIT_TIME);
287     ASSERT_GT(taskResult, EXPECT_RUN_TIMES);
288 }
289 
290 /**
291  * @tc.name: Watchdog thread run a periodical task and stop the watchdog
292  * @tc.desc: Verify whether the task has been executed
293  * @tc.type: FUNC
294  */
295 HWTEST_F(WatchdogInterfaceTest, WatchdogStopTest_001, TestSize.Level1)
296 {
297     /**
298      * @tc.steps: step1. create periodical task and add to watchdog
299      * @tc.expected: step1. task has not been executed
300      */
301     int taskResult = 0;
__anon9420ee760d02() 302     auto taskFunc = [&taskResult]() { taskResult += 1; };
303     Watchdog::GetInstance().RunPeriodicalTask("periodicalTask2", taskFunc, PERIODICAL_TASK_TIME);
304     ASSERT_EQ(taskResult, 0);
305     Watchdog::GetInstance().StopWatchdog();
306     Sleep(TOTAL_WAIT_TIME);
307     ASSERT_EQ(taskResult, 0);
308 }
309 } // namespace HiviewDFX
310 } // namespace OHOS
311