diff --git a/src/fspp/impl/IdList.h b/src/fspp/impl/IdList.h index c5aaa57f..07b1f1a8 100644 --- a/src/fspp/impl/IdList.h +++ b/src/fspp/impl/IdList.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "fspp/utils/macros.h" namespace fspp { @@ -60,7 +61,11 @@ const Entry *IdList::get(int id) const { template void IdList::remove(int id) { std::lock_guard lock(_mutex); - _entries.erase(id); + auto found_iter = _entries.find(id); + if (found_iter == _entries.end()) { + throw std::out_of_range("Called IdList::remove() with an invalid ID"); + } + _entries.erase(found_iter); } } /* namespace fspp */ diff --git a/src/test/fspp/impl/FuseOpenFileListTest.cpp b/src/test/fspp/impl/FuseOpenFileListTest.cpp index 6e0a2e01..ee54f5d4 100644 --- a/src/test/fspp/impl/FuseOpenFileListTest.cpp +++ b/src/test/fspp/impl/FuseOpenFileListTest.cpp @@ -3,47 +3,162 @@ #include "fspp/impl/FuseOpenFileList.h" +#include + using std::unique_ptr; using std::make_unique; using namespace fspp; -class MyOpenFile: public OpenFile { +class MockOpenFile: public OpenFile { public: - MyOpenFile(int fileid_, int flags_) :fileid(fileid_), flags(flags_) {} - ~MyOpenFile() {} - int fileid; - int flags; + MockOpenFile(int fileid_, int flags_): fileid(fileid_), flags(flags_), destructed(false) {} + int fileid, flags; + bool destructed; - void stat(struct ::stat *) const override {} - void truncate(off_t) const override {} - int read(void *, size_t, off_t) override {return 0;} - void write(const void *, size_t, off_t) override {} - void fsync() override {} - void fdatasync() override {} + ~MockOpenFile() {destructed = true;} + + MOCK_CONST_METHOD1(stat, void(struct ::stat*)); + MOCK_CONST_METHOD1(truncate, void(off_t)); + MOCK_METHOD3(read, int(void*, size_t, off_t)); + MOCK_METHOD3(write, void(const void*, size_t, off_t)); + MOCK_METHOD0(fsync, void()); + MOCK_METHOD0(fdatasync, void()); }; -class MyFile: public File { +class MockFile: public File { public: - MyFile(int id_): id(id_) {} + MockFile(int id_): id(id_) {} int id; unique_ptr open(int flags) const override { - return make_unique(id, flags); + return make_unique(id, flags); } - - void truncate(off_t) const override {} - void unlink() override {} - void stat(struct ::stat *) const override {} - void access(int) const override {} - void rename(const boost::filesystem::path &) override {} - void utimens(const timespec[2]) override {} + MOCK_CONST_METHOD1(truncate, void(off_t)); + MOCK_METHOD0(unlink, void()); + MOCK_CONST_METHOD1(stat, void(struct ::stat*)); + MOCK_CONST_METHOD1(access, void(int)); + MOCK_METHOD1(rename, void(const boost::filesystem::path &)); + MOCK_METHOD1(utimens, void(const timespec[2])); }; -TEST(FuseOpenFileListTest, Open) { - MyFile file(3); +TEST(FuseOpenFileListTest, EmptyList1) { FuseOpenFileList list; - int id = list.open(file, 4); - EXPECT_EQ(3, dynamic_cast(list.get(id))->fileid); - EXPECT_EQ(4, dynamic_cast(list.get(id))->flags); + ASSERT_THROW(list.get(0), std::out_of_range); +} + +TEST(FuseOpenFileListTest, EmptyList2) { + FuseOpenFileList list; + ASSERT_THROW(list.get(3), std::out_of_range); +} + +TEST(FuseOpenFileListTest, InvalidId) { + FuseOpenFileList list; + int valid_id = list.open(MockFile(3), 2); + int invalid_id = valid_id + 1; + ASSERT_THROW(list.get(invalid_id), std::out_of_range); +} + +TEST(FuseOpenFileListTest, Open1AndGet) { + const int FILEID = 4; + const int FLAGS = 5; + + FuseOpenFileList list; + int id = list.open(MockFile(FILEID), FLAGS); + + MockOpenFile *openFile = dynamic_cast(list.get(id)); + + EXPECT_EQ(FILEID, openFile->fileid); + EXPECT_EQ(FLAGS, openFile->flags); +} + +TEST(FuseOpenFileListTest, Open2AndGet) { + const int FILEID1 = 4; + const int FLAGS1 = 5; + const int FILEID2 = 6; + const int FLAGS2 = 7; + + FuseOpenFileList list; + int id1 = list.open(MockFile(FILEID1), FLAGS1); + int id2 = list.open(MockFile(FILEID2), FLAGS2); + + MockOpenFile *openFile1 = dynamic_cast(list.get(id1)); + MockOpenFile *openFile2 = dynamic_cast(list.get(id2)); + + EXPECT_EQ(FILEID1, openFile1->fileid); + EXPECT_EQ(FLAGS1, openFile1->flags); + EXPECT_EQ(FILEID2, openFile2->fileid); + EXPECT_EQ(FLAGS2, openFile2->flags); +} + +TEST(FuseOpenFileListTest, Open3AndGet) { + const int FILEID1 = 4; + const int FLAGS1 = 5; + const int FILEID2 = 6; + const int FLAGS2 = 7; + const int FILEID3 = 8; + const int FLAGS3 = 9; + + FuseOpenFileList list; + int id1 = list.open(MockFile(FILEID1), FLAGS1); + int id2 = list.open(MockFile(FILEID2), FLAGS2); + int id3 = list.open(MockFile(FILEID3), FLAGS3); + + MockOpenFile *openFile1 = dynamic_cast(list.get(id1)); + MockOpenFile *openFile3 = dynamic_cast(list.get(id3)); + MockOpenFile *openFile2 = dynamic_cast(list.get(id2)); + + EXPECT_EQ(FILEID1, openFile1->fileid); + EXPECT_EQ(FLAGS1, openFile1->flags); + EXPECT_EQ(FILEID2, openFile2->fileid); + EXPECT_EQ(FLAGS2, openFile2->flags); + EXPECT_EQ(FILEID3, openFile3->fileid); + EXPECT_EQ(FLAGS3, openFile3->flags); +} + +TEST(FuseOpenFileListTest, DestructOnClose) { + FuseOpenFileList list; + int id = list.open(MockFile(3), 4); + + MockOpenFile *openFile = dynamic_cast(list.get(id)); + + EXPECT_FALSE(openFile->destructed); + list.close(id); + EXPECT_TRUE(openFile->destructed); +} + +TEST(FuseOpenFileListTest, GetClosedItemOnEmptyList) { + FuseOpenFileList list; + int id = list.open(MockFile(3), 4); + + ASSERT_NO_THROW(list.get(id)); + list.close(id); + ASSERT_THROW(list.get(id), std::out_of_range); +} + +TEST(FuseOpenFileListTest, GetClosedItemOnNonEmptyList) { + FuseOpenFileList list; + int id = list.open(MockFile(3), 4); + list.open(MockFile(5), 4); + + ASSERT_NO_THROW(list.get(id)); + list.close(id); + ASSERT_THROW(list.get(id), std::out_of_range); +} + +TEST(FuseOpenFileListTest, CloseOnEmptyList1) { + FuseOpenFileList list; + ASSERT_THROW(list.close(0), std::out_of_range); +} + +TEST(FuseOpenFileListTest, CloseOnEmptyList2) { + FuseOpenFileList list; + ASSERT_THROW(list.close(4), std::out_of_range); +} + +TEST(FuseOpenFileListTest, RemoveInvalidId) { + FuseOpenFileList list; + int valid_id = list.open(MockFile(3), 4); + int invalid_id = valid_id + 1; + ASSERT_THROW(list.close(invalid_id), std::out_of_range); } diff --git a/src/test/fspp/impl/IdListTest.cpp b/src/test/fspp/impl/IdListTest.cpp index 513593f5..111de068 100644 --- a/src/test/fspp/impl/IdListTest.cpp +++ b/src/test/fspp/impl/IdListTest.cpp @@ -45,6 +45,23 @@ TEST(IdListTest, GetRemovedItemOnNonEmptyList) { ASSERT_THROW(list.get(id), std::out_of_range); } +TEST(IdListTest, RemoveOnEmptyList1) { + IdList list; + ASSERT_THROW(list.remove(0), std::out_of_range); +} + +TEST(IdListTest, RemoveOnEmptyList2) { + IdList list; + ASSERT_THROW(list.remove(4), std::out_of_range); +} + +TEST(IdListTest, RemoveInvalidId) { + IdList list; + int valid_id = list.add(make_unique(6)); + int invalid_id = valid_id + 1; + ASSERT_THROW(list.remove(invalid_id), std::out_of_range); +} + TEST(IdListTest, Add1AndGet) { IdList list; int id6 = list.add(make_unique(6));