Skip to content

Commit 9c4996c

Browse files
committed
restruct SrsFileWriter to use libc file functions mockable
1 parent c24a000 commit 9c4996c

File tree

3 files changed

+206
-10
lines changed

3 files changed

+206
-10
lines changed

trunk/src/kernel/srs_kernel_file.cpp

+18-10
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ srs_read_t _srs_read_fn = ::read;
2626
srs_lseek_t _srs_lseek_fn = ::lseek;
2727
srs_close_t _srs_close_fn = ::close;
2828

29+
srs_fopen_t _srs_fopen_fn = ::fopen;
30+
srs_fwrite_t _srs_fwrite_fn = ::fwrite;
31+
srs_fread_t _srs_fread_fn = ::fread;
32+
srs_fseek_t _srs_fseek_fn = ::fseek;
33+
srs_fclose_t _srs_fclose_fn = ::fclose;
34+
srs_ftell_t _srs_ftell_fn = ::ftell;
35+
srs_setvbuf_t _srs_setvbuf_fn = ::setvbuf;
36+
2937
SrsFileWriter::SrsFileWriter()
3038
{
3139
fp_ = NULL;
@@ -53,10 +61,10 @@ srs_error_t SrsFileWriter::set_iobuf_size(int size)
5361

5462
if (size > 0) {
5563
buf_ = new char[size];
56-
ret = setvbuf(fp_, buf_, _IOFBF, size);
64+
ret = _srs_setvbuf_fn(fp_, buf_, _IOFBF, size);
5765
}
5866
else {
59-
ret = setvbuf(fp_, NULL, _IONBF, size);
67+
ret = _srs_setvbuf_fn(fp_, NULL, _IONBF, size);
6068
}
6169

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

78-
if ((fp_ = fopen(p.c_str(), "wb")) == NULL) {
86+
if ((fp_ = _srs_fopen_fn(p.c_str(), "wb")) == NULL) {
7987
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
8088
}
8189

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

95-
if ((fp_ = fopen(p.c_str(), "ab")) == NULL) {
103+
if ((fp_ = _srs_fopen_fn(p.c_str(), "ab")) == NULL) {
96104
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
97105
}
98106

@@ -107,7 +115,7 @@ void SrsFileWriter::close()
107115
return;
108116
}
109117

110-
if (fclose(fp_) < 0) {
118+
if (_srs_fclose_fn(fp_) < 0) {
111119
srs_warn("close file %s failed", path_.c_str());
112120
}
113121
fp_ = NULL;
@@ -124,15 +132,15 @@ void SrsFileWriter::seek2(int64_t offset)
124132
{
125133
srs_assert(is_open());
126134

127-
int r0 = fseek(fp_, (long)offset, SEEK_SET);
135+
int r0 = _srs_fseek_fn(fp_, (long)offset, SEEK_SET);
128136
srs_assert(r0 != -1);
129137
}
130138

131139
int64_t SrsFileWriter::tellg()
132140
{
133141
srs_assert(is_open());
134142

135-
return ftell(fp_);
143+
return _srs_ftell_fn(fp_);
136144
}
137145

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

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

183-
if (fseek(fp_, (long)offset, whence) == -1) {
191+
if (_srs_fseek_fn(fp_, (long)offset, whence) == -1) {
184192
return srs_error_new(ERROR_SYSTEM_FILE_SEEK, "seek file");
185193
}
186194

187195
if (seeked) {
188-
*seeked = ftell(fp_);
196+
*seeked = _srs_ftell_fn(fp_);
189197
}
190198

191199
return srs_success;

trunk/src/kernel/srs_kernel_file.hpp

+11
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,16 @@ typedef ssize_t (*srs_read_t)(int fildes, void* buf, size_t nbyte);
116116
typedef off_t (*srs_lseek_t)(int fildes, off_t offset, int whence);
117117
typedef int (*srs_close_t)(int fildes);
118118

119+
120+
typedef FILE* (*srs_fopen_t)(const char* path, const char* mode);
121+
typedef size_t (*srs_fwrite_t)(const void* ptr, size_t size, size_t nitems,
122+
FILE* stream);
123+
typedef size_t (*srs_fread_t)(void* ptr, size_t size, size_t nitems,
124+
FILE* stream);
125+
typedef int (*srs_fseek_t)(FILE* stream, long offset, int whence);
126+
typedef int (*srs_fclose_t)(FILE* stream);
127+
typedef long (*srs_ftell_t)(FILE* stream);
128+
typedef int (*srs_setvbuf_t)(FILE* stream, char* buf, int type, size_t size);
129+
119130
#endif
120131

trunk/src/utest/srs_utest_kernel.cpp

+177
Original file line numberDiff line numberDiff line change
@@ -4093,6 +4093,114 @@ class MockSystemIO
40934093
}
40944094
};
40954095

4096+
4097+
extern srs_fopen_t _srs_fopen_fn;
4098+
extern srs_fwrite_t _srs_fwrite_fn;
4099+
extern srs_fread_t _srs_fread_fn;
4100+
extern srs_fseek_t _srs_fseek_fn;
4101+
extern srs_fclose_t _srs_fclose_fn;
4102+
extern srs_ftell_t _srs_ftell_fn;
4103+
extern srs_setvbuf_t _srs_setvbuf_fn;
4104+
4105+
4106+
FILE* mock_fopen(const char* path, const char* mode) {
4107+
return NULL;
4108+
}
4109+
4110+
size_t mock_fwrite(const void* ptr, size_t size, size_t nitems, FILE* stream) {
4111+
return -1;
4112+
}
4113+
4114+
size_t mock_fread(void* ptr, size_t size, size_t nitems, FILE* stream) {
4115+
return -1;
4116+
}
4117+
4118+
int mock_fseek(FILE* stream, long offset, int whence) {
4119+
return -1;
4120+
}
4121+
4122+
int mock_fclose(FILE *stream) {
4123+
return -1;
4124+
}
4125+
4126+
long mock_ftell(FILE *stream) {
4127+
return -1;
4128+
}
4129+
4130+
int mock_setvbuf(FILE* stream, char* buf, int type, size_t size) {
4131+
return -1;
4132+
}
4133+
4134+
class MockLibcIO
4135+
{
4136+
private:
4137+
srs_fopen_t oo_;
4138+
srs_fwrite_t ow_;
4139+
srs_fread_t or_;
4140+
srs_fseek_t os_;
4141+
srs_fclose_t oc_;
4142+
srs_ftell_t ot_;
4143+
srs_setvbuf_t osb_;
4144+
4145+
public:
4146+
MockLibcIO(srs_fopen_t o = NULL, srs_fwrite_t w = NULL, srs_fread_t r = NULL,
4147+
srs_fseek_t s = NULL, srs_fclose_t c = NULL, srs_ftell_t t = NULL,
4148+
srs_setvbuf_t sb = NULL) {
4149+
oo_ = _srs_fopen_fn;
4150+
ow_ = _srs_fwrite_fn;
4151+
os_ = _srs_fseek_fn;
4152+
or_ = _srs_fread_fn;
4153+
oc_ = _srs_fclose_fn;
4154+
ot_ = _srs_ftell_fn;
4155+
osb_= _srs_setvbuf_fn;
4156+
4157+
if (o) {
4158+
_srs_fopen_fn = o;
4159+
}
4160+
if (w) {
4161+
_srs_fwrite_fn = w;
4162+
}
4163+
if (r) {
4164+
_srs_fread_fn = r;
4165+
}
4166+
if (s) {
4167+
_srs_fseek_fn = s;
4168+
}
4169+
if (c) {
4170+
_srs_fclose_fn = c;
4171+
}
4172+
if (t) {
4173+
_srs_ftell_fn = t;
4174+
}
4175+
if (sb){
4176+
_srs_setvbuf_fn = sb;
4177+
}
4178+
}
4179+
virtual ~MockLibcIO() {
4180+
if (oo_) {
4181+
_srs_fopen_fn = oo_;
4182+
}
4183+
if (ow_) {
4184+
_srs_fwrite_fn = ow_;
4185+
}
4186+
if (or_) {
4187+
_srs_fread_fn = or_;
4188+
}
4189+
if (os_) {
4190+
_srs_fseek_fn = os_;
4191+
}
4192+
if (oc_) {
4193+
_srs_fclose_fn = oc_;
4194+
}
4195+
if (ot_) {
4196+
_srs_ftell_fn = ot_;
4197+
}
4198+
if (osb_) {
4199+
_srs_setvbuf_fn = osb_;
4200+
}
4201+
}
4202+
};
4203+
40964204
VOID TEST(KernelFileWriterTest, WriteSpecialCase)
40974205
{
40984206
srs_error_t err;
@@ -4111,6 +4219,27 @@ VOID TEST(KernelFileWriterTest, WriteSpecialCase)
41114219
HELPER_EXPECT_FAILED(f.open_append("/dev/null"));
41124220
}
41134221

4222+
if (true) {
4223+
SrsFileWriter f;
4224+
HELPER_EXPECT_SUCCESS(f.open_append("/dev/null"));
4225+
HELPER_EXPECT_SUCCESS(f.set_iobuf_size(65536));
4226+
}
4227+
4228+
// Always fail.
4229+
if (true) {
4230+
MockLibcIO _mockio(mock_fopen);
4231+
SrsFileWriter f;
4232+
HELPER_EXPECT_FAILED(f.open("/dev/null"));
4233+
HELPER_EXPECT_FAILED(f.open("/dev/null"));
4234+
}
4235+
4236+
if (true) {
4237+
MockLibcIO _mockio(mock_fopen);
4238+
SrsFileWriter f;
4239+
HELPER_EXPECT_FAILED(f.open_append("/dev/null"));
4240+
HELPER_EXPECT_FAILED(f.open_append("/dev/null"));
4241+
}
4242+
41144243
// Should ok for write, writev or lseek.
41154244
if (true) {
41164245
SrsFileWriter f;
@@ -4140,6 +4269,54 @@ VOID TEST(KernelFileWriterTest, WriteSpecialCase)
41404269
#endif
41414270
}
41424271

4272+
// Always fail.
4273+
if (true) {
4274+
MockLibcIO _mockio(NULL, mock_fwrite);
4275+
SrsFileWriter f;
4276+
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));
4277+
4278+
ssize_t nn = 0;
4279+
HELPER_EXPECT_FAILED(f.write((void*)"Hello", 5, &nn));
4280+
4281+
iovec iovs[3];
4282+
iovs[0].iov_base = (void*)"H";
4283+
iovs[0].iov_len = 1;
4284+
iovs[1].iov_base = (void*)"e";
4285+
iovs[1].iov_len = 1;
4286+
iovs[2].iov_base = (void*)"llo";
4287+
iovs[2].iov_len = 3;
4288+
HELPER_EXPECT_FAILED(f.writev(iovs, 3, NULL));
4289+
}
4290+
if (true) {
4291+
MockLibcIO _mockio(NULL, NULL, NULL, mock_fseek);
4292+
SrsFileWriter f;
4293+
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));
4294+
4295+
HELPER_EXPECT_FAILED(f.lseek(0, 0, NULL));
4296+
}
4297+
if (true) {
4298+
MockLibcIO _mockio(NULL, NULL, NULL, NULL, mock_fclose);
4299+
SrsFileWriter f;
4300+
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));
4301+
f.close();
4302+
}
4303+
4304+
if (true) {
4305+
MockLibcIO _mockio(NULL, NULL, NULL, NULL, NULL, NULL, mock_setvbuf);
4306+
SrsFileWriter f;
4307+
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));
4308+
4309+
HELPER_EXPECT_FAILED(f.set_iobuf_size(100));
4310+
}
4311+
4312+
if (true) {
4313+
MockLibcIO _mockio(NULL, NULL, NULL, NULL, NULL, mock_ftell);
4314+
SrsFileWriter f;
4315+
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));
4316+
4317+
EXPECT_EQ(f.tellg(), -1);
4318+
}
4319+
41434320
}
41444321

41454322
VOID TEST(KernelFileReaderTest, WriteSpecialCase)

0 commit comments

Comments
 (0)