fspp::Dir, fspp::File and fspp::Symlink don't inherit from fspp::Node anymore. This allows file systems to return a generic fspp::Node instead of a concrete subclass when the operation doesn't need to know what type of node it is.

This commit is contained in:
Sebastian Messmer 2017-01-21 19:16:35 +00:00
parent 002b1a2e23
commit e37d84a3d6
32 changed files with 938 additions and 355 deletions

2
.gitignore vendored
View File

@ -7,3 +7,5 @@ umltest.status
src/gitversion/*.pyc
src/gitversion/__pycache__
cmake-build-debug
cmake-build-release

View File

@ -66,7 +66,44 @@ Key CryDevice::CreateRootBlobAndReturnKey() {
return rootBlob->key();
}
optional<unique_ref<fspp::File>> CryDevice::LoadFile(const bf::path &path) {
auto loaded = Load(path);
if (loaded == none) {
return none;
}
auto file = cpputils::dynamic_pointer_move<fspp::File>(*loaded);
if (file == none) {
throw fspp::fuse::FuseErrnoException(EISDIR); // TODO Also EISDIR if it is a symlink?
}
return std::move(*file);
}
optional<unique_ref<fspp::Dir>> CryDevice::LoadDir(const bf::path &path) {
auto loaded = Load(path);
if (loaded == none) {
return none;
}
auto dir = cpputils::dynamic_pointer_move<fspp::Dir>(*loaded);
if (dir == none) {
throw fspp::fuse::FuseErrnoException(ENOTDIR);
}
return std::move(*dir);
}
optional<unique_ref<fspp::Symlink>> CryDevice::LoadSymlink(const bf::path &path) {
auto loaded = Load(path);
if (loaded == none) {
return none;
}
auto lnk = cpputils::dynamic_pointer_move<fspp::Symlink>(*loaded);
if (lnk == none) {
throw fspp::fuse::FuseErrnoException(ENOTDIR); // TODO ENOTDIR although it is a symlink?
}
return std::move(*lnk);
}
optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
// TODO Is it faster to not let CryFile/CryDir/CryDevice inherit from CryNode and loading CryNode without having to know what it is?
// TODO Split into smaller functions
ASSERT(path.is_absolute(), "Non absolute path given");

View File

@ -35,6 +35,9 @@ public:
void onFsAction(std::function<void()> callback);
boost::optional<cpputils::unique_ref<fspp::Node>> Load(const boost::filesystem::path &path) override;
boost::optional<cpputils::unique_ref<fspp::File>> LoadFile(const boost::filesystem::path &path) override;
boost::optional<cpputils::unique_ref<fspp::Dir>> LoadDir(const boost::filesystem::path &path) override;
boost::optional<cpputils::unique_ref<fspp::Symlink>> LoadSymlink(const boost::filesystem::path &path) override;
void callFsActionCallbacks() const;

View File

@ -8,7 +8,7 @@
namespace cryfs {
class CryDir final: public fspp::Dir, CryNode {
class CryDir final: public fspp::Dir, public CryNode {
public:
CryDir(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::Key &key);
~CryDir();

View File

@ -9,7 +9,7 @@
namespace cryfs {
class CryFile final: public fspp::File, CryNode {
class CryFile final: public fspp::File, public CryNode {
public:
CryFile(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::Key &key);
~CryFile();

View File

@ -10,7 +10,7 @@
namespace cryfs {
class CryNode: public virtual fspp::Node {
class CryNode: public fspp::Node {
public:
virtual ~CryNode();

View File

@ -9,7 +9,7 @@
namespace cryfs {
class CrySymlink final: public fspp::Symlink, CryNode {
class CrySymlink final: public fspp::Symlink, public CryNode {
public:
CrySymlink(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::Key &key);
~CrySymlink();

View File

@ -8,6 +8,9 @@
namespace fspp {
class Node;
class File;
class Dir;
class Symlink;
class Device {
public:
@ -15,6 +18,14 @@ public:
virtual void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) = 0;
virtual boost::optional<cpputils::unique_ref<Node>> Load(const boost::filesystem::path &path) = 0;
//TODO Test default implementation (Device.cpp)
//TODO Test client implementation (fstest)
//TODO When it exists but is wrong node type, don't throw exception, but return this somehow (or at least throw specific exception, not just FuseErrnoException)
virtual boost::optional<cpputils::unique_ref<File>> LoadFile(const boost::filesystem::path &path) = 0;
virtual boost::optional<cpputils::unique_ref<Dir>> LoadDir(const boost::filesystem::path &path) = 0;
virtual boost::optional<cpputils::unique_ref<Symlink>> LoadSymlink(const boost::filesystem::path &path) = 0;
};
}

View File

@ -2,15 +2,15 @@
#ifndef MESSMER_FSPP_FSINTERFACE_DIR_H_
#define MESSMER_FSPP_FSINTERFACE_DIR_H_
#include "Node.h"
#include <cpp-utils/pointer/unique_ref.h>
#include <string>
#include <boost/filesystem/path.hpp>
namespace fspp {
class Device;
class OpenFile;
class Dir: public virtual Node {
class Dir {
public:
virtual ~Dir() {}

View File

@ -2,14 +2,13 @@
#ifndef MESSMER_FSPP_FSINTERFACE_FILE_H_
#define MESSMER_FSPP_FSINTERFACE_FILE_H_
#include "Node.h"
#include <cpp-utils/pointer/unique_ref.h>
namespace fspp {
class Device;
class OpenFile;
class File: public virtual Node {
class File {
public:
virtual ~File() {}

View File

@ -2,14 +2,14 @@
#ifndef MESSMER_FSPP_FSINTERFACE_SYMLINK_H_
#define MESSMER_FSPP_FSINTERFACE_SYMLINK_H_
#include "Node.h"
#include <cpp-utils/pointer/unique_ref.h>
#include <string>
#include <boost/filesystem/path.hpp>
namespace fspp {
class Device;
class Symlink: public virtual Node {
class Symlink {
public:
virtual ~Symlink() {}

View File

@ -18,7 +18,8 @@
#include "FsppOpenFileTest_Timestamps.h"
#define FSPP_ADD_FILESYTEM_TESTS(FS_NAME, FIXTURE) \
INSTANTIATE_TYPED_TEST_CASE_P(FS_NAME, FsppDeviceTest, FIXTURE); \
INSTANTIATE_TYPED_TEST_CASE_P(FS_NAME, FsppDeviceTest_One, FIXTURE); \
INSTANTIATE_TYPED_TEST_CASE_P(FS_NAME, FsppDeviceTest_Two, FIXTURE); \
INSTANTIATE_NODE_TEST_CASE( FS_NAME, FsppDeviceTest_Timestamps, FIXTURE); \
INSTANTIATE_TYPED_TEST_CASE_P(FS_NAME, FsppDirTest, FIXTURE); \
INSTANTIATE_TYPED_TEST_CASE_P(FS_NAME, FsppDirTest_Timestamps, FIXTURE); \

View File

@ -2,104 +2,481 @@
#ifndef MESSMER_FSPP_FSTEST_FSPPDEVICETEST_H_
#define MESSMER_FSPP_FSTEST_FSPPDEVICETEST_H_
#include <fspp/fuse/FuseErrnoException.h>
template<class ConcreteFileSystemTestFixture>
class FsppDeviceTest: public FileSystemTest<ConcreteFileSystemTestFixture> {
public:
void InitDirStructure() {
this->LoadDir("/")->createAndOpenFile("myfile", this->MODE_PUBLIC, 0, 0);
this->LoadDir("/")->createSymlink("mysymlink", "/symlink/target", 0, 0);
this->LoadDir("/")->createDir("mydir", this->MODE_PUBLIC, 0, 0);
this->LoadDir("/")->createDir("myemptydir", this->MODE_PUBLIC, 0, 0);
this->LoadDir("/mydir")->createAndOpenFile("myfile", this->MODE_PUBLIC, 0, 0);
this->LoadDir("/mydir")->createAndOpenFile("myfile2", this->MODE_PUBLIC, 0, 0);
this->LoadDir("/mydir")->createSymlink("mysymlink", "/symlink/target", 0, 0);
this->LoadDir("/mydir")->createDir("mysubdir", this->MODE_PUBLIC, 0, 0);
this->LoadDir("/mydir/mysubdir")->createAndOpenFile("myfile", this->MODE_PUBLIC, 0, 0);
this->LoadDir("/mydir/mysubdir")->createSymlink("mysymlink", "/symlink/target", 0, 0);
this->LoadDir("/mydir/mysubdir")->createDir("mysubsubdir", this->MODE_PUBLIC, 0, 0);
}
};
TYPED_TEST_CASE_P(FsppDeviceTest);
//Unfortunately, googletest only allows 50 test cases per REGISTER_TYPED_TEST_CASE_P, so we have to split it.
template<class ConcreteFileSystemTestFixture> class FsppDeviceTest_One: public FsppDeviceTest<ConcreteFileSystemTestFixture> {};
template<class ConcreteFileSystemTestFixture> class FsppDeviceTest_Two: public FsppDeviceTest<ConcreteFileSystemTestFixture> {};
TYPED_TEST_P(FsppDeviceTest, InitFilesystem) {
TYPED_TEST_CASE_P(FsppDeviceTest_One);
TYPED_TEST_CASE_P(FsppDeviceTest_Two);
TYPED_TEST_P(FsppDeviceTest_One, InitFilesystem) {
//fixture->createDevice() is called in the FileSystemTest constructor
}
TYPED_TEST_P(FsppDeviceTest, LoadRootDir) {
TYPED_TEST_P(FsppDeviceTest_One, LoadRootDir_Load) {
auto node = this->Load("/");
this->EXPECT_IS_DIR(node);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadRootDir_LoadDir) {
this->LoadDir("/");
}
TYPED_TEST_P(FsppDeviceTest, LoadFileFromRootDir) {
TYPED_TEST_P(FsppDeviceTest_One, LoadRootDir_LoadFile) {
EXPECT_THROW(
this->LoadFile("/"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadRootDir_LoadSymlink) {
EXPECT_THROW(
this->LoadSymlink("/"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadFileFromRootDir_Load) {
this->InitDirStructure();
auto node = this->Load("/myfile");
this->EXPECT_IS_FILE(node);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadFileFromRootDir_LoadFile) {
this->InitDirStructure();
this->LoadFile("/myfile");
}
TYPED_TEST_P(FsppDeviceTest, LoadDirFromRootDir) {
TYPED_TEST_P(FsppDeviceTest_One, LoadFileFromRootDir_LoadDir) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadDir("/myfile"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadFileFromRootDir_LoadSymlink) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadSymlink("/myfile"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadDirFromRootDir_Load) {
this->InitDirStructure();
auto node = this->Load("/mydir");
this->EXPECT_IS_DIR(node);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadDirFromRootDir_LoadDir) {
this->InitDirStructure();
this->LoadDir("/mydir");
}
TYPED_TEST_P(FsppDeviceTest, LoadNonexistingFromEmptyRootDir) {
EXPECT_EQ(boost::none, this->device->Load("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest, LoadNonexistingFromRootDir) {
TYPED_TEST_P(FsppDeviceTest_One, LoadDirFromRootDir_LoadFile) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->Load("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest, LoadNonexistingFromNonexistingDir) {
this->InitDirStructure();
//TODO Change as soon as we have a concept of how to handle filesystem errors in the interface
EXPECT_ANY_THROW(
this->device->Load("/nonexisting/nonexisting2")
EXPECT_THROW(
this->LoadFile("/mydir"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest, LoadNonexistingFromExistingDir) {
TYPED_TEST_P(FsppDeviceTest_One, LoadDirFromRootDir_LoadSymlink) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadSymlink("/mydir"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadSymlinkFromRootDir_Load) {
this->InitDirStructure();
auto node = this->Load("/mysymlink");
this->EXPECT_IS_SYMLINK(node);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadSymlinkFromRootDir_LoadSymlink) {
this->InitDirStructure();
this->LoadSymlink("/mysymlink");
}
TYPED_TEST_P(FsppDeviceTest_One, LoadSymlinkFromRootDir_LoadFile) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadFile("/mysymlink"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadSymlinkFromRootDir_LoadDir) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadDir("/mysymlink"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromEmptyRootDir_Load) {
EXPECT_EQ(boost::none, this->device->Load("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromEmptyRootDir_LoadDir) {
EXPECT_EQ(boost::none, this->device->LoadDir("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromEmptyRootDir_LoadFile) {
EXPECT_EQ(boost::none, this->device->LoadFile("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromEmptyRootDir_LoadSymlink) {
EXPECT_EQ(boost::none, this->device->LoadSymlink("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromRootDir_Load) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->Load("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromRootDir_LoadDir) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->LoadDir("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromRootDir_LoadFile) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->LoadFile("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromRootDir_LoadSymlink) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->LoadSymlink("/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromNonexistingDir_Load) {
this->InitDirStructure();
//TODO Change as soon as we have a concept of how to handle filesystem errors in the interface
EXPECT_ANY_THROW(
this->device->Load("/nonexisting/nonexisting2")
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromNonexistingDir_LoadDir) {
this->InitDirStructure();
//TODO Change as soon as we have a concept of how to handle filesystem errors in the interface
EXPECT_ANY_THROW(
this->device->LoadDir("/nonexisting/nonexisting2")
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromNonexistingDir_LoadFile) {
this->InitDirStructure();
//TODO Change as soon as we have a concept of how to handle filesystem errors in the interface
EXPECT_ANY_THROW(
this->device->LoadFile("/nonexisting/nonexisting2")
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromNonexistingDir_LoadSymlink) {
this->InitDirStructure();
//TODO Change as soon as we have a concept of how to handle filesystem errors in the interface
EXPECT_ANY_THROW(
this->device->LoadSymlink("/nonexisting/nonexisting2")
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromExistingDir_Load) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->Load("/mydir/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest, LoadNonexistingFromExistingEmptyDir) {
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromExistingDir_LoadDir) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->LoadDir("/mydir/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromExistingDir_LoadFile) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->LoadFile("/mydir/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromExistingDir_LoadSymlink) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->LoadSymlink("/mydir/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromExistingEmptyDir_Load) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->Load("/myemptydir/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest, LoadFileFromDir_Nesting1) {
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromExistingEmptyDir_LoadDir) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->LoadDir("/myemptydir/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromExistingEmptyDir_LoadFile) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->LoadFile("/myemptydir/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadNonexistingFromExistingEmptyDir_LoadSymlink) {
this->InitDirStructure();
EXPECT_EQ(boost::none, this->device->LoadSymlink("/myemptydir/nonexisting"));
}
TYPED_TEST_P(FsppDeviceTest_One, LoadFileFromDir_Nesting1_Load) {
this->InitDirStructure();
auto node = this->Load("/mydir/myfile");
this->EXPECT_IS_FILE(node);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadFileFromDir_Nesting1_LoadFile) {
this->InitDirStructure();
this->LoadFile("/mydir/myfile");
}
TYPED_TEST_P(FsppDeviceTest, LoadDirFromDir_Nesting1) {
TYPED_TEST_P(FsppDeviceTest_One, LoadFileFromDir_Nesting1_LoadDir) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadDir("/mydir/myfile"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadFileFromDir_Nesting1_LoadSymlink) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadSymlink("/mydir/myfile"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadDirFromDir_Nesting1_Load) {
this->InitDirStructure();
auto node = this->Load("/mydir/mysubdir");
this->EXPECT_IS_DIR(node);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadDirFromDir_Nesting1_LoadDir) {
this->InitDirStructure();
this->LoadDir("/mydir/mysubdir");
}
TYPED_TEST_P(FsppDeviceTest, LoadFileFromDir_Nesting2) {
TYPED_TEST_P(FsppDeviceTest_One, LoadDirFromDir_Nesting1_LoadFile) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadFile("/mydir/mysubdir"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadDirFromDir_Nesting1_LoadSymlink) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadSymlink("/mydir/mysubdir"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadSymlinkFromDir_Nesting1_Load) {
this->InitDirStructure();
auto node = this->Load("/mydir/mysymlink");
this->EXPECT_IS_SYMLINK(node);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadSymlinkFromDir_Nesting1_LoadSymlink) {
this->InitDirStructure();
this->LoadSymlink("/mydir/mysymlink");
}
TYPED_TEST_P(FsppDeviceTest_One, LoadSymlinkFromDir_Nesting1_LoadFile) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadFile("/mydir/mysymlink"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_One, LoadSymlinkFromDir_Nesting1_LoadDir) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadDir("/mydir/mysymlink"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadFileFromDir_Nesting2_Load) {
this->InitDirStructure();
auto node = this->Load("/mydir/mysubdir/myfile");
this->EXPECT_IS_FILE(node);
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadFileFromDir_Nesting2_LoadFile) {
this->InitDirStructure();
this->LoadFile("/mydir/mysubdir/myfile");
}
TYPED_TEST_P(FsppDeviceTest, LoadDirFromDir_Nesting2) {
TYPED_TEST_P(FsppDeviceTest_Two, LoadFileFromDir_Nesting2_LoadDir) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadDir("/mydir/mysubdir/myfile"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadFileFromDir_Nesting2_LoadSymlink) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadSymlink("/mydir/mysubdir/myfile"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadDirFromDir_Nesting2_Load) {
this->InitDirStructure();
auto node = this->Load("/mydir/mysubdir/mysubsubdir");
this->EXPECT_IS_DIR(node);
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadDirFromDir_Nesting2_LoadDir) {
this->InitDirStructure();
this->LoadDir("/mydir/mysubdir/mysubsubdir");
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadDirFromDir_Nesting2_LoadFile) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadFile("/mydir/mysubdir/mysubsubdir"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadDirFromDir_Nesting2_LoadSymlink) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadSymlink("/mydir/mysubdir/mysubsubdir"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadSymlinkFromDir_Nesting2_Load) {
this->InitDirStructure();
auto node = this->Load("/mydir/mysubdir/mysymlink");
this->EXPECT_IS_SYMLINK(node);
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadSymlinkFromDir_Nesting2_LoadSymlink) {
this->InitDirStructure();
this->LoadSymlink("/mydir/mysubdir/mysymlink");
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadSymlinkFromDir_Nesting2_LoadFile) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadFile("/mydir/mysubdir/mysymlink"),
fspp::fuse::FuseErrnoException
);
}
TYPED_TEST_P(FsppDeviceTest_Two, LoadSymlinkFromDir_Nesting2_LoadDir) {
this->InitDirStructure();
EXPECT_THROW(
this->LoadDir("/mydir/mysubdir/mysymlink"),
fspp::fuse::FuseErrnoException
);
}
//TODO Test statfs
REGISTER_TYPED_TEST_CASE_P(FsppDeviceTest,
REGISTER_TYPED_TEST_CASE_P(FsppDeviceTest_One,
InitFilesystem,
LoadRootDir,
LoadFileFromRootDir,
LoadDirFromRootDir,
LoadNonexistingFromEmptyRootDir,
LoadNonexistingFromRootDir,
LoadNonexistingFromNonexistingDir,
LoadNonexistingFromExistingDir,
LoadNonexistingFromExistingEmptyDir,
LoadFileFromDir_Nesting1,
LoadDirFromDir_Nesting1,
LoadFileFromDir_Nesting2,
LoadDirFromDir_Nesting2
LoadRootDir_Load,
LoadRootDir_LoadDir,
LoadRootDir_LoadFile,
LoadRootDir_LoadSymlink,
LoadFileFromRootDir_Load,
LoadFileFromRootDir_LoadFile,
LoadFileFromRootDir_LoadDir,
LoadFileFromRootDir_LoadSymlink,
LoadDirFromRootDir_Load,
LoadDirFromRootDir_LoadDir,
LoadDirFromRootDir_LoadFile,
LoadDirFromRootDir_LoadSymlink,
LoadSymlinkFromRootDir_Load,
LoadSymlinkFromRootDir_LoadSymlink,
LoadSymlinkFromRootDir_LoadFile,
LoadSymlinkFromRootDir_LoadDir,
LoadNonexistingFromEmptyRootDir_Load,
LoadNonexistingFromEmptyRootDir_LoadDir,
LoadNonexistingFromEmptyRootDir_LoadFile,
LoadNonexistingFromEmptyRootDir_LoadSymlink,
LoadNonexistingFromRootDir_Load,
LoadNonexistingFromRootDir_LoadDir,
LoadNonexistingFromRootDir_LoadFile,
LoadNonexistingFromRootDir_LoadSymlink,
LoadNonexistingFromNonexistingDir_Load,
LoadNonexistingFromNonexistingDir_LoadDir,
LoadNonexistingFromNonexistingDir_LoadFile,
LoadNonexistingFromNonexistingDir_LoadSymlink,
LoadNonexistingFromExistingDir_Load,
LoadNonexistingFromExistingDir_LoadDir,
LoadNonexistingFromExistingDir_LoadFile,
LoadNonexistingFromExistingDir_LoadSymlink,
LoadNonexistingFromExistingEmptyDir_Load,
LoadNonexistingFromExistingEmptyDir_LoadDir,
LoadNonexistingFromExistingEmptyDir_LoadFile,
LoadNonexistingFromExistingEmptyDir_LoadSymlink,
LoadFileFromDir_Nesting1_Load,
LoadFileFromDir_Nesting1_LoadFile,
LoadFileFromDir_Nesting1_LoadDir,
LoadFileFromDir_Nesting1_LoadSymlink,
LoadDirFromDir_Nesting1_Load,
LoadDirFromDir_Nesting1_LoadDir,
LoadDirFromDir_Nesting1_LoadFile,
LoadDirFromDir_Nesting1_LoadSymlink,
LoadSymlinkFromDir_Nesting1_Load,
LoadSymlinkFromDir_Nesting1_LoadSymlink,
LoadSymlinkFromDir_Nesting1_LoadFile,
LoadSymlinkFromDir_Nesting1_LoadDir
);
REGISTER_TYPED_TEST_CASE_P(FsppDeviceTest_Two,
LoadFileFromDir_Nesting2_Load,
LoadFileFromDir_Nesting2_LoadFile,
LoadFileFromDir_Nesting2_LoadDir,
LoadFileFromDir_Nesting2_LoadSymlink,
LoadDirFromDir_Nesting2_Load,
LoadDirFromDir_Nesting2_LoadDir,
LoadDirFromDir_Nesting2_LoadFile,
LoadDirFromDir_Nesting2_LoadSymlink,
LoadSymlinkFromDir_Nesting2_Load,
LoadSymlinkFromDir_Nesting2_LoadSymlink,
LoadSymlinkFromDir_Nesting2_LoadFile,
LoadSymlinkFromDir_Nesting2_LoadDir
);
//TODO Missing tests: LoadSymlink
#endif

View File

@ -5,21 +5,21 @@
#include "testutils/TimestampTestUtils.h"
template<class ConcreteFileSystemTestFixture>
class FsppDeviceTest_Timestamps: public FsppNodeTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils {
class FsppDeviceTest_Timestamps: public FsppNodeTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils<ConcreteFileSystemTestFixture> {
public:
void Test_Load_While_Loaded() {
auto node = this->CreateNode("/mynode");
auto operation = [this, &node] () {
this->device->Load("/mynode");
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mynode", operation, {this->ExpectDoesntUpdateAnyTimestamps});
}
void Test_Load_While_Not_Loaded() {
struct stat oldStat;
{
auto node = this->CreateNode("/mynode");
oldStat = stat(*node);
oldStat = this->stat(*node);
this->ensureNodeTimestampsAreOld(oldStat);
}
@ -28,7 +28,7 @@ public:
auto node = this->device->Load("/mynode");
//Test that timestamps didn't change
struct stat newStat = stat(*node.value());
struct stat newStat = this->stat(*node.value());
EXPECT_EQ(oldStat.st_atim, newStat.st_atim);
EXPECT_EQ(oldStat.st_mtim, newStat.st_mtim);
EXPECT_EQ(oldStat.st_ctim, newStat.st_ctim);

View File

@ -163,6 +163,7 @@ TYPED_TEST_P(FsppDirTest, Children_Nested2_LargerStructure) {
TYPED_TEST_P(FsppDirTest, CreateAndOpenFile_InEmptyRoot) {
this->LoadDir("/")->createAndOpenFile("myfile", this->MODE_PUBLIC, 0, 0);
this->LoadFile("/myfile");
this->Load("/myfile"); // Test that we can also load the file node
}
TYPED_TEST_P(FsppDirTest, CreateAndOpenFile_InNonemptyRoot) {
@ -206,6 +207,7 @@ TYPED_TEST_P(FsppDirTest, CreateAndOpenFile_AlreadyExisting) {
TYPED_TEST_P(FsppDirTest, CreateDir_InEmptyRoot) {
this->LoadDir("/")->createDir("mydir", this->MODE_PUBLIC, 0, 0);
this->LoadDir("/mydir");
this->Load("/mydir"); // Test we can also load the dir node
}
TYPED_TEST_P(FsppDirTest, CreateDir_InNonemptyRoot) {

View File

@ -5,7 +5,7 @@
#include "testutils/TimestampTestUtils.h"
template<class ConcreteFileSystemTestFixture>
class FsppDirTest_Timestamps: public FileSystemTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils {
class FsppDirTest_Timestamps: public TimestampTestUtils<ConcreteFileSystemTestFixture> {
public:
};
TYPED_TEST_CASE_P(FsppDirTest_Timestamps);
@ -15,7 +15,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, createAndOpenFile) {
auto operation = [&dir] () {
dir->createAndOpenFile("childname", S_IFREG, 1000, 1000);
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}
/* TODO Re-enable this test once the root dir handles timestamps correctly
@ -24,7 +24,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, createAndOpenFile_inRootDir) {
auto operation = [&dir] () {
dir->createAndOpenFile("childname", S_IFREG, 1000, 1000);
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}*/
TYPED_TEST_P(FsppDirTest_Timestamps, createAndOpenFile_TimestampsOfCreatedFile) {
@ -32,7 +32,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, createAndOpenFile_TimestampsOfCreatedFile)
timespec lowerBound = now();
dir->createAndOpenFile("childname", S_IFREG, 1000, 1000);
timespec upperBound = now();
auto child = this->LoadFile("/mydir/childname");
auto child = this->Load("/mydir/childname");
this->EXPECT_ACCESS_TIMESTAMP_BETWEEN (lowerBound, upperBound, *child);
this->EXPECT_MODIFICATION_TIMESTAMP_BETWEEN (lowerBound, upperBound, *child);
this->EXPECT_METADATACHANGE_TIMESTAMP_BETWEEN(lowerBound, upperBound, *child);
@ -43,7 +43,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, createDir) {
auto operation = [&dir] () {
dir->createDir("childname", S_IFDIR, 1000, 1000);
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}
/* TODO Re-enable this test once the root dir handles timestamps correctly
@ -52,7 +52,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, createDir_inRootDir) {
auto operation = [&dir] () {
dir->createDir("childname", S_IFDIR, 1000, 1000);
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}*/
TYPED_TEST_P(FsppDirTest_Timestamps, createDir_TimestampsOfCreatedDir) {
@ -60,7 +60,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, createDir_TimestampsOfCreatedDir) {
timespec lowerBound = now();
dir->createDir("childname", S_IFDIR, 1000, 1000);
timespec upperBound = now();
auto child = this->LoadDir("/mydir/childname");
auto child = this->Load("/mydir/childname");
this->EXPECT_ACCESS_TIMESTAMP_BETWEEN (lowerBound, upperBound, *child);
this->EXPECT_MODIFICATION_TIMESTAMP_BETWEEN (lowerBound, upperBound, *child);
this->EXPECT_METADATACHANGE_TIMESTAMP_BETWEEN(lowerBound, upperBound, *child);
@ -71,7 +71,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, createSymlink) {
auto operation = [&dir] () {
dir->createSymlink("childname", "/target", 1000, 1000);
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}
/* TODO Re-enable this test once the root dir handles timestamps correctly
@ -80,7 +80,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, createSymlink_inRootDir) {
auto operation = [&dir] () {
dir->createSymlink("childname", "/target", 1000, 1000);
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}*/
TYPED_TEST_P(FsppDirTest_Timestamps, createSymlink_TimestampsOfCreatedSymlink) {
@ -88,7 +88,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, createSymlink_TimestampsOfCreatedSymlink) {
timespec lowerBound = now();
dir->createSymlink("childname", "/target", 1000, 1000);
timespec upperBound = now();
auto child = this->LoadSymlink("/mydir/childname");
auto child = this->Load("/mydir/childname");
this->EXPECT_ACCESS_TIMESTAMP_BETWEEN (lowerBound, upperBound, *child);
this->EXPECT_MODIFICATION_TIMESTAMP_BETWEEN (lowerBound, upperBound, *child);
this->EXPECT_METADATACHANGE_TIMESTAMP_BETWEEN(lowerBound, upperBound, *child);
@ -99,7 +99,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, children_empty) {
auto operation = [&dir] () {
dir->children();
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir", operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
}
/* TODO Re-enable this test once the root dir handles timestamps correctly
@ -108,7 +108,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, children_empty_inRootDir) {
auto operation = [&dir] () {
dir->children();
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/", operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
}*/
TYPED_TEST_P(FsppDirTest_Timestamps, children_nonempty) {
@ -117,7 +117,7 @@ TYPED_TEST_P(FsppDirTest_Timestamps, children_nonempty) {
auto operation = [&dir] () {
dir->children();
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir", operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
}
/* TODO Re-enable this test once the root dir handles timestamps correctly
@ -127,11 +127,11 @@ TYPED_TEST_P(FsppDirTest_Timestamps, children_nonempty_inRootDir) {
auto operation = [&dir] () {
dir->children();
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/", operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
}*/
template<class ConcreteFileSystemTestFixture>
class FsppDirTest_Timestamps_Entries: public FsppNodeTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils {
class FsppDirTest_Timestamps_Entries: public FsppNodeTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils<ConcreteFileSystemTestFixture> {
public:
void Test_deleteChild() {
@ -140,9 +140,11 @@ public:
auto operation = [&child]() {
child->remove();
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp,
this->ExpectUpdatesModificationTimestamp,
this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir", operation, {
this->ExpectDoesntUpdateAccessTimestamp,
this->ExpectUpdatesModificationTimestamp,
this->ExpectUpdatesMetadataTimestamp
});
}
/* TODO Re-enable this test once the root dir handles timestamps correctly
@ -152,7 +154,7 @@ public:
auto operation = [&child] () {
child->remove();
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}*/
void Test_renameChild() {
@ -161,9 +163,11 @@ public:
auto operation = [&child]() {
child->rename("/mydir/mychild");
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp,
this->ExpectUpdatesModificationTimestamp,
this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir", operation, {
this->ExpectDoesntUpdateAccessTimestamp,
this->ExpectUpdatesModificationTimestamp,
this->ExpectUpdatesMetadataTimestamp
});
}
/* TODO Re-enable this test once the root dir handles timestamps correctly
@ -173,7 +177,7 @@ public:
auto operation = [&child] () {
child->rename("/mydir/mychild");
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}*/
void Test_moveChildIn() {
@ -183,9 +187,11 @@ public:
auto operation = [&child]() {
child->rename("/mydir/mychild");
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp,
this->ExpectUpdatesModificationTimestamp,
this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir", operation, {
this->ExpectDoesntUpdateAccessTimestamp,
this->ExpectUpdatesModificationTimestamp,
this->ExpectUpdatesMetadataTimestamp
});
}
/* TODO Re-enable this test once the root dir handles timestamps correctly
@ -196,7 +202,7 @@ public:
auto operation = [&child] () {
child->rename("/mychild");
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}*/
void Test_moveChildOut() {
@ -206,9 +212,11 @@ public:
auto operation = [&child]() {
child->rename("/targetdir/mychild");
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp,
this->ExpectUpdatesModificationTimestamp,
this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir", operation, {
this->ExpectDoesntUpdateAccessTimestamp,
this->ExpectUpdatesModificationTimestamp,
this->ExpectUpdatesMetadataTimestamp
});
}
/* TODO Re-enable this test once the root dir handles timestamps correctly
@ -219,7 +227,7 @@ public:
auto operation = [&child] () {
child->rename("/targetdir/mychild");
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*dir, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
}*/
};

View File

@ -7,6 +7,8 @@
#include "testutils/FileTest.h"
//TODO Restructure. FsppFileTest tests fspp::File interface. All tests for fspp::Node interface go to a FsppNodeTest.
template<class ConcreteFileSystemTestFixture>
class FsppFileTest: public FileTest<ConcreteFileSystemTestFixture> {
public:
@ -22,65 +24,65 @@ public:
file->open(O_RDONLY);
}
void Test_Truncate_DontChange1(fspp::File *file) {
void Test_Truncate_DontChange1(fspp::File *file, fspp::Node *node) {
file->truncate(0);
this->EXPECT_SIZE(0, file);
this->EXPECT_SIZE(0, file, node);
}
void Test_Truncate_GrowTo1(fspp::File *file) {
void Test_Truncate_GrowTo1(fspp::File *file, fspp::Node *node) {
file->truncate(1);
this->EXPECT_SIZE(1, file);
this->EXPECT_SIZE(1, file, node);
}
void Test_Truncate_Grow(fspp::File *file) {
void Test_Truncate_Grow(fspp::File *file, fspp::Node *node) {
file->truncate(10*1024*1024);
this->EXPECT_SIZE(10*1024*1024, file);
this->EXPECT_SIZE(10*1024*1024, file, node);
}
void Test_Truncate_DontChange2(fspp::File *file) {
void Test_Truncate_DontChange2(fspp::File *file, fspp::Node *node) {
file->truncate(10*1024*1024);
file->truncate(10*1024*1024);
this->EXPECT_SIZE(10*1024*1024, file);
this->EXPECT_SIZE(10*1024*1024, file, node);
}
void Test_Truncate_Shrink(fspp::File *file) {
void Test_Truncate_Shrink(fspp::File *file, fspp::Node *node) {
file->truncate(10*1024*1024);
file->truncate(5*1024*1024);
this->EXPECT_SIZE(5*1024*1024, file);
this->EXPECT_SIZE(5*1024*1024, file, node);
}
void Test_Truncate_ShrinkTo0(fspp::File *file) {
void Test_Truncate_ShrinkTo0(fspp::File *file, fspp::Node *node) {
file->truncate(10*1024*1024);
file->truncate(0);
this->EXPECT_SIZE(0, file);
this->EXPECT_SIZE(0, file, node);
}
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_Uid(fspp::File *file, fspp::Node *node) {
node->chown(100, 200);
this->IN_STAT(file, node, [] (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){
void Test_Chown_Gid(fspp::File *file, fspp::Node *node) {
node->chown(100, 200);
this->IN_STAT(file, node, [] (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){
void Test_Chmod(fspp::File *file, fspp::Node *node) {
node->chmod(S_IFREG | S_IRUSR | S_IWOTH);
this->IN_STAT(file, node, [] (struct stat st){
EXPECT_EQ((mode_t)(S_IFREG | S_IRUSR | S_IWOTH), st.st_mode);
});
}
void Test_Utimens(fspp::File *file) {
void Test_Utimens(fspp::File *file, fspp::Node *node) {
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) {
node->utimens(ATIME, MTIME);
this->IN_STAT(file, node, [this, ATIME, MTIME] (struct stat st) {
this->EXPECT_ATIME_EQ(ATIME, st);
this->EXPECT_MTIME_EQ(MTIME, st);
});
@ -114,83 +116,83 @@ TYPED_TEST_P(FsppFileTest, Open_RDWR_Nested) {
}
TYPED_TEST_P(FsppFileTest, Truncate_DontChange1) {
this->Test_Truncate_DontChange1(this->file_root.get());
this->Test_Truncate_DontChange1(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_DontChange1_Nested) {
this->Test_Truncate_DontChange1(this->file_nested.get());
this->Test_Truncate_DontChange1(this->file_nested.get(), this->file_nested_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_GrowTo1) {
this->Test_Truncate_GrowTo1(this->file_root.get());
this->Test_Truncate_GrowTo1(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_GrowTo1_Nested) {
this->Test_Truncate_GrowTo1(this->file_nested.get());
this->Test_Truncate_GrowTo1(this->file_nested.get(), this->file_nested_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_Grow) {
this->Test_Truncate_Grow(this->file_root.get());
this->Test_Truncate_Grow(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_Grow_Nested) {
this->Test_Truncate_Grow(this->file_nested.get());
this->Test_Truncate_Grow(this->file_nested.get(), this->file_nested_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_DontChange2) {
this->Test_Truncate_DontChange2(this->file_root.get());
this->Test_Truncate_DontChange2(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_DontChange2_Nested) {
this->Test_Truncate_DontChange2(this->file_nested.get());
this->Test_Truncate_DontChange2(this->file_nested.get(), this->file_nested_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_Shrink) {
this->Test_Truncate_Shrink(this->file_root.get());
this->Test_Truncate_Shrink(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_Shrink_Nested) {
this->Test_Truncate_Shrink(this->file_nested.get());
this->Test_Truncate_Shrink(this->file_nested.get(), this->file_nested_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_ShrinkTo0) {
this->Test_Truncate_ShrinkTo0(this->file_root.get());
this->Test_Truncate_ShrinkTo0(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Truncate_ShrinkTo0_Nested) {
this->Test_Truncate_ShrinkTo0(this->file_nested.get());
this->Test_Truncate_ShrinkTo0(this->file_nested.get(), this->file_nested_node.get());
}
TYPED_TEST_P(FsppFileTest, Chown_Uid) {
this->Test_Chown_Uid(this->file_root.get());
this->Test_Chown_Uid(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Chown_Uid_Nested) {
this->Test_Chown_Uid(this->file_nested.get());
this->Test_Chown_Uid(this->file_nested.get(), this->file_nested_node.get());
}
TYPED_TEST_P(FsppFileTest, Chown_Gid) {
this->Test_Chown_Gid(this->file_root.get());
this->Test_Chown_Gid(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Chown_Gid_Nested) {
this->Test_Chown_Gid(this->file_nested.get());
this->Test_Chown_Gid(this->file_nested.get(), this->file_nested_node.get());
}
TYPED_TEST_P(FsppFileTest, Chmod) {
this->Test_Chmod(this->file_root.get());
this->Test_Chmod(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Chmod_Nested) {
this->Test_Chmod(this->file_nested.get());
this->Test_Chmod(this->file_nested.get(), this->file_nested_node.get());
}
TYPED_TEST_P(FsppFileTest, Utimens) {
this->Test_Utimens(this->file_root.get());
this->Test_Utimens(this->file_root.get(), this->file_root_node.get());
}
TYPED_TEST_P(FsppFileTest, Utimens_Nested) {
this->Test_Utimens(this->file_nested.get());
this->Test_Utimens(this->file_nested.get(), this->file_nested_node.get());
}
REGISTER_TYPED_TEST_CASE_P(FsppFileTest,

View File

@ -5,12 +5,12 @@
#include "testutils/TimestampTestUtils.h"
template<class ConcreteFileSystemTestFixture>
class FsppFileTest_Timestamps: public FileSystemTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils {
class FsppFileTest_Timestamps: public TimestampTestUtils<ConcreteFileSystemTestFixture> {
public:
cpputils::unique_ref<fspp::File> CreateFileWithSize(const boost::filesystem::path &path, off_t size) {
auto file = this->CreateFile(path);
file->truncate(size);
assert(stat(*file).st_size == size);
assert(this->stat(*this->Load(path)).st_size == size);
return file;
}
};
@ -21,7 +21,7 @@ TYPED_TEST_P(FsppFileTest_Timestamps, open_nomode) {
auto operation = [&file] () {
file->open(0);
};
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*file, operation, {this->ExpectDoesntUpdateAnyTimestamps});
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/myfile", operation, {this->ExpectDoesntUpdateAnyTimestamps});
}
TYPED_TEST_P(FsppFileTest_Timestamps, open_rdonly) {