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/statvfs.h>
17 #include "init_cmds.h"
18 #include "init_param.h"
19 #include "init_group_manager.h"
20 #include "param_stub.h"
21 #include "init_utils.h"
22 #include "trigger_manager.h"
23 
24 using namespace testing::ext;
25 using namespace std;
26 
DoCmdByName(const char * name,const char * cmdContent)27 static void DoCmdByName(const char *name, const char *cmdContent)
28 {
29     int cmdIndex = 0;
30     (void)GetMatchCmd(name, &cmdIndex);
31     DoCmdByIndex(cmdIndex, cmdContent, nullptr);
32 }
33 
34 namespace init_ut {
35 class CmdsUnitTest : public testing::Test {
36 public:
SetUpTestCase(void)37     static void SetUpTestCase(void) {};
TearDownTestCase(void)38     static void TearDownTestCase(void) {};
SetUp()39     void SetUp() {};
TearDown()40     void TearDown() {};
41 };
42 
43 HWTEST_F(CmdsUnitTest, TestCmdExecByName1, TestSize.Level1)
44 {
45     DoCmdByName("timer_start ", "media_service|5000");
46     DoCmdByName("timer_start ", "|5000");
47     DoCmdByName("timer_stop ", "media_service");
48     DoCmdByName("exec ", "media_service");
49     DoCmdByName("syncexec ", "/system/bin/toybox");
50     DoCmdByName("load_access_token_id ", "media_service");
51     DoCmdByName("load_access_token_id ", "");
52     DoCmdByName("stopAllServices ", "false");
53     DoCmdByName("stopAllServices ", "true");
54     DoCmdByName("umount ", "/2222222");
55     DoCmdByName("mount ", "/2222222");
56     DoCmdByName("mount ", "ext4 /2222222 /data wait filecrypt=555");
57     DoCmdByName("umount ", "/2222222");
58     DoCmdByName("init_global_key ", "/data");
59     DoCmdByName("init_global_key ", "arg0 arg1");
60     DoCmdByName("init_main_user ", "testUser");
61     DoCmdByName("init_main_user ", nullptr);
62     DoCmdByName("mkswap ", "/data/init_ut");
63     DoCmdByName("swapon ", "/data/init_ut");
64     DoCmdByName("sync ", "");
65     DoCmdByName("restorecon ", "");
66     DoCmdByName("restorecon ", "/data  /data");
67     DoCmdByName("suspend ", "");
68     DoCmdByName("wait ", "1");
69     DoCmdByName("wait ", "aaa 1");
70     DoCmdByName("mksandbox", "/sandbox");
71     DoCmdByName("mount_fstab ", "/2222222");
72     DoCmdByName("umount_fstab ", "/2222222");
73     DoCmdByName("mknode  ", "node1 node1 node1 node1 node1");
74     DoCmdByName("makedev ", "/device1 device2");
75     DoCmdByName("symlink ", "/xxx/xxx/xxx1 /xxx/xxx/xxx2");
76     DoCmdByName("load_param ", "aaa onlyadd");
77     DoCmdByName("load_persist_params ", "");
78     DoCmdByName("load_param ", "");
79     DoCmdByName("setparam ", "bbb 0");
80     DoCmdByName("ifup ", "aaa, bbb");
81     DoCmdByName("insmod ", "a b");
82     DoCmdByName("insmod ", "/data /data");
83 }
84 
85 HWTEST_F(CmdsUnitTest, TestCommonMkdir, TestSize.Level1)
86 {
__anon799520280102(const char *mkdirFile, const char *cmdLine) 87     auto checkMkdirCmd = [=](const char *mkdirFile, const char *cmdLine) {
88         DoCmdByName("mkdir ", cmdLine);
89         return access(mkdirFile, F_OK);
90     };
91     EXPECT_EQ(checkMkdirCmd("/data/init_ut/test_dir0", "/data/init_ut/test_dir0"), 0);
92     EXPECT_EQ(checkMkdirCmd("/data/init_ut/test_dir1", "/data/init_ut/test_dir1 0755"), 0);
93     EXPECT_EQ(checkMkdirCmd("/data/init_ut/test_dir2", "/data/init_ut/test_dir2 0755 system system"), 0);
94 
95     // abnormal
96     EXPECT_NE(checkMkdirCmd("/data/init_ut/test_dir3", ""), 0);
97     EXPECT_NE(checkMkdirCmd("/data/init_ut/test_dir4", "/data/init_ut/test_dir4 0755 system"), 0);
98     EXPECT_EQ(checkMkdirCmd("/data/init_ut/test_dir5", "/data/init_ut/test_dir5 0755 error error"), 0);
99 }
100 
101 HWTEST_F(CmdsUnitTest, TestCommonChown, TestSize.Level1)
102 {
103     const char *testFile = "/data/init_ut/test_dir0";
104     DoCmdByName("chown ", "system system /data/init_ut/test_dir0");
105     struct stat info = {};
106     stat(testFile, &info);
107     const unsigned int systemUidGid = 1000;
108     EXPECT_EQ(info.st_uid, systemUidGid);
109     EXPECT_EQ(info.st_gid, systemUidGid);
110 
111     // abnormal
112     DoCmdByName("chown ", "error error /data/init_ut/test_dir0");
113     stat(testFile, &info);
114     EXPECT_EQ(info.st_uid, systemUidGid);
115     EXPECT_EQ(info.st_gid, systemUidGid);
116 }
117 
118 HWTEST_F(CmdsUnitTest, TestCommonChmod, TestSize.Level1)
119 {
120     const char *testFile = "/data/init_ut/test_dir0/test_file0";
121     const mode_t testMode = S_IRWXU | S_IRWXG | S_IRWXO;
122     int fd = open(testFile, O_CREAT | O_WRONLY, testMode);
123     ASSERT_GE(fd, 0);
124     DoCmdByName("chmod ", "777 /data/init_ut/test_dir0/test_file0");
125     struct stat info;
126     stat(testFile, &info);
127     EXPECT_EQ(testMode, testMode & info.st_mode);
128 
129     // abnormal
130     DoCmdByName("chmod ", "999 /data/init_ut/test_dir0/test_file0");
131     stat(testFile, &info);
132     EXPECT_EQ(testMode, testMode & info.st_mode);
133     DoCmdByName("chmod ", "777 /data/init_ut/test_dir0/test_file001");
134 
135     close(fd);
136 }
137 
138 HWTEST_F(CmdsUnitTest, TestCommonCopy, TestSize.Level1)
139 {
140     const char *testFile1 = "/data/init_ut/test_dir0/test_file_copy1";
141     DoCmdByName("copy ", "/data/init_ut/test_dir0/test_file0 /data/init_ut/test_dir0/test_file_copy1");
142     int fd = open(testFile1, O_RDWR);
143     ASSERT_GE(fd, 0);
144     write(fd, "aaa", strlen("aaa"));
145 
146     const char *testFile2 = "/data/init_ut/test_dir0/test_file_copy2";
147     DoCmdByName("copy ", "/data/init_ut/test_dir0/test_file_copy1 /data/init_ut/test_dir0/test_file_copy2");
148     int ret = access(testFile2, F_OK);
149     EXPECT_EQ(ret, 0);
150     close(fd);
151     // abnormal
152     DoCmdByName("copy ", "/data/init_ut/test_dir0/test_file_copy1 /data/init_ut/test_dir0/test_file_copy1");
153     DoCmdByName("copy ", "/data/init_ut/test_dir0/test_file_copy11 /data/init_ut/test_dir0/test_file_copy1");
154     DoCmdByName("copy ", "a");
155 
156     DoCmdByName("chmod ", "111 /data/init_ut/test_dir0/test_file_copy1");
157     DoCmdByName("copy ", "/data/init_ut/test_dir0/test_file_copy1 /data/init_ut/test_dir0/test_file_copy2");
158 
159     DoCmdByName("chmod ", "777 /data/init_ut/test_dir0/test_file_copy1");
160     DoCmdByName("chmod ", "111 /data/init_ut/test_dir0/test_file_copy2");
161     DoCmdByName("copy ", "/data/init_ut/test_dir0/test_file_copy1 /data/init_ut/test_dir0/test_file_copy2");
162     DoCmdByName("chmod ", "777 /data/init_ut/test_dir0/test_file_copy2");
163 }
164 
165 HWTEST_F(CmdsUnitTest, TestCommonWrite, TestSize.Level1)
166 {
167     const char *testFile1 = "/data/init_ut/test_dir0/test_file_write1";
168     int fd = open(testFile1, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
169     ASSERT_GE(fd, 0);
170 
171     DoCmdByName("write ", "/data/init_ut/test_dir0/test_file_write1 aaa");
172     const int bufLen = 50;
173     char buffer[bufLen];
174     int length = read(fd, buffer, bufLen - 1);
175     EXPECT_EQ(length, strlen("aaa"));
176     close(fd);
177     // abnormal
178     DoCmdByName("write ", "/data/init_ut/test_dir0/test_file_write2 aaa 2");
179 }
180 
181 HWTEST_F(CmdsUnitTest, TestCommonRm, TestSize.Level1)
182 {
183     const char *testFile1 = "/data/init_ut/test_dir0/test_file_write1";
184     DoCmdByName("rm ", testFile1);
185     int ret = access(testFile1, F_OK);
186     EXPECT_NE(ret, 0);
187 
188     testFile1 = "/data/init_ut/test_dir1";
189     DoCmdByName("rmdir ", testFile1);
190     ret = access(testFile1, F_OK);
191     EXPECT_NE(ret, 0);
192 
193     // abnormal
194     DoCmdByName("rmdir ", testFile1);
195 }
196 
197 HWTEST_F(CmdsUnitTest, TestCommonExport, TestSize.Level1)
198 {
199     DoCmdByName("export ", "TEST_INIT 1");
200     EXPECT_STREQ("1", getenv("TEST_INIT"));
201     unsetenv("TEST_INIT");
202     EXPECT_STRNE("1", getenv("TEST_INIT"));
203 }
204 
205 HWTEST_F(CmdsUnitTest, TestCommonMount, TestSize.Level1)
206 {
207     DoCmdByName("mount ", "ext4 /dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor "
208         "/vendor wait rdonly barrier=1");
209     struct statvfs64 vfs {};
210     int ret = statvfs64("/vendor", &vfs);
211     EXPECT_GE(ret, 0);
212     EXPECT_GT(vfs.f_bsize, 0);
213 }
214 
215 HWTEST_F(CmdsUnitTest, TestGetCmdKey, TestSize.Level1)
216 {
217     const char *cmd1 = GetCmdKey(0);
218     EXPECT_STREQ(cmd1, "start ");
219 }
220 
221 HWTEST_F(CmdsUnitTest, TestDoCmdByIndex, TestSize.Level1)
222 {
223     DoCmdByIndex(1, "/data/init_ut/test_cmd_dir0", nullptr);
224     int ret = access("/data/init_ut/test_cmd_dir0", F_OK);
225     EXPECT_EQ(ret, 0);
226 
227     const int execPos = 17;
228     DoCmdByIndex(execPos, "sleep 1", nullptr);
229     DoCmdByIndex(23, "test", nullptr); // 23 is cmd index
230 }
231 
232 HWTEST_F(CmdsUnitTest, TestGetCmdLinesFromJson, TestSize.Level1)
233 {
234     const char *jsonStr = "{\"jobs\":[{\"name\":\"init\",\"cmds\":[\"sleep 1\",100,\"test321 123\"]}]}";
235     cJSON* jobItem = cJSON_Parse(jsonStr);
236     ASSERT_NE(nullptr, jobItem);
237     cJSON *cmdsItem = cJSON_GetObjectItem(jobItem, "jobs");
238     ASSERT_NE(nullptr, cmdsItem);
239     ASSERT_TRUE(cJSON_IsArray(cmdsItem));
240 
241     cJSON *cmdsItem1 = cJSON_GetArrayItem(cmdsItem, 0);
242     ASSERT_NE(nullptr, cmdsItem1);
243     CmdLines **cmdLines = (CmdLines **)calloc(1, sizeof(CmdLines *));
244     ASSERT_NE(nullptr, cmdLines);
245     int ret = GetCmdLinesFromJson(cmdsItem1, cmdLines);
246     EXPECT_EQ(ret, -1);
247     cJSON *cmdsItem2 = cJSON_GetObjectItem(cmdsItem1, "cmds");
248     ASSERT_NE(nullptr, cmdsItem2);
249     ret = GetCmdLinesFromJson(cmdsItem2, cmdLines);
250     EXPECT_EQ(ret, 0);
251 
252     cJSON_Delete(jobItem);
253     if (cmdLines[0] != nullptr) {
254         free(cmdLines[0]);
255         cmdLines[0] = nullptr;
256     }
257     free(cmdLines);
258     cmdLines = nullptr;
259 }
260 
261 HWTEST_F(CmdsUnitTest, TestInitCmdFunc, TestSize.Level1)
262 {
263     int ret = GetBootModeFromMisc();
264     EXPECT_EQ(ret, 0);
265     ret = SetFileCryptPolicy(nullptr);
266     EXPECT_NE(ret, 0);
267 }
268 
269 HWTEST_F(CmdsUnitTest, TestBuildStringFromCmdArg, TestSize.Level1)
270 {
271     int strNum = 3;
272     struct CmdArgs *ctx = (struct CmdArgs *)calloc(1, sizeof(struct CmdArgs) + sizeof(char *) * (strNum));
273     ctx->argc = strNum;
274     ctx->argv[0] = strdup("123456789012345678901234567890123456789012345678901234567890   \
275             1234567890123456789012345678901234567890123456789012345678901234567");
276     ctx->argv[1] = strdup("test");
277     ctx->argv[2] = nullptr;
278     char *options = BuildStringFromCmdArg(ctx, 0);
279     EXPECT_EQ(options[0], '\0');
280     free(options);
281 
282     options = BuildStringFromCmdArg(ctx, 1);
283     EXPECT_STREQ(options, "test");
284     free(options);
285     FreeCmdArg(ctx);
286 }
287 
288 HWTEST_F(CmdsUnitTest, TestInitDiffTime, TestSize.Level1)
289 {
290     INIT_TIMING_STAT stat;
291     stat.startTime.tv_sec = 2; // 2 is test sec
292     stat.startTime.tv_nsec = 1000;  // 1000 is test nsec
293 
294     stat.endTime.tv_sec = 3;  // 3 is test sec
295     stat.endTime.tv_nsec = 0;
296 
297     long long diff = InitDiffTime(&stat);
298     EXPECT_TRUE(diff > 0);
299 }
300 } // namespace init_ut
301