1 /*
2 * Copyright (c) 2020-2021 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 "securec.h"
10 #include "hdf_dlist.h"
11 #include "hdf_log.h"
12 #include "osal_case_cmd_test.h"
13 #include "osal_work_test.h"
14 #include "osal_sem.h"
15 #include "osal_thread.h"
16 #include "osal_time.h"
17
18 #define LIST_LEN_TAIL 10
19 #define LIST_LEN_HEAD 10
20
21 #define HDF_LOG_TAG osal_test
22
23 #define HDF_THREAD_TEST_SLEEP_MS 200
24 #define HDF_TEST_STACK_SIZE (1024 * 16) // 16KB
25
26 typedef void(*EventHandle)(int para);
27
28 typedef struct {
29 EventHandle handle;
30 struct DListHead list;
31 } OsalTestEventHandle;
32 bool g_testEndFlag = false;
33 static OsalTestEventHandle g_handleMng;
34 static OsalTestEventHandle g_handleArr[LIST_LEN_TAIL + LIST_LEN_HEAD];
35
36 static struct OsalSem g_hdfSem;
37 static struct OsalThread g_threadPostSem;
38 static struct OsalThread g_threadWaitSem;
39 static bool g_threadTestFlag = true;
40 static int32_t g_threadPara = 120;
41 static bool g_hdfListStatus = true;
42 static bool g_hdfSemStatus = true;
43
44 #define MSG_SEND_PERIOD 5
45 #define MSG_TEST_ITME_PERIOD 10
46
47 #define MSG_NOSEND_CNT 1
48 #define MSG_NOSEND_CHECK_CNT 2
49 #define MSG_EVENT_AGAIN 3
50
51 static int g_listCnt = 0;
52 static int g_listLen = LIST_LEN_TAIL + LIST_LEN_HEAD;
OsalEventHandlerTail(int para)53 static void OsalEventHandlerTail(int para)
54 {
55 static int cnt = 0;
56
57 cnt += para;
58 if ((g_listLen != 0) && (cnt % g_listLen) == 0) {
59 HDF_LOGE("in %s msg:%d", __func__, cnt);
60 }
61 g_hdfListStatus = false;
62 g_listCnt++;
63 }
64
OsalEventHandlerHead(int para)65 static void OsalEventHandlerHead(int para)
66 {
67 static int cnt = 0;
68
69 cnt += para;
70 if ((g_listLen != 0) && (cnt % g_listLen) == 0) {
71 HDF_LOGE("in %s msg:%d", __func__, cnt);
72 }
73 g_hdfListStatus = false;
74 g_listCnt++;
75 }
76
OsalTestList(const struct DListHead * head)77 static void OsalTestList(const struct DListHead *head)
78 {
79 OsalTestEventHandle *pos = NULL;
80 g_listCnt = 0;
81 DLIST_FOR_EACH_ENTRY(pos, head, OsalTestEventHandle, list) {
82 if (pos->handle != NULL) {
83 pos->handle(1);
84 } else {
85 HDF_LOGE("%s no handle\n", __func__);
86 UT_TEST_CHECK_RET(true, OSAL_LIST_TRAVERSAL);
87 }
88 }
89 }
90
TestListAddTail(void)91 static void TestListAddTail(void)
92 {
93 int i = 0;
94 for (; i < LIST_LEN_TAIL; i++) {
95 g_handleArr[i].handle = OsalEventHandlerTail;
96 DListHeadInit(&g_handleArr[i].list);
97 DListInsertTail(&g_handleArr[i].list, &g_handleMng.list);
98 }
99 }
100
TestListMerge(void)101 static void TestListMerge(void)
102 {
103 OsalTestEventHandle list1[LIST_LEN_TAIL];
104 OsalTestEventHandle list2[LIST_LEN_TAIL];
105 OsalTestEventHandle mng1;
106 OsalTestEventHandle mng2;
107 int i = 0;
108
109 HDF_LOGE("[OSAL_UT_TEST]%s start", __func__);
110
111 DListHeadInit(&mng1.list);
112 mng1.handle = NULL;
113 for (; i < LIST_LEN_TAIL; i++) {
114 list1[i].handle = OsalEventHandlerTail;
115 DListHeadInit(&list1[i].list);
116 DListInsertTail(&list1[i].list, &mng1.list);
117 }
118 OsalTestList(&mng1.list);
119 UT_TEST_CHECK_RET(g_listCnt != LIST_LEN_TAIL, OSAL_LIST_TAIL);
120
121 DListHeadInit(&mng2.list);
122 mng2.handle = NULL;
123 for (i = 0; i < LIST_LEN_TAIL; i++) {
124 list2[i].handle = OsalEventHandlerTail;
125 DListHeadInit(&list2[i].list);
126 DListInsertTail(&list2[i].list, &mng2.list);
127 }
128 OsalTestList(&mng2.list);
129 UT_TEST_CHECK_RET(g_listCnt != LIST_LEN_TAIL, OSAL_LIST_TAIL);
130
131 DListMerge(&mng1.list, &mng2.list);
132 OsalTestList(&mng2.list);
133 UT_TEST_CHECK_RET(g_listCnt != g_listLen, OSAL_LIST_TAIL);
134
135 OsalTestList(&mng1.list);
136 UT_TEST_CHECK_RET(g_listCnt != 0, OSAL_LIST_TAIL);
137 HDF_LOGE("[OSAL_UT_TEST]%s end", __func__);
138 }
139
TestListAddHead(void)140 static void TestListAddHead(void)
141 {
142 int i = 0;
143 for (; i < LIST_LEN_HEAD; i++) {
144 g_handleArr[LIST_LEN_TAIL + i].handle = OsalEventHandlerHead;
145 DListHeadInit(&g_handleArr[LIST_LEN_TAIL + i].list);
146 DListInsertHead(&g_handleArr[LIST_LEN_TAIL + i].list, &g_handleMng.list);
147 }
148 }
149
TestListRemoveInlist(void)150 static void TestListRemoveInlist(void)
151 {
152 OsalTestEventHandle *pos = NULL;
153 OsalTestEventHandle *q = NULL;
154
155 g_listCnt = 0;
156 DLIST_FOR_EACH_ENTRY_SAFE(pos, q, &g_handleMng.list, OsalTestEventHandle, list) {
157 if (&(pos->list) == &g_handleArr[0].list) {
158 DListRemove(&(pos->list));
159 g_listLen--;
160 HDF_LOGE("%s find\n", __func__);
161 continue;
162 }
163 if (pos->handle != NULL) {
164 pos->handle(1);
165 } else {
166 HDF_LOGE("%s no handle\n", __func__);
167 UT_TEST_CHECK_RET(true, OSAL_LIST_TRAVERSAL);
168 }
169 }
170 }
171
OsalTestListInit(void)172 static void OsalTestListInit(void)
173 {
174 int i = 0;
175 HDF_LOGE("[OSAL_UT_TEST]%s start", __func__);
176
177 g_handleMng.handle = NULL;
178 DListHeadInit(&g_handleMng.list);
179 UT_TEST_CHECK_RET(DListIsEmpty(&g_handleMng.list) != true, OSAL_LIST_INIT);
180 OsalTestList(&g_handleMng.list);
181 UT_TEST_CHECK_RET(g_listCnt != 0, OSAL_LIST_COUNT_CHECK);
182 HDF_LOGE("g_listCnt %d %d", g_listCnt, g_listLen);
183
184 TestListAddTail();
185 UT_TEST_CHECK_RET(DListIsEmpty(&g_handleMng.list) == true, OSAL_LIST_TAIL);
186 TestListAddHead();
187
188 OsalTestList(&g_handleMng.list);
189 UT_TEST_CHECK_RET(g_listCnt != g_listLen, OSAL_LIST_HEAD);
190 HDF_LOGE("g_listCnt %d %d", g_listCnt, g_listLen);
191
192 for (; i < g_listLen; i++) {
193 DListRemove(&g_handleArr[i].list);
194 }
195 UT_TEST_CHECK_RET(DListIsEmpty(&g_handleMng.list) != true, OSAL_LIST_REMOVE);
196
197 OsalTestList(&g_handleMng.list);
198 UT_TEST_CHECK_RET(g_listCnt != 0, OSAL_LIST_TRAVERSAL);
199 HDF_LOGE("g_listCnt %d %d", g_listCnt, g_listLen);
200
201 TestListAddHead();
202 TestListAddTail();
203
204 OsalTestList(&g_handleMng.list);
205 UT_TEST_CHECK_RET(g_listCnt != g_listLen, OSAL_LIST_TRAVERSAL);
206 HDF_LOGE("g_listCnt %d %d", g_listCnt, g_listLen);
207
208 TestListRemoveInlist();
209 UT_TEST_CHECK_RET(g_listCnt != g_listLen, OSAL_LIST_TRAVERSAL_REMOVE);
210 HDF_LOGE("g_listCnt %d %d", g_listCnt, g_listLen);
211
212 DListInsertTail(&g_handleArr[0].list, &g_handleMng.list);
213 g_listLen++;
214
215 UT_TEST_CHECK_RET(DListIsEmpty(&g_handleMng.list) == true, OSAL_LIST_EMPTY);
216
217 TestListMerge();
218 }
219
OsalTestSemList(void)220 static void OsalTestSemList(void)
221 {
222 OsalTestEventHandle *pos = NULL;
223 OsalTestEventHandle *q = NULL;
224
225 DLIST_FOR_EACH_ENTRY_SAFE(pos, q, &g_handleMng.list, OsalTestEventHandle, list) {
226 if (pos->handle != NULL) {
227 pos->handle(1);
228 } else {
229 HDF_LOGE("%s no handle\n", __func__);
230 UT_TEST_CHECK_RET(true, OSAL_LIST_TRAVERSAL);
231 }
232 }
233 }
234
235 static bool g_noSemFlag = false;
ThreadTestPostSem(void * arg)236 static int ThreadTestPostSem(void *arg)
237 {
238 static int cnt = 0;
239 static int index = 0;
240 HDF_STATUS ret;
241
242 HDF_LOGI("[OSAL_UT_TEST]%s entry", __func__);
243 (void)arg;
244
245 while (g_threadTestFlag) {
246 OsalMSleep(HDF_THREAD_TEST_SLEEP_MS);
247 if (cnt % MSG_SEND_PERIOD == 0) {
248 g_hdfSemStatus = true;
249 g_hdfListStatus = true;
250 index = 0;
251 g_listCnt = 0;
252 if (g_testEndFlag) {
253 g_noSemFlag = true;
254 break;
255 }
256 ret = OsalSemPost(&g_hdfSem);
257 UT_TEST_CHECK_RET(ret != HDF_SUCCESS, OSAL_SEM_POST);
258 }
259 if (index == MSG_NOSEND_CNT) {
260 UT_TEST_CHECK_RET(g_hdfSemStatus == true, OSAL_SEM_POST_RESULT);
261 UT_TEST_CHECK_RET(g_hdfListStatus == true, OSAL_LIST_STRESS);
262 UT_TEST_CHECK_RET(g_listCnt != g_listLen, OSAL_LIST_COUNT_CHECK);
263 HDF_LOGE("g_listCnt %d %d", g_listCnt, g_listLen);
264 g_hdfSemStatus = true;
265 g_hdfListStatus = true;
266 }
267
268 if (index == MSG_NOSEND_CHECK_CNT) {
269 UT_TEST_CHECK_RET(g_hdfSemStatus == false, OSAL_SEM_POST_RESULT);
270 UT_TEST_CHECK_RET(g_hdfListStatus == false, OSAL_LIST_STRESS);
271 }
272 #ifndef __USER__
273 TestAddRoute(cnt);
274 #endif
275 cnt++;
276 index++;
277 }
278 #ifndef __USER__
279 OsalTestWorkEnd();
280 #endif
281 OsalSemPost(&g_hdfSem);
282 HDF_LOGE("%s exit", __func__);
283 return 0;
284 }
285
ThreadTestWaitSem(void * arg)286 static int ThreadTestWaitSem(void *arg)
287 {
288 HDF_STATUS ret;
289
290 HDF_LOGI("[OSAL_UT_TEST]%s entry", __func__);
291 (void)arg;
292
293 while (g_threadTestFlag) {
294 ret = OsalSemWait(&g_hdfSem, HDF_WAIT_FOREVER);
295 if (ret == HDF_SUCCESS) {
296 OsalTestSemList();
297 g_hdfSemStatus = false;
298 } else {
299 HDF_LOGE("[OSAL_UT_TEST]%s OsalSemWait fail", __func__);
300 UT_TEST_CHECK_RET(true, OSAL_SEM_WAIT_FOREVER);
301 }
302 if (g_testEndFlag && g_noSemFlag) {
303 break;
304 }
305 }
306 HDF_LOGE("%s exit", __func__);
307 return 0;
308 }
309
OsalOsalSemInterface(void)310 static void OsalOsalSemInterface(void)
311 {
312 HDF_STATUS ret;
313 struct OsalSem hdfSem = { NULL };
314
315 ret = OsalSemInit(&hdfSem, 0);
316 UT_TEST_CHECK_RET(ret != HDF_SUCCESS, OSAL_SEM_CREATE);
317 ret = OsalSemPost(&hdfSem);
318 UT_TEST_CHECK_RET(ret != HDF_SUCCESS, OSAL_SEM_POST);
319 ret = OsalSemWait(&hdfSem, HDF_WAIT_FOREVER);
320 UT_TEST_CHECK_RET(ret != HDF_SUCCESS, OSAL_SEM_WAIT_FOREVER);
321 ret = OsalSemWait(&hdfSem, 1);
322 UT_TEST_CHECK_RET(ret == HDF_SUCCESS, OSAL_SEM_WAIT_TIMEOUT);
323 ret = OsalSemDestroy(&hdfSem);
324 UT_TEST_CHECK_RET(ret != HDF_SUCCESS, OSAL_SEM_DESTROY);
325
326 HDF_LOGE("[OSAL_UT_TEST]%s no init test", __func__);
327 ret = OsalSemPost(&hdfSem);
328 UT_TEST_CHECK_RET(ret == HDF_SUCCESS, OSAL_SEM_VISIT_AFTER_DESTROY);
329 ret = OsalSemWait(&hdfSem, HDF_WAIT_FOREVER);
330 UT_TEST_CHECK_RET(ret == HDF_SUCCESS, OSAL_SEM_VISIT_AFTER_DESTROY);
331 ret = OsalSemWait(&hdfSem, 1);
332 UT_TEST_CHECK_RET(ret == HDF_SUCCESS, OSAL_SEM_VISIT_AFTER_DESTROY);
333 OsalSemDestroy(&hdfSem);
334 }
335
OsalTestSem(void)336 static void OsalTestSem(void)
337 {
338 struct OsalThreadParam threadCfg;
339 int32_t ret;
340
341 HDF_LOGI("[OSAL_UT_TEST]%s start", __func__);
342
343 OsalOsalSemInterface();
344
345 UT_TEST_CHECK_RET(OsalSemInit(&g_hdfSem, 0) != HDF_SUCCESS, OSAL_SEM_CREATE);
346 (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
347 threadCfg.name = "hdf_test_Post";
348 threadCfg.priority = OSAL_THREAD_PRI_LOW;
349 threadCfg.stackSize = HDF_TEST_STACK_SIZE;
350 ret = OsalThreadCreate(&g_threadPostSem, (OsalThreadEntry)ThreadTestPostSem, (void *)&g_threadPara);
351 UT_TEST_CHECK_RET(ret != HDF_SUCCESS, OSAL_THREAD_CREATE);
352
353 (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
354 threadCfg.name = "hdf_test_Wait";
355 threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
356 threadCfg.stackSize = HDF_TEST_STACK_SIZE;
357 ret = OsalThreadCreate(&g_threadWaitSem, (OsalThreadEntry)ThreadTestWaitSem, (void *)&g_threadPara);
358 UT_TEST_CHECK_RET(ret != HDF_SUCCESS, OSAL_THREAD_CREATE);
359 ret = OsalThreadStart(&g_threadWaitSem, &threadCfg);
360 UT_TEST_CHECK_RET(ret != HDF_SUCCESS, OSAL_THREAD_CREATE);
361
362 ret = OsalThreadStart(&g_threadPostSem, &threadCfg);
363 UT_TEST_CHECK_RET(ret != HDF_SUCCESS, OSAL_THREAD_CREATE);
364 }
365
OsalTestOther(int flag)366 void OsalTestOther(int flag)
367 {
368 HDF_LOGI("[OSAL_UT_TEST]%s entry flag:%d", __func__, flag);
369 #ifndef __USER__
370 OsalTestWork(flag);
371 #endif
372 OsalTestListInit();
373 OsalTestSem();
374 }
375
OsalStopThread(void)376 void OsalStopThread(void)
377 {
378 g_testEndFlag = true;
379 OsalThreadDestroy(&g_threadPostSem);
380 OsalThreadDestroy(&g_threadWaitSem);
381 }
382