Test if File::size can handle maximum file size.

This commit is contained in:
Victor Zverovich
2014-09-12 11:12:22 -07:00
parent e34e9fa0c7
commit 949c3c5df4
3 changed files with 52 additions and 9 deletions

View File

@ -145,7 +145,7 @@ void fmt::File::close() {
fmt::LongLong fmt::File::size() const { fmt::LongLong fmt::File::size() const {
#ifdef _WIN32 #ifdef _WIN32
LARGE_INTEGER size = {}; LARGE_INTEGER size = {};
if (!GetFileSizeEx(_get_osfhandle(fd_), &size)) if (!FMT_SYSTEM(GetFileSizeEx(_get_osfhandle(fd_), &size)))
throw WindowsError(GetLastError(), "cannot get file size"); throw WindowsError(GetLastError(), "cannot get file size");
FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(size.QuadPart), FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(size.QuadPart),
"return type of File::size is not large enough"); "return type of File::size is not large enough");
@ -153,7 +153,7 @@ fmt::LongLong fmt::File::size() const {
#else #else
typedef struct stat Stat; typedef struct stat Stat;
Stat file_stat = Stat(); Stat file_stat = Stat();
if (fstat(fd_, &file_stat) == -1) if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
throw SystemError(errno, "cannot get file attributes"); throw SystemError(errno, "cannot get file attributes");
FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(file_stat.st_size), FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(file_stat.st_size),
"return type of File::size is not large enough"); "return type of File::size is not large enough");

View File

@ -55,6 +55,15 @@ int fclose_count;
int fileno_count; int fileno_count;
std::size_t read_nbyte; std::size_t read_nbyte;
std::size_t write_nbyte; std::size_t write_nbyte;
bool increase_file_size;
std::string TEST_FILE_CONTENT = "top secret, destroy before reading";
void WriteTestFile() {
BufferedFile bf("test", "w");
bf.print(TEST_FILE_CONTENT);
bf.close();
}
} }
#define EMULATE_EINTR(func, error_result) \ #define EMULATE_EINTR(func, error_result) \
@ -70,12 +79,30 @@ int test::open(const char *path, int oflag, int mode) {
EMULATE_EINTR(open, -1); EMULATE_EINTR(open, -1);
return ::open(path, oflag, mode); return ::open(path, oflag, mode);
} }
static off_t max_file_size() { return std::numeric_limits<off_t>::max(); }
int test::fstat(int fd, struct stat *buf) {
int result = ::fstat(fd, buf);
if (increase_file_size)
buf->st_size = max_file_size();
return result;
}
#else #else
errno_t test::sopen_s( errno_t test::sopen_s(
int* pfh, const char *filename, int oflag, int shflag, int pmode) { int* pfh, const char *filename, int oflag, int shflag, int pmode) {
EMULATE_EINTR(open, EINTR); EMULATE_EINTR(open, EINTR);
return _sopen_s(pfh, filename, oflag, shflag, pmode); return _sopen_s(pfh, filename, oflag, shflag, pmode);
} }
static LONGLONG max_file_size() {return std::numeric_limits<LONGLONG>::max(); }
BOOL test::GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize) {
BOOL result = GetFileSizeEx(hFile, lpFileSize);
if (increase_file_size)
lpFileSize->QuadPart = max_file_size();
return result;
}
#endif #endif
int test::close(int fildes) { int test::close(int fildes) {
@ -195,16 +222,24 @@ TEST(FileTest, CloseNoRetry) {
} }
TEST(FileTest, Size) { TEST(FileTest, Size) {
BufferedFile bf("test", "w"); WriteTestFile();
std::string content = "top secret, destroy before reading";
bf.print(content);
bf.close();
File f("test", File::RDONLY); File f("test", File::RDONLY);
EXPECT_EQ(content.size(), f.size()); EXPECT_EQ(TEST_FILE_CONTENT.size(), f.size());
// TODO: test if size can handle large file sizes f.close();
// TODO: test FMT_STATIC_ASSERT EXPECT_SYSTEM_ERROR(f.size(), EBADF, "cannot get file attributes");
} }
TEST(FileTest, MaxSize) {
WriteTestFile();
File f("test", File::RDONLY);
increase_file_size = true;
EXPECT_GE(f.size(), 0);
EXPECT_EQ(max_file_size(), f.size());
increase_file_size = false;
}
// TODO: test FMT_STATIC_ASSERT
TEST(FileTest, ReadRetry) { TEST(FileTest, ReadRetry) {
File read_end, write_end; File read_end, write_end;
File::pipe(read_end, write_end); File::pipe(read_end, write_end);

View File

@ -31,6 +31,12 @@
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#ifndef _WIN32
struct stat;
#else
# include <windows.h>
#endif
namespace test { namespace test {
#ifndef _WIN32 #ifndef _WIN32
@ -38,11 +44,13 @@ namespace test {
typedef size_t size_t; typedef size_t size_t;
typedef ssize_t ssize_t; typedef ssize_t ssize_t;
int open(const char *path, int oflag, int mode); int open(const char *path, int oflag, int mode);
int fstat(int fd, struct stat *buf);
#else #else
typedef unsigned size_t; typedef unsigned size_t;
typedef int ssize_t; typedef int ssize_t;
errno_t sopen_s( errno_t sopen_s(
int* pfh, const char *filename, int oflag, int shflag, int pmode); int* pfh, const char *filename, int oflag, int shflag, int pmode);
BOOL GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize);
#endif #endif
int close(int fildes); int close(int fildes);