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