mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Merge branch '3.0release' into develop
This commit is contained in:
commit
ae710f00b1
18 changed files with 425 additions and 73 deletions
|
@ -54,7 +54,7 @@ start() {
|
||||||
ok_msg "Starting SRS-api..."
|
ok_msg "Starting SRS-api..."
|
||||||
# TODO: FIXME: set limit by, for instance, "ulimit -HSn 10000"
|
# TODO: FIXME: set limit by, for instance, "ulimit -HSn 10000"
|
||||||
# TODO: FIXME: write log to, for instance, the same dir of log.
|
# TODO: FIXME: write log to, for instance, the same dir of log.
|
||||||
# TODO: FIXME: support deamon, without nohup.
|
# TODO: FIXME: support daemon, without nohup.
|
||||||
(cd ${ROOT}; nohup ${APP} ${CONFIG} >/dev/null 2>&1 &)
|
(cd ${ROOT}; nohup ${APP} ${CONFIG} >/dev/null 2>&1 &)
|
||||||
|
|
||||||
# check again after start server
|
# check again after start server
|
||||||
|
|
|
@ -3890,7 +3890,7 @@ srs_error_t SrsConfig::check_normal_config()
|
||||||
}
|
}
|
||||||
|
|
||||||
// asprocess conflict with daemon
|
// asprocess conflict with daemon
|
||||||
if (get_asprocess() && get_deamon()) {
|
if (get_asprocess() && get_daemon()) {
|
||||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "daemon conflicts with asprocess");
|
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "daemon conflicts with asprocess");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3990,7 +3990,7 @@ string SrsConfig::argv()
|
||||||
return _argv;
|
return _argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsConfig::get_deamon()
|
bool SrsConfig::get_daemon()
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = root->get("daemon");
|
SrsConfDirective* conf = root->get("daemon");
|
||||||
if (!conf || conf->arg0().empty()) {
|
if (!conf || conf->arg0().empty()) {
|
||||||
|
|
|
@ -406,10 +406,10 @@ public:
|
||||||
// The root directive, no name and args, contains directives.
|
// The root directive, no name and args, contains directives.
|
||||||
// All directive parsed can retrieve from root.
|
// All directive parsed can retrieve from root.
|
||||||
virtual SrsConfDirective* get_root();
|
virtual SrsConfDirective* get_root();
|
||||||
// Get the deamon config.
|
// Get the daemon config.
|
||||||
// If true, SRS will run in deamon mode, fork and fork to reap the
|
// If true, SRS will run in daemon mode, fork and fork to reap the
|
||||||
// grand-child process to init process.
|
// grand-child process to init process.
|
||||||
virtual bool get_deamon();
|
virtual bool get_daemon();
|
||||||
// Get the max connections limit of system.
|
// Get the max connections limit of system.
|
||||||
// If exceed the max connection, SRS will disconnect the connection.
|
// If exceed the max connection, SRS will disconnect the connection.
|
||||||
// @remark, linux will limit the connections of each process,
|
// @remark, linux will limit the connections of each process,
|
||||||
|
|
|
@ -902,7 +902,7 @@ srs_error_t SrsServer::do_cycle()
|
||||||
// for asprocess.
|
// for asprocess.
|
||||||
bool asprocess = _srs_config->get_asprocess();
|
bool asprocess = _srs_config->get_asprocess();
|
||||||
|
|
||||||
// the deamon thread, update the time cache
|
// the daemon thread, update the time cache
|
||||||
// TODO: FIXME: use SrsHourGlass.
|
// TODO: FIXME: use SrsHourGlass.
|
||||||
while (true) {
|
while (true) {
|
||||||
if (handler && (err = handler->on_cycle()) != srs_success) {
|
if (handler && (err = handler->on_cycle()) != srs_success) {
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
|
|
||||||
// Get system rusage, use cache to avoid performance problem.
|
// Get system rusage, use cache to avoid performance problem.
|
||||||
extern SrsRusage* srs_get_system_rusage();
|
extern SrsRusage* srs_get_system_rusage();
|
||||||
// The deamon st-thread will update it.
|
// The daemon st-thread will update it.
|
||||||
extern void srs_update_system_rusage();
|
extern void srs_update_system_rusage();
|
||||||
|
|
||||||
// To stat the process info.
|
// To stat the process info.
|
||||||
|
@ -339,7 +339,7 @@ public:
|
||||||
extern SrsProcSelfStat* srs_get_self_proc_stat();
|
extern SrsProcSelfStat* srs_get_self_proc_stat();
|
||||||
// Get system cpu stat, use cache to avoid performance problem.
|
// Get system cpu stat, use cache to avoid performance problem.
|
||||||
extern SrsProcSystemStat* srs_get_system_proc_stat();
|
extern SrsProcSystemStat* srs_get_system_proc_stat();
|
||||||
// The deamon st-thread will update it.
|
// The daemon st-thread will update it.
|
||||||
extern void srs_update_proc_stat();
|
extern void srs_update_proc_stat();
|
||||||
|
|
||||||
// Stat disk iops
|
// Stat disk iops
|
||||||
|
@ -446,7 +446,7 @@ public:
|
||||||
|
|
||||||
// Get disk stat, use cache to avoid performance problem.
|
// Get disk stat, use cache to avoid performance problem.
|
||||||
extern SrsDiskStat* srs_get_disk_stat();
|
extern SrsDiskStat* srs_get_disk_stat();
|
||||||
// The deamon st-thread will update it.
|
// The daemon st-thread will update it.
|
||||||
extern void srs_update_disk_stat();
|
extern void srs_update_disk_stat();
|
||||||
|
|
||||||
// Stat system memory info
|
// Stat system memory info
|
||||||
|
@ -487,7 +487,7 @@ public:
|
||||||
|
|
||||||
// Get system meminfo, use cache to avoid performance problem.
|
// Get system meminfo, use cache to avoid performance problem.
|
||||||
extern SrsMemInfo* srs_get_meminfo();
|
extern SrsMemInfo* srs_get_meminfo();
|
||||||
// The deamon st-thread will update it.
|
// The daemon st-thread will update it.
|
||||||
extern void srs_update_meminfo();
|
extern void srs_update_meminfo();
|
||||||
|
|
||||||
// system cpu hardware info.
|
// system cpu hardware info.
|
||||||
|
@ -543,7 +543,7 @@ public:
|
||||||
|
|
||||||
// Get platform info, use cache to avoid performance problem.
|
// Get platform info, use cache to avoid performance problem.
|
||||||
extern SrsPlatformInfo* srs_get_platform_info();
|
extern SrsPlatformInfo* srs_get_platform_info();
|
||||||
// The deamon st-thread will update it.
|
// The daemon st-thread will update it.
|
||||||
extern void srs_update_platform_info();
|
extern void srs_update_platform_info();
|
||||||
|
|
||||||
// The network device summary for each network device, for example, eth0, eth1, ethN
|
// The network device summary for each network device, for example, eth0, eth1, ethN
|
||||||
|
@ -586,7 +586,7 @@ public:
|
||||||
// Get network devices info, use cache to avoid performance problem.
|
// Get network devices info, use cache to avoid performance problem.
|
||||||
extern SrsNetworkDevices* srs_get_network_devices();
|
extern SrsNetworkDevices* srs_get_network_devices();
|
||||||
extern int srs_get_network_devices_count();
|
extern int srs_get_network_devices_count();
|
||||||
// The deamon st-thread will update it.
|
// The daemon st-thread will update it.
|
||||||
extern void srs_update_network_devices();
|
extern void srs_update_network_devices();
|
||||||
|
|
||||||
// The system connections, and srs rtmp network summary
|
// The system connections, and srs rtmp network summary
|
||||||
|
@ -629,7 +629,7 @@ public:
|
||||||
|
|
||||||
// Get network devices info, use cache to avoid performance problem.
|
// Get network devices info, use cache to avoid performance problem.
|
||||||
extern SrsNetworkRtmpServer* srs_get_network_rtmp_server();
|
extern SrsNetworkRtmpServer* srs_get_network_rtmp_server();
|
||||||
// The deamon st-thread will update it.
|
// The daemon st-thread will update it.
|
||||||
extern void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps);
|
extern void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps);
|
||||||
|
|
||||||
// Get local or peer ip.
|
// Get local or peer ip.
|
||||||
|
|
|
@ -36,6 +36,11 @@ using namespace std;
|
||||||
#include <srs_kernel_log.hpp>
|
#include <srs_kernel_log.hpp>
|
||||||
#include <srs_kernel_error.hpp>
|
#include <srs_kernel_error.hpp>
|
||||||
|
|
||||||
|
// For utest to mock it.
|
||||||
|
_srs_open_t _srs_open_fn = ::open;
|
||||||
|
_srs_write_t _srs_write_fn = ::write;
|
||||||
|
_srs_lseek_t _srs_lseek_fn = ::lseek;
|
||||||
|
|
||||||
SrsFileWriter::SrsFileWriter()
|
SrsFileWriter::SrsFileWriter()
|
||||||
{
|
{
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
@ -57,7 +62,7 @@ srs_error_t SrsFileWriter::open(string p)
|
||||||
int flags = O_CREAT|O_WRONLY|O_TRUNC;
|
int flags = O_CREAT|O_WRONLY|O_TRUNC;
|
||||||
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
|
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
|
||||||
|
|
||||||
if ((fd = ::open(p.c_str(), flags, mode)) < 0) {
|
if ((fd = _srs_open_fn(p.c_str(), flags, mode)) < 0) {
|
||||||
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
|
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +82,7 @@ srs_error_t SrsFileWriter::open_append(string p)
|
||||||
int flags = O_APPEND|O_WRONLY;
|
int flags = O_APPEND|O_WRONLY;
|
||||||
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
|
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
|
||||||
|
|
||||||
if ((fd = ::open(p.c_str(), flags, mode)) < 0) {
|
if ((fd = _srs_open_fn(p.c_str(), flags, mode)) < 0) {
|
||||||
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
|
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,13 +112,13 @@ bool SrsFileWriter::is_open()
|
||||||
|
|
||||||
void SrsFileWriter::seek2(int64_t offset)
|
void SrsFileWriter::seek2(int64_t offset)
|
||||||
{
|
{
|
||||||
off_t r0 = ::lseek(fd, (off_t)offset, SEEK_SET);
|
off_t r0 = _srs_lseek_fn(fd, (off_t)offset, SEEK_SET);
|
||||||
srs_assert(r0 != -1);
|
srs_assert(r0 != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t SrsFileWriter::tellg()
|
int64_t SrsFileWriter::tellg()
|
||||||
{
|
{
|
||||||
return (int64_t)::lseek(fd, 0, SEEK_CUR);
|
return (int64_t)_srs_lseek_fn(fd, 0, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
|
srs_error_t SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
|
||||||
|
@ -122,7 +127,7 @@ srs_error_t SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
|
||||||
|
|
||||||
ssize_t nwrite;
|
ssize_t nwrite;
|
||||||
// TODO: FIXME: use st_write.
|
// TODO: FIXME: use st_write.
|
||||||
if ((nwrite = ::write(fd, buf, count)) < 0) {
|
if ((nwrite = _srs_write_fn(fd, buf, count)) < 0) {
|
||||||
return srs_error_new(ERROR_SYSTEM_FILE_WRITE, "write to file %s failed", path.c_str());
|
return srs_error_new(ERROR_SYSTEM_FILE_WRITE, "write to file %s failed", path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +161,7 @@ srs_error_t SrsFileWriter::writev(const iovec* iov, int iovcnt, ssize_t* pnwrite
|
||||||
|
|
||||||
srs_error_t SrsFileWriter::lseek(off_t offset, int whence, off_t* seeked)
|
srs_error_t SrsFileWriter::lseek(off_t offset, int whence, off_t* seeked)
|
||||||
{
|
{
|
||||||
off_t sk = ::lseek(fd, offset, whence);
|
off_t sk = _srs_lseek_fn(fd, offset, whence);
|
||||||
if (sk < 0) {
|
if (sk < 0) {
|
||||||
return srs_error_new(ERROR_SYSTEM_FILE_SEEK, "seek file");
|
return srs_error_new(ERROR_SYSTEM_FILE_SEEK, "seek file");
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,5 +108,10 @@ public:
|
||||||
virtual srs_error_t lseek(off_t offset, int whence, off_t* seeked);
|
virtual srs_error_t lseek(off_t offset, int whence, off_t* seeked);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For utest to mock it.
|
||||||
|
typedef int (*_srs_open_t)(const char* path, int oflag, ...);
|
||||||
|
typedef ssize_t (*_srs_write_t)(int fildes, const void* buf, size_t nbyte);
|
||||||
|
typedef off_t (*_srs_lseek_t)(int fildes, off_t offset, int whence);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -424,13 +424,6 @@ srs_error_t SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t*
|
||||||
return srs_success;
|
return srs_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface ISrsProtocolReadWriter
|
|
||||||
bool SimpleSocketStream::is_never_timeout(srs_utime_t tm)
|
|
||||||
{
|
|
||||||
srs_assert(io);
|
|
||||||
return srs_hijack_io_is_never_timeout(io, tm);
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t SimpleSocketStream::read_fully(void* buf, size_t size, ssize_t* nread)
|
srs_error_t SimpleSocketStream::read_fully(void* buf, size_t size, ssize_t* nread)
|
||||||
{
|
{
|
||||||
srs_assert(io);
|
srs_assert(io);
|
||||||
|
|
|
@ -65,7 +65,6 @@ public:
|
||||||
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite);
|
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite);
|
||||||
// Interface ISrsProtocolReadWriter
|
// Interface ISrsProtocolReadWriter
|
||||||
public:
|
public:
|
||||||
virtual bool is_never_timeout(srs_utime_t tm);
|
|
||||||
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
|
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
|
||||||
virtual srs_error_t write(void* buf, size_t size, ssize_t* nwrite);
|
virtual srs_error_t write(void* buf, size_t size, ssize_t* nwrite);
|
||||||
};
|
};
|
||||||
|
|
|
@ -378,15 +378,15 @@ srs_error_t run(SrsServer* svr)
|
||||||
return srs_error_wrap(err, "server initialize");
|
return srs_error_wrap(err, "server initialize");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not deamon, directly run master.
|
// If not daemon, directly run master.
|
||||||
if (!_srs_config->get_deamon()) {
|
if (!_srs_config->get_daemon()) {
|
||||||
if ((err = run_master(svr)) != srs_success) {
|
if ((err = run_master(svr)) != srs_success) {
|
||||||
return srs_error_wrap(err, "run master");
|
return srs_error_wrap(err, "run master");
|
||||||
}
|
}
|
||||||
return srs_success;
|
return srs_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_trace("start deamon mode...");
|
srs_trace("start daemon mode...");
|
||||||
|
|
||||||
int pid = fork();
|
int pid = fork();
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ srs_error_t run(SrsServer* svr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// son
|
// son
|
||||||
srs_trace("son(deamon) process running.");
|
srs_trace("son(daemon) process running.");
|
||||||
|
|
||||||
if ((err = run_master(svr)) != srs_success) {
|
if ((err = run_master(svr)) != srs_success) {
|
||||||
return srs_error_wrap(err, "daemon run master");
|
return srs_error_wrap(err, "daemon run master");
|
||||||
|
|
|
@ -54,8 +54,6 @@
|
||||||
* +--+-----------------------------+-+
|
* +--+-----------------------------+-+
|
||||||
* | IProtocolReadWriter |
|
* | IProtocolReadWriter |
|
||||||
* +----------------------------------+
|
* +----------------------------------+
|
||||||
* | + is_never_timeout() |
|
|
||||||
* +----------------------------------+
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,10 +119,6 @@ class ISrsProtocolReadWriter : virtual public ISrsProtocolReader, virtual public
|
||||||
public:
|
public:
|
||||||
ISrsProtocolReadWriter();
|
ISrsProtocolReadWriter();
|
||||||
virtual ~ISrsProtocolReadWriter();
|
virtual ~ISrsProtocolReadWriter();
|
||||||
// For protocol
|
|
||||||
public:
|
|
||||||
// Whether the specified tm in srs_utime_t is never timeout.
|
|
||||||
virtual bool is_never_timeout(srs_utime_t tm) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -362,6 +362,11 @@ ssize_t srs_read(srs_netfd_t stfd, void *buf, size_t nbyte, srs_utime_t timeout)
|
||||||
return st_read((st_netfd_t)stfd, buf, nbyte, (st_utime_t)timeout);
|
return st_read((st_netfd_t)stfd, buf, nbyte, (st_utime_t)timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool srs_is_never_timeout(srs_utime_t tm)
|
||||||
|
{
|
||||||
|
return tm == SRS_UTIME_NO_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
SrsStSocket::SrsStSocket()
|
SrsStSocket::SrsStSocket()
|
||||||
{
|
{
|
||||||
stfd = NULL;
|
stfd = NULL;
|
||||||
|
@ -379,11 +384,6 @@ srs_error_t SrsStSocket::initialize(srs_netfd_t fd)
|
||||||
return srs_success;
|
return srs_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsStSocket::is_never_timeout(srs_utime_t tm)
|
|
||||||
{
|
|
||||||
return tm == SRS_UTIME_NO_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SrsStSocket::set_recv_timeout(srs_utime_t tm)
|
void SrsStSocket::set_recv_timeout(srs_utime_t tm)
|
||||||
{
|
{
|
||||||
rtm = tm;
|
rtm = tm;
|
||||||
|
@ -593,11 +593,6 @@ void SrsTcpClient::close()
|
||||||
srs_close_stfd(stfd);
|
srs_close_stfd(stfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsTcpClient::is_never_timeout(srs_utime_t tm)
|
|
||||||
{
|
|
||||||
return io->is_never_timeout(tm);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SrsTcpClient::set_recv_timeout(srs_utime_t tm)
|
void SrsTcpClient::set_recv_timeout(srs_utime_t tm)
|
||||||
{
|
{
|
||||||
io->set_recv_timeout(tm);
|
io->set_recv_timeout(tm);
|
||||||
|
|
|
@ -90,6 +90,8 @@ extern srs_netfd_t srs_accept(srs_netfd_t stfd, struct sockaddr *addr, int *addr
|
||||||
|
|
||||||
extern ssize_t srs_read(srs_netfd_t stfd, void *buf, size_t nbyte, srs_utime_t timeout);
|
extern ssize_t srs_read(srs_netfd_t stfd, void *buf, size_t nbyte, srs_utime_t timeout);
|
||||||
|
|
||||||
|
extern bool srs_is_never_timeout(srs_utime_t tm);
|
||||||
|
|
||||||
// The mutex locker.
|
// The mutex locker.
|
||||||
#define SrsLocker(instance) \
|
#define SrsLocker(instance) \
|
||||||
impl__SrsLocker _srs_auto_free_##instance(&instance)
|
impl__SrsLocker _srs_auto_free_##instance(&instance)
|
||||||
|
@ -130,7 +132,6 @@ public:
|
||||||
// Initialize the socket with stfd, user must manage it.
|
// Initialize the socket with stfd, user must manage it.
|
||||||
virtual srs_error_t initialize(srs_netfd_t fd);
|
virtual srs_error_t initialize(srs_netfd_t fd);
|
||||||
public:
|
public:
|
||||||
virtual bool is_never_timeout(srs_utime_t tm);
|
|
||||||
virtual void set_recv_timeout(srs_utime_t tm);
|
virtual void set_recv_timeout(srs_utime_t tm);
|
||||||
virtual srs_utime_t get_recv_timeout();
|
virtual srs_utime_t get_recv_timeout();
|
||||||
virtual void set_send_timeout(srs_utime_t tm);
|
virtual void set_send_timeout(srs_utime_t tm);
|
||||||
|
@ -181,7 +182,6 @@ private:
|
||||||
virtual void close();
|
virtual void close();
|
||||||
// Interface ISrsProtocolReadWriter
|
// Interface ISrsProtocolReadWriter
|
||||||
public:
|
public:
|
||||||
virtual bool is_never_timeout(srs_utime_t tm);
|
|
||||||
virtual void set_recv_timeout(srs_utime_t tm);
|
virtual void set_recv_timeout(srs_utime_t tm);
|
||||||
virtual srs_utime_t get_recv_timeout();
|
virtual srs_utime_t get_recv_timeout();
|
||||||
virtual void set_send_timeout(srs_utime_t tm);
|
virtual void set_send_timeout(srs_utime_t tm);
|
||||||
|
|
|
@ -307,8 +307,6 @@ VOID TEST(AppCoroutineTest, StartThread)
|
||||||
srs_freep(err);
|
srs_freep(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VOID TEST(AppFragmentTest, CheckDuration)
|
VOID TEST(AppFragmentTest, CheckDuration)
|
||||||
{
|
{
|
||||||
if (true) {
|
if (true) {
|
||||||
|
@ -377,9 +375,5 @@ VOID TEST(AppFragmentTest, CheckDuration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MOCK_LISTEN_PORT 11935
|
#endif
|
||||||
|
|
||||||
VOID TEST(TCPServerTest, PingPong)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -2971,6 +2971,141 @@ VOID TEST(KernelFileTest, FileWriteReader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mock the system call hooks.
|
||||||
|
extern _srs_open_t _srs_open_fn;
|
||||||
|
extern _srs_write_t _srs_write_fn;
|
||||||
|
extern _srs_lseek_t _srs_lseek_fn;
|
||||||
|
|
||||||
|
int mock_open(const char* /*path*/, int /*oflag*/, ...) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t mock_write(int /*fildes*/, const void* /*buf*/, size_t /*nbyte*/) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t mock_lseek(int /*fildes*/, off_t /*offset*/, int /*whence*/) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockSystemIO
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
_srs_open_t oo;
|
||||||
|
_srs_write_t ow;
|
||||||
|
_srs_lseek_t os;
|
||||||
|
public:
|
||||||
|
MockSystemIO(_srs_open_t o = NULL, _srs_write_t w = NULL, _srs_lseek_t s = NULL) {
|
||||||
|
oo = _srs_open_fn;
|
||||||
|
ow = _srs_write_fn;
|
||||||
|
os = _srs_lseek_fn;
|
||||||
|
if (o) {
|
||||||
|
_srs_open_fn = o;
|
||||||
|
}
|
||||||
|
if (w) {
|
||||||
|
_srs_write_fn = w;
|
||||||
|
}
|
||||||
|
if (s) {
|
||||||
|
_srs_lseek_fn = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual ~MockSystemIO() {
|
||||||
|
if (oo) {
|
||||||
|
_srs_open_fn = oo;
|
||||||
|
}
|
||||||
|
if (ow) {
|
||||||
|
_srs_write_fn = ow;
|
||||||
|
}
|
||||||
|
if (os) {
|
||||||
|
_srs_lseek_fn = os;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VOID TEST(KernelFileTest, WriteSpecialCase)
|
||||||
|
{
|
||||||
|
srs_error_t err;
|
||||||
|
|
||||||
|
// Should fail when open multiple times.
|
||||||
|
if (true) {
|
||||||
|
SrsFileWriter f;
|
||||||
|
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));
|
||||||
|
HELPER_EXPECT_FAILED(f.open("/dev/null"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should fail when open multiple times.
|
||||||
|
if (true) {
|
||||||
|
SrsFileWriter f;
|
||||||
|
HELPER_EXPECT_SUCCESS(f.open_append("/dev/null"));
|
||||||
|
HELPER_EXPECT_FAILED(f.open_append("/dev/null"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always fail.
|
||||||
|
if (true) {
|
||||||
|
MockSystemIO _mockio(mock_open);
|
||||||
|
SrsFileWriter f;
|
||||||
|
HELPER_EXPECT_FAILED(f.open("/dev/null"));
|
||||||
|
HELPER_EXPECT_FAILED(f.open("/dev/null"));
|
||||||
|
}
|
||||||
|
if (true) {
|
||||||
|
MockSystemIO _mockio(mock_open);
|
||||||
|
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;
|
||||||
|
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));
|
||||||
|
|
||||||
|
ssize_t nn = 0;
|
||||||
|
HELPER_EXPECT_SUCCESS(f.write((void*)"Hello", 5, &nn));
|
||||||
|
EXPECT_EQ(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;
|
||||||
|
nn = 0;
|
||||||
|
HELPER_EXPECT_SUCCESS(f.writev(iovs, 3, &nn));
|
||||||
|
EXPECT_EQ(5, nn);
|
||||||
|
|
||||||
|
off_t seeked = 0;
|
||||||
|
HELPER_EXPECT_SUCCESS(f.lseek(0, SEEK_CUR, &seeked));
|
||||||
|
EXPECT_EQ(0, seeked);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always fail.
|
||||||
|
if (true) {
|
||||||
|
MockSystemIO _mockio(NULL, mock_write);
|
||||||
|
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) {
|
||||||
|
MockSystemIO _mockio(NULL, NULL, mock_lseek);
|
||||||
|
SrsFileWriter f;
|
||||||
|
HELPER_EXPECT_SUCCESS(f.open("/dev/null"));
|
||||||
|
|
||||||
|
HELPER_EXPECT_FAILED(f.lseek(0, 0, NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID TEST(KernelFLVTest, CoverAll)
|
VOID TEST(KernelFLVTest, CoverAll)
|
||||||
{
|
{
|
||||||
if (true) {
|
if (true) {
|
||||||
|
|
|
@ -43,11 +43,6 @@ MockEmptyIO::~MockEmptyIO()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MockEmptyIO::is_never_timeout(srs_utime_t /*tm*/)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockEmptyIO::read_fully(void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/)
|
srs_error_t MockEmptyIO::read_fully(void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/)
|
||||||
{
|
{
|
||||||
return srs_success;
|
return srs_success;
|
||||||
|
@ -112,11 +107,6 @@ MockBufferIO* MockBufferIO::append(string data)
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MockBufferIO::is_never_timeout(srs_utime_t tm)
|
|
||||||
{
|
|
||||||
return tm == SRS_UTIME_NO_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread)
|
srs_error_t MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread)
|
||||||
{
|
{
|
||||||
if (in_buffer.length() < (int)size) {
|
if (in_buffer.length() < (int)size) {
|
||||||
|
|
|
@ -46,9 +46,6 @@ class MockEmptyIO : public ISrsProtocolReadWriter
|
||||||
public:
|
public:
|
||||||
MockEmptyIO();
|
MockEmptyIO();
|
||||||
virtual ~MockEmptyIO();
|
virtual ~MockEmptyIO();
|
||||||
// for protocol
|
|
||||||
public:
|
|
||||||
virtual bool is_never_timeout(srs_utime_t tm);
|
|
||||||
// for handshake.
|
// for handshake.
|
||||||
public:
|
public:
|
||||||
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
|
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
|
||||||
|
@ -87,9 +84,6 @@ public:
|
||||||
virtual ~MockBufferIO();
|
virtual ~MockBufferIO();
|
||||||
public:
|
public:
|
||||||
virtual MockBufferIO* append(std::string data);
|
virtual MockBufferIO* append(std::string data);
|
||||||
// for protocol
|
|
||||||
public:
|
|
||||||
virtual bool is_never_timeout(srs_utime_t tm);
|
|
||||||
// for handshake.
|
// for handshake.
|
||||||
public:
|
public:
|
||||||
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
|
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
|
||||||
|
|
|
@ -25,6 +25,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#include <srs_kernel_error.hpp>
|
#include <srs_kernel_error.hpp>
|
||||||
|
#include <srs_app_listener.hpp>
|
||||||
|
#include <srs_service_st.hpp>
|
||||||
|
|
||||||
// Disable coroutine test for OSX.
|
// Disable coroutine test for OSX.
|
||||||
#if !defined(SRS_OSX)
|
#if !defined(SRS_OSX)
|
||||||
|
@ -37,6 +39,252 @@ VOID TEST(ServiceTimeTest, TimeUnit)
|
||||||
EXPECT_EQ(1000*1000, SRS_UTIME_SECONDS);
|
EXPECT_EQ(1000*1000, SRS_UTIME_SECONDS);
|
||||||
EXPECT_EQ(60*1000*1000, SRS_UTIME_MINUTES);
|
EXPECT_EQ(60*1000*1000, SRS_UTIME_MINUTES);
|
||||||
EXPECT_EQ(3600*1000*1000LL, SRS_UTIME_HOURS);
|
EXPECT_EQ(3600*1000*1000LL, SRS_UTIME_HOURS);
|
||||||
|
|
||||||
|
EXPECT_TRUE(srs_is_never_timeout(SRS_UTIME_NO_TIMEOUT));
|
||||||
|
EXPECT_FALSE(srs_is_never_timeout(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MOCK_LISTEN_HOST "127.0.0.1"
|
||||||
|
#define MOCK_LISTEN_PORT 11935
|
||||||
|
#define MOCK_TCP_TIMEOUT (100 * SRS_UTIME_MILLISECONDS)
|
||||||
|
|
||||||
|
class MockTcpHandler : public ISrsTcpHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
srs_netfd_t fd;
|
||||||
|
public:
|
||||||
|
MockTcpHandler();
|
||||||
|
virtual ~MockTcpHandler();
|
||||||
|
public:
|
||||||
|
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||||
|
};
|
||||||
|
|
||||||
|
MockTcpHandler::MockTcpHandler()
|
||||||
|
{
|
||||||
|
fd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
MockTcpHandler::~MockTcpHandler()
|
||||||
|
{
|
||||||
|
srs_close_stfd(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_error_t MockTcpHandler::on_tcp_client(srs_netfd_t stfd)
|
||||||
|
{
|
||||||
|
fd = stfd;
|
||||||
|
return srs_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(TCPServerTest, PingPong)
|
||||||
|
{
|
||||||
|
srs_error_t err;
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
EXPECT_TRUE(l.fd() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
|
||||||
|
SrsTcpClient c(MOCK_LISTEN_HOST, MOCK_LISTEN_PORT, MOCK_TCP_TIMEOUT);
|
||||||
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
|
EXPECT_TRUE(h.fd != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
|
||||||
|
SrsTcpClient c(MOCK_LISTEN_HOST, MOCK_LISTEN_PORT, MOCK_TCP_TIMEOUT);
|
||||||
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
|
SrsStSocket skt;
|
||||||
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(c.write((void*)"Hello", 5, NULL));
|
||||||
|
|
||||||
|
char buf[16] = {0};
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.read(buf, 5, NULL));
|
||||||
|
EXPECT_STREQ(buf, "Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
|
||||||
|
SrsTcpClient c(MOCK_LISTEN_HOST, MOCK_LISTEN_PORT, MOCK_TCP_TIMEOUT);
|
||||||
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
|
SrsStSocket skt;
|
||||||
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(c.write((void*)"Hello", 5, NULL));
|
||||||
|
HELPER_EXPECT_SUCCESS(c.write((void*)" ", 1, NULL));
|
||||||
|
HELPER_EXPECT_SUCCESS(c.write((void*)"SRS", 3, NULL));
|
||||||
|
|
||||||
|
char buf[16] = {0};
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.read(buf, 9, NULL));
|
||||||
|
EXPECT_STREQ(buf, "Hello SRS");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
|
||||||
|
SrsTcpClient c(MOCK_LISTEN_HOST, MOCK_LISTEN_PORT, MOCK_TCP_TIMEOUT);
|
||||||
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
|
SrsStSocket skt;
|
||||||
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(c.write((void*)"Hello SRS", 9, NULL));
|
||||||
|
EXPECT_EQ(9, c.get_send_bytes());
|
||||||
|
EXPECT_EQ(0, c.get_recv_bytes());
|
||||||
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == c.get_send_timeout());
|
||||||
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == c.get_recv_timeout());
|
||||||
|
|
||||||
|
char buf[16] = {0};
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.read(buf, 9, NULL));
|
||||||
|
EXPECT_STREQ(buf, "Hello SRS");
|
||||||
|
EXPECT_EQ(0, skt.get_send_bytes());
|
||||||
|
EXPECT_EQ(9, skt.get_recv_bytes());
|
||||||
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_send_timeout());
|
||||||
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_recv_timeout());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(TCPServerTest, PingPongWithTimeout)
|
||||||
|
{
|
||||||
|
srs_error_t err;
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
|
||||||
|
SrsTcpClient c(MOCK_LISTEN_HOST, MOCK_LISTEN_PORT, MOCK_TCP_TIMEOUT);
|
||||||
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
|
SrsStSocket skt;
|
||||||
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
||||||
|
skt.set_recv_timeout(1 * SRS_UTIME_MILLISECONDS);
|
||||||
|
|
||||||
|
char buf[16] = {0};
|
||||||
|
HELPER_EXPECT_FAILED(skt.read(buf, 9, NULL));
|
||||||
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_send_timeout());
|
||||||
|
EXPECT_TRUE(1*SRS_UTIME_MILLISECONDS == skt.get_recv_timeout());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
|
||||||
|
SrsTcpClient c(MOCK_LISTEN_HOST, MOCK_LISTEN_PORT, MOCK_TCP_TIMEOUT);
|
||||||
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
|
SrsStSocket skt;
|
||||||
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
||||||
|
skt.set_recv_timeout(1 * SRS_UTIME_MILLISECONDS);
|
||||||
|
|
||||||
|
char buf[16] = {0};
|
||||||
|
HELPER_EXPECT_FAILED(skt.read_fully(buf, 9, NULL));
|
||||||
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_send_timeout());
|
||||||
|
EXPECT_TRUE(1*SRS_UTIME_MILLISECONDS == skt.get_recv_timeout());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
|
||||||
|
SrsTcpClient c(MOCK_LISTEN_HOST, MOCK_LISTEN_PORT, MOCK_TCP_TIMEOUT);
|
||||||
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
|
SrsStSocket skt;
|
||||||
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
||||||
|
skt.set_recv_timeout(1 * SRS_UTIME_MILLISECONDS);
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(c.write((void*)"Hello", 5, NULL));
|
||||||
|
|
||||||
|
char buf[16] = {0};
|
||||||
|
HELPER_EXPECT_FAILED(skt.read_fully(buf, 9, NULL));
|
||||||
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_send_timeout());
|
||||||
|
EXPECT_TRUE(1*SRS_UTIME_MILLISECONDS == skt.get_recv_timeout());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(TCPServerTest, WritevIOVC)
|
||||||
|
{
|
||||||
|
srs_error_t err;
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
|
||||||
|
SrsTcpClient c(MOCK_LISTEN_HOST, MOCK_LISTEN_PORT, MOCK_TCP_TIMEOUT);
|
||||||
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
|
SrsStSocket skt;
|
||||||
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
||||||
|
|
||||||
|
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_SUCCESS(c.writev(iovs, 3, NULL));
|
||||||
|
|
||||||
|
char buf[16] = {0};
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.read(buf, 5, NULL));
|
||||||
|
EXPECT_STREQ(buf, "Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockTcpHandler h;
|
||||||
|
SrsTcpListener l(&h, MOCK_LISTEN_HOST, MOCK_LISTEN_PORT);
|
||||||
|
HELPER_EXPECT_SUCCESS(l.listen());
|
||||||
|
|
||||||
|
SrsTcpClient c(MOCK_LISTEN_HOST, MOCK_LISTEN_PORT, MOCK_TCP_TIMEOUT);
|
||||||
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
|
SrsStSocket skt;
|
||||||
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
||||||
|
|
||||||
|
iovec iovs[3];
|
||||||
|
iovs[0].iov_base = (void*)"H";
|
||||||
|
iovs[0].iov_len = 1;
|
||||||
|
iovs[1].iov_base = (void*)NULL;
|
||||||
|
iovs[1].iov_len = 0;
|
||||||
|
iovs[2].iov_base = (void*)"llo";
|
||||||
|
iovs[2].iov_len = 3;
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(c.writev(iovs, 3, NULL));
|
||||||
|
|
||||||
|
char buf[16] = {0};
|
||||||
|
HELPER_EXPECT_SUCCESS(skt.read(buf, 4, NULL));
|
||||||
|
EXPECT_STREQ(buf, "Hllo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue