Merge from develop
This commit is contained in:
commit
42765c6be6
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,3 +7,5 @@ umltest.status
|
||||
|
||||
src/gitversion/*.pyc
|
||||
src/gitversion/__pycache__
|
||||
cmake-build-debug
|
||||
cmake-build-release
|
||||
|
@ -7,10 +7,6 @@ compiler:
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
matrix:
|
||||
allow_failures:
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
|
@ -7,6 +7,12 @@ New Features:
|
||||
Improvements:
|
||||
* Performance improvements
|
||||
|
||||
Version 0.9.7 (unreleased)
|
||||
--------------
|
||||
Compatibility:
|
||||
* Runs on FreeBSD
|
||||
* Works with Clang++ 3.8 (Debian experimental or newer Ubuntu systems)
|
||||
|
||||
Version 0.9.6
|
||||
---------------
|
||||
Fixed bugs:
|
||||
|
@ -54,8 +54,7 @@ Requirements
|
||||
- chrono
|
||||
- program_options
|
||||
- thread
|
||||
- Crypto++ version == 5.6.3 (including development headers)
|
||||
(not compatible to Crypto++ 5.6.4, but will be compatible with Crypto++ 5.6.5+)
|
||||
- Crypto++ version >= 5.6.3 (including development headers)
|
||||
- SSL development libraries (including development headers, e.g. libssl-dev)
|
||||
- libFUSE version >= 2.8.6 (including development headers), on Mac OS X instead install osxfuse from https://osxfuse.github.io/
|
||||
- Python >= 2.7
|
||||
@ -90,9 +89,9 @@ Build & Install
|
||||
$ sudo make install
|
||||
|
||||
You can pass the following variables to the *cmake* command (using *-Dvariablename=value*):
|
||||
- -D**CMAKE_BUILD_TYPE**=[Release|Debug]: Whether to run code optimization or add debug symbols. Default: Release
|
||||
- -D**BUILD_TESTING**=[on|off]: Whether to build the test cases (can take a long time). Default: off
|
||||
- -D**CRYFS_UPDATE_CHECKS**=off: Build a CryFS that doesn't check online for updates and security vulnerabilities.
|
||||
- **-DCMAKE_BUILD_TYPE**=[Release|Debug]: Whether to run code optimization or add debug symbols. Default: Release
|
||||
- **-DBUILD_TESTING**=[on|off]: Whether to build the test cases (can take a long time). Default: off
|
||||
- **-DCRYFS_UPDATE_CHECKS**=off: Build a CryFS that doesn't check online for updates and security vulnerabilities.
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
7
archive.sh
Executable file
7
archive.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
TAG=$1
|
||||
GPGHOMEDIR=$2
|
||||
|
||||
git archive --format=tgz "$1" > cryfs-$1.tar.gz
|
||||
gpg --homedir "$GPGHOMEDIR" --armor --detach-sign cryfs-$1.tar.gz
|
@ -39,7 +39,8 @@ if(BUILDTYPE MATCHES RELEASE AND NOT BUILD_TESTING)
|
||||
set(CPACK_PACKAGE_EXECUTABLES "cryfs" "CryFS")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "fuse")
|
||||
# Needs gnupg2 for postinst script
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "fuse, gnupg2")
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://www.cryfs.org")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "LGPLv3")
|
||||
|
@ -37,7 +37,7 @@ sources_list_dir () {
|
||||
root=$(get_apt_config "Dir")
|
||||
etc=$(get_apt_config "Dir::Etc")
|
||||
sourceparts=$(get_apt_config "Dir::Etc::sourceparts")
|
||||
echo $root$etc$sourceparts
|
||||
echo "$root/$etc/$sourceparts"
|
||||
}
|
||||
|
||||
add_repository () {
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include <cpp-utils/data/DataUtils.h>
|
||||
#include <mutex>
|
||||
#include <cpp-utils/logging/logging.h>
|
||||
#include "../../../../vendor/googletest/gtest-1.7.0/googletest/include/gtest/gtest_prod.h"
|
||||
#include "IntegrityViolationError.h"
|
||||
#include "VersionCountingBlockStore.h"
|
||||
|
||||
|
@ -12,6 +12,7 @@ set(SOURCES
|
||||
tempfile/TempDir.cpp
|
||||
network/HttpClient.cpp
|
||||
network/CurlHttpClient.cpp
|
||||
network/CurlInitializerRAII.cpp
|
||||
network/FakeHttpClient.cpp
|
||||
io/Console.cpp
|
||||
io/DontEchoStdinToStdoutRAII.cpp
|
||||
|
@ -17,7 +17,7 @@ namespace cpputils {
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
CurlHttpClient::CurlHttpClient() {
|
||||
CurlHttpClient::CurlHttpClient(): curlInitializer(), curl() {
|
||||
curl = curl_easy_init();
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "HttpClient.h"
|
||||
#include "../macros.h"
|
||||
#include <curl/curl.h>
|
||||
#include "CurlInitializerRAII.h"
|
||||
|
||||
namespace cpputils {
|
||||
|
||||
@ -17,6 +17,7 @@ namespace cpputils {
|
||||
boost::optional <std::string> get(const std::string &url, boost::optional<long> timeoutMsec = boost::none) override;
|
||||
|
||||
private:
|
||||
CurlInitializerRAII curlInitializer;
|
||||
CURL *curl;
|
||||
|
||||
static size_t write_data(void *ptr, size_t size, size_t nmemb, std::ostringstream *stream);
|
||||
|
27
src/cpp-utils/network/CurlInitializerRAII.cpp
Normal file
27
src/cpp-utils/network/CurlInitializerRAII.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "CurlInitializerRAII.h"
|
||||
|
||||
using std::mutex;
|
||||
using std::unique_lock;
|
||||
|
||||
namespace cpputils {
|
||||
|
||||
mutex CurlInitializerRAII::_mutex;
|
||||
uint32_t CurlInitializerRAII::_refcount = 0;
|
||||
|
||||
CurlInitializerRAII::CurlInitializerRAII() {
|
||||
unique_lock<mutex> lock(_mutex);
|
||||
if (0 == _refcount) {
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
}
|
||||
_refcount += 1;
|
||||
}
|
||||
|
||||
CurlInitializerRAII::~CurlInitializerRAII() {
|
||||
unique_lock<mutex> lock(_mutex);
|
||||
_refcount -= 1;
|
||||
if (0 == _refcount) {
|
||||
curl_global_cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
27
src/cpp-utils/network/CurlInitializerRAII.h
Normal file
27
src/cpp-utils/network/CurlInitializerRAII.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CPPUTILS_NETWORK_CURLINITIALIZERRAII_HPP
|
||||
#define MESSMER_CPPUTILS_NETWORK_CURLINITIALIZERRAII_HPP
|
||||
|
||||
#include <cpp-utils/macros.h>
|
||||
#include <mutex>
|
||||
#include <curl/curl.h>
|
||||
|
||||
namespace cpputils {
|
||||
// TODO Test
|
||||
|
||||
// When the first object of this class is created, it will initialize curl using curl_global_init().
|
||||
// When the last object is destroyed, it will deinitialize curl using curl_global_cleanup().
|
||||
class CurlInitializerRAII final {
|
||||
public:
|
||||
CurlInitializerRAII();
|
||||
~CurlInitializerRAII();
|
||||
private:
|
||||
static std::mutex _mutex;
|
||||
static uint32_t _refcount;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CurlInitializerRAII);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -14,7 +14,7 @@ namespace cpputils{
|
||||
if (0 != result) {
|
||||
throw std::runtime_error("sysctlbyname syscall failed");
|
||||
}
|
||||
#elif __linux__
|
||||
#elif __linux__ || __FreeBSD__
|
||||
long numRAMPages = sysconf(_SC_PHYS_PAGES);
|
||||
long pageSize = sysconf(_SC_PAGESIZE);
|
||||
mem = numRAMPages * pageSize;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <cpp-utils/io/NoninteractiveConsole.h>
|
||||
#include "Environment.h"
|
||||
|
||||
//TODO Fails with gpg-homedir in filesystem: gpg --homedir gpg-homedir --gen-key
|
||||
//TODO Many functions accessing the ProgramOptions object. Factor out into class that stores it as a member.
|
||||
//TODO Factor out class handling askPassword
|
||||
|
||||
@ -71,7 +70,6 @@ using gitversion::VersionCompare;
|
||||
//TODO Improve parallelity.
|
||||
//TODO Replace ASSERTs with other error handling when it is not a programming error but an environment influence (e.g. a block is missing)
|
||||
//TODO Can we improve performance by setting compiler parameter -maes for scrypt?
|
||||
//TODO Running nano in a cryfs file system, editing and saving an existing file shows "file was modified since opening".
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
|
@ -24,14 +24,6 @@ CryConfig::CryConfig()
|
||||
: _rootBlob(""), _encKey(""), _cipher(""), _version(""), _createdWithVersion(""), _blocksizeBytes(0), _filesystemId(FilesystemID::Null()), _exclusiveClientId(none), _hasVersionNumbers(true) {
|
||||
}
|
||||
|
||||
CryConfig::CryConfig(CryConfig &&rhs)
|
||||
: _rootBlob(std::move(rhs._rootBlob)), _encKey(std::move(rhs._encKey)), _cipher(std::move(rhs._cipher)), _version(std::move(rhs._version)), _createdWithVersion(std::move(rhs._createdWithVersion)), _blocksizeBytes(rhs._blocksizeBytes), _filesystemId(std::move(rhs._filesystemId)), _exclusiveClientId(std::move(rhs._exclusiveClientId)), _hasVersionNumbers(rhs._hasVersionNumbers) {
|
||||
}
|
||||
|
||||
CryConfig::CryConfig(const CryConfig &rhs)
|
||||
: _rootBlob(rhs._rootBlob), _encKey(rhs._encKey), _cipher(rhs._cipher), _version(rhs._version), _createdWithVersion(rhs._createdWithVersion), _blocksizeBytes(rhs._blocksizeBytes), _filesystemId(rhs._filesystemId) {
|
||||
}
|
||||
|
||||
CryConfig CryConfig::load(const Data &data) {
|
||||
stringstream stream;
|
||||
data.StoreToStream(stream);
|
||||
|
@ -14,8 +14,8 @@ class CryConfig final {
|
||||
public:
|
||||
//TODO No default constructor, pass in config values instead!
|
||||
CryConfig();
|
||||
CryConfig(CryConfig &&rhs);
|
||||
CryConfig(const CryConfig &rhs);
|
||||
CryConfig(CryConfig &&rhs) = default;
|
||||
CryConfig(const CryConfig &rhs) = default;
|
||||
|
||||
const std::string &RootBlob() const;
|
||||
void SetRootBlob(const std::string &value);
|
||||
|
@ -120,7 +120,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");
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class CryNode: public virtual fspp::Node {
|
||||
class CryNode: public fspp::Node {
|
||||
public:
|
||||
virtual ~CryNode();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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); \
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
}
|
||||
|
||||
void EXPECT_CHILDREN_ARE(const boost::filesystem::path &path, const std::initializer_list<fspp::Dir::Entry> expected) {
|
||||
EXPECT_CHILDREN_ARE(this->LoadDir(path).get(), expected);
|
||||
EXPECT_CHILDREN_ARE(this->LoadDir(path).get(), expected);
|
||||
}
|
||||
|
||||
void EXPECT_CHILDREN_ARE(fspp::Dir *dir, const std::initializer_list<fspp::Dir::Entry> expected) {
|
||||
@ -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) {
|
||||
@ -247,18 +249,22 @@ TYPED_TEST_P(FsppDirTest, CreateDir_AlreadyExisting) {
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppDirTest, Remove) {
|
||||
this->CreateDir("/mytestdir");
|
||||
EXPECT_NE(boost::none, this->device->Load("/mytestdir"));
|
||||
this->LoadDir("/mytestdir")->remove();
|
||||
EXPECT_EQ(boost::none, this->device->Load("/mytestdir"));
|
||||
this->CreateDir("/mytestdir");
|
||||
EXPECT_NE(boost::none, this->device->Load("/mytestdir"));
|
||||
EXPECT_NE(boost::none, this->device->LoadDir("/mytestdir"));
|
||||
this->Load("/mytestdir")->remove();
|
||||
EXPECT_EQ(boost::none, this->device->Load("/mytestdir"));
|
||||
EXPECT_EQ(boost::none, this->device->LoadDir("/mytestdir"));
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppDirTest, Remove_Nested) {
|
||||
this->CreateDir("/mytestdir");
|
||||
this->CreateDir("/mytestdir/mydir");
|
||||
EXPECT_NE(boost::none, this->device->Load("/mytestdir/mydir"));
|
||||
this->LoadDir("/mytestdir/mydir")->remove();
|
||||
EXPECT_EQ(boost::none, this->device->Load("/mytestdir/mydir"));
|
||||
this->CreateDir("/mytestdir");
|
||||
this->CreateDir("/mytestdir/mydir");
|
||||
EXPECT_NE(boost::none, this->device->Load("/mytestdir/mydir"));
|
||||
EXPECT_NE(boost::none, this->device->LoadDir("/mytestdir/mydir"));
|
||||
this->Load("/mytestdir/mydir")->remove();
|
||||
EXPECT_EQ(boost::none, this->device->Load("/mytestdir/mydir"));
|
||||
EXPECT_EQ(boost::none, this->device->LoadDir("/mytestdir/mydir"));
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(FsppDirTest,
|
||||
|
@ -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});
|
||||
}*/
|
||||
};
|
||||
|
||||
|
@ -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,98 +116,102 @@ 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());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppFileTest, Remove) {
|
||||
this->CreateFile("/mytestfile");
|
||||
EXPECT_NE(boost::none, this->device->Load("/mytestfile"));
|
||||
this->LoadFile("/mytestfile")->remove();
|
||||
EXPECT_NE(boost::none, this->device->LoadFile("/mytestfile"));
|
||||
this->Load("/mytestfile")->remove();
|
||||
EXPECT_EQ(boost::none, this->device->Load("/mytestfile"));
|
||||
EXPECT_EQ(boost::none, this->device->LoadFile("/mytestfile"));
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppFileTest, Remove_Nested) {
|
||||
this->CreateDir("/mytestdir");
|
||||
this->CreateFile("/mytestdir/myfile");
|
||||
EXPECT_NE(boost::none, this->device->Load("/mytestdir/myfile"));
|
||||
this->LoadFile("/mytestdir/myfile")->remove();
|
||||
EXPECT_NE(boost::none, this->device->LoadFile("/mytestdir/myfile"));
|
||||
this->Load("/mytestdir/myfile")->remove();
|
||||
EXPECT_EQ(boost::none, this->device->Load("/mytestdir/myfile"));
|
||||
EXPECT_EQ(boost::none, this->device->LoadFile("/mytestdir/myfile"));
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(FsppFileTest,
|
||||
|
@ -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) {
|
||||
@ -29,7 +29,7 @@ TYPED_TEST_P(FsppFileTest_Timestamps, open_rdonly) {
|
||||
auto operation = [&file] () {
|
||||
file->open(O_RDONLY);
|
||||
};
|
||||
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_wronly) {
|
||||
@ -37,7 +37,7 @@ TYPED_TEST_P(FsppFileTest_Timestamps, open_wronly) {
|
||||
auto operation = [&file] () {
|
||||
file->open(O_WRONLY);
|
||||
};
|
||||
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_rdwr) {
|
||||
@ -45,7 +45,7 @@ TYPED_TEST_P(FsppFileTest_Timestamps, open_rdwr) {
|
||||
auto operation = [&file] () {
|
||||
file->open(O_RDWR);
|
||||
};
|
||||
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, truncate_empty_to_empty) {
|
||||
@ -53,7 +53,7 @@ TYPED_TEST_P(FsppFileTest_Timestamps, truncate_empty_to_empty) {
|
||||
auto operation = [&file] () {
|
||||
file->truncate(0);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*file, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/myfile", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppFileTest_Timestamps, truncate_empty_to_nonempty) {
|
||||
@ -61,7 +61,7 @@ TYPED_TEST_P(FsppFileTest_Timestamps, truncate_empty_to_nonempty) {
|
||||
auto operation = [&file] () {
|
||||
file->truncate(10);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*file, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/myfile", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppFileTest_Timestamps, truncate_nonempty_to_empty) {
|
||||
@ -69,7 +69,7 @@ TYPED_TEST_P(FsppFileTest_Timestamps, truncate_nonempty_to_empty) {
|
||||
auto operation = [&file] () {
|
||||
file->truncate(0);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*file, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/myfile", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppFileTest_Timestamps, truncate_nonempty_to_nonempty_shrink) {
|
||||
@ -77,7 +77,7 @@ TYPED_TEST_P(FsppFileTest_Timestamps, truncate_nonempty_to_nonempty_shrink) {
|
||||
auto operation = [&file] () {
|
||||
file->truncate(5);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*file, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/myfile", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppFileTest_Timestamps, truncate_nonempty_to_nonempty_grow) {
|
||||
@ -85,7 +85,7 @@ TYPED_TEST_P(FsppFileTest_Timestamps, truncate_nonempty_to_nonempty_grow) {
|
||||
auto operation = [&file] () {
|
||||
file->truncate(20);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*file, operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/myfile", operation, {this->ExpectDoesntUpdateAccessTimestamp, this->ExpectUpdatesModificationTimestamp, this->ExpectUpdatesMetadataTimestamp});
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(FsppFileTest_Timestamps,
|
||||
|
@ -16,28 +16,28 @@ public:
|
||||
} catch (const fspp::fuse::FuseErrnoException &e) {
|
||||
EXPECT_EQ(ENOENT, e.getErrno());
|
||||
}
|
||||
//Old file should still exist
|
||||
//Old node should still exist
|
||||
EXPECT_NE(boost::none, this->device->Load("/oldname"));
|
||||
}
|
||||
|
||||
void Test_Error_TargetParentDirIsFile() {
|
||||
auto node = this->CreateNode("/oldname");
|
||||
this->CreateNode("/oldname");
|
||||
this->CreateFile("/somefile");
|
||||
try {
|
||||
node->rename("/somefile/newname");
|
||||
this->Load("/somefile")->rename("/somefile/newname");
|
||||
EXPECT_TRUE(false); // Expect it throws an exception
|
||||
} catch (const fspp::fuse::FuseErrnoException &e) {
|
||||
EXPECT_EQ(ENOTDIR, e.getErrno());
|
||||
}
|
||||
//Files should still exist
|
||||
//Nodes should still exist
|
||||
EXPECT_NE(boost::none, this->device->Load("/oldname"));
|
||||
EXPECT_NE(boost::none, this->device->Load("/somefile"));
|
||||
}
|
||||
|
||||
void Test_Error_RootDir() {
|
||||
auto root = this->LoadDir("/");
|
||||
auto rootDirNode = this->Load("/");
|
||||
try {
|
||||
root->rename("/newname");
|
||||
rootDirNode->rename("/newname");
|
||||
EXPECT_TRUE(false); // expect throws
|
||||
} catch (const fspp::fuse::FuseErrnoException &e) {
|
||||
EXPECT_EQ(EBUSY, e.getErrno());
|
||||
@ -142,10 +142,10 @@ public:
|
||||
}
|
||||
|
||||
void Test_Overwrite_Error_DirWithFile_InSameDir() {
|
||||
auto file = this->CreateFile("/oldname");
|
||||
this->CreateFile("/oldname");
|
||||
this->CreateDir("/newname");
|
||||
try {
|
||||
file->rename("/newname");
|
||||
this->Load("/oldname")->rename("/newname");
|
||||
EXPECT_TRUE(false); // expect throw
|
||||
} catch (const fspp::fuse::FuseErrnoException &e) {
|
||||
EXPECT_EQ(EISDIR, e.getErrno());
|
||||
@ -157,10 +157,10 @@ public:
|
||||
void Test_Overwrite_Error_DirWithFile_InDifferentDir() {
|
||||
this->CreateDir("/parent1");
|
||||
this->CreateDir("/parent2");
|
||||
auto file = this->CreateFile("/parent1/oldname");
|
||||
this->CreateFile("/parent1/oldname");
|
||||
this->CreateDir("/parent2/newname");
|
||||
try {
|
||||
file->rename("/parent2/newname");
|
||||
this->Load("/parent1/oldname")->rename("/parent2/newname");
|
||||
EXPECT_TRUE(false); // expect throw
|
||||
} catch (const fspp::fuse::FuseErrnoException &e) {
|
||||
EXPECT_EQ(EISDIR, e.getErrno());
|
||||
@ -170,10 +170,10 @@ public:
|
||||
}
|
||||
|
||||
void Test_Overwrite_Error_FileWithDir_InSameDir() {
|
||||
auto dir = this->CreateDir("/oldname");
|
||||
this->CreateDir("/oldname");
|
||||
this->CreateFile("/newname");
|
||||
try {
|
||||
dir->rename("/newname");
|
||||
this->Load("/oldname")->rename("/newname");
|
||||
EXPECT_TRUE(false); // expect throw
|
||||
} catch (const fspp::fuse::FuseErrnoException &e) {
|
||||
EXPECT_EQ(ENOTDIR, e.getErrno());
|
||||
@ -185,10 +185,10 @@ public:
|
||||
void Test_Overwrite_Error_FileWithDir_InDifferentDir() {
|
||||
this->CreateDir("/parent1");
|
||||
this->CreateDir("/parent2");
|
||||
auto dir = this->CreateDir("/parent1/oldname");
|
||||
this->CreateDir("/parent1/oldname");
|
||||
this->CreateFile("/parent2/newname");
|
||||
try {
|
||||
dir->rename("/parent2/newname");
|
||||
this->Load("/parent1/oldname")->rename("/parent2/newname");
|
||||
EXPECT_TRUE(false); // expect throw
|
||||
} catch (const fspp::fuse::FuseErrnoException &e) {
|
||||
EXPECT_EQ(ENOTDIR, e.getErrno());
|
||||
|
@ -9,7 +9,8 @@ template<class ConcreteFileSystemTestFixture>
|
||||
class FsppNodeTest_Stat: public FsppNodeTest<ConcreteFileSystemTestFixture> {
|
||||
public:
|
||||
void Test_Nlink() {
|
||||
auto node = this->CreateNode("/mynode");
|
||||
this->CreateNode("/mynode");
|
||||
auto node = this->Load("/mynode");
|
||||
this->IN_STAT(node.get(), [] (struct stat st) {
|
||||
EXPECT_EQ(1u, st.st_nlink);
|
||||
});
|
||||
@ -23,13 +24,15 @@ class FsppNodeTest_Stat_FileOnly: public FileSystemTest<ConcreteFileSystemTestFi
|
||||
TYPED_TEST_CASE_P(FsppNodeTest_Stat_FileOnly);
|
||||
|
||||
TYPED_TEST_P(FsppNodeTest_Stat_FileOnly, CreatedFileIsEmpty) {
|
||||
auto file = this->CreateFile("/myfile");
|
||||
this->EXPECT_SIZE(0, file.get());
|
||||
this->CreateFile("/myfile");
|
||||
auto node = this->Load("/myfile");
|
||||
this->EXPECT_SIZE(0, node.get());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppNodeTest_Stat_FileOnly, FileIsFile) {
|
||||
auto file = this->CreateFile("/myfile");
|
||||
this->IN_STAT(file.get(), [] (struct stat st) {
|
||||
this->CreateFile("/myfile");
|
||||
auto node = this->Load("/myfile");
|
||||
this->IN_STAT(node.get(), [] (struct stat st) {
|
||||
EXPECT_TRUE(S_ISREG(st.st_mode));
|
||||
});
|
||||
}
|
||||
@ -41,8 +44,9 @@ class FsppNodeTest_Stat_DirOnly: public FileSystemTest<ConcreteFileSystemTestFix
|
||||
TYPED_TEST_CASE_P(FsppNodeTest_Stat_DirOnly);
|
||||
|
||||
TYPED_TEST_P(FsppNodeTest_Stat_DirOnly, DirIsDir) {
|
||||
auto file = this->CreateDir("/mydir");
|
||||
this->IN_STAT(file.get(), [] (struct stat st) {
|
||||
this->CreateDir("/mydir");
|
||||
auto node = this->Load("/mydir");
|
||||
this->IN_STAT(node.get(), [] (struct stat st) {
|
||||
EXPECT_TRUE(S_ISDIR(st.st_mode));
|
||||
});
|
||||
}
|
||||
@ -54,8 +58,9 @@ class FsppNodeTest_Stat_SymlinkOnly: public FileSystemTest<ConcreteFileSystemTes
|
||||
TYPED_TEST_CASE_P(FsppNodeTest_Stat_SymlinkOnly);
|
||||
|
||||
TYPED_TEST_P(FsppNodeTest_Stat_SymlinkOnly, SymlinkIsSymlink) {
|
||||
auto file = this->CreateSymlink("/mysymlink");
|
||||
this->IN_STAT(file.get(), [] (struct stat st) {
|
||||
this->CreateSymlink("/mysymlink");
|
||||
auto node = this->Load("/mysymlink");
|
||||
this->IN_STAT(node.get(), [] (struct stat st) {
|
||||
EXPECT_TRUE(S_ISLNK(st.st_mode));
|
||||
});
|
||||
}
|
||||
|
@ -11,16 +11,16 @@ using namespace cpputils::time;
|
||||
using std::function;
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
class FsppNodeTest_Timestamps: public FsppNodeTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils {
|
||||
class FsppNodeTest_Timestamps: public FsppNodeTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils<ConcreteFileSystemTestFixture> {
|
||||
public:
|
||||
|
||||
void Test_Create() {
|
||||
timespec lowerBound = now();
|
||||
auto node = this->CreateNode("/mynode");
|
||||
timespec upperBound = now();
|
||||
EXPECT_ACCESS_TIMESTAMP_BETWEEN (lowerBound, upperBound, *node);
|
||||
EXPECT_MODIFICATION_TIMESTAMP_BETWEEN (lowerBound, upperBound, *node);
|
||||
EXPECT_METADATACHANGE_TIMESTAMP_BETWEEN(lowerBound, upperBound, *node);
|
||||
this->EXPECT_ACCESS_TIMESTAMP_BETWEEN (lowerBound, upperBound, *node);
|
||||
this->EXPECT_MODIFICATION_TIMESTAMP_BETWEEN (lowerBound, upperBound, *node);
|
||||
this->EXPECT_METADATACHANGE_TIMESTAMP_BETWEEN(lowerBound, upperBound, *node);
|
||||
}
|
||||
|
||||
void Test_Stat() {
|
||||
@ -29,26 +29,36 @@ public:
|
||||
struct stat st;
|
||||
node->stat(&st);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mynode", operation, {
|
||||
this->ExpectDoesntUpdateAnyTimestamps
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Chmod() {
|
||||
auto node = this->CreateNode("/mynode");
|
||||
mode_t mode = stat(*node).st_mode;
|
||||
mode_t mode = this->stat(*node).st_mode;
|
||||
auto operation = [&node, mode] () {
|
||||
node->chmod(mode);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mynode", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Chown() {
|
||||
auto node = this->CreateNode("/mynode");
|
||||
uid_t uid = stat(*node).st_uid;
|
||||
gid_t gid = stat(*node).st_gid;
|
||||
uid_t uid = this->stat(*node).st_uid;
|
||||
gid_t gid = this->stat(*node).st_gid;
|
||||
auto operation = [&node, uid, gid] () {
|
||||
node->chown(uid, gid);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mynode", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Access() {
|
||||
@ -56,7 +66,9 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->access(0);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mynode", operation, {
|
||||
this->ExpectDoesntUpdateAnyTimestamps
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_Error_TargetParentDirDoesntExist() {
|
||||
@ -69,7 +81,9 @@ public:
|
||||
EXPECT_EQ(ENOENT, e.getErrno()); //Rename fails, everything is ok.
|
||||
}
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAnyTimestamps
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_Error_TargetParentDirIsFile() {
|
||||
@ -83,13 +97,15 @@ public:
|
||||
EXPECT_EQ(ENOTDIR, e.getErrno()); //Rename fails, everything is ok.
|
||||
}
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAnyTimestamps
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_Error_RootDir() {
|
||||
// TODO Re-enable this test once the root dir stores timestamps correctly
|
||||
/*
|
||||
auto root = this->LoadDir("/");
|
||||
auto root = this->Load("/");
|
||||
auto operation = [&root] () {
|
||||
try {
|
||||
root->rename("/newname");
|
||||
@ -98,7 +114,9 @@ public:
|
||||
EXPECT_EQ(EBUSY, e.getErrno()); //Rename fails, everything is ok.
|
||||
}
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mynode", operation, {
|
||||
this->ExpectDoesntUpdateAnyTimestamps
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
@ -107,7 +125,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/newname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/oldname", "/newname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_InNested() {
|
||||
@ -116,7 +138,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/mydir/newname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir/oldname", "/mydir/newname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_RootToNested_SameName() {
|
||||
@ -125,7 +151,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/mydir/oldname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/oldname", "/mydir/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_RootToNested_NewName() {
|
||||
@ -134,7 +164,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/mydir/newname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/oldname", "/mydir/newname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_NestedToRoot_SameName() {
|
||||
@ -143,7 +177,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/oldname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir/oldname", "/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_NestedToRoot_NewName() {
|
||||
@ -152,7 +190,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/newname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir/oldname", "/newname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_NestedToNested_SameName() {
|
||||
@ -162,7 +204,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/mydir2/oldname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir1/oldname", "/mydir2/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_NestedToNested_NewName() {
|
||||
@ -172,7 +218,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/mydir2/newname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir1/oldname", "/mydir2/newname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_ToItself() {
|
||||
@ -180,7 +230,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/oldname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/oldname", "/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_Overwrite_InSameDir() {
|
||||
@ -189,7 +243,11 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/newname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/oldname", "/newname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_Overwrite_InDifferentDir() {
|
||||
@ -200,12 +258,17 @@ public:
|
||||
auto operation = [&node] () {
|
||||
node->rename("/mydir2/newname");
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAccessTimestamp, ExpectDoesntUpdateModificationTimestamp, ExpectUpdatesMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir1/oldname", "/mydir2/newname", operation, {
|
||||
this->ExpectDoesntUpdateAccessTimestamp,
|
||||
this->ExpectDoesntUpdateModificationTimestamp,
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_Overwrite_Error_DirWithFile_InSameDir() {
|
||||
auto node = this->CreateFile("/oldname");
|
||||
this->CreateFile("/oldname");
|
||||
this->CreateDir("/newname");
|
||||
auto node = this->Load("/oldname");
|
||||
auto operation = [&node] () {
|
||||
try {
|
||||
node->rename("/newname");
|
||||
@ -214,14 +277,17 @@ public:
|
||||
EXPECT_EQ(EISDIR, e.getErrno()); //Rename fails, everything is ok.
|
||||
}
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAnyTimestamps
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_Overwrite_Error_DirWithFile_InDifferentDir() {
|
||||
this->CreateDir("/mydir1");
|
||||
this->CreateDir("/mydir2");
|
||||
auto node = this->CreateFile("/mydir1/oldname");
|
||||
this->CreateFile("/mydir1/oldname");
|
||||
this->CreateDir("/mydir2/newname");
|
||||
auto node = this->Load("/mydir1/oldname");
|
||||
auto operation = [&node] () {
|
||||
try {
|
||||
node->rename("/mydir2/newname");
|
||||
@ -230,12 +296,15 @@ public:
|
||||
EXPECT_EQ(EISDIR, e.getErrno());//Rename fails, everything is ok.
|
||||
}
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir1/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAnyTimestamps
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_Overwrite_Error_FileWithDir_InSameDir() {
|
||||
auto node = this->CreateDir("/oldname");
|
||||
this->CreateDir("/oldname");
|
||||
this->CreateFile("/newname");
|
||||
auto node = this->Load("/oldname");
|
||||
auto operation = [&node] () {
|
||||
try {
|
||||
node->rename("/newname");
|
||||
@ -244,14 +313,17 @@ public:
|
||||
EXPECT_EQ(ENOTDIR, e.getErrno()); //Rename fails, everything is ok.
|
||||
}
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAnyTimestamps
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Rename_Overwrite_Error_FileWithDir_InDifferentDir() {
|
||||
this->CreateDir("/mydir1");
|
||||
this->CreateDir("/mydir2");
|
||||
auto node = this->CreateDir("/mydir1/oldname");
|
||||
this->CreateDir("/mydir1/oldname");
|
||||
this->CreateFile("/mydir2/newname");
|
||||
auto node = this->Load("/mydir1/oldname");
|
||||
auto operation = [&node] () {
|
||||
try {
|
||||
node->rename("/mydir2/newname");
|
||||
@ -260,19 +332,23 @@ public:
|
||||
EXPECT_EQ(ENOTDIR, e.getErrno()); //Rename fails, everything is ok.
|
||||
}
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectDoesntUpdateAnyTimestamps});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mydir1/oldname", operation, {
|
||||
this->ExpectDoesntUpdateAnyTimestamps
|
||||
});
|
||||
}
|
||||
|
||||
void Test_Utimens() {
|
||||
auto node = this->CreateNode("/mynode");
|
||||
timespec atime = xSecondsAgo(100);
|
||||
timespec mtime = xSecondsAgo(200);
|
||||
timespec atime = this->xSecondsAgo(100);
|
||||
timespec mtime = this->xSecondsAgo(200);
|
||||
auto operation = [&node, atime, mtime] () {
|
||||
node->utimens(atime, mtime);
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*node, operation, {ExpectUpdatesMetadataTimestamp});
|
||||
EXPECT_EQ(atime, stat(*node).st_atim);
|
||||
EXPECT_EQ(mtime, stat(*node).st_mtim);
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mynode", operation, {
|
||||
this->ExpectUpdatesMetadataTimestamp
|
||||
});
|
||||
EXPECT_EQ(atime, this->stat(*node).st_atim);
|
||||
EXPECT_EQ(mtime, this->stat(*node).st_mtim);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,18 +5,50 @@
|
||||
#include "testutils/FileTest.h"
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
class FsppOpenFileTest: public FileTest<ConcreteFileSystemTestFixture> {
|
||||
class FsppOpenFileTest: public FileSystemTest<ConcreteFileSystemTestFixture> {
|
||||
public:
|
||||
void IN_STAT(fspp::OpenFile *openFile, std::function<void (struct stat)> callback) {
|
||||
struct stat st;
|
||||
openFile->stat(&st);
|
||||
callback(st);
|
||||
}
|
||||
|
||||
void EXPECT_SIZE(uint64_t expectedSize, fspp::OpenFile *openFile) {
|
||||
IN_STAT(openFile, [expectedSize] (struct stat st) {
|
||||
EXPECT_EQ(expectedSize, (uint64_t)st.st_size);
|
||||
});
|
||||
|
||||
EXPECT_NUMBYTES_READABLE(expectedSize, openFile);
|
||||
}
|
||||
|
||||
void EXPECT_NUMBYTES_READABLE(uint64_t expectedSize, fspp::OpenFile *openFile) {
|
||||
cpputils::Data data(expectedSize);
|
||||
//Try to read one byte more than the expected size
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
TYPED_TEST_CASE_P(FsppOpenFileTest);
|
||||
|
||||
TYPED_TEST_P(FsppOpenFileTest, Bla) {
|
||||
//TODO
|
||||
TYPED_TEST_P(FsppOpenFileTest, CreatedFileIsEmpty) {
|
||||
auto file = this->CreateFile("/myfile");
|
||||
auto openFile = this->LoadFile("/myfile")->open(O_RDONLY);
|
||||
this->EXPECT_SIZE(0, openFile.get());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppOpenFileTest, FileIsFile) {
|
||||
auto file = this->CreateFile("/myfile");
|
||||
auto openFile = this->LoadFile("/myfile")->open(O_RDONLY);
|
||||
this->IN_STAT(openFile.get(), [] (struct stat st) {
|
||||
EXPECT_TRUE(S_ISREG(st.st_mode));
|
||||
});
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(FsppOpenFileTest,
|
||||
Bla
|
||||
CreatedFileIsEmpty,
|
||||
FileIsFile
|
||||
);
|
||||
|
||||
//TODO Test stat
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "testutils/TimestampTestUtils.h"
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
class FsppOpenFileTest_Timestamps: public FileSystemTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils {
|
||||
class FsppOpenFileTest_Timestamps: public TimestampTestUtils<ConcreteFileSystemTestFixture> {
|
||||
public:
|
||||
cpputils::unique_ref<fspp::OpenFile> CreateAndOpenFile(const boost::filesystem::path &path) {
|
||||
return this->CreateFile(path)->open(O_RDWR);
|
||||
@ -14,7 +14,8 @@ public:
|
||||
auto file = this->CreateFile(path);
|
||||
file->truncate(size);
|
||||
auto openFile = file->open(O_RDWR);
|
||||
assert(stat(*openFile).st_size == size);
|
||||
assert(this->stat(*openFile).st_size == size);
|
||||
assert(this->stat(*this->Load(path)).st_size == size);
|
||||
return openFile;
|
||||
}
|
||||
};
|
||||
|
@ -35,16 +35,20 @@ TYPED_TEST_P(FsppSymlinkTest, Read_RelativePath) {
|
||||
TYPED_TEST_P(FsppSymlinkTest, Remove) {
|
||||
this->CreateSymlink("/mysymlink", "/my/symlink/target");
|
||||
EXPECT_NE(boost::none, this->device->Load("/mysymlink"));
|
||||
this->LoadSymlink("/mysymlink")->remove();
|
||||
EXPECT_NE(boost::none, this->device->LoadSymlink("/mysymlink"));
|
||||
this->Load("/mysymlink")->remove();
|
||||
EXPECT_EQ(boost::none, this->device->Load("/mysymlink"));
|
||||
EXPECT_EQ(boost::none, this->device->LoadSymlink("/mysymlink"));
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FsppSymlinkTest, Remove_Nested) {
|
||||
this->CreateDir("/mytestdir");
|
||||
this->CreateSymlink("/mytestdir/mysymlink", "/my/symlink/target");
|
||||
EXPECT_NE(boost::none, this->device->Load("/mytestdir/mysymlink"));
|
||||
this->LoadSymlink("/mytestdir/mysymlink")->remove();
|
||||
EXPECT_NE(boost::none, this->device->LoadSymlink("/mytestdir/mysymlink"));
|
||||
this->Load("/mytestdir/mysymlink")->remove();
|
||||
EXPECT_EQ(boost::none, this->device->Load("/mytestdir/mysymlink"));
|
||||
EXPECT_EQ(boost::none, this->device->LoadSymlink("/mytestdir/mysymlink"));
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(FsppSymlinkTest,
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "testutils/TimestampTestUtils.h"
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
class FsppSymlinkTest_Timestamps: public FileSystemTest<ConcreteFileSystemTestFixture>, public TimestampTestUtils {
|
||||
class FsppSymlinkTest_Timestamps: public TimestampTestUtils<ConcreteFileSystemTestFixture> {
|
||||
public:
|
||||
};
|
||||
TYPED_TEST_CASE_P(FsppSymlinkTest_Timestamps);
|
||||
@ -15,7 +15,7 @@ TYPED_TEST_P(FsppSymlinkTest_Timestamps, target) {
|
||||
auto operation = [&symlink] () {
|
||||
symlink->target();
|
||||
};
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(*symlink, operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
|
||||
this->EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS("/mysymlink", operation, {this->ExpectUpdatesAccessTimestamp, this->ExpectDoesntUpdateModificationTimestamp, this->ExpectDoesntUpdateMetadataTimestamp});
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(FsppSymlinkTest_Timestamps,
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
|
||||
|
||||
#include "../../fs_interface/Device.h"
|
||||
#include "../../fs_interface/Node.h"
|
||||
#include "../../fs_interface/Dir.h"
|
||||
#include "../../fs_interface/File.h"
|
||||
#include "../../fs_interface/Symlink.h"
|
||||
@ -35,28 +36,28 @@ public:
|
||||
|
||||
static constexpr mode_t MODE_PUBLIC = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
|
||||
|
||||
cpputils::unique_ref<fspp::Dir> LoadDir(const boost::filesystem::path &path) {
|
||||
auto loaded = device->Load(path);
|
||||
cpputils::unique_ref<fspp::Node> Load(const boost::filesystem::path &path) {
|
||||
auto loaded = device->Load(path);
|
||||
EXPECT_NE(boost::none, loaded);
|
||||
auto dir = cpputils::dynamic_pointer_move<fspp::Dir>(*loaded);
|
||||
EXPECT_NE(boost::none, dir);
|
||||
return std::move(*dir);
|
||||
return std::move(*loaded);
|
||||
}
|
||||
|
||||
cpputils::unique_ref<fspp::Dir> LoadDir(const boost::filesystem::path &path) {
|
||||
auto loaded = device->LoadDir(path);
|
||||
EXPECT_NE(boost::none, loaded);
|
||||
return std::move(*loaded);
|
||||
}
|
||||
|
||||
cpputils::unique_ref<fspp::File> LoadFile(const boost::filesystem::path &path) {
|
||||
auto loaded = device->Load(path);
|
||||
auto loaded = device->LoadFile(path);
|
||||
EXPECT_NE(boost::none, loaded);
|
||||
auto file = cpputils::dynamic_pointer_move<fspp::File>(*loaded);
|
||||
EXPECT_NE(boost::none, file);
|
||||
return std::move(*file);
|
||||
return std::move(*loaded);
|
||||
}
|
||||
|
||||
cpputils::unique_ref<fspp::Symlink> LoadSymlink(const boost::filesystem::path &path) {
|
||||
auto loaded = device->Load(path);
|
||||
auto loaded = device->LoadSymlink(path);
|
||||
EXPECT_NE(boost::none, loaded);
|
||||
auto symlink = cpputils::dynamic_pointer_move<fspp::Symlink>(*loaded);
|
||||
EXPECT_NE(boost::none, symlink);
|
||||
return std::move(*symlink);
|
||||
return std::move(*loaded);
|
||||
}
|
||||
|
||||
cpputils::unique_ref<fspp::Dir> CreateDir(const boost::filesystem::path &path) {
|
||||
@ -73,6 +74,18 @@ public:
|
||||
this->LoadDir(path.parent_path())->createSymlink(path.filename().native(), target, 0, 0);
|
||||
return this->LoadSymlink(path);
|
||||
}
|
||||
|
||||
void EXPECT_IS_FILE(const cpputils::unique_ref<fspp::Node> &node) {
|
||||
EXPECT_NE(nullptr, dynamic_cast<const fspp::File*>(node.get()));
|
||||
}
|
||||
|
||||
void EXPECT_IS_DIR(const cpputils::unique_ref<fspp::Node> &node) {
|
||||
EXPECT_NE(nullptr, dynamic_cast<const fspp::Dir*>(node.get()));
|
||||
}
|
||||
|
||||
void EXPECT_IS_SYMLINK(const cpputils::unique_ref<fspp::Node> &node) {
|
||||
EXPECT_NE(nullptr, dynamic_cast<const fspp::Symlink*>(node.get()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -13,27 +13,31 @@ public:
|
||||
FileTest(): file_root(), file_nested() {
|
||||
this->LoadDir("/")->createAndOpenFile("myfile", this->MODE_PUBLIC, 0, 0);
|
||||
file_root = cpputils::to_unique_ptr(this->LoadFile("/myfile"));
|
||||
file_root_node = cpputils::to_unique_ptr(this->Load("/myfile"));
|
||||
|
||||
this->LoadDir("/")->createDir("mydir", this->MODE_PUBLIC, 0, 0);
|
||||
this->LoadDir("/mydir")->createAndOpenFile("mynestedfile", this->MODE_PUBLIC, 0, 0);
|
||||
file_nested = cpputils::to_unique_ptr(this->LoadFile("/mydir/mynestedfile"));
|
||||
file_nested_node = cpputils::to_unique_ptr(this->Load("/mydir/mynestedfile"));
|
||||
|
||||
this->LoadDir("/")->createDir("mydir2", this->MODE_PUBLIC, 0, 0);
|
||||
}
|
||||
std::unique_ptr<fspp::File> file_root;
|
||||
std::unique_ptr<fspp::File> file_nested;
|
||||
std::unique_ptr<fspp::Node> file_root_node;
|
||||
std::unique_ptr<fspp::Node> file_nested_node;
|
||||
|
||||
//TODO IN_STAT still needed after moving it to FsppNodeTest?
|
||||
void IN_STAT(fspp::File *file, std::function<void (struct stat)> callback) {
|
||||
void IN_STAT(fspp::File *file, fspp::Node *node, std::function<void (struct stat)> callback) {
|
||||
struct stat st1, st2;
|
||||
file->stat(&st1);
|
||||
node->stat(&st1);
|
||||
callback(st1);
|
||||
file->open(O_RDONLY)->stat(&st2);
|
||||
callback(st2);
|
||||
}
|
||||
|
||||
void EXPECT_SIZE(uint64_t expectedSize, fspp::File *file) {
|
||||
IN_STAT(file, [expectedSize] (struct stat st) {
|
||||
void EXPECT_SIZE(uint64_t expectedSize, fspp::File *file, fspp::Node *node) {
|
||||
IN_STAT(file, node, [expectedSize] (struct stat st) {
|
||||
EXPECT_EQ(expectedSize, (uint64_t)st.st_size);
|
||||
});
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <boost/preprocessor/variadic/to_seq.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
|
||||
// TODO separation into File/Dir/Symlink Helpers probably not needed anymore
|
||||
|
||||
class FsppNodeTestBase {
|
||||
public:
|
||||
virtual void IN_STAT(fspp::Node *node, std::function<void (struct stat)> callback) = 0;
|
||||
@ -22,7 +24,7 @@ public:
|
||||
* See FsppNodeTest_Rename for an example.
|
||||
*/
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
class FsppNodeTest: public virtual FsppNodeTestBase, public FileSystemTest<ConcreteFileSystemTestFixture> {
|
||||
class FsppNodeTest: public virtual FsppNodeTestBase, public virtual FileSystemTest<ConcreteFileSystemTestFixture> {
|
||||
public:
|
||||
virtual cpputils::unique_ref<fspp::Node> CreateNode(const boost::filesystem::path &path) = 0;
|
||||
};
|
||||
@ -30,30 +32,15 @@ public:
|
||||
class FsppNodeTest_File_Helper: public virtual FsppNodeTestBase {
|
||||
public:
|
||||
void IN_STAT(fspp::Node *file, std::function<void (struct stat)> callback) override {
|
||||
struct stat st1, st2;
|
||||
file->stat(&st1);
|
||||
callback(st1);
|
||||
dynamic_cast<fspp::File &>(*file).open(O_RDONLY)->stat(&st2);
|
||||
callback(st2);
|
||||
struct stat st;
|
||||
file->stat(&st);
|
||||
callback(st);
|
||||
}
|
||||
|
||||
void EXPECT_SIZE(uint64_t expectedSize, fspp::Node *node) override {
|
||||
IN_STAT(node, [expectedSize] (struct stat st) {
|
||||
EXPECT_EQ(expectedSize, (uint64_t)st.st_size);
|
||||
});
|
||||
|
||||
fspp::File* fileNode = dynamic_cast<fspp::File*>(node);
|
||||
ASSERT(fileNode != nullptr, "Is not a file node");
|
||||
EXPECT_NUMBYTES_READABLE(expectedSize, fileNode);
|
||||
}
|
||||
|
||||
void EXPECT_NUMBYTES_READABLE(uint64_t expectedSize, fspp::File *file) {
|
||||
auto openFile = file->open(O_RDONLY);
|
||||
cpputils::Data data(expectedSize);
|
||||
//Try to read one byte more than the expected size
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
@ -101,7 +88,8 @@ public:
|
||||
class Class##_FileNode: public Class<ConcreteFileSystemTestFixture>, public FsppNodeTest_File_Helper { \
|
||||
public: \
|
||||
cpputils::unique_ref<fspp::Node> CreateNode(const boost::filesystem::path &path) override { \
|
||||
return this->CreateFile(path); \
|
||||
this->CreateFile(path); \
|
||||
return this->Load(path); \
|
||||
} \
|
||||
}; \
|
||||
TYPED_TEST_CASE_P(Class##_FileNode); \
|
||||
@ -112,7 +100,8 @@ public:
|
||||
class Class##_DirNode: public Class<ConcreteFileSystemTestFixture>, public FsppNodeTest_Dir_Helper { \
|
||||
public: \
|
||||
cpputils::unique_ref<fspp::Node> CreateNode(const boost::filesystem::path &path) override { \
|
||||
return this->CreateDir(path); \
|
||||
this->CreateDir(path); \
|
||||
return this->Load(path); \
|
||||
} \
|
||||
}; \
|
||||
TYPED_TEST_CASE_P(Class##_DirNode); \
|
||||
@ -123,7 +112,8 @@ public:
|
||||
class Class##_SymlinkNode: public Class<ConcreteFileSystemTestFixture>, public FsppNodeTest_Symlink_Helper { \
|
||||
public: \
|
||||
cpputils::unique_ref<fspp::Node> CreateNode(const boost::filesystem::path &path) override { \
|
||||
return this->CreateSymlink(path); \
|
||||
this->CreateSymlink(path); \
|
||||
return this->Load(path); \
|
||||
} \
|
||||
}; \
|
||||
TYPED_TEST_CASE_P(Class##_SymlinkNode); \
|
||||
|
@ -4,100 +4,83 @@
|
||||
|
||||
#include <cpp-utils/system/time.h>
|
||||
#include <cpp-utils/system/stat.h>
|
||||
#include "FileSystemTest.h"
|
||||
#include <functional>
|
||||
|
||||
class TimestampTestUtils {
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
class TimestampTestUtils : public virtual FileSystemTest<ConcreteFileSystemTestFixture> {
|
||||
public:
|
||||
using TimestampUpdateBehavior = std::function<void (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation)>;
|
||||
|
||||
TimestampUpdateBehavior ExpectUpdatesAccessTimestamp = [] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(statBeforeOperation);
|
||||
UNUSED(timeBeforeOperation);
|
||||
UNUSED(timeAfterOperation);
|
||||
EXPECT_LE(timeBeforeOperation, statAfterOperation.st_atim);
|
||||
EXPECT_GE(timeAfterOperation, statAfterOperation.st_atim);
|
||||
};
|
||||
static TimestampUpdateBehavior ExpectUpdatesAccessTimestamp;
|
||||
static TimestampUpdateBehavior ExpectDoesntUpdateAccessTimestamp;
|
||||
static TimestampUpdateBehavior ExpectUpdatesModificationTimestamp;
|
||||
static TimestampUpdateBehavior ExpectDoesntUpdateModificationTimestamp;
|
||||
static TimestampUpdateBehavior ExpectUpdatesMetadataTimestamp;
|
||||
static TimestampUpdateBehavior ExpectDoesntUpdateMetadataTimestamp;
|
||||
static TimestampUpdateBehavior ExpectDoesntUpdateAnyTimestamps;
|
||||
|
||||
TimestampUpdateBehavior ExpectDoesntUpdateAccessTimestamp = [] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(timeBeforeOperation);
|
||||
UNUSED(timeAfterOperation);
|
||||
EXPECT_EQ(statBeforeOperation.st_atim, statAfterOperation.st_atim);
|
||||
};
|
||||
|
||||
TimestampUpdateBehavior ExpectUpdatesModificationTimestamp = [] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(statBeforeOperation);
|
||||
EXPECT_LE(timeBeforeOperation, statAfterOperation.st_mtim);
|
||||
EXPECT_GE(timeAfterOperation, statAfterOperation.st_mtim);
|
||||
};
|
||||
|
||||
TimestampUpdateBehavior ExpectDoesntUpdateModificationTimestamp = [] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(timeBeforeOperation);
|
||||
UNUSED(timeAfterOperation);
|
||||
EXPECT_EQ(statBeforeOperation.st_mtim, statAfterOperation.st_mtim);
|
||||
};
|
||||
|
||||
TimestampUpdateBehavior ExpectUpdatesMetadataTimestamp = [] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(statBeforeOperation);
|
||||
EXPECT_LE(timeBeforeOperation, statAfterOperation.st_ctim);
|
||||
EXPECT_GE(timeAfterOperation, statAfterOperation.st_ctim);
|
||||
};
|
||||
|
||||
TimestampUpdateBehavior ExpectDoesntUpdateMetadataTimestamp = [] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(timeBeforeOperation);
|
||||
UNUSED(timeAfterOperation);
|
||||
EXPECT_EQ(statBeforeOperation.st_ctim, statAfterOperation.st_ctim);
|
||||
};
|
||||
|
||||
TimestampUpdateBehavior ExpectDoesntUpdateAnyTimestamps = [this] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
ExpectDoesntUpdateAccessTimestamp(statBeforeOperation, statAfterOperation, timeBeforeOperation, timeAfterOperation);
|
||||
ExpectDoesntUpdateModificationTimestamp(statBeforeOperation, statAfterOperation, timeBeforeOperation, timeAfterOperation);
|
||||
ExpectDoesntUpdateMetadataTimestamp(statBeforeOperation, statAfterOperation, timeBeforeOperation, timeAfterOperation);
|
||||
};
|
||||
|
||||
void EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(std::function<struct stat()> stat, std::function<void()> operation, std::initializer_list<TimestampUpdateBehavior> behaviorChecks) {
|
||||
struct stat oldStat = stat();
|
||||
void EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(std::function<struct stat()> statOld, std::function<struct stat()> statNew, std::function<void()> operation, std::initializer_list<TimestampUpdateBehavior> behaviorChecks) {
|
||||
struct stat oldStat = statOld();
|
||||
ensureNodeTimestampsAreOld(oldStat);
|
||||
timespec timeBeforeOperation = cpputils::time::now();
|
||||
operation();
|
||||
timespec timeAfterOperation = cpputils::time::now();
|
||||
struct stat newStat = stat();
|
||||
struct stat newStat = statNew();
|
||||
for (auto behaviorCheck : behaviorChecks) {
|
||||
behaviorCheck(oldStat, newStat, timeBeforeOperation, timeAfterOperation);
|
||||
}
|
||||
}
|
||||
|
||||
void EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(const fspp::OpenFile &node, std::function<void()> operation, std::initializer_list<TimestampUpdateBehavior> behaviorChecks) {
|
||||
return EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS([&node](){return stat(node);}, operation, behaviorChecks);
|
||||
EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(
|
||||
[this, &node](){return this->stat(node);},
|
||||
[this, &node](){return this->stat(node);},
|
||||
operation,
|
||||
behaviorChecks
|
||||
);
|
||||
}
|
||||
|
||||
void EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(const fspp::Node &node, std::function<void()> operation, std::initializer_list<TimestampUpdateBehavior> behaviorChecks) {
|
||||
return EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS([&node](){return stat(node);}, operation, behaviorChecks);
|
||||
void EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(const boost::filesystem::path &oldPath, const boost::filesystem::path &newPath, std::function<void()> operation, std::initializer_list<TimestampUpdateBehavior> behaviorChecks) {
|
||||
EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(
|
||||
[this, oldPath](){return this->stat(*this->Load(oldPath));},
|
||||
[this, newPath](){return this->stat(*this->Load(newPath));},
|
||||
operation,
|
||||
behaviorChecks
|
||||
);
|
||||
}
|
||||
|
||||
template<typename NodeType>
|
||||
void EXPECT_ACCESS_TIMESTAMP_BETWEEN(timespec lowerBound, timespec upperBound, const NodeType &node) {
|
||||
void EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(const boost::filesystem::path &path, std::function<void()> operation, std::initializer_list<TimestampUpdateBehavior> behaviorChecks) {
|
||||
EXPECT_OPERATION_UPDATES_TIMESTAMPS_AS(path, path, operation, behaviorChecks);
|
||||
}
|
||||
|
||||
void EXPECT_ACCESS_TIMESTAMP_BETWEEN(timespec lowerBound, timespec upperBound, const fspp::Node &node) {
|
||||
EXPECT_LE(lowerBound, stat(node).st_atim);
|
||||
EXPECT_GE(upperBound, stat(node).st_atim);
|
||||
}
|
||||
|
||||
template<typename NodeType>
|
||||
void EXPECT_MODIFICATION_TIMESTAMP_BETWEEN(timespec lowerBound, timespec upperBound, const NodeType &node) {
|
||||
void EXPECT_MODIFICATION_TIMESTAMP_BETWEEN(timespec lowerBound, timespec upperBound, const fspp::Node &node) {
|
||||
EXPECT_LE(lowerBound, stat(node).st_mtim);
|
||||
EXPECT_GE(upperBound, stat(node).st_mtim);
|
||||
}
|
||||
|
||||
template<typename NodeType>
|
||||
void EXPECT_METADATACHANGE_TIMESTAMP_BETWEEN(timespec lowerBound, timespec upperBound, const NodeType &node) {
|
||||
void EXPECT_METADATACHANGE_TIMESTAMP_BETWEEN(timespec lowerBound, timespec upperBound, const fspp::Node &node) {
|
||||
EXPECT_LE(lowerBound, stat(node).st_ctim);
|
||||
EXPECT_GE(upperBound, stat(node).st_ctim);
|
||||
}
|
||||
|
||||
template<typename NodeType>
|
||||
static struct stat stat(const NodeType &node) {
|
||||
static struct stat stat(const fspp::Node &node) {
|
||||
struct stat st;
|
||||
node.stat(&st);
|
||||
return st;
|
||||
}
|
||||
|
||||
static struct stat stat(const fspp::OpenFile &openFile) {
|
||||
struct stat st;
|
||||
openFile.stat(&st);
|
||||
return st;
|
||||
}
|
||||
|
||||
timespec xSecondsAgo(int sec) {
|
||||
timespec result = cpputils::time::now();
|
||||
result.tv_sec -= sec;
|
||||
@ -121,4 +104,62 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
typename TimestampTestUtils<ConcreteFileSystemTestFixture>::TimestampUpdateBehavior TimestampTestUtils<ConcreteFileSystemTestFixture>::ExpectUpdatesAccessTimestamp =
|
||||
[] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(statBeforeOperation);
|
||||
UNUSED(timeBeforeOperation);
|
||||
UNUSED(timeAfterOperation);
|
||||
EXPECT_LE(timeBeforeOperation, statAfterOperation.st_atim);
|
||||
EXPECT_GE(timeAfterOperation, statAfterOperation.st_atim);
|
||||
};
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
typename TimestampTestUtils<ConcreteFileSystemTestFixture>::TimestampUpdateBehavior TimestampTestUtils<ConcreteFileSystemTestFixture>::ExpectDoesntUpdateAccessTimestamp =
|
||||
[] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(timeBeforeOperation);
|
||||
UNUSED(timeAfterOperation);
|
||||
EXPECT_EQ(statBeforeOperation.st_atim, statAfterOperation.st_atim);
|
||||
};
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
typename TimestampTestUtils<ConcreteFileSystemTestFixture>::TimestampUpdateBehavior TimestampTestUtils<ConcreteFileSystemTestFixture>::ExpectUpdatesModificationTimestamp =
|
||||
[] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(statBeforeOperation);
|
||||
EXPECT_LE(timeBeforeOperation, statAfterOperation.st_mtim);
|
||||
EXPECT_GE(timeAfterOperation, statAfterOperation.st_mtim);
|
||||
};
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
typename TimestampTestUtils<ConcreteFileSystemTestFixture>::TimestampUpdateBehavior TimestampTestUtils<ConcreteFileSystemTestFixture>::ExpectDoesntUpdateModificationTimestamp =
|
||||
[] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(timeBeforeOperation);
|
||||
UNUSED(timeAfterOperation);
|
||||
EXPECT_EQ(statBeforeOperation.st_mtim, statAfterOperation.st_mtim);
|
||||
};
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
typename TimestampTestUtils<ConcreteFileSystemTestFixture>::TimestampUpdateBehavior TimestampTestUtils<ConcreteFileSystemTestFixture>::ExpectUpdatesMetadataTimestamp =
|
||||
[] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(statBeforeOperation);
|
||||
EXPECT_LE(timeBeforeOperation, statAfterOperation.st_ctim);
|
||||
EXPECT_GE(timeAfterOperation, statAfterOperation.st_ctim);
|
||||
};
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
typename TimestampTestUtils<ConcreteFileSystemTestFixture>::TimestampUpdateBehavior TimestampTestUtils<ConcreteFileSystemTestFixture>::ExpectDoesntUpdateMetadataTimestamp =
|
||||
[] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
UNUSED(timeBeforeOperation);
|
||||
UNUSED(timeAfterOperation);
|
||||
EXPECT_EQ(statBeforeOperation.st_ctim, statAfterOperation.st_ctim);
|
||||
};
|
||||
|
||||
template<class ConcreteFileSystemTestFixture>
|
||||
typename TimestampTestUtils<ConcreteFileSystemTestFixture>::TimestampUpdateBehavior TimestampTestUtils<ConcreteFileSystemTestFixture>::ExpectDoesntUpdateAnyTimestamps =
|
||||
[] (struct stat statBeforeOperation, struct stat statAfterOperation, timespec timeBeforeOperation, timespec timeAfterOperation) {
|
||||
ExpectDoesntUpdateAccessTimestamp(statBeforeOperation, statAfterOperation, timeBeforeOperation, timeAfterOperation);
|
||||
ExpectDoesntUpdateModificationTimestamp(statBeforeOperation, statAfterOperation, timeBeforeOperation, timeAfterOperation);
|
||||
ExpectDoesntUpdateMetadataTimestamp(statBeforeOperation, statAfterOperation, timeBeforeOperation, timeAfterOperation);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "../fuse/FuseErrnoException.h"
|
||||
#include "../fs_interface/File.h"
|
||||
#include "../fs_interface/Node.h"
|
||||
|
||||
#include <cpp-utils/logging/logging.h>
|
||||
#include <cpp-utils/pointer/unique_ref.h>
|
||||
@ -93,62 +94,31 @@ FilesystemImpl::~FilesystemImpl() {
|
||||
|
||||
unique_ref<File> FilesystemImpl::LoadFile(const bf::path &path) {
|
||||
PROFILE(_loadFileNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if (node == none) {
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
}
|
||||
auto file = dynamic_pointer_move<File>(*node);
|
||||
auto file = _device->LoadFile(path);
|
||||
if (file == none) {
|
||||
throw fuse::FuseErrnoException(EISDIR);
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
}
|
||||
return std::move(*file);
|
||||
}
|
||||
|
||||
unique_ref<Dir> FilesystemImpl::LoadDir(const bf::path &path) {
|
||||
PROFILE(_loadDirNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if (node == none) {
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
}
|
||||
auto dir = dynamic_pointer_move<Dir>(*node);
|
||||
auto dir = _device->LoadDir(path);
|
||||
if (dir == none) {
|
||||
throw fuse::FuseErrnoException(ENOTDIR);
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
}
|
||||
return std::move(*dir);
|
||||
}
|
||||
|
||||
unique_ref<Symlink> FilesystemImpl::LoadSymlink(const bf::path &path) {
|
||||
PROFILE(_loadSymlinkNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if (node == none) {
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
}
|
||||
auto lnk = dynamic_pointer_move<Symlink>(*node);
|
||||
auto lnk = _device->LoadSymlink(path);
|
||||
if (lnk == none) {
|
||||
throw fuse::FuseErrnoException(ENOTDIR);
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
}
|
||||
return std::move(*lnk);
|
||||
}
|
||||
|
||||
unique_ref<Node> FilesystemImpl::LoadFileOrSymlink(const bf::path &path) {
|
||||
PROFILE(_loadFileOrSymlinkNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if (node == none) {
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
}
|
||||
auto file = dynamic_pointer_move<File>(*node);
|
||||
if (file != none) {
|
||||
return std::move(*file);
|
||||
}
|
||||
|
||||
auto symlink = dynamic_pointer_move<Symlink>(*node);
|
||||
if (symlink != none) {
|
||||
return std::move(*symlink);
|
||||
}
|
||||
|
||||
throw fuse::FuseErrnoException(EISDIR);
|
||||
}
|
||||
|
||||
int FilesystemImpl::openFile(const bf::path &path, int flags) {
|
||||
auto file = LoadFile(path);
|
||||
return openFile(file.get(), flags);
|
||||
@ -260,17 +230,25 @@ void FilesystemImpl::mkdir(const bf::path &path, mode_t mode, uid_t uid, gid_t g
|
||||
}
|
||||
|
||||
void FilesystemImpl::rmdir(const bf::path &path) {
|
||||
//TODO Don't allow removing files/symlinks with this
|
||||
PROFILE(_rmdirNanosec);
|
||||
auto dir = LoadDir(path);
|
||||
auto node = _device->Load(path);
|
||||
if(node == none) {
|
||||
throw fuse::FuseErrnoException(ENOENT);
|
||||
}
|
||||
PROFILE(_rmdirNanosec_withoutLoading);
|
||||
dir->remove();
|
||||
(*node)->remove();
|
||||
}
|
||||
|
||||
void FilesystemImpl::unlink(const bf::path &path) {
|
||||
//TODO Don't allow removing directories with this
|
||||
PROFILE(_unlinkNanosec);
|
||||
auto node = LoadFileOrSymlink(path);
|
||||
auto node = _device->Load(path);
|
||||
if (node == none) {
|
||||
throw fuse::FuseErrnoException(ENOENT);
|
||||
}
|
||||
PROFILE(_unlinkNanosec_withoutLoading);
|
||||
node->remove();
|
||||
(*node)->remove();
|
||||
}
|
||||
|
||||
void FilesystemImpl::rename(const bf::path &from, const bf::path &to) {
|
||||
|
@ -11,7 +11,7 @@ function (get_git_version OUTPUT_VARIABLE)
|
||||
IF(NOT ${result} EQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Error running versioneer. Return code is: ${result}, error message is: ${error}")
|
||||
ENDIF()
|
||||
IF("${STRIPPED_VERSION}" EQUAL "0+unknown")
|
||||
IF("${STRIPPED_VERSION}" STREQUAL "0+unknown")
|
||||
MESSAGE(FATAL_ERROR "Unable to find git version information. Please build directly from a git repository (i.e. after git clone).")
|
||||
ENDIF()
|
||||
endfunction(get_git_version)
|
||||
|
@ -59,8 +59,8 @@ TEST_F(CryFsTest, CreatedRootdirIsLoadableAfterClosing) {
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678);
|
||||
}
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678);
|
||||
auto root = dev.Load(bf::path("/"));
|
||||
dynamic_pointer_move<CryDir>(root.get()).get()->children();
|
||||
auto rootDir = dev.LoadDir(bf::path("/"));
|
||||
rootDir.value()->children();
|
||||
}
|
||||
|
||||
TEST_F(CryFsTest, LoadingFilesystemDoesntModifyConfigFile) {
|
||||
|
@ -17,11 +17,10 @@ public:
|
||||
static constexpr mode_t MODE_PUBLIC = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
|
||||
|
||||
unique_ref<CryNode> CreateFile(const bf::path &path) {
|
||||
auto _parentDir = device().Load(path.parent_path()).value();
|
||||
auto parentDir = dynamic_pointer_move<CryDir>(_parentDir).value();
|
||||
auto parentDir = device().LoadDir(path.parent_path()).value();
|
||||
parentDir->createAndOpenFile(path.filename().native(), MODE_PUBLIC, 0, 0);
|
||||
auto createdFile = device().Load(path).value();
|
||||
return dynamic_pointer_move<CryNode>(createdFile).value();
|
||||
auto file = device().Load(path).value();
|
||||
return dynamic_pointer_move<CryNode>(file).value();
|
||||
}
|
||||
|
||||
unique_ref<CryNode> CreateDir(const bf::path &path) {
|
||||
|
@ -22,9 +22,13 @@ function(target_activate_cpp14 TARGET)
|
||||
endif()
|
||||
endif(COMPILER_HAS_CPP14_SUPPORT)
|
||||
endif("${CMAKE_VERSION}" VERSION_GREATER "3.1")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# Ideally, we'd like to use libc++ on linux as well, but:
|
||||
# - http://stackoverflow.com/questions/37096062/get-a-basic-c-program-to-compile-using-clang-on-ubuntu-16
|
||||
# - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=808086
|
||||
# so only use it on Apple systems...
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND APPLE)
|
||||
target_compile_options(${TARGET} PUBLIC -stdlib=libc++)
|
||||
endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND APPLE)
|
||||
endfunction(target_activate_cpp14)
|
||||
|
||||
#################################################
|
||||
|
2
vendor/README
vendored
2
vendor/README
vendored
@ -1,6 +1,6 @@
|
||||
This directory contains external projects, taken from the following locations:
|
||||
scrypt: http://www.tarsnap.com/scrypt.html
|
||||
googletest: https://github.com/google/googletest
|
||||
googletest: https://github.com/google/googletest/tree/release-1.8.0
|
||||
spdlog: https://github.com/gabime/spdlog/commit/0c7beb2e36008598cf80d0e8eb8635ac403febb9
|
||||
- with own fix: https://github.com/cryfs/spdlog/commit/7b8d507615b8075fc6c8793a0965a32a708288c4
|
||||
gitversion: https://github.com/smessmer/gitversion
|
2
vendor/googletest/CMakeLists.txt
vendored
2
vendor/googletest/CMakeLists.txt
vendored
@ -4,7 +4,7 @@ if (BUILD_TESTING)
|
||||
# When test cases are build, disable "make install", because this would also install gtest libraries.
|
||||
macro(install)
|
||||
endmacro(install)
|
||||
add_subdirectory(gtest-1.7.0)
|
||||
add_subdirectory(gtest-1.8.0)
|
||||
|
||||
project (googletest)
|
||||
add_library(${PROJECT_NAME} dummy.cpp)
|
||||
|
2
vendor/googletest/gtest-1.8.0/.gitignore
vendored
Normal file
2
vendor/googletest/gtest-1.8.0/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Ignore CI build directory
|
||||
build/
|
46
vendor/googletest/gtest-1.8.0/.travis.yml
vendored
Normal file
46
vendor/googletest/gtest-1.8.0/.travis.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
# Build matrix / environment variable are explained on:
|
||||
# http://about.travis-ci.org/docs/user/build-configuration/
|
||||
# This file can be validated on:
|
||||
# http://lint.travis-ci.org/
|
||||
|
||||
install:
|
||||
# /usr/bin/gcc is 4.6 always, but gcc-X.Y is available.
|
||||
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
|
||||
# /usr/bin/clang is 3.4, lets override with modern one.
|
||||
- if [ "$CXX" = "clang++" ] && [ "$TRAVIS_OS_NAME" = "linux" ]; then export CXX="clang++-3.7" CC="clang-3.7"; fi
|
||||
- echo ${PATH}
|
||||
- echo ${CXX}
|
||||
- ${CXX} --version
|
||||
- ${CXX} -v
|
||||
addons:
|
||||
apt:
|
||||
# List of whitelisted in travis packages for ubuntu-precise can be found here:
|
||||
# https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise
|
||||
# List of whitelisted in travis apt-sources:
|
||||
# https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.7
|
||||
packages:
|
||||
- gcc-4.9
|
||||
- g++-4.9
|
||||
- clang-3.7
|
||||
- valgrind
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
script: ./travis.sh
|
||||
env:
|
||||
matrix:
|
||||
- GTEST_TARGET=googletest SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug VERBOSE_MAKE=true VERBOSE
|
||||
- GTEST_TARGET=googlemock SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug VERBOSE_MAKE=true VERBOSE
|
||||
- GTEST_TARGET=googlemock SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug CXX_FLAGS=-std=c++11 VERBOSE_MAKE=true VERBOSE
|
||||
# - GTEST_TARGET=googletest SHARED_LIB=ON STATIC_LIB=ON CMAKE_PKG=ON BUILD_TYPE=release VERBOSE_MAKE=false
|
||||
# - GTEST_TARGET=googlemock SHARED_LIB=ON STATIC_LIB=ON CMAKE_PKG=ON BUILD_TYPE=release VERBOSE_MAKE=false
|
||||
notifications:
|
||||
email: false
|
||||
sudo: false
|
@ -2,6 +2,7 @@
|
||||
# Google Test #
|
||||
|
||||
[![Build Status](https://travis-ci.org/google/googletest.svg?branch=master)](https://travis-ci.org/google/googletest)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/4o38plt0xbo1ubc8/branch/master?svg=true)](https://ci.appveyor.com/project/BillyDonahue/googletest/branch/master)
|
||||
|
||||
Welcome to **Google Test**, Google's C++ test framework!
|
||||
|
||||
@ -105,7 +106,7 @@ package (as described below):
|
||||
### Mac OS X Requirements ###
|
||||
|
||||
* Mac OS X v10.4 Tiger or newer
|
||||
* XCode Developer Tools
|
||||
* Xcode Developer Tools
|
||||
|
||||
### Requirements for Contributors ###
|
||||
|
71
vendor/googletest/gtest-1.8.0/appveyor.yml
vendored
Normal file
71
vendor/googletest/gtest-1.8.0/appveyor.yml
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
version: '{build}'
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- Toolset: v140
|
||||
- Toolset: v120
|
||||
- Toolset: v110
|
||||
- Toolset: v100
|
||||
|
||||
platform:
|
||||
- Win32
|
||||
- x64
|
||||
|
||||
configuration:
|
||||
# - Release
|
||||
- Debug
|
||||
|
||||
build:
|
||||
verbosity: minimal
|
||||
|
||||
artifacts:
|
||||
- path: '_build/Testing/Temporary/*'
|
||||
name: test_results
|
||||
|
||||
before_build:
|
||||
- ps: |
|
||||
Write-Output "Configuration: $env:CONFIGURATION"
|
||||
Write-Output "Platform: $env:PLATFORM"
|
||||
$generator = switch ($env:TOOLSET)
|
||||
{
|
||||
"v140" {"Visual Studio 14 2015"}
|
||||
"v120" {"Visual Studio 12 2013"}
|
||||
"v110" {"Visual Studio 11 2012"}
|
||||
"v100" {"Visual Studio 10 2010"}
|
||||
}
|
||||
if ($env:PLATFORM -eq "x64")
|
||||
{
|
||||
$generator = "$generator Win64"
|
||||
}
|
||||
|
||||
build_script:
|
||||
- ps: |
|
||||
if (($env:TOOLSET -eq "v100") -and ($env:PLATFORM -eq "x64"))
|
||||
{
|
||||
return
|
||||
}
|
||||
md _build -Force | Out-Null
|
||||
cd _build
|
||||
|
||||
& cmake -G "$generator" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -Dgtest_build_tests=ON -Dgtest_build_samples=ON -Dgmock_build_tests=ON ..
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Exec: $ErrorMessage"
|
||||
}
|
||||
& cmake --build . --config $env:CONFIGURATION
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Exec: $ErrorMessage"
|
||||
}
|
||||
|
||||
test_script:
|
||||
- ps: |
|
||||
if (($env:Toolset -eq "v100") -and ($env:PLATFORM -eq "x64"))
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
& ctest -C $env:CONFIGURATION --output-on-failure
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Exec: $ErrorMessage"
|
||||
}
|
@ -2103,7 +2103,7 @@ For better readability, Google Mock also gives you:
|
||||
* `WithArg<N>(action)` (no `s` after `Arg`) when the inner `action` takes _one_ argument.
|
||||
|
||||
As you may have realized, `InvokeWithoutArgs(...)` is just syntactic
|
||||
sugar for `WithoutArgs(Inovke(...))`.
|
||||
sugar for `WithoutArgs(Invoke(...))`.
|
||||
|
||||
Here are more tips:
|
||||
|
@ -44,7 +44,7 @@ We encourage you to use Google Mock as:
|
||||
* a _testing_ tool to cut your tests' outbound dependencies and probe the interaction between your module and its collaborators.
|
||||
|
||||
# Getting Started #
|
||||
Using Google Mock is easy! Inside your C++ source file, just #include `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go.
|
||||
Using Google Mock is easy! Inside your C++ source file, just `#include` `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go.
|
||||
|
||||
# A Case for Mock Turtles #
|
||||
Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-like API for drawing. How would you test that it does the right thing? Well, you can run it and compare the screen with a golden screen snapshot, but let's admit it: tests like this are expensive to run and fragile (What if you just upgraded to a shiny new graphics card that has better anti-aliasing? Suddenly you have to update all your golden images.). It would be too painful if all your tests are like this. Fortunately, you learned about Dependency Injection and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, `Turtle`) and code to that interface:
|
@ -44,7 +44,7 @@ We encourage you to use Google Mock as:
|
||||
* a _testing_ tool to cut your tests' outbound dependencies and probe the interaction between your module and its collaborators.
|
||||
|
||||
# Getting Started #
|
||||
Using Google Mock is easy! Inside your C++ source file, just #include `<gtest/gtest.h>` and `<gmock/gmock.h>`, and you are ready to go.
|
||||
Using Google Mock is easy! Inside your C++ source file, just `#include` `<gtest/gtest.h>` and `<gmock/gmock.h>`, and you are ready to go.
|
||||
|
||||
# A Case for Mock Turtles #
|
||||
Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-like API for drawing. How would you test that it does the right thing? Well, you can run it and compare the screen with a golden screen snapshot, but let's admit it: tests like this are expensive to run and fragile (What if you just upgraded to a shiny new graphics card that has better anti-aliasing? Suddenly you have to update all your golden images.). It would be too painful if all your tests are like this. Fortunately, you learned about Dependency Injection and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, `Turtle`) and code to that interface:
|
@ -44,7 +44,7 @@ We encourage you to use Google Mock as:
|
||||
* a _testing_ tool to cut your tests' outbound dependencies and probe the interaction between your module and its collaborators.
|
||||
|
||||
# Getting Started #
|
||||
Using Google Mock is easy! Inside your C++ source file, just #include `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go.
|
||||
Using Google Mock is easy! Inside your C++ source file, just `#include` `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go.
|
||||
|
||||
# A Case for Mock Turtles #
|
||||
Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-like API for drawing. How would you test that it does the right thing? Well, you can run it and compare the screen with a golden screen snapshot, but let's admit it: tests like this are expensive to run and fragile (What if you just upgraded to a shiny new graphics card that has better anti-aliasing? Suddenly you have to update all your golden images.). It would be too painful if all your tests are like this. Fortunately, you learned about Dependency Injection and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, `Turtle`) and code to that interface:
|
@ -44,7 +44,7 @@ We encourage you to use Google Mock as:
|
||||
* a _testing_ tool to cut your tests' outbound dependencies and probe the interaction between your module and its collaborators.
|
||||
|
||||
# Getting Started #
|
||||
Using Google Mock is easy! Inside your C++ source file, just #include `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go.
|
||||
Using Google Mock is easy! Inside your C++ source file, just `#include` `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go.
|
||||
|
||||
# A Case for Mock Turtles #
|
||||
Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-like API for drawing. How would you test that it does the right thing? Well, you can run it and compare the screen with a golden screen snapshot, but let's admit it: tests like this are expensive to run and fragile (What if you just upgraded to a shiny new graphics card that has better anti-aliasing? Suddenly you have to update all your golden images.). It would be too painful if all your tests are like this. Fortunately, you learned about Dependency Injection and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, `Turtle`) and code to that interface:
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user