• 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)71 static void TestHashNodeFree(const HashNode *node)
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 
93 namespace init_ut {
94 class InitGroupManagerUnitTest : public testing::Test {
95 public:
SetUpTestCase(void)96     static void SetUpTestCase(void) {};
TearDownTestCase(void)97     static void TearDownTestCase(void) {};
SetUp(void)98     void SetUp(void) {};
TearDown(void)99     void TearDown(void) {};
100 };
101 
102 HashInfo g_info = {
103     TestHashNodeCompare,
104     TestHashKeyCompare,
105     TestHashNodeFunction,
106     TestHashKeyFunction,
107     TestHashNodeFree,
108     2
109 };
110 
111 HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1)
112 {
113     HashMapHandle handle;
114     OH_HashMapCreate(&handle, &g_info);
115     const char *str1 = "Test hash map node 1";
116     const char *str2 = "Test hash map node 2";
117     const char *str3 = "Test hash map node 3";
118     TestHashNode *node1 = TestCreateHashNode(str1);
119     TestHashNode *node2 = TestCreateHashNode(str2);
120     OH_HashMapAdd(handle, &node1->node);
121     OH_HashMapAdd(handle, &node2->node);
122     HashNode *node = OH_HashMapGet(handle, (const void *)str1);
123     EXPECT_NE(node != nullptr, 0);
124     if (node) {
125         TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
126         EXPECT_EQ(strcmp(tmp->name, str1), 0);
127     }
128     node = OH_HashMapGet(handle, (const void *)str2);
129     EXPECT_NE(node != nullptr, 0);
130     if (node) {
131         TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
132         EXPECT_EQ(strcmp(tmp->name, str2), 0);
133     }
134     TestHashNode *node3 = TestCreateHashNode(str3);
135     OH_HashMapAdd(handle, &node3->node);
136     node3 = TestCreateHashNode("Test hash map node 4");
137     OH_HashMapAdd(handle, &node3->node);
138     node3 = TestCreateHashNode("Test hash map node 5");
139     OH_HashMapAdd(handle, &node3->node);
140     node = OH_HashMapGet(handle, (const void *)str3);
141     EXPECT_NE(node != nullptr, 0);
142     if (node) {
143         TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
144         EXPECT_EQ(strcmp(tmp->name, str3), 0);
145     }
146     TestHashNode *node4 = TestCreateHashNode("pre-init");
147     OH_HashMapAdd(handle, &node4->node);
148 
149     const char *act = "load_persist_props_action";
150     TestHashNode *node5 = TestCreateHashNode(act);
151     OH_HashMapAdd(handle, &node5->node);
152     OH_HashMapRemove(handle, "pre-init");
153     node = OH_HashMapGet(handle, (const void *)act);
154     EXPECT_NE(node != nullptr, 0);
155     if (node) {
156         TestHashNode *tmp = HASHMAP_ENTRY(node, TestHashNode, node);
157         EXPECT_EQ(strcmp(tmp->name, act), 0);
158     }
159     OH_HashMapIsEmpty(handle);
__anonf82052960202(const HashNode *node, const void *context) 160     OH_HashMapTraverse(handle, [](const HashNode *node, const void *context) {return;}, nullptr);
161     OH_HashMapDestory(handle);
162 }
163 
164 HWTEST_F(InitGroupManagerUnitTest, TestInitGroupMgrInit, TestSize.Level1)
165 {
166     InitServiceSpace();
167     InitWorkspace *workspace = GetInitWorkspace();
168     EXPECT_EQ(workspace->groupMode, GROUP_CHARGE);
169     workspace->groupMode = GROUP_BOOT;
170     if (strcpy_s(workspace->groupModeStr, GROUP_NAME_MAX_LENGTH, "device.boot.group") != EOK) {
171         EXPECT_EQ(1, 0);
172     } // test read cfgfile
173     int ret = InitParseGroupCfg();
174     EXPECT_EQ(ret, 0);
175 }
176 
177 HWTEST_F(InitGroupManagerUnitTest, TestAddService, TestSize.Level1)
178 {
179     const char *serviceStr = "{"
180 	    "\"services\": [{"
181             "\"name\" : \"test-service\","
182             "\"path\" : [\"/dev/test_service\"],"
183             "\"start-mode\" : \"condition\","
184             "\"end-mode\" : \"after-exec\","
185             "\"console\":1,"
186             "\"writepid\":[\"/dev/test_service\"],"
187             "\"jobs\" : {"
188                     "\"on-boot\" : \"boot:bootjob1\","
189                     "\"on-start\" : \"service:startjob\","
190                     "\"on-stop\" : \"service:stopjob\","
191                     "\"on-restart\" : \"service:restartjob\""
192                 "}"
193         "},{"
194             "\"name\" : \"test-service2\","
195             "\"path\" : [\"/dev/test_service\"],"
196             "\"console\":1,"
197             "\"start-mode\" : \"boot\","
198             "\"writepid\":[\"/dev/test_service\"],"
199             "\"jobs\" : {"
200                     "\"on-boot\" : \"boot:bootjob1\","
201                     "\"on-start\" : \"service:startjob\","
202                     "\"on-stop\" : \"service:stopjob\","
203                     "\"on-restart\" : \"service:restartjob\""
204                 "}"
205         "}]"
206     "}";
207 
208     cJSON *fileRoot = cJSON_Parse(serviceStr);
209     ASSERT_NE(nullptr, fileRoot);
210     ParseAllServices(fileRoot);
211     cJSON_Delete(fileRoot);
212 
213     Service *service = GetServiceByName("test-service");
214     ServiceStartTimer(service, 1);
215     ((TimerTask *)service->timer)->base.handleEvent(LE_GetDefaultLoop(), (LoopBase *)service->timer, Event_Read);
216     ServiceStopTimer(service);
217     ASSERT_NE(service != nullptr, 0);
218     EXPECT_EQ(service->startMode, START_MODE_CONDITION);
219     ReleaseService(service);
220     service = GetServiceByName("test-service2");
221     ASSERT_NE(service != nullptr, 0);
222     EXPECT_EQ(service->startMode, START_MODE_BOOT);
223     ReleaseService(service);
224 }
225 
226 /**
227  * @brief
228  *
229 
230     "socket" : [{
231         "name" : "ueventd",
232         "family" : "AF_INET", // AF_INET,AF_INET6,AF_UNIX(AF_LOCAL),AF_NETLINK
233         "type" : : "SOCK_STREAM", // SOCK_STREAM,SOCK_DGRAM,SOCK_RAW,SOCK_PACKET,SOCK_SEQPACKET
234         "protocol" : "IPPROTO_TCP", // IPPROTO_TCP,IPPTOTO_UDP,IPPROTO_SCTP,PPROTO_TIPC
235         "permissions" : "0660",
236         "uid" : "system",
237         "gid" : "system",
238         "option" : {
239             "passcred" : "true",
240             "rcvbufforce" : "",
241             "cloexec" : "",
242             "nonblock : ""
243         }
244     }],
245  */
246 HWTEST_F(InitGroupManagerUnitTest, TestAddServiceDeny, TestSize.Level1)
247 {
248     const char *serviceStr = "{"
249 	    "\"services\": [{"
250             "\"name\" : \"test-service5\","
251             "\"path\" : [\"/dev/test_service\"],"
252             "\"start-mode\" : \"by-condition\","
253             "\"end-mode\" : \"ready\","
254             "\"console\":1,"
255             "\"writepid\":[\"/dev/test_service\"],"
256             "\"jobs\" : {"
257                     "\"on-boot\" : \"boot:bootjob1\","
258                     "\"on-start\" : \"service:startjob\","
259                     "\"on-stop\" : \"service:stopjob\","
260                     "\"on-restart\" : \"service:restartjob\""
261                 "}"
262         "}]"
263     "}";
264     InitWorkspace *workspace = GetInitWorkspace();
265     workspace->groupMode = GROUP_CHARGE;
266 
267     cJSON *fileRoot = cJSON_Parse(serviceStr);
268     ASSERT_NE(nullptr, fileRoot);
269     ParseAllServices(fileRoot);
270     cJSON_Delete(fileRoot);
271 
272     Service *service = GetServiceByName("test-service5");
273     ASSERT_EQ(service, nullptr);
274     workspace->groupMode = GROUP_BOOT;
275 }
276 
277 HWTEST_F(InitGroupManagerUnitTest, TestAddService2, TestSize.Level1)
278 {
279     const char *serviceStr = "{"
280 	    "\"services\": [{"
281             "\"name\" : \"test-service6\","
282             "\"path\" : [\"/dev/test_service\"],"
283             "\"console\":1,"
284             "\"writepid\":[\"/dev/test_service\"],"
285             "\"jobs\" : {"
286                     "\"on-boot\" : \"boot:bootjob1\","
287                     "\"on-start\" : \"service:startjob\","
288                     "\"on-stop\" : \"service:stopjob\","
289                     "\"on-restart\" : \"service:restartjob\""
290                 "}"
291         "}]"
292     "}";
293 
294     InitWorkspace *workspace = GetInitWorkspace();
295     workspace->groupMode = GROUP_CHARGE;
296 
297     InitGroupNode *node = AddGroupNode(NODE_TYPE_SERVICES, "test-service6");
298     ASSERT_NE(nullptr, node);
299 
300     cJSON *fileRoot = cJSON_Parse(serviceStr);
301     ASSERT_NE(nullptr, fileRoot);
302     ParseAllServices(fileRoot);
303     cJSON_Delete(fileRoot);
304     char cmdStr[] = "all#bootevent";
305     char cmdStr1[] = "parameter_service";
306     ProcessControlFd(ACTION_DUMP, "all", NULL);
307     ProcessControlFd(ACTION_DUMP, cmdStr, NULL);
308     ProcessControlFd(ACTION_DUMP, cmdStr1, NULL);
309     ProcessControlFd(ACTION_SANDBOX, cmdStr, NULL);
310     ProcessControlFd(ACTION_MODULEMGR, cmdStr, NULL);
311     ProcessControlFd(ACTION_MAX, cmdStr, NULL);
312     Service *service = GetServiceByName("test-service6");
313     ASSERT_NE(service, nullptr);
314     workspace->groupMode = GROUP_BOOT;
315 }
316 
317 HWTEST_F(InitGroupManagerUnitTest, TestParseServiceCpucore, TestSize.Level1)
318 {
319     const char *jsonStr = "{\"services\":{\"name\":\"test_service22\",\"path\":[\"/data/init_ut/test_service\"],"
320         "\"importance\":-20,\"uid\":\"root\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
321         "\"gid\":[\"root\"], \"cpucore\":[5, 2, 4, 1, 2, 0, 1], \"critical\":[1]}}";
322     cJSON* jobItem = cJSON_Parse(jsonStr);
323     ASSERT_NE(nullptr, jobItem);
324     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
325     ASSERT_NE(nullptr, serviceItem);
326     Service *service = AddService("test_service22");
327     const int invalidImportantValue = 20;
328     SetImportantValue(service, "", invalidImportantValue, 1);
329     if (service != nullptr) {
330         int ret = ParseOneService(serviceItem, service);
331         GetAccessToken();
332         DoCmdByName("timer_start ", "test_service22|5000");
333         DoCmdByName("timer_start ", "test_service22|aa");
334         DoCmdByName("timer_start ", "");
335         EXPECT_EQ(ret, 0);
336         StartServiceByName("test_service22|path");
337         ReleaseService(service);
338     }
339     cJSON_Delete(jobItem);
340 }
341 HWTEST_F(InitGroupManagerUnitTest, TestNodeFree, TestSize.Level1)
342 {
343     DoCmdByName("stopAllServices ", "");
344 }
345 HWTEST_F(InitGroupManagerUnitTest, TestUpdaterServiceFds, TestSize.Level1)
346 {
347     Service *service = AddService("test_service8");
348     ASSERT_NE(nullptr, service);
349     int *fds = (int *)malloc(sizeof(int) * 1); // ServiceStop will release fds
350     UpdaterServiceFds(nullptr, nullptr, 0);
351     UpdaterServiceFds(service, fds, 1);
352     UpdaterServiceFds(service, fds, 0);
353     UpdaterServiceFds(service, fds, 1);
354     UpdaterServiceFds(service, nullptr, 1);
355     UpdaterServiceFds(service, fds, 1);
356     int ret = UpdaterServiceFds(service, nullptr, 2); // 2 is fd num
357     ASSERT_NE(ret, 0);
358     service->attribute = SERVICE_ATTR_TIMERSTART;
359     ServiceStartTimer(service, 0);
360 }
361 HWTEST_F(InitGroupManagerUnitTest, TestProcessWatchEvent, TestSize.Level1)
362 {
363     Service *service = AddService("test_service9");
364     ASSERT_NE(nullptr, service);
365     ServiceSocket servercfg = {.next = nullptr, .sockFd = 0};
366     service->socketCfg = &servercfg;
367     ServiceWatcher watcher;
368     int ret = SocketAddWatcher(&watcher, service, 0);
369     ASSERT_EQ(ret, 0);
370     uint32_t event;
371     ((WatcherTask *)watcher)->processEvent((WatcherHandle)watcher, 0, &event, service);
372 }
373 }  // namespace init_ut
374