From 5d8fb01b45d3c4da0f8d1e69bd7d0282e93f57e1 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 7 May 2019 07:46:20 +0800 Subject: [PATCH 1/9] Fix #1352, fix typo of daemon. --- trunk/etc/init.d/srs-api | 2 +- trunk/src/app/srs_app_config.cpp | 4 ++-- trunk/src/app/srs_app_config.hpp | 6 +++--- trunk/src/app/srs_app_server.cpp | 2 +- trunk/src/app/srs_app_utility.hpp | 14 +++++++------- trunk/src/main/srs_main_server.cpp | 8 ++++---- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/trunk/etc/init.d/srs-api b/trunk/etc/init.d/srs-api index 758a79a17..64e5413c7 100755 --- a/trunk/etc/init.d/srs-api +++ b/trunk/etc/init.d/srs-api @@ -54,7 +54,7 @@ start() { ok_msg "Starting SRS-api..." # TODO: FIXME: set limit by, for instance, "ulimit -HSn 10000" # 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 &) # check again after start server diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index b3d90a66c..0210eed1d 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3890,7 +3890,7 @@ srs_error_t SrsConfig::check_normal_config() } // 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"); } @@ -3990,7 +3990,7 @@ string SrsConfig::argv() return _argv; } -bool SrsConfig::get_deamon() +bool SrsConfig::get_daemon() { SrsConfDirective* conf = root->get("daemon"); if (!conf || conf->arg0().empty()) { diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 6d52eb18e..9d30cae86 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -406,10 +406,10 @@ public: // The root directive, no name and args, contains directives. // All directive parsed can retrieve from root. virtual SrsConfDirective* get_root(); - // Get the deamon config. - // If true, SRS will run in deamon mode, fork and fork to reap the + // Get the daemon config. + // If true, SRS will run in daemon mode, fork and fork to reap the // grand-child process to init process. - virtual bool get_deamon(); + virtual bool get_daemon(); // Get the max connections limit of system. // If exceed the max connection, SRS will disconnect the connection. // @remark, linux will limit the connections of each process, diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 5f0d00830..4d2241bc9 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -902,7 +902,7 @@ srs_error_t SrsServer::do_cycle() // for 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. while (true) { if (handler && (err = handler->on_cycle()) != srs_success) { diff --git a/trunk/src/app/srs_app_utility.hpp b/trunk/src/app/srs_app_utility.hpp index 2cf3ee54c..e058e0a93 100644 --- a/trunk/src/app/srs_app_utility.hpp +++ b/trunk/src/app/srs_app_utility.hpp @@ -89,7 +89,7 @@ public: // Get system rusage, use cache to avoid performance problem. 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(); // To stat the process info. @@ -339,7 +339,7 @@ public: extern SrsProcSelfStat* srs_get_self_proc_stat(); // Get system cpu stat, use cache to avoid performance problem. 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(); // Stat disk iops @@ -446,7 +446,7 @@ public: // Get disk stat, use cache to avoid performance problem. 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(); // Stat system memory info @@ -487,7 +487,7 @@ public: // Get system meminfo, use cache to avoid performance problem. extern SrsMemInfo* srs_get_meminfo(); -// The deamon st-thread will update it. +// The daemon st-thread will update it. extern void srs_update_meminfo(); // system cpu hardware info. @@ -543,7 +543,7 @@ public: // Get platform info, use cache to avoid performance problem. 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(); // 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. extern SrsNetworkDevices* srs_get_network_devices(); 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(); // The system connections, and srs rtmp network summary @@ -629,7 +629,7 @@ public: // Get network devices info, use cache to avoid performance problem. 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); // Get local or peer ip. diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index 7bbc75998..39d518fa0 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -378,15 +378,15 @@ srs_error_t run(SrsServer* svr) return srs_error_wrap(err, "server initialize"); } - // If not deamon, directly run master. - if (!_srs_config->get_deamon()) { + // If not daemon, directly run master. + if (!_srs_config->get_daemon()) { if ((err = run_master(svr)) != srs_success) { return srs_error_wrap(err, "run master"); } return srs_success; } - srs_trace("start deamon mode..."); + srs_trace("start daemon mode..."); int pid = fork(); @@ -415,7 +415,7 @@ srs_error_t run(SrsServer* svr) } // son - srs_trace("son(deamon) process running."); + srs_trace("son(daemon) process running."); if ((err = run_master(svr)) != srs_success) { return srs_error_wrap(err, "daemon run master"); From 936616187106d77062670fb7afda9f04fe319e22 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 9 May 2019 07:54:21 +0800 Subject: [PATCH 2/9] Refine utest for tcp connection. --- trunk/src/utest/srs_utest_app.cpp | 8 +------- trunk/src/utest/srs_utest_service.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/trunk/src/utest/srs_utest_app.cpp b/trunk/src/utest/srs_utest_app.cpp index f3b8e759a..7a2f01dd7 100644 --- a/trunk/src/utest/srs_utest_app.cpp +++ b/trunk/src/utest/srs_utest_app.cpp @@ -307,8 +307,6 @@ VOID TEST(AppCoroutineTest, StartThread) srs_freep(err); } -#endif - VOID TEST(AppFragmentTest, CheckDuration) { if (true) { @@ -377,9 +375,5 @@ VOID TEST(AppFragmentTest, CheckDuration) } } -#define MOCK_LISTEN_PORT 11935 - -VOID TEST(TCPServerTest, PingPong) -{ -} +#endif diff --git a/trunk/src/utest/srs_utest_service.cpp b/trunk/src/utest/srs_utest_service.cpp index 343c21755..b4486cc71 100644 --- a/trunk/src/utest/srs_utest_service.cpp +++ b/trunk/src/utest/srs_utest_service.cpp @@ -39,4 +39,10 @@ VOID TEST(ServiceTimeTest, TimeUnit) EXPECT_EQ(3600*1000*1000LL, SRS_UTIME_HOURS); } +#define MOCK_LISTEN_PORT 11935 + +VOID TEST(TCPServerTest, PingPong) +{ +} + #endif From 38a6f5e6cfd56320a89319f51aee14d8464727f5 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 9 May 2019 08:05:27 +0800 Subject: [PATCH 3/9] Support TCP server utest. --- trunk/src/utest/srs_utest_service.cpp | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/trunk/src/utest/srs_utest_service.cpp b/trunk/src/utest/srs_utest_service.cpp index b4486cc71..4d2e5268b 100644 --- a/trunk/src/utest/srs_utest_service.cpp +++ b/trunk/src/utest/srs_utest_service.cpp @@ -25,6 +25,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using namespace std; #include +#include +#include // Disable coroutine test for OSX. #if !defined(SRS_OSX) @@ -39,10 +41,46 @@ VOID TEST(ServiceTimeTest, TimeUnit) EXPECT_EQ(3600*1000*1000LL, SRS_UTIME_HOURS); } +#define MOCK_LISTEN_HOST "127.0.0.1" #define MOCK_LISTEN_PORT 11935 +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); + } } #endif From 1b37b90b8f1d89bd49ec2c5b9b071532cfe08f74 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 9 May 2019 08:38:54 +0800 Subject: [PATCH 4/9] Covert tcp read, write and readfully. --- trunk/src/utest/srs_utest_service.cpp | 143 ++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/trunk/src/utest/srs_utest_service.cpp b/trunk/src/utest/srs_utest_service.cpp index 4d2e5268b..edcd34a6f 100644 --- a/trunk/src/utest/srs_utest_service.cpp +++ b/trunk/src/utest/srs_utest_service.cpp @@ -43,6 +43,7 @@ VOID TEST(ServiceTimeTest, TimeUnit) #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 { @@ -81,6 +82,148 @@ VOID TEST(TCPServerTest, PingPong) 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()); + } } #endif From ccba55cdd85eed3207b47c1995bf2cac5d74626b Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 9 May 2019 08:42:53 +0800 Subject: [PATCH 5/9] Migrate is_never_timeout to utility. --- trunk/src/libs/srs_lib_simple_socket.cpp | 7 ------- trunk/src/libs/srs_lib_simple_socket.hpp | 1 - trunk/src/protocol/srs_protocol_io.hpp | 6 ------ trunk/src/service/srs_service_st.cpp | 15 +++++---------- trunk/src/service/srs_service_st.hpp | 2 -- trunk/src/utest/srs_utest_protocol.cpp | 10 ---------- trunk/src/utest/srs_utest_protocol.hpp | 6 ------ trunk/src/utest/srs_utest_service.cpp | 3 +++ 8 files changed, 8 insertions(+), 42 deletions(-) diff --git a/trunk/src/libs/srs_lib_simple_socket.cpp b/trunk/src/libs/srs_lib_simple_socket.cpp index 844932ea0..76dfe3bdc 100644 --- a/trunk/src/libs/srs_lib_simple_socket.cpp +++ b/trunk/src/libs/srs_lib_simple_socket.cpp @@ -424,13 +424,6 @@ srs_error_t SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t* 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_assert(io); diff --git a/trunk/src/libs/srs_lib_simple_socket.hpp b/trunk/src/libs/srs_lib_simple_socket.hpp index a03fa96b5..3045d2c22 100644 --- a/trunk/src/libs/srs_lib_simple_socket.hpp +++ b/trunk/src/libs/srs_lib_simple_socket.hpp @@ -65,7 +65,6 @@ public: virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite); // Interface ISrsProtocolReadWriter 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 write(void* buf, size_t size, ssize_t* nwrite); }; diff --git a/trunk/src/protocol/srs_protocol_io.hpp b/trunk/src/protocol/srs_protocol_io.hpp index 3bea8e3f5..abcd14c7c 100644 --- a/trunk/src/protocol/srs_protocol_io.hpp +++ b/trunk/src/protocol/srs_protocol_io.hpp @@ -54,8 +54,6 @@ * +--+-----------------------------+-+ * | IProtocolReadWriter | * +----------------------------------+ - * | + is_never_timeout() | - * +----------------------------------+ */ /** @@ -121,10 +119,6 @@ class ISrsProtocolReadWriter : virtual public ISrsProtocolReader, virtual public public: 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 diff --git a/trunk/src/service/srs_service_st.cpp b/trunk/src/service/srs_service_st.cpp index f25cf20d8..7b595baaa 100644 --- a/trunk/src/service/srs_service_st.cpp +++ b/trunk/src/service/srs_service_st.cpp @@ -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); } +bool srs_is_never_timeout(srs_utime_t tm) +{ + return tm == SRS_UTIME_NO_TIMEOUT; +} + SrsStSocket::SrsStSocket() { stfd = NULL; @@ -379,11 +384,6 @@ srs_error_t SrsStSocket::initialize(srs_netfd_t fd) 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) { rtm = tm; @@ -593,11 +593,6 @@ void SrsTcpClient::close() 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) { io->set_recv_timeout(tm); diff --git a/trunk/src/service/srs_service_st.hpp b/trunk/src/service/srs_service_st.hpp index 18b0837fe..c3f03b8a3 100644 --- a/trunk/src/service/srs_service_st.hpp +++ b/trunk/src/service/srs_service_st.hpp @@ -130,7 +130,6 @@ public: // Initialize the socket with stfd, user must manage it. virtual srs_error_t initialize(srs_netfd_t fd); public: - virtual bool is_never_timeout(srs_utime_t tm); virtual void set_recv_timeout(srs_utime_t tm); virtual srs_utime_t get_recv_timeout(); virtual void set_send_timeout(srs_utime_t tm); @@ -181,7 +180,6 @@ private: virtual void close(); // Interface ISrsProtocolReadWriter public: - virtual bool is_never_timeout(srs_utime_t tm); virtual void set_recv_timeout(srs_utime_t tm); virtual srs_utime_t get_recv_timeout(); virtual void set_send_timeout(srs_utime_t tm); diff --git a/trunk/src/utest/srs_utest_protocol.cpp b/trunk/src/utest/srs_utest_protocol.cpp index 86a7af41c..1a6a7a6e3 100644 --- a/trunk/src/utest/srs_utest_protocol.cpp +++ b/trunk/src/utest/srs_utest_protocol.cpp @@ -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*/) { return srs_success; @@ -112,11 +107,6 @@ MockBufferIO* MockBufferIO::append(string data) 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) { if (in_buffer.length() < (int)size) { diff --git a/trunk/src/utest/srs_utest_protocol.hpp b/trunk/src/utest/srs_utest_protocol.hpp index 0ed844ece..a27d338db 100644 --- a/trunk/src/utest/srs_utest_protocol.hpp +++ b/trunk/src/utest/srs_utest_protocol.hpp @@ -46,9 +46,6 @@ class MockEmptyIO : public ISrsProtocolReadWriter public: MockEmptyIO(); virtual ~MockEmptyIO(); -// for protocol -public: - virtual bool is_never_timeout(srs_utime_t tm); // for handshake. public: virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread); @@ -87,9 +84,6 @@ public: virtual ~MockBufferIO(); public: virtual MockBufferIO* append(std::string data); -// for protocol -public: - virtual bool is_never_timeout(srs_utime_t tm); // for handshake. public: virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread); diff --git a/trunk/src/utest/srs_utest_service.cpp b/trunk/src/utest/srs_utest_service.cpp index edcd34a6f..868116f92 100644 --- a/trunk/src/utest/srs_utest_service.cpp +++ b/trunk/src/utest/srs_utest_service.cpp @@ -39,6 +39,9 @@ VOID TEST(ServiceTimeTest, TimeUnit) EXPECT_EQ(1000*1000, SRS_UTIME_SECONDS); EXPECT_EQ(60*1000*1000, SRS_UTIME_MINUTES); 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" From 467d5e5f50c3b18b55d6f8fba721a36dbd6eb678 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 9 May 2019 08:51:14 +0800 Subject: [PATCH 6/9] Fix build failed bug. --- trunk/src/service/srs_service_st.hpp | 2 ++ trunk/src/utest/srs_utest_service.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/trunk/src/service/srs_service_st.hpp b/trunk/src/service/srs_service_st.hpp index c3f03b8a3..4bb02a5b5 100644 --- a/trunk/src/service/srs_service_st.hpp +++ b/trunk/src/service/srs_service_st.hpp @@ -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 bool srs_is_never_timeout(srs_utime_t tm); + // The mutex locker. #define SrsLocker(instance) \ impl__SrsLocker _srs_auto_free_##instance(&instance) diff --git a/trunk/src/utest/srs_utest_service.cpp b/trunk/src/utest/srs_utest_service.cpp index 868116f92..a1b9d53ff 100644 --- a/trunk/src/utest/srs_utest_service.cpp +++ b/trunk/src/utest/srs_utest_service.cpp @@ -39,7 +39,7 @@ VOID TEST(ServiceTimeTest, TimeUnit) EXPECT_EQ(1000*1000, SRS_UTIME_SECONDS); EXPECT_EQ(60*1000*1000, SRS_UTIME_MINUTES); 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)); } From 6ac5b0a006493508b3859505b0014a755a6d698f Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 13 May 2019 08:08:41 +0800 Subject: [PATCH 7/9] Cover tcp socket IO. --- trunk/src/utest/srs_utest_service.cpp | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/trunk/src/utest/srs_utest_service.cpp b/trunk/src/utest/srs_utest_service.cpp index a1b9d53ff..c113d17b1 100644 --- a/trunk/src/utest/srs_utest_service.cpp +++ b/trunk/src/utest/srs_utest_service.cpp @@ -229,4 +229,62 @@ VOID TEST(TCPServerTest, PingPongWithTimeout) } } +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 From a7e0d672a7d797f0f3e6dbb5553396e98d3ad299 Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 13 May 2019 08:48:53 +0800 Subject: [PATCH 8/9] Cover kernel file writer. --- trunk/src/kernel/srs_kernel_file.cpp | 15 ++- trunk/src/kernel/srs_kernel_file.hpp | 5 + trunk/src/utest/srs_utest_kernel.cpp | 135 +++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 5 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_file.cpp b/trunk/src/kernel/srs_kernel_file.cpp index 46e229678..67eafd557 100644 --- a/trunk/src/kernel/srs_kernel_file.cpp +++ b/trunk/src/kernel/srs_kernel_file.cpp @@ -36,6 +36,11 @@ using namespace std; #include #include +// 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() { fd = -1; @@ -57,7 +62,7 @@ srs_error_t SrsFileWriter::open(string p) int flags = O_CREAT|O_WRONLY|O_TRUNC; 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()); } @@ -107,13 +112,13 @@ bool SrsFileWriter::is_open() 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); } 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) @@ -122,7 +127,7 @@ srs_error_t SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) ssize_t nwrite; // 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()); } @@ -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) { - off_t sk = ::lseek(fd, offset, whence); + off_t sk = _srs_lseek_fn(fd, offset, whence); if (sk < 0) { return srs_error_new(ERROR_SYSTEM_FILE_SEEK, "seek file"); } diff --git a/trunk/src/kernel/srs_kernel_file.hpp b/trunk/src/kernel/srs_kernel_file.hpp index 770b645a7..acf2d5d0e 100644 --- a/trunk/src/kernel/srs_kernel_file.hpp +++ b/trunk/src/kernel/srs_kernel_file.hpp @@ -108,5 +108,10 @@ public: 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 diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index 990754ce1..3c61e58c3 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -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) { if (true) { From d5661dcc4ea873b47f565a4af3e014262cbae2c5 Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 13 May 2019 08:49:38 +0800 Subject: [PATCH 9/9] Cover kernel file writer. --- trunk/src/kernel/srs_kernel_file.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/src/kernel/srs_kernel_file.cpp b/trunk/src/kernel/srs_kernel_file.cpp index 67eafd557..0f7625bd9 100644 --- a/trunk/src/kernel/srs_kernel_file.cpp +++ b/trunk/src/kernel/srs_kernel_file.cpp @@ -82,7 +82,7 @@ srs_error_t SrsFileWriter::open_append(string p) int flags = O_APPEND|O_WRONLY; 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()); }