mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
beef up write syscall tests
Added a few tests for write(2) and pwrite(2) 1. Regular Files For write(2) - write zero bytes should not move the offset - write non-zero bytes should increment the offset the exact amount - write non-zero bytes after a lseek() should move the offset the exact amount after the seek - write non-zero bytes with O_APPEND should move the offset the exact amount after original EOF For pwrite(2), offset is not affected when - pwrite zero bytes - pwrite non-zero bytes For EOF, added a test asserting the EOF (indicated by lseek(SEEK_END)) is updated properly after writing non-zero bytes 2. Symlink Added one pwite64() call for symlink that is written as a counterpart of the existing test using pread64()
This commit is contained in:
@@ -218,6 +218,35 @@ TEST(SymlinkTest, PreadFromSymlink) {
|
||||
EXPECT_THAT(unlink(linkname.c_str()), SyscallSucceeds());
|
||||
}
|
||||
|
||||
TEST(SymlinkTest, PwriteToSymlink) {
|
||||
std::string name = NewTempAbsPath();
|
||||
int fd;
|
||||
ASSERT_THAT(fd = open(name.c_str(), O_CREAT, 0644), SyscallSucceeds());
|
||||
ASSERT_THAT(close(fd), SyscallSucceeds());
|
||||
|
||||
std::string linkname = NewTempAbsPath();
|
||||
ASSERT_THAT(symlink(name.c_str(), linkname.c_str()), SyscallSucceeds());
|
||||
|
||||
ASSERT_THAT(fd = open(linkname.c_str(), O_WRONLY), SyscallSucceeds());
|
||||
|
||||
const int data_size = 10;
|
||||
const std::string data = std::string(data_size, 'a');
|
||||
EXPECT_THAT(pwrite64(fd, data.c_str(), data.size(), 0), SyscallSucceedsWithValue(data.size()));
|
||||
|
||||
ASSERT_THAT(close(fd), SyscallSucceeds());
|
||||
ASSERT_THAT(fd = open(name.c_str(), O_RDONLY), SyscallSucceeds());
|
||||
|
||||
char buf[data_size+1];
|
||||
EXPECT_THAT(pread64(fd, buf, data.size(), 0), SyscallSucceeds());
|
||||
buf[data.size()] = '\0';
|
||||
EXPECT_STREQ(buf, data.c_str());
|
||||
|
||||
ASSERT_THAT(close(fd), SyscallSucceeds());
|
||||
|
||||
EXPECT_THAT(unlink(name.c_str()), SyscallSucceeds());
|
||||
EXPECT_THAT(unlink(linkname.c_str()), SyscallSucceeds());
|
||||
}
|
||||
|
||||
TEST(SymlinkTest, SymlinkAtDegradedPermissions_NoRandomSave) {
|
||||
// Drop capabilities that allow us to override file and directory permissions.
|
||||
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false));
|
||||
|
||||
@@ -133,6 +133,77 @@ TEST_F(WriteTest, WriteExceedsRLimit) {
|
||||
EXPECT_THAT(close(fd), SyscallSucceeds());
|
||||
}
|
||||
|
||||
TEST_F(WriteTest, WriteIncrementOffset) {
|
||||
TempPath tmpfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
|
||||
FileDescriptor f = ASSERT_NO_ERRNO_AND_VALUE(Open(tmpfile.path().c_str(), O_WRONLY));
|
||||
int fd = f.get();
|
||||
|
||||
EXPECT_THAT(WriteBytes(fd, 0), SyscallSucceedsWithValue(0));
|
||||
EXPECT_THAT(lseek(fd, 0, SEEK_CUR), SyscallSucceedsWithValue(0));
|
||||
|
||||
const int bytes_total = 1024;
|
||||
|
||||
EXPECT_THAT(WriteBytes(fd, bytes_total), SyscallSucceedsWithValue(bytes_total));
|
||||
EXPECT_THAT(lseek(fd, 0, SEEK_CUR), SyscallSucceedsWithValue(bytes_total));
|
||||
}
|
||||
|
||||
TEST_F(WriteTest, WriteIncrementOffsetSeek) {
|
||||
const std::string data = "hello world\n";
|
||||
TempPath tmpfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith(
|
||||
GetAbsoluteTestTmpdir(), data, TempPath::kDefaultFileMode));
|
||||
FileDescriptor f = ASSERT_NO_ERRNO_AND_VALUE(Open(tmpfile.path().c_str(), O_WRONLY));
|
||||
int fd = f.get();
|
||||
|
||||
const int seek_offset = data.size()/2;
|
||||
ASSERT_THAT(lseek(fd, seek_offset, SEEK_SET), SyscallSucceedsWithValue(seek_offset));
|
||||
|
||||
const int write_bytes = 512;
|
||||
EXPECT_THAT(WriteBytes(fd, write_bytes), SyscallSucceedsWithValue(write_bytes));
|
||||
EXPECT_THAT(lseek(fd, 0, SEEK_CUR), SyscallSucceedsWithValue(seek_offset+write_bytes));
|
||||
}
|
||||
|
||||
TEST_F(WriteTest, WriteIncrementOffsetAppend) {
|
||||
const std::string data = "hello world\n";
|
||||
TempPath tmpfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith(
|
||||
GetAbsoluteTestTmpdir(), data, TempPath::kDefaultFileMode));
|
||||
FileDescriptor f = ASSERT_NO_ERRNO_AND_VALUE(Open(tmpfile.path().c_str(),O_WRONLY | O_APPEND));
|
||||
int fd = f.get();
|
||||
|
||||
EXPECT_THAT(WriteBytes(fd, 1024), SyscallSucceedsWithValue(1024));
|
||||
EXPECT_THAT(lseek(fd, 0, SEEK_CUR), SyscallSucceedsWithValue(data.size()+1024));
|
||||
}
|
||||
|
||||
TEST_F(WriteTest, WriteIncrementOffsetEOF) {
|
||||
const std::string data = "hello world\n";
|
||||
const TempPath tmpfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith(
|
||||
GetAbsoluteTestTmpdir(), data, TempPath::kDefaultFileMode));
|
||||
FileDescriptor f = ASSERT_NO_ERRNO_AND_VALUE(Open(tmpfile.path().c_str(), O_WRONLY));
|
||||
int fd = f.get();
|
||||
|
||||
EXPECT_THAT(lseek(fd, 0, SEEK_END), SyscallSucceedsWithValue(data.size()));
|
||||
|
||||
EXPECT_THAT(WriteBytes(fd, 1024), SyscallSucceedsWithValue(1024));
|
||||
EXPECT_THAT(lseek(fd, 0, SEEK_END), SyscallSucceedsWithValue(data.size()+1024));
|
||||
}
|
||||
|
||||
TEST_F(WriteTest, PwriteNoChangeOffset) {
|
||||
TempPath tmpfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
|
||||
FileDescriptor f = ASSERT_NO_ERRNO_AND_VALUE(Open(tmpfile.path().c_str(), O_WRONLY));
|
||||
int fd = f.get();
|
||||
|
||||
const std::string data = "hello world\n";
|
||||
|
||||
EXPECT_THAT(pwrite(fd, data.data(), data.size(), 0), SyscallSucceedsWithValue(data.size()));
|
||||
EXPECT_THAT(lseek(fd, 0, SEEK_CUR), SyscallSucceedsWithValue(0));
|
||||
|
||||
const int bytes_total = 1024;
|
||||
ASSERT_THAT(WriteBytes(fd, bytes_total), SyscallSucceedsWithValue(bytes_total));
|
||||
ASSERT_THAT(lseek(fd, 0, SEEK_CUR), SyscallSucceedsWithValue(bytes_total));
|
||||
|
||||
EXPECT_THAT(pwrite(fd, data.data(), data.size(), bytes_total), SyscallSucceedsWithValue(data.size()));
|
||||
EXPECT_THAT(lseek(fd, 0, SEEK_CUR), SyscallSucceedsWithValue(bytes_total));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace testing
|
||||
|
||||
Reference in New Issue
Block a user