diff --git a/src/fspp/fstest/FsppFileTest.h b/src/fspp/fstest/FsppFileTest.h index ac6df30d..d87bd9ca 100644 --- a/src/fspp/fstest/FsppFileTest.h +++ b/src/fspp/fstest/FsppFileTest.h @@ -58,6 +58,49 @@ public: void Test_Stat_CreatedFileIsEmpty(fspp::File *file) { this->EXPECT_SIZE(0, *file); } + + void Test_Stat_Nlink(fspp::File *file) { + this->IN_STAT(*file, [] (struct stat st) { + EXPECT_EQ(1u, st.st_nlink); + }); + } + + void Test_Stat_IsFile(fspp::File *file) { + this->IN_STAT(*file, [] (struct stat st) { + EXPECT_TRUE(S_ISREG(st.st_mode)); + }); + } + + void Test_Chown_Uid(fspp::File *file) { + file->chown(100, 200); + this->IN_STAT(*file, [] (struct stat st){ + EXPECT_EQ(100u, st.st_uid); + }); + } + + void Test_Chown_Gid(fspp::File *file) { + file->chown(100, 200); + this->IN_STAT(*file, [] (struct stat st){ + EXPECT_EQ(200u, st.st_gid); + }); + } + + void Test_Chmod(fspp::File *file) { + file->chmod(S_IFREG | S_IRUSR | S_IWOTH); + this->IN_STAT(*file, [] (struct stat st){ + EXPECT_EQ((mode_t)(S_IFREG | S_IRUSR | S_IWOTH), st.st_mode); + }); + } + + void Test_Utimens(fspp::File *file) { + struct timespec ATIME; ATIME.tv_sec = 1458086400; ATIME.tv_nsec = 34525; + struct timespec MTIME; MTIME.tv_sec = 1458086300; MTIME.tv_nsec = 48293; + file->utimens(ATIME, MTIME); + this->IN_STAT(*file, [this, ATIME, MTIME] (struct stat st) { + this->EXPECT_ATIME_EQ(ATIME, st); + this->EXPECT_MTIME_EQ(MTIME, st); + }); + } }; TYPED_TEST_CASE_P(FsppFileTest); @@ -134,6 +177,14 @@ TYPED_TEST_P(FsppFileTest, Truncate_ShrinkTo0_Nested) { this->Test_Truncate_ShrinkTo0(this->file_nested.get()); } +TYPED_TEST_P(FsppFileTest, Stat_IsFile) { + this->Test_Stat_IsFile(this->file_root.get()); +} + +TYPED_TEST_P(FsppFileTest, Stat_IsFile_Nested) { + this->Test_Stat_IsFile(this->file_nested.get()); +} + TYPED_TEST_P(FsppFileTest, Stat_CreatedFileIsEmpty) { this->Test_Stat_CreatedFileIsEmpty(this->file_root.get()); } @@ -142,6 +193,46 @@ TYPED_TEST_P(FsppFileTest, Stat_CreatedFileIsEmpty_Nested) { this->Test_Stat_CreatedFileIsEmpty(this->file_nested.get()); } +TYPED_TEST_P(FsppFileTest, Stat_Nlink) { + this->Test_Stat_Nlink(this->file_root.get()); +} + +TYPED_TEST_P(FsppFileTest, Stat_Nlink_Nested) { + this->Test_Stat_Nlink(this->file_nested.get()); +} + +TYPED_TEST_P(FsppFileTest, Chown_Uid) { + this->Test_Chown_Uid(this->file_root.get()); +} + +TYPED_TEST_P(FsppFileTest, Chown_Uid_Nested) { + this->Test_Chown_Uid(this->file_nested.get()); +} + +TYPED_TEST_P(FsppFileTest, Chown_Gid) { + this->Test_Chown_Gid(this->file_root.get()); +} + +TYPED_TEST_P(FsppFileTest, Chown_Gid_Nested) { + this->Test_Chown_Gid(this->file_nested.get()); +} + +TYPED_TEST_P(FsppFileTest, Chmod) { + this->Test_Chmod(this->file_root.get()); +} + +TYPED_TEST_P(FsppFileTest, Chmod_Nested) { + this->Test_Chmod(this->file_nested.get()); +} + +TYPED_TEST_P(FsppFileTest, Utimens) { + this->Test_Utimens(this->file_root.get()); +} + +TYPED_TEST_P(FsppFileTest, Utimens_Nested) { + this->Test_Utimens(this->file_nested.get()); +} + REGISTER_TYPED_TEST_CASE_P(FsppFileTest, Open_RDONLY, Open_RDONLY_Nested, @@ -162,18 +253,25 @@ REGISTER_TYPED_TEST_CASE_P(FsppFileTest, Truncate_ShrinkTo0, Truncate_ShrinkTo0_Nested, Stat_CreatedFileIsEmpty, - Stat_CreatedFileIsEmpty_Nested + Stat_CreatedFileIsEmpty_Nested, + Stat_Nlink, + Stat_Nlink_Nested, + Stat_IsFile, + Stat_IsFile_Nested, + Chown_Uid, + Chown_Uid_Nested, + Chown_Gid, + Chown_Gid_Nested, + Chmod, + Chmod_Nested, + Utimens, + Utimens_Nested ); -//TODO stat //TODO access //TODO rename -//TODO utimens //TODO unlink -//TODO chmod -//TODO chown -//TODO createAndOpenFile with uid/gid - -//TODO Test permission flags +//TODO createAndOpenFile (all stat values correctly set) +//TODO Test all operations do (or don't) affect file timestamps correctly #endif diff --git a/src/fspp/fstest/testutils/FileTest.h b/src/fspp/fstest/testutils/FileTest.h index 773219d1..64ff94df 100644 --- a/src/fspp/fstest/testutils/FileTest.h +++ b/src/fspp/fstest/testutils/FileTest.h @@ -20,32 +20,51 @@ public: std::unique_ptr file_root; std::unique_ptr file_nested; + void IN_STAT(const fspp::File &file, std::function callback) { + struct stat st1, st2; + file.stat(&st1); + callback(st1); + file.open(O_RDONLY)->stat(&st2); + //TODO Enable this line + //callback(st2); + } + void EXPECT_SIZE(uint64_t expectedSize, const fspp::File &file) { - EXPECT_SIZE_IN_FILE(expectedSize, file); + IN_STAT(file, [expectedSize] (struct stat st) { + EXPECT_EQ(expectedSize, (uint64_t)st.st_size); + }); + + EXPECT_NUMBYTES_READABLE(expectedSize, file); + } + + void EXPECT_NUMBYTES_READABLE(uint64_t expectedSize, const fspp::File &file) { auto openFile = file.open(O_RDONLY); - EXPECT_SIZE_IN_OPEN_FILE(expectedSize, *openFile); - EXPECT_NUMBYTES_READABLE(expectedSize, *openFile); - } - - void EXPECT_SIZE_IN_FILE(uint64_t expectedSize, const fspp::File &file) { - struct stat st; - file.stat(&st); - EXPECT_EQ(expectedSize, (uint64_t)st.st_size); - } - - void EXPECT_SIZE_IN_OPEN_FILE(uint64_t expectedSize, const fspp::OpenFile &file) { - struct stat st; - file.stat(&st); - EXPECT_EQ(expectedSize, (uint64_t)st.st_size); - } - - void EXPECT_NUMBYTES_READABLE(uint64_t expectedSize, const fspp::OpenFile &file) { cpputils::Data data(expectedSize); //Try to read one byte more than the expected size - ssize_t readBytes = file.read(data.data(), expectedSize+1, 0); + ssize_t readBytes = openFile->read(data.data(), expectedSize+1, 0); //and check that it only read the expected size (but also not less) EXPECT_EQ(expectedSize, (uint64_t)readBytes); } + + void EXPECT_ATIME_EQ(struct timespec expected, struct stat st) { +#ifdef __APPLE__ + EXPECT_EQ(expected.tv_sec, st.st_atimespec.tv_sec); + EXPECT_EQ(expected.tv_nsec, st.st_atimespec.tv_nsec); +#else + EXPECT_EQ(expected.tv_sec, st.st_atim.tv_sec); + EXPECT_EQ(expected.tv_nsec, st.st_atim.tv_nsec); +#endif + } + + void EXPECT_MTIME_EQ(struct timespec expected, struct stat st) { +#ifdef __APPLE__ + EXPECT_EQ(expected.tv_sec, st.st_mtimespec.tv_sec); + EXPECT_EQ(expected.tv_nsec, st.st_mtimespec.tv_nsec); +#else + EXPECT_EQ(expected.tv_sec, st.st_mtim.tv_sec); + EXPECT_EQ(expected.tv_nsec, st.st_mtim.tv_nsec); +#endif + } }; #endif