2014-11-27 03:48:38 +01:00
|
|
|
#include "testutils/FuseReadTest.h"
|
|
|
|
|
2018-05-21 08:18:34 +02:00
|
|
|
#include "fspp/fs_interface/FuseErrnoException.h"
|
2014-11-27 03:48:38 +01:00
|
|
|
|
|
|
|
using ::testing::_;
|
|
|
|
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 03:48:38 +01:00
|
|
|
|
|
|
|
class FuseReadErrorTest: public FuseReadTest, 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 READCOUNT = fspp::num_bytes_t(32*1024*1024);
|
2014-11-27 03:48:38 +01:00
|
|
|
|
|
|
|
void SetUp() override {
|
|
|
|
//Make the file size big enough that fuse should issue at least two reads
|
|
|
|
ReturnIsFileOnLstatWithSize(FILENAME, FILESIZE);
|
|
|
|
OnOpenReturnFileDescriptor(FILENAME, 0);
|
|
|
|
}
|
|
|
|
};
|
2019-10-13 14:16:06 +02:00
|
|
|
INSTANTIATE_TEST_SUITE_P(FuseReadErrorTest, FuseReadErrorTest, Values(EAGAIN, EBADF, EFAULT, EINTR, EINVAL, EIO, EISDIR, EOVERFLOW, ESPIPE, ENXIO));
|
2014-11-27 03:48:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
TEST_P(FuseReadErrorTest, ReturnErrorOnFirstReadCall) {
|
2018-12-03 07:57:21 +01:00
|
|
|
EXPECT_CALL(*fsimpl, read(0, _, _, _))
|
2014-11-27 03:48:38 +01:00
|
|
|
.WillRepeatedly(Throw(FuseErrnoException(GetParam())));
|
|
|
|
|
2018-09-15 23:32:58 +02:00
|
|
|
char *buf = new char[READCOUNT.value()];
|
|
|
|
auto retval = ReadFileReturnError(FILENAME, buf, READCOUNT, fspp::num_bytes_t(0));
|
2014-12-06 15:33:01 +01:00
|
|
|
EXPECT_EQ(GetParam(), retval.error);
|
2014-11-27 03:48:38 +01:00
|
|
|
delete[] buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(FuseReadErrorTest, ReturnErrorOnSecondReadCall) {
|
|
|
|
// The first read 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 read and check later that our
|
|
|
|
// read syscall returns exactly this number of bytes
|
2018-09-15 23:32:58 +02:00
|
|
|
fspp::num_bytes_t successfullyReadBytes = fspp::num_bytes_t(-1);
|
2018-12-03 07:57:21 +01:00
|
|
|
EXPECT_CALL(*fsimpl, read(0, _, _, Eq(fspp::num_bytes_t(0))))
|
2014-11-27 03:48:38 +01:00
|
|
|
.Times(1)
|
2018-09-15 23:32:58 +02:00
|
|
|
.WillOnce(Invoke([&successfullyReadBytes](int, void*, fspp::num_bytes_t count, fspp::num_bytes_t) {
|
2014-11-27 03:48:38 +01:00
|
|
|
// Store the number of successfully read bytes
|
|
|
|
successfullyReadBytes = count;
|
|
|
|
return count;
|
|
|
|
}));
|
2018-12-03 07:57:21 +01:00
|
|
|
EXPECT_CALL(*fsimpl, read(0, _, _, Ne(fspp::num_bytes_t(0))))
|
2014-11-27 03:48:38 +01:00
|
|
|
.WillRepeatedly(Throw(FuseErrnoException(GetParam())));
|
|
|
|
|
2018-09-15 23:32:58 +02:00
|
|
|
char *buf = new char[READCOUNT.value()];
|
|
|
|
auto retval = ReadFileReturnError(FILENAME, buf, READCOUNT, fspp::num_bytes_t(0));
|
2014-12-06 15:33:01 +01:00
|
|
|
EXPECT_EQ(0, retval.error);
|
|
|
|
EXPECT_EQ(successfullyReadBytes, retval.read_bytes); // Check that we're getting the number of successfully read bytes (the first read call) returned
|
2014-11-27 03:48:38 +01:00
|
|
|
delete[] buf;
|
|
|
|
}
|