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 <cstdlib> 18#include <cstdio> 19#include <string> 20#include <fcntl.h> 21#include <unistd.h> 22#include <gtest/gtest.h> 23#include <sys/stat.h> 24#include <sys/types.h> 25 26using namespace testing::ext; 27using namespace std; 28 29class OpenatApiTest : public testing::Test { 30public: 31 static void SetUpTestCase(); 32 static void TearDownTestCase(); 33 void SetUp(); 34 void TearDown(); 35 36private: 37}; 38 39static const char *TEST_DIR = "/data/local/tmp/tmp"; 40static const char *TEST_FILE = "/data/local/tmp/tmp/test"; 41 42void OpenatApiTest::SetUpTestCase() 43{ 44} 45 46void OpenatApiTest::TearDownTestCase() 47{ 48} 49 50void OpenatApiTest::SetUp() 51{ 52 mkdir(TEST_DIR, S_IRWXU | S_IRWXG | S_IRWXO); 53} 54 55void OpenatApiTest::TearDown() 56{ 57 rmdir(TEST_DIR); 58} 59 60/* 61 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0100 62 * @tc.name : OpenatReadOnlySuccess_0001 63 * @tc.desc : openat with O_RDONLY should open a file for reading only. 64 * @tc.size : MediumTest 65 * @tc.type : Function 66 * @tc.level : Level 1 67 */ 68HWTEST_F(OpenatApiTest, OpenatReadOnlySuccess_0001, Function | MediumTest | Level1) 69{ 70 int dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 71 72 int fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644); 73 EXPECT_TRUE(fd >= 0); 74 close(fd); 75 76 fd = openat(dirFd, TEST_FILE, O_RDONLY); 77 EXPECT_TRUE(fd >= 0); 78 79 errno = 0; 80 ssize_t bytesWritten = write(fd, "A", 1); 81 EXPECT_EQ(bytesWritten, -1); 82 EXPECT_EQ(errno, EBADF); 83 close(fd); 84 unlinkat(dirFd, TEST_FILE, 0); 85 close(dirFd); 86} 87 88/* 89 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0200 90 * @tc.name : OpenatReadWriteSuccess_0002 91 * @tc.desc : openat with O_RDWR should open a file for reading and writing. 92 * @tc.size : MediumTest 93 * @tc.type : Function 94 * @tc.level : Level 1 95 */ 96HWTEST_F(OpenatApiTest, OpenatReadWriteSuccess_0002, Function | MediumTest | Level1) 97{ 98 const char *data = "Hello, World!"; 99 char readBuf[128]; 100 int dirFd = -1; 101 int fd = -1; 102 dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 103 EXPECT_TRUE(dirFd >= 0); 104 105 fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT, 0644); 106 EXPECT_TRUE(fd >= 0); 107 write(fd, data, strlen(data)); 108 lseek(fd, 0, SEEK_SET); 109 read(fd, readBuf, sizeof(readBuf)); 110 EXPECT_STREQ(readBuf, data); 111 close(fd); 112 unlinkat(dirFd, TEST_FILE, 0); 113 close(dirFd); 114} 115 116/* 117 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0300 118 * @tc.name : OpenatAppendSuccess_0003 119 * @tc.desc : openat with O_APPEND should append to the end of the file. 120 * @tc.size : MediumTest 121 * @tc.type : Function 122 * @tc.level : Level 1 123 */ 124HWTEST_F(OpenatApiTest, OpenatAppendSuccess_0003, Function | MediumTest | Level1) 125{ 126 char readBuf[256] = {0}; 127 const char *data = "Hello, World!"; 128 const char *appendData = " More data"; 129 int dirFd = -1; 130 int fd = -1; 131 132 dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 133 134 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644); 135 EXPECT_TRUE(fd >= 0); 136 ssize_t bytesWritten = write(fd, data, strlen(data)); 137 EXPECT_EQ(bytesWritten, strlen(data)); 138 139 close(fd); 140 141 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_APPEND); 142 EXPECT_TRUE(fd >= 0); 143 bytesWritten = write(fd, appendData, strlen(appendData)); 144 EXPECT_EQ(bytesWritten, strlen(appendData)); 145 146 close(fd); 147 148 fd = openat(dirFd, TEST_FILE, O_RDONLY); 149 EXPECT_TRUE(fd >= 0); 150 ssize_t bytesRead = read(fd, readBuf, sizeof(readBuf) - 1); 151 EXPECT_TRUE(bytesRead > 0); 152 153 readBuf[bytesRead] = '\0'; 154 std::string expectedContent(data); 155 expectedContent += appendData; 156 EXPECT_STREQ(readBuf, expectedContent.c_str()); 157 158 close(fd); 159 unlinkat(dirFd, TEST_FILE, 0); 160 close(dirFd); 161} 162 163/* 164 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0400 165 * @tc.name : OpenatNoFollowFailed_0004 166 * @tc.desc : openat with O_NOFOLLOW should fail if the path is a symbolic link. 167 * @tc.size : MediumTest 168 * @tc.type : Function 169 * @tc.level : Level 2 170 */ 171HWTEST_F(OpenatApiTest, OpenatNoFollowFailed_0004, Function | MediumTest | Level2) 172{ 173 int dirFd = -1; 174 int fd = -1; 175 dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 176 177 errno = 0; 178 symlink("target", TEST_FILE); 179 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT | O_NOFOLLOW); 180 EXPECT_EQ(fd, -1); 181 EXPECT_EQ(errno, ELOOP); 182 close(dirFd); 183} 184 185/* 186 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0500 187 * @tc.name : OpenatWriteOnlySuccess_0005 188 * @tc.desc : openat with O_WRONLY should open a file for writing only. 189 * @tc.size : MediumTest 190 * @tc.type : Function 191 * @tc.level : Level 1 192 */ 193HWTEST_F(OpenatApiTest, OpenatWriteOnlySuccess_0005, Function | MediumTest | Level1) 194{ 195 int dirFd; 196 int fd; 197 char buf; 198 ssize_t bytesRead; 199 ssize_t bytesWritten; 200 const char *data; 201 202 203 dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 204 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644); 205 EXPECT_TRUE(fd >= 0); 206 207 bytesRead = read(fd, &buf, 1); 208 EXPECT_EQ(bytesRead, -1); 209 EXPECT_EQ(errno, EBADF); 210 211 data = "Test data"; 212 bytesWritten = write(fd, data, strlen(data)); 213 EXPECT_TRUE(bytesWritten == strlen(data)); 214 215 close(fd); 216 unlinkat(dirFd, TEST_FILE, 0); 217 close(dirFd); 218} 219 220/* 221 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0600 222 * @tc.name : OpenatCreateTest_0006 223 * @tc.desc : openat with O_CREAT. 224 * @tc.size : MediumTest 225 * @tc.type : Function 226 * @tc.level : Level 2 227 */ 228HWTEST_F(OpenatApiTest, OpenatCreateTest_0006, Function | MediumTest | Level2) 229{ 230 int dirFd = -1; 231 int fd = -1; 232 struct stat buf; 233 dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 234 235 fd = openat(dirFd, TEST_FILE, O_WRONLY, 0644); 236 EXPECT_TRUE(fd == -1); 237 stat(TEST_FILE, &buf); 238 EXPECT_EQ(errno, ENOENT); 239 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644); 240 EXPECT_TRUE(fd >= 0); 241 EXPECT_TRUE(stat(TEST_FILE, &buf) == 0); 242 243 close(fd); 244 unlinkat(dirFd, TEST_FILE, 0); 245 close(dirFd); 246} 247 248/* 249 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0700 250 * @tc.name : OpenatDirectoryTest_0007 251 * @tc.desc : openat with O_DIRECTORY. 252 * @tc.size : MediumTest 253 * @tc.type : Function 254 * @tc.level : Level 2 255 */ 256HWTEST_F(OpenatApiTest, OpenatDirectoryTest_0007, Function | MediumTest | Level2) 257{ 258 int dirFd = -1; 259 int fd = -1; 260 struct stat buf; 261 dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 262 263 fd = open(TEST_FILE, O_WRONLY | O_CREAT, 0644); 264 close(fd); 265 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_DIRECTORY, 0644); 266 EXPECT_TRUE(fd == -1); 267 stat(TEST_FILE, &buf); 268 EXPECT_TRUE(S_ISREG(buf.st_mode)); 269 unlinkat(dirFd, TEST_FILE, 0); 270 271 mkdir(TEST_FILE, 0644); 272 fd = openat(dirFd, TEST_FILE, O_DIRECTORY, 0644); 273 EXPECT_TRUE(fd >= 0); 274 stat(TEST_FILE, &buf); 275 EXPECT_TRUE(S_ISDIR(buf.st_mode)); 276 277 close(fd); 278 rmdir(TEST_FILE); 279 close(dirFd); 280} 281 282/* 283 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0800 284 * @tc.name : OpenatExclTest_0008 285 * @tc.desc : openat with O_EXCL to prevent overwriting the content of existing files. 286 * @tc.size : MediumTest 287 * @tc.type : Function 288 * @tc.level : Level 2 289 */ 290HWTEST_F(OpenatApiTest, OpenatExclTest_0008, Function | MediumTest | Level2) 291{ 292 int dirFd = -1; 293 int fd = -1; 294 dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 295 296 EXPECT_TRUE(access(TEST_FILE, F_OK) == -1); 297 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT | O_EXCL, 0644); 298 EXPECT_TRUE(fd >= 0); 299 close(fd); 300 EXPECT_TRUE(access(TEST_FILE, F_OK) == 0); 301 302 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT | O_EXCL, 0644); 303 EXPECT_TRUE(fd == -1); 304 EXPECT_TRUE(access(TEST_FILE, F_OK) == 0); 305 306 unlinkat(dirFd, TEST_FILE, 0); 307 close(dirFd); 308} 309 310/* 311 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0900 312 * @tc.name : OpenatNoatimeSuccess_0009 313 * @tc.desc : openat with O_NOATIME to prevent changing atime but still changing mtime. 314 * @tc.size : MediumTest 315 * @tc.type : Function 316 * @tc.level : Level 1 317 */ 318HWTEST_F(OpenatApiTest, OpenatNoatimeSuccess_0009, Function | MediumTest | Level1) 319{ 320 int dirFd = -1; 321 int fd = -1; 322 struct stat bufFirst; 323 struct stat bufSecond; 324 dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 325 326 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644); 327 EXPECT_TRUE(fd >= 0); 328 close(fd); 329 stat(TEST_FILE, &bufFirst); 330 331 usleep(100); 332 fd = openat(dirFd, TEST_FILE, O_WRONLY | O_NOATIME, 0644); 333 EXPECT_TRUE(fd >= 0); 334 close(fd); 335 stat(TEST_FILE, &bufSecond); 336 EXPECT_TRUE(bufFirst.st_atime == bufSecond.st_atime); 337 338 unlinkat(dirFd, TEST_FILE, 0); 339 close(dirFd); 340} 341 342/* 343 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_1000 344 * @tc.name : OpenatFlagsTestSuccess_0010 345 * @tc.desc : openat with some flags. 346 * @tc.size : MediumTest 347 * @tc.type : Function 348 * @tc.level : Level 1 349 */ 350HWTEST_F(OpenatApiTest, OpenatFlagsTestSuccess_0010, Function | MediumTest | Level1) 351{ 352 int dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 353 354 // O_TRUNC test 355 int fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT, 0644); 356 const char *data = "Test data"; 357 write(fd, data, strlen(data)); 358 close(fd); 359 fd = openat(dirFd, TEST_FILE, O_RDWR | O_TRUNC, 0644); 360 EXPECT_TRUE(fd >= 0); 361 close(fd); 362 unlinkat(dirFd, TEST_FILE, 0); 363 364 // O_ASYNC test 365 fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT | O_ASYNC, 0644); 366 EXPECT_TRUE(fd >= 0); 367 close(fd); 368 unlinkat(dirFd, TEST_FILE, 0); 369 370 // O_DIRECT test 371 fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT | O_DIRECT, 0644); 372 EXPECT_TRUE(fd >= 0); 373 close(fd); 374 unlinkat(dirFd, TEST_FILE, 0); 375 376 // O_DSYNC test 377 fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT | O_DSYNC, 0644); 378 EXPECT_TRUE(fd >= 0); 379 close(fd); 380 unlinkat(dirFd, TEST_FILE, 0); 381 382 // O_SYNC test 383 fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT | O_SYNC, 0644); 384 EXPECT_TRUE(fd >= 0); 385 close(fd); 386 unlinkat(dirFd, TEST_FILE, 0); 387 388 close(dirFd); 389} 390 391/* 392 * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_1100 393 * @tc.name : OpenatFlagsTestSuccess_0011 394 * @tc.desc : openat O_CLOEXEC/O_LARGEFILE/O_NOCTTY/O_NONBLOCK flags test success. 395 * @tc.size : MediumTest 396 * @tc.type : Function 397 * @tc.level : Level 1 398 */ 399HWTEST_F(OpenatApiTest, OpenatO_CLOEXECFlagSuccess_0011, Function | MediumTest | Level1) 400{ 401 int dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY); 402 403 int fd = openat(dirFd, TEST_FILE, O_RDWR | O_CLOEXEC | O_CREAT, 0755); 404 EXPECT_TRUE(fd >= 0); 405 close(fd); 406 unlinkat(dirFd, TEST_FILE, 0); 407 408 fd = openat(dirFd, TEST_FILE, O_RDWR | O_LARGEFILE | O_CREAT, 0755); 409 EXPECT_TRUE(fd >= 0); 410 close(fd); 411 unlinkat(dirFd, TEST_FILE, 0); 412 413 fd = openat(dirFd, TEST_FILE, O_RDWR | O_NOCTTY | O_CREAT, 0755); 414 EXPECT_TRUE(fd >= 0); 415 close(fd); 416 unlinkat(dirFd, TEST_FILE, 0); 417 418 fd = openat(dirFd, TEST_FILE, O_RDWR | O_NONBLOCK | O_CREAT, 0755); 419 EXPECT_TRUE(fd >= 0); 420 close(fd); 421 unlinkat(dirFd, TEST_FILE, 0); 422 423 close(dirFd); 424}