2014-11-27 16:40:22 +01:00
# include "testutils/FuseWriteTest.h"
2018-05-21 08:18:34 +02:00
# include "fspp/fs_interface/FuseErrnoException.h"
2014-11-27 16:40:22 +01:00
using : : testing : : WithParamInterface ;
using : : testing : : Values ;
using : : testing : : Eq ;
using : : testing : : Ne ;
using : : testing : : Invoke ;
using : : testing : : Throw ;
2014-11-28 14:46:45 +01:00
using namespace fspp : : fuse ;
2014-11-27 16:40:22 +01:00
class FuseWriteErrorTest : public FuseWriteTest , public WithParamInterface < int > {
public :
2018-09-15 23:32:58 +02:00
fspp : : num_bytes_t FILESIZE = fspp : : num_bytes_t ( 64 * 1024 * 1024 ) ;
fspp : : num_bytes_t WRITECOUNT = fspp : : num_bytes_t ( 32 * 1024 * 1024 ) ;
2014-11-27 16:40:22 +01:00
void SetUp ( ) override {
2014-11-27 16:40:44 +01:00
//Make the file size big enough that fuse should issue at least two writes
2014-11-27 16:40:22 +01:00
ReturnIsFileOnLstatWithSize ( FILENAME , FILESIZE ) ;
OnOpenReturnFileDescriptor ( FILENAME , 0 ) ;
}
} ;
2019-10-13 14:16:06 +02:00
INSTANTIATE_TEST_SUITE_P ( FuseWriteErrorTest , FuseWriteErrorTest , Values ( EAGAIN , EBADF , EDESTADDRREQ , EDQUOT , EFAULT , EFBIG , EINTR , EINVAL , EIO , ENOSPC , EPIPE , EOVERFLOW , ESPIPE , ENXIO ) ) ;
2014-11-27 16:40:22 +01:00
TEST_P ( FuseWriteErrorTest , ReturnErrorOnFirstWriteCall ) {
2021-04-21 08:09:00 +02:00
EXPECT_CALL ( * fsimpl , write ( 0 , testing : : _ , testing : : _ , testing : : _ ) )
2014-11-27 16:40:22 +01:00
. WillRepeatedly ( Throw ( FuseErrnoException ( GetParam ( ) ) ) ) ;
2018-09-15 23:32:58 +02:00
char * buf = new char [ WRITECOUNT . value ( ) ] ;
auto retval = WriteFileReturnError ( FILENAME , buf , WRITECOUNT , fspp : : num_bytes_t ( 0 ) ) ;
2014-12-06 15:33:01 +01:00
EXPECT_EQ ( GetParam ( ) , retval . error ) ;
2014-11-27 16:40:22 +01:00
delete [ ] buf ;
}
TEST_P ( FuseWriteErrorTest , ReturnErrorOnSecondWriteCall ) {
// The first write request is from the beginning of the file and works, but the later ones fail.
// We store the number of bytes the first call could successfully write and check later that our
// write syscall returns exactly this number of bytes
2018-09-15 23:32:58 +02:00
fspp : : num_bytes_t successfullyWrittenBytes = fspp : : num_bytes_t ( - 1 ) ;
2021-04-21 08:09:00 +02:00
EXPECT_CALL ( * fsimpl , write ( 0 , testing : : _ , testing : : _ , Eq ( fspp : : num_bytes_t ( 0 ) ) ) )
2014-11-27 16:40:22 +01:00
. Times ( 1 )
2018-09-15 23:32:58 +02:00
. WillOnce ( Invoke ( [ & successfullyWrittenBytes ] ( int , const void * , fspp : : num_bytes_t count , fspp : : num_bytes_t ) {
2014-11-27 16:40:22 +01:00
// Store the number of successfully written bytes
successfullyWrittenBytes = count ;
} ) ) ;
2021-04-21 08:09:00 +02:00
EXPECT_CALL ( * fsimpl , write ( 0 , testing : : _ , testing : : _ , Ne ( fspp : : num_bytes_t ( 0 ) ) ) )
2014-11-27 16:40:22 +01:00
. WillRepeatedly ( Throw ( FuseErrnoException ( GetParam ( ) ) ) ) ;
2018-09-15 23:32:58 +02:00
char * buf = new char [ WRITECOUNT . value ( ) ] ;
auto retval = WriteFileReturnError ( FILENAME , buf , WRITECOUNT , fspp : : num_bytes_t ( 0 ) ) ;
2014-12-06 15:33:01 +01:00
EXPECT_EQ ( 0 , retval . error ) ;
EXPECT_EQ ( successfullyWrittenBytes , retval . written_bytes ) ; // Check that we're getting the number of successfully written bytes (the first write call) returned
2014-11-27 16:40:22 +01:00
delete [ ] buf ;
}