• 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 
16 #include <sys/socket.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <cstdlib>
20 #include "init.h"
21 #include "init_cmds.h"
22 #include "init_service.h"
23 #include "init_service_manager.h"
24 #include "init_service_socket.h"
25 #include "param_stub.h"
26 #include "init_utils.h"
27 #include "securec.h"
28 #include "init_group_manager.h"
29 #include "trigger_manager.h"
30 #include "bootstage.h"
31 #include "init_hook.h"
32 #include "plugin_adapter.h"
33 
34 const char *SERVICE_INFO_JSONSTR = "{"
35     "\"services\":{"
36     "   \"name\":\"test_service\","
37     "   \"path\":[\"/data/init_ut/test_service\"],"
38     "   \"importance\":-20,"
39     "   \"uid\":\"system\","
40     "   \"writepid\":[\"/dev/test_service\"],"
41     "   \"console\":1,"
42     "   \"caps\":[\"TEST_ERR\"],"
43     "   \"gid\":[\"system\"],"
44     "   \"period\":2,"
45     "   \"env\":[{ "
46     "      \"name\":\"test\","
47     "      \"value\":\"xxxx\""
48     "    }],"
49     "   \"critical\":1,"
50     "   \"jobs\" : {"
51     "       \"pre-start\":\"test_service:pre-start\""
52     "   }"
53     "}"
54 "}";
55 const char *JOB_INFO_JSONSTR = "{"
56     "\"jobs\": ["
57     "   {"
58     "       \"name\" : \"test_service:pre-start\","
59     "       \"cmds\" : ["
60     "           \"setparam test.test.prestartKey 1\""
61     "       ]"
62     "   }"
63     "]"
64 "}";
65 const char *PRE_START_KEY = "test.test.prestartKey";
DoCmdByName(const char * name,const char * cmdContent)66 static void DoCmdByName(const char *name, const char *cmdContent)
67 {
68     int cmdIndex = 0;
69     (void)GetMatchCmd(name, &cmdIndex);
70     DoCmdByIndex(cmdIndex, cmdContent, nullptr);
71 }
72 
LoadJobs()73 static void LoadJobs()
74 {
75     cJSON *jobJson = cJSON_Parse(JOB_INFO_JSONSTR);
76     INIT_ERROR_CHECK(jobJson != NULL, return, "Failed to loadJobs");
77     ParseTriggerConfig(jobJson, nullptr, nullptr);
78     cJSON_Delete(jobJson);
79 }
80 
ServiceTestTriggerExe(const TriggerNode * trigger,const char * content,uint32_t size)81 static int ServiceTestTriggerExe(const TriggerNode *trigger, const char *content, uint32_t size)
82 {
83     INIT_ERROR_CHECK(trigger != NULL, return -1, "ParamWriteTriggerExe trigger is NULL");
84     CommandNode *cmd = GetNextCmdNode((JobNode *)trigger, NULL);
85     while (cmd != NULL) {
86         DoCmdByIndex(cmd->cmdKeyIndex, cmd->content, &cmd->cfgContext);
87         cmd = GetNextCmdNode((JobNode *)trigger, cmd);
88     }
89     return 0;
90 }
91 
92 using namespace testing::ext;
93 using namespace std;
94 
95 extern "C" {
96     INIT_STATIC int GetCgroupPath(Service *service, char *buffer, uint32_t buffLen);
97 }
98 
99 namespace init_ut {
100 class ServiceUnitTest : public testing::Test {
101 public:
SetUpTestCase(void)102     static void SetUpTestCase(void)
103     {
104         string svcPath = "/data/init_ut/test_service";
105         auto fp = std::unique_ptr<FILE, decltype(&fclose)>(fopen(svcPath.c_str(), "wb"), fclose);
106         if (fp == nullptr) {
107             cout << "ServiceUnitTest open : " << svcPath << " failed." << errno << endl;
108         }
109         sync();
110     }
111 
TearDownTestCase(void)112     static void TearDownTestCase(void) {};
SetUp()113     void SetUp() {};
TearDown()114     void TearDown() {};
115 };
116 
117 HWTEST_F(ServiceUnitTest, case01, TestSize.Level1)
118 {
119     cJSON* jobItem = cJSON_Parse(SERVICE_INFO_JSONSTR);
120     ASSERT_NE(nullptr, jobItem);
121     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
122     ASSERT_NE(nullptr, serviceItem);
123     Service *service = AddService("test_service");
124     int ret = ParseOneService(serviceItem, service);
125     EXPECT_EQ(ret, 0);
126 
127     LoadJobs();
128     RegisterTriggerExec(TRIGGER_UNKNOW, ServiceTestTriggerExe);
129 
130     ret = ServiceStart(service, &service->pathArgs);
131     EXPECT_EQ(ret, 0);
132 
133     char value[PARAM_VALUE_LEN_MAX] = {0};
134     u_int32_t len = sizeof(value);
135     ret = SystemGetParameter(PRE_START_KEY, value, &len);
136     EXPECT_EQ(ret, 0);
137     EXPECT_EQ(0, strcmp("1", value));
138 
139     ret = ServiceStop(service);
140     EXPECT_EQ(ret, 0);
141 
142     ReleaseService(service);
143     cJSON_Delete(jobItem);
144 }
145 
146 HWTEST_F(ServiceUnitTest, case02, TestSize.Level1)
147 {
148     const char *jsonStr = "{\"services\":{\"name\":\"test_service8\",\"path\":[\"/data/init_ut/test_service\"],"
149         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
150         "\"gid\":[\"system\", \"shell\", \"root\"],\"caps\":[10, 4294967295, 10000],\"cpucore\":[1]}}";
151     cJSON* jobItem = cJSON_Parse(jsonStr);
152     ASSERT_NE(nullptr, jobItem);
153     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
154     ASSERT_NE(nullptr, serviceItem);
155     Service *service = AddService("test_service8");
156     ASSERT_NE(nullptr, service);
157     int ret = ParseOneService(serviceItem, service);
158     EXPECT_EQ(ret, 0);
159 
160     int fds[1] = {-1}; // ServiceStop will release fds
161     UpdaterServiceFds(service, fds, 1);
162     service->attribute = SERVICE_ATTR_ONDEMAND;
163     ret = ServiceStart(service, &service->pathArgs);
164     EXPECT_EQ(ret, 0);
165     CmdLines *cmdline = (CmdLines *)malloc(sizeof(CmdLines) + sizeof(CmdLine));
166     ASSERT_NE(nullptr, cmdline);
167     cmdline->cmdNum = 1;
168     cmdline->cmds[0].cmdIndex = 0;
169     service->restartArg = cmdline;
170     ServiceSocket tmpSock = { .next = nullptr, .sockFd = 0 };
171     ServiceSocket tmpSock1 = { .next = &tmpSock, .sockFd = 0 };
172     service->socketCfg = &tmpSock1;
173     ServiceReap(service);
174     service->socketCfg = nullptr;
175     service->attribute &= SERVICE_ATTR_NEED_RESTART;
176     service->firstCrashTime = 0;
177     ServiceReap(service);
178     DoCmdByName("reset ", "test_service8");
179     // reset again
180     DoCmdByName("reset ", "test_service8");
181     service->pid = 0xfffffff; // 0xfffffff is not exist pid
182     service->attribute = SERVICE_ATTR_TIMERSTART;
183     ret = ServiceStop(service);
184     EXPECT_EQ(ret, 0);
185     ReleaseService(service);
186     cJSON_Delete(jobItem);
187 }
188 
189 HWTEST_F(ServiceUnitTest, TestServiceStartAbnormal, TestSize.Level1)
190 {
191     const char *jsonStr = "{\"services\":{\"name\":\"test_service1\",\"path\":[\"/data/init_ut/test_service\"],"
192         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
193         "\"gid\":[\"system\"],\"caps\":[\"\"]}}";
194     cJSON* jobItem = cJSON_Parse(jsonStr);
195     ASSERT_NE(nullptr, jobItem);
196     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
197     ASSERT_NE(nullptr, serviceItem);
198     Service *service = AddService("test_service1");
199     ASSERT_NE(nullptr, service);
200     int ret = ParseOneService(serviceItem, service);
201     EXPECT_EQ(ret, 0);
202 
203     ret = ServiceStart(service, &service->pathArgs);
204     EXPECT_EQ(ret, 0);
205 
206     service->attribute &= SERVICE_ATTR_INVALID;
207     ret = ServiceStart(service, &service->pathArgs);
208     EXPECT_EQ(ret, 0);
209 
210     service->pid = -1;
211     ret = ServiceStop(service);
212     EXPECT_EQ(ret, 0);
213     ReleaseService(service);
214     cJSON_Delete(jobItem);
215 }
216 
217 HWTEST_F(ServiceUnitTest, TestServiceReap, TestSize.Level1)
218 {
219     Service *service = AddService("test_service2");
220     ASSERT_NE(nullptr, service);
221     EXPECT_EQ(service->attribute, 0);
222     service->attribute = SERVICE_ATTR_ONDEMAND;
223     ServiceReap(service);
224     service->attribute = 0;
225 
226     service->restartArg = (CmdLines *)calloc(1, sizeof(CmdLines));
227     ASSERT_NE(nullptr, service->restartArg);
228     ServiceReap(service);
229     EXPECT_EQ(service->attribute, SERVICE_ATTR_TIMERSTART);
230 
231     const int crashCount = 241;
232     service->crashCnt = crashCount;
233     ServiceReap(service);
234     EXPECT_EQ(service->attribute, SERVICE_ATTR_TIMERSTART);
235 
236     service->attribute |= SERVICE_ATTR_ONCE;
237     ServiceReap(service);
238     EXPECT_EQ(service->attribute, (SERVICE_ATTR_ONCE | SERVICE_ATTR_TIMERSTART));
239     service->attribute = SERVICE_ATTR_CRITICAL;
240     service->crashCount = 1;
241     ServiceReap(service);
242     ReleaseService(service);
243 }
244 
245 HWTEST_F(ServiceUnitTest, TestServiceReapOther, TestSize.Level1)
246 {
247     const char *serviceStr = "{\"services\":{\"name\":\"test_service4\",\"path\":[\"/data/init_ut/test_service\"],"
248         "\"onrestart\":[\"sleep 1\"],\"console\":1,\"writepid\":[\"/dev/test_service\"]}}";
249 
250     cJSON* jobItem = cJSON_Parse(serviceStr);
251     ASSERT_NE(nullptr, jobItem);
252     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
253     ASSERT_NE(nullptr, serviceItem);
254     Service *service = AddService("test_service4");
255     ASSERT_NE(nullptr, service);
256     int ret = ParseOneService(serviceItem, service);
257     EXPECT_EQ(ret, 0);
258 
259     ServiceReap(service);
260     EXPECT_NE(service->attribute, 0);
261 
262     service->attribute |= SERVICE_ATTR_CRITICAL;
263     ServiceReap(service);
264     EXPECT_NE(service->attribute, 0);
265 
266     service->attribute |= SERVICE_ATTR_NEED_STOP;
267     ServiceReap(service);
268     EXPECT_NE(service->attribute, 0);
269 
270     service->attribute |= SERVICE_ATTR_INVALID;
271     ServiceReap(service);
272     EXPECT_NE(service->attribute, 0);
273 
274     ret = ServiceStop(service);
275     EXPECT_EQ(ret, 0);
276     ReleaseService(service);
277     cJSON_Delete(jobItem);
278 }
279 
280 HWTEST_F(ServiceUnitTest, TestServiceManagerRelease, TestSize.Level1)
281 {
282     Service *service = nullptr;
283     ReleaseService(service);
284     EXPECT_TRUE(service == nullptr);
285     service = AddService("test_service5");
286     ASSERT_NE(nullptr, service);
287     service->pathArgs.argv = (char **)malloc(sizeof(char *));
288     ASSERT_NE(nullptr, service->pathArgs.argv);
289     service->pathArgs.count = 1;
290     const char *path = "/data/init_ut/test_service_release";
291     service->pathArgs.argv[0] = strdup(path);
292 
293     service->writePidArgs.argv = (char **)malloc(sizeof(char *));
294     ASSERT_NE(nullptr, service->writePidArgs.argv);
295     service->writePidArgs.count = 1;
296     service->writePidArgs.argv[0] = strdup(path);
297 
298     service->servPerm.caps = (unsigned int *)malloc(sizeof(unsigned int));
299     ASSERT_NE(nullptr, service->servPerm.caps);
300     service->servPerm.gIDArray = (gid_t *)malloc(sizeof(gid_t));
301     ASSERT_NE(nullptr, service->servPerm.gIDArray);
302     service->socketCfg = (ServiceSocket *)malloc(sizeof(ServiceSocket));
303     ASSERT_NE(nullptr, service->socketCfg);
304     service->socketCfg->sockFd = 0;
305     service->socketCfg->next = nullptr;
306     service->fileCfg = (ServiceFile *)malloc(sizeof(ServiceFile));
307     ASSERT_NE(nullptr, service->fileCfg);
308     service->fileCfg->fd = 0;
309     service->fileCfg->next = nullptr;
310     service->env = (ServiceEnv*)malloc(sizeof(ServiceEnv));
311     ASSERT_NE(nullptr, service->env);
312     int ret = strcpy_s(service->env->name, MAX_ENV_NAME, "test5");
313     EXPECT_EQ(ret, EOK);
314     ret = strcpy_s(service->env->value, MAX_ENV_VALUE, "xxxxx");
315     EXPECT_EQ(ret, EOK);
316     ReleaseService(service);
317     service = nullptr;
318 }
319 
320 HWTEST_F(ServiceUnitTest, TestServiceManagerGetService, TestSize.Level1)
321 {
322     Service *service = GetServiceByPid(1);
323     StopAllServices(1, nullptr, 0, nullptr);
324     EXPECT_TRUE(service == nullptr);
325     const char *jsonStr = "{\"services\":{\"name\":\"test_service2\",\"path\":[\"/data/init_ut/test_service\"],"
326         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
327         "\"gid\":[\"system\"], \"critical\":[1,2]}}";
328     cJSON* jobItem = cJSON_Parse(jsonStr);
329     ASSERT_NE(nullptr, jobItem);
330     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
331     ASSERT_NE(nullptr, serviceItem);
332     service = AddService("test_service2");
333     ASSERT_NE(nullptr, service);
334     int ret = ParseOneService(serviceItem, service);
335     EXPECT_NE(ret, 0);
336     cJSON_Delete(jobItem);
337     const char *jsonStr1 = "{\"services\":{\"name\":\"test_service3\",\"path\":[\"/data/init_ut/test_service\"],"
338         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
339         "\"gid\":[\"system\"], \"critical\":[\"on\"]}}";
340     jobItem = cJSON_Parse(jsonStr1);
341     ASSERT_NE(nullptr, jobItem);
342     serviceItem = cJSON_GetObjectItem(jobItem, "services");
343     ASSERT_NE(nullptr, serviceItem);
344     service = AddService("test_service3");
345     ASSERT_NE(nullptr, service);
346     ret = ParseOneService(serviceItem, service);
347     EXPECT_NE(ret, 0);
348     cJSON_Delete(jobItem);
349 }
350 
351 /**
352 * @tc.name: TestServiceBootEventHook
353 * @tc.desc: test bootevent module exec correct
354 * @tc.type: FUNC
355 * @tc.require: issueI5NTX4
356 * @tc.author:
357 */
358 HWTEST_F(ServiceUnitTest, TestServiceBootEventHook, TestSize.Level1)
359 {
360     const char *serviceStr = "{"
361 	    "\"services\": [{"
362             "\"name\" : \"test-service\","
363             "\"path\" : [\"/dev/test_service\"],"
364             "\"start-mode\" : \"condition\","
365             "\"writepid\":[\"/dev/test_service\"],"
366             "\"bootevents\" : \"bootevent2\""
367         "},{"
368             "\"name\" : \"test-service\","
369             "\"path\" : [\"/dev/test_service\"],"
370             "\"start-mode\" : \"condition\","
371             "\"writepid\":[\"/dev/test_service\"],"
372             "\"bootevents\" : \"bootevent.bootevent2\""
373         "},{"
374             "\"name\" : \"test-service2\","
375             "\"path\" : [\"/dev/test_service\"],"
376             "\"console\":1,"
377             "\"start-mode\" : \"boot\","
378             "\"writepid\":[\"/dev/test_service\"],"
379             "\"bootevents\" : [\"bootevent.bootevent1\", \"bootevent.bootevent2\"]"
380         "}]"
381     "}";
382 
383     SERVICE_INFO_CTX serviceInfoContext;
384     serviceInfoContext.serviceName = "test-service2";
385     serviceInfoContext.reserved = "bootevent";
386     HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
387     (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&serviceInfoContext), nullptr);
388     cJSON *fileRoot = cJSON_Parse(serviceStr);
389     ASSERT_NE(nullptr, fileRoot);
390     ConfigContext context = { INIT_CONTEXT_MAIN };
391     ParseAllServices(fileRoot, &context);
392     (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), nullptr);
393     serviceInfoContext.reserved = nullptr;
394     (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), nullptr);
395     const char *initBootevent[] = {"init", "test"};
396     PluginExecCmd("bootevent", ARRAY_LENGTH(initBootevent), initBootevent);
397     const char *initBooteventDup[] = {"init", "test"};
398     PluginExecCmd("bootevent", ARRAY_LENGTH(initBooteventDup), initBooteventDup);
399     const char *initBooteventErr[] = {"init"};
400     PluginExecCmd("bootevent", ARRAY_LENGTH(initBooteventErr), initBooteventErr);
401     SystemWriteParam("bootevent.bootevent1", "true");
402     SystemWriteParam("bootevent.bootevent2", "true");
403     SystemWriteParam("bootevent.bootevent2", "true");
404     SystemWriteParam("persist.init.bootevent.enable", "false");
405     HookMgrExecute(GetBootStageHookMgr(), INIT_POST_PERSIST_PARAM_LOAD, nullptr, nullptr);
406     cJSON_Delete(fileRoot);
407 }
408 
409 HWTEST_F(ServiceUnitTest, TestSetServiceContent, TestSize.Level1)
410 {
411     int ret = WatchConsoleDevice(nullptr);
412     EXPECT_EQ(ret, -1);
413     Service service;
414     (void)WatchConsoleDevice(&service);
415     int fd = open("/dev/console", O_RDWR);
416     if (fd >= 0) {
417         (void)write(fd, "0", 1);
418         (void)close(fd);
419     }
420     PluginExecCmdByName("setServiceContent", "netmanager");
421     StopServiceByName("netmanager");
422 }
423 
424 HWTEST_F(ServiceUnitTest, TestServiceExec, TestSize.Level1)
425 {
426     Service *service = AddService("test_service7");
427     ASSERT_NE(nullptr, service);
428 
429     service->pathArgs.argv = (char **)malloc(sizeof(char *));
430     ASSERT_NE(service->pathArgs.argv, nullptr);
431     service->pathArgs.count = 1;
432     const char *path = "/data/init_ut/test_service_release";
433     service->pathArgs.argv[0] = strdup(path);
434     service->importance = 20;
435     service->servPerm.gIDCnt = -1;
436     service->servPerm.uID = 0;
437     unsigned int *caps = (unsigned int *)calloc(1, sizeof(unsigned int) * 1);
438     ASSERT_NE(nullptr, caps);
439     caps[0] = FULL_CAP;
440     service->servPerm.caps = caps;
441     service->servPerm.capsCnt = 1;
442     IsEnableSandbox();
443     EnterServiceSandbox(service);
444     int ret = ServiceExec(service, &service->pathArgs);
445     EXPECT_EQ(ret, 0);
446 
447     const int invalidImportantValue = 20;
448     ret = SetImportantValue(service, "", invalidImportantValue, 1);
449     EXPECT_EQ(ret, -1);
450     ReleaseService(service);
451 }
452 
453 HWTEST_F(ServiceUnitTest, TestServiceCGroup1, TestSize.Level1)
454 {
455     const char *jsonStr = "{\"services\":{\"name\":\"test_service1\",\"path\":[\"/data/init_ut/test_service\"],"
456         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
457         "\"gid\":[\"system\"],\"caps\":[\"\"]}}";
458     cJSON* jobItem = cJSON_Parse(jsonStr);
459     ASSERT_NE(nullptr, jobItem);
460     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
461     ASSERT_NE(nullptr, serviceItem);
462     const char serviceName[] = "test_service1";
463     Service *service = AddService(serviceName);
464     ASSERT_NE(nullptr, service);
465     int ret = ParseOneService(serviceItem, service);
466     EXPECT_EQ(service->isCgroupEnabled, false);
467     EXPECT_EQ(ret, 0);
468 
469     char path[PATH_MAX] = {};
470     ret = GetCgroupPath(service, path, sizeof(path));
471     ASSERT_EQ(ret, 0);
472     ReleaseService(service);
473     cJSON_Delete(jobItem);
474 }
475 
476 HWTEST_F(ServiceUnitTest, TestServiceCGroup2, TestSize.Level1)
477 {
478     const char *jsonStr = "{\"services\":{\"name\":\"test_service1\",\"path\":[\"/data/init_ut/test_service\"],"
479     "\"importance\":-20,\"uid\":\"system\",\"cgroup\":true,\"writepid\":[\"/dev/test_service\"],\"console\":1,"
480     "\"gid\":[\"system\"],\"caps\":[\"\"]}}";
481     cJSON* jobItem = cJSON_Parse(jsonStr);
482     ASSERT_NE(nullptr, jobItem);
483     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
484     ASSERT_NE(nullptr, serviceItem);
485     const char serviceName[] = "test_service1";
486     Service *service = AddService(serviceName);
487     ASSERT_NE(nullptr, service);
488     int ret = ParseOneService(serviceItem, service);
489     EXPECT_EQ(service->isCgroupEnabled, true);
490     EXPECT_EQ(ret, 0);
491 
492     ret = ServiceStart(service, &service->pathArgs);
493     EXPECT_EQ(ret, 0);
494 
495     char path[PATH_MAX] = {};
496     ret = GetCgroupPath(service, path, sizeof(path));
497     ASSERT_EQ(ret, 0);
498     ret = strcat_s(path, sizeof(path), "cgroup.procs");
499     EXPECT_EQ(ret, 0);
500 
501     FILE *file = nullptr;
502     file = fopen(path, "r");
503     ASSERT_NE(file, nullptr);
504     pid_t pid = 0;
505     ret = -1;
506     while (fscanf_s(file, "%d\n", &pid) == 1 && pid > 0) {
507         if (pid == service->pid) {
508             ret = 0;
509             break;
510         }
511     }
512     fclose(file);
513     ret = ServiceStop(service);
514     EXPECT_EQ(ret, 0);
515     ReleaseService(service);
516     cJSON_Delete(jobItem);
517 }
518 
519 HWTEST_F(ServiceUnitTest, TestKernelPermAllRight, TestSize.Level1)
520 {
521     const char *jsonStr = "{\"services\":{\"name\":\"test_service1\",\"path\":[\"/system/bin/sa_main\"],"
522         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
523         "\"gid\":[\"system\"],\"caps\":[\"\"],\"kernel_permission\":{\"ohos.filesystem.dfs\":345,"
524         "\"ohos.permission.kernel.ALLOW_WRITABLE_CODE_MEMORY\":true}}}";
525     const char *kernelPermStr = "{\"encaps\":{\"ohos.encaps.count\":2,\"ohos.filesystem.dfs\":345,"
526                             "\"ohos.permission.kernel.ALLOW_WRITABLE_CODE_MEMORY\":true}}";
527     cJSON* jobItem = cJSON_Parse(jsonStr);
528     ASSERT_NE(nullptr, jobItem);
529     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
530     ASSERT_NE(nullptr, serviceItem);
531     const char serviceName[] = "test_service1";
532     Service *service = AddService(serviceName);
533     ASSERT_NE(nullptr, service);
534     int ret = ParseOneService(serviceItem, service);
535     EXPECT_EQ(ret, 0);
536     ret = strcmp(service->kernelPerms, kernelPermStr);
537     EXPECT_EQ(ret, 0);
538 
539     SERVICE_INFO_CTX context;
540     context.serviceName = service->name;
541     context.reserved = (const char*)service->pathArgs.argv[0];
542     HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
543     (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_SET_PERMS_BEFORE, (void *)(&context), NULL);
544 
545     ReleaseService(service);
546     cJSON_Delete(jobItem);
547 }
548 
549 HWTEST_F(ServiceUnitTest, TestKernelPermValueNotSupport, TestSize.Level1)
550 {
551     const char *jsonStr = "{\"services\":{\"name\":\"test_service1\",\"path\":[\"/system/bin/sa_main\"],"
552         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
553         "\"gid\":[\"system\"],\"caps\":[\"\"],\"kernel_permission\":{\"ohos.filesystem.dfs\":[345,678],"
554         "\"ohos.permission.kernel.ALLOW_WRITABLE_CODE_MEMORY\":true}}}";
555 
556     cJSON* jobItem = cJSON_Parse(jsonStr);
557     ASSERT_NE(nullptr, jobItem);
558     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
559     ASSERT_NE(nullptr, serviceItem);
560     const char serviceName[] = "test_service1";
561     Service *service = AddService(serviceName);
562     ASSERT_NE(nullptr, service);
563     int ret = ParseOneService(serviceItem, service);
564     EXPECT_EQ(ret, 0);
565     EXPECT_TRUE(service->kernelPerms == nullptr);
566 
567     SERVICE_INFO_CTX context;
568     context.serviceName = service->name;
569     context.reserved = (const char*)service->pathArgs.argv[0];
570     HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
571     (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_SET_PERMS_BEFORE, (void *)(&context), NULL);
572 
573     ReleaseService(service);
574     cJSON_Delete(jobItem);
575 }
576 
577 HWTEST_F(ServiceUnitTest, TestKernelPermNotSa, TestSize.Level1)
578 {
579     const char *jsonStr = "{\"services\":{\"name\":\"test_service1\",\"path\":[\"/system/bin\"],"
580         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
581         "\"gid\":[\"system\"],\"caps\":[\"\"],\"kernel_permission\":{\"ohos.filesystem.dfs\":[345,678],"
582         "\"ohos.permission.kernel.ALLOW_WRITABLE_CODE_MEMORY\":true}}}";
583 
584     cJSON* jobItem = cJSON_Parse(jsonStr);
585     ASSERT_NE(nullptr, jobItem);
586     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
587     ASSERT_NE(nullptr, serviceItem);
588     const char serviceName[] = "test_service1";
589     Service *service = AddService(serviceName);
590     ASSERT_NE(nullptr, service);
591     int ret = ParseOneService(serviceItem, service);
592     EXPECT_EQ(ret, 0);
593     EXPECT_TRUE(service->kernelPerms == nullptr);
594 
595     SERVICE_INFO_CTX context;
596     context.serviceName = service->name;
597     context.reserved = (const char*)service->pathArgs.argv[0];
598     HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
599     (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_SET_PERMS_BEFORE, (void *)(&context), NULL);
600 
601     ReleaseService(service);
602     cJSON_Delete(jobItem);
603 }
604 
605 HWTEST_F(ServiceUnitTest, TestKernelPermPermissionError, TestSize.Level1)
606 {
607     const char *jsonStr = "{\"services\":{\"name\":\"test_service1\",\"path\":[\"/system/bin/sa_main\"],"
608         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
609         "\"gid\":[\"system\"],\"caps\":[\"\"],\"kernel_permission\":{\"ohos.filesystem.dfsxxx\":1,"
610         "\"ohos.permission.kernel.ALLOW_WRITABLE_CODE_MEMORY\":true}}}";
611 
612     cJSON* jobItem = cJSON_Parse(jsonStr);
613     ASSERT_NE(nullptr, jobItem);
614     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
615     ASSERT_NE(nullptr, serviceItem);
616     const char serviceName[] = "test_service1";
617     Service *service = AddService(serviceName);
618     ASSERT_NE(nullptr, service);
619     int ret = ParseOneService(serviceItem, service);
620     EXPECT_EQ(ret, 0);
621 
622     SERVICE_INFO_CTX context;
623     context.serviceName = service->name;
624     context.reserved = (const char*)service->pathArgs.argv[0];
625     HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
626     (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_SET_PERMS_BEFORE, (void *)(&context), NULL);
627 
628     ReleaseService(service);
629     cJSON_Delete(jobItem);
630 }
631 
632 HWTEST_F(ServiceUnitTest, TestKernelPermServiceNameError, TestSize.Level1)
633 {
634     const char *jsonStr = "{\"services\":{\"name\":\"test_service1\",\"path\":[\"/system/bin/sa_main\"],"
635         "\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
636         "\"gid\":[\"system\"],\"caps\":[\"\"],\"kernel_permission\":{\"ohos.filesystem.dfs\":1,"
637         "\"ohos.permission.kernel.ALLOW_WRITABLE_CODE_MEMORY\":true}}}";
638 
639     cJSON* jobItem = cJSON_Parse(jsonStr);
640     ASSERT_NE(nullptr, jobItem);
641     cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
642     ASSERT_NE(nullptr, serviceItem);
643     const char serviceName[] = "test_service1";
644     Service *service = AddService(serviceName);
645     ASSERT_NE(nullptr, service);
646     int ret = ParseOneService(serviceItem, service);
647     EXPECT_EQ(ret, 0);
648 
649     SERVICE_INFO_CTX context;
650     context.serviceName = "wrongServiceName";
651     context.reserved = (const char*)service->pathArgs.argv[0];
652     HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
653     (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_SET_PERMS_BEFORE, (void *)(&context), NULL);
654 
655     ReleaseService(service);
656     cJSON_Delete(jobItem);
657 }
658 } // namespace init_ut
659