1 /*
2 * Copyright (c) 2020-2022 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 "hdf_message_test.h"
10 #include "message/message_types.h"
11 #include "message/message_router.h"
12 #include "message/sidecar.h"
13 #include "hdf_log.h"
14 #include "hdf_sbuf.h"
15 #include "osal_time.h"
16
17 const uint32_t SEND_MESSAGE_COUNT = 40000;
18 const uint32_t SYNC_MESSAGE_TIMEOUT = 2;
19 const uint32_t ASYNC_MESSAGE_TIMEOUT = 8;
20 #define COMMON_SEM_TIMEOUT 300
21
22 enum ServiceList {
23 SERVICE_ID_A = 10,
24 SERVICE_ID_B
25 };
26
27 const uint8_t CUSTOM_DISPATCHER_ID = 1;
28 const uint8_t SINGLE_NODE_TEST_CUSTOM_DISPATCHER_PRIORITYLEVEL = 4;
29 const uint32_t SINGLE_NODE_TEST_CUSTOM_DISPATCHER_QUEUESIZE = 10000;
30
31 const uint16_t SMALL_LOAD_WAIT_TIME = 500;
32
33
34 #define CMD_LIST_MAX_SIZE 32
35 uint8_t g_cmdList[CMD_LIST_MAX_SIZE];
36 uint8_t g_cmdListCount = 0;
37
ClearRecvQueue(void)38 void ClearRecvQueue(void)
39 {
40 g_cmdListCount = 0;
41 }
42
GetCMDByIndex(uint8_t index)43 uint8_t GetCMDByIndex(uint8_t index)
44 {
45 return g_cmdList[index];
46 }
47
GetRecvQueueSize(void)48 size_t GetRecvQueueSize(void)
49 {
50 return g_cmdListCount;
51 }
52
FuncNoLoad(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)53 static ErrorCode FuncNoLoad(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
54 {
55 (void)reqData;
56 (void)rspData;
57 (void)context;
58 return ME_SUCCESS;
59 }
60
FuncSmallLoad(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)61 static ErrorCode FuncSmallLoad(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
62 {
63 if (context == NULL) {
64 HDF_LOGE("%s:FuncSmallLoad context NULL!", __func__);
65 return HDF_FAILURE;
66 }
67 (void)reqData;
68 (void)rspData;
69 HDF_LOGI("Handle message %d\n", context->commandId);
70
71 OsalMSleep(SMALL_LOAD_WAIT_TIME);
72 if (g_cmdListCount >= CMD_LIST_MAX_SIZE) {
73 HDF_LOGE("%s:Too much cmd!", __func__);
74 return HDF_FAILURE;
75 }
76 g_cmdList[g_cmdListCount++] = context->commandId;
77 HDF_LOGI("Finish handle message %d\n", context->commandId);
78 return ME_SUCCESS;
79 }
80
81 static struct MessageDef g_testServiceACmds[] = {
82 DUEMessage(0, FuncNoLoad, 1)
83 };
84
85 ServiceDefine(TestServiceA, SERVICE_ID_A, g_testServiceACmds);
86
87 static struct MessageDef g_testServiceBCmds[] = {
88 DUEMessage(0, FuncNoLoad, 2), // commandId = 0
89 DUEMessage(1, FuncSmallLoad, 0),
90 DUEMessage(2, FuncSmallLoad, 1),
91 DUEMessage(3, FuncSmallLoad, 2),
92 DUEMessage(4, FuncSmallLoad, 3),
93 };
94
95 ServiceDefine(TestServiceB, SERVICE_ID_B, g_testServiceBCmds);
96
97 Service *g_serviceA = NULL;
98 Service *g_serviceB = NULL;
99 bool g_dispatcherInited = false;
100
StartEnv(void)101 static int32_t StartEnv(void)
102 {
103 int32_t errCode;
104 if (!g_dispatcherInited) {
105 DispatcherConfig config = {
106 .dispatcherId = CUSTOM_DISPATCHER_ID,
107 .priorityLevelCount = SINGLE_NODE_TEST_CUSTOM_DISPATCHER_PRIORITYLEVEL,
108 .queueSize = SINGLE_NODE_TEST_CUSTOM_DISPATCHER_QUEUESIZE
109 };
110 MSG_RETURN_IF_FUNCTION_FAILED(errCode, AddDispatcher(&config));
111 g_dispatcherInited = true;
112 }
113 if (g_serviceA == NULL) {
114 ServiceCfg cfgA = {
115 .dispatcherId = DEFAULT_DISPATCHER_ID
116 };
117 g_serviceA = CreateService(TestServiceA, &cfgA);
118 MSG_RETURN_IF(g_serviceA == NULL);
119 }
120
121 if (g_serviceB == NULL) {
122 ServiceCfg cfgB = {
123 .dispatcherId = CUSTOM_DISPATCHER_ID
124 };
125 g_serviceB = CreateService(TestServiceB, &cfgB);
126 MSG_RETURN_IF(g_serviceB == NULL);
127 }
128 return HDF_SUCCESS;
129 }
130
StopEnv(void)131 static int32_t StopEnv(void)
132 {
133 if (g_serviceA != NULL) {
134 if (g_serviceA->Destroy != NULL) {
135 g_serviceA->Destroy(g_serviceA);
136 }
137 g_serviceA = NULL;
138 }
139
140 if (g_serviceB != NULL) {
141 if (g_serviceB->Destroy != NULL) {
142 g_serviceB->Destroy(g_serviceB);
143 }
144 g_serviceB = NULL;
145 }
146 return HDF_SUCCESS;
147 }
148
149 // Repeated register
MessageSingleNodeTest001(void)150 int32_t MessageSingleNodeTest001(void)
151 {
152 ErrorCode errCode = HDF_SUCCESS;
153 ErrorCode errShutdown = HDF_SUCCESS;
154 Service *service = NULL;
155
156 do {
157 ServiceCfg cfgB = {
158 .dispatcherId = CUSTOM_DISPATCHER_ID
159 };
160
161 MSG_RETURN_IF_FUNCTION_FAILED(errCode, StartEnv());
162
163 service = CreateService(TestServiceB, &cfgB);
164 MSG_BREAK_IF(errCode, service != NULL);
165 } while (false);
166
167 MSG_RETURN_IF_FUNCTION_FAILED(errShutdown, StopEnv());
168 if (service != NULL) {
169 if (service->Destroy != NULL) {
170 service->Destroy(service);
171 }
172 service = NULL;
173 }
174 return errCode;
175 }
176
177 // Sync message test
MessageSingleNodeTest002(void)178 int32_t MessageSingleNodeTest002(void)
179 {
180 ErrorCode errCode = HDF_SUCCESS;
181 ErrorCode errShutdown = HDF_SUCCESS;
182 struct HdfSBuf *rspData = NULL;
183
184 do {
185 MSG_BREAK_IF_FUNCTION_FAILED(errCode, StartEnv());
186
187 MSG_BREAK_IF(errCode, g_serviceA == NULL);
188
189 rspData = HdfSbufObtainDefaultSize();
190
191 MSG_BREAK_IF_FUNCTION_FAILED(errCode, g_serviceA->SendSyncMessage(g_serviceA, SERVICE_ID_B, 0, NULL, rspData));
192 } while (false);
193
194 if (rspData != NULL) {
195 HdfSbufRecycle(rspData);
196 rspData = NULL;
197 }
198
199 MSG_RETURN_IF_FUNCTION_FAILED(errShutdown, StopEnv());
200
201 return errCode;
202 }
203
204
205 // Sync Perf test
MessageSingleNodeTest003(void)206 int32_t MessageSingleNodeTest003(void)
207 {
208 ErrorCode errCode = HDF_SUCCESS;
209 ErrorCode errShutdown = HDF_SUCCESS;
210 uint32_t i;
211 struct HdfSBuf *rspData = NULL;
212 struct HdfSBuf *sendData = NULL;
213 do {
214 OsalTimespec startTime;
215 OsalTimespec endTime;
216 OsalTimespec diffTime;
217 MSG_BREAK_IF_FUNCTION_FAILED(errCode, StartEnv());
218 MSG_BREAK_IF(errCode, g_serviceA == NULL);
219 rspData = HdfSbufObtainDefaultSize();
220 sendData = HdfSbufObtainDefaultSize();
221
222 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalGetTime(&startTime));
223 for (i = 0; i < SEND_MESSAGE_COUNT; i++) {
224 MSG_BREAK_IF_FUNCTION_FAILED(errCode,
225 g_serviceA->SendSyncMessage(g_serviceA, SERVICE_ID_B, 0, sendData, rspData));
226 }
227 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalGetTime(&endTime));
228
229 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalDiffTime(&startTime, &endTime, &diffTime));
230
231 HDF_LOGI("Process time %llu \n", diffTime.sec);
232 MSG_BREAK_IF(errCode, diffTime.sec > SYNC_MESSAGE_TIMEOUT);
233 } while (false);
234
235 if (rspData != NULL) {
236 HdfSbufRecycle(rspData);
237 rspData = NULL;
238 }
239
240 if (sendData != NULL) {
241 HdfSbufRecycle(sendData);
242 sendData = NULL;
243 }
244
245 MSG_RETURN_IF_FUNCTION_FAILED(errShutdown, StopEnv());
246
247 return errCode;
248 }
249
250 OSAL_DECLARE_SEMAPHORE(g_callBackSem);
251
SendMessageTestCallBack(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData,ErrorCode rspCode)252 static void SendMessageTestCallBack(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData,
253 ErrorCode rspCode)
254 {
255 if (context == NULL) {
256 HDF_LOGE("%s:SendMessageTestCallBack context NULL!", __func__);
257 return;
258 }
259 (void)reqData;
260 (void)rspData;
261 (void)rspCode;
262 OsalSemPost(&g_callBackSem);
263 HDF_LOGI("Receive response for CMD %d.\n", context->commandId);
264 }
265
MessageSingleNodeTest004(void)266 int32_t MessageSingleNodeTest004(void)
267 {
268 ErrorCode errCode = HDF_SUCCESS;
269 ErrorCode errShutdown = HDF_SUCCESS;
270
271 do {
272 MSG_BREAK_IF_FUNCTION_FAILED(errCode, StartEnv());
273 MSG_BREAK_IF(errCode, g_serviceA == NULL);
274
275 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalSemInit(&g_callBackSem, 0));
276
277 MSG_BREAK_IF_FUNCTION_FAILED(errCode,
278 g_serviceA->SendAsyncMessage(g_serviceA, SERVICE_ID_B, 0, NULL, SendMessageTestCallBack));
279
280 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalSemWait(&g_callBackSem, COMMON_SEM_TIMEOUT));
281 } while (false);
282 errShutdown = OsalSemDestroy(&g_callBackSem);
283 errShutdown = errShutdown | StopEnv();
284 if (errShutdown != HDF_SUCCESS) {
285 HDF_LOGE("%s:Destroy message semaphore failed! errShutdown=%d", __func__, errShutdown);
286 }
287
288 return errCode;
289 }
290
SendMessagePerfTestCallBack(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData,ErrorCode rspCode)291 static void SendMessagePerfTestCallBack(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData,
292 ErrorCode rspCode)
293 {
294 (void)context;
295 (void)reqData;
296 (void)rspData;
297 (void)rspCode;
298
299 ErrorCode errCode = OsalSemPost(&g_callBackSem);
300 if (HDF_SUCCESS != errCode) {
301 HDF_LOGE("%s:Post sem failed!ret=%d", __func__, errCode);
302 }
303 }
304
305 const uint32_t PERF_TEST_COUNT = 10000;
306
MessageSingleNodeTest005(void)307 int32_t MessageSingleNodeTest005(void)
308 {
309 ErrorCode errCode = HDF_SUCCESS;
310 ErrorCode errShutdown = HDF_SUCCESS;
311 uint32_t i;
312
313 do {
314 OsalTimespec startTime;
315 OsalTimespec endTime;
316 OsalTimespec diffTime;
317 MSG_BREAK_IF_FUNCTION_FAILED(errCode, StartEnv());
318 MSG_BREAK_IF(errCode, g_serviceA == NULL);
319
320 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalSemInit(&g_callBackSem, 0));
321
322 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalGetTime(&startTime));
323
324 for (i = 0; i < PERF_TEST_COUNT; i++) {
325 MSG_BREAK_IF_FUNCTION_FAILED(errCode,
326 g_serviceA->SendAsyncMessage(g_serviceA, SERVICE_ID_B, 0, NULL, SendMessagePerfTestCallBack));
327 }
328
329 for (i = 0; i < PERF_TEST_COUNT; i++) {
330 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalSemWait(&g_callBackSem, COMMON_SEM_TIMEOUT));
331 }
332
333 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalGetTime(&endTime));
334
335 MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalDiffTime(&startTime, &endTime, &diffTime));
336
337 HDF_LOGW("Process time %llu \n", diffTime.sec);
338 MSG_BREAK_IF(errCode, diffTime.sec > ASYNC_MESSAGE_TIMEOUT);
339 } while (false);
340 errShutdown = OsalSemDestroy(&g_callBackSem);
341 errShutdown = errShutdown | StopEnv();
342 if (errShutdown != HDF_SUCCESS) {
343 HDF_LOGE("%s:Destroy message semaphore failed! errShutdown=%d", __func__, errShutdown);
344 }
345
346 return errCode;
347 }
348