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