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 }