Skip to content

Commit

Permalink
restruct SrsFileWriter to use libc file functions mockable
Browse files Browse the repository at this point in the history
  • Loading branch information
bluestn committed Dec 17, 2022
1 parent c24a000 commit 9c4996c
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 10 deletions.
28 changes: 18 additions & 10 deletions trunk/src/kernel/srs_kernel_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ srs_read_t _srs_read_fn = ::read;
srs_lseek_t _srs_lseek_fn = ::lseek;
srs_close_t _srs_close_fn = ::close;

srs_fopen_t _srs_fopen_fn = ::fopen;
srs_fwrite_t _srs_fwrite_fn = ::fwrite;
srs_fread_t _srs_fread_fn = ::fread;
srs_fseek_t _srs_fseek_fn = ::fseek;
srs_fclose_t _srs_fclose_fn = ::fclose;
srs_ftell_t _srs_ftell_fn = ::ftell;
srs_setvbuf_t _srs_setvbuf_fn = ::setvbuf;

SrsFileWriter::SrsFileWriter()
{
fp_ = NULL;
Expand Down Expand Up @@ -53,10 +61,10 @@ srs_error_t SrsFileWriter::set_iobuf_size(int size)

if (size > 0) {
buf_ = new char[size];
ret = setvbuf(fp_, buf_, _IOFBF, size);
ret = _srs_setvbuf_fn(fp_, buf_, _IOFBF, size);
}
else {
ret = setvbuf(fp_, NULL, _IONBF, size);
ret = _srs_setvbuf_fn(fp_, NULL, _IONBF, size);
}

if (ret != 0) {
Expand All @@ -75,7 +83,7 @@ srs_error_t SrsFileWriter::open(string p)
return srs_error_new(ERROR_SYSTEM_FILE_ALREADY_OPENED, "file %s already opened", p.c_str());
}

if ((fp_ = fopen(p.c_str(), "wb")) == NULL) {
if ((fp_ = _srs_fopen_fn(p.c_str(), "wb")) == NULL) {
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
}

Expand All @@ -92,7 +100,7 @@ srs_error_t SrsFileWriter::open_append(string p)
return srs_error_new(ERROR_SYSTEM_FILE_ALREADY_OPENED, "file %s already opened", p.c_str());
}

if ((fp_ = fopen(p.c_str(), "ab")) == NULL) {
if ((fp_ = _srs_fopen_fn(p.c_str(), "ab")) == NULL) {
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
}

Expand All @@ -107,7 +115,7 @@ void SrsFileWriter::close()
return;
}

if (fclose(fp_) < 0) {
if (_srs_fclose_fn(fp_) < 0) {
srs_warn("close file %s failed", path_.c_str());
}
fp_ = NULL;
Expand All @@ -124,15 +132,15 @@ void SrsFileWriter::seek2(int64_t offset)
{
srs_assert(is_open());

int r0 = fseek(fp_, (long)offset, SEEK_SET);
int r0 = _srs_fseek_fn(fp_, (long)offset, SEEK_SET);
srs_assert(r0 != -1);
}

int64_t SrsFileWriter::tellg()
{
srs_assert(is_open());

return ftell(fp_);
return _srs_ftell_fn(fp_);
}

srs_error_t SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
Expand All @@ -143,7 +151,7 @@ srs_error_t SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
return srs_error_new(ERROR_SYSTEM_FILE_NOT_OPEN, "file %s is not opened", path_.c_str());
}

size_t n = fwrite(buf, 1, count, fp_);
size_t n = _srs_fwrite_fn(buf, 1, count, fp_);
if (n != count) {
return srs_error_new(ERROR_SYSTEM_FILE_WRITE, "write to file %s failed", path_.c_str());
}
Expand Down Expand Up @@ -180,12 +188,12 @@ srs_error_t SrsFileWriter::lseek(off_t offset, int whence, off_t* seeked)
{
srs_assert(is_open());

if (fseek(fp_, (long)offset, whence) == -1) {
if (_srs_fseek_fn(fp_, (long)offset, whence) == -1) {
return srs_error_new(ERROR_SYSTEM_FILE_SEEK, "seek file");
}

if (seeked) {
*seeked = ftell(fp_);
*seeked = _srs_ftell_fn(fp_);
}

return srs_success;
Expand Down
11 changes: 11 additions & 0 deletions trunk/src/kernel/srs_kernel_file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,16 @@ typedef ssize_t (*srs_read_t)(int fildes, void* buf, size_t nbyte);
typedef off_t (*srs_lseek_t)(int fildes, off_t offset, int whence);
typedef int (*srs_close_t)(int fildes);


typedef FILE* (*srs_fopen_t)(const char* path, const char* mode);
typedef size_t (*srs_fwrite_t)(const void* ptr, size_t size, size_t nitems,
FILE* stream);
typedef size_t (*srs_fread_t)(void* ptr, size_t size, size_t nitems,
FILE* stream);
typedef int (*srs_fseek_t)(FILE* stream, long offset, int whence);
typedef int (*srs_fclose_t)(FILE* stream);
typedef long (*srs_ftell_t)(FILE* stream);
typedef int (*srs_setvbuf_t)(FILE* stream, char* buf, int type, size_t size);

#endif

177 changes: 177 additions & 0 deletions trunk/src/utest/srs_utest_kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4093,6 +4093,114 @@ class MockSystemIO
}
};


extern srs_fopen_t _srs_fopen_fn;
extern srs_fwrite_t _srs_fwrite_fn;
extern srs_fread_t _srs_fread_fn;
extern srs_fseek_t _srs_fseek_fn;
extern srs_fclose_t _srs_fclose_fn;
extern srs_ftell_t _srs_ftell_fn;
extern srs_setvbuf_t _srs_setvbuf_fn;


FILE* mock_fopen(const char* path, const char* mode) {
return NULL;
}

size_t mock_fwrite(const void* ptr, size_t size, size_t nitems, FILE* stream) {
return -1;
}

size_t mock_fread(void* ptr, size_t size, size_t nitems, FILE* stream) {
return -1;
}

int mock_fseek(FILE* stream, long offset, int whence) {
return -1;
}

int mock_fclose(FILE *stream) {
return -1;
}

long mock_ftell(FILE *stream) {
return -1;
}

int mock_setvbuf(FILE* stream, char* buf, int type, size_t size) {
return -1;
}

class MockLibcIO
{
private:
srs_fopen_t oo_;
srs_fwrite_t ow_;
srs_fread_t or_;
srs_fseek_t os_;
srs_fclose_t oc_;
srs_ftell_t ot_;
srs_setvbuf_t osb_;

public:
MockLibcIO(srs_fopen_t o = NULL, srs_fwrite_t w = NULL, srs_fread_t r = NULL,
srs_fseek_t s = NULL, srs_fclose_t c = NULL, srs_ftell_t t = NULL,
srs_setvbuf_t sb = NULL) {
oo_ = _srs_fopen_fn;
ow_ = _srs_fwrite_fn;
os_ = _srs_fseek_fn;
or_ = _srs_fread_fn;
oc_ = _srs_fclose_fn;
ot_ = _srs_ftell_fn;
osb_= _srs_setvbuf_fn;

if (o) {
_srs_fopen_fn = o;
}
if (w) {
_srs_fwrite_fn = w;
}
if (r) {
_srs_fread_fn = r;
}
if (s) {
_srs_fseek_fn = s;
}
if (c) {
_srs_fclose_fn = c;
}
if (t) {
_srs_ftell_fn = t;
}
if (sb){
_srs_setvbuf_fn = sb;
}
}
virtual ~MockLibcIO() {
if (oo_) {
_srs_fopen_fn = oo_;
}
if (ow_) {
_srs_fwrite_fn = ow_;
}
if (or_) {
_srs_fread_fn = or_;
}
if (os_) {
_srs_fseek_fn = os_;
}
if (oc_) {
_srs_fclose_fn = oc_;
}
if (ot_) {
_srs_ftell_fn = ot_;
}
if (osb_) {
_srs_setvbuf_fn = osb_;
}
}
};

VOID TEST(KernelFileWriterTest, WriteSpecialCase)
{
srs_error_t err;
Expand All @@ -4111,6 +4219,27 @@ VOID TEST(KernelFileWriterTest, WriteSpecialCase)
HELPER_EXPECT_FAILED(f.open_append("/dev/null"));
}

if (true) {
SrsFileWriter f;
HELPER_EXPECT_SUCCESS(f.open_append("/dev/null"));
HELPER_EXPECT_SUCCESS(f.set_iobuf_size(65536));
}

// Always fail.
if (true) {
MockLibcIO _mockio(mock_fopen);
SrsFileWriter f;
HELPER_EXPECT_FAILED(f.open("/dev/null"));
HELPER_EXPECT_FAILED(f.open("/dev/null"));
}

if (true) {
MockLibcIO _mockio(mock_fopen);
SrsFileWriter f;
HELPER_EXPECT_FAILED(f.open_append("/dev/null"));
HELPER_EXPECT_FAILED(f.open_append("/dev/null"));
}

// Should ok for write, writev or lseek.
if (true) {
SrsFileWriter f;
Expand Down Expand Up @@ -4140,6 +4269,54 @@ VOID TEST(KernelFileWriterTest, WriteSpecialCase)
#endif
}

// Always fail.
if (true) {
MockLibcIO _mockio(NULL, mock_fwrite);
SrsFileWriter f;
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));

ssize_t nn = 0;
HELPER_EXPECT_FAILED(f.write((void*)"Hello", 5, &nn));

iovec iovs[3];
iovs[0].iov_base = (void*)"H";
iovs[0].iov_len = 1;
iovs[1].iov_base = (void*)"e";
iovs[1].iov_len = 1;
iovs[2].iov_base = (void*)"llo";
iovs[2].iov_len = 3;
HELPER_EXPECT_FAILED(f.writev(iovs, 3, NULL));
}
if (true) {
MockLibcIO _mockio(NULL, NULL, NULL, mock_fseek);
SrsFileWriter f;
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));

HELPER_EXPECT_FAILED(f.lseek(0, 0, NULL));
}
if (true) {
MockLibcIO _mockio(NULL, NULL, NULL, NULL, mock_fclose);
SrsFileWriter f;
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));
f.close();
}

if (true) {
MockLibcIO _mockio(NULL, NULL, NULL, NULL, NULL, NULL, mock_setvbuf);
SrsFileWriter f;
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));

HELPER_EXPECT_FAILED(f.set_iobuf_size(100));
}

if (true) {
MockLibcIO _mockio(NULL, NULL, NULL, NULL, NULL, mock_ftell);
SrsFileWriter f;
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));

EXPECT_EQ(f.tellg(), -1);
}

}

VOID TEST(KernelFileReaderTest, WriteSpecialCase)
Expand Down

0 comments on commit 9c4996c

Please sign in to comment.