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