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 30using namespace testing::ext; 31using namespace std; 32 33class CopyFileRangeApiTest : public testing::Test { 34public: 35 static void SetUpTestCase(); 36 static void TearDownTestCase(); 37 void SetUp(); 38 void TearDown(); 39private: 40}; 41void CopyFileRangeApiTest::SetUp() 42{ 43} 44void CopyFileRangeApiTest::TearDown() 45{ 46} 47void CopyFileRangeApiTest::SetUpTestCase() 48{ 49} 50void CopyFileRangeApiTest::TearDownTestCase() 51{ 52} 53 54static const int MAX_LEN = 128; 55static const char *TEST_FILE = "/data/local/tmp/CopyFileRange.txt"; 56static const char *TEST_SRC_FILE = "/data/local/tmp/CopyFileRangeSource.txt"; 57static const char *TEST_DES_FILE = "/data/local/tmp/CopyFileRangeDestination.txt"; 58static const char *TEST_SRC_DIR = "/data/local/tmp/CopyFileRangeSource"; 59static const char *TEST_DES_DIR = "/data/local/tmp/CopyFileRangeDestination"; 60static const char *TEST_DATA = "Hello, world!"; 61mode_t MODE_0644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 62mode_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 */ 72HWTEST_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 */ 106HWTEST_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 */ 137HWTEST_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 */ 166HWTEST_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 */ 207HWTEST_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}