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 "event_handler.h"
23 #include "watchdog.h"
24
25 using namespace testing::ext;
26 using namespace OHOS::AppExecFwk;
27 namespace OHOS {
28 namespace HiviewDFX {
29 class TestEventHandler : public EventHandler {
30 public:
TestEventHandler(const std::shared_ptr<EventRunner> & runner)31 explicit TestEventHandler(const std::shared_ptr<EventRunner> &runner)
32 : EventHandler(runner) {};
~TestEventHandler()33 ~TestEventHandler() {};
ProcessEvent(const InnerEvent::Pointer & event)34 void ProcessEvent(const InnerEvent::Pointer &event)
35 {
36 count++;
37 }
38 int count;
39 };
40
41 constexpr int PERIODICAL_TASK_TIME = 2000;
42 constexpr int TOTAL_WAIT_TIME = 11;
43 constexpr int EXPECT_RUN_TIMES = 5;
SetUpTestCase(void)44 void WatchdogInterfaceTest::SetUpTestCase(void)
45 {
46 }
47
TearDownTestCase(void)48 void WatchdogInterfaceTest::TearDownTestCase(void)
49 {
50 }
51
SetUp(void)52 void WatchdogInterfaceTest::SetUp(void)
53 {
54 }
55
TearDown(void)56 void WatchdogInterfaceTest::TearDown(void)
57 {
58 }
59
60 int g_ret = 0;
DoAddWatchThread()61 void WatchdogInterfaceTest::DoAddWatchThread()
62 {
63 auto runner = EventRunner::Create("test_thread");
64 auto handler = std::make_shared<TestEventHandler>(runner);
65 g_ret += Watchdog::GetInstance().AddThread("DoAddWatchThread", handler);
66 handler.reset();
67 }
68
Sleep(int second)69 static inline void Sleep(int second)
70 {
71 int left = second;
72 while (left > 0) {
73 left = sleep(left);
74 }
75 }
76
77 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_003, TestSize.Level1)
78 {
79 constexpr int BLOCK_TIME = 10;
80 constexpr int MAX_THREAD = 5;
81 std::vector<std::thread> threads(MAX_THREAD);
82 for (int i = 0; i < MAX_THREAD; i++) {
83 threads[i] = std::thread(&WatchdogInterfaceTest::DoAddWatchThread, this);
84 }
85
86 for (auto& th : threads) {
87 th.join();
88 }
89 ASSERT_EQ(g_ret, -4); // -4 : -1 * 4
90 Sleep(BLOCK_TIME);
91 }
92
93 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_004, TestSize.Level1)
94 {
95 constexpr int BLOCK_TIME = 10;
96 constexpr int CHECK_PERIOD = 2000;
97 auto runner = EventRunner::Create("test_thread");
98 auto handler = std::make_shared<TestEventHandler>(runner);
99 int ret = Watchdog::GetInstance().AddThread("BLOCK2S", handler, CHECK_PERIOD);
100 ASSERT_EQ(ret, 0);
101
__anonbe3e6b960102() 102 auto taskFunc = []() { Sleep(BLOCK_TIME); };
103 Watchdog::GetInstance().RunOneShotTask("block", taskFunc);
104 Sleep(BLOCK_TIME);
105 }
106
107 /**
108 * @tc.name: Watchdog handler checker with default timeout
109 * @tc.desc: Verify default timeout in handler checker interface
110 * @tc.type: FUNC
111 */
112 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_001, TestSize.Level1)
113 {
114 /**
115 * @tc.steps: step1. post one task to handler
116 * @tc.expected: step1. post task successfully
117 */
118 constexpr int BLOCK_TIME = 70;
__anonbe3e6b960202() 119 auto blockFunc = []() {
120 printf("before block 70s in %d\n", gettid());
121 Sleep(BLOCK_TIME);
122 printf("after block 70s in %d\n", gettid());
123 };
124 auto runner = EventRunner::Create(true);
125 auto handler = std::make_shared<TestEventHandler>(runner);
126 bool ret = handler->PostTask(blockFunc, "Block70s", 0, EventQueue::Priority::LOW);
127 ASSERT_EQ(ret, true);
128
129 /**
130 * @tc.steps: step2. add handler to watchdog and check the hisysevent result
131 * @tc.expected: step2. add handler to watchdog successfully
132 */
__anonbe3e6b960302(const std::string &name, int waitState) 133 auto timeOutCallback = [](const std::string &name, int waitState) {
134 printf("TestBlock70s time out in %d, name is %s, waitState is %d\n", gettid(), name.c_str(), waitState);
135 };
136 int result = Watchdog::GetInstance().AddThread("TestBlock70s", handler, timeOutCallback);
137 ASSERT_EQ(result, 0);
138
139 /**
140 * @tc.steps: step3. sleep a while until timeout
141 * @tc.expected: step3. SERVICE_BLOCK event has been created and fired
142 */
143 Sleep(BLOCK_TIME);
144 }
145
146 /**
147 * @tc.name: Watchdog handler checker with customized timeout
148 * @tc.desc: Verify customized timeout in handler checker interface
149 * @tc.type: FUNC
150 */
151 HWTEST_F(WatchdogInterfaceTest, WatchdogHandlerCheckerTest_002, TestSize.Level1)
152 {
153 /**
154 * @tc.steps: step1. post one task to handler
155 * @tc.expected: step1. post task successfully
156 */
157 constexpr int BLOCK_TIME = 30;
158 constexpr int CHECK_PERIOD = 3000;
__anonbe3e6b960402() 159 auto blockFunc = []() {
160 printf("before block 30s in %d\n", gettid());
161 Sleep(BLOCK_TIME);
162 printf("after block 30s in %d\n", gettid());
163 };
164 auto runner = EventRunner::Create(true);
165 auto handler = std::make_shared<TestEventHandler>(runner);
166 bool ret = handler->PostTask(blockFunc, "Block30", 0, EventQueue::Priority::LOW);
167 ASSERT_EQ(ret, true);
168
169 /**
170 * @tc.steps: step2. add handler to watchdog and check the hisysevent result
171 * @tc.expected: step2. add handler to watchdog successfully
172 */
__anonbe3e6b960502(const std::string &name, int waitState) 173 auto timeOutCallback = [](const std::string &name, int waitState) {
174 printf("TestBlock20 time out in %d, name is %s, waitState is %d\n", gettid(), name.c_str(), waitState);
175 };
176 int result = Watchdog::GetInstance().AddThread("TestBlock20", handler, timeOutCallback, CHECK_PERIOD);
177
__anonbe3e6b960602(const std::string &name, int waitState) 178 auto timeOutCallback1 = [](const std::string &name, int waitState) {
179 printf("TestBlock20_1 time out in %d, name is %s, waitState is %d\n", gettid(), name.c_str(), waitState);
180 };
181 int result2 = Watchdog::GetInstance().AddThread("TestBlock20_1", handler, timeOutCallback1, CHECK_PERIOD);
182 ASSERT_EQ(result, 0);
183 ASSERT_EQ(result2, 0);
184
185 /**
186 * @tc.steps: step3. sleep a while until timeout
187 * @tc.expected: step3. SERVICE_BLOCK event has been created and fired
188 */
189 Sleep(BLOCK_TIME);
190 }
191
192 /**
193 * @tc.name: Watchdog thread run a oneshot task
194 * @tc.desc: Verify whether the task has been executed successfully
195 * @tc.type: FUNC
196 */
197 HWTEST_F(WatchdogInterfaceTest, WatchdogRunTaskTest_001, TestSize.Level1)
198 {
199 /**
200 * @tc.steps: step1. create 2 oneshot task and add to watchdog
201 * @tc.expected: step1. task has been executed
202 */
203 constexpr int ONESHOT_TASK_TIME = 1;
204 constexpr int DELAYED_TASK_TIME = 3;
205 constexpr int DELAYED_TASK_TIME_MILLISECOND = 3000;
206 int task1Result = 0;
__anonbe3e6b960702() 207 auto task1Func = [&task1Result]() { task1Result = 1; };
208 int task2Result = 0;
__anonbe3e6b960802() 209 auto task2Func = [&task2Result]() { task2Result = 1; };
210 Watchdog::GetInstance().RunOneShotTask("task1", task1Func);
211 Watchdog::GetInstance().RunOneShotTask("task2", task2Func);
212 Sleep(ONESHOT_TASK_TIME);
213 ASSERT_EQ(task1Result, 1);
214 ASSERT_EQ(task2Result, 1);
215
216 /**
217 * @tc.steps: step2. create a delayed oneshot task and add to watchdog
218 * @tc.expected: step2. task has been executed
219 */
220 int delayedTaskResult = 0;
__anonbe3e6b960902() 221 auto delayedTaskFunc = [&delayedTaskResult]() { delayedTaskResult = 1; };
222 Watchdog::GetInstance().RunOneShotTask("task3", delayedTaskFunc, DELAYED_TASK_TIME_MILLISECOND);
223 ASSERT_EQ(delayedTaskResult, 0);
224 Sleep(ONESHOT_TASK_TIME + DELAYED_TASK_TIME);
225 ASSERT_EQ(delayedTaskResult, 1);
226 }
227
228 /**
229 * @tc.name: Watchdog thread run a periodical task
230 * @tc.desc: Verify whether the task has been executed successfully
231 * @tc.type: FUNC
232 */
233 HWTEST_F(WatchdogInterfaceTest, WatchdogRunTaskTest_002, TestSize.Level1)
234 {
235 /**
236 * @tc.steps: step1. create periodical task and add to watchdog
237 * @tc.expected: step1. task has been executed
238 */
239 int taskResult = 0;
__anonbe3e6b960a02() 240 auto taskFunc = [&taskResult]() { taskResult += 1; };
241 Watchdog::GetInstance().RunPeriodicalTask("periodicalTask", taskFunc, PERIODICAL_TASK_TIME);
242 Sleep(TOTAL_WAIT_TIME);
243 ASSERT_GT(taskResult, EXPECT_RUN_TIMES);
244 }
245
246 /**
247 * @tc.name: Watchdog thread run a periodical task and stop the watchdog
248 * @tc.desc: Verify whether the task has been executed
249 * @tc.type: FUNC
250 */
251 HWTEST_F(WatchdogInterfaceTest, WatchdogStopTest_001, TestSize.Level1)
252 {
253 /**
254 * @tc.steps: step1. create periodical task and add to watchdog
255 * @tc.expected: step1. task has not been executed
256 */
257 int taskResult = 0;
__anonbe3e6b960b02() 258 auto taskFunc = [&taskResult]() { taskResult += 1; };
259 Watchdog::GetInstance().RunPeriodicalTask("periodicalTask2", taskFunc, PERIODICAL_TASK_TIME);
260 ASSERT_EQ(taskResult, 0);
261 Watchdog::GetInstance().StopWatchdog();
262 Sleep(TOTAL_WAIT_TIME);
263 ASSERT_EQ(taskResult, 0);
264 }
265 } // namespace HiviewDFX
266 } // namespace OHOS
267