Changeset View
Changeset View
Standalone View
Standalone View
tests/sys/fs/fusefs/write.cc
Show First 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
}; | }; | ||||
/* Tests for clustered writes with WriteBack cacheing */ | /* Tests for clustered writes with WriteBack cacheing */ | ||||
class WriteCluster: public WriteBack { | class WriteCluster: public WriteBack { | ||||
public: | public: | ||||
virtual void SetUp() { | virtual void SetUp() { | ||||
m_async = true; | m_async = true; | ||||
m_maxwrite = m_maxphys; | m_maxwrite = 1 << 25; // Anything larger than MAXPHYS will suffice | ||||
WriteBack::SetUp(); | WriteBack::SetUp(); | ||||
if (m_maxphys < 2 * DFLTPHYS) | if (m_maxphys < 2 * DFLTPHYS) | ||||
GTEST_SKIP() << "MAXPHYS must be at least twice DFLTPHYS" | GTEST_SKIP() << "MAXPHYS must be at least twice DFLTPHYS" | ||||
<< " for this test"; | << " for this test"; | ||||
if (m_maxphys < 2 * m_maxbcachebuf) | if (m_maxphys < 2 * m_maxbcachebuf) | ||||
GTEST_SKIP() << "MAXPHYS must be at least twice maxbcachebuf" | GTEST_SKIP() << "MAXPHYS must be at least twice maxbcachebuf" | ||||
<< " for this test"; | << " for this test"; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 363 Lines • ▼ Show 20 Lines | TEST_F(Write, mmap) | ||||
memmove((uint8_t*)p + offset, CONTENTS, bufsize); | memmove((uint8_t*)p + offset, CONTENTS, bufsize); | ||||
ASSERT_EQ(0, munmap(p, len)) << strerror(errno); | ASSERT_EQ(0, munmap(p, len)) << strerror(errno); | ||||
close(fd); // Write mmap'd data on close | close(fd); // Write mmap'd data on close | ||||
free(expected); | free(expected); | ||||
free(zeros); | free(zeros); | ||||
leak(fd); | |||||
} | } | ||||
TEST_F(Write, pwrite) | TEST_F(Write, pwrite) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_file.txt"; | const char FULLPATH[] = "mountpoint/some_file.txt"; | ||||
const char RELPATH[] = "some_file.txt"; | const char RELPATH[] = "some_file.txt"; | ||||
const char *CONTENTS = "abcdefgh"; | const char *CONTENTS = "abcdefgh"; | ||||
uint64_t ino = 42; | uint64_t ino = 42; | ||||
Show All 35 Lines | TEST_F(Write, timestamps) | ||||
nap(); | nap(); | ||||
ASSERT_EQ(0, fstat(fd, &sb1)) << strerror(errno); | ASSERT_EQ(0, fstat(fd, &sb1)) << strerror(errno); | ||||
EXPECT_EQ(sb0.st_atime, sb1.st_atime); | EXPECT_EQ(sb0.st_atime, sb1.st_atime); | ||||
EXPECT_NE(sb0.st_mtime, sb1.st_mtime); | EXPECT_NE(sb0.st_mtime, sb1.st_mtime); | ||||
EXPECT_NE(sb0.st_ctime, sb1.st_ctime); | EXPECT_NE(sb0.st_ctime, sb1.st_ctime); | ||||
leak(fd); | |||||
} | } | ||||
TEST_F(Write, write) | TEST_F(Write, write) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_file.txt"; | const char FULLPATH[] = "mountpoint/some_file.txt"; | ||||
const char RELPATH[] = "some_file.txt"; | const char RELPATH[] = "some_file.txt"; | ||||
const char *CONTENTS = "abcdefgh"; | const char *CONTENTS = "abcdefgh"; | ||||
uint64_t ino = 42; | uint64_t ino = 42; | ||||
▲ Show 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | |||||
TEST_F(WriteBack, cache) | TEST_F(WriteBack, cache) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_file.txt"; | const char FULLPATH[] = "mountpoint/some_file.txt"; | ||||
const char RELPATH[] = "some_file.txt"; | const char RELPATH[] = "some_file.txt"; | ||||
const char *CONTENTS = "abcdefgh"; | const char *CONTENTS = "abcdefgh"; | ||||
uint64_t ino = 42; | uint64_t ino = 42; | ||||
int fd; | int fd; | ||||
ssize_t bufsize = strlen(CONTENTS); | ssize_t bufsize = strlen(CONTENTS); | ||||
char readbuf[bufsize]; | uint8_t readbuf[bufsize]; | ||||
expect_lookup(RELPATH, ino, 0); | expect_lookup(RELPATH, ino, 0); | ||||
expect_open(ino, 0, 1); | expect_open(ino, 0, 1); | ||||
expect_write(ino, 0, bufsize, bufsize, CONTENTS); | expect_write(ino, 0, bufsize, bufsize, CONTENTS); | ||||
fd = open(FULLPATH, O_RDWR); | fd = open(FULLPATH, O_RDWR); | ||||
EXPECT_LE(0, fd) << strerror(errno); | EXPECT_LE(0, fd) << strerror(errno); | ||||
Show All 15 Lines | |||||
TEST_F(WriteBack, o_direct) | TEST_F(WriteBack, o_direct) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_file.txt"; | const char FULLPATH[] = "mountpoint/some_file.txt"; | ||||
const char RELPATH[] = "some_file.txt"; | const char RELPATH[] = "some_file.txt"; | ||||
const char *CONTENTS = "abcdefgh"; | const char *CONTENTS = "abcdefgh"; | ||||
uint64_t ino = 42; | uint64_t ino = 42; | ||||
int fd; | int fd; | ||||
ssize_t bufsize = strlen(CONTENTS); | ssize_t bufsize = strlen(CONTENTS); | ||||
char readbuf[bufsize]; | uint8_t readbuf[bufsize]; | ||||
expect_lookup(RELPATH, ino, 0); | expect_lookup(RELPATH, ino, 0); | ||||
expect_open(ino, 0, 1); | expect_open(ino, 0, 1); | ||||
FuseTest::expect_write(ino, 0, bufsize, bufsize, 0, FUSE_WRITE_CACHE, | FuseTest::expect_write(ino, 0, bufsize, bufsize, 0, FUSE_WRITE_CACHE, | ||||
CONTENTS); | CONTENTS); | ||||
expect_read(ino, 0, bufsize, bufsize, CONTENTS); | expect_read(ino, 0, bufsize, bufsize, CONTENTS); | ||||
fd = open(FULLPATH, O_RDWR | O_DIRECT); | fd = open(FULLPATH, O_RDWR | O_DIRECT); | ||||
Show All 30 Lines | TEST_F(WriteBackAsync, delay) | ||||
).Times(0); | ).Times(0); | ||||
fd = open(FULLPATH, O_RDWR); | fd = open(FULLPATH, O_RDWR); | ||||
EXPECT_LE(0, fd) << strerror(errno); | EXPECT_LE(0, fd) << strerror(errno); | ||||
ASSERT_EQ(bufsize, write(fd, CONTENTS, bufsize)) << strerror(errno); | ASSERT_EQ(bufsize, write(fd, CONTENTS, bufsize)) << strerror(errno); | ||||
/* Don't close the file because that would flush the cache */ | /* Don't close the file because that would flush the cache */ | ||||
leak(fd); | |||||
} | } | ||||
/* | /* | ||||
* A direct write should not evict dirty cached data from outside of its own | * A direct write should not evict dirty cached data from outside of its own | ||||
* byte range. | * byte range. | ||||
*/ | */ | ||||
TEST_F(WriteBackAsync, direct_io_ignores_unrelated_cached) | TEST_F(WriteBackAsync, direct_io_ignores_unrelated_cached) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 217 Lines • ▼ Show 20 Lines | TEST_F(WriteBackAsync, timestamps) | ||||
fd = open(FULLPATH, O_RDWR); | fd = open(FULLPATH, O_RDWR); | ||||
EXPECT_LE(0, fd) << strerror(errno); | EXPECT_LE(0, fd) << strerror(errno); | ||||
ASSERT_EQ(bufsize, write(fd, CONTENTS, bufsize)) << strerror(errno); | ASSERT_EQ(bufsize, write(fd, CONTENTS, bufsize)) << strerror(errno); | ||||
ASSERT_EQ(0, fstat(fd, &sb)) << strerror(errno); | ASSERT_EQ(0, fstat(fd, &sb)) << strerror(errno); | ||||
EXPECT_EQ((time_t)server_time, sb.st_atime); | EXPECT_EQ((time_t)server_time, sb.st_atime); | ||||
EXPECT_NE((time_t)server_time, sb.st_mtime); | EXPECT_NE((time_t)server_time, sb.st_mtime); | ||||
EXPECT_NE((time_t)server_time, sb.st_ctime); | EXPECT_NE((time_t)server_time, sb.st_ctime); | ||||
leak(fd); | |||||
} | } | ||||
/* Any dirty timestamp fields should be flushed during a SETATTR */ | /* Any dirty timestamp fields should be flushed during a SETATTR */ | ||||
TEST_F(WriteBackAsync, timestamps_during_setattr) | TEST_F(WriteBackAsync, timestamps_during_setattr) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_file.txt"; | const char FULLPATH[] = "mountpoint/some_file.txt"; | ||||
const char RELPATH[] = "some_file.txt"; | const char RELPATH[] = "some_file.txt"; | ||||
const char *CONTENTS = "abcdefgh"; | const char *CONTENTS = "abcdefgh"; | ||||
Show All 17 Lines | ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { | ||||
out.body.attr.attr.ino = ino; | out.body.attr.attr.ino = ino; | ||||
out.body.attr.attr.mode = S_IFREG | newmode; | out.body.attr.attr.mode = S_IFREG | newmode; | ||||
}))); | }))); | ||||
fd = open(FULLPATH, O_RDWR); | fd = open(FULLPATH, O_RDWR); | ||||
EXPECT_LE(0, fd) << strerror(errno); | EXPECT_LE(0, fd) << strerror(errno); | ||||
ASSERT_EQ(bufsize, write(fd, CONTENTS, bufsize)) << strerror(errno); | ASSERT_EQ(bufsize, write(fd, CONTENTS, bufsize)) << strerror(errno); | ||||
ASSERT_EQ(0, fchmod(fd, newmode)) << strerror(errno); | ASSERT_EQ(0, fchmod(fd, newmode)) << strerror(errno); | ||||
emaste: why empty space for some but not all? | |||||
Done Inline ActionsUh, because I wasn't careful? I'll try to use the space everywhere, and add it before I commit. asomers: Uh, because I wasn't careful? I'll try to use the space everywhere, and add it before I commit. | |||||
leak(fd); | |||||
} | } | ||||
/* fuse_init_out.time_gran controls the granularity of timestamps */ | /* fuse_init_out.time_gran controls the granularity of timestamps */ | ||||
TEST_P(TimeGran, timestamps_during_setattr) | TEST_P(TimeGran, timestamps_during_setattr) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_file.txt"; | const char FULLPATH[] = "mountpoint/some_file.txt"; | ||||
const char RELPATH[] = "some_file.txt"; | const char RELPATH[] = "some_file.txt"; | ||||
const char *CONTENTS = "abcdefgh"; | const char *CONTENTS = "abcdefgh"; | ||||
Show All 19 Lines | ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { | ||||
out.body.attr.attr.ino = ino; | out.body.attr.attr.ino = ino; | ||||
out.body.attr.attr.mode = S_IFREG | newmode; | out.body.attr.attr.mode = S_IFREG | newmode; | ||||
}))); | }))); | ||||
fd = open(FULLPATH, O_RDWR); | fd = open(FULLPATH, O_RDWR); | ||||
EXPECT_LE(0, fd) << strerror(errno); | EXPECT_LE(0, fd) << strerror(errno); | ||||
ASSERT_EQ(bufsize, write(fd, CONTENTS, bufsize)) << strerror(errno); | ASSERT_EQ(bufsize, write(fd, CONTENTS, bufsize)) << strerror(errno); | ||||
ASSERT_EQ(0, fchmod(fd, newmode)) << strerror(errno); | ASSERT_EQ(0, fchmod(fd, newmode)) << strerror(errno); | ||||
leak(fd); | |||||
} | } | ||||
INSTANTIATE_TEST_CASE_P(RA, TimeGran, Range(0u, 10u)); | INSTANTIATE_TEST_CASE_P(RA, TimeGran, Range(0u, 10u)); | ||||
/* | /* | ||||
* Without direct_io, writes should be committed to cache | * Without direct_io, writes should be committed to cache | ||||
*/ | */ | ||||
TEST_F(Write, writethrough) | TEST_F(Write, writethrough) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_file.txt"; | const char FULLPATH[] = "mountpoint/some_file.txt"; | ||||
const char RELPATH[] = "some_file.txt"; | const char RELPATH[] = "some_file.txt"; | ||||
const char *CONTENTS = "abcdefgh"; | const char *CONTENTS = "abcdefgh"; | ||||
uint64_t ino = 42; | uint64_t ino = 42; | ||||
int fd; | int fd; | ||||
ssize_t bufsize = strlen(CONTENTS); | ssize_t bufsize = strlen(CONTENTS); | ||||
char readbuf[bufsize]; | uint8_t readbuf[bufsize]; | ||||
expect_lookup(RELPATH, ino, 0); | expect_lookup(RELPATH, ino, 0); | ||||
expect_open(ino, 0, 1); | expect_open(ino, 0, 1); | ||||
expect_write(ino, 0, bufsize, bufsize, CONTENTS); | expect_write(ino, 0, bufsize, bufsize, CONTENTS); | ||||
fd = open(FULLPATH, O_RDWR); | fd = open(FULLPATH, O_RDWR); | ||||
EXPECT_LE(0, fd) << strerror(errno); | EXPECT_LE(0, fd) << strerror(errno); | ||||
Show All 34 Lines |
why empty space for some but not all?