AI: Add utests to cover app rtc module. (#4498)

Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This commit is contained in:
Winlin 2025-09-18 09:33:12 -04:00 committed by winlin
parent 04b88e889f
commit e999de09ea
6 changed files with 2986 additions and 27 deletions

25
trunk/configure vendored
View File

@ -237,8 +237,8 @@ fi
MODULE_ID="CORE"
MODULE_DEPENDS=()
ModuleLibIncs=(${SRS_OBJS})
MODULE_FILES=("srs_core" "srs_core_version" "srs_core_version7" "srs_core_autofree" "srs_core_performance"
"srs_core_time" "srs_core_platform" "srs_core_deprecated")
MODULE_FILES=("srs_core" "srs_core_version" "srs_core_version7" "srs_core_autofree"
"srs_core_time" "srs_core_platform" "srs_core_deprecated" "srs_core_performance")
CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . $SRS_WORKDIR/auto/modules.sh
CORE_OBJS="${MODULE_OBJS[@]}"
#
@ -248,10 +248,10 @@ MODULE_DEPENDS=("CORE")
ModuleLibIncs=(${SRS_OBJS} ${LibSSLRoot})
MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_buffer"
"srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_io"
"srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts" "srs_kernel_ps"
"srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts"
"srs_kernel_stream" "srs_kernel_balance" "srs_kernel_mp4" "srs_kernel_file"
"srs_kernel_kbps" "srs_kernel_rtc_rtp" "srs_kernel_rtc_rtcp" "srs_kernel_packet"
"srs_kernel_st" "srs_kernel_factory" "srs_kernel_hourglass"
"srs_kernel_st" "srs_kernel_factory" "srs_kernel_hourglass" "srs_kernel_ps"
"srs_kernel_pithy_print" "srs_kernel_rtc_queue" "srs_kernel_resource")
KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . $SRS_WORKDIR/auto/modules.sh
KERNEL_OBJS="${MODULE_OBJS[@]}"
@ -261,8 +261,8 @@ MODULE_ID="PROTOCOL"
MODULE_DEPENDS=("CORE" "KERNEL")
ModuleLibIncs=(${SRS_OBJS} ${LibSTRoot} ${LibSSLRoot})
MODULE_FILES=("srs_protocol_amf0" "srs_protocol_io" "srs_protocol_conn" "srs_protocol_rtmp_handshake"
"srs_protocol_rtmp_stack" "srs_protocol_utility" "srs_protocol_rtmp_msg_array" "srs_protocol_stream"
"srs_protocol_raw_avc" "srs_protocol_http_stack" "srs_protocol_json"
"srs_protocol_rtmp_stack" "srs_protocol_utility" "srs_protocol_rtmp_msg_array"
"srs_protocol_raw_avc" "srs_protocol_http_stack" "srs_protocol_json" "srs_protocol_stream"
"srs_protocol_format" "srs_protocol_log" "srs_protocol_st" "srs_protocol_http_client"
"srs_protocol_http_conn" "srs_protocol_rtmp_conn" "srs_protocol_protobuf"
"srs_protocol_http_stack_llhttp" "srs_protocol_http_stack_llhttpapi"
@ -289,17 +289,17 @@ if [[ $SRS_FFMPEG_FIT == YES ]]; then
ModuleLibIncs+=("${LibFfmpegRoot[*]}")
fi
MODULE_FILES=("srs_app_server" "srs_app_rtmp_conn" "srs_app_rtmp_source"
"srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream"
"srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder"
"srs_app_st" "srs_app_log" "srs_app_config" "srs_app_stream_bridge"
"srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks"
"srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_edge"
"srs_app_heartbeat" "srs_app_http_client" "srs_app_http_static"
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
"srs_app_mpegts_udp" "srs_app_listener" "srs_app_async_call"
"srs_app_caster_flv" "srs_app_latest_version" "srs_app_process" "srs_app_ng_exec"
"srs_app_dash" "srs_app_fragment" "srs_app_dvr"
"srs_app_caster_flv" "srs_app_latest_version" "srs_app_process"
"srs_app_dash" "srs_app_fragment" "srs_app_dvr" "srs_app_ng_exec"
"srs_app_coworkers" "srs_app_circuit_breaker" "srs_app_factory"
"srs_app_stream_token")
"srs_app_stream_token" "srs_app_http_stream")
# Always include SRT app modules
MODULE_FILES+=("srs_app_srt_server" "srs_app_srt_listener" "srs_app_srt_conn" "srs_app_srt_source")
MODULE_FILES+=("srs_app_rtc_conn" "srs_app_rtc_dtls" "srs_app_rtc_network"
@ -378,10 +378,11 @@ if [[ $SRS_UTEST == YES ]]; then
MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_kernel" "srs_utest_core"
"srs_utest_config" "srs_utest_rtmp" "srs_utest_http" "srs_utest_avc" "srs_utest_reload"
"srs_utest_mp4" "srs_utest_service" "srs_utest_app" "srs_utest_app2" "srs_utest_rtc" "srs_utest_config2"
"srs_utest_config3" "srs_utest_config4" "srs_utest_protocol" "srs_utest_protocol2" "srs_utest_kernel2" "srs_utest_protocol3"
"srs_utest_config3" "srs_utest_config4" "srs_utest_protocol" "srs_utest_protocol2" "srs_utest_kernel2"
"srs_utest_st" "srs_utest_rtc2" "srs_utest_rtc3" "srs_utest_fmp4" "srs_utest_source_lock"
"srs_utest_stream_token" "srs_utest_rtc_recv_track" "srs_utest_st2" "srs_utest_hevc_structs"
"srs_utest_coworkers" "srs_utest_pithy_print" "srs_utest_kernel3" "srs_utest_protocol4")
"srs_utest_coworkers" "srs_utest_pithy_print" "srs_utest_kernel3" "srs_utest_protocol4"
"srs_utest_protocol3")
# Always include SRT utest
MODULE_FILES+=("srs_utest_srt")
if [[ $SRS_GB28181 == YES ]]; then

View File

@ -400,6 +400,7 @@ SrsRtcSource::SrsRtcSource()
#ifdef SRS_FFMPEG_FIT
frame_builder_ = NULL;
#endif
circuit_breaker_ = _srs_circuit_breaker;
pli_for_rtmp_ = pli_elapsed_ = 0;
stream_die_at_ = 0;
@ -793,7 +794,7 @@ srs_error_t SrsRtcSource::on_rtp(SrsRtpPacket *pkt)
srs_error_t err = srs_success;
// If circuit-breaker is dying, drop packet.
if (_srs_circuit_breaker->hybrid_dying_water_level()) {
if (circuit_breaker_ && circuit_breaker_->hybrid_dying_water_level()) {
_srs_pps_aloss2->sugar_ += (int64_t)consumers_.size();
return err;
}

View File

@ -44,6 +44,7 @@ class SrsRtcFrameBuilder;
class SrsLiveSource;
class SrsRtpVideoBuilder;
class ISrsRtcConsumer;
class ISrsCircuitBreaker;
// Firefox defaults as 109, Chrome is 111.
const int kAudioPayloadType = 111;
@ -219,6 +220,8 @@ public:
class SrsRtcSource : public ISrsFastTimer, public ISrsRtcSourceForConsumer
{
private:
// Circuit breaker for protecting server resources.
ISrsCircuitBreaker *circuit_breaker_;
// For publish, it's the publish client id.
// For edge, it's the edge ingest id.
// when source id changed, for example, the edge reconnect,

View File

@ -329,8 +329,23 @@ srs_error_t SrsHttpTestServer::start()
{
srs_error_t err = srs_success;
if ((err = srs_tcp_listen(ip_, port_, &fd_)) != srs_success) {
return srs_error_wrap(err, "listen %s:%d", ip_.c_str(), port_);
// Retry up to 3 times with different random ports if listen fails
for (int retry = 0; retry < 3; retry++) {
if ((err = srs_tcp_listen(ip_, port_, &fd_)) == srs_success) {
break;
}
// If this is not the last retry, generate a new random port and try again
if (retry < 2) {
srs_freep(err);
port_ = srs_rand_integer(30000, 60000);
srs_trace("HTTP test server listen failed on %s:%d, retry %d with new port %d",
ip_.c_str(), port_, retry + 1, port_);
}
}
if (err != srs_success) {
return srs_error_wrap(err, "listen %s:%d after 3 retries", ip_.c_str(), port_);
}
return trd_->start();
@ -418,8 +433,23 @@ srs_error_t SrsHttpsTestServer::start()
{
srs_error_t err = srs_success;
if ((err = srs_tcp_listen(ip_, port_, &fd_)) != srs_success) {
return srs_error_wrap(err, "listen %s:%d", ip_.c_str(), port_);
// Retry up to 3 times with different random ports if listen fails
for (int retry = 0; retry < 3; retry++) {
if ((err = srs_tcp_listen(ip_, port_, &fd_)) == srs_success) {
break;
}
// If this is not the last retry, generate a new random port and try again
if (retry < 2) {
srs_freep(err);
port_ = srs_rand_integer(30000, 60000);
srs_trace("HTTPS test server listen failed on %s:%d, retry %d with new port %d",
ip_.c_str(), port_, retry + 1, port_);
}
}
if (err != srs_success) {
return srs_error_wrap(err, "listen %s:%d after 3 retries", ip_.c_str(), port_);
}
if ((err = trd_->start()) != srs_success) {
@ -527,8 +557,23 @@ srs_error_t SrsRtmpTestServer::start()
{
srs_error_t err = srs_success;
if ((err = srs_tcp_listen(ip_, port_, &fd_)) != srs_success) {
return srs_error_wrap(err, "listen %s:%d", ip_.c_str(), port_);
// Retry up to 3 times with different random ports if listen fails
for (int retry = 0; retry < 3; retry++) {
if ((err = srs_tcp_listen(ip_, port_, &fd_)) == srs_success) {
break;
}
// If this is not the last retry, generate a new random port and try again
if (retry < 2) {
srs_freep(err);
port_ = srs_rand_integer(30000, 60000);
srs_trace("RTMP test server listen failed on %s:%d, retry %d with new port %d",
ip_.c_str(), port_, retry + 1, port_);
}
}
if (err != srs_success) {
return srs_error_wrap(err, "listen %s:%d after 3 retries", ip_.c_str(), port_);
}
return trd_->start();
@ -835,9 +880,23 @@ srs_error_t SrsUdpTestServer::start()
return err;
}
// Create UDP socket
if ((err = srs_udp_listen(host_, port_, &lfd_)) != srs_success) {
return srs_error_wrap(err, "udp listen %s:%d", host_.c_str(), port_);
// Create UDP socket - retry up to 3 times with different random ports if listen fails
for (int retry = 0; retry < 3; retry++) {
if ((err = srs_udp_listen(host_, port_, &lfd_)) == srs_success) {
break;
}
// If this is not the last retry, generate a new random port and try again
if (retry < 2) {
srs_freep(err);
port_ = 30000 + (srs_rand_integer() % (60000 - 30000 + 1));
srs_trace("UDP test server listen failed on %s:%d, retry %d with new port %d",
host_.c_str(), port_, retry + 1, port_);
}
}
if (err != srs_success) {
return srs_error_wrap(err, "udp listen %s:%d after 3 retries", host_.c_str(), port_);
}
// Get the actual port that was assigned

File diff suppressed because it is too large Load Diff

View File

@ -1516,19 +1516,19 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoFrameDetectorNullPacketHandling
}
// Mock bridge for testing SrsRtcFrameBuilder
class MockStreamBridge : public ISrsStreamBridge
class MockRtcFrameBuilderBridge : public ISrsStreamBridge
{
public:
srs_error_t last_error;
int frame_count;
MockStreamBridge()
MockRtcFrameBuilderBridge()
{
last_error = srs_success;
last_error = NULL;
frame_count = 0;
}
virtual ~MockStreamBridge()
virtual ~MockRtcFrameBuilderBridge()
{
srs_freep(last_error);
}
@ -1577,7 +1577,7 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderPacketVideoRtmpNullPointerCrash)
// but the start packet (100) is missing. With the fix, the function should use
// packet 101 (first available) instead of crashing on the missing packet 100.
if (true) {
MockStreamBridge bridge;
MockRtcFrameBuilderBridge bridge;
SrsRtcFrameBuilder frame_builder(&bridge);
// Skip initialization and directly set up the test scenario