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 <fcntl.h>
22 #include <unistd.h>
23 #include <gtest/gtest.h>
24 #include <sys/file.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <sys/xattr.h>
28 #include "securec.h"
29
30 using namespace testing::ext;
31 using namespace std;
32
33 class CopyFileRangeApiTest : 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 CopyFileRangeApiTest::SetUp()
42 {
43 }
TearDown()44 void CopyFileRangeApiTest::TearDown()
45 {
46 }
SetUpTestCase()47 void CopyFileRangeApiTest::SetUpTestCase()
48 {
49 }
TearDownTestCase()50 void CopyFileRangeApiTest::TearDownTestCase()
51 {
52 }
53
54 static const int MAX_LEN = 128;
55 static const char *TEST_FILE = "/data/local/tmp/CopyFileRange.txt";
56 static const char *TEST_SRC_FILE = "/data/local/tmp/CopyFileRangeSource.txt";
57 static const char *TEST_DES_FILE = "/data/local/tmp/CopyFileRangeDestination.txt";
58 static const char *TEST_SRC_DIR = "/data/local/tmp/CopyFileRangeSource";
59 static const char *TEST_DES_DIR = "/data/local/tmp/CopyFileRangeDestination";
60 static const char *TEST_DATA = "Hello, world!";
61 mode_t MODE_0644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
62 mode_t MODE_0755 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
63
64 /*
65 * @tc.number : SUB_KERNEL_SYSCALL_COPYFILERANGE_0100
66 * @tc.name : CopyFileRangeCopyValidFdContentSuccess_0001
67 * @tc.desc : copy_file_range copy TEST_DATA in fdOut with specify length from fdIn success.
68 * @tc.size : MediumTest
69 * @tc.type : Function
70 * @tc.level : Level 1
71 */
72 HWTEST_F(CopyFileRangeApiTest, CopyFileRangeCopyValidFdContentSuccess_0001, Function | MediumTest | Level1)
73 {
74 ssize_t size;
75 loff_t offIn = 0;
76 loff_t offOut = 0;
77 int ret = 0;
78 char buffer[MAX_LEN];
79 int fdIn = open(TEST_SRC_FILE, O_RDWR | O_CREAT | O_TRUNC, MODE_0644);
80 EXPECT_TRUE(fdIn > 0);
81 ret = write(fdIn, TEST_DATA, strlen(TEST_DATA));
82 EXPECT_EQ(ret, strlen(TEST_DATA));
83 int fdOut = open(TEST_DES_FILE, O_RDWR | O_CREAT | O_TRUNC, MODE_0644);
84 EXPECT_TRUE(fdOut > 0);
85
86 size = copy_file_range(fdIn, &offIn, fdOut, &offOut, strlen(TEST_DATA), 0);
87 EXPECT_EQ(size, strlen(TEST_DATA));
88 ret = read(fdOut, buffer, strlen(TEST_DATA));
89 EXPECT_EQ(size, strlen(TEST_DATA));
90 EXPECT_STREQ(buffer, TEST_DATA);
91
92 close(fdIn);
93 close(fdOut);
94 remove(TEST_SRC_FILE);
95 remove(TEST_DES_FILE);
96 }
97
98 /*
99 * @tc.number : SUB_KERNEL_SYSCALL_COPYFILERANGE_0200
100 * @tc.name : CopyFileRangeCopyInvalidFdContentFail_0002
101 * @tc.desc : copy_file_range copy from invalid fd or copy into invalid fd fail, errno EBADF.
102 * @tc.size : MediumTest
103 * @tc.type : Function
104 * @tc.level : Level 2
105 */
106 HWTEST_F(CopyFileRangeApiTest, CopyFileRangeCopyInvalidFdContentFail_0002, Function | MediumTest | Level2)
107 {
108 ssize_t size;
109 loff_t offIn = 0;
110 loff_t offOut = 0;
111 int invalidFd = -1;
112 int fd = open(TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, MODE_0644);
113 EXPECT_TRUE(fd > 0);
114
115 errno = 0;
116 size = copy_file_range(invalidFd, &offIn, fd, &offOut, strlen(TEST_DATA), 0);
117 EXPECT_EQ(size, -1);
118 EXPECT_EQ(errno, EBADF);
119
120 errno = 0;
121 size = copy_file_range(fd, &offIn, invalidFd, &offOut, strlen(TEST_DATA), 0);
122 EXPECT_EQ(size, -1);
123 EXPECT_EQ(errno, EBADF);
124
125 close(fd);
126 remove(TEST_FILE);
127 }
128
129 /*
130 * @tc.number : SUB_KERNEL_SYSCALL_COPYFILERANGE_0300
131 * @tc.name : CopyFileRangeCopyInvalidFlagFail_0003
132 * @tc.desc : copy_file_range copy with invalid flag fail, errno EINVAL.
133 * @tc.size : MediumTest
134 * @tc.type : Function
135 * @tc.level : Level 2
136 */
137 HWTEST_F(CopyFileRangeApiTest, CopyFileRangeCopyInvalidFlagFail_0003, Function | MediumTest | Level2)
138 {
139 ssize_t size;
140 loff_t offIn = 0;
141 loff_t offOut = 0;
142 int fdIn = open(TEST_SRC_FILE, O_RDWR | O_CREAT | O_TRUNC, MODE_0644);
143 EXPECT_TRUE(fdIn > 0);
144 int fdOut = open(TEST_DES_FILE, O_RDWR | O_CREAT | O_TRUNC, MODE_0644);
145 EXPECT_TRUE(fdOut > 0);
146
147 errno = 0;
148 size = copy_file_range(fdIn, &offIn, fdOut, &offOut, strlen(TEST_DATA), 1);
149 EXPECT_EQ(size, -1);
150 EXPECT_EQ(errno, EINVAL);
151
152 close(fdIn);
153 close(fdOut);
154 remove(TEST_SRC_FILE);
155 remove(TEST_DES_FILE);
156 }
157
158 /*
159 * @tc.number : SUB_KERNEL_SYSCALL_COPYFILERANGE_0400
160 * @tc.name : CopyFileRangeCopyFdNoPermissionFail_0004
161 * @tc.desc : copy_file_range copy TEST_DATA without correct permission in fdOut or fdIn fail, errno EBADF.
162 * @tc.size : MediumTest
163 * @tc.type : Function
164 * @tc.level : Level 2
165 */
166 HWTEST_F(CopyFileRangeApiTest, CopyFileRangeCopyFdNoPermissionFail_0004, Function | MediumTest | Level2)
167 {
168 ssize_t size;
169 loff_t offIn = 0;
170 loff_t offOut = 0;
171 int result = 0;
172 int fdIn = open(TEST_SRC_FILE, O_WRONLY | O_CREAT, MODE_0644);
173 EXPECT_TRUE(fdIn > 0);
174 result = write(fdIn, TEST_DATA, strlen(TEST_DATA));
175 EXPECT_EQ(result, strlen(TEST_DATA));
176 int fdOut = open(TEST_DES_FILE, O_RDONLY | O_CREAT, MODE_0644);
177 EXPECT_TRUE(fdOut > 0);
178 int fd = open(TEST_FILE, O_RDWR | O_CREAT, MODE_0644);
179 EXPECT_TRUE(fd > 0);
180
181 errno = 0;
182 size = copy_file_range(fdIn, &offIn, fd, &offOut, strlen(TEST_DATA), 0);
183 EXPECT_EQ(size, -1);
184 EXPECT_EQ(errno, EBADF);
185
186 errno = 0;
187 size = copy_file_range(fd, &offIn, fdOut, &offOut, strlen(TEST_DATA), 0);
188 EXPECT_EQ(size, -1);
189 EXPECT_EQ(errno, EBADF);
190
191 close(fd);
192 close(fdIn);
193 close(fdOut);
194 remove(TEST_FILE);
195 remove(TEST_SRC_FILE);
196 remove(TEST_DES_FILE);
197 }
198
199 /*
200 * @tc.number : SUB_KERNEL_SYSCALL_COPYFILERANGE_0500
201 * @tc.name : CopyFileRangeCopyOverOffsetContentFail_0005
202 * @tc.desc : copy_file_range copy TEST_DATA in fdOut with over offset length from fdIn .
203 * @tc.size : MediumTest
204 * @tc.type : Function
205 * @tc.level : Level 2
206 */
207 HWTEST_F(CopyFileRangeApiTest, CopyFileRangeCopyOverOffsetContentFail_0005, Function | MediumTest | Level2)
208 {
209 int ret;
210 ssize_t size;
211 loff_t offIn = 0;
212 loff_t offOut = 0;
213 if (access(TEST_SRC_DIR, F_OK) != 0) {
214 ret = mkdir(TEST_SRC_DIR, MODE_0755);
215 EXPECT_EQ(ret, 0);
216 }
217 int fdIn = open(TEST_SRC_DIR, O_RDONLY | O_DIRECTORY);
218 EXPECT_NE(fdIn, -1);
219 if (access(TEST_DES_DIR, F_OK) != 0) {
220 ret = mkdir(TEST_DES_DIR, MODE_0755);
221 EXPECT_EQ(ret, 0);
222 }
223 int fdOut = open(TEST_DES_DIR, O_RDONLY | O_DIRECTORY);
224 EXPECT_NE(fdOut, -1);
225
226 errno = 0;
227 size = copy_file_range(fdIn, &offIn, fdOut, &offOut, strlen(TEST_DATA), 0);
228 EXPECT_EQ(size, -1);
229 EXPECT_EQ(errno, EISDIR);
230
231 close(fdIn);
232 close(fdOut);
233 remove(TEST_SRC_DIR);
234 remove(TEST_DES_DIR);
235 }