1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdlib.h>
17 #include <string.h>
18 #include "cmsis_os.h"
19 #include "securec.h"
20 #include "hctest.h"
21 #include "samgr_lite.h"
22
23 #define OPER_INTERVAL 200 // 200 ms
24 #define SERVICE_NUM 4
25 #define INDEX0 0
26 #define INDEX1 1
27 #define INDEX2 2
28 #define INDEX3 3
29
30 static char *g_serviceNameArray[] = {"SingleTS01", "SingleTS02", "SingleTS03", "SingleTS04"};
31
32 static const char *GetName(Service *service);
33 static BOOL Initialize(Service *service, Identity identity);
34 static BOOL MessageHandle(Service *service, Request *msg);
35 static TaskConfig GetTaskConfig(Service *service);
36
37 static Vector g_nodeVector;
38 typedef struct Node {
39 int id;
40 const char *name;
41 } Node;
GetNode(const Node * node)42 static const Node *GetNode(const Node *node)
43 {
44 return node;
45 }
CompareNode(const Node * node1,const Node * node2)46 static int CompareNode(const Node *node1, const Node *node2)
47 {
48 if (node1->id < node2->id) {
49 return -1;
50 } else if (node1->id == node2->id) {
51 return 0;
52 } else {
53 return 1;
54 }
55 }
56
57 typedef struct DemoApi {
58 INHERIT_IUNKNOWN;
59 BOOL (*FeatureApi001)(IUnknown *iUnknown, char *para1);
60 int32 (*SendRequestProxyF)(const Identity *identity, const Request *request, Handler handler);
61 } DemoApi;
62
63 typedef struct DemoFeature {
64 INHERIT_FEATURE;
65 INHERIT_IUNKNOWNENTRY(DemoApi);
66 Identity identity;
67 int featureCalledCount;
68 } DemoFeature;
69
70 typedef struct DefaultFeatureApi {
71 INHERIT_IUNKNOWN;
72 BOOL (*DefaultApi001)(IUnknown *iUnknown, char *para1);
73 int32 (*SendRequestProxyDF)(const Identity *identity, const Request *request, Handler handler);
74 } DefaultFeatureApi;
75
76 typedef struct DemoService {
77 INHERIT_SERVICE;
78 INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
79 Identity identity;
80 int serviceCalledCount;
81 } DemoService;
82
DefaultApi001(IUnknown * iUnknown,char * para1)83 static BOOL DefaultApi001(IUnknown *iUnknown, char *para1)
84 {
85 (void)iUnknown;
86 (void)para1;
87 return TRUE;
88 }
SendRequestProxyDF(const Identity * identity,const Request * request,Handler handler)89 static int32 SendRequestProxyDF(const Identity *identity, const Request *request, Handler handler)
90 {
91 return SAMGR_SendRequest(identity, request, handler);
92 }
93
FeatureApi001(IUnknown * iUnknown,char * para1)94 static BOOL FeatureApi001(IUnknown *iUnknown, char *para1)
95 {
96 (void)iUnknown;
97 (void)para1;
98 return TRUE;
99 }
SendRequestProxyF(const Identity * identity,const Request * request,Handler handler)100 static int32 SendRequestProxyF(const Identity *identity, const Request *request, Handler handler)
101 {
102 return SAMGR_SendRequest(identity, request, handler);
103 }
104
105 static DemoService g_service[] = {
106 {
107 .GetName = GetName,
108 .Initialize = Initialize,
109 .MessageHandle = MessageHandle,
110 .GetTaskConfig = GetTaskConfig,
111 .ref = 1,
112 .iUnknown = {
113 DEFAULT_IUNKNOWN_IMPL,
114 .DefaultApi001 = DefaultApi001,
115 .SendRequestProxyDF = SendRequestProxyDF,
116 },
117 .serviceCalledCount = 0,
118 },
119 {
120 .GetName = GetName,
121 .Initialize = Initialize,
122 .MessageHandle = MessageHandle,
123 .GetTaskConfig = GetTaskConfig,
124 .ref = 1,
125 .iUnknown = {
126 DEFAULT_IUNKNOWN_IMPL,
127 .DefaultApi001 = DefaultApi001,
128 .SendRequestProxyDF = SendRequestProxyDF,
129 },
130 .serviceCalledCount = 0,
131 },
132 {
133 .GetName = GetName,
134 .Initialize = Initialize,
135 .MessageHandle = MessageHandle,
136 .GetTaskConfig = GetTaskConfig,
137 .ref = 1,
138 .iUnknown = {
139 DEFAULT_IUNKNOWN_IMPL,
140 .DefaultApi001 = DefaultApi001,
141 .SendRequestProxyDF = SendRequestProxyDF,
142 },
143 .serviceCalledCount = 0,
144 },
145 {
146 .GetName = GetName,
147 .Initialize = Initialize,
148 .MessageHandle = MessageHandle,
149 .GetTaskConfig = GetTaskConfig,
150 .ref = 1,
151 .iUnknown = {
152 DEFAULT_IUNKNOWN_IMPL,
153 .DefaultApi001 = DefaultApi001,
154 .SendRequestProxyDF = SendRequestProxyDF,
155 },
156 .serviceCalledCount = 0,
157 }
158 };
159
GetName(Service * service)160 static const char *GetName(Service *service)
161 {
162 if (service == (Service *)&g_service[INDEX0]) {
163 return g_serviceNameArray[INDEX0];
164 } else if (service == (Service *)&g_service[INDEX1]) {
165 return g_serviceNameArray[INDEX1];
166 } else if (service == (Service *)&g_service[INDEX2]) {
167 return g_serviceNameArray[INDEX2];
168 } else {
169 return g_serviceNameArray[INDEX3];
170 }
171 }
172
173 static int g_initlizationOrder = 0;
Initialize(Service * service,Identity identity)174 static BOOL Initialize(Service *service, Identity identity)
175 {
176 DemoService *demoService = (DemoService *)service;
177 demoService->identity = identity;
178
179 g_initlizationOrder++;
180 Node *node = (Node *)malloc(sizeof(Node));
181 if (node == NULL) {
182 TEST_FAIL();
183 }
184 node->id = g_initlizationOrder;
185 node->name = service->GetName(service);
186 VECTOR_Add(&g_nodeVector, node);
187 return TRUE;
188 }
189
MessageHandle(Service * service,Request * msg)190 static BOOL MessageHandle(Service *service, Request *msg)
191 {
192 (void)msg;
193 DemoService *demoService = (DemoService *)service;
194 demoService->serviceCalledCount++;
195 return TRUE;
196 }
197
GetTaskConfig(Service * service)198 static TaskConfig GetTaskConfig(Service *service)
199 {
200 // stackSize: valid stackSize is [1600, 342000), the L0 RAM size is 342000, if stackSize <= 800, system will crash
201 // queueSize: [0, system upper limit), 0: will not create taskpool, the max value depends on RAM size
202 // priority: PRI_ABOVE_NORMAL PRI_NORMAL PRI_BELOW_NORMAL PRI_LOW
203
204 TaskConfig config = { LEVEL_HIGH, PRI_NORMAL, 1600, 2, SINGLE_TASK };
205 if (service == (Service *)&g_service[INDEX0]) {
206 config.priority = PRI_LOW;
207 } else if (service == (Service *)&g_service[INDEX1]) {
208 config.priority = PRI_BELOW_NORMAL;
209 } else if (service == (Service *)&g_service[INDEX2]) {
210 config.priority = PRI_NORMAL;
211 } else {
212 config.priority = PRI_ABOVE_NORMAL;
213 }
214 return config;
215 }
216
FEATURE_GetName(Feature * feature)217 static const char *FEATURE_GetName(Feature *feature)
218 {
219 (void)feature;
220 return "featureName501";
221 }
222
FEATURE_OnInitialize(Feature * feature,Service * parent,Identity identity)223 static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
224 {
225 (void)parent;
226 DemoFeature *demoFeature = (DemoFeature *)feature;
227 demoFeature->identity = identity;
228 }
229
FEATURE_OnStop(Feature * feature,Identity identity)230 static void FEATURE_OnStop(Feature *feature, Identity identity)
231 {
232 (void)feature;
233 (void)identity;
234 }
235
FEATURE_OnMessage(Feature * feature,Request * request)236 static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
237 {
238 (void)request;
239 DemoFeature *demoFeature = (DemoFeature *)feature;
240 demoFeature->featureCalledCount++;
241
242 return TRUE;
243 }
244
245 static DemoFeature g_createFeature = {
246 .GetName = FEATURE_GetName,
247 .OnInitialize = FEATURE_OnInitialize,
248 .OnStop = FEATURE_OnStop,
249 .OnMessage = FEATURE_OnMessage,
250 .ref = 1,
251 .iUnknown = {
252 DEFAULT_IUNKNOWN_IMPL,
253 .FeatureApi001 = FeatureApi001,
254 .SendRequestProxyF = SendRequestProxyF,
255 },
256 .identity = {-1, -1, NULL},
257 .featureCalledCount = 0,
258 };
259
ServiceInit(void)260 static void ServiceInit(void)
261 {
262 g_nodeVector = VECTOR_Make((VECTOR_Key)GetNode, (VECTOR_Compare)CompareNode);
263 for (int i = 0; i < SERVICE_NUM; i++) {
264 BOOL result = SAMGR_GetInstance()->RegisterService((Service *)&g_service[i]);
265 if (result == FALSE) {
266 printf("[hctest]E RegisterService failed, occurs: %d\n", i);
267 }
268 }
269 }
270 SYS_SERVICE_INIT(ServiceInit);
271
FeatureInit(void)272 static void FeatureInit(void)
273 {
274 for (int i = 0; i < SERVICE_NUM; i++) {
275 BOOL result1 = SAMGR_GetInstance()->RegisterDefaultFeatureApi(g_service[i].GetName((Service *)&g_service[i]),
276 GET_IUNKNOWN(g_service[i]));
277 BOOL result2 = SAMGR_GetInstance()->RegisterFeature(g_service[i].GetName((Service *)&g_service[i]),
278 (Feature *)&g_createFeature);
279 BOOL result3 = SAMGR_GetInstance()->RegisterFeatureApi(g_service[i].GetName((Service *)&g_service[i]),
280 "featureName501", GET_IUNKNOWN(g_createFeature));
281 if (result1 == FALSE || result2 == FALSE || result3 == FALSE) {
282 printf("[hctest]E failed to register feature or api.\n");
283 }
284 }
285 }
286 SYS_FEATURE_INIT(FeatureInit);
287
GetIUnknown(const char * serviceName,const char * featureName)288 static DemoApi *GetIUnknown(const char *serviceName, const char *featureName)
289 {
290 DemoApi *demoApi = NULL;
291 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(serviceName, featureName);
292 if (iUnknown == NULL) {
293 printf("[hctest]failed to GetFeatureApi.\n");
294 return NULL;
295 }
296 int result = iUnknown->QueryInterface(iUnknown, 0, (void **)&demoApi);
297 if (result == 0 && demoApi != NULL) {
298 return demoApi;
299 } else {
300 printf("[hctest]failed to QueryInterface.\n");
301 return NULL;
302 }
303 }
304
GetDefaultIUnknown(const char * serviceName)305 static DefaultFeatureApi *GetDefaultIUnknown(const char *serviceName)
306 {
307 DefaultFeatureApi *defaultApi = NULL;
308 IUnknown *iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(serviceName);
309 if (iUnknown == NULL) {
310 printf("[hctest]failed to GetFeatureApi.\n");
311 return NULL;
312 }
313 int result = iUnknown->QueryInterface(iUnknown, 0, (void **)&defaultApi);
314 if (result == 0 && defaultApi != NULL) {
315 return defaultApi;
316 } else {
317 printf("[hctest]failed to QueryInterface.\n");
318 return NULL;
319 }
320 }
321
322 LITE_TEST_SUIT(distributedschedule, samgr, SingleTaskFuncTestSuite);
323
SingleTaskFuncTestSuiteSetUp(void)324 static BOOL SingleTaskFuncTestSuiteSetUp(void)
325 {
326 osDelay(OPER_INTERVAL);
327 return TRUE;
328 }
329
SingleTaskFuncTestSuiteTearDown(void)330 static BOOL SingleTaskFuncTestSuiteTearDown(void)
331 {
332 return TRUE;
333 }
334
335 /* *
336 * @tc.number : DMSLite_SAMGR_Taskpool_SingleTask_0010
337 * @tc.name : Service with PRI_LOW priority function is ok
338 * @tc.desc : [C- SOFTWARE -0200]
339 */
340 LITE_TEST_CASE(SingleTaskFuncTestSuite, testSingleTask0010, Function | MediumTest | Level2)
341 {
342 // test featureApi function
343 DemoApi *demoApi = GetIUnknown("SingleTS01", "featureName501");
344 if (demoApi == NULL) {
345 TEST_FAIL();
346 }
347 BOOL result = demoApi->FeatureApi001((IUnknown *)demoApi, "xxxx");
348 TEST_ASSERT_EQUAL_INT(result, TRUE);
349
350 g_createFeature.featureCalledCount = 0;
351 Request request = {
352 .msgId = 0,
353 .msgValue = 0
354 };
355 char *body = "I wanna async call good result!";
356 request.len = (int16)(strlen(body) + 1);
357 request.data = malloc(request.len);
358 if (request.data == NULL) {
359 TEST_FAIL();
360 }
361 strcpy_s(request.data, request.len, body);
362 int32 result2 = demoApi->SendRequestProxyF(&(g_createFeature.identity), &request, NULL);
363 TEST_ASSERT_EQUAL_INT(result2 == 0, TRUE);
364 osDelay(OPER_INTERVAL);
365 TEST_ASSERT_EQUAL_INT(g_createFeature.featureCalledCount == 1, TRUE);
366
367 // test defaultFeatureApi function
368 DefaultFeatureApi *defaultApi = GetDefaultIUnknown("SingleTS01");
369 if (defaultApi == NULL) {
370 TEST_FAIL();
371 }
372 result = defaultApi->DefaultApi001((IUnknown *)defaultApi, "yyyy");
373 TEST_ASSERT_EQUAL_INT(result, TRUE);
374
375 Request request2 = {
376 .msgId = 0,
377 .msgValue = 0
378 };
379 char *body2 = "I want to call defaultFeature!";
380 request2.len = (int16)(strlen(body2) + 1);
381 request2.data = malloc(request2.len);
382 if (request2.data == NULL) {
383 TEST_FAIL();
384 }
385 strcpy_s(request2.data, request2.len, body2);
386 result2 = defaultApi->SendRequestProxyDF(&(g_service[0].identity), &request2, NULL);
387 TEST_ASSERT_EQUAL_INT(result2 == 0, TRUE);
388 osDelay(OPER_INTERVAL);
389 TEST_ASSERT_EQUAL_INT(g_service[0].serviceCalledCount == 1, TRUE);
390 };
391
392 /* *
393 * @tc.number : DMSLite_SAMGR_Taskpool_SingleTask_0020
394 * @tc.name : Service with PRI_BELOW_NORMAL priority function is ok
395 * @tc.desc : [C- SOFTWARE -0200]
396 */
397 LITE_TEST_CASE(SingleTaskFuncTestSuite, testSingleTask0020, Function | MediumTest | Level2)
398 {
399 DemoApi *demoApi = GetIUnknown("SingleTS02", "featureName501");
400 if (demoApi == NULL) {
401 TEST_FAIL();
402 }
403 BOOL result = demoApi->FeatureApi001((IUnknown *)demoApi, "xxxx");
404 TEST_ASSERT_EQUAL_INT(result, TRUE);
405
406 g_createFeature.featureCalledCount = 0;
407 Request request = {
408 .msgId = 0,
409 .msgValue = 0
410 };
411 char *body = "I wanna async call good result!";
412 request.len = (int16)(strlen(body) + 1);
413 request.data = malloc(request.len);
414 if (request.data == NULL) {
415 TEST_FAIL();
416 }
417 strcpy_s(request.data, request.len, body);
418 int32 result2 = demoApi->SendRequestProxyF(&(g_createFeature.identity), &request, NULL);
419 TEST_ASSERT_EQUAL_INT(result2 == 0, TRUE);
420 osDelay(OPER_INTERVAL);
421 TEST_ASSERT_EQUAL_INT(g_createFeature.featureCalledCount == 1, TRUE);
422
423 DefaultFeatureApi *defaultApi = GetDefaultIUnknown("SingleTS02");
424 if (defaultApi == NULL) {
425 TEST_FAIL();
426 }
427 result = defaultApi->DefaultApi001((IUnknown *)defaultApi, "yyyy");
428 TEST_ASSERT_EQUAL_INT(result, TRUE);
429
430 Request request2 = {
431 .msgId = 0,
432 .msgValue = 0
433 };
434 char *body2 = "I want to call defaultFeature!";
435 request2.len = (int16)(strlen(body2) + 1);
436 request2.data = malloc(request2.len);
437 if (request2.data == NULL) {
438 TEST_FAIL();
439 }
440 strcpy_s(request2.data, request2.len, body2);
441 result2 = defaultApi->SendRequestProxyDF(&(g_service[1].identity), &request2, NULL);
442 TEST_ASSERT_EQUAL_INT(result2 == 0, TRUE);
443 osDelay(OPER_INTERVAL);
444 TEST_ASSERT_EQUAL_INT(g_service[1].serviceCalledCount == 1, TRUE);
445 };
446
447 /* *
448 * @tc.number : DMSLite_SAMGR_Taskpool_SingleTask_0030
449 * @tc.name : Service with PRI_NORMAL priority function is ok
450 * @tc.desc : [C- SOFTWARE -0200]
451 */
452 LITE_TEST_CASE(SingleTaskFuncTestSuite, testSingleTask0030, Function | MediumTest | Level2)
453 {
454 DemoApi *demoApi = GetIUnknown("SingleTS03", "featureName501");
455 if (demoApi == NULL) {
456 TEST_FAIL();
457 }
458 BOOL result = demoApi->FeatureApi001((IUnknown *)demoApi, "xxxx");
459 TEST_ASSERT_EQUAL_INT(result, TRUE);
460
461 g_createFeature.featureCalledCount = 0;
462 Request request = {
463 .msgId = 0,
464 .msgValue = 0
465 };
466 char *body = "I wanna async call good result!";
467 request.len = (int16)(strlen(body) + 1);
468 request.data = malloc(request.len);
469 if (request.data == NULL) {
470 TEST_FAIL();
471 }
472 strcpy_s(request.data, request.len, body);
473 int32 result2 = demoApi->SendRequestProxyF(&(g_createFeature.identity), &request, NULL);
474 TEST_ASSERT_EQUAL_INT(result2 == 0, TRUE);
475 osDelay(OPER_INTERVAL);
476 TEST_ASSERT_EQUAL_INT(g_createFeature.featureCalledCount == 1, TRUE);
477
478 DefaultFeatureApi *defaultApi = GetDefaultIUnknown("SingleTS03");
479 if (defaultApi == NULL) {
480 TEST_FAIL();
481 }
482 result = defaultApi->DefaultApi001((IUnknown *)defaultApi, "yyyy");
483 TEST_ASSERT_EQUAL_INT(result, TRUE);
484
485 Request request2 = {
486 .msgId = 0,
487 .msgValue = 0
488 };
489 char *body2 = "I want to call defaultFeature!";
490 request2.len = (int16)(strlen(body2) + 1);
491 request2.data = malloc(request2.len);
492 if (request2.data == NULL) {
493 TEST_FAIL();
494 }
495 strcpy_s(request2.data, request2.len, body2);
496 result2 = defaultApi->SendRequestProxyDF(&(g_service[INDEX2].identity), &request2, NULL);
497 TEST_ASSERT_EQUAL_INT(result2 == 0, TRUE);
498 osDelay(OPER_INTERVAL);
499 TEST_ASSERT_EQUAL_INT(g_service[INDEX2].serviceCalledCount == 1, TRUE);
500 };
501
502 /* *
503 * @tc.number : DMSLite_SAMGR_Taskpool_SingleTask_0040
504 * @tc.name : Service with PRI_ABOVE_NORMAL priority function is ok
505 * @tc.desc : [C- SOFTWARE -0200]
506 */
507 LITE_TEST_CASE(SingleTaskFuncTestSuite, testSingleTask0040, Function | MediumTest | Level2)
508 {
509 DemoApi *demoApi = GetIUnknown("SingleTS04", "featureName501");
510 if (demoApi == NULL) {
511 TEST_FAIL();
512 }
513 BOOL result = demoApi->FeatureApi001((IUnknown *)demoApi, "xxxx");
514 TEST_ASSERT_EQUAL_INT(result, TRUE);
515
516 g_createFeature.featureCalledCount = 0;
517 Request request = {
518 .msgId = 0,
519 .msgValue = 0
520 };
521 char *body = "I wanna async call good result!";
522 request.len = (int16)(strlen(body) + 1);
523 request.data = malloc(request.len);
524 if (request.data == NULL) {
525 TEST_FAIL();
526 }
527 strcpy_s(request.data, request.len, body);
528 int32 result2 = demoApi->SendRequestProxyF(&(g_createFeature.identity), &request, NULL);
529 TEST_ASSERT_EQUAL_INT(result2 == 0, TRUE);
530 osDelay(OPER_INTERVAL);
531 TEST_ASSERT_EQUAL_INT(g_createFeature.featureCalledCount == 1, TRUE);
532
533 DefaultFeatureApi *defaultApi = GetDefaultIUnknown("SingleTS04");
534 if (defaultApi == NULL) {
535 TEST_FAIL();
536 }
537 result = defaultApi->DefaultApi001((IUnknown *)defaultApi, "yyyy");
538 TEST_ASSERT_EQUAL_INT(result, TRUE);
539
540 Request request2 = {
541 .msgId = 0,
542 .msgValue = 0
543 };
544 char *body2 = "I want to call defaultFeature!";
545 request2.len = (int16)(strlen(body2) + 1);
546 request2.data = malloc(request2.len);
547 if (request2.data == NULL) {
548 TEST_FAIL();
549 }
550 strcpy_s(request2.data, request2.len, body2);
551 result2 = defaultApi->SendRequestProxyDF(&(g_service[INDEX3].identity), &request2, NULL);
552 TEST_ASSERT_EQUAL_INT(result2 == 0, TRUE);
553 osDelay(OPER_INTERVAL);
554 TEST_ASSERT_EQUAL_INT(g_service[INDEX3].serviceCalledCount == 1, TRUE);
555 };
556
557 /* *
558 * @tc.number : DMSLite_SAMGR_Taskpool_SingleTask_0050
559 * @tc.name : Service initialization order depends on service priority
560 * @tc.desc : [C- SOFTWARE -0200]
561 */
562 LITE_TEST_CASE(SingleTaskFuncTestSuite, testSingleTask0050, Function | MediumTest | Level2)
563 {
564 for (int i = 0; i < VECTOR_Num(&g_nodeVector); i++) {
565 Node *vectorAt = (Node *)VECTOR_At(&g_nodeVector, i);
566 if (vectorAt == NULL) {
567 continue;
568 }
569 TEST_ASSERT_EQUAL_INT(vectorAt->id, i + 1);
570 TEST_ASSERT_EQUAL_INT(strcmp(vectorAt->name, g_serviceNameArray[SERVICE_NUM - (i + 1)]), 0);
571 }
572 };
573
574 RUN_TEST_SUITE(SingleTaskFuncTestSuite);