2014-11-19 00:25:57 +01:00
# pragma once
# ifndef TEST_TESTUTILS_FUSETEST_H_
# define TEST_TESTUTILS_FUSETEST_H_
2015-02-17 00:48:49 +01:00
# include "google/gtest/gtest.h"
# include "google/gmock/gmock.h"
2014-11-19 00:25:57 +01:00
2015-02-17 00:48:49 +01:00
# include "../../fuse/Filesystem.h"
# include "../../fuse/FuseErrnoException.h"
# include "../../fuse/Fuse.h"
2015-03-10 21:51:12 +01:00
# include "../../fs_interface/Dir.h"
2014-11-19 00:25:57 +01:00
# include <boost/filesystem.hpp>
2015-04-25 03:47:30 +02:00
# include <messmer/cpp-utils/tempfile/TempDir.h>
2014-11-19 00:40:46 +01:00
# include "FuseThread.h"
2014-11-19 00:25:57 +01:00
# define MOCK_PATH_METHOD1(NAME, RETURNTYPE) \
2014-11-27 16:51:15 +01:00
RETURNTYPE NAME ( const boost : : filesystem : : path & path ) override { \
2014-11-19 00:25:57 +01:00
return NAME ( path . c_str ( ) ) ; \
} \
MOCK_METHOD1 ( NAME , RETURNTYPE ( const char * ) ) ; \
2014-11-27 16:51:15 +01:00
# define MOCK_PATH_METHOD2(NAME, RETURNTYPE, PARAM1) \
2014-11-19 00:25:57 +01:00
RETURNTYPE NAME ( const boost : : filesystem : : path & path , PARAM1 param1 ) override { \
2014-11-27 16:51:15 +01:00
return NAME ( path . c_str ( ) , param1 ) ; \
} \
MOCK_METHOD2 ( NAME , RETURNTYPE ( const char * , PARAM1 ) ) ; \
2014-11-19 00:25:57 +01:00
2015-04-25 03:26:59 +02:00
# define MOCK_PATH_METHOD3(NAME, RETURNTYPE, PARAM1, PARAM2) \
RETURNTYPE NAME ( const boost : : filesystem : : path & path , PARAM1 p1 , PARAM2 p2 ) override { \
return NAME ( path . c_str ( ) , p1 , p2 ) ; \
} \
MOCK_METHOD3 ( NAME , RETURNTYPE ( const char * , PARAM1 , PARAM2 ) ) ; \
2014-11-27 16:51:15 +01:00
# define MOCK_PATH_METHOD4(NAME, RETURNTYPE, PARAM1, PARAM2, PARAM3) \
2014-11-19 00:25:57 +01:00
RETURNTYPE NAME ( const boost : : filesystem : : path & path , PARAM1 p1 , PARAM2 p2 , PARAM3 p3 ) override { \
2014-11-27 16:51:15 +01:00
return NAME ( path . c_str ( ) , p1 , p2 , p3 ) ; \
} \
MOCK_METHOD4 ( NAME , RETURNTYPE ( const char * , PARAM1 , PARAM2 , PARAM3 ) ) ; \
2014-11-19 00:25:57 +01:00
2014-11-28 14:46:45 +01:00
class MockFilesystem : public fspp : : fuse : : Filesystem {
2014-11-19 00:25:57 +01:00
public :
2014-11-25 15:01:33 +01:00
MockFilesystem ( ) ;
virtual ~ MockFilesystem ( ) ;
2014-11-19 00:25:57 +01:00
MOCK_PATH_METHOD2 ( openFile , int , int ) ;
MOCK_METHOD1 ( closeFile , void ( int ) ) ;
MOCK_PATH_METHOD2 ( lstat , void , struct : : stat * ) ;
MOCK_METHOD2 ( fstat , void ( int , struct : : stat * ) ) ;
MOCK_PATH_METHOD2 ( truncate , void , off_t ) ;
MOCK_METHOD2 ( ftruncate , void ( int , off_t ) ) ;
MOCK_METHOD4 ( read , int ( int , void * , size_t , off_t ) ) ;
MOCK_METHOD4 ( write , void ( int , const void * , size_t , off_t ) ) ;
2014-11-21 01:11:24 +01:00
MOCK_METHOD1 ( flush , void ( int ) ) ;
2014-11-19 00:25:57 +01:00
MOCK_METHOD1 ( fsync , void ( int ) ) ;
MOCK_METHOD1 ( fdatasync , void ( int ) ) ;
MOCK_PATH_METHOD2 ( access , void , int ) ;
2015-04-25 03:26:59 +02:00
MOCK_PATH_METHOD4 ( createAndOpenFile , int , mode_t , uid_t , gid_t ) ;
MOCK_PATH_METHOD4 ( mkdir , void , mode_t , uid_t , gid_t ) ;
2014-11-19 00:25:57 +01:00
MOCK_PATH_METHOD1 ( rmdir , void ) ;
MOCK_PATH_METHOD1 ( unlink , void ) ;
void rename ( const boost : : filesystem : : path & from , const boost : : filesystem : : path & to ) override {
return rename ( from . c_str ( ) , to . c_str ( ) ) ;
}
MOCK_METHOD2 ( rename , void ( const char * , const char * ) ) ;
2015-06-18 19:30:52 +02:00
cpputils : : unique_ref < std : : vector < fspp : : Dir : : Entry > > readDir ( const boost : : filesystem : : path & path ) {
return std : : move ( cpputils : : nullcheck ( std : : unique_ptr < std : : vector < fspp : : Dir : : Entry > > ( readDir ( path . c_str ( ) ) ) ) . get ( ) ) ;
2014-11-19 00:25:57 +01:00
}
2015-03-10 21:51:12 +01:00
MOCK_METHOD1 ( readDir , std : : vector < fspp : : Dir : : Entry > * ( const char * ) ) ;
2014-11-19 00:25:57 +01:00
void utimens ( const boost : : filesystem : : path & path , const timespec ts [ 2 ] ) override {
return utimens ( path . c_str ( ) , ts ) ;
}
MOCK_METHOD2 ( utimens , void ( const char * , const timespec [ 2 ] ) ) ;
MOCK_PATH_METHOD2 ( statfs , void , struct statvfs * ) ;
2015-04-25 03:26:59 +02:00
void createSymlink ( const boost : : filesystem : : path & to , const boost : : filesystem : : path & from , uid_t uid , gid_t gid ) override {
return createSymlink ( to . c_str ( ) , from . c_str ( ) , uid , gid ) ;
}
MOCK_PATH_METHOD2 ( chmod , void , mode_t ) ;
MOCK_PATH_METHOD3 ( chown , void , uid_t , gid_t ) ;
MOCK_METHOD4 ( createSymlink , void ( const char * , const char * , uid_t , gid_t ) ) ;
MOCK_PATH_METHOD3 ( readSymlink , void , char * , size_t ) ;
2014-11-19 00:25:57 +01:00
} ;
class FuseTest : public : : testing : : Test {
public :
2014-11-25 14:29:44 +01:00
const char * FILENAME = " /myfile " ;
2014-11-27 16:51:15 +01:00
FuseTest ( ) ;
2014-11-19 00:25:57 +01:00
class TempTestFS {
public :
2014-11-27 16:51:15 +01:00
TempTestFS ( MockFilesystem * fsimpl ) ;
virtual ~ TempTestFS ( ) ;
2014-11-19 00:25:57 +01:00
public :
2014-11-27 16:51:15 +01:00
const boost : : filesystem : : path & mountDir ( ) const ;
2014-11-19 00:25:57 +01:00
private :
2015-04-25 03:47:30 +02:00
cpputils : : TempDir _mountDir ;
2014-11-19 00:25:57 +01:00
fspp : : fuse : : Fuse _fuse ;
FuseThread _fuse_thread ;
} ;
2015-06-18 19:30:52 +02:00
cpputils : : unique_ref < TempTestFS > TestFS ( ) ;
2014-11-19 00:25:57 +01:00
2014-11-25 13:07:15 +01:00
MockFilesystem fsimpl ;
2014-11-19 00:38:41 +01:00
2014-11-27 16:51:15 +01:00
static : : testing : : Action < void ( const char * , struct : : stat * ) > ReturnIsFileWithSize ( size_t size ) ;
2014-11-25 14:29:44 +01:00
2014-11-27 16:51:15 +01:00
//TODO Combine ReturnIsFile and ReturnIsFileFstat. This should be possible in gmock by either (a) using ::testing::Undefined as parameter type or (b) using action macros
static : : testing : : Action < void ( const char * , struct : : stat * ) > ReturnIsFile ;
static : : testing : : Action < void ( int , struct : : stat * ) > ReturnIsFileFstat ;
static : : testing : : Action < void ( const char * , struct : : stat * ) > ReturnIsDir ;
static : : testing : : Action < void ( const char * , struct : : stat * ) > ReturnDoesntExist ;
2014-11-25 14:29:44 +01:00
2015-02-17 00:48:49 +01:00
void ReturnIsFileOnLstat ( const boost : : filesystem : : path & path ) ;
void ReturnIsFileOnLstatWithSize ( const boost : : filesystem : : path & path , const size_t size ) ;
void ReturnIsDirOnLstat ( const boost : : filesystem : : path & path ) ;
void ReturnDoesntExistOnLstat ( const boost : : filesystem : : path & path ) ;
2014-11-25 18:43:50 +01:00
void OnOpenReturnFileDescriptor ( const char * filename , int descriptor ) ;
void ReturnIsFileOnFstat ( int descriptor ) ;
2014-11-19 00:25:57 +01:00
} ;
# endif