• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include <cstdlib>
16 #include "init_cmds.h"
17 #include "init_group_manager.h"
18 #include "init_hashmap.h"
19 #include "init_param.h"
20 #include "init_service_manager.h"
21 #include "init_utils.h"
22 #include "init_unittest.h"
23 #include "le_timer.h"
24 #include "param_stub.h"
25 #include "securec.h"
26 #include "control_fd.h"
27 
28 using namespace testing::ext;
29 using namespace std;
30 
31 typedef struct {
32     HashNode node;
33     char name[0];
34 } TestHashNode;
35 
TestHashNodeCompare(const HashNode * node1,const HashNode * node2)36 static int TestHashNodeCompare(const HashNode *node1, const HashNode *node2)
37 {
38     TestHashNode *testNode1 = HASHMAP_ENTRY(node1, TestHashNode, node);
39     TestHashNode *testNode2 = HASHMAP_ENTRY(node2, TestHashNode, node);
40     return strcmp(testNode1->name, testNode2->name);
41 }
42 
TestHashKeyCompare(const HashNode * node1,const void * key)43 static int TestHashKeyCompare(const HashNode *node1, const void *key)
44 {
45     TestHashNode *testNode1 = HASHMAP_ENTRY(node1, TestHashNode, node);
46     return strcmp(testNode1->name, reinterpret_cast<char *>(const_cast<void *>(key)));
47 }
48 
TestHashNodeFunction(const HashNode * node)49 static int TestHashNodeFunction(const HashNode *node)
50 {
51     TestHashNode *testNode = HASHMAP_ENTRY(node, TestHashNode, node);
52     int code = 0;
53     size_t nameLen = strlen(testNode->name);
54     for (size_t i = 0; i < nameLen; i++) {
55         code += testNode->name[i] - 'A';
56     }
57     return code;
58 }
59 
TestHashKeyFunction(const void * key)60 static int TestHashKeyFunction(const void *key)
61 {
62     int code = 0;
63     char *buff = const_cast<char *>(static_cast<const char *>(key));
64     size_t buffLen = strlen(buff);
65     for (size_t i = 0; i < buffLen; i++) {
66         code += buff[i] - 'A';
67     }
68     return code;
69 }
70 
TestHashNodeFree(const HashNode * node,void * context)71 static void TestHashNodeFree(const HashNode *node, void *context)
72 {
73     TestHashNode *testNode = HASHMAP_ENTRY(node, TestHashNode, node);
74     printf("TestHashNodeFree %s\n", testNode->name);
75     free(testNode);
76 }
77 
TestCreateHashNode(const char * value)78 static TestHashNode *TestCreateHashNode(const char *value)
79 {
80     TestHashNode *node = reinterpret_cast<TestHashNode *>(malloc(sizeof(TestHashNode) + strlen(value) + 1));
81     if (node == nullptr) {
82         return nullptr;
83     }
84     int ret = strcpy_s(node->name, strlen(value) + 1, value);
85     if (ret != 0) {
86         free(node);
87         return nullptr;
88     }
89     HASHMAPInitNode(&node->node);
90     return node;
91 }
92 
DoCmdByName(const char * name,const char * cmdContent)93 static void DoCmdByName(const char *name, const char *cmdContent)
94 {
95     int cmdIndex = 0;
96     (void)GetMatchCmd(name, &cmdIndex);
97     DoCmdByIndex(cmdIndex, cmdContent, nullptr);
98 }
99 
100 namespace init_ut {
101 class InitGroupManagerUnitTest : public testing::Test {
102 public:
SetUpTestCase(void)103     static void SetUpTestCase(void) {};
TearDownTestCase(void)104     static void TearDownTestCase(void) {};
SetUp(void)105     void SetUp(void) {};
TearDown(void)106     void TearDown(void) {};
107 };
108 
109 HashInfo g_info = {
110     TestHashNodeCompare,
111     TestHashKeyCompare,
112     TestHashNodeFunction,
113     TestHashKeyFunction,
114     TestHashNodeFree,
115     2
116 };
117 
118 HWTEST_F(InitGroupManagerUnitTest, TestHashMap001, TestSize.Level1)
119 {
120     HashMapHandle handle;
121     OH_HashMapCreate(&handle, &g_info);
122     const char *str1 = "Test hash map node 1";
123     const char *str2 = "Test hash map node 2";
124     const char *str3 = "Test hash map node 3";
125     TestHashNode *node1 = TestCreateHashNode(str1);
126     TestHashNode *node2 = TestCreateHashNode(str2);
127     OH_HashMapAdd(handle, &node1->node);
128     OH_HashMapAdd(handle, &node2->node);
129     HashNode *node = OH_HashMapGet(handle, (const void *)str1);
130     EXPECT_NE(node != nullptr, 0);
131     if (node) {
132         TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
133         EXPECT_EQ(strcmp(tmp->name, str1), 0);
134     }
135     node = OH_HashMapGet(handle, (const void *)str2);
136     EXPECT_NE(node != nullptr, 0);
137     if (node) {
138         TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
139         EXPECT_EQ(strcmp(tmp->name, str2), 0);
140     }
141     TestHashNode *node3 = TestCreateHashNode(str3);
142     OH_HashMapAdd(handle, &node3->node);
143     node3 = TestCreateHashNode("Test hash map node 4");
144     OH_HashMapAdd(handle, &node3->node);
145     node3 = TestCreateHashNode("Test hash map node 5");
146     OH_HashMapAdd(handle, &node3->node);
147     node = OH_HashMapGet(handle, (const void *)str3);
148     EXPECT_NE(node != nullptr, 0);
149     if (node) {
150         TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
151         EXPECT_EQ(strcmp(tmp->name, str3), 0);
152     }
153     OH_HashMapIsEmpty(handle);
__anon7872c9770202(const HashNode *node, const void *context) 154     OH_HashMapTraverse(handle, [](const HashNode *node, const void *context) {return;}, nullptr);
155     OH_HashMapDestory(handle, nullptr);
156 }
157 
158 HWTEST_F(InitGroupManagerUnitTest, TestHashMap002, TestSize.Level1)
159 {
160     HashMapHandle handle;
161     OH_HashMapCreate(&handle, &g_info);
162     TestHashNode *node4 = TestCreateHashNode("pre-init");
163     OH_HashMapAdd(handle, &node4->node);
164     OH_HashMapRemove(handle, "pre-init");
165     TestHashNodeFree(&node4->node, nullptr);
166 
167     const char *act = "load_persist_props_action";
168     TestHashNode *node5 = TestCreateHashNode(act);
169     OH_HashMapAdd(handle, &node5->node);
170     HashNode *node = OH_HashMapGet(handle, (const void *)act);
171     EXPECT_NE(node != nullptr, 0);
172     if (node) {
173         TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
174         EXPECT_EQ(strcmp(tmp->name, act), 0);
175     }
176     OH_HashMapIsEmpty(handle);
__anon7872c9770302(const HashNode *node, const void *context) 177     OH_HashMapTraverse(handle, [](const HashNode *node, const void *context) {return;}, nullptr);
178     OH_HashMapDestory(handle, nullptr);
179 }
180 
181 HWTEST_F(InitGroupManagerUnitTest, TestInitGroupMgrInit, TestSize.Level1)
182 {
183     InitServiceSpace();
184     InitWorkspace *workspace = GetInitWorkspace();
185     EXPECT_EQ(workspace->groupMode, GROUP_BOOT);
186     workspace->groupMode = GROUP_BOOT;
187     if (strcpy_s(workspace->groupModeStr, GROUP_NAME_MAX_LENGTH, "device.boot.group") != EOK) {
188         EXPECT_EQ(1, 0);
189     }
190     // test read cfgfile
191     int ret = InitParseGroupCfg();
192     EXPECT_EQ(ret, 0);
193 }
194 
195 HWTEST_F(InitGroupManagerUnitTest, TestAddService, TestSize.Level1)
196 {
197     const char *serviceStr = "{"
198 	    "\"services\": [{"
199             "\"name\" : \"test-service\","
200             "\"path\" : [\"/dev/test_service\"],"
201             "\"start-mode\" : \"condition\","
202             "\"end-mode\" : \"after-exec\","
203             "\"console\":1,"
204             "\"writepid\":[\"/dev/test_service\"],"
205             "\"jobs\" : {"
206                     "\"on-boot\" : \"boot:bootjob1\","
207                     "\"on-start\" : \"service:startjob\","
208                     "\"on-stop\" : \"service:stopjob\","
209                     "\"on-restart\" : \"service:restartjob\""
210                 "}"
211         "},{"
212             "\"name\" : \"test-service2\","
213             "\"path\" : [\"/dev/test_service\"],"
214             "\"console\":1,"
215             "\"start-mode\" : \"boot\","
216             "\"writepid\":[\"/dev/test_service\"],"
217             "\"jobs\" : {"
218                     "\"on-boot\" : \"boot:bootjob1\","
219                     "\"on-start\" : \"service:startjob\","
220                     "\"on-stop\" : \"service:stopjob\","
221                     "\"on-restart\" : \"service:restartjob\""
222                 "}"
223         "}]"
224     "}";
225 
226     cJSON *fileRoot = cJSON_Parse(serviceStr);
227     ASSERT_NE(nullptr, fileRoot);
228     ConfigContext context = { INIT_CONTEXT_MAIN };
229     ParseAllServices(fileRoot, &context);
230     cJSON_Delete(fileRoot);
231 
232     Service *service = GetServiceByName("test-service");
233     ServiceStartTimer(service, 1);
234     ((TimerTask *)service->timer)->base.handleEvent(LE_GetDefaultLoop(), (LoopBase *)service->timer, Event_Read);
235     ServiceStopTimer(service);
236     ASSERT_NE(service != nullptr, 0);
237     EXPECT_EQ(service->startMode, START_MODE_CONDITION);
238     ReleaseService(service);
239     service = GetServiceByName("test-service2");
240     ASSERT_NE(service != nullptr, 0);
241     EXPECT_EQ(service->startMode, START_MODE_BOOT);
242     ReleaseService(service);
243 }
244 
245 /**
246  * @brief
247  *
248 
249     "socket" : [{
250         "name" : "ueventd",
251         "family" : "AF_INET", // AF_INET,AF_INET6,AF_UNIX(AF_LOCAL),AF_NETLINK
252         "type" : : "SOCK_STREAM", // SOCK_STREAM,SOCK_DGRAM,SOCK_RAW,SOCK_PACKET,SOCK_SEQPACKET
253         "protocol" : "IPPROTO_TCP", // IPPROTO_TCP,IPPTOTO_UDP,IPPROTO_SCTP,PPROTO_TIPC
254         "permissions" : "0660",
255         "uid" : "system",
256         "gid" : "system",
257         "option" : {
258             "passcred" : "true",
259             "rcvbufforce" : "",
260             "cloexec" : "",
261             "nonblock : ""
262         }
263     }],
264  */
265 HWTEST_F(InitGroupManagerUnitTest, TestAddServiceDeny, TestSize.Level1)
266 {
267     const char *serviceStr = "{"
268 	    "\"services\": [{"
269             "\"name\" : \"test-service5\","
270             "\"path\" : [\"/dev/test_service\"],"
271             "\"start-mode\" : \"by-condition\","
272             "\"end-mode\" : \"ready\","
273             "\"console\":1,"
274             "\"writepid\":[\"/dev/test_service\"],"
275             "\"jobs\" : {"
276                     "\"on-boot\" : \"boot:bootjob1\","
277                     "\"on-start\" : \"service:startjob\","
278                     "\"on-stop\" : \"service:stopjob\","
279                     "\"on-restart\" : \"service:restartjob\""
280                 "}"
281         "}]"
282     "}";
283     InitWorkspace *workspace = GetInitWorkspace();
284     workspace->groupMode = GROUP_CHARGE;
285 
286     cJSON *fileRoot = cJSON_Parse(serviceStr);
287     ASSERT_NE(nullptr, fileRoot);
288     ConfigContext context = { INIT_CONTEXT_MAIN };
289     ParseAllServices(fileRoot, &context);
290     cJSON_Delete(fileRoot);
291 
292     Service *service = GetServiceByName("test-service5");
293     ASSERT_EQ(service, nullptr);
294     workspace->groupMode = GROUP_BOOT;
295 }
296 
297 HWTEST_F(InitGroupManagerUnitTest, TestAddService2, TestSize.Level1)
298 {
299     const char *serviceStr = "{"
300 	    "\"services\": [{"
301             "\"name\" : \"test-service6\","
302             "\"path\" : [\"/dev/test_service\"],"
303             "\"console\":1,"
304             "\"writepid\":[\"/dev/test_service\"],"
305             "\"jobs\" : {"
306                     "\"on-boot\" : \"boot:bootjob1\","
307                     "\"on-start\" : \"service:startjob\","
308                     "\"on-stop\" : \"service:stopjob\","
309                     "\"on-restart\" : \"service:restartjob\""
310                 "}"
311         "}]"
312     "}";
313 
314     InitWorkspace *workspace = GetInitWorkspace();
315     workspace->groupMode = GROUP_CHARGE;
316 
317     InitGroupNode *node = AddGroupNode(NODE_TYPE_SERVICES, "test-service6");
318     ASSERT_NE(nullptr, node);
319 
320     cJSON *fileRoot = cJSON_Parse(serviceStr);
321     ASSERT_NE(nullptr, fileRoot);
322     ConfigContext context = { INIT_CONTEXT_MAIN };
323     ParseAllServices(fileRoot, &context);
324     cJSON_Delete(fileRoot);
325     char cmdStr[] = "all#bootevent";
326     char cmdStr1[] = "parameter_service";
327     ProcessControlFd(ACTION_DUMP, "all", nullptr);
328     ProcessControlFd(ACTION_DUMP, cmdStr, nullptr);
329     ProcessControlFd(ACTION_DUMP, cmdStr1, nullptr);
330     ProcessControlFd(ACTION_SANDBOX, cmdStr, nullptr);
331     ProcessControlFd(ACTION_MODULEMGR, cmdStr, nullptr);
332     ProcessControlFd(ACTION_MAX, cmdStr, nullptr);
333     Service *service = GetServiceByName("test-service6");
334     ASSERT_NE(service, nullptr);
335     workspace->groupMode = GROUP_BOOT;
336 }
337 
338 HWTEST_F(InitGroupManagerUnitTest, TestParseServiceCpucore, TestSize.Level1)
339 {
340     const char *jsonStr = "{\"services\":{\"name\":\"test_service22\",\"path\":[\"/data/init_ut/test_service\"],"
341         "\"importance\":-20,\"uid\":\"root\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
342         "\"gid\":[\"root\"], \"cpucore\":[5, 2, 4, 1, 2, 0, 1], \"critical\":[1]}}";
343     cJSON* jobItem = cJSON_Parse(jsonStr);
344     ASSERT_NE(nullptr, jobItem);
345     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
346     ASSERT_NE(nullptr, serviceItem);
347     Service *service = AddService("test_service22");
348     const int invalidImportantValue = 20;
349     SetImportantValue(service, "", invalidImportantValue, 1);
350     if (service != nullptr) {
351         int ret = ParseOneService(serviceItem, service);
352         GetAccessToken();
353         DoCmdByName("timer_start ", "test_service22|5000");
354         DoCmdByName("timer_start ", "test_service22|aa");
355         DoCmdByName("timer_start ", "");
356         EXPECT_EQ(ret, 0);
357         StartServiceByName("test_service22|path");
358         ReleaseService(service);
359     }
360     cJSON_Delete(jobItem);
361 }
362 
363 HWTEST_F(InitGroupManagerUnitTest, TestUpdaterServiceFds, TestSize.Level1)
364 {
365     Service *service = AddService("test_service8");
366     ASSERT_NE(nullptr, service);
367     int fds[1] = { -1 }; // ServiceStop will release fds
368     UpdaterServiceFds(nullptr, nullptr, 0);
369     UpdaterServiceFds(service, fds, 1);
370     UpdaterServiceFds(service, fds, 0);
371     UpdaterServiceFds(service, fds, 1);
372     UpdaterServiceFds(service, nullptr, 1);
373     UpdaterServiceFds(service, fds, 1);
374     int ret = UpdaterServiceFds(service, nullptr, 2); // 2 is fd num
375     ASSERT_NE(ret, 0);
376     service->attribute = SERVICE_ATTR_TIMERSTART;
377     ServiceStartTimer(service, 0);
378 }
379 HWTEST_F(InitGroupManagerUnitTest, TestProcessWatchEvent, TestSize.Level1)
380 {
381     Service *service = AddService("test_service9");
382     ASSERT_NE(nullptr, service);
383     ServiceSocket servercfg = {.next = nullptr, .sockFd = 0};
384     service->socketCfg = &servercfg;
385     ServiceWatcher watcher;
386     int ret = AddSocketWatcher(&watcher, service, 0);
387     ASSERT_EQ(ret, 0);
388     uint32_t event;
389     ((WatcherTask *)watcher)->processEvent((WatcherHandle)watcher, 0, &event, service);
390     service->socketCfg = nullptr;
391 }
392 
393 HWTEST_F(InitGroupManagerUnitTest, TestCheckNodeValid, TestSize.Level1)
394 {
395     int ret = CheckNodeValid(NODE_TYPE_MAX, "charger");
396     EXPECT_EQ(ret, -1);
397     ret = CheckNodeValid(NODE_TYPE_PLUGINS, "charger");
398     EXPECT_EQ(ret, -1);
399 }
400 
401 HWTEST_F(InitGroupManagerUnitTest, TestGetGroupHashMap, TestSize.Level1)
402 {
403     HashMapHandle handle = GetGroupHashMap(NODE_TYPE_GROUPS);
404     EXPECT_TRUE(handle == nullptr);
405 }
406 }  // namespace init_ut
407