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 <ohos_init.h>
18 #include "gtest/gtest.h"
19 #include "utils/SamgrTestBase.h"
20
21 using namespace testing::ext;
22
23 enum MessageId {
24 MSG_NO = 1, // receiver does not send response
25 MSG_RT = 2, // receiver send response
26 MSG_FW = 3, // receiver forward message
27 MSG_RT_MULTI = 4, // receiver send response
28 };
29
30 struct Payload {
31 int id;
32 const char *name;
33 int value;
34 };
35
36 struct DemoApi {
37 INHERIT_IUNKNOWN;
38 int32 (*SAMGR_SendRequestProxy)(const Identity *identity, const Request *request, Handler handler);
39 };
40
41 struct DemoFeature {
42 INHERIT_FEATURE;
43 INHERIT_IUNKNOWNENTRY(DemoApi);
44 Identity identity;
45 int featureCalledCount;
46 bool featureStatus;
47 };
48
49 struct DefaultFeatureApi {
50 INHERIT_IUNKNOWN;
51 };
52
53 struct ExampleService {
54 INHERIT_SERVICE;
55 INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
56 Identity identity;
57 };
58
SAMGR_SendRequestProxy(const Identity * identity,const Request * request,Handler handler)59 static int32 SAMGR_SendRequestProxy(const Identity *identity, const Request *request, Handler handler)
60 {
61 return SAMGR_SendRequest(identity, request, handler);
62 }
63
GetName(Service * service)64 static const char *GetName(Service *service)
65 {
66 (void)service;
67 return "serviceName601";
68 }
69
Initialize(Service * service,Identity identity)70 static BOOL Initialize(Service *service, Identity identity)
71 {
72 ExampleService *example = (ExampleService *)service;
73 example->identity = identity;
74
75 printf("[hcpptest]serviceName %s Initialize \n", service->GetName(service));
76 return TRUE;
77 }
78
MessageHandle(Service * service,Request * msg)79 static BOOL MessageHandle(Service *service, Request *msg)
80 {
81 (void)service;
82 (void)msg;
83 return FALSE;
84 }
85
GetTaskConfig(Service * service)86 static TaskConfig GetTaskConfig(Service *service)
87 {
88 (void)service;
89 TaskConfig config = {LEVEL_HIGH, PRI_ABOVE_NORMAL, 0x800, 20, SHARED_TASK}; // share with broadcast
90 return config;
91 }
92
93 static ExampleService g_service = {
94 .GetName = GetName,
95 .Initialize = Initialize,
96 .MessageHandle = MessageHandle,
97 .GetTaskConfig = GetTaskConfig,
98 .ver = 0x20,
99 .ref = 1,
100 .iUnknown = {
101 DEFAULT_IUNKNOWN_IMPL,
102 }
103 };
104
FEATURE_GetName(Feature * feature)105 static const char *FEATURE_GetName(Feature *feature)
106 {
107 (void)feature;
108 return "featureName601";
109 }
110
FEATURE_GetName02(Feature * feature)111 static const char *FEATURE_GetName02(Feature *feature)
112 {
113 (void)feature;
114 return "featureName602";
115 }
116
FEATURE_GetName03(Feature * feature)117 static const char *FEATURE_GetName03(Feature *feature)
118 {
119 (void)feature;
120 return "featureName603";
121 }
122
FEATURE_OnInitialize(Feature * feature,Service * parent,Identity identity)123 static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
124 {
125 DemoFeature *demoFeature = (DemoFeature *)feature;
126 demoFeature->identity = identity;
127
128 (void)parent;
129 }
130
FEATURE_OnStop(Feature * feature,Identity identity)131 static void FEATURE_OnStop(Feature *feature, Identity identity)
132 {
133 (void)feature;
134 (void)identity;
135 }
136
FEATURE_OnMessage(Feature * feature,Request * request)137 static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
138 {
139 DemoFeature *demoFeature = (DemoFeature *)feature;
140 demoFeature->featureCalledCount++;
141 demoFeature->featureStatus = TRUE;
142
143 return TRUE;
144 }
145
FEATURE_OnMessage02(Feature * feature,Request * request)146 static BOOL FEATURE_OnMessage02(Feature *feature, Request *request)
147 {
148 int32 returnCode;
149 DemoFeature *demoFeature = (DemoFeature *)feature;
150 demoFeature->featureCalledCount++;
151
152 switch (request->msgId) {
153 case MSG_NO:
154 returnCode = 0;
155 break;
156 case MSG_RT:
157 {
158 char *dataR = (char*)"Yes, you did!";
159 Response response = {
160 .data = dataR,
161 .len = 0,
162 };
163 returnCode = SAMGR_SendResponse(request, &response);
164 break;
165 };
166 case MSG_FW:
167 {
168 char *dataR = (char*)"Yes, you did!";
169 Response response = {
170 .data = dataR,
171 .len = 0,
172 };
173 request->msgId = MSG_NO;
174 IUnknown *iUnknownX = SAMGR_GetInstance()->GetFeatureApi("serviceName601", "featureName602");
175 DemoFeature *featureX = GET_OBJECT(iUnknownX, DemoFeature, iUnknown);
176 returnCode = SAMGR_SendResponseByIdentity(&featureX->identity, request, &response);
177 break;
178 };
179 default:
180 returnCode = 0;
181 }
182 demoFeature->featureStatus = ((returnCode == 0) ? TRUE : FALSE);
183 return demoFeature->featureStatus;
184 }
185
FEATURE_OnMessage03(Feature * feature,Request * request)186 static BOOL FEATURE_OnMessage03(Feature *feature, Request *request)
187 {
188 int32 returnCode = 0;
189 DemoFeature *demoFeature = (DemoFeature *)feature;
190 demoFeature->featureCalledCount++;
191
192 switch (request->msgId) {
193 case MSG_NO:
194 returnCode = 0;
195 break;
196 case MSG_RT:
197 {
198 char *dataR = (char*)"Yes, you did!";
199 Response response = {
200 .data = dataR,
201 .len = 0,
202 };
203 returnCode = SAMGR_SendResponse(request, &response);
204 };
205 break;
206 case MSG_FW:
207 {
208 char *dataR = (char*)"Yes, you did!";
209 Response response = {
210 .data = dataR,
211 .len = 0,
212 };
213 request->msgId = MSG_NO;
214 IUnknown *iUnknownX = SAMGR_GetInstance()->GetFeatureApi("serviceName601", "featureName602");
215 DemoFeature *featureX = GET_OBJECT(iUnknownX, DemoFeature, iUnknown);
216 returnCode = SAMGR_SendResponseByIdentity(&featureX->identity, request, &response);
217 };
218 break;
219 case MSG_RT_MULTI:
220 {
221 Response response = {
222 .data = (char*)"Yes, you did!",
223 .len = 0,
224 };
225 int tempCode = SAMGR_SendResponse(request, &response);
226 if (tempCode != 0) {
227 printf("[hctest]E failed to SendResponse rt: %d \n", tempCode);
228 returnCode++;
229 }
230 }
231 }
232 demoFeature->featureStatus = ((returnCode == 0) ? TRUE : FALSE);
233 return demoFeature->featureStatus;
234 }
235
236 static DemoFeature g_feature = {
237 .GetName = FEATURE_GetName,
238 .OnInitialize = FEATURE_OnInitialize,
239 .OnStop = FEATURE_OnStop,
240 .OnMessage = FEATURE_OnMessage,
241 .ver = 0x20,
242 .ref = 1,
243 .iUnknown = {
244 DEFAULT_IUNKNOWN_IMPL,
245 .SAMGR_SendRequestProxy = SAMGR_SendRequestProxy,
246 },
247 .identity = {-1, -1, nullptr},
248 .featureCalledCount = 0,
249 .featureStatus = TRUE,
250 };
251 static DemoFeature g_feature02 = {
252 .GetName = FEATURE_GetName02,
253 .OnInitialize = FEATURE_OnInitialize,
254 .OnStop = FEATURE_OnStop,
255 .OnMessage = FEATURE_OnMessage02,
256 .ver = 0x20,
257 .ref = 0,
258 .iUnknown = {
259 DEFAULT_IUNKNOWN_IMPL,
260 .SAMGR_SendRequestProxy = SAMGR_SendRequestProxy,
261 },
262 .identity = {-1, 1, nullptr},
263 .featureCalledCount = 0,
264 .featureStatus = TRUE,
265 };
266 static DemoFeature g_feature03 = {
267 .GetName = FEATURE_GetName03,
268 .OnInitialize = FEATURE_OnInitialize,
269 .OnStop = FEATURE_OnStop,
270 .OnMessage = FEATURE_OnMessage03,
271 .ver = 0x20,
272 .ref = 0,
273 .iUnknown = {
274 DEFAULT_IUNKNOWN_IMPL,
275 .SAMGR_SendRequestProxy = SAMGR_SendRequestProxy,
276 },
277 .identity = {-1, 2, nullptr},
278 .featureCalledCount = 0,
279 .featureStatus = TRUE,
280 };
281
GServiceInit(void)282 static void GServiceInit(void)
283 {
284 printf("[hcpptest]ServiceInit! \n");
285 SAMGR_GetInstance()->RegisterService((Service *)&g_service);
286 }
287 SYSEX_SERVICE_INIT(GServiceInit);
288
GFeatureInit(void)289 static void GFeatureInit(void)
290 {
291 printf("[hcpptest]FeatureInit! \n");
292 SAMGR_GetInstance()->RegisterDefaultFeatureApi("serviceName601", GET_IUNKNOWN(g_feature));
293
294 SAMGR_GetInstance()->RegisterFeature("serviceName601", (Feature *)&g_feature02);
295 SAMGR_GetInstance()->RegisterFeatureApi("serviceName601", "featureName602", GET_IUNKNOWN(g_feature02));
296
297 SAMGR_GetInstance()->RegisterFeature("serviceName601", (Feature *)&g_feature03);
298 SAMGR_GetInstance()->RegisterFeatureApi("serviceName601", "featureName603", GET_IUNKNOWN(g_feature03));
299 }
300 SYSEX_FEATURE_INIT(GFeatureInit);
301
GetIUnknown(const char * serviceName,const char * featureName)302 static DemoApi *GetIUnknown(const char *serviceName, const char *featureName)
303 {
304 DemoApi *demoApi = nullptr;
305 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(serviceName, featureName);
306 if (iUnknown == nullptr) {
307 return nullptr;
308 }
309 int result = iUnknown->QueryInterface(iUnknown, 0x20, (void **)&demoApi);
310 if (result == 0 && demoApi != nullptr) {
311 return demoApi;
312 } else {
313 return nullptr;
314 }
315 }
316
ReleaseIUnknown(DemoApi * demoApi)317 static void ReleaseIUnknown(DemoApi *demoApi)
318 {
319 demoApi->Release((IUnknown *)demoApi);
320 }
321
DemoHandler(const Request * request,const Response * response)322 static void DemoHandler(const Request *request, const Response *response)
323 {
324 (void)request;
325 (void)response;
326 }
327
DemoHandlerAndCheck(const Request * request,const Response * response)328 static void DemoHandlerAndCheck(const Request *request, const Response *response)
329 {
330 char *requestData = (char*)"I wanna async call good result!";
331 ASSERT_EQ(strcmp((char *)request->data, requestData), 0);
332
333 char *responseData = (char*)"Yes, you did!";
334 ASSERT_EQ(strcmp((char *)response->data, responseData), 0);
335 }
336
337 class SendResponseTest : public testing::Test {
338 protected:
339 // SetUpTestCase: Testsuit setup, run before 1st testcase
SetUpTestCase(void)340 static void SetUpTestCase(void)
341 {
342 }
343 // TearDownTestCase: Testsuit teardown, run after last testcase
TearDownTestCase(void)344 static void TearDownTestCase(void)
345 {
346 }
347 // Testcase setup
SetUp()348 virtual void SetUp()
349 {
350 }
351 // Testcase teardown
TearDown()352 virtual void TearDown()
353 {
354 }
355 };
356
357 /**
358 * @tc.number : DMSLite_SAMGR_SendResponse_0010
359 * @tc.name : Receiver send response successfully
360 * @tc.desc : [C- SOFTWARE -0200]
361 */
362 HWTEST_F(SendResponseTest, testSendResponse0010, Function | MediumTest | Level2) {
363 DemoApi *demoApi = GetIUnknown("serviceName601", "featureName602");
364 if (demoApi == nullptr) {
365 ADD_FAILURE();
366 }
367 Request request = {.msgId = MSG_RT,
368 .len = 0,
369 .data = nullptr,
370 .msgValue = 0};
371 char *body = (char*)"I wanna async call good result!";
372 request.len = strlen(body) + 1;
373 request.data = malloc(request.len);
374 if (request.data == nullptr) {
375 ADD_FAILURE();
376 }
377 errno_t error = strcpy_s((char *)request.data, request.len, body);
378 if (error != EOK) {
379 ADD_FAILURE();
380 }
381
382 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi("serviceName601", "featureName603");
383 DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
384 demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, DemoHandlerAndCheck);
385
386 usleep(OPER_INTERVAL * MS2US);
387 ASSERT_EQ(feature->featureStatus, TRUE);
388
389 ReleaseIUnknown(demoApi);
390 }
391
392 /**
393 * @tc.number : DMSLite_SAMGR_SendResponse_0020
394 * @tc.name : Receiver can not send response if sender has not register callback
395 * @tc.desc : [C- SOFTWARE -0200]
396 */
397 HWTEST_F(SendResponseTest, testSendResponse0020, Function | MediumTest | Level2) {
398 DemoApi *demoApi = GetIUnknown("serviceName601", "featureName602");
399 if (demoApi == nullptr) {
400 ADD_FAILURE();
401 }
402 Request request = {.msgId = MSG_RT,
403 .len = 0,
404 .data = nullptr,
405 .msgValue = 0};
406 char *body = (char*)"I wanna async call good result!";
407 request.len = strlen(body) + 1;
408 request.data = malloc(request.len);
409 if (request.data == nullptr) {
410 ADD_FAILURE();
411 }
412 errno_t error = strcpy_s((char *)request.data, request.len, body);
413 if (error != EOK) {
414 ADD_FAILURE();
415 }
416
417 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi("serviceName601", "featureName603");
418 DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
419 demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, nullptr);
420
421 usleep(OPER_INTERVAL * MS2US);
422 ASSERT_EQ(feature->featureStatus == FALSE, TRUE);
423 ReleaseIUnknown(demoApi);
424 }
425
426 /**
427 * @tc.number : DMSLite_SAMGR_SendResponse_0030
428 * @tc.name : Receiver send response to itself successfully
429 * @tc.desc : [C- SOFTWARE -0200]
430 */
431 HWTEST_F(SendResponseTest, testSendResponse0030, Function | MediumTest | Level2) {
432 DemoApi *demoApi = GetIUnknown("serviceName601", "featureName603");
433 if (demoApi == nullptr) {
434 ADD_FAILURE();
435 }
436 Request request = {.msgId = MSG_RT,
437 .len = 0,
438 .data = nullptr,
439 .msgValue = 0};
440 char *body = (char*)"I wanna async call good result!";
441 request.len = strlen(body) + 1;
442 request.data = malloc(request.len);
443 if (request.data == nullptr) {
444 ADD_FAILURE();
445 }
446 errno_t error = strcpy_s((char *)request.data, request.len, body);
447 if (error != EOK) {
448 ADD_FAILURE();
449 }
450
451 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi("serviceName601", "featureName603");
452 DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
453 demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, DemoHandler);
454
455 usleep(OPER_INTERVAL * MS2US);
456 ASSERT_EQ(feature->featureStatus == TRUE, TRUE);
457 ReleaseIUnknown(demoApi);
458 }
459
460 /**
461 * @tc.number : DMSLite_SAMGR_SendResponseByIdentity_0020
462 * @tc.name : Receiver can not forward message if the sender has not registered handler
463 * @tc.desc : [C- SOFTWARE -0200]
464 */
465 HWTEST_F(SendResponseTest, testSendResponseByIdentity0020, Function | MediumTest | Level2) {
466 DemoApi *demoApi = GetIUnknown("serviceName601", "featureName602");
467 if (demoApi == nullptr) {
468 ADD_FAILURE();
469 }
470 Request request = {.msgId = MSG_FW,
471 .len = 0,
472 .data = nullptr,
473 .msgValue = 0};
474 char *body = (char*)"I wanna async call good result!";
475 request.len = strlen(body) + 1;
476 request.data = malloc(request.len);
477 if (request.data == nullptr) {
478 ADD_FAILURE();
479 }
480 errno_t error = strcpy_s((char *)request.data, request.len, body);
481 if (error != EOK) {
482 ADD_FAILURE();
483 }
484
485 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi("serviceName601", "featureName603");
486 DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
487
488 demoApi->SAMGR_SendRequestProxy(&feature->identity, &request, nullptr);
489
490 usleep(OPER_INTERVAL * MS2US);
491 ASSERT_EQ(feature->featureStatus == FALSE, TRUE);
492
493 ReleaseIUnknown(demoApi);
494 }