1 /*
2  * Copyright (C) 2024 HiHope Open Source Organization.
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 <cerrno>
17 #include <cstdio>
18 #include <cstdlib>
19 #include <string>
20 #include <vector>
21 #include <dirent.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <arpa/inet.h>
25 #include <gtest/gtest.h>
26 #include <netinet/in.h>
27 #include <sys/stat.h>
28 #include <sys/socket.h>
29 #include <sys/types.h>
30 
31 using namespace testing::ext;
32 
33 class HatsUnlinkatTest : public testing::Test {
34 public:
35 static void SetUpTestCase();
36 static void TearDownTestCase();
37 void SetUp();
38 void TearDown();
39 private:
40 };
SetUp()41 void HatsUnlinkatTest::SetUp()
42 {
43 }
TearDown()44 void HatsUnlinkatTest::TearDown()
45 {
46 }
SetUpTestCase()47 void HatsUnlinkatTest::SetUpTestCase()
48 {
49 }
TearDownTestCase()50 void HatsUnlinkatTest::TearDownTestCase()
51 {
52 }
53 
54 static const char *UNLINKAT_TEST_FILE = "/data/local/tmp/tryUnlinkat.txt";
55 static const char *UNLINKAT_TEST_DIR = "/data/local/tmp";
56 static const char *UNLINKAT_TEST_FILENAME = "tryUnlinkat.txt";
57 
58 /*
59  * @tc.number : SUB_KERNEL_SYSCALL_UNLINKAT_0100
60  * @tc.name   : UnlinkatUnlinkFileSuccess_0001
61  * @tc.desc   : Unlinkat unlink file success.
62  * @tc.size   : MediumTest
63  * @tc.type   : Function
64  * @tc.level  : Level 1
65  */
HWTEST_F(HatsUnlinkatTest, UnlinkatUnlinkFileSuccess_0001, Function | MediumTest | Level1)66 HWTEST_F(HatsUnlinkatTest, UnlinkatUnlinkFileSuccess_0001, Function | MediumTest | Level1)
67 {
68     int fileFd;
69     int dirFd;
70     int ret;
71 
72     fileFd = open(UNLINKAT_TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
73     EXPECT_TRUE(fileFd >= 3);
74     close(fileFd);
75 
76     dirFd = open(UNLINKAT_TEST_DIR, O_RDONLY);
77     EXPECT_TRUE(dirFd >= 3);
78 
79     ret = unlinkat(dirFd, UNLINKAT_TEST_FILENAME, 0);
80     EXPECT_TRUE(ret == 0);
81     close(dirFd);
82 
83     fileFd = open(UNLINKAT_TEST_FILE, O_RDWR, 0644);
84     EXPECT_TRUE(fileFd == -1);
85     close(fileFd);
86 }
87 
88 /*
89  * @tc.number : SUB_KERNEL_SYSCALL_UNLINKAT_0200
90  * @tc.name   : UnlinkatUnlinkEmptyDirectorySuccess_0002
91  * @tc.desc   : Unlinkat unlink an empty directory success.
92  * @tc.size   : MediumTest
93  * @tc.type   : Function
94  * @tc.level  : Level 1
95  */
HWTEST_F(HatsUnlinkatTest, UnlinkatUnlinkEmptyDirectorySuccess_0002, Function | MediumTest | Level1)96 HWTEST_F(HatsUnlinkatTest, UnlinkatUnlinkEmptyDirectorySuccess_0002, Function | MediumTest | Level1)
97 {
98     int ret;
99     DIR *testDir;
100     struct dirent *dirEntry;
101     const char *unlinkatNewDir1 = "/data/local/tmp/unlinkatDir1";
102 
103 
104     ret = mkdir(unlinkatNewDir1, 0777);
105     if (ret == -1) {
106         testDir = opendir(unlinkatNewDir1);
107         EXPECT_TRUE(testDir != nullptr);
108 
109         dirEntry = readdir(testDir);
110         EXPECT_TRUE(dirEntry != nullptr);
111 
112         ret = strcmp(dirEntry->d_name, ".");
113         EXPECT_TRUE(ret == 0);
114     }
115 
116     ret = unlinkat(AT_FDCWD, unlinkatNewDir1, AT_REMOVEDIR);
117     EXPECT_TRUE(ret == 0);
118 }
119 
120 /*
121  * @tc.number : SUB_KERNEL_SYSCALL_UNLINKAT_0300
122  * @tc.name   : UnlinkatUnlinkNonemptyDirectoryFail_0003
123  * @tc.desc   : Unlinkat unlink a non-empty directory fail.
124  * @tc.size   : MediumTest
125  * @tc.type   : Function
126  * @tc.level  : Level 2
127  */
HWTEST_F(HatsUnlinkatTest, UnlinkatUnlinkNonemptyDirectoryFail_0003, Function | MediumTest | Level2)128 HWTEST_F(HatsUnlinkatTest, UnlinkatUnlinkNonemptyDirectoryFail_0003, Function | MediumTest | Level2)
129 {
130     int fileFd;
131     int ret;
132     DIR *testDir;
133     struct dirent *dirEntry;
134     const char *unlinkatNewDir2 = "/data/local/tmp/unlinkatDir2";
135     const char *unlinkatNewFile2 = "/data/local/tmp/unlinkatDir2/testFile.txt";
136 
137     ret = mkdir(unlinkatNewDir2, 0777);
138     if (ret == -1) {
139         testDir = opendir(unlinkatNewDir2);
140         EXPECT_TRUE(testDir != nullptr);
141 
142         dirEntry = readdir(testDir);
143         EXPECT_TRUE(dirEntry != nullptr);
144 
145         ret = strcmp(dirEntry->d_name, ".");
146         if (ret == 0) {
147             fileFd = open(unlinkatNewFile2, O_RDWR | O_CREAT, 0777);
148             EXPECT_TRUE(fileFd >= 3);
149             close(fileFd);
150         }
151     } else {
152         fileFd = open(unlinkatNewFile2, O_RDWR | O_CREAT, 0777);
153         EXPECT_TRUE(fileFd >= 3);
154         close(fileFd);
155     }
156     errno = 0;
157     ret = unlinkat(AT_FDCWD, unlinkatNewDir2, AT_REMOVEDIR);
158     EXPECT_TRUE(ret == -1);
159     EXPECT_EQ(errno, ENOTEMPTY);
160 
161     remove(unlinkatNewFile2);
162 }
163 
164 /*
165  * @tc.number : SUB_KERNEL_SYSCALL_UNLINKAT_0400
166  * @tc.name   : UnlinkatNonexistFileFail_0004
167  * @tc.desc   : Unlinkat a non-exist file fail.
168  * @tc.size   : MediumTest
169  * @tc.type   : Function
170  * @tc.level  : Level 2
171  */
HWTEST_F(HatsUnlinkatTest, UnlinkatNonexistFileFail_0004, Function | MediumTest | Level2)172 HWTEST_F(HatsUnlinkatTest, UnlinkatNonexistFileFail_0004, Function | MediumTest | Level2)
173 {
174     int fileFd;
175     int dirFd;
176     int ret;
177 
178     remove(UNLINKAT_TEST_FILE);
179     fileFd = open(UNLINKAT_TEST_FILE, O_RDWR | O_TRUNC, 0644);
180     EXPECT_TRUE(fileFd == -1);
181     close(fileFd);
182 
183     dirFd = open(UNLINKAT_TEST_DIR, O_RDONLY);
184     EXPECT_TRUE(dirFd >= 3);
185 
186     errno = 0;
187     ret = unlinkat(dirFd, UNLINKAT_TEST_FILENAME, 0);
188     EXPECT_TRUE(ret == -1);
189     EXPECT_EQ(errno, ENOENT);
190     close(dirFd);
191 }
192 
193 /*
194  * @tc.number : SUB_KERNEL_SYSCALL_UNLINKAT_0500
195  * @tc.name   : UnlinkatDirectoryWhenFlagIsNotRemovedirFail_0005
196  * @tc.desc   : Unlinkat unlink a directory when flag is not set to AT_REMOVEDIR fail.
197  * @tc.size   : MediumTest
198  * @tc.type   : Function
199  * @tc.level  : Level 2
200  */
HWTEST_F(HatsUnlinkatTest, UnlinkatDirectoryWhenFlagIsNotRemovedirFail_0005, Function | MediumTest | Level2)201 HWTEST_F(HatsUnlinkatTest, UnlinkatDirectoryWhenFlagIsNotRemovedirFail_0005, Function | MediumTest | Level2)
202 {
203     int ret;
204     DIR *testDir;
205     struct dirent *dirEntry;
206     const char *unlinkatNewDir3 = "/data/local/tmp/unlinkatDir3";
207 
208     ret = mkdir(unlinkatNewDir3, 0777);
209     if (ret == -1) {
210         testDir = opendir(unlinkatNewDir3);
211         EXPECT_TRUE(testDir != nullptr);
212 
213         dirEntry = readdir(testDir);
214         EXPECT_TRUE(dirEntry != nullptr);
215 
216         ret = strcmp(dirEntry->d_name, ".");
217         EXPECT_TRUE(ret == 0);
218     }
219     errno = 0;
220     ret = unlinkat(AT_FDCWD, unlinkatNewDir3, 0);
221     EXPECT_TRUE(ret == -1);
222     EXPECT_EQ(errno, EISDIR);
223 }
224 
225 /*
226  * @tc.number : SUB_KERNEL_SYSCALL_UNLINKAT_0600
227  * @tc.name   : UnlinkatFileWhenFlagIsNot0Fail_0006
228  * @tc.desc   : Unlinkat a file when flag is not set 0 fail.
229  * @tc.size   : MediumTest
230  * @tc.type   : Function
231  * @tc.level  : Level 2
232  */
HWTEST_F(HatsUnlinkatTest, UnlinkatFileWhenFlagIsNot0Fail_0006, Function | MediumTest | Level2)233 HWTEST_F(HatsUnlinkatTest, UnlinkatFileWhenFlagIsNot0Fail_0006, Function | MediumTest | Level2)
234 {
235     int fileFd;
236     int dirFd;
237     int ret;
238 
239     fileFd = open(UNLINKAT_TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
240     EXPECT_TRUE(fileFd >= 3);
241     close(fileFd);
242 
243     dirFd = open(UNLINKAT_TEST_DIR, O_RDONLY);
244     EXPECT_TRUE(dirFd >= 3);
245 
246     errno = 0;
247     ret = unlinkat(dirFd, UNLINKAT_TEST_FILENAME, AT_REMOVEDIR);
248     EXPECT_TRUE(ret == -1);
249     EXPECT_EQ(errno, ENOTDIR);
250     close(dirFd);
251 }