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 const int TARGET_NUM = 2;
22 
23 using namespace testing::ext;
24 
25 static const char *GetName(Service *service);
26 static BOOL Initialize(Service *service, Identity identity);
27 static BOOL MessageHandle(Service *service, Request *msg);
28 static TaskConfig GetTaskConfig(Service *service);
29 
30 static pthread_t g_servicePoint1;
31 static pthread_t g_servicePoint2;
32 
33 struct DemoApi {
34     INHERIT_IUNKNOWN;
35     bool(*FeatureApi001)(IUnknown *iUnknown, const char *para1);
36     int32 (*SendRequestProxyF)(const Identity *identity, const Request *request, Handler handler);
37 };
38 
39 struct DemoFeature {
40     INHERIT_FEATURE;
41     INHERIT_IUNKNOWNENTRY(DemoApi);
42     Identity identity;
43     int featureCalledCount;
44 };
45 
46 struct DefaultFeatureApi {
47     INHERIT_IUNKNOWN;
48     BOOL(*DefaultApi001)
49     (IUnknown *iUnknown, char *para1);
50     int32 (*SendRequestProxyDF)(const Identity *identity, const Request *request, Handler handler);
51 };
52 
53 struct DemoService {
54     INHERIT_SERVICE;
55     INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
56     Identity identity;
57     int serviceCalledCount;
58 };
59 
DefaultApi001(IUnknown *iUnknown, char *para1)60 static BOOL DefaultApi001(IUnknown *iUnknown, char *para1)
61 {
62     (void)iUnknown;
63     return TRUE;
64 }
SendRequestProxyDF(const Identity *identity, const Request *request, Handler handler)65 static int32 SendRequestProxyDF(const Identity *identity, const Request *request, Handler handler)
66 {
67     return SAMGR_SendRequest(identity, request, handler);
68 }
69 
FeatureApi001(IUnknown *iUnknown, const char *para1)70 static bool FeatureApi001(IUnknown *iUnknown, const char *para1)
71 {
72     (void)iUnknown;
73     return TRUE;
74 }
SendRequestProxyF(const Identity *identity, const Request *request, Handler handler)75 static int32 SendRequestProxyF(const Identity *identity, const Request *request, Handler handler)
76 {
77     return SAMGR_SendRequest(identity, request, handler);
78 }
79 
80 static DemoService g_createService[] = {
81     {
82         .GetName = GetName,
83         .Initialize = Initialize,
84         .MessageHandle = MessageHandle,
85         .GetTaskConfig = GetTaskConfig,
86         .ver = 0x20,
87         .ref = 1,
88         .iUnknown = {
89             DEFAULT_IUNKNOWN_IMPL,
90             .DefaultApi001 = DefaultApi001,
91             .SendRequestProxyDF = SendRequestProxyDF,
92         },
93         .identity = {-1, -1, nullptr},
94         .serviceCalledCount = 0,
95     },
96     {
97         .GetName = GetName,
98         .Initialize = Initialize,
99         .MessageHandle = MessageHandle,
100         .GetTaskConfig = GetTaskConfig,
101         .ver = 0x20,
102         .ref = 1,
103         .iUnknown = {
104             DEFAULT_IUNKNOWN_IMPL,
105             .DefaultApi001 = DefaultApi001,
106             .SendRequestProxyDF = SendRequestProxyDF,
107         },
108         .identity = {-1, -1, nullptr},
109         .serviceCalledCount = 0,
110     }
111 };
112 
GetName(Service *service)113 static const char *GetName(Service *service)
114 {
115     if (service == (Service *)&g_createService[0]) {
116         return "SpecifiedT01";
117     } else {
118         return "SpecifiedT02";
119     }
120 }
121 
Initialize(Service *service, Identity identity)122 static BOOL Initialize(Service *service, Identity identity)
123 {
124     DemoService *demoService = (DemoService *)service;
125     demoService->identity = identity;
126 
127     return TRUE;
128 }
129 
MessageHandle(Service *service, Request *msg)130 static BOOL MessageHandle(Service *service, Request *msg)
131 {
132     DemoService *demoService = (DemoService *)service;
133     demoService->serviceCalledCount++;
134 
135     if (service == (Service *)&g_createService[0]) {
136         g_servicePoint1 = pthread_self();
137     } else {
138         g_servicePoint2 = pthread_self();
139     }
140 
141     return TRUE;
142 }
143 
GetTaskConfig(Service *service)144 static TaskConfig GetTaskConfig(Service *service)
145 {
146     TaskConfig config = {LEVEL_HIGH, PRI_NORMAL, 1600, 20, SPECIFIED_TASK};
147     return config;
148 }
149 
FEATURE_GetName(Feature *feature)150 static const char *FEATURE_GetName(Feature *feature)
151 {
152     (void)feature;
153     return "featureName501";
154 }
155 
FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)156 static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
157 {
158     DemoFeature *demoFeature = (DemoFeature *)feature;
159     demoFeature->identity = identity;
160 }
161 
FEATURE_OnStop(Feature *feature, Identity identity)162 static void FEATURE_OnStop(Feature *feature, Identity identity)
163 {
164     (void)feature;
165     (void)identity;
166 }
167 
FEATURE_OnMessage(Feature *feature, Request *request)168 static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
169 {
170     DemoFeature *demoFeature = (DemoFeature *)feature;
171     demoFeature->featureCalledCount++;
172 
173     return TRUE;
174 }
175 
176 static DemoFeature g_createFeature = {
177     .GetName = FEATURE_GetName,
178     .OnInitialize = FEATURE_OnInitialize,
179     .OnStop = FEATURE_OnStop,
180     .OnMessage = FEATURE_OnMessage,
181     .ver = 0x20,
182     .ref = 1,
183     .iUnknown = {
184         DEFAULT_IUNKNOWN_IMPL,
185         .FeatureApi001 = FeatureApi001,
186         .SendRequestProxyF = SendRequestProxyF,
187     },
188     .identity = {-1, -1, nullptr},
189     .featureCalledCount = 0,
190 };
191 
GServiceInit(void)192 static void GServiceInit(void)
193 {
194     for (int i = 0; i < TARGET_NUM; i++) {
195         SAMGR_GetInstance()->RegisterService((Service *)&g_createService[i]);
196     }
197 }
198 SYS_SERVICE_INIT(GServiceInit);
199 
GFeatureInit(void)200 static void GFeatureInit(void)
201 {
202     for (int i = 0; i < TARGET_NUM; i++) {
203         SAMGR_GetInstance()->RegisterDefaultFeatureApi(g_createService[i].GetName((Service *)&g_createService[i]),
204                                                        GET_IUNKNOWN(g_createService[i]));
205 
206         SAMGR_GetInstance()->RegisterFeature(g_createService[i].GetName((Service *)&g_createService[i]),
207                                              (Feature *)&g_createFeature);
208         SAMGR_GetInstance()->RegisterFeatureApi(g_createService[i].GetName((Service *)&g_createService[i]),
209                                                 "featureName501", GET_IUNKNOWN(g_createFeature));
210     }
211 }
212 SYS_FEATURE_INIT(GFeatureInit);
213 
GetIUnknown(const char *serviceName, const char *featureName)214 static DemoApi *GetIUnknown(const char *serviceName, const char *featureName)
215 {
216     DemoApi *demoApi = nullptr;
217     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(serviceName, featureName);
218     if (iUnknown == nullptr) {
219         return nullptr;
220     }
221     int result = iUnknown->QueryInterface(iUnknown, 0x20, (void **)&demoApi);
222     if (result == 0 && demoApi != nullptr) {
223         return demoApi;
224     } else {
225         return nullptr;
226     }
227 }
228 
GetDefaultIUnknown(const char *serviceName)229 static DefaultFeatureApi *GetDefaultIUnknown(const char *serviceName)
230 {
231     DefaultFeatureApi *defaultApi = nullptr;
232     IUnknown *iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(serviceName);
233     if (iUnknown == nullptr) {
234         return nullptr;
235     }
236     int result = iUnknown->QueryInterface(iUnknown, 0x20, (void **)&defaultApi);
237     if (result == 0 && defaultApi != nullptr) {
238         return defaultApi;
239     } else {
240         return nullptr;
241     }
242 }
243 
244 class TaskpoolSpecifiedTaskTest : public testing::Test {
245 protected:
246     // SetUpTestCase: Testsuit setup, run before 1st testcase
SetUpTestCase(void)247     static void SetUpTestCase(void)
248     {
249         printf("[hcpptest]SetUpTestCase ! \n");
250         SystemInitProxy();
251     }
252     // TearDownTestCase: Testsuit teardown, run after last testcase
TearDownTestCase(void)253     static void TearDownTestCase(void)
254     {
255     }
256     // Testcase setup
SetUp()257     virtual void SetUp()
258     {
259         usleep(OPER_INTERVAL * MS2US);
260     }
261     // Testcase teardown
TearDown()262     virtual void TearDown()
263     {
264     }
265 };
266 
267 /**
268  * @tc.number    : DMSLite_SAMGR_Taskpool_SpecifiedTask_0010
269  * @tc.name      : Service share taskpool by the same level, the first task function is ok
270  * @tc.desc      : [C- SOFTWARE -0200]
271 */
HWTEST_F(TaskpoolSpecifiedTaskTest, testSpecifiedTask0010, Function | MediumTest | Level2)272 HWTEST_F(TaskpoolSpecifiedTaskTest, testSpecifiedTask0010, Function | MediumTest | Level2)
273 {
274     DemoApi *demoApi = GetIUnknown("SpecifiedT01", "featureName501");
275     if (demoApi == nullptr) {
276         ADD_FAILURE();
277     }
278     bool result = demoApi->FeatureApi001((IUnknown *)demoApi, (char*)"xxxx");
279     ASSERT_EQ(result, TRUE);
280 
281     g_createFeature.featureCalledCount = 0;
282     Request request = {.msgId = 0, .len = 0, .data = nullptr, .msgValue = 0};
283     char *body = (char*)"I wanna async call good result!";
284     request.len = (uint32_t)(strlen(body) + 1);
285     request.data = malloc(request.len);
286     if (request.data == nullptr) {
287         ADD_FAILURE();
288     }
289     errno_t error = strcpy_s((char *)request.data, request.len, body);
290     if (error != EOK) {
291         ADD_FAILURE();
292     }
293     int32 result2 = demoApi->SendRequestProxyF(&(g_createFeature.identity), &request, nullptr);
294     ASSERT_EQ(result2 == 0, TRUE);
295     usleep(OPER_INTERVAL * MS2US);
296     ASSERT_EQ(g_createFeature.featureCalledCount == 1, TRUE);
297 
298     DefaultFeatureApi *defaultApi = GetDefaultIUnknown("SpecifiedT01");
299     if (defaultApi == nullptr) {
300         ADD_FAILURE();
301     }
302     result = defaultApi->DefaultApi001((IUnknown *)defaultApi, (char*)"yyyy");
303     ASSERT_EQ(result, TRUE);
304 
305     g_createService[0].serviceCalledCount = 0;
306     Request request2 = {.msgId = 0, .len = 0, .data = nullptr, .msgValue = 0};
307     char *body2 = (char*)"I want to call defaultFeature!";
308     request2.len = (uint32_t)(strlen(body2) + 1);
309     request2.data = malloc(request2.len);
310     if (request2.data == nullptr) {
311         ADD_FAILURE();
312     }
313     error = strcpy_s((char *)request2.data, request2.len, body2);
314     if (error != EOK) {
315         ADD_FAILURE();
316     }
317     result2 = defaultApi->SendRequestProxyDF(&(g_createService[0].identity), &request2, nullptr);
318     ASSERT_EQ(result2 == 0, TRUE);
319     usleep(OPER_INTERVAL * MS2US);
320     ASSERT_EQ(g_createService[0].serviceCalledCount == 1, TRUE);
321 };
322 
323 /**
324  * @tc.number    : DMSLite_SAMGR_Taskpool_SpecifiedTask_0020
325  * @tc.name      : Service share taskpool by the same level, the second task function is ok
326  * @tc.desc      : [C- SOFTWARE -0200]
327 */
HWTEST_F(TaskpoolSpecifiedTaskTest, testSpecifiedTask0020, Function | MediumTest | Level2)328 HWTEST_F(TaskpoolSpecifiedTaskTest, testSpecifiedTask0020, Function | MediumTest | Level2)
329 {
330     DemoApi *demoApi = GetIUnknown("SpecifiedT02", "featureName501");
331     if (demoApi == nullptr) {
332         ADD_FAILURE();
333     }
334     bool result = demoApi->FeatureApi001((IUnknown *)demoApi, (char*)"xxxx");
335     ASSERT_EQ(result, TRUE);
336 
337     g_createFeature.featureCalledCount = 0;
338     Request request = {.msgId = 0, .len = 0, .data = nullptr, .msgValue = 0};
339     char *body = (char*)"I wanna async call good result!";
340     request.len = (uint32_t)(strlen(body) + 1);
341     request.data = malloc(request.len);
342     if (request.data == nullptr) {
343         ADD_FAILURE();
344     }
345     errno_t error = strcpy_s((char *)request.data, request.len, body);
346     if (error != EOK) {
347         ADD_FAILURE();
348     }
349     int32 result2 = demoApi->SendRequestProxyF(&(g_createFeature.identity), &request, nullptr);
350     ASSERT_EQ(result2 == 0, TRUE);
351     usleep(OPER_INTERVAL * MS2US);
352     ASSERT_EQ(g_createFeature.featureCalledCount == 1, TRUE);
353 
354     DefaultFeatureApi *defaultApi = GetDefaultIUnknown("SpecifiedT02");
355     if (defaultApi == nullptr) {
356         ADD_FAILURE();
357     }
358     result = defaultApi->DefaultApi001((IUnknown *)defaultApi, (char*)"yyyy");
359     ASSERT_EQ(result, TRUE);
360 
361     g_createService[0].serviceCalledCount = 0;
362     Request request2 = {.msgId = 0, .len = 0, .data = nullptr, .msgValue = 0};
363     char *body2 = (char*)"I want to call defaultFeature!";
364     request2.len = (uint32_t)(strlen(body2) + 1);
365     request2.data = malloc(request2.len);
366     if (request2.data == nullptr) {
367         ADD_FAILURE();
368     }
369     error = strcpy_s((char *)request2.data, request2.len, body2);
370     if (error != EOK) {
371         ADD_FAILURE();
372     }
373     result2 = defaultApi->SendRequestProxyDF(&(g_createService[0].identity), &request2, nullptr);
374     ASSERT_EQ(result2 == 0, TRUE);
375     usleep(OPER_INTERVAL * MS2US);
376     ASSERT_EQ(g_createService[0].serviceCalledCount == 1, TRUE);
377 };
378 
379 /**
380  * @tc.number    : DMSLite_SAMGR_Taskpool_SpecifiedTask_0030
381  * @tc.name      : Service share taskpool by the same level, the thread id is the same
382  * @tc.desc      : [C- SOFTWARE -0200]
383 */
HWTEST_F(TaskpoolSpecifiedTaskTest, testSpecifiedTask0030, Function | MediumTest | Level2)384 HWTEST_F(TaskpoolSpecifiedTaskTest, testSpecifiedTask0030, Function | MediumTest | Level2)
385 {
386     DefaultFeatureApi *defaultApi = GetDefaultIUnknown("SpecifiedT01");
387     if (defaultApi == nullptr) {
388         ADD_FAILURE();
389     }
390     Request request = {.msgId = 0, .len = 0, .data = nullptr, .msgValue = 0};
391     char *body = (char*)"I want to call defaultFeature!";
392     request.len = (uint32_t)(strlen(body) + 1);
393     request.data = malloc(request.len);
394     if (request.data == nullptr) {
395         ADD_FAILURE();
396     }
397     errno_t error = strcpy_s((char *)request.data, request.len, body);
398     if (error != EOK) {
399         ADD_FAILURE();
400     }
401     defaultApi->SendRequestProxyDF(&(g_createService[0].identity), &request, nullptr);
402 
403     DefaultFeatureApi *defaultApi2 = GetDefaultIUnknown("SpecifiedT01");
404     if (defaultApi2 == nullptr) {
405         ADD_FAILURE();
406     }
407     Request request2 = {.msgId = 0, .len = 0, .data = nullptr, .msgValue = 0};
408     char *body2 = (char*)"I want to call defaultFeature!";
409     request2.len = (uint32_t)(strlen(body2) + 1);
410     request2.data = malloc(request2.len);
411     if (request2.data == nullptr) {
412         ADD_FAILURE();
413     }
414     error = strcpy_s((char *)request2.data, request2.len, body2);
415     if (error != EOK) {
416         ADD_FAILURE();
417     }
418     defaultApi2->SendRequestProxyDF(&(g_createService[1].identity), &request2, nullptr);
419 
420     usleep(OPER_INTERVAL * MS2US);
421     ASSERT_EQ(g_servicePoint1 == g_servicePoint2, TRUE);
422 };