1 /*
2 * Copyright (c) 2021-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 "platform_event_test.h"
10 #include "hdf_base.h"
11 #include "hdf_log.h"
12 #include "osal_sem.h"
13 #include "osal_spinlock.h"
14 #include "osal_time.h"
15 #include "platform_assert.h"
16 #include "platform_event.h"
17
18 #define HDF_LOG_TAG platform_event_test
19
20 #define PLAT_EVENT_TEST_TIMEOUT 10
21
22 enum PlatformTestEvent {
23 PLAT_TEST_EVENT_A = 0x1,
24 PLAT_TEST_EVENT_B = 0x2,
25 PLAT_TEST_EVENT_C = 0x4,
26 };
27
PlatformEventTestInitAndUninit(struct PlatformEvent * pe)28 static int32_t PlatformEventTestInitAndUninit(struct PlatformEvent *pe)
29 {
30 int32_t ret;
31
32 PLAT_LOGD("PlatformEventTestInitAndUninit: enter!");
33 // eventsWord should be 0 after init
34 CHECK_EQ_RETURN(pe->eventsWord, 0, HDF_FAILURE);
35
36 // can use spinlock after init
37 ret = OsalSpinLock(&pe->spin);
38 if (!CHECK_EQ(ret, HDF_SUCCESS)) {
39 return HDF_FAILURE;
40 }
41 (void)OsalSpinUnlock(&pe->spin);
42
43 // can use sem after init
44 ret = OsalSemPost(&pe->sem);
45 if (!CHECK_EQ(ret, HDF_SUCCESS)) {
46 return HDF_FAILURE;
47 }
48 (void)OsalSemWait(&pe->sem, HDF_WAIT_FOREVER);
49
50 PLAT_LOGD("PlatformEventTestInitAndUninit: exit!");
51 return HDF_SUCCESS;
52 }
53
PlatformEventTestPostAndWait(struct PlatformEvent * pe)54 static int32_t PlatformEventTestPostAndWait(struct PlatformEvent *pe)
55 {
56 int32_t ret;
57 uint32_t events;
58
59 PLAT_LOGD("PlatformEventTestPostAndWait: enter!");
60 // should wait timeout before post
61 ret = PlatformEventWait(pe, PLAT_TEST_EVENT_A, 0, PLAT_EVENT_TEST_TIMEOUT, &events);
62 CHECK_EQ_RETURN(ret, HDF_ERR_TIMEOUT, HDF_FAILURE);
63
64 // should post success
65 ret = PlatformEventPost(pe, PLAT_TEST_EVENT_A);
66 CHECK_EQ_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
67
68 // should wait success after post
69 ret = PlatformEventWait(pe, PLAT_TEST_EVENT_A, 0, PLAT_EVENT_TEST_TIMEOUT, &events);
70 CHECK_EQ_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
71 CHECK_EQ_RETURN(events, PLAT_TEST_EVENT_A, HDF_FAILURE);
72
73 // should wait timeut if wait again
74 ret = PlatformEventWait(pe, PLAT_TEST_EVENT_A, 0, PLAT_EVENT_TEST_TIMEOUT, &events);
75 CHECK_EQ_RETURN(ret, HDF_ERR_TIMEOUT, HDF_FAILURE);
76
77 // should post success for multi events
78 ret = PlatformEventPost(pe, PLAT_TEST_EVENT_A | PLAT_TEST_EVENT_B);
79 CHECK_EQ_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
80
81 // should wait timeout if events not match
82 ret = PlatformEventWait(pe, PLAT_TEST_EVENT_B | PLAT_TEST_EVENT_C, PLAT_EVENT_MODE_AND,
83 PLAT_EVENT_TEST_TIMEOUT, &events);
84 CHECK_EQ_RETURN(ret, HDF_ERR_TIMEOUT, HDF_FAILURE);
85 ret = PlatformEventWait(pe, PLAT_TEST_EVENT_C, 0, PLAT_EVENT_TEST_TIMEOUT, &events);
86 CHECK_EQ_RETURN(ret, HDF_ERR_TIMEOUT, HDF_FAILURE);
87
88 // should wait success if events match
89 ret = PlatformEventWait(pe, PLAT_TEST_EVENT_A | PLAT_TEST_EVENT_B, PLAT_EVENT_MODE_AND,
90 PLAT_EVENT_TEST_TIMEOUT, &events);
91 CHECK_EQ_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
92 CHECK_EQ_RETURN(events, PLAT_TEST_EVENT_A | PLAT_TEST_EVENT_B, HDF_FAILURE);
93
94 // should wait timeut if wait again
95 ret = PlatformEventWait(pe, PLAT_TEST_EVENT_A, 0, PLAT_EVENT_TEST_TIMEOUT, &events);
96 CHECK_EQ_RETURN(ret, HDF_ERR_TIMEOUT, HDF_FAILURE);
97
98 PLAT_LOGD("PlatformEventTestPostAndWait: exit!");
99 return HDF_SUCCESS;
100 }
101
PlatformEventListenTestCb(struct PlatformEventListener * listener,uint32_t events)102 static int32_t PlatformEventListenTestCb(struct PlatformEventListener *listener, uint32_t events)
103 {
104 uint32_t *pEvents = (uint32_t *)listener->data;
105
106 *pEvents = events;
107 return HDF_SUCCESS;
108 }
109
PlatformEventTestListenAndUnliten(struct PlatformEvent * pe)110 static int32_t PlatformEventTestListenAndUnliten(struct PlatformEvent *pe)
111 {
112 int32_t ret;
113 struct PlatformEventListener listener;
114 uint32_t events = 0;
115
116 PLAT_LOGD("PlatformEventTestListenAndUnliten: enter!");
117 listener.mask = PLAT_TEST_EVENT_A | PLAT_TEST_EVENT_B;
118 listener.cb = PlatformEventListenTestCb;
119 listener.data = (void *)&events;
120
121 // should listen success
122 ret = PlatformEventListen(pe, &listener);
123 CHECK_EQ_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
124
125 // no events got before post
126 OsalMSleep(PLAT_EVENT_TEST_TIMEOUT);
127 CHECK_EQ_RETURN(events, 0, HDF_FAILURE);
128
129 PlatformEventPost(pe, PLAT_TEST_EVENT_A);
130 OsalMSleep(PLAT_EVENT_TEST_TIMEOUT);
131 // should got the events in callback
132 CHECK_EQ_RETURN(events, PLAT_TEST_EVENT_A, HDF_FAILURE);
133
134 events = 0;
135 PlatformEventPost(pe, PLAT_TEST_EVENT_B);
136 OsalMSleep(PLAT_EVENT_TEST_TIMEOUT);
137 // should got the events in callback
138 CHECK_EQ_RETURN(events, PLAT_TEST_EVENT_B, HDF_FAILURE);
139
140 events = 0;
141 PlatformEventPost(pe, PLAT_TEST_EVENT_A | PLAT_TEST_EVENT_B);
142 OsalMSleep(PLAT_EVENT_TEST_TIMEOUT);
143 // should got the events in callback
144 CHECK_EQ_RETURN(events, PLAT_TEST_EVENT_A | PLAT_TEST_EVENT_B, HDF_FAILURE);
145
146 PLAT_LOGD("PlatformEventTestListenAndUnliten: exit!");
147 return HDF_SUCCESS;
148 }
149
PlatformEventTestReliability(struct PlatformEvent * pe)150 static int32_t PlatformEventTestReliability(struct PlatformEvent *pe)
151 {
152 int32_t ret;
153 uint32_t events;
154 struct PlatformEventListener listener;
155
156 PLAT_LOGD("PlatformEventTestReliability: enter!");
157 // should return invalid obj when init null pointer
158 ret = PlatformEventInit(NULL);
159 CHECK_EQ_RETURN(ret, HDF_ERR_INVALID_OBJECT, HDF_FAILURE);
160
161 // should not wait success when event instance is NULL
162 ret = PlatformEventWait(NULL, 0x1, 0, PLAT_EVENT_TEST_TIMEOUT, &events);
163 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
164
165 // should not wait success when events is NULL
166 ret = PlatformEventWait(pe, 0x1, 0, PLAT_EVENT_TEST_TIMEOUT, NULL);
167 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
168
169 // should not wait success when mask is 0
170 ret = PlatformEventWait(pe, 0, 0, PLAT_EVENT_TEST_TIMEOUT, &events);
171 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
172
173 // should not listen success when event instance is NULL
174 ret = PlatformEventListen(NULL, &listener);
175 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
176
177 // should not wait success when listener is NULL
178 ret = PlatformEventListen(pe, NULL);
179 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
180
181 PLAT_LOGD("PlatformEventTestReliability: exit!");
182 return HDF_SUCCESS;
183 }
184
185 struct PlatformEventTestEntry {
186 int cmd;
187 int32_t (*func)(struct PlatformEvent *pe);
188 const char *name;
189 };
190
191 static struct PlatformEventTestEntry g_entry[] = {
192 { PLAT_EVENT_TEST_INIT_AND_UNINIT, PlatformEventTestInitAndUninit, "PlatformEventTestInitAndUninit" },
193 { PLAT_EVENT_TEST_POST_AND_WAIT, PlatformEventTestPostAndWait, "PlatformEventTestPostAndWait" },
194 { PLAT_EVENT_TEST_LISTEN_AND_UNLISTEN, PlatformEventTestListenAndUnliten, "PlatformEventTestListenAndUnliten" },
195 { PLAT_EVENT_TEST_RELIABILITY, PlatformEventTestReliability, "PlatformEventTestReliability" },
196 };
197
PlatformEventTestExecute(int cmd)198 int PlatformEventTestExecute(int cmd)
199 {
200 uint32_t i;
201 int32_t ret = HDF_ERR_NOT_SUPPORT;
202 struct PlatformEvent pe;
203 struct PlatformEventTestEntry *entry = NULL;
204
205 if (cmd > PLAT_EVENT_TEST_CMD_MAX) {
206 PLAT_LOGE("PlatformEventTestExecute: invalid cmd:%d", cmd);
207 ret = HDF_ERR_NOT_SUPPORT;
208 PLAT_LOGE("[PlatformEventTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
209 return ret;
210 }
211
212 for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
213 if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
214 continue;
215 }
216 entry = &g_entry[i];
217 break;
218 }
219
220 if (entry == NULL) {
221 PLAT_LOGE("PlatformEventTestExecute: no entry matched, cmd = %d!", cmd);
222 return HDF_ERR_NOT_SUPPORT;
223 }
224
225 if ((ret = PlatformEventInit(&pe)) != HDF_SUCCESS) {
226 PLAT_LOGE("PlatformEventTestExecute: init failed, ret = %d!", ret);
227 return ret;
228 }
229
230 ret = entry->func(&pe);
231 PlatformEventUninit(&pe);
232
233 PLAT_LOGE("[PlatformEventTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
234 return ret;
235 }
236
PlatformEventTestExecuteAll(void)237 void PlatformEventTestExecuteAll(void)
238 {
239 int32_t i;
240 int32_t ret;
241 int32_t fails = 0;
242
243 for (i = 0; i < PLAT_EVENT_TEST_CMD_MAX; i++) {
244 ret = PlatformEventTestExecute(i);
245 fails += (ret != HDF_SUCCESS) ? 1 : 0;
246 }
247
248 PLAT_LOGE("PlatformEventTestExecuteALL: **********PASS:%d FAIL:%d************\n\n",
249 PLAT_EVENT_TEST_CMD_MAX - fails, fails);
250 }
251