1 /*
2 * Copyright (c) 2020-2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "watchdog_test.h"
10 #include "hdf_base.h"
11 #include "hdf_io_service_if.h"
12 #include "hdf_log.h"
13 #include "osal_mem.h"
14 #include "osal_time.h"
15 #include "securec.h"
16 #include "watchdog_if.h"
17
18 #define HDF_LOG_TAG watchdog_test
19 static int32_t g_wdtState = 0;
20
21 struct WatchdogTestEntry {
22 int cmd;
23 int32_t (*func)(struct WatchdogTester *tester);
24 };
25
WatchdogTestGetTestConfig(struct WatchdogTestConfig * config)26 static int32_t WatchdogTestGetTestConfig(struct WatchdogTestConfig *config)
27 {
28 int32_t ret;
29 struct HdfSBuf *reply = NULL;
30 struct HdfIoService *service = NULL;
31 const void *buf = NULL;
32 uint32_t len;
33
34 service = HdfIoServiceBind("WATCHDOG_TEST");
35 if ((service == NULL) || (service->dispatcher == NULL) || (service->dispatcher->Dispatch == NULL)) {
36 HDF_LOGE("WatchdogTestGetTestConfig: service null!");
37 return HDF_ERR_NOT_SUPPORT;
38 }
39
40 reply = HdfSbufObtain(sizeof(*config) + sizeof(uint64_t));
41 if (reply == NULL) {
42 HDF_LOGE("WatchdogTestGetTestConfig: fail to obtain reply!");
43 HdfIoServiceRecycle(service);
44 return HDF_ERR_MALLOC_FAIL;
45 }
46
47 ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
48 if (ret != HDF_SUCCESS) {
49 HDF_LOGE("WatchdogTestGetTestConfig: remote dispatch fail, ret: %d!", ret);
50 HdfIoServiceRecycle(service);
51 HdfSbufRecycle(reply);
52 return ret;
53 }
54
55 if (!HdfSbufReadBuffer(reply, &buf, &len)) {
56 HDF_LOGE("WatchdogTestGetTestConfig: read buf fail!");
57 HdfIoServiceRecycle(service);
58 HdfSbufRecycle(reply);
59 return HDF_ERR_IO;
60 }
61
62 if (len != sizeof(*config)) {
63 HDF_LOGE("WatchdogTestGetTestConfig: config size:%zu, read size:%u!", sizeof(*config), len);
64 HdfIoServiceRecycle(service);
65 HdfSbufRecycle(reply);
66 return HDF_ERR_IO;
67 }
68
69 if (memcpy_s(config, sizeof(*config), buf, sizeof(*config)) != EOK) {
70 HDF_LOGE("WatchdogTestGetTestConfig: memcpy buf fail!");
71 HdfIoServiceRecycle(service);
72 HdfSbufRecycle(reply);
73 return HDF_ERR_IO;
74 }
75 HdfIoServiceRecycle(service);
76 HdfSbufRecycle(reply);
77 return HDF_SUCCESS;
78 }
79
WatchdogTesterGet(void)80 static struct WatchdogTester *WatchdogTesterGet(void)
81 {
82 int32_t ret;
83 static struct WatchdogTester tester;
84
85 ret = WatchdogTestGetTestConfig(&tester.config);
86 if (ret != HDF_SUCCESS) {
87 HDF_LOGE("WatchdogTesterGet: read config fail, ret: %d!", ret);
88 return NULL;
89 }
90
91 ret = WatchdogOpen(tester.config.id, &tester.handle);
92 if (ret != HDF_SUCCESS) {
93 if (ret == HDF_ERR_DEVICE_BUSY) {
94 g_wdtState = ret;
95 }
96 HDF_LOGE("WatchdogTesterGet: open watchdog_%d fail, ret: %d!", tester.config.id, ret);
97 return NULL;
98 }
99
100 return &tester;
101 }
102
WatchdogTesterPut(struct WatchdogTester * tester)103 static void WatchdogTesterPut(struct WatchdogTester *tester)
104 {
105 if (tester == NULL) {
106 HDF_LOGE("WatchdogTesterPut: tester is null!");
107 return;
108 }
109 WatchdogClose(tester->handle);
110 tester->handle = NULL;
111 }
112
TestCaseWatchdogSetGetTimeout(struct WatchdogTester * tester)113 static int32_t TestCaseWatchdogSetGetTimeout(struct WatchdogTester *tester)
114 {
115 int32_t ret;
116 uint32_t timeoutGet = 0;
117
118 ret = WatchdogSetTimeout(tester->handle, tester->config.timeoutSet);
119 if (ret != HDF_SUCCESS) {
120 HDF_LOGE("TestCaseWatchdogSetGetTimeout: set timeout fail, ret: %d!", ret);
121 return ret;
122 }
123 ret = WatchdogGetTimeout(tester->handle, &timeoutGet);
124 if (ret != HDF_SUCCESS) {
125 HDF_LOGE("TestCaseWatchdogSetGetTimeout: get timeout fail, ret: %d!", ret);
126 return ret;
127 }
128 if (tester->config.timeoutSet != timeoutGet) {
129 HDF_LOGE("TestCaseWatchdogSetGetTimeout: set:%u, but get:%u!", tester->config.timeoutSet, timeoutGet);
130 return HDF_FAILURE;
131 }
132
133 return HDF_SUCCESS;
134 }
135
TestCaseWatchdogStartStop(struct WatchdogTester * tester)136 static int32_t TestCaseWatchdogStartStop(struct WatchdogTester *tester)
137 {
138 int32_t ret;
139 int32_t status;
140
141 ret = WatchdogStart(tester->handle);
142 if (ret != HDF_SUCCESS) {
143 HDF_LOGE("TestCaseWatchdogStartStop: satrt fail, ret: %d!", ret);
144 return ret;
145 }
146 status = WATCHDOG_STOP;
147 ret = WatchdogGetStatus(tester->handle, &status);
148 if (ret != HDF_SUCCESS) {
149 HDF_LOGE("TestCaseWatchdogStartStop: get status fail, ret: %d!", ret);
150 return ret;
151 }
152 if (status != WATCHDOG_START) {
153 HDF_LOGE("TestCaseWatchdogStartStop: status is:%d after start!", status);
154 return HDF_FAILURE;
155 }
156
157 ret = WatchdogStop(tester->handle);
158 if (ret != HDF_SUCCESS) {
159 HDF_LOGE("TestCaseWatchdogStartStop: stop fail, ret: %d!", ret);
160 return ret;
161 }
162 status = WATCHDOG_START;
163 ret = WatchdogGetStatus(tester->handle, &status);
164 if (status != WATCHDOG_STOP) {
165 HDF_LOGE("TestCaseWatchdogStartStop: status is:%d after stop!", status);
166 return HDF_FAILURE;
167 }
168
169 return HDF_SUCCESS;
170 }
171
TestCaseWatchdogFeed(struct WatchdogTester * tester)172 static int32_t TestCaseWatchdogFeed(struct WatchdogTester *tester)
173 {
174 int32_t ret;
175 uint32_t i;
176
177 ret = WatchdogStart(tester->handle);
178 if (ret != HDF_SUCCESS) {
179 HDF_LOGE("TestCaseWatchdogFeed: satrt fail, ret: %d!", ret);
180 return ret;
181 }
182
183 for (i = 0; i < tester->config.feedTime; i++) {
184 HDF_LOGE("TestCaseWatchdogFeed: feeding watchdog %d times... ", i);
185 ret = WatchdogFeed(tester->handle);
186 if (ret != HDF_SUCCESS) {
187 HDF_LOGE("TestCaseWatchdogFeed: feed dog fail, ret: %d!", ret);
188 return ret;
189 }
190 OsalSleep(1);
191 }
192
193 ret = WatchdogStop(tester->handle);
194 if (ret != HDF_SUCCESS) {
195 HDF_LOGE("TestCaseWatchdogFeed: stop fail, ret: %d!", ret);
196 return ret;
197 }
198
199 HDF_LOGD("TestCaseWatchdogFeed: no reset ... feeding test OK!!!");
200 return HDF_SUCCESS;
201 }
202
TestCaseWatchdogBark(struct WatchdogTester * tester)203 static int32_t TestCaseWatchdogBark(struct WatchdogTester *tester)
204 {
205 #ifdef WATCHDOG_TEST_BARK_RESET
206 int32_t ret;
207 int32_t i;
208
209 ret = WatchdogStart(tester->handle);
210 if (ret != HDF_SUCCESS) {
211 HDF_LOGE("TestCaseWatchdogBark: satrt fail, ret: %d!", ret);
212 return ret;
213 }
214
215 for (i = 0; i < tester->config.feedTime; i++) {
216 HDF_LOGE("TestCaseWatchdogBark: watiting dog buck %d times... ", i);
217 OsalSleep(1);
218 }
219
220 HDF_LOGE("TestCaseWatchdogBark: dog has't buck!!! ", i);
221 return HDF_FAILURE;
222 #else
223 (void)tester;
224 return HDF_SUCCESS;
225 #endif
226 }
227
TestCaseWatchdogReliability(struct WatchdogTester * tester)228 static int32_t TestCaseWatchdogReliability(struct WatchdogTester *tester)
229 {
230 int32_t status;
231 uint32_t timeout;
232
233 HDF_LOGD("TestCaseWatchdogReliability: test dfr for WatchdogGetStatus ...");
234 /* invalid device handle */
235 (void)WatchdogGetStatus(NULL, &status);
236 /* invalid status pointer */
237 (void)WatchdogGetStatus(tester->handle, NULL);
238
239 HDF_LOGD("TestCaseWatchdogReliability: test dfr for WatchdogStart&Stop ...");
240 /* invalid device handle */
241 (void)WatchdogStart(NULL);
242 /* invalid device handle */
243 (void)WatchdogStop(NULL);
244
245 HDF_LOGD("TestCaseWatchdogReliability: test dfr for WatchdogSet&GetTimeout ...");
246 /* invalid device handle */
247 (void)WatchdogSetTimeout(NULL, tester->config.timeoutSet);
248 /* invalid device handle */
249 (void)WatchdogGetTimeout(NULL, &timeout);
250 /* invalid timeout pointer */
251 (void)WatchdogGetTimeout(tester->handle, NULL);
252
253 HDF_LOGD("TestCaseWatchdogReliability: test dfr for WatchdogFeed ...");
254 /* invalid device handle */
255 (void)WatchdogFeed(NULL);
256
257 return HDF_SUCCESS;
258 }
259
TestCaseWatchdogIfPerformanceTest(struct WatchdogTester * tester)260 static int32_t TestCaseWatchdogIfPerformanceTest(struct WatchdogTester *tester)
261 {
262 #ifdef __LITEOS__
263 // liteos the accuracy of the obtained time is too large and inaccurate.
264 if (tester == NULL) {
265 HDF_LOGE("TestCaseWatchdogIfPerformanceTest: tester is null!");
266 return HDF_FAILURE;
267 }
268 return HDF_SUCCESS;
269 #endif
270
271 uint32_t timeoutGet = 0;
272 uint64_t startMs;
273 uint64_t endMs;
274 uint64_t useTime; // ms
275
276 if (tester == NULL) {
277 HDF_LOGE("TestCaseWatchdogIfPerformanceTest: tester is null!");
278 return HDF_FAILURE;
279 }
280
281 startMs = OsalGetSysTimeMs();
282 WatchdogGetTimeout(tester->handle, &timeoutGet);
283 endMs = OsalGetSysTimeMs();
284
285 useTime = endMs - startMs;
286 HDF_LOGI("TestCaseWatchdogIfPerformanceTest: ----->interface performance test:[start - end] < 1ms[%s]\r\n",
287 useTime < 1 ? "yes" : "no");
288 return HDF_SUCCESS;
289 }
290
291 static struct WatchdogTestEntry g_entry[] = {
292 { WATCHDOG_TEST_SET_GET_TIMEOUT, TestCaseWatchdogSetGetTimeout},
293 { WATCHDOG_TEST_START_STOP, TestCaseWatchdogStartStop},
294 { WATCHDOG_TEST_FEED, TestCaseWatchdogFeed},
295 { WATCHDOG_TEST_RELIABILITY, TestCaseWatchdogReliability},
296 { WATCHDOG_TEST_BARK, TestCaseWatchdogBark},
297 { WATCHDOG_IF_PERFORMANCE_TEST, TestCaseWatchdogIfPerformanceTest},
298 };
299
WatchdogTestExecute(int cmd)300 int32_t WatchdogTestExecute(int cmd)
301 {
302 uint32_t i;
303 int32_t ret = HDF_ERR_NOT_SUPPORT;
304 struct WatchdogTester *tester = NULL;
305
306 tester = WatchdogTesterGet();
307 if (tester == NULL) {
308 if (g_wdtState == HDF_ERR_DEVICE_BUSY) {
309 HDF_LOGE("WatchdogTestExecute: device is busy!");
310 return HDF_SUCCESS;
311 }
312 HDF_LOGE("WatchdogTestExecute: get tester fail!");
313 return HDF_ERR_INVALID_OBJECT;
314 }
315
316 if (cmd > WATCHDOG_TEST_MAX) {
317 HDF_LOGE("WatchdogTestExecute: invalid cmd:%d!", cmd);
318 ret = HDF_ERR_NOT_SUPPORT;
319 HDF_LOGI("[WatchdogTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
320 WatchdogTesterPut(tester);
321 return ret;
322 }
323
324 for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
325 if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
326 continue;
327 }
328 ret = g_entry[i].func(tester);
329 break;
330 }
331
332 HDF_LOGI("[WatchdogTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
333 WatchdogTesterPut(tester);
334 return ret;
335 }
336