From 7dcb29d515ec21f8ac740cae78621e4d93baa442 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Tue, 21 Jul 2015 19:45:44 +0200 Subject: [PATCH] Implemented fspp_assert() --- fuse/Fuse.cpp | 73 +++++++++++++++++++++++++++++- test/utils/assert_debug_test.cpp | 26 +++++++++++ test/utils/assert_release_test.cpp | 30 ++++++++++++ utils/IOException.cpp | 1 + utils/IOException.h | 22 +++++++++ utils/assert.h | 32 +++++++++++++ 6 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 test/utils/assert_debug_test.cpp create mode 100644 test/utils/assert_release_test.cpp create mode 100644 utils/IOException.cpp create mode 100644 utils/IOException.h create mode 100644 utils/assert.h diff --git a/fuse/Fuse.cpp b/fuse/Fuse.cpp index 266f3d37..4b721e2b 100644 --- a/fuse/Fuse.cpp +++ b/fuse/Fuse.cpp @@ -3,7 +3,9 @@ #include #include "FuseErrnoException.h" +#include "../utils/IOException.h" #include "Filesystem.h" +#include using std::string; @@ -221,6 +223,9 @@ int Fuse::getattr(const bf::path &path, struct stat *stbuf) { try { _fs->lstat(path, stbuf); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::getattr: " << e.what() << std::endl; + return -EIO; } catch(fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -240,7 +245,10 @@ int Fuse::fgetattr(const bf::path &path, struct stat *stbuf, fuse_file_info *fil try { _fs->fstat(fileinfo->fh, stbuf); - return 0; + return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::fgetattr: " << e.what() << std::endl; + return -EIO; } catch(fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -251,6 +259,9 @@ int Fuse::readlink(const bf::path &path, char *buf, size_t size) { try { _fs->readSymlink(path, buf, size); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::readlink: " << e.what() << std::endl; + return -EIO; } catch (fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -270,6 +281,9 @@ int Fuse::mkdir(const bf::path &path, mode_t mode) { auto context = fuse_get_context(); _fs->mkdir(path, mode, context->uid, context->gid); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::mkdir: " << e.what() << std::endl; + return -EIO; } catch(fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -280,6 +294,9 @@ int Fuse::unlink(const bf::path &path) { try { _fs->unlink(path); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::unlink: " << e.what() << std::endl; + return -EIO; } catch(fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -289,6 +306,9 @@ int Fuse::rmdir(const bf::path &path) { try { _fs->rmdir(path); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::rmdir: " << e.what() << std::endl; + return -EIO; } catch(fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -300,6 +320,9 @@ int Fuse::symlink(const bf::path &from, const bf::path &to) { auto context = fuse_get_context(); _fs->createSymlink(from, to, context->uid, context->gid); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::symlink: " << e.what() << std::endl; + return -EIO; } catch(fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -310,6 +333,9 @@ int Fuse::rename(const bf::path &from, const bf::path &to) { try { _fs->rename(from, to); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::rename: " << e.what() << std::endl; + return -EIO; } catch(fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -329,6 +355,9 @@ int Fuse::chmod(const bf::path &path, mode_t mode) { try { _fs->chmod(path, mode); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::chmod: " << e.what() << std::endl; + return -EIO; } catch (fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -338,6 +367,9 @@ int Fuse::chown(const bf::path &path, uid_t uid, gid_t gid) { try { _fs->chown(path, uid, gid); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::chown: " << e.what() << std::endl; + return -EIO; } catch (fspp::fuse::FuseErrnoException &e) { return -e.getErrno(); } @@ -348,6 +380,9 @@ int Fuse::truncate(const bf::path &path, off_t size) { try { _fs->truncate(path, size); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::truncate: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -359,6 +394,9 @@ int Fuse::ftruncate(const bf::path &path, off_t size, fuse_file_info *fileinfo) try { _fs->ftruncate(fileinfo->fh, size); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::ftruncate: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -370,6 +408,9 @@ int Fuse::utimens(const bf::path &path, const timespec times[2]) { try { _fs->utimens(path, times); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::utimens: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -380,6 +421,9 @@ int Fuse::open(const bf::path &path, fuse_file_info *fileinfo) { try { fileinfo->fh = _fs->openFile(path, fileinfo->flags); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::open: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -391,6 +435,9 @@ int Fuse::release(const bf::path &path, fuse_file_info *fileinfo) { try { _fs->closeFile(fileinfo->fh); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::release: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -401,6 +448,9 @@ int Fuse::read(const bf::path &path, char *buf, size_t size, off_t offset, fuse_ UNUSED(path); try { return _fs->read(fileinfo->fh, buf, size, offset); + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::read: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -412,6 +462,9 @@ int Fuse::write(const bf::path &path, const char *buf, size_t size, off_t offset try { _fs->write(fileinfo->fh, buf, size, offset); return size; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::write: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -423,6 +476,9 @@ int Fuse::statfs(const bf::path &path, struct statvfs *fsstat) { try { _fs->statfs(path, fsstat); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::statfs: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -435,6 +491,9 @@ int Fuse::flush(const bf::path &path, fuse_file_info *fileinfo) { try { _fs->flush(fileinfo->fh); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::flush: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -450,6 +509,9 @@ int Fuse::fsync(const bf::path &path, int datasync, fuse_file_info *fileinfo) { _fs->fsync(fileinfo->fh); } return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::fsync: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -489,6 +551,9 @@ int Fuse::readdir(const bf::path &path, void *buf, fuse_fill_dir_t filler, off_t } } return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::readdir: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -527,6 +592,9 @@ int Fuse::access(const bf::path &path, int mask) { try { _fs->access(path, mask); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::access: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } @@ -538,6 +606,9 @@ int Fuse::create(const bf::path &path, mode_t mode, fuse_file_info *fileinfo) { auto context = fuse_get_context(); fileinfo->fh = _fs->createAndOpenFile(path, mode, context->uid, context->gid); return 0; + } catch(const fspp::IOException &e) { + std::cerr << "IOException in Fuse::create: " << e.what() << std::endl; + return -EIO; } catch (FuseErrnoException &e) { return -e.getErrno(); } diff --git a/test/utils/assert_debug_test.cpp b/test/utils/assert_debug_test.cpp new file mode 100644 index 00000000..f371685c --- /dev/null +++ b/test/utils/assert_debug_test.cpp @@ -0,0 +1,26 @@ +#include +#include + +//Include the fspp_assert macro for a debug build +#undef NDEBUG +#include "../../utils/assert.h" + +using testing::MatchesRegex; + +TEST(AssertTest_DebugBuild, DoesntDieIfTrue) { + fspp_assert(true, "bla"); +} + +TEST(AssertTest_DebugBuild, DiesIfFalse) { + EXPECT_DEATH( + fspp_assert(false, "bla"), + "" + ); +} + +TEST(AssertTest_DebugBuild, AssertMessage) { + EXPECT_DEATH( + fspp_assert(2==5, "my message"), + "Assertion \\[2==5\\] failed in .*/assert_debug_test.cpp:25: my message" + ); +} \ No newline at end of file diff --git a/test/utils/assert_release_test.cpp b/test/utils/assert_release_test.cpp new file mode 100644 index 00000000..d961fd63 --- /dev/null +++ b/test/utils/assert_release_test.cpp @@ -0,0 +1,30 @@ +#include +#include + +//Include the fspp_assert macro for a release build +#define NDEBUG +#include "../../utils/assert.h" + +using testing::MatchesRegex; + +TEST(AssertTest_ReleaseBuild, DoesntThrowIfTrue) { + fspp_assert(true, "bla"); +} + +TEST(AssertTest_ReleaseBuild, ThrowsIfFalse) { + EXPECT_THROW( + fspp_assert(false, "bla"), + fspp::IOException + ); +} + +TEST(AssertTest_ReleaseBuild, AssertMessage) { + try { + fspp_assert(2==5, "my message"); + FAIL(); + } catch (const fspp::IOException &e) { + EXPECT_THAT(e.what(), MatchesRegex( + "Assertion \\[2==5\\] failed in .*/assert_release_test.cpp:23: my message" + )); + } +} \ No newline at end of file diff --git a/utils/IOException.cpp b/utils/IOException.cpp new file mode 100644 index 00000000..2cd303e4 --- /dev/null +++ b/utils/IOException.cpp @@ -0,0 +1 @@ +#include "IOException.h" diff --git a/utils/IOException.h b/utils/IOException.h new file mode 100644 index 00000000..74f6e9f1 --- /dev/null +++ b/utils/IOException.h @@ -0,0 +1,22 @@ +#ifndef CRYFS_IOEXCEPTION_H +#define CRYFS_IOEXCEPTION_H + +#include + +namespace fspp { + + class IOException : public std::exception { + public: + IOException(const std::string &message) : _message(message) { } + + const char *what() const throw() override { + return _message.c_str(); + } + + private: + std::string _message; + }; + +} + +#endif diff --git a/utils/assert.h b/utils/assert.h new file mode 100644 index 00000000..f220f623 --- /dev/null +++ b/utils/assert.h @@ -0,0 +1,32 @@ +#ifndef CRYFS_ASSERT_H +#define CRYFS_ASSERT_H + +#include "IOException.h" +#include +#include + +namespace fspp { + namespace _assert { + inline std::string format(const char *expr, const char *message, const char *file, int line) { + return std::string()+"Assertion ["+expr+"] failed in "+file+":"+std::to_string(line)+": "+message; + } + + inline void assert_fail_release(const char *expr, const char *message, const char *file, int line) { + throw IOException(format(expr, message, file, line)); + } + + inline void assert_fail_debug(const char *expr, const char *message, const char *file, int line) { + std::cerr << format(expr, message, file, line) << std::endl; + abort(); + } + } +} + +#ifdef NDEBUG +//TODO Check whether disabling assertions in prod affects speed. +# define fspp_assert(expr, msg) (void)((expr) || (fspp::_assert::assert_fail_release(#expr, msg, __FILE__, __LINE__),0)) +#else +# define fspp_assert(expr, msg) (void)((expr) || (fspp::_assert::assert_fail_debug(#expr, msg, __FILE__, __LINE__),0)) +#endif + +#endif