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 <securec.h>
17 #include <semaphore.h>
18 #include <ohos_init.h>
19 #include "gtest/gtest.h"
20 #include "utils/SamgrTestBase.h"
21 
22 using namespace testing::ext;
23 
24 static const char S_SERVICE[] = "s_service";
25 static const char S_FEATURE[] = "s_feature";
26 
27 static const char T_SERVICE[] = "t_service";
28 static const char T_FEATURE[] = "t_feature";
29 
30 static sem_t g_sem;
31 
32 enum MessageId {
33     MSG_NO, // receiver and no response
34     MSG_RT, // receiver then send response
35     MSG_FW, // receiver then forward message
36 };
37 
38 struct Payload {
39     int id;
40     const char *name;
41     int value;
42 };
43 
44 struct DemoApi {
45     INHERIT_IUNKNOWN;
46     bool(*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
47     int32 (*SAMGR_SendRequestProxy)(const Identity *identity, const Request *request, Handler handler);
48 };
49 
50 struct DemoFeature {
51     INHERIT_FEATURE;
52     INHERIT_IUNKNOWNENTRY(DemoApi);
53     Identity identity;
54     int featureCalledCount;
55     BOOL featureStatus;
56     char *latestRequest;
57 };
58 
59 struct DefaultFeatureApi {
60     INHERIT_IUNKNOWN;
61 };
62 
63 struct ExampleService {
64     INHERIT_SERVICE;
65     INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
66     Identity identity;
67 };
68 
SyncCall(IUnknown *iUnknown, struct Payload *payload)69 static bool SyncCall(IUnknown *iUnknown, struct Payload *payload)
70 {
71     (void)iUnknown;
72     if (payload != nullptr && payload->id >= 0 && payload->name != nullptr) {
73         return TRUE;
74     } else {
75         return FALSE;
76     }
77 }
78 
SAMGR_SendRequestProxy(const Identity *identity, const Request *request, Handler handler)79 static int32 SAMGR_SendRequestProxy(const Identity *identity, const Request *request, Handler handler)
80 {
81     // this api SAMGR_SendRequest is the test target
82     return SAMGR_SendRequest(identity, request, handler);
83 }
84 
GetName(Service *service)85 static const char *GetName(Service *service)
86 {
87     (void)service;
88     return S_SERVICE;
89 }
90 
GetName2(Service *service)91 static const char *GetName2(Service *service)
92 {
93     (void)service;
94     return T_SERVICE;
95 }
96 
Initialize(Service *service, Identity identity)97 static BOOL Initialize(Service *service, Identity identity)
98 {
99     ExampleService *example = (ExampleService *)service;
100     example->identity = identity;
101     printf("[hcpptest]serviceName %s Initialize \n", service->GetName(service));
102 
103     return TRUE;
104 }
105 
MessageHandle(Service *service, Request *msg)106 static BOOL MessageHandle(Service *service, Request *msg)
107 {
108     (void)service;
109     return FALSE;
110 }
111 
GetTaskConfig(Service *service)112 static TaskConfig GetTaskConfig(Service *service)
113 {
114     (void)service;
115     TaskConfig config = {LEVEL_HIGH, PRI_ABOVE_NORMAL, 0x800, 20, SHARED_TASK};
116     return config;
117 }
118 
119 static ExampleService g_service = {
120     .GetName = GetName,
121     .Initialize = Initialize,
122     .MessageHandle = MessageHandle,
123     .GetTaskConfig = GetTaskConfig,
124     .ver = 0x20,
125     .ref = 1,
126     .iUnknown = {
127         DEFAULT_IUNKNOWN_IMPL,
128     }
129 };
130 
131 static ExampleService g_service2 = {
132     .GetName = GetName2,
133     .Initialize = Initialize,
134     .MessageHandle = MessageHandle,
135     .GetTaskConfig = GetTaskConfig,
136     .ver = 0x20,
137     .ref = 1,
138     .iUnknown = {
139         DEFAULT_IUNKNOWN_IMPL,
140     }
141 };
142 
FEATURE_GetName(Feature *feature)143 static const char *FEATURE_GetName(Feature *feature)
144 {
145     (void)feature;
146     return S_FEATURE;
147 }
148 
FEATURE_GetName2(Feature *feature)149 static const char *FEATURE_GetName2(Feature *feature)
150 {
151     (void)feature;
152     return T_FEATURE;
153 }
154 
FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)155 static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
156 {
157     DemoFeature *demoFeature = (DemoFeature *)feature;
158     demoFeature->identity = identity;
159     printf("[hcpptest]featureName %s Initialize \n", feature->GetName(feature));
160     (void)parent;
161 }
162 
FEATURE_OnStop(Feature *feature, Identity identity)163 static void FEATURE_OnStop(Feature *feature, Identity identity)
164 {
165     (void)feature;
166     (void)identity;
167 }
168 
FEATURE_OnMessage(Feature *feature, Request *request)169 static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
170 {
171     int32 returnCode;
172     DemoFeature *demoFeature = (DemoFeature *)feature;
173     demoFeature->featureCalledCount++;
174 
175     if (demoFeature->latestRequest != nullptr) {
176         free(demoFeature->latestRequest);
177     }
178 
179     int requestLen = 0;
180     if (request->len > 0) {
181         requestLen = request->len;
182     } else {
183         requestLen = strlen((char *)request->data) + 1;
184     }
185     demoFeature->latestRequest = (char *)malloc(requestLen * sizeof(char));
186     if (demoFeature->latestRequest == nullptr) {
187         ADD_FAILURE();
188     }
189     errno_t error = strcpy_s(demoFeature->latestRequest, requestLen, (char *)request->data);
190     if (error != EOK) {
191         ADD_FAILURE();
192     }
193 
194     switch (request->msgId) {
195         case MSG_NO:
196             returnCode = 0;
197             break;
198         case MSG_RT:
199         {
200             char dataR[] = "Yes, you did!";
201             Response response = {
202                 .data = dataR,
203                 .len = 0,
204                 };
205             returnCode = SAMGR_SendResponse(request, &response);
206             break;
207         };
208         case MSG_FW:
209         {
210             returnCode = 0;
211             break;
212         };
213         default:
214             returnCode = 0;
215     }
216     demoFeature->featureStatus = ((returnCode == 0) ? TRUE : FALSE);
217 
218     sem_post(&g_sem);
219     return demoFeature->featureStatus;
220 }
221 
222 static DemoFeature g_feature = {
223     .GetName = FEATURE_GetName,
224     .OnInitialize = FEATURE_OnInitialize,
225     .OnStop = FEATURE_OnStop,
226     .OnMessage = FEATURE_OnMessage,
227     .ver = 0x20,
228     .ref = 0,
229     .iUnknown = {
230         DEFAULT_IUNKNOWN_IMPL,
231         .SyncCall = SyncCall,
232         .SAMGR_SendRequestProxy = SAMGR_SendRequestProxy,
233     },
234     .identity = {-1, 1, nullptr},
235     .featureCalledCount = 0,
236     .featureStatus = TRUE,
237     .latestRequest = nullptr,
238 };
239 static DemoFeature g_feature2 = {
240     .GetName = FEATURE_GetName2,
241     .OnInitialize = FEATURE_OnInitialize,
242     .OnStop = FEATURE_OnStop,
243     .OnMessage = FEATURE_OnMessage,
244     .ver = 0x20,
245     .ref = 0,
246     .iUnknown = {
247         DEFAULT_IUNKNOWN_IMPL,
248         .SyncCall = SyncCall,
249         .SAMGR_SendRequestProxy = SAMGR_SendRequestProxy,
250     },
251     .identity = {-1, 2, nullptr},
252     .featureCalledCount = 0,
253     .featureStatus = TRUE,
254     .latestRequest = nullptr,
255 };
256 
GServiceInit(void)257 static void GServiceInit(void)
258 {
259     printf("[hcpptest]GServiceInit start! \n");
260     BOOL result = SAMGR_GetInstance()->RegisterService((Service *)&g_service);
261     BOOL result2 = SAMGR_GetInstance()->RegisterService((Service *)&g_service2);
262     if (result == FALSE || result2 == FALSE) {
263         printf("[hcpptest]E RegisterService failed! \n");
264     }
265 }
266 SYSEX_SERVICE_INIT(GServiceInit);
267 
GFeatureInit(void)268 static void GFeatureInit(void)
269 {
270     printf("[hcpptest]GFeatureInit start! \n");
271     BOOL result1 = SAMGR_GetInstance()->RegisterFeature(S_SERVICE, (Feature *)&g_feature);
272     BOOL result2 = SAMGR_GetInstance()->RegisterFeatureApi(S_SERVICE, S_FEATURE,
273                                                            GET_IUNKNOWN(g_feature));
274 
275     BOOL result3 = SAMGR_GetInstance()->RegisterFeature(T_SERVICE, (Feature *)&g_feature2);
276     BOOL result4 = SAMGR_GetInstance()->RegisterFeatureApi(T_SERVICE, T_FEATURE,
277                                                            GET_IUNKNOWN(g_feature2));
278     if (result1 == FALSE || result2 == FALSE || result3 == FALSE || result4 == FALSE) {
279         printf("[hcpptest]E failed to register feature or api! \n");
280     }
281 }
282 SYSEX_FEATURE_INIT(GFeatureInit);
283 
GetIUnknown(const char *serviceName, const char *featureName)284 static DemoApi *GetIUnknown(const char *serviceName, const char *featureName)
285 {
286     DemoApi *demoApi = nullptr;
287     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(serviceName, featureName);
288     if (iUnknown == nullptr) {
289         return nullptr;
290     }
291     int result = iUnknown->QueryInterface(iUnknown, 0x20, (void **)&demoApi);
292     if (result == 0 && demoApi != nullptr) {
293         return demoApi;
294     } else {
295         return nullptr;
296     }
297 }
298 
ReleaseIUnknown(DemoApi *demoApi)299 static void ReleaseIUnknown(DemoApi *demoApi)
300 {
301     demoApi->Release((IUnknown *)demoApi);
302 }
303 
WaitBySem(void)304 static void WaitBySem(void)
305 {
306     struct timespec ts = {};
307     clock_gettime(CLOCK_REALTIME, &ts);
308     ts.tv_sec += 1;
309     sem_timedwait(&g_sem, &ts);
310 }
311 
DemoHandlerAndCheck(const Request *request, const Response *response)312 static void DemoHandlerAndCheck(const Request *request, const Response *response)
313 {
314     char requestData[] = "I wanna async call good result!";
315     ASSERT_EQ(strcmp((char *)request->data, requestData), 0);
316 
317     char responseData[] = "Yes, you did!";
318     ASSERT_EQ(strcmp((char *)response->data, responseData), 0);
319 }
320 
321 class SendRequestTest : public testing::Test {
322 protected:
323     // SetUpTestCase: Testsuit setup, run before 1st testcase
SetUpTestCase(void)324     static void SetUpTestCase(void)
325     {
326         printf("[hcpptest]SetUpTestCase! \n");
327         SystemInitProxy();
328     }
329     // TearDownTestCase: Testsuit teardown, run after last testcase
TearDownTestCase(void)330     static void TearDownTestCase(void)
331     {
332     }
333     // Testcase setup
SetUp()334     virtual void SetUp()
335     {
336         usleep(OPER_INTERVAL * MS2US);
337     }
338     // Testcase teardown
TearDown()339     virtual void TearDown()
340     {
341         sem_destroy(&g_sem);
342     }
343 };
344 
345 /**
346  * @tc.number    : DMSLite_SAMGR_SyncCall_0010
347  * @tc.name      : Service support synchronous call
348  * @tc.desc      : [C- SOFTWARE -0200]
349 */
HWTEST_F(SendRequestTest, testSyncCall0010, Function | MediumTest | Level1)350 HWTEST_F(SendRequestTest, testSyncCall0010, Function | MediumTest | Level1) {
351     DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
352     if (demoApi == nullptr) {
353         ADD_FAILURE();
354     }
355     char nameR[] = "I wanna sync call good result!";
356     struct Payload payload = {
357         .id = 0, // api will return true
358         .name = nameR,
359         .value = 1};
360     bool result = demoApi->SyncCall((IUnknown *)demoApi, &payload);
361     ASSERT_EQ(result, TRUE);
362 
363     struct Payload payloadX = {
364         .id = -1,  // api will return false
365         .name = nameR,
366         .value = 1};
367     result = demoApi->SyncCall((IUnknown *)demoApi, &payloadX);
368     ASSERT_EQ(result, FALSE);
369 
370     ReleaseIUnknown(demoApi);
371 }
372 
373 /**
374  * @tc.number    : DMSLite_SAMGR_SendRequest_0010
375  * @tc.name      : Service support asynchronous call
376  * @tc.desc      : [C- SOFTWARE -0200]
377 */
HWTEST_F(SendRequestTest, testSendRequest0010, Function | MediumTest | Level1)378 HWTEST_F(SendRequestTest, testSendRequest0010, Function | MediumTest | Level1) {
379     DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
380     if (demoApi == nullptr) {
381         ADD_FAILURE();
382     }
383     Request request = {.msgId = MSG_NO,
384                        .len = 0,
385                        .data = nullptr,
386                        .msgValue = 0};
387     char body[] = "I wanna async call good result!";
388     request.len = strlen(body) + 1;
389     request.data = malloc(request.len);
390     if (request.data == nullptr) {
391         ADD_FAILURE();
392     }
393     errno_t error = strcpy_s((char *)request.data, request.len, body);
394     if (error != EOK) {
395         printf("[hcpptest]E failed to strcpy_s \n");
396     }
397 
398     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(T_SERVICE, T_FEATURE);
399     DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
400 
401     feature->featureCalledCount = 0;
402     sem_init(&g_sem, 0, 0);
403     int32 result = demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, nullptr);
404     ASSERT_EQ(result == 0, TRUE);
405 
406     WaitBySem();
407     ASSERT_EQ(feature->featureCalledCount == 1, TRUE);
408     ASSERT_EQ(strcmp(feature->latestRequest, body), 0);
409 
410     ReleaseIUnknown(demoApi);
411 }
412 
413 /**
414  * @tc.number    : DMSLite_SAMGR_SendRequest_0020
415  * @tc.name      : Feature can send an asynchronous message to itself
416  * @tc.desc      : [C- SOFTWARE -0200]
417 */
HWTEST_F(SendRequestTest, testSendRequest0020, Function | MediumTest | Level2)418 HWTEST_F(SendRequestTest, testSendRequest0020, Function | MediumTest | Level2) {
419     DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
420     if (demoApi == nullptr) {
421         ADD_FAILURE();
422     }
423     Request request = {.msgId = MSG_RT,
424                         .len = 0,
425                        .data = nullptr,
426                        .msgValue = 0};
427     char body[] = "I wanna async call good result!";
428     request.len = (uint32_t)(strlen(body) + 1);
429     request.data = malloc(request.len);
430     if (request.data == nullptr) {
431         ADD_FAILURE();
432     }
433     errno_t error = strcpy_s((char *)request.data, request.len, body);
434     if (error != EOK) {
435         printf("[hcpptest]E failed to strcpy_s \n");
436     }
437 
438     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(S_SERVICE, S_FEATURE);
439     DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
440 
441     feature->featureCalledCount = 0;
442     sem_init(&g_sem, 0, 0);
443     int32 result = demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, nullptr);
444     ASSERT_EQ(result == 0, TRUE);
445 
446     WaitBySem();
447     ASSERT_EQ(feature->featureCalledCount == 1, TRUE);
448     ASSERT_EQ(strcmp(feature->latestRequest, body), 0);
449     ReleaseIUnknown(demoApi);
450 }
451 
452 /**
453  * @tc.number    : DMSLite_SAMGR_SendRequest_0030
454  * @tc.name      : Feature failed to send an asynchronous message if the specified identity does not exist
455  * @tc.desc      : [C- SOFTWARE -0200]
456 */
HWTEST_F(SendRequestTest, testSendRequest0030, Function | MediumTest | Level2)457 HWTEST_F(SendRequestTest, testSendRequest0030, Function | MediumTest | Level2) {
458     DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
459     if (demoApi == nullptr) {
460         ADD_FAILURE();
461     }
462     Request request = {.msgId = MSG_RT,
463                        .len = 0,
464                        .data = nullptr,
465                        .msgValue = 0};
466     char body[] = "I wanna async call good result!";
467     request.len = (uint32_t)(strlen(body) + 1);
468     request.data = malloc(request.len);
469     if (request.data == nullptr) {
470         ADD_FAILURE();
471     }
472     errno_t error = strcpy_s((char *)request.data, request.len, body);
473     if (error != EOK) {
474         ADD_FAILURE();
475     }
476 
477     Identity identityX = {-1, -200, nullptr};
478     int32 result = demoApi->SAMGR_SendRequestProxy(&identityX, &request, nullptr);
479     free(request.data);
480     ASSERT_EQ(result != 0, TRUE);
481 
482     ReleaseIUnknown(demoApi);
483 }
484 
485 /**
486  * @tc.number    : DMSLite_SAMGR_SendRequest_0040
487  * @tc.name      : Feature can send an asynchronous message which length is 0
488  * @tc.desc      : [C- SOFTWARE -0200]
489 */
HWTEST_F(SendRequestTest, testSendRequest0040, Function | MediumTest | Level2)490 HWTEST_F(SendRequestTest, testSendRequest0040, Function | MediumTest | Level2) {
491     DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
492     if (demoApi == nullptr) {
493         ADD_FAILURE();
494     }
495     Request request = {.msgId = MSG_RT,
496                        .len = 0,
497                        .data = nullptr,
498                        .msgValue = 0};
499     char body[] = "";
500     request.len = (uint32_t)(strlen(body) + 1);
501     request.data = malloc(request.len);
502     if (request.data == nullptr) {
503         ADD_FAILURE();
504     }
505     errno_t error = strcpy_s((char *)request.data, request.len, body);
506     if (error != EOK) {
507         ADD_FAILURE();
508     }
509 
510     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(T_SERVICE, T_FEATURE);
511     DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
512 
513     feature->featureCalledCount = 0;
514     sem_init(&g_sem, 0, 0);
515     int32 result = demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, nullptr);
516     ASSERT_EQ(result == 0, TRUE);
517 
518     WaitBySem();
519     ASSERT_EQ(feature->featureCalledCount == 1, TRUE);
520     ASSERT_EQ(strcmp(feature->latestRequest, body), 0);
521 
522     ReleaseIUnknown(demoApi);
523 }
524 
525 /**
526  * @tc.number    : DMSLite_SAMGR_SendRequest_0050
527  * @tc.name      : Feature failed to send an asynchronous message if id or request is nullptr
528  * @tc.desc      : [C- SOFTWARE -0200]
529 */
HWTEST_F(SendRequestTest, testSendRequest0050, Function | MediumTest | Level2)530 HWTEST_F(SendRequestTest, testSendRequest0050, Function | MediumTest | Level2) {
531     DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
532     if (demoApi == nullptr) {
533         ADD_FAILURE();
534     }
535     Request request = {.msgId = MSG_RT,
536                        .len = 0,
537                        .data = nullptr,
538                        .msgValue = 0};
539     char body[] = "xxxx";
540     request.len = strlen(body) + 1;
541     request.data = malloc(request.len);
542     if (request.data == nullptr) {
543         ADD_FAILURE();
544     }
545     errno_t error = strcpy_s((char *)request.data, request.len, body);
546     if (error != EOK) {
547         ADD_FAILURE();
548     }
549 
550     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(T_SERVICE, T_FEATURE);
551     DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
552 
553     int32 result = demoApi->SAMGR_SendRequestProxy(NULL, &request, nullptr);
554     ASSERT_EQ(result != 0, TRUE);
555 
556     result = demoApi->SAMGR_SendRequestProxy(&feature->identity, nullptr, nullptr);
557     ASSERT_EQ(result != 0, TRUE);
558 
559     free(request.data);
560     ReleaseIUnknown(demoApi);
561 }
562 
563 /**
564  * @tc.number    : DMSLite_SAMGR_SendRequest_0060
565  * @tc.name      : Samgr will not check the matching relationship between len and data
566  * @tc.desc      : [C- SOFTWARE -0200]
567 */
HWTEST_F(SendRequestTest, testSendRequest0060, Function | MediumTest | Level2)568 HWTEST_F(SendRequestTest, testSendRequest0060, Function | MediumTest | Level2) {
569     DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
570     if (demoApi == nullptr) {
571         ADD_FAILURE();
572     }
573     Request request = {.msgId = MSG_NO,
574                        .len = 0,
575                        .data = nullptr,
576                        .msgValue = 0};
577     char body[] = "I wanna async call good result!";
578     request.len = 0;
579     request.data = malloc(strlen(body) + 1);
580     if (request.data == nullptr) {
581         ADD_FAILURE();
582     }
583     errno_t error = strcpy_s((char *)request.data, strlen(body) + 1, body);
584     if (error != EOK) {
585         ADD_FAILURE();
586     }
587     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(T_SERVICE, T_FEATURE);
588     DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
589 
590     int32 result = demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, nullptr);
591     free(request.data);
592     ASSERT_EQ(result == 0, TRUE);
593 
594     Request request2 = {.msgId = MSG_NO,
595                         .len = 0,
596                         .data = nullptr,
597                         .msgValue = 0};
598     request2.len = (uint32_t)(strlen(body) + 1);
599     request2.data = malloc(request2.len);
600     if (request2.data == nullptr) {
601         ADD_FAILURE();
602     }
603     error = strcpy_s((char *)request2.data, request2.len, body);
604     if (error != EOK) {
605         ADD_FAILURE();
606     }
607 
608     result = demoApi->SAMGR_SendRequestProxy(&feature->identity, &request2, nullptr);
609     ASSERT_EQ(result == 0, TRUE);
610 
611     ReleaseIUnknown(demoApi);
612 }
613 
614 /**
615  * @tc.number    : DMSLite_SAMGR_SendRequest_0070
616  * @tc.name      : Feature send an asynchronous message and register handler then can receive response
617  * @tc.desc      : [C- SOFTWARE -0200]
618 */
HWTEST_F(SendRequestTest, testSendRequest0070, Function | MediumTest | Level2)619 HWTEST_F(SendRequestTest, testSendRequest0070, Function | MediumTest | Level2) {
620     DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
621     if (demoApi == nullptr) {
622         ADD_FAILURE();
623     }
624     Request request = {.msgId = MSG_RT,
625                        .len = 0,
626                        .data = nullptr,
627                        .msgValue = 0};
628     char body[] = "I wanna async call good result!";
629     request.len = strlen(body) + 1;
630     request.data = malloc(request.len);
631     if (request.data == nullptr) {
632         ADD_FAILURE();
633     }
634     errno_t error = strcpy_s((char *)request.data, request.len, body);
635     if (error != EOK) {
636         ADD_FAILURE();
637     }
638 
639     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(T_SERVICE, T_FEATURE);
640     DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
641 
642     sem_init(&g_sem, 0, 0);
643 
644     auto onHandlerAndCheck = [] (const Request *request, const Response *response) {
645         char requestData[] = "I wanna async call good result!";
646         ASSERT_EQ(strcmp((char *)request->data, requestData), 0);
647 
648         char responseData[] = "Yes, you did!";
649         ASSERT_EQ(strcmp((char *)response->data, responseData), 0);
650     };
651     int32 result = demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, onHandlerAndCheck);
652 
653     WaitBySem();
654     ASSERT_EQ(result, 0);
655     ASSERT_EQ(strcmp(feature->latestRequest, body), 0);
656 
657     ReleaseIUnknown(demoApi);
658 }
659 
660 /**
661  * @tc.number    : DMSLite_SAMGR_SendRequest_0080
662  * @tc.name      : Feature send an asynchronous message repeatedly, no memory leak
663  * @tc.desc      : [C- SOFTWARE -0200]
664 */
HWTEST_F(SendRequestTest, testSendRequest0080, Function | MediumTest | Level2)665 HWTEST_F(SendRequestTest, testSendRequest0080, Function | MediumTest | Level2) {
666     for (int i = 0; i < PRESSURE_L0; i++) {
667         DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
668         if (demoApi == nullptr) {
669             ADD_FAILURE();
670         }
671         Request request = {.msgId = MSG_RT,
672                            .len = 0,
673                            .data = nullptr,
674                            .msgValue = 0};
675         char body[] = "I wanna async call good result!";
676         request.len = strlen(body) + 1;
677         request.data = malloc(request.len);
678         if (request.data == nullptr) {
679             ADD_FAILURE();
680         }
681         errno_t error = strcpy_s((char *)request.data, request.len, body);
682         if (error != EOK) {
683             ADD_FAILURE();
684         }
685 
686         IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(T_SERVICE, T_FEATURE);
687         DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
688 
689         sem_init(&g_sem, 0, 0);
690         int32 result = demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, DemoHandlerAndCheck);
691         ASSERT_EQ(result, 0);
692 
693         WaitBySem();
694         ASSERT_EQ(strcmp(feature->latestRequest, body), 0);
695 
696         ReleaseIUnknown(demoApi);
697     }
698 }
699 
700 /**
701  * @tc.number    : DMSLite_SAMGR_SendRequest_0090
702  * @tc.name      : Feature send an asynchronous message with 0 len repeatedly, no memory leak
703  * @tc.desc      : [C- SOFTWARE -0200]
704 */
HWTEST_F(SendRequestTest, testSendRequest0090, Function | MediumTest | Level2)705 HWTEST_F(SendRequestTest, testSendRequest0090, Function | MediumTest | Level2) {
706     for (int i = 0; i < PRESSURE_L0; i++) {
707         DemoApi *demoApi = GetIUnknown(S_SERVICE, S_FEATURE);
708         if (demoApi == nullptr) {
709             ADD_FAILURE();
710         }
711         Request request = {.msgId = MSG_RT,
712                            .len = 0,
713                            .data = nullptr,
714                            .msgValue = 0};
715         char body[] = "I wanna async call good result!";
716         request.len = 0;
717         request.data = body;
718 
719         IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(T_SERVICE, T_FEATURE);
720         DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
721 
722         sem_init(&g_sem, 0, 0);
723         int32 result = demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, DemoHandlerAndCheck);
724         ASSERT_EQ(result, 0);
725 
726         WaitBySem();
727         ASSERT_EQ(strcmp(feature->latestRequest, body), 0);
728 
729         ReleaseIUnknown(demoApi);
730     }
731 }