From 04b88e889f4192b548ec60fcf51db4615e78d6a5 Mon Sep 17 00:00:00 2001 From: Winlin Date: Wed, 17 Sep 2025 17:07:37 -0400 Subject: [PATCH] AI: Improve coverage of app by utest (#4494) Co-authored-by: OSSRS-AI --- trunk/configure | 4 +- trunk/src/app/srs_app_config.cpp | 2 +- trunk/src/app/srs_app_gb28181.cpp | 10 +- trunk/src/app/srs_app_rtc_conn.cpp | 20 +- trunk/src/app/srs_app_rtc_source.cpp | 134 +- trunk/src/app/srs_app_rtc_source.hpp | 43 +- trunk/src/app/srs_app_rtsp_conn.cpp | 6 +- trunk/src/app/srs_app_rtsp_source.cpp | 40 +- trunk/src/kernel/srs_kernel_rtc_queue.cpp | 2 +- trunk/src/kernel/srs_kernel_rtc_rtp.cpp | 22 +- trunk/src/kernel/srs_kernel_rtc_rtp.hpp | 4 +- trunk/src/protocol/srs_protocol_rtp.cpp | 42 +- trunk/src/utest/srs_utest_app2.cpp | 679 ++ trunk/src/utest/srs_utest_app2.hpp | 15 + trunk/src/utest/srs_utest_config.cpp | 737 +- trunk/src/utest/srs_utest_config.hpp | 2 +- trunk/src/utest/srs_utest_config2.cpp | 5365 ++++++++++++- trunk/src/utest/srs_utest_config3.cpp | 7436 ++++++++++++++++++ trunk/src/utest/srs_utest_config3.hpp | 15 + trunk/src/utest/srs_utest_config4.cpp | 2037 +++++ trunk/src/utest/srs_utest_config4.hpp | 15 + trunk/src/utest/srs_utest_kernel3.cpp | 48 +- trunk/src/utest/srs_utest_protocol3.cpp | 26 +- trunk/src/utest/srs_utest_protocol4.cpp | 66 +- trunk/src/utest/srs_utest_reload.cpp | 6 +- trunk/src/utest/srs_utest_rtc.cpp | 28 +- trunk/src/utest/srs_utest_rtc2.cpp | 28 +- trunk/src/utest/srs_utest_rtc3.cpp | 38 +- trunk/src/utest/srs_utest_rtc_recv_track.cpp | 68 +- 29 files changed, 16265 insertions(+), 673 deletions(-) create mode 100644 trunk/src/utest/srs_utest_app2.cpp create mode 100644 trunk/src/utest/srs_utest_app2.hpp create mode 100644 trunk/src/utest/srs_utest_config3.cpp create mode 100644 trunk/src/utest/srs_utest_config3.hpp create mode 100644 trunk/src/utest/srs_utest_config4.cpp create mode 100644 trunk/src/utest/srs_utest_config4.hpp diff --git a/trunk/configure b/trunk/configure index efa9aaba9..193244cf3 100755 --- a/trunk/configure +++ b/trunk/configure @@ -377,8 +377,8 @@ fi 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_rtc" "srs_utest_config2" - "srs_utest_protocol" "srs_utest_protocol2" "srs_utest_kernel2" "srs_utest_protocol3" + "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_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") diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 7f211c435..90f9c1d29 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -277,7 +277,7 @@ bool srs_directive_equals(SrsConfDirective *a, SrsConfDirective *b, string excep SrsConfDirective *b0 = b->at(i); // donot compare the except child directive. - if (a0->name_ == except) { + if (a0->name_ == except && b0->name_ == except) { continue; } diff --git a/trunk/src/app/srs_app_gb28181.cpp b/trunk/src/app/srs_app_gb28181.cpp index 4a178065b..b93bff9e1 100644 --- a/trunk/src/app/srs_app_gb28181.cpp +++ b/trunk/src/app/srs_app_gb28181.cpp @@ -564,7 +564,7 @@ srs_error_t SrsGbMediaTcpConn::do_cycle() continue; } - if ((err = bind_session(rtp.header.get_ssrc(), &session_)) != srs_success) { + if ((err = bind_session(rtp.header_.get_ssrc(), &session_)) != srs_success) { return srs_error_wrap(err, "bind session"); } } @@ -1432,11 +1432,11 @@ srs_error_t SrsRecoverablePsContext::decode_rtp(SrsBuffer *stream, int reserved, } SrsBuffer b((char *)rtp_raw->payload_, rtp_raw->nn_payload_); - // srs_trace("GB: Got RTP length=%d, payload=%d, seq=%u, ts=%d", length, rtp_raw->nn_payload, rtp.header.get_sequence(), rtp.header.get_timestamp()); + // srs_trace("GB: Got RTP length=%d, payload=%d, seq=%u, ts=%d", length, rtp_raw->nn_payload, rtp.header_.get_sequence(), rtp.header_.get_timestamp()); - ctx_.helper_.rtp_seq_ = rtp.header.get_sequence(); - ctx_.helper_.rtp_ts_ = rtp.header.get_timestamp(); - ctx_.helper_.rtp_pt_ = rtp.header.get_payload_type(); + ctx_.helper_.rtp_seq_ = rtp.header_.get_sequence(); + ctx_.helper_.rtp_ts_ = rtp.header_.get_timestamp(); + ctx_.helper_.rtp_pt_ = rtp.header_.get_payload_type(); if ((err = decode(&b, handler)) != srs_success) { return srs_error_wrap(err, "decode"); } diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 7ddf0ec8d..7e6f1926e 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -626,13 +626,13 @@ srs_error_t SrsRtcPlayStream::cycle() SrsSharedPtr &source = source_; srs_assert(source.get()); - SrsRtcConsumer *consumer_raw = NULL; + ISrsRtcConsumer *consumer_raw = NULL; if ((err = source->create_consumer(consumer_raw)) != srs_success) { return srs_error_wrap(err, "create consumer, source=%s", req_->get_stream_url().c_str()); } srs_assert(consumer_raw); - SrsUniquePtr consumer(consumer_raw); + SrsUniquePtr consumer(dynamic_cast(consumer_raw)); consumer->set_handler(this); @@ -685,7 +685,7 @@ srs_error_t SrsRtcPlayStream::send_packet(SrsRtpPacket *&pkt) { srs_error_t err = srs_success; - uint32_t ssrc = pkt->header.get_ssrc(); + uint32_t ssrc = pkt->header_.get_ssrc(); // Try to find track from cache. SrsRtcSendTrack *track = NULL; @@ -733,7 +733,7 @@ srs_error_t SrsRtcPlayStream::send_packet(SrsRtpPacket *&pkt) // Consume packet by track. if ((err = track->on_rtp(pkt)) != srs_success) { - return srs_error_wrap(err, "audio track, SSRC=%u, SEQ=%u", ssrc, pkt->header.get_sequence()); + return srs_error_wrap(err, "audio track, SSRC=%u, SEQ=%u", ssrc, pkt->header_.get_sequence()); } // For NACK to handle packet. @@ -1433,14 +1433,14 @@ srs_error_t SrsRtcPublishStream::do_on_rtp_plaintext(SrsRtpPacket *&pkt, SrsBuff pkt->set_decode_handler(this); pkt->set_extension_types(&extension_types_); - pkt->header.ignore_padding(false); + pkt->header_.ignore_padding(false); if ((err = pkt->decode(buf)) != srs_success) { return srs_error_wrap(err, "decode rtp packet"); } // For source to consume packet. - uint32_t ssrc = pkt->header.get_ssrc(); + uint32_t ssrc = pkt->header_.get_ssrc(); SrsRtcAudioRecvTrack *audio_track = get_audio_track(ssrc); SrsRtcVideoRecvTrack *video_track = get_video_track(ssrc); if (audio_track) { @@ -1512,7 +1512,7 @@ void SrsRtcPublishStream::on_before_decode_payload(SrsRtpPacket *pkt, SrsBuffer return; } - uint32_t ssrc = pkt->header.get_ssrc(); + uint32_t ssrc = pkt->header_.get_ssrc(); SrsRtcAudioRecvTrack *audio_track = get_audio_track(ssrc); SrsRtcVideoRecvTrack *video_track = get_video_track(ssrc); @@ -2518,7 +2518,7 @@ srs_error_t SrsRtcConnection::do_send_packet(SrsRtpPacket *pkt) // For NACK simulator, drop packet. if (nn_simulate_player_nack_drop_) { - simulate_player_drop_packet(&pkt->header, (int)iov->iov_len); + simulate_player_drop_packet(&pkt->header_, (int)iov->iov_len); iov->iov_len = 0; return err; } @@ -2532,8 +2532,8 @@ srs_error_t SrsRtcConnection::do_send_packet(SrsRtpPacket *pkt) } // Detail log, should disable it in release version. - srs_info("RTC: SEND PT=%u, SSRC=%#x, SEQ=%u, Time=%u, %u/%u bytes", pkt->header.get_payload_type(), pkt->header.get_ssrc(), - pkt->header.get_sequence(), pkt->header.get_timestamp(), pkt->nb_bytes(), iov->iov_len); + srs_info("RTC: SEND PT=%u, SSRC=%#x, SEQ=%u, Time=%u, %u/%u bytes", pkt->header_.get_payload_type(), pkt->header_.get_ssrc(), + pkt->header_.get_sequence(), pkt->header_.get_timestamp(), pkt->nb_bytes(), iov->iov_len); return err; } diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index 19788ff53..df4336900 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -150,7 +150,23 @@ ISrsRtcSourceChangeCallback::~ISrsRtcSourceChangeCallback() { } -SrsRtcConsumer::SrsRtcConsumer(SrsRtcSource *s) +ISrsRtcSourceForConsumer::ISrsRtcSourceForConsumer() +{ +} + +ISrsRtcSourceForConsumer::~ISrsRtcSourceForConsumer() +{ +} + +ISrsRtcConsumer::ISrsRtcConsumer() +{ +} + +ISrsRtcConsumer::~ISrsRtcConsumer() +{ +} + +SrsRtcConsumer::SrsRtcConsumer(ISrsRtcSourceForConsumer *s) { source_ = s; should_update_source_id_ = false; @@ -548,9 +564,9 @@ srs_error_t SrsRtcSource::on_source_changed() } // Notify all consumers. - std::vector::iterator it; + std::vector::iterator it; for (it = consumers_.begin(); it != consumers_.end(); ++it) { - SrsRtcConsumer *consumer = *it; + ISrsRtcConsumer *consumer = *it; // Notify if context id changed. if (id_changed) { @@ -585,7 +601,7 @@ void SrsRtcSource::set_bridge(ISrsStreamBridge *bridge) #endif } -srs_error_t SrsRtcSource::create_consumer(SrsRtcConsumer *&consumer) +srs_error_t SrsRtcSource::create_consumer(ISrsRtcConsumer *&consumer) { srs_error_t err = srs_success; @@ -599,7 +615,7 @@ srs_error_t SrsRtcSource::create_consumer(SrsRtcConsumer *&consumer) return err; } -srs_error_t SrsRtcSource::consumer_dumps(SrsRtcConsumer *consumer, bool ds, bool dm, bool dg) +srs_error_t SrsRtcSource::consumer_dumps(ISrsRtcConsumer *consumer, bool ds, bool dm, bool dg) { srs_error_t err = srs_success; @@ -609,9 +625,9 @@ srs_error_t SrsRtcSource::consumer_dumps(SrsRtcConsumer *consumer, bool ds, bool return err; } -void SrsRtcSource::on_consumer_destroy(SrsRtcConsumer *consumer) +void SrsRtcSource::on_consumer_destroy(ISrsRtcConsumer *consumer) { - std::vector::iterator it; + std::vector::iterator it; it = std::find(consumers_.begin(), consumers_.end(), consumer); if (it != consumers_.end()) { it = consumers_.erase(it); @@ -783,7 +799,7 @@ srs_error_t SrsRtcSource::on_rtp(SrsRtpPacket *pkt) } for (int i = 0; i < (int)consumers_.size(); i++) { - SrsRtcConsumer *consumer = consumers_.at(i); + ISrsRtcConsumer *consumer = consumers_.at(i); if ((err = consumer->enqueue(pkt->copy())) != srs_success) { return srs_error_wrap(err, "consume message"); } @@ -1153,12 +1169,12 @@ srs_error_t SrsRtcRtpBuilder::package_opus(SrsParsedAudioPacket *audio, SrsRtpPa { srs_error_t err = srs_success; - pkt->header.set_payload_type(audio_payload_type_); - pkt->header.set_ssrc(audio_ssrc_); + pkt->header_.set_payload_type(audio_payload_type_); + pkt->header_.set_ssrc(audio_ssrc_); pkt->frame_type_ = SrsFrameTypeAudio; - pkt->header.set_marker(true); - pkt->header.set_sequence(audio_sequence_++); - pkt->header.set_timestamp(audio->dts_ * 48); + pkt->header_.set_marker(true); + pkt->header_.set_sequence(audio_sequence_++); + pkt->header_.set_timestamp(audio->dts_ * 48); SrsRtpRawPayload *raw = new SrsRtpRawPayload(); pkt->set_payload(raw, SrsRtpPacketPayloadTypeRaw); @@ -1262,7 +1278,7 @@ srs_error_t SrsRtcRtpBuilder::on_video(SrsMediaPacket *msg) } if (!pkts.empty()) { - pkts.back()->header.set_marker(true); + pkts.back()->header_.set_marker(true); } return consume_packets(pkts); @@ -1405,15 +1421,15 @@ void SrsRtcFrameBuilderVideoPacketCache::store_packet(SrsRtpPacket *pkt) return; // Ignore null packets } - uint16_t index = cache_index(pkt->header.get_sequence()); + uint16_t index = cache_index(pkt->header_.get_sequence()); RtcPacketCache &cache = cache_pkts_[index]; cache.in_use_ = true; srs_freep(cache.pkt_); cache.pkt_ = pkt; - cache.sn_ = pkt->header.get_sequence(); + cache.sn_ = pkt->header_.get_sequence(); cache.ts_ = pkt->get_avsync_time(); - cache.rtp_ts_ = pkt->header.get_timestamp(); + cache.rtp_ts_ = pkt->header_.get_timestamp(); } bool SrsRtcFrameBuilderVideoPacketCache::is_slot_in_use(uint16_t sequence_number) @@ -1485,7 +1501,7 @@ int32_t SrsRtcFrameBuilderVideoPacketCache::find_next_lost_sn(uint16_t current_s } SrsRtpPacket *pkt = get_packet(lost_sn); - if (pkt && pkt->header.get_marker()) { + if (pkt && pkt->header_.get_marker()) { end_sn = lost_sn; return -1; } @@ -1546,19 +1562,19 @@ SrsRtcFrameBuilderVideoFrameDetector::~SrsRtcFrameBuilderVideoFrameDetector() void SrsRtcFrameBuilderVideoFrameDetector::on_keyframe_start(SrsRtpPacket *pkt) { if (-1 == rtp_key_frame_ts_) { - rtp_key_frame_ts_ = pkt->header.get_timestamp(); - header_sn_ = pkt->header.get_sequence(); + rtp_key_frame_ts_ = pkt->header_.get_timestamp(); + header_sn_ = pkt->header_.get_sequence(); lost_sn_ = header_sn_ + 1; // Received key frame and clean cache of old p frame pkts video_cache_->clear_all(); srs_trace("RTC2RTMP: keyframe set ts=%u, header=%hu, lost=%hu", (uint32_t)rtp_key_frame_ts_, header_sn_, lost_sn_); - } else if (rtp_key_frame_ts_ != pkt->header.get_timestamp()) { + } else if (rtp_key_frame_ts_ != pkt->header_.get_timestamp()) { // new key frame, clean cache int64_t old_ts = rtp_key_frame_ts_; uint16_t old_header_sn = header_sn_; uint16_t old_lost_sn = lost_sn_; - rtp_key_frame_ts_ = pkt->header.get_timestamp(); - header_sn_ = pkt->header.get_sequence(); + rtp_key_frame_ts_ = pkt->header_.get_timestamp(); + header_sn_ = pkt->header_.get_sequence(); lost_sn_ = header_sn_ + 1; video_cache_->clear_all(); srs_warn("RTC2RTMP: keyframe drop old ts=%u, header=%hu, lost=%hu, set new ts=%u, header=%hu, lost=%hu", @@ -1654,7 +1670,7 @@ srs_error_t SrsRtcFrameBuilderAudioPacketCache::process_packet(SrsRtpPacket *src { srs_error_t err = srs_success; - uint16_t seq = src->header.get_sequence(); + uint16_t seq = src->header_.get_sequence(); srs_utime_t now = srs_time_now_realtime(); if (!initialized_) { @@ -1811,7 +1827,7 @@ srs_error_t SrsRtcFrameBuilder::on_rtp(SrsRtpPacket *pkt) // Have no received any sender report, can't calculate avsync_time, // discard it to avoid timestamp problem in live source - const SrsRtpHeader &h = pkt->header; + const SrsRtpHeader &h = pkt->header_; if (pkt->get_avsync_time() <= 0) { if (sync_state_ < 0) { srs_trace("RTC: Discard no-sync %s, ssrc=%u, seq=%u, ts=%u, state=%d", pkt->is_audio() ? "Audio" : "Video", @@ -1944,7 +1960,7 @@ srs_error_t SrsRtcFrameBuilder::packet_video(SrsRtpPacket *pkt) video_cache_->store_packet(pkt->copy()); // check whether to recovery lost packet and can construct a video frame - uint16_t current_sn = pkt->header.get_sequence(); + uint16_t current_sn = pkt->header_.get_sequence(); if (frame_detector_->is_lost_sn(current_sn)) { uint16_t start, end; bool got_frame; @@ -1979,7 +1995,7 @@ srs_error_t SrsRtcFrameBuilder::packet_video_key_frame(SrsRtpPacket *pkt) video_cache_->store_packet(pkt->copy()); - uint16_t current_sn = pkt->header.get_sequence(); + uint16_t current_sn = pkt->header_.get_sequence(); if (frame_detector_->is_lost_sn(current_sn)) { uint16_t start, end; bool got_frame; @@ -3171,7 +3187,7 @@ srs_error_t SrsRtcRecvTrack::on_nack(SrsRtpPacket **ppkt) srs_error_t err = srs_success; SrsRtpPacket *pkt = *ppkt; - uint16_t seq = pkt->header.get_sequence(); + uint16_t seq = pkt->header_.get_sequence(); SrsRtpNackInfo *nack_info = nack_receiver_->find(seq); if (nack_info) { @@ -3248,8 +3264,8 @@ srs_error_t SrsRtcAudioRecvTrack::on_rtp(SrsSharedPtr &source, Srs { srs_error_t err = srs_success; - pkt->set_avsync_time(cal_avsync_time(pkt->header.get_timestamp())); - srs_info("Audio async rate=%d, rtp=%u, corrected=%" PRId64, (int)rate_, pkt->header.get_timestamp(), pkt->get_avsync_time()); + pkt->set_avsync_time(cal_avsync_time(pkt->header_.get_timestamp())); + srs_info("Audio async rate=%d, rtp=%u, corrected=%" PRId64, (int)rate_, pkt->header_.get_timestamp(), pkt->get_avsync_time()); if ((err = source->on_rtp(pkt)) != srs_success) { return srs_error_wrap(err, "source on rtp"); @@ -3327,8 +3343,8 @@ srs_error_t SrsRtcVideoRecvTrack::on_rtp(SrsSharedPtr &source, Srs { srs_error_t err = srs_success; - pkt->set_avsync_time(cal_avsync_time(pkt->header.get_timestamp())); - srs_info("Video async rate=%d, rtp=%u, corrected=%" PRId64, (int)rate_, pkt->header.get_timestamp(), pkt->get_avsync_time()); + pkt->set_avsync_time(cal_avsync_time(pkt->header_.get_timestamp())); + srs_info("Video async rate=%d, rtp=%u, corrected=%" PRId64, (int)rate_, pkt->header_.get_timestamp(), pkt->get_avsync_time()); if ((err = source->on_rtp(pkt)) != srs_success) { return srs_error_wrap(err, "source on rtp"); @@ -3433,7 +3449,7 @@ SrsRtpPacket *SrsRtcSendTrack::fetch_rtp_packet(uint16_t seq) // For NACK, it sequence must match exactly, or it cause SRTP fail. // Return packet only when sequence is equal. - if (pkt->header.get_sequence() == seq) { + if (pkt->header_.get_sequence() == seq) { ++_srs_pps_rhnack->sugar_; return pkt; } @@ -3441,9 +3457,9 @@ SrsRtpPacket *SrsRtcSendTrack::fetch_rtp_packet(uint16_t seq) // Ignore if sequence not match. uint32_t nn = 0; - if (nack_epp->can_print(pkt->header.get_ssrc(), &nn)) { - srs_trace("RTC: NACK miss seq=%u, require_seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", seq, pkt->header.get_sequence(), - pkt->header.get_ssrc(), pkt->header.get_timestamp(), nn, nack_epp->nn_count_, pkt->nb_bytes()); + if (nack_epp->can_print(pkt->header_.get_ssrc(), &nn)) { + srs_trace("RTC: NACK miss seq=%u, require_seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", seq, pkt->header_.get_sequence(), + pkt->header_.get_ssrc(), pkt->header_.get_timestamp(), nn, nack_epp->nn_count_, pkt->nb_bytes()); } return NULL; } @@ -3469,14 +3485,14 @@ std::string SrsRtcSendTrack::get_track_id() void SrsRtcSendTrack::rebuild_packet(SrsRtpPacket *pkt) { // Rebuild the sequence number. - int16_t seq = pkt->header.get_sequence(); - pkt->header.set_sequence(jitter_seq_->correct(seq)); + int16_t seq = pkt->header_.get_sequence(); + pkt->header_.set_sequence(jitter_seq_->correct(seq)); // Rebuild the timestamp. - uint32_t ts = pkt->header.get_timestamp(); - pkt->header.set_timestamp(jitter_ts_->correct(ts)); + uint32_t ts = pkt->header_.get_timestamp(); + pkt->header_.set_timestamp(jitter_ts_->correct(ts)); - srs_info("RTC: Correct %s seq=%u/%u, ts=%u/%u", track_desc_->type_.c_str(), seq, pkt->header.get_sequence(), ts, pkt->header.get_timestamp()); + srs_info("RTC: Correct %s seq=%u/%u, ts=%u/%u", track_desc_->type_.c_str(), seq, pkt->header_.get_sequence(), ts, pkt->header_.get_timestamp()); } srs_error_t SrsRtcSendTrack::on_nack(SrsRtpPacket **ppkt) @@ -3484,7 +3500,7 @@ srs_error_t SrsRtcSendTrack::on_nack(SrsRtpPacket **ppkt) srs_error_t err = srs_success; SrsRtpPacket *pkt = *ppkt; - uint16_t seq = pkt->header.get_sequence(); + uint16_t seq = pkt->header_.get_sequence(); // insert into video_queue and audio_queue // We directly use the pkt, never copy it, so we should set the pkt to NULL. @@ -3512,9 +3528,9 @@ srs_error_t SrsRtcSendTrack::on_recv_nack(const vector &lost_seqs) } uint32_t nn = 0; - if (nack_epp->can_print(pkt->header.get_ssrc(), &nn)) { - srs_trace("RTC: NACK ARQ seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", pkt->header.get_sequence(), - pkt->header.get_ssrc(), pkt->header.get_timestamp(), nn, nack_epp->nn_count_, pkt->nb_bytes()); + if (nack_epp->can_print(pkt->header_.get_ssrc(), &nn)) { + srs_trace("RTC: NACK ARQ seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", pkt->header_.get_sequence(), + pkt->header_.get_ssrc(), pkt->header_.get_timestamp(), nn, nack_epp->nn_count_, pkt->nb_bytes()); } // By default, we send packets by sendmmsg. @@ -3543,15 +3559,15 @@ srs_error_t SrsRtcAudioSendTrack::on_rtp(SrsRtpPacket *pkt) return err; } - pkt->header.set_ssrc(track_desc_->ssrc_); + pkt->header_.set_ssrc(track_desc_->ssrc_); // Should update PT, because subscriber may use different PT to publisher. - if (track_desc_->media_ && pkt->header.get_payload_type() == track_desc_->media_->pt_of_publisher_) { + if (track_desc_->media_ && pkt->header_.get_payload_type() == track_desc_->media_->pt_of_publisher_) { // If PT is media from publisher, change to PT of media for subscriber. - pkt->header.set_payload_type(track_desc_->media_->pt_); - } else if (track_desc_->red_ && pkt->header.get_payload_type() == track_desc_->red_->pt_of_publisher_) { + pkt->header_.set_payload_type(track_desc_->media_->pt_); + } else if (track_desc_->red_ && pkt->header_.get_payload_type() == track_desc_->red_->pt_of_publisher_) { // If PT is RED from publisher, change to PT of RED for subscriber. - pkt->header.set_payload_type(track_desc_->red_->pt_); + pkt->header_.set_payload_type(track_desc_->red_->pt_); } else { // TODO: FIXME: Should update PT for RTX. } @@ -3563,8 +3579,8 @@ srs_error_t SrsRtcAudioSendTrack::on_rtp(SrsRtpPacket *pkt) return srs_error_wrap(err, "raw send"); } - srs_info("RTC: Send audio ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(), - pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp()); + srs_info("RTC: Send audio ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header_.get_ssrc(), + pkt->header_.get_sequence(), pkt->is_keyframe(), pkt->header_.get_timestamp()); return err; } @@ -3593,15 +3609,15 @@ srs_error_t SrsRtcVideoSendTrack::on_rtp(SrsRtpPacket *pkt) return err; } - pkt->header.set_ssrc(track_desc_->ssrc_); + pkt->header_.set_ssrc(track_desc_->ssrc_); // Should update PT, because subscriber may use different PT to publisher. - if (track_desc_->media_ && pkt->header.get_payload_type() == track_desc_->media_->pt_of_publisher_) { + if (track_desc_->media_ && pkt->header_.get_payload_type() == track_desc_->media_->pt_of_publisher_) { // If PT is media from publisher, change to PT of media for subscriber. - pkt->header.set_payload_type(track_desc_->media_->pt_); - } else if (track_desc_->red_ && pkt->header.get_payload_type() == track_desc_->red_->pt_of_publisher_) { + pkt->header_.set_payload_type(track_desc_->media_->pt_); + } else if (track_desc_->red_ && pkt->header_.get_payload_type() == track_desc_->red_->pt_of_publisher_) { // If PT is RED from publisher, change to PT of RED for subscriber. - pkt->header.set_payload_type(track_desc_->red_->pt_); + pkt->header_.set_payload_type(track_desc_->red_->pt_); } else { // TODO: FIXME: Should update PT for RTX. } @@ -3613,8 +3629,8 @@ srs_error_t SrsRtcVideoSendTrack::on_rtp(SrsRtpPacket *pkt) return srs_error_wrap(err, "raw send"); } - srs_info("RTC: Send video ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(), - pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp()); + srs_info("RTC: Send video ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header_.get_ssrc(), + pkt->header_.get_sequence(), pkt->is_keyframe(), pkt->header_.get_timestamp()); return err; } diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index 7872b1671..db1fa8293 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -43,6 +43,7 @@ class SrsErrorPithyPrint; class SrsRtcFrameBuilder; class SrsLiveSource; class SrsRtpVideoBuilder; +class ISrsRtcConsumer; // Firefox defaults as 109, Chrome is 111. const int kAudioPayloadType = 111; @@ -89,12 +90,38 @@ public: virtual void on_stream_change(SrsRtcSourceDescription *desc) = 0; }; +// The RTC source for consumer. +class ISrsRtcSourceForConsumer +{ +public: + ISrsRtcSourceForConsumer(); + virtual ~ISrsRtcSourceForConsumer(); + +public: + virtual void on_consumer_destroy(ISrsRtcConsumer *consumer) = 0; + virtual SrsContextId source_id() = 0; + virtual SrsContextId pre_source_id() = 0; +}; + +// The RTC consumer interface. +class ISrsRtcConsumer +{ +public: + ISrsRtcConsumer(); + virtual ~ISrsRtcConsumer(); + +public: + virtual void update_source_id() = 0; + virtual void on_stream_change(SrsRtcSourceDescription *desc) = 0; + virtual srs_error_t enqueue(SrsRtpPacket *pkt) = 0; +}; + // The RTC stream consumer, consume packets from RTC stream source. -class SrsRtcConsumer +class SrsRtcConsumer : public ISrsRtcConsumer { private: // Because source references to this object, so we should directly use the source ptr. - SrsRtcSource *source_; + ISrsRtcSourceForConsumer *source_; private: std::vector queue_; @@ -110,7 +137,7 @@ private: ISrsRtcSourceChangeCallback *handler_; public: - SrsRtcConsumer(SrsRtcSource *s); + SrsRtcConsumer(ISrsRtcSourceForConsumer *s); virtual ~SrsRtcConsumer(); public: @@ -189,7 +216,7 @@ public: }; // A Source is a stream, to publish and to play with, binding to SrsRtcPublishStream and SrsRtcPlayStream. -class SrsRtcSource : public ISrsFastTimer +class SrsRtcSource : public ISrsFastTimer, public ISrsRtcSourceForConsumer { private: // For publish, it's the publish client id. @@ -214,7 +241,7 @@ private: private: // To delivery stream to clients. - std::vector consumers_; + std::vector consumers_; // Whether stream is created, that is, SDP is done. bool is_created_; // Whether stream is delivering data, that is, DTLS is done. @@ -264,13 +291,13 @@ public: public: // Create consumer // @param consumer, output the create consumer. - virtual srs_error_t create_consumer(SrsRtcConsumer *&consumer); + virtual srs_error_t create_consumer(ISrsRtcConsumer *&consumer); // Dumps packets in cache to consumer. // @param ds, whether dumps the sequence header. // @param dm, whether dumps the metadata. // @param dg, whether dumps the gop cache. - virtual srs_error_t consumer_dumps(SrsRtcConsumer *consumer, bool ds = true, bool dm = true, bool dg = true); - virtual void on_consumer_destroy(SrsRtcConsumer *consumer); + virtual srs_error_t consumer_dumps(ISrsRtcConsumer *consumer, bool ds = true, bool dm = true, bool dg = true); + virtual void on_consumer_destroy(ISrsRtcConsumer *consumer); // Whether we can publish stream to the source, return false if it exists. // @remark Note that when SDP is done, we set the stream is not able to publish. virtual bool can_publish(); diff --git a/trunk/src/app/srs_app_rtsp_conn.cpp b/trunk/src/app/srs_app_rtsp_conn.cpp index e73831979..d6e8472fc 100644 --- a/trunk/src/app/srs_app_rtsp_conn.cpp +++ b/trunk/src/app/srs_app_rtsp_conn.cpp @@ -264,7 +264,7 @@ srs_error_t SrsRtspPlayStream::send_packet(SrsRtpPacket *&pkt) { srs_error_t err = srs_success; - uint32_t ssrc = pkt->header.get_ssrc(); + uint32_t ssrc = pkt->header_.get_ssrc(); // Try to find track from cache. SrsRtspSendTrack *track = NULL; @@ -312,7 +312,7 @@ srs_error_t SrsRtspPlayStream::send_packet(SrsRtpPacket *&pkt) // Consume packet by track. if ((err = track->on_rtp(pkt)) != srs_success) { - return srs_error_wrap(err, "audio track, SSRC=%u, SEQ=%u", ssrc, pkt->header.get_sequence()); + return srs_error_wrap(err, "audio track, SSRC=%u, SEQ=%u", ssrc, pkt->header_.get_sequence()); } return err; @@ -416,7 +416,7 @@ srs_error_t SrsRtspConnection::do_send_packet(SrsRtpPacket *pkt) { srs_error_t err = srs_success; - uint32_t ssrc = pkt->header.get_ssrc(); + uint32_t ssrc = pkt->header_.get_ssrc(); ISrsStreamWriter *network = networks_[ssrc]; if (!network) { return srs_error_new(ERROR_RTSP_NO_TRACK, "network not found for ssrc: %u", ssrc); diff --git a/trunk/src/app/srs_app_rtsp_source.cpp b/trunk/src/app/srs_app_rtsp_source.cpp index f881f9ada..9ed18b01e 100644 --- a/trunk/src/app/srs_app_rtsp_source.cpp +++ b/trunk/src/app/srs_app_rtsp_source.cpp @@ -765,12 +765,12 @@ srs_error_t SrsRtspRtpBuilder::package_aac(SrsParsedAudioPacket *audio, SrsRtpPa dts *= (int64_t)audio_sample_rate_; dts /= 1000; - pkt->header.set_payload_type(audio_payload_type_); - pkt->header.set_ssrc(audio_ssrc_); + pkt->header_.set_payload_type(audio_payload_type_); + pkt->header_.set_ssrc(audio_ssrc_); pkt->frame_type_ = SrsFrameTypeAudio; - pkt->header.set_marker(true); - pkt->header.set_sequence(audio_sequence_++); - pkt->header.set_timestamp(dts); + pkt->header_.set_marker(true); + pkt->header_.set_sequence(audio_sequence_++); + pkt->header_.set_timestamp(dts); SrsRtpRawPayload *raw = new SrsRtpRawPayload(); pkt->set_payload(raw, SrsRtpPacketPayloadTypeRaw); @@ -902,7 +902,7 @@ srs_error_t SrsRtspRtpBuilder::on_video(SrsMediaPacket *msg) } if (!pkts.empty()) { - pkts.back()->header.set_marker(true); + pkts.back()->header_.set_marker(true); } return consume_packets(pkts); @@ -1035,15 +1035,15 @@ srs_error_t SrsRtspAudioSendTrack::on_rtp(SrsRtpPacket *pkt) return err; } - pkt->header.set_ssrc(track_desc_->ssrc_); + pkt->header_.set_ssrc(track_desc_->ssrc_); // Should update PT, because subscriber may use different PT to publisher. - if (track_desc_->media_ && pkt->header.get_payload_type() == track_desc_->media_->pt_of_publisher_) { + if (track_desc_->media_ && pkt->header_.get_payload_type() == track_desc_->media_->pt_of_publisher_) { // If PT is media from publisher, change to PT of media for subscriber. - pkt->header.set_payload_type(track_desc_->media_->pt_); - } else if (track_desc_->red_ && pkt->header.get_payload_type() == track_desc_->red_->pt_of_publisher_) { + pkt->header_.set_payload_type(track_desc_->media_->pt_); + } else if (track_desc_->red_ && pkt->header_.get_payload_type() == track_desc_->red_->pt_of_publisher_) { // If PT is RED from publisher, change to PT of RED for subscriber. - pkt->header.set_payload_type(track_desc_->red_->pt_); + pkt->header_.set_payload_type(track_desc_->red_->pt_); } else { // TODO: FIXME: Should update PT for RTX. } @@ -1052,8 +1052,8 @@ srs_error_t SrsRtspAudioSendTrack::on_rtp(SrsRtpPacket *pkt) return srs_error_wrap(err, "raw send"); } - srs_info("RTSP: Send audio ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(), - pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp()); + srs_info("RTSP: Send audio ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header_.get_ssrc(), + pkt->header_.get_sequence(), pkt->is_keyframe(), pkt->header_.get_timestamp()); return err; } @@ -1075,15 +1075,15 @@ srs_error_t SrsRtspVideoSendTrack::on_rtp(SrsRtpPacket *pkt) return err; } - pkt->header.set_ssrc(track_desc_->ssrc_); + pkt->header_.set_ssrc(track_desc_->ssrc_); // Should update PT, because subscriber may use different PT to publisher. - if (track_desc_->media_ && pkt->header.get_payload_type() == track_desc_->media_->pt_of_publisher_) { + if (track_desc_->media_ && pkt->header_.get_payload_type() == track_desc_->media_->pt_of_publisher_) { // If PT is media from publisher, change to PT of media for subscriber. - pkt->header.set_payload_type(track_desc_->media_->pt_); - } else if (track_desc_->red_ && pkt->header.get_payload_type() == track_desc_->red_->pt_of_publisher_) { + pkt->header_.set_payload_type(track_desc_->media_->pt_); + } else if (track_desc_->red_ && pkt->header_.get_payload_type() == track_desc_->red_->pt_of_publisher_) { // If PT is RED from publisher, change to PT of RED for subscriber. - pkt->header.set_payload_type(track_desc_->red_->pt_); + pkt->header_.set_payload_type(track_desc_->red_->pt_); } else { // TODO: FIXME: Should update PT for RTX. } @@ -1092,8 +1092,8 @@ srs_error_t SrsRtspVideoSendTrack::on_rtp(SrsRtpPacket *pkt) return srs_error_wrap(err, "raw send"); } - srs_info("RTSP: Send video ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(), - pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp()); + srs_info("RTSP: Send video ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header_.get_ssrc(), + pkt->header_.get_sequence(), pkt->is_keyframe(), pkt->header_.get_timestamp()); return err; } diff --git a/trunk/src/kernel/srs_kernel_rtc_queue.cpp b/trunk/src/kernel/srs_kernel_rtc_queue.cpp index f3ff5fc69..592fda2db 100644 --- a/trunk/src/kernel/srs_kernel_rtc_queue.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_queue.cpp @@ -149,7 +149,7 @@ void SrsRtpRingBuffer::clear_histroy(uint16_t seq) // TODO FIXME Did not consider loopback for (uint16_t i = 0; i < capacity_; i++) { SrsRtpPacket *p = queue_[i]; - if (p && p->header.get_sequence() < seq) { + if (p && p->header_.get_sequence() < seq) { srs_freep(p); queue_[i] = NULL; } diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp index e0445fce8..b3920227c 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp @@ -824,7 +824,7 @@ SrsRtpPacket *SrsRtpPacket::copy() { SrsRtpPacket *cp = new SrsRtpPacket(); - cp->header = header; + cp->header_ = header_; cp->payload_ = payload_ ? payload_->copy() : NULL; cp->payload_type_ = payload_type_; @@ -844,15 +844,15 @@ SrsRtpPacket *SrsRtpPacket::copy() void SrsRtpPacket::set_padding(int size) { - header.set_padding(size); + header_.set_padding(size); if (cached_payload_size_) { - cached_payload_size_ += size - header.get_padding(); + cached_payload_size_ += size - header_.get_padding(); } } void SrsRtpPacket::add_padding(int size) { - header.set_padding(header.get_padding() + size); + header_.set_padding(header_.get_padding() + size); if (cached_payload_size_) { cached_payload_size_ += size; } @@ -870,14 +870,14 @@ bool SrsRtpPacket::is_audio() void SrsRtpPacket::set_extension_types(SrsRtpExtensionTypes *v) { - return header.set_extensions(v); + return header_.set_extensions(v); } uint64_t SrsRtpPacket::nb_bytes() { if (!cached_payload_size_) { int nn_payload = (payload_ ? payload_->nb_bytes() : 0); - cached_payload_size_ = header.nb_bytes() + nn_payload + header.get_padding(); + cached_payload_size_ = header_.nb_bytes() + nn_payload + header_.get_padding(); } return cached_payload_size_; } @@ -886,7 +886,7 @@ srs_error_t SrsRtpPacket::encode(SrsBuffer *buf) { srs_error_t err = srs_success; - if ((err = header.encode(buf)) != srs_success) { + if ((err = header_.encode(buf)) != srs_success) { return srs_error_wrap(err, "rtp header"); } @@ -894,8 +894,8 @@ srs_error_t SrsRtpPacket::encode(SrsBuffer *buf) return srs_error_wrap(err, "rtp payload"); } - if (header.get_padding() > 0) { - uint8_t padding = header.get_padding(); + if (header_.get_padding() > 0) { + uint8_t padding = header_.get_padding(); if (!buf->require(padding)) { return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", padding); } @@ -910,12 +910,12 @@ srs_error_t SrsRtpPacket::decode(SrsBuffer *buf) { srs_error_t err = srs_success; - if ((err = header.decode(buf)) != srs_success) { + if ((err = header_.decode(buf)) != srs_success) { return srs_error_wrap(err, "rtp header"); } // We must skip the padding bytes before parsing payload. - uint8_t padding = header.get_padding(); + uint8_t padding = header_.get_padding(); if (!buf->require(padding)) { return srs_error_wrap(err, "requires padding %d bytes", padding); } diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp index 93fa48ead..3be90f81a 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp @@ -324,7 +324,7 @@ class SrsRtpPacket { // RTP packet fields. public: - SrsRtpHeader header; + SrsRtpHeader header_; private: ISrsRtpPayloader *payload_; @@ -369,7 +369,7 @@ public: public: // Parse the TWCC extension, ignore by default. - void enable_twcc_decode() { header.enable_twcc_decode(); } // SrsRtpPacket::enable_twcc_decode + void enable_twcc_decode() { header_.enable_twcc_decode(); } // SrsRtpPacket::enable_twcc_decode // Get and set the payload of packet. // @remark Note that return NULL if no payload. void set_payload(ISrsRtpPayloader *p, SrsRtpPacketPayloadType pt) diff --git a/trunk/src/protocol/srs_protocol_rtp.cpp b/trunk/src/protocol/srs_protocol_rtp.cpp index 8742fafc4..596f325eb 100644 --- a/trunk/src/protocol/srs_protocol_rtp.cpp +++ b/trunk/src/protocol/srs_protocol_rtp.cpp @@ -45,12 +45,12 @@ srs_error_t SrsRtpVideoBuilder::package_stap_a(SrsMediaPacket *msg, SrsRtpPacket return err; } - pkt->header.set_payload_type(video_payload_type_); - pkt->header.set_ssrc(video_ssrc_); + pkt->header_.set_payload_type(video_payload_type_); + pkt->header_.set_ssrc(video_ssrc_); pkt->frame_type_ = SrsFrameTypeVideo; - pkt->header.set_marker(false); - pkt->header.set_sequence(video_sequence_++); - pkt->header.set_timestamp(msg->timestamp_ * 90); + pkt->header_.set_marker(false); + pkt->header_.set_sequence(video_sequence_++); + pkt->header_.set_timestamp(msg->timestamp_ * 90); ISrsRtpPayloader *stap = NULL; vector *> params; @@ -141,12 +141,12 @@ srs_error_t SrsRtpVideoBuilder::package_nalus(SrsMediaPacket *msg, const vector< SrsRtpPacket *pkt = new SrsRtpPacket(); pkts.push_back(pkt); - pkt->header.set_payload_type(video_payload_type_); - pkt->header.set_ssrc(video_ssrc_); + pkt->header_.set_payload_type(video_payload_type_); + pkt->header_.set_ssrc(video_ssrc_); pkt->frame_type_ = SrsFrameTypeVideo; pkt->nalu_type_ = first_nalu_type; - pkt->header.set_sequence(video_sequence_++); - pkt->header.set_timestamp(msg->timestamp_ * 90); + pkt->header_.set_sequence(video_sequence_++); + pkt->header_.set_timestamp(msg->timestamp_ * 90); pkt->set_payload(raw_raw, SrsRtpPacketPayloadTypeNALU); pkt->wrap(msg->payload_); } else { @@ -171,12 +171,12 @@ srs_error_t SrsRtpVideoBuilder::package_nalus(SrsMediaPacket *msg, const vector< SrsRtpPacket *pkt = new SrsRtpPacket(); pkts.push_back(pkt); - pkt->header.set_payload_type(video_payload_type_); - pkt->header.set_ssrc(video_ssrc_); + pkt->header_.set_payload_type(video_payload_type_); + pkt->header_.set_ssrc(video_ssrc_); pkt->frame_type_ = SrsFrameTypeVideo; pkt->nalu_type_ = kFuA; - pkt->header.set_sequence(video_sequence_++); - pkt->header.set_timestamp(msg->timestamp_ * 90); + pkt->header_.set_sequence(video_sequence_++); + pkt->header_.set_timestamp(msg->timestamp_ * 90); if (is_hevc) { SrsRtpFUAPayloadHevc *fua = new SrsRtpFUAPayloadHevc(); @@ -219,11 +219,11 @@ srs_error_t SrsRtpVideoBuilder::package_single_nalu(SrsMediaPacket *msg, SrsNalu SrsRtpPacket *pkt = new SrsRtpPacket(); pkts.push_back(pkt); - pkt->header.set_payload_type(video_payload_type_); - pkt->header.set_ssrc(video_ssrc_); + pkt->header_.set_payload_type(video_payload_type_); + pkt->header_.set_ssrc(video_ssrc_); pkt->frame_type_ = SrsFrameTypeVideo; - pkt->header.set_sequence(video_sequence_++); - pkt->header.set_timestamp(msg->timestamp_ * 90); + pkt->header_.set_sequence(video_sequence_++); + pkt->header_.set_timestamp(msg->timestamp_ * 90); SrsRtpRawPayload *raw = new SrsRtpRawPayload(); pkt->set_payload(raw, SrsRtpPacketPayloadTypeRaw); @@ -260,11 +260,11 @@ srs_error_t SrsRtpVideoBuilder::package_fu_a(SrsMediaPacket *msg, SrsNaluSample SrsRtpPacket *pkt = new SrsRtpPacket(); pkts.push_back(pkt); - pkt->header.set_payload_type(video_payload_type_); - pkt->header.set_ssrc(video_ssrc_); + pkt->header_.set_payload_type(video_payload_type_); + pkt->header_.set_ssrc(video_ssrc_); pkt->frame_type_ = SrsFrameTypeVideo; - pkt->header.set_sequence(video_sequence_++); - pkt->header.set_timestamp(msg->timestamp_ * 90); + pkt->header_.set_sequence(video_sequence_++); + pkt->header_.set_timestamp(msg->timestamp_ * 90); pkt->nalu_type_ = is_hevc ? kFuHevc : kFuA; if (is_hevc) { diff --git a/trunk/src/utest/srs_utest_app2.cpp b/trunk/src/utest/srs_utest_app2.cpp new file mode 100644 index 000000000..33847299b --- /dev/null +++ b/trunk/src/utest/srs_utest_app2.cpp @@ -0,0 +1,679 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// + +#include + +#include +#include +#include +#include +#include +#include +#include + +// External function declaration from srs_app_rtc_source.cpp +extern srs_error_t aac_raw_append_adts_header(SrsMediaPacket *shared_audio, SrsFormat *format, char **pbuf, int *pnn_buf); + +// Mock implementation of ISrsRtcSourceForConsumer for testing SrsRtcConsumer +class MockRtcSourceForConsumer : public ISrsRtcSourceForConsumer +{ +public: + SrsContextId source_id_; + SrsContextId pre_source_id_; + int consumer_destroy_count_; + ISrsRtcConsumer *last_destroyed_consumer_; + + MockRtcSourceForConsumer() + { + source_id_.set_value("test-source-id"); + pre_source_id_.set_value("test-pre-source-id"); + consumer_destroy_count_ = 0; + last_destroyed_consumer_ = NULL; + } + + virtual ~MockRtcSourceForConsumer() + { + } + + virtual void on_consumer_destroy(ISrsRtcConsumer *consumer) + { + consumer_destroy_count_++; + last_destroyed_consumer_ = consumer; + } + + virtual SrsContextId source_id() + { + return source_id_; + } + + virtual SrsContextId pre_source_id() + { + return pre_source_id_; + } +}; + +// Mock implementation of ISrsRtcSourceChangeCallback for testing +class MockRtcSourceChangeCallback : public ISrsRtcSourceChangeCallback +{ +public: + int stream_change_count_; + SrsRtcSourceDescription *last_stream_desc_; + + MockRtcSourceChangeCallback() + { + stream_change_count_ = 0; + last_stream_desc_ = NULL; + } + + virtual ~MockRtcSourceChangeCallback() + { + } + + virtual void on_stream_change(SrsRtcSourceDescription *desc) + { + stream_change_count_++; + last_stream_desc_ = desc; + } +}; + +VOID TEST(AppTest2, AacRawAppendAdtsHeaderSequenceHeader) +{ + srs_error_t err; + + // Create a mock AAC sequence header packet + SrsUniquePtr audio_packet(new SrsMediaPacket()); + audio_packet->message_type_ = SrsFrameTypeAudio; + + // Create format with AAC sequence header + SrsUniquePtr format(new SrsFormat()); + HELPER_EXPECT_SUCCESS(format->initialize()); + + // Set up AAC codec info to simulate sequence header + format->acodec_ = new SrsAudioCodecConfig(); + format->acodec_->id_ = SrsAudioCodecIdAAC; + format->acodec_->aac_object_ = SrsAacObjectTypeAacLC; + format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index + format->acodec_->aac_channels_ = 2; + + // Create audio frame info to simulate sequence header + format->audio_ = new SrsParsedAudioPacket(); + format->audio_->dts_ = 1000; + format->audio_->cts_ = 0; + format->audio_->nb_samples_ = 0; // Sequence header has 0 samples + + char *buf = NULL; + int nn_buf = 0; + + // Test: sequence header should return success without creating buffer + HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf)); + EXPECT_TRUE(buf == NULL); + EXPECT_EQ(0, nn_buf); +} + +VOID TEST(AppTest2, AacRawAppendAdtsHeaderNoSamples) +{ + srs_error_t err; + + // Create a mock AAC packet + SrsUniquePtr audio_packet(new SrsMediaPacket()); + audio_packet->message_type_ = SrsFrameTypeAudio; + + // Create format with AAC but no samples + SrsUniquePtr format(new SrsFormat()); + HELPER_EXPECT_SUCCESS(format->initialize()); + + // Set up AAC codec info + format->acodec_ = new SrsAudioCodecConfig(); + format->acodec_->id_ = SrsAudioCodecIdAAC; + format->acodec_->aac_object_ = SrsAacObjectTypeAacLC; + format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index + format->acodec_->aac_channels_ = 2; + + // Create audio frame info with no samples + format->audio_ = new SrsParsedAudioPacket(); + format->audio_->dts_ = 1000; + format->audio_->cts_ = 0; + format->audio_->nb_samples_ = 0; // No samples + + char *buf = NULL; + int nn_buf = 0; + + // Test: no samples should return success without creating buffer + HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf)); + EXPECT_TRUE(buf == NULL); + EXPECT_EQ(0, nn_buf); +} + +VOID TEST(AppTest2, AacRawAppendAdtsHeaderMultipleSamples) +{ + srs_error_t err; + + // Create a mock AAC packet + SrsUniquePtr audio_packet(new SrsMediaPacket()); + audio_packet->message_type_ = SrsFrameTypeAudio; + + // Create format with AAC + SrsUniquePtr format(new SrsFormat()); + HELPER_EXPECT_SUCCESS(format->initialize()); + + // Set up AAC codec info + format->acodec_ = new SrsAudioCodecConfig(); + format->acodec_->id_ = SrsAudioCodecIdAAC; + format->acodec_->aac_object_ = SrsAacObjectTypeAacLC; + format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index + format->acodec_->aac_channels_ = 2; + + // Create audio frame info with multiple samples (should fail) + format->audio_ = new SrsParsedAudioPacket(); + format->audio_->dts_ = 1000; + format->audio_->cts_ = 0; + format->audio_->nb_samples_ = 2; // Multiple samples should cause error + + char *buf = NULL; + int nn_buf = 0; + + // Test: multiple samples should return error + HELPER_EXPECT_FAILED(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf)); +} + +VOID TEST(AppTest2, AacRawAppendAdtsHeaderValidSingleSample) +{ + srs_error_t err; + + // Create a mock AAC packet + SrsUniquePtr audio_packet(new SrsMediaPacket()); + audio_packet->message_type_ = SrsFrameTypeAudio; + + // Create format with AAC + SrsUniquePtr format(new SrsFormat()); + HELPER_EXPECT_SUCCESS(format->initialize()); + + // Set up AAC codec info + format->acodec_ = new SrsAudioCodecConfig(); + format->acodec_->id_ = SrsAudioCodecIdAAC; + format->acodec_->aac_object_ = SrsAacObjectTypeAacLC; // Object type 2 + format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index + format->acodec_->aac_channels_ = 2; // Stereo + + // Create audio frame info with single sample + format->audio_ = new SrsParsedAudioPacket(); + format->audio_->dts_ = 1000; + format->audio_->cts_ = 0; + format->audio_->nb_samples_ = 1; // Single sample + + // Create sample data + const char sample_data[] = {0x01, 0x02, 0x03, 0x04, 0x05}; // 5 bytes of sample data + format->audio_->samples_[0].bytes_ = (char *)sample_data; + format->audio_->samples_[0].size_ = sizeof(sample_data); + + char *buf = NULL; + int nn_buf = 0; + + // Test: valid single sample should create ADTS header + data + HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf)); + + // Verify buffer was created + EXPECT_TRUE(buf != NULL); + EXPECT_EQ(7 + sizeof(sample_data), nn_buf); // 7 bytes ADTS header + sample data + + if (!buf) { + return; + } + SrsUniquePtr buf_ptr(buf); + + // Verify ADTS header structure + EXPECT_EQ((unsigned char)0xFF, (unsigned char)buf[0]); // Sync word high + EXPECT_EQ((unsigned char)0xF9, (unsigned char)buf[1]); // Sync word low + layer + protection + + // Verify AAC object type, sample rate, and channels are encoded correctly + // Byte 2: (object-1)<<6 | (sample_rate&0x0F)<<2 | (channels&0x04)>>2 + unsigned char expected_byte2 = ((SrsAacObjectTypeAacLC - 1) << 6) | ((4 & 0x0F) << 2) | ((2 & 0x04) >> 2); + EXPECT_EQ(expected_byte2, (unsigned char)buf[2]); + + // Verify frame length is encoded correctly (total length = 7 + sample size) + int expected_frame_len = 7 + sizeof(sample_data); + // Frame length spans bytes 3-5 + unsigned char expected_byte3 = ((2 & 0x03) << 6) | ((expected_frame_len >> 11) & 0x03); + unsigned char expected_byte4 = (expected_frame_len >> 3) & 0xFF; + unsigned char expected_byte5 = ((expected_frame_len & 0x07) << 5) | 0x1F; + + EXPECT_EQ(expected_byte3, (unsigned char)buf[3]); + EXPECT_EQ(expected_byte4, (unsigned char)buf[4]); + EXPECT_EQ(expected_byte5, (unsigned char)buf[5]); + + EXPECT_EQ((unsigned char)0xFC, (unsigned char)buf[6]); // Buffer fullness + frame count + + // Verify sample data is copied correctly + for (int i = 0; i < sizeof(sample_data); i++) { + EXPECT_EQ(sample_data[i], buf[7 + i]); + } +} + +VOID TEST(AppTest2, AacRawAppendAdtsHeaderDifferentCodecParams) +{ + srs_error_t err; + + // Create a mock AAC packet + SrsUniquePtr audio_packet(new SrsMediaPacket()); + audio_packet->message_type_ = SrsFrameTypeAudio; + + // Create format with different AAC parameters + SrsUniquePtr format(new SrsFormat()); + HELPER_EXPECT_SUCCESS(format->initialize()); + + // Set up AAC codec info with different parameters + format->acodec_ = new SrsAudioCodecConfig(); + format->acodec_->id_ = SrsAudioCodecIdAAC; + format->acodec_->aac_object_ = SrsAacObjectTypeAacHE; // Object type 5 + format->acodec_->aac_sample_rate_ = 3; // 48000 Hz index + format->acodec_->aac_channels_ = 1; // Mono + + // Create audio frame info with single sample + format->audio_ = new SrsParsedAudioPacket(); + format->audio_->dts_ = 2000; + format->audio_->cts_ = 0; + format->audio_->nb_samples_ = 1; + + // Create sample data + const char sample_data[] = {(char)0xAA, (char)0xBB, (char)0xCC}; // 3 bytes of sample data + format->audio_->samples_[0].bytes_ = (char *)sample_data; + format->audio_->samples_[0].size_ = sizeof(sample_data); + + char *buf = NULL; + int nn_buf = 0; + + // Test: different codec parameters should work + HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf)); + + // Verify buffer was created with correct size + EXPECT_TRUE(buf != NULL); + EXPECT_EQ(7 + sizeof(sample_data), nn_buf); + + if (!buf) { + return; + } + SrsUniquePtr buf_ptr(buf); + + // Verify ADTS header with different parameters + EXPECT_EQ((unsigned char)0xFF, (unsigned char)buf[0]); + EXPECT_EQ((unsigned char)0xF9, (unsigned char)buf[1]); + + // Verify different AAC object type, sample rate, and channels + unsigned char expected_byte2 = (unsigned char)(((SrsAacObjectTypeAacHE - 1) << 6) | ((3 & 0x0F) << 2) | ((1 & 0x04) >> 2)); + EXPECT_EQ(expected_byte2, (unsigned char)buf[2]); +} + +VOID TEST(AppTest2, AacRawAppendAdtsHeaderLargeSample) +{ + srs_error_t err; + + // Create a mock AAC packet + SrsUniquePtr audio_packet(new SrsMediaPacket()); + audio_packet->message_type_ = SrsFrameTypeAudio; + + // Create format with AAC + SrsUniquePtr format(new SrsFormat()); + HELPER_EXPECT_SUCCESS(format->initialize()); + + // Set up AAC codec info + format->acodec_ = new SrsAudioCodecConfig(); + format->acodec_->id_ = SrsAudioCodecIdAAC; + format->acodec_->aac_object_ = SrsAacObjectTypeAacLC; + format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index + format->acodec_->aac_channels_ = 2; + + // Create audio frame info with single large sample + format->audio_ = new SrsParsedAudioPacket(); + format->audio_->dts_ = 1000; + format->audio_->cts_ = 0; + format->audio_->nb_samples_ = 1; + + // Create large sample data (1KB) + const int large_size = 1024; + SrsUniquePtr large_sample(new char[large_size]); + for (int i = 0; i < large_size; i++) { + large_sample.get()[i] = (char)(i % 256); + } + + format->audio_->samples_[0].bytes_ = large_sample.get(); + format->audio_->samples_[0].size_ = large_size; + + char *buf = NULL; + int nn_buf = 0; + + // Test: large sample should work correctly + HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf)); + + // Verify buffer was created with correct size + EXPECT_TRUE(buf != NULL); + EXPECT_EQ(7 + large_size, nn_buf); + + if (!buf) { + return; + } + SrsUniquePtr buf_ptr(buf); + + // Verify ADTS header + EXPECT_EQ((unsigned char)0xFF, (unsigned char)buf[0]); + EXPECT_EQ((unsigned char)0xF9, (unsigned char)buf[1]); + + // Verify frame length encoding for large frame + int expected_frame_len = 7 + large_size; + unsigned char byte4 = (expected_frame_len >> 3) & 0xFF; + EXPECT_EQ(byte4, (unsigned char)buf[4]); + + // Verify sample data is copied correctly (check first and last bytes) + EXPECT_EQ(large_sample.get()[0], buf[7]); + EXPECT_EQ(large_sample.get()[large_size - 1], buf[7 + large_size - 1]); +} + +VOID TEST(AppTest2, RtcConsumerUpdateSourceId) +{ + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + // Initially should_update_source_id_ should be false + consumer.update_source_id(); + + // After calling update_source_id, the flag should be set + // We can verify this by calling dump_packet which checks and resets the flag + SrsRtpPacket *pkt = NULL; + srs_error_t err; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt)); + EXPECT_TRUE(pkt == NULL); // No packets in queue +} + +VOID TEST(AppTest2, RtcConsumerEnqueueAndDumpSinglePacket) +{ + srs_error_t err; + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + // Create a test RTP packet + SrsRtpPacket *test_pkt = new SrsRtpPacket(); + test_pkt->header_.set_sequence(1234); + test_pkt->header_.set_timestamp(5678); + test_pkt->header_.set_ssrc(0x12345678); + + // Enqueue the packet (consumer takes ownership) + HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt)); + + // Dump the packet + SrsRtpPacket *dumped_pkt = NULL; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&dumped_pkt)); + + EXPECT_TRUE(dumped_pkt != NULL); + EXPECT_EQ(1234, dumped_pkt->header_.get_sequence()); + EXPECT_EQ(5678, dumped_pkt->header_.get_timestamp()); + EXPECT_EQ(0x12345678, dumped_pkt->header_.get_ssrc()); + + srs_freep(dumped_pkt); +} + +VOID TEST(AppTest2, RtcConsumerEnqueueMultiplePackets) +{ + srs_error_t err; + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + // Create and enqueue multiple test packets + for (int i = 0; i < 5; i++) { + SrsRtpPacket *test_pkt = new SrsRtpPacket(); + test_pkt->header_.set_sequence(1000 + i); + test_pkt->header_.set_timestamp(2000 + i * 100); + test_pkt->header_.set_ssrc(0x12345678); + + HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt)); + } + + // Dump packets in FIFO order + for (int i = 0; i < 5; i++) { + SrsRtpPacket *dumped_pkt = NULL; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&dumped_pkt)); + + EXPECT_TRUE(dumped_pkt != NULL); + EXPECT_EQ(1000 + i, dumped_pkt->header_.get_sequence()); + EXPECT_EQ(2000 + i * 100, dumped_pkt->header_.get_timestamp()); + + srs_freep(dumped_pkt); + } + + // Queue should be empty now + SrsRtpPacket *empty_pkt = NULL; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&empty_pkt)); + EXPECT_TRUE(empty_pkt == NULL); +} + +VOID TEST(AppTest2, RtcConsumerDumpEmptyQueue) +{ + srs_error_t err; + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + // Dump from empty queue should return NULL + SrsRtpPacket *pkt = NULL; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt)); + EXPECT_TRUE(pkt == NULL); +} + +VOID TEST(AppTest2, RtcConsumerStreamChangeCallback) +{ + MockRtcSourceForConsumer mock_source; + MockRtcSourceChangeCallback mock_callback; + SrsRtcConsumer consumer(&mock_source); + + // Set the callback handler + consumer.set_handler(&mock_callback); + + // Create a mock stream description + SrsUniquePtr stream_desc(new SrsRtcSourceDescription()); + stream_desc->id_ = "test-stream"; + + // Trigger stream change + consumer.on_stream_change(stream_desc.get()); + + // Verify callback was called + EXPECT_EQ(1, mock_callback.stream_change_count_); + EXPECT_EQ(stream_desc.get(), mock_callback.last_stream_desc_); +} + +VOID TEST(AppTest2, RtcConsumerStreamChangeCallbackNoHandler) +{ + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + // No handler set - should not crash + SrsUniquePtr stream_desc(new SrsRtcSourceDescription()); + stream_desc->id_ = "test-stream"; + + // This should not crash even without handler + consumer.on_stream_change(stream_desc.get()); +} + +VOID TEST(AppTest2, RtcConsumerQueueSizeCheck) +{ + srs_error_t err; + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + // Enqueue packets and verify queue behavior + for (int i = 0; i < 5; i++) { + SrsRtpPacket *test_pkt = new SrsRtpPacket(); + test_pkt->header_.set_sequence(1000 + i); + HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt)); + } + + // Verify we can dump packets in correct order + SrsRtpPacket *pkt = NULL; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt)); + EXPECT_TRUE(pkt != NULL); + EXPECT_EQ(1000, pkt->header_.get_sequence()); + srs_freep(pkt); +} + +VOID TEST(AppTest2, RtcConsumerEnqueueBehavior) +{ + srs_error_t err; + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + // Enqueue multiple packets to test queue behavior + SrsRtpPacket *test_pkt1 = new SrsRtpPacket(); + test_pkt1->header_.set_sequence(1001); + HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt1)); + + SrsRtpPacket *test_pkt2 = new SrsRtpPacket(); + test_pkt2->header_.set_sequence(1002); + HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt2)); + + SrsRtpPacket *test_pkt3 = new SrsRtpPacket(); + test_pkt3->header_.set_sequence(1003); + HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt3)); + + // Verify packets are in queue in FIFO order + SrsRtpPacket *pkt = NULL; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt)); + EXPECT_TRUE(pkt != NULL); + EXPECT_EQ(1001, pkt->header_.get_sequence()); + srs_freep(pkt); + + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt)); + EXPECT_TRUE(pkt != NULL); + EXPECT_EQ(1002, pkt->header_.get_sequence()); + srs_freep(pkt); +} + +VOID TEST(AppTest2, RtcConsumerSourceIdUpdate) +{ + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + // Set different source IDs + mock_source.source_id_.set_value("new-source-id"); + mock_source.pre_source_id_.set_value("old-source-id"); + + // Trigger source ID update + consumer.update_source_id(); + + // Dump packet should log the source ID change + SrsRtpPacket *pkt = NULL; + srs_error_t err; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt)); + EXPECT_TRUE(pkt == NULL); // No packets in queue + + // After dump_packet, the update flag should be reset + // Calling dump_packet again should not trigger another log + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt)); + EXPECT_TRUE(pkt == NULL); +} + +VOID TEST(AppTest2, RtcConsumerPacketMemoryManagement) +{ + srs_error_t err; + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + // Create test packets and enqueue copies (simulating real usage) + std::vector original_packets; + for (int i = 0; i < 3; i++) { + SrsRtpPacket *original_pkt = new SrsRtpPacket(); + original_pkt->header_.set_sequence(2000 + i); + original_pkt->header_.set_timestamp(3000 + i * 100); + original_packets.push_back(original_pkt); + + // Enqueue a copy (this is how it's used in real code) + HELPER_EXPECT_SUCCESS(consumer.enqueue(original_pkt->copy())); + } + + // Dump all packets and verify they have correct data + for (int i = 0; i < 3; i++) { + SrsRtpPacket *dumped_pkt = NULL; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&dumped_pkt)); + + EXPECT_TRUE(dumped_pkt != NULL); + EXPECT_TRUE(dumped_pkt != original_packets[i]); // Should be different instances + EXPECT_EQ(2000 + i, dumped_pkt->header_.get_sequence()); + EXPECT_EQ(3000 + i * 100, dumped_pkt->header_.get_timestamp()); + + srs_freep(dumped_pkt); + } + + // Clean up original packets + for (size_t i = 0; i < original_packets.size(); i++) { + srs_freep(original_packets[i]); + } +} + +VOID TEST(AppTest2, RtcConsumerCallbackHandlerLifecycle) +{ + MockRtcSourceForConsumer mock_source; + MockRtcSourceChangeCallback callback1; + MockRtcSourceChangeCallback callback2; + SrsRtcConsumer consumer(&mock_source); + + // Initially no handler + SrsUniquePtr stream_desc(new SrsRtcSourceDescription()); + stream_desc->id_ = "test-stream-1"; + consumer.on_stream_change(stream_desc.get()); + EXPECT_EQ(0, callback1.stream_change_count_); + EXPECT_EQ(0, callback2.stream_change_count_); + + // Set first handler + consumer.set_handler(&callback1); + consumer.on_stream_change(stream_desc.get()); + EXPECT_EQ(1, callback1.stream_change_count_); + EXPECT_EQ(0, callback2.stream_change_count_); + + // Change handler + consumer.set_handler(&callback2); + stream_desc->id_ = "test-stream-2"; + consumer.on_stream_change(stream_desc.get()); + EXPECT_EQ(1, callback1.stream_change_count_); // Should not increase + EXPECT_EQ(1, callback2.stream_change_count_); // Should increase + + // Remove handler + consumer.set_handler(NULL); + consumer.on_stream_change(stream_desc.get()); + EXPECT_EQ(1, callback1.stream_change_count_); // Should not increase + EXPECT_EQ(1, callback2.stream_change_count_); // Should not increase +} + +VOID TEST(AppTest2, RtcConsumerLargePacketQueue) +{ + srs_error_t err; + MockRtcSourceForConsumer mock_source; + SrsRtcConsumer consumer(&mock_source); + + const int large_count = 100; + + // Enqueue many packets + for (int i = 0; i < large_count; i++) { + SrsRtpPacket *test_pkt = new SrsRtpPacket(); + test_pkt->header_.set_sequence(4000 + i); + test_pkt->header_.set_timestamp(5000 + i * 10); + test_pkt->header_.set_ssrc(0xABCDEF00 + i); + + HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt)); + } + + // Dump all packets and verify order + for (int i = 0; i < large_count; i++) { + SrsRtpPacket *dumped_pkt = NULL; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&dumped_pkt)); + + EXPECT_TRUE(dumped_pkt != NULL); + EXPECT_EQ(4000 + i, dumped_pkt->header_.get_sequence()); + EXPECT_EQ(5000 + i * 10, dumped_pkt->header_.get_timestamp()); + EXPECT_EQ(0xABCDEF00 + i, dumped_pkt->header_.get_ssrc()); + + srs_freep(dumped_pkt); + } + + // Queue should be empty + SrsRtpPacket *empty_pkt = NULL; + HELPER_EXPECT_SUCCESS(consumer.dump_packet(&empty_pkt)); + EXPECT_TRUE(empty_pkt == NULL); +} diff --git a/trunk/src/utest/srs_utest_app2.hpp b/trunk/src/utest/srs_utest_app2.hpp new file mode 100644 index 000000000..f5fced030 --- /dev/null +++ b/trunk/src/utest/srs_utest_app2.hpp @@ -0,0 +1,15 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// + +#ifndef SRS_UTEST_APP2_HPP +#define SRS_UTEST_APP2_HPP + +/* +#include +*/ +#include + +#endif diff --git a/trunk/src/utest/srs_utest_config.cpp b/trunk/src/utest/srs_utest_config.cpp index e06fe931d..d85444c20 100644 --- a/trunk/src/utest/srs_utest_config.cpp +++ b/trunk/src/utest/srs_utest_config.cpp @@ -51,7 +51,7 @@ MockSrsConfig::~MockSrsConfig() { } -srs_error_t MockSrsConfig::parse(string buf) +srs_error_t MockSrsConfig::mock_parse(string buf) { srs_error_t err = srs_success; @@ -980,7 +980,7 @@ VOID TEST(ConfigMainTest, ParseEmpty) srs_error_t err; MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse("")); + HELPER_ASSERT_FAILED(conf.mock_parse("")); } VOID TEST(ConfigMainTest, ParseMinConf) @@ -988,7 +988,7 @@ VOID TEST(ConfigMainTest, ParseMinConf) srs_error_t err; MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); vector listens = conf.get_listens(); EXPECT_EQ(1, (int)listens.size()); @@ -1000,7 +1000,7 @@ VOID TEST(ConfigMainTest, ParseInvalidDirective) srs_error_t err; MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse("listens 1935;")); + HELPER_ASSERT_FAILED(conf.mock_parse("listens 1935;")); } VOID TEST(ConfigMainTest, ParseInvalidDirective2) @@ -1009,7 +1009,7 @@ VOID TEST(ConfigMainTest, ParseInvalidDirective2) MockSrsConfig conf; // check error for user not specified the listen directive. - HELPER_ASSERT_FAILED(conf.parse("chunk_size 4096;")); + HELPER_ASSERT_FAILED(conf.mock_parse("chunk_size 4096;")); } VOID TEST(ConfigMainTest, CheckConf_listen) @@ -1018,27 +1018,27 @@ VOID TEST(ConfigMainTest, CheckConf_listen) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse("listens 1935;")); + HELPER_ASSERT_FAILED(conf.mock_parse("listens 1935;")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse("listen 0;")); + HELPER_ASSERT_FAILED(conf.mock_parse("listen 0;")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse("listen -1;")); + HELPER_ASSERT_FAILED(conf.mock_parse("listen -1;")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse("listen -1935;")); + HELPER_ASSERT_FAILED(conf.mock_parse("listen -1935;")); } } @@ -1048,7 +1048,7 @@ VOID TEST(ConfigMainTest, CheckConf_pid) if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "pids ./objs/srs.pid;")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "pids ./objs/srs.pid;")); } } @@ -1058,42 +1058,42 @@ VOID TEST(ConfigMainTest, CheckConf_chunk_size) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1935; chunk_size 60000;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 60000;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse("rtmp{listen 1935; chunk_sizes 60000;}")); + HELPER_ASSERT_FAILED(conf.mock_parse("rtmp{listen 1935; chunk_sizes 60000;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1935; chunk_size 0;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 0;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1935; chunk_size 1;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 1;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1935; chunk_size 127;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 127;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1935; chunk_size -1;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size -1;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1935; chunk_size -4096;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size -4096;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1935; chunk_size 65537;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 65537;}")); } } @@ -1103,17 +1103,17 @@ VOID TEST(ConfigMainTest, CheckConf_ff_log_dir) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "ff_log_dir ./objs;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_dir ./objs;")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "ff_log_dirs ./objs;")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "ff_log_dirs ./objs;")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "ff_log_levels info;")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "ff_log_levels info;")); } } @@ -1123,12 +1123,12 @@ VOID TEST(ConfigMainTest, CheckConf_srs_log_level) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "srs_log_level trace;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srs_log_level trace;")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "srs_log_levels trace;")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "srs_log_levels trace;")); } } @@ -1138,12 +1138,12 @@ VOID TEST(ConfigMainTest, CheckConf_srs_log_file) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "srs_log_file ./objs/srs.log;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srs_log_file ./objs/srs.log;")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "srs_log_files ./objs/srs.log;")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "srs_log_files ./objs/srs.log;")); } } @@ -1153,12 +1153,12 @@ VOID TEST(ConfigMainTest, CheckConf_daemon) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "daemon on;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "daemon on;")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "daemons on;")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "daemons on;")); } } @@ -1168,62 +1168,62 @@ VOID TEST(ConfigMainTest, CheckConf_heartbeat) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "heartbeat{}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "heartbeats{}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "heartbeats{}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "heartbeat{enabled on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{enabled on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "heartbeat{enableds on;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "heartbeat{enableds on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "heartbeat{interval 9;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{interval 9;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "heartbeat{intervals 9;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "heartbeat{intervals 9;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "heartbeat{url http://127.0.0.1:8085/api/v1/servers;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{url http://127.0.0.1:8085/api/v1/servers;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "heartbeat{urls http://127.0.0.1:8085/api/v1/servers;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "heartbeat{urls http://127.0.0.1:8085/api/v1/servers;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "heartbeat{device_id 0;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{device_id 0;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "heartbeat{device_ids 0;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "heartbeat{device_ids 0;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "heartbeat{summaries on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{summaries on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "heartbeat{summariess on;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "heartbeat{summariess on;}")); } } @@ -1233,22 +1233,22 @@ VOID TEST(ConfigMainTest, CheckConf_http_api) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "http_apis{}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "http_apis{}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "http_api{enableds on;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "http_api{enableds on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "http_api{listens 1985;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "http_api{listens 1985;}")); } } @@ -1258,42 +1258,42 @@ VOID TEST(ConfigMainTest, CheckConf_stats) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stats{}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "statss{}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "statss{}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stats{network 0;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{network 0;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "stats{networks 0;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "stats{networks 0;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "stats{network -100;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "stats{network -100;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "stats{network -1;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "stats{network -1;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stats{disk sda;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{disk sda;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "stats{disks sda;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "stats{disks sda;}")); } } @@ -1303,27 +1303,27 @@ VOID TEST(ConfigMainTest, CheckConf_http_stream) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_stream{}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_stream{}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "http_streams{}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "http_streams{}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "http_stream{enableds on;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "http_stream{enableds on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "http_stream{listens 8080;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "http_stream{listens 8080;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "http_stream{dirs ./objs/nginx/html;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "http_stream{dirs ./objs/nginx/html;}")); } } @@ -1333,12 +1333,12 @@ VOID TEST(ConfigMainTest, CheckConf_vhost) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhosts{}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhosts{}")); } } @@ -1348,32 +1348,32 @@ VOID TEST(ConfigMainTest, CheckConf_vhost_edge) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{mode remote;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{mode remote;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{modes remote;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{modes remote;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{origin 127.0.0.1:1935 localhost:1935;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{origin 127.0.0.1:1935 localhost:1935;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{origins 127.0.0.1:1935 localhost:1935;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{origins 127.0.0.1:1935 localhost:1935;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{token_traverse off;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{token_traverse off;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{token_traverses off;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{token_traverses off;}")); } } @@ -1383,72 +1383,72 @@ VOID TEST(ConfigMainTest, CheckConf_vhost_dvr) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{dvr{}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{dvrs{}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{dvrs{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{dvr{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{enabled on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{dvr{enableds on;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{enableds on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{dvr{dvr_path ./objs/nginx/html;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{dvr_path ./objs/nginx/html;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{dvr{dvr_paths ./objs/nginx/html;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{dvr_paths ./objs/nginx/html;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{dvr{dvr_plan session;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{dvr_plan session;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{dvr{dvr_plans session;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{dvr_plans session;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{dvr{dvr_duration 30;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{dvr_duration 30;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{dvr{dvr_durations 30;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{dvr_durations 30;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{dvr{dvr_wait_keyframe on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{dvr_wait_keyframe on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{dvr{dvr_wait_keyframes on;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{dvr_wait_keyframes on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{dvr{time_jitter full;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{time_jitter full;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{dvr{time_jitters full;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{time_jitters full;}}")); } } @@ -1458,52 +1458,52 @@ VOID TEST(ConfigMainTest, CheckConf_vhost_ingest) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{ingest{}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{ingests{}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{ingests{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{ingest{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{enabled on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{ingest{enableds on;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{enableds on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{ingest{input{}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{input{}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{ingest{inputs{}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{inputs{}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{ingest{ffmpeg ./objs/ffmpeg/bin/ffmpeg;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{ffmpeg ./objs/ffmpeg/bin/ffmpeg;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{ingest{ffmpegs ./objs/ffmpeg/bin/ffmpeg;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{ffmpegs ./objs/ffmpeg/bin/ffmpeg;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{ingest{engine{}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{engine{}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{ingest{engines{}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{engines{}}}")); } } @@ -1513,42 +1513,42 @@ VOID TEST(ConfigMainTest, CheckConf_vhost_http) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http{}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{https{}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{https{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http{enabled on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http{enableds on;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http{enableds on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http{mount /hls;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http{mount /hls;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http{mounts /hls;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http{mounts /hls;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http{dir ./objs/nginx/html/hls;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http{dir ./objs/nginx/html/hls;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http{dirs ./objs/nginx/html/hls;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http{dirs ./objs/nginx/html/hls;}}")); } } @@ -1558,57 +1558,57 @@ VOID TEST(ConfigMainTest, CheckConf_vhost_hls) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{hls{}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{hlss{}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{hlss{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{hls{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{enabled on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{hls{enableds on;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{enableds on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{hls{hls_path ./objs/nginx/html;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{hls_path ./objs/nginx/html;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{hls{hls_paths ./objs/nginx/html;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{hls_paths ./objs/nginx/html;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{hls{hls_fragment 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{hls_fragment 10;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{hls{hls_fragments 10;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{hls_fragments 10;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{hls{hls_window 60;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{hls_window 60;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{hls{hls_windows 60;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{hls_windows 60;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{hls{hls_ctx on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{hls_ctx on;}}")); } } @@ -1618,82 +1618,82 @@ VOID TEST(ConfigMainTest, CheckConf_hooks) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http_hookss{}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hookss{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{enabled on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{enableds on;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{enableds on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_connect http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_connect http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_connects http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_connects http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_close http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_close http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_closes http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_closes http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_publish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_publish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_publishs http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_publishs http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_unpublish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_unpublish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_unpublishs http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_unpublishs http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_play http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_play http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_plays http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_plays http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{http_hooks{on_stops http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{http_hooks{on_stops http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;}}")); } } @@ -1703,22 +1703,22 @@ VOID TEST(ConfigMainTest, CheckConf_gop_cache) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{gop_cache off;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{gop_cache off;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{gop_caches off;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{gop_caches off;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{queue_length 10;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{queue_length 10;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{queue_lengths 10;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{queue_lengths 10;}")); } } @@ -1728,12 +1728,12 @@ VOID TEST(ConfigMainTest, CheckConf_debug_srs_upnode) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{debug_srs_upnode off;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{debug_srs_upnode off;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{debug_srs_upnodes off;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{debug_srs_upnodes off;}")); } } @@ -1743,32 +1743,32 @@ VOID TEST(ConfigMainTest, CheckConf_refer) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{refer github.com github.io;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{refer github.com github.io;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{refers github.com github.io;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{refers github.com github.io;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{refer_publish github.com github.io;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{refer_publish github.com github.io;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{refer_publishs github.com github.io;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{refer_publishs github.com github.io;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{refer_play github.com github.io;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{refer_play github.com github.io;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{refer_plays github.com github.io;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{refer_plays github.com github.io;}")); } } @@ -1778,12 +1778,12 @@ VOID TEST(ConfigMainTest, CheckConf_forward) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{forward 127.0.0.1:1936;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{forward 127.0.0.1:1936;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{forwards 127.0.0.1:1936;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{forwards 127.0.0.1:1936;}")); } } @@ -1793,212 +1793,212 @@ VOID TEST(ConfigMainTest, CheckConf_transcode) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcodes{}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcodes{}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{enabled on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{enableds on;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{enableds on;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{ffmpeg ./objs/ffmpeg/bin/ffmpeg;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{ffmpeg ./objs/ffmpeg/bin/ffmpeg;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{ffmpegs ./objs/ffmpeg/bin/ffmpeg;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{ffmpegs ./objs/ffmpeg/bin/ffmpeg;}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engines {}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engines {}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {enabled on;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {enabled on;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {enableds on;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {enableds on;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vfilter {}}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vfilter {}}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vfilters {}}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vfilters {}}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vcodec libx264;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vcodec libx264;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vcodecs libx264;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vcodecs libx264;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vbitrate 300;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vbitrate 300;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vbitrates 300;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vbitrates 300;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vfps 20;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vfps 20;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vfpss 20;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vfpss 20;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vwidth 768;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vwidth 768;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vwidths 768;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vwidths 768;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vheight 320;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vheight 320;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vheights 320;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vheights 320;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vthreads 2;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vthreads 2;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vthreadss 2;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vthreadss 2;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vprofile baseline;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vprofile baseline;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vprofiles baseline;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vprofiles baseline;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vpreset superfast;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vpreset superfast;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vpresets superfast;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vpresets superfast;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vparams {}}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vparams {}}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {vparamss {}}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {vparamss {}}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {acodec libfdk_aac;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {acodec libfdk_aac;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {acodecs libfdk_aac;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {acodecs libfdk_aac;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {abitrate 45;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {abitrate 45;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {abitrates 45;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {abitrates 45;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {asample_rate 44100;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {asample_rate 44100;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {asample_rates 44100;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {asample_rates 44100;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {achannels 2;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {achannels 2;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {achannelss 2;}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {achannelss 2;}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {aparams {}}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {aparams {}}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {aparamss {}}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {aparamss {}}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];}}}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{transcode{engine {outputs rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];}}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{transcode{engine {outputs rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];}}}")); } } @@ -2008,37 +2008,37 @@ VOID TEST(ConfigMainTest, CheckConf_chunk_size2) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{chunk_size 128;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{chunk_size 128;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{chunk_sizes 128;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{chunk_sizes 128;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{chunk_size 127;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{chunk_size 127;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{chunk_size 0;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{chunk_size 0;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{chunk_size -1;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{chunk_size -1;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{chunk_size -128;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{chunk_size -128;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{chunk_size 65537;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{chunk_size 65537;}")); } } @@ -2049,7 +2049,7 @@ VOID TEST(ConfigMainTest, TransformRtmpConfig) // Test backward compatibility: global listen should be transformed to rtmp.listen if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("listen 1935;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("listen 1935;")); // After parsing and transformation, should be able to get listen from rtmp section vector listens = conf.get_listens(); @@ -2071,7 +2071,7 @@ VOID TEST(ConfigMainTest, TransformRtmpConfig) // Test backward compatibility: global chunk_size should be transformed to rtmp.chunk_size if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("listen 1935; chunk_size 60000;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("listen 1935; chunk_size 60000;")); // After parsing and transformation, should be able to get chunk_size from rtmp section EXPECT_EQ(60000, conf.get_global_chunk_size()); @@ -2091,7 +2091,7 @@ VOID TEST(ConfigMainTest, TransformRtmpConfig) // Test backward compatibility: multiple global RTMP configs if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("listen 1935 1936; chunk_size 128;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("listen 1935 1936; chunk_size 128;")); // Verify listen ports vector listens = conf.get_listens(); @@ -2106,7 +2106,7 @@ VOID TEST(ConfigMainTest, TransformRtmpConfig) // Test that new rtmp section format still works if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1937; chunk_size 256;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1937; chunk_size 256;}")); vector listens = conf.get_listens(); EXPECT_EQ(1, (int)listens.size()); @@ -2117,7 +2117,7 @@ VOID TEST(ConfigMainTest, TransformRtmpConfig) // Test mixed format: existing rtmp section + global configs (global should be merged) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1938;} chunk_size 512;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1938;} chunk_size 512;")); vector listens = conf.get_listens(); EXPECT_EQ(1, (int)listens.size()); @@ -2140,12 +2140,12 @@ VOID TEST(ConfigMainTest, CheckConf_jitter) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{time_jitter full;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{time_jitter full;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{time_jitters full;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{time_jitters full;}")); } } @@ -2155,32 +2155,32 @@ VOID TEST(ConfigMainTest, CheckConf_atc) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{atc on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{atc on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{atcs on;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{atcs on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{atc_auto on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{atc_auto on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{atc_autos on;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{atc_autos on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{enabled on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{enabled on;}")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{enableds on;}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{enableds on;}")); } } @@ -2190,12 +2190,12 @@ VOID TEST(ConfigMainTest, CheckConf_pithy_print) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "pithy_print_ms 1000;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "pithy_print_ms 1000;")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "pithy_print_mss 1000;")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "pithy_print_mss 1000;")); } } @@ -2204,9 +2204,9 @@ VOID TEST(ConfigMainTest, CheckConf_vhost_ingest_id) srs_error_t err; MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{ingest id{}}")); - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{ingest id{} ingest id{}}")); - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "vhost v{ingest{} ingest{}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest id{}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest id{} ingest id{}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "vhost v{ingest{} ingest{}}")); } VOID TEST(ConfigUnitTest, CheckDefaultValuesVhost) @@ -2216,91 +2216,91 @@ VOID TEST(ConfigUnitTest, CheckDefaultValuesVhost) MockSrsConfig conf; if (true) { - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dash_fragment("")); EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_dash_update_period("")); EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("")); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{dash{dash_fragment 4;dash_update_period 40;dash_timeshift 70;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{dash{dash_fragment 4;dash_update_period 40;dash_timeshift 70;}}")); EXPECT_EQ(4 * SRS_UTIME_SECONDS, conf.get_dash_fragment("v")); EXPECT_EQ(40 * SRS_UTIME_SECONDS, conf.get_dash_update_period("v")); EXPECT_EQ(70 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("v")); } if (true) { - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(srs_utime_t(10 * SRS_UTIME_SECONDS), conf.get_heartbeat_interval()); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "heartbeat{interval 10;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{interval 10;}")); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_heartbeat_interval()); } if (true) { - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_pithy_print()); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "pithy_print_ms 20000;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "pithy_print_ms 20000;")); EXPECT_EQ(20 * SRS_UTIME_SECONDS, conf.get_pithy_print()); } if (true) { - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(350 * SRS_UTIME_MILLISECONDS, conf.get_mr_sleep("")); EXPECT_EQ(350 * SRS_UTIME_MILLISECONDS, conf.get_mw_sleep("")); EXPECT_EQ(20 * SRS_UTIME_SECONDS, conf.get_publish_1stpkt_timeout("")); EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_publish_normal_timeout("")); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{publish{mr_latency 1000; firstpkt_timeout 100; normal_timeout 100;} play{mw_latency 1000;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{publish{mr_latency 1000; firstpkt_timeout 100; normal_timeout 100;} play{mw_latency 1000;}}")); EXPECT_EQ(1000 * SRS_UTIME_MILLISECONDS, conf.get_mr_sleep("v")); EXPECT_EQ(100 * SRS_UTIME_MILLISECONDS, conf.get_publish_1stpkt_timeout("v")); EXPECT_EQ(100 * SRS_UTIME_MILLISECONDS, conf.get_publish_normal_timeout("v")); } if (true) { - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_dvr_duration("")); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{dvr{dvr_duration 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{dvr{dvr_duration 10;}}")); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dvr_duration("v")); } if (true) { - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(120 * SRS_UTIME_SECONDS, (int)conf.get_hls_dispose("")); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hls_fragment("")); EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hls_window("")); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{hls{hls_dispose 10;hls_fragment 20;hls_window 30;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{hls{hls_dispose 10;hls_fragment 20;hls_window 30;}}")); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hls_dispose("v")); EXPECT_EQ(20 * SRS_UTIME_SECONDS, conf.get_hls_fragment("v")); EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_hls_window("v")); } if (true) { - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hds_fragment("")); EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hds_window("")); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{hds{hds_fragment 20;hds_window 30;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{hds{hds_fragment 20;hds_window 30;}}")); EXPECT_EQ(20 * SRS_UTIME_SECONDS, conf.get_hds_fragment("v")); EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_hds_window("v")); } if (true) { - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_queue_length("")); EXPECT_EQ(0, (int)conf.get_send_min_interval("")); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{play{queue_length 100;send_min_interval 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{play{queue_length 100;send_min_interval 10;}}")); EXPECT_EQ(100 * SRS_UTIME_SECONDS, conf.get_queue_length("v")); EXPECT_EQ(10 * SRS_UTIME_MILLISECONDS, conf.get_send_min_interval("v")); } if (true) { - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(0, (int)conf.get_vhost_http_remux_fast_cache("")); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost v{http_remux{fast_cache 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost v{http_remux{fast_cache 10;}}")); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_vhost_http_remux_fast_cache("v")); } } @@ -2433,6 +2433,7 @@ VOID TEST(ConfigUnitTest, DirectiveEquals) a->at(0)->name_ = "hls"; SrsConfDirective *b = new SrsConfDirective(); b->directives_.push_back(new SrsConfDirective()); + b->at(0)->name_ = "hls"; EXPECT_TRUE(srs_directive_equals(a, b, "hls")); srs_freep(a); srs_freep(b); @@ -2917,128 +2918,128 @@ VOID TEST(ConfigMainTest, CheckGlobalConfig) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_TRUE(conf.cwd().empty()); EXPECT_TRUE(conf.argv().empty()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_TRUE(conf.get_daemon()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "daemon on;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "daemon on;")); EXPECT_TRUE(conf.get_daemon()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "daemon off;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "daemon off;")); EXPECT_FALSE(conf.get_daemon()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_TRUE(conf.get_root() != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(1000, conf.get_max_connections()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "max_connections 1024;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "max_connections 1024;")); EXPECT_EQ(1024, conf.get_max_connections()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1935;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935;}")); EXPECT_EQ(1, (int)conf.get_listens().size()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse("rtmp{listen 1935 1936;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935 1936;}")); EXPECT_EQ(2, (int)conf.get_listens().size()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_STREQ("./objs/srs.pid", conf.get_pid_file().c_str()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "pid server.pid;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "pid server.pid;")); EXPECT_STREQ("server.pid", conf.get_pid_file().c_str()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_pithy_print()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_FALSE(conf.get_utc_time()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "utc_time on;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "utc_time on;")); EXPECT_TRUE(conf.get_utc_time()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "utc_time off;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "utc_time off;")); EXPECT_FALSE(conf.get_utc_time()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_STREQ("./", conf.get_work_dir().c_str()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "work_dir objs;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "work_dir objs;")); EXPECT_STREQ("objs", conf.get_work_dir().c_str()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_FALSE(conf.get_asprocess()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "asprocess off;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "asprocess off;")); EXPECT_FALSE(conf.get_asprocess()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "daemon off; asprocess on;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "daemon off; asprocess on;")); EXPECT_TRUE(conf.get_asprocess()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "daemon on; asprocess on;")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "daemon on; asprocess on;")); } } @@ -3048,25 +3049,25 @@ VOID TEST(ConfigMainTest, CheckStreamConverter) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(0, (int)conf.get_stream_casters().size()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stream_caster;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster;")); EXPECT_EQ(1, (int)conf.get_stream_casters().size()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stream_caster; stream_caster;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster; stream_caster;")); EXPECT_EQ(2, (int)conf.get_stream_casters().size()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stream_caster;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster;")); vector arr = conf.get_stream_casters(); ASSERT_EQ(1, (int)arr.size()); @@ -3076,7 +3077,7 @@ VOID TEST(ConfigMainTest, CheckStreamConverter) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stream_caster {enabled off;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster {enabled off;}")); vector arr = conf.get_stream_casters(); ASSERT_EQ(1, (int)arr.size()); @@ -3086,7 +3087,7 @@ VOID TEST(ConfigMainTest, CheckStreamConverter) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stream_caster {enabled on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster {enabled on;}")); vector arr = conf.get_stream_casters(); ASSERT_EQ(1, (int)arr.size()); @@ -3096,7 +3097,7 @@ VOID TEST(ConfigMainTest, CheckStreamConverter) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stream_caster;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster;")); vector arr = conf.get_stream_casters(); ASSERT_EQ(1, (int)arr.size()); @@ -3106,7 +3107,7 @@ VOID TEST(ConfigMainTest, CheckStreamConverter) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stream_caster {output xxx;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster {output xxx;}")); vector arr = conf.get_stream_casters(); ASSERT_EQ(1, (int)arr.size()); @@ -3116,7 +3117,7 @@ VOID TEST(ConfigMainTest, CheckStreamConverter) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stream_caster;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster;")); vector arr = conf.get_stream_casters(); ASSERT_EQ(1, (int)arr.size()); @@ -3126,7 +3127,7 @@ VOID TEST(ConfigMainTest, CheckStreamConverter) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stream_caster {listen 8080;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster {listen 8080;}")); vector arr = conf.get_stream_casters(); ASSERT_EQ(1, (int)arr.size()); @@ -3141,13 +3142,13 @@ VOID TEST(ConfigMainTest, CheckVhostConfig2) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_FALSE(conf.get_vhost_enabled("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net;")); EXPECT_TRUE(conf.get_vhost_enabled("ossrs.net")); EXPECT_TRUE(conf.get_gop_cache("ossrs.net")); EXPECT_TRUE(conf.get_debug_srs_upnode("ossrs.net")); @@ -3181,181 +3182,181 @@ VOID TEST(ConfigMainTest, CheckVhostConfig2) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{forward {backend xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{forward {backend xxx;}}")); EXPECT_TRUE(conf.get_forward_backend("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{forward {destination xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{forward {destination xxx;}}")); EXPECT_TRUE(conf.get_forwards("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{forward {enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{forward {enabled on;}}")); EXPECT_TRUE(conf.get_forward_enabled("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{publish {normal_timeout 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{publish {normal_timeout 10;}}")); EXPECT_EQ(10000, conf.get_publish_normal_timeout("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{publish {firstpkt_timeout 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{publish {firstpkt_timeout 10;}}")); EXPECT_EQ(10000, conf.get_publish_1stpkt_timeout("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play {reduce_sequence_header on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play {reduce_sequence_header on;}}")); EXPECT_TRUE(conf.get_reduce_sequence_header("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play {send_min_interval 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play {send_min_interval 10;}}")); EXPECT_EQ(10000, conf.get_send_min_interval("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{tcp_nodelay on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{tcp_nodelay on;}")); EXPECT_TRUE(conf.get_tcp_nodelay("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{min_latency on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{min_latency on;}")); EXPECT_TRUE(conf.get_realtime_enabled("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play{mw_latency 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play{mw_latency 10;}}")); EXPECT_EQ(10000, conf.get_mw_sleep("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{publish{mr_latency 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{publish{mr_latency 10;}}")); EXPECT_EQ(10000, conf.get_mr_sleep("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{publish{mr on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{publish{mr on;}}")); EXPECT_TRUE(conf.get_mr_enabled("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{publish{parse_sps off;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{publish{parse_sps off;}}")); EXPECT_FALSE(conf.get_parse_sps("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{publish{try_annexb_first off;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{publish{try_annexb_first off;}}")); EXPECT_FALSE(conf.try_annexb_first("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{chunk_size 10;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{chunk_size 10;}")); EXPECT_EQ(10, conf.get_chunk_size("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{out_ack_size 10;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{out_ack_size 10;}")); EXPECT_EQ(10, conf.get_out_ack_size("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{in_ack_size 10;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{in_ack_size 10;}")); EXPECT_EQ(10, conf.get_in_ack_size("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{refer{publish xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{refer{publish xxx;}}")); EXPECT_TRUE(conf.get_refer_publish("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{refer{play xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{refer{play xxx;}}")); EXPECT_TRUE(conf.get_refer_play("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{refer{all xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{refer{all xxx;}}")); EXPECT_TRUE(conf.get_refer_all("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{refer{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{refer{enabled on;}}")); EXPECT_TRUE(conf.get_refer_enabled("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play{queue_length 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play{queue_length 10;}}")); EXPECT_EQ(10000000, conf.get_queue_length("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play{mix_correct on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play{mix_correct on;}}")); EXPECT_TRUE(conf.get_mix_correct("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play{time_jitter zero;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play{time_jitter zero;}}")); EXPECT_EQ(2, (int)conf.get_time_jitter("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play{atc_auto on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play{atc_auto on;}}")); EXPECT_TRUE(conf.get_gop_cache("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play{atc on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play{atc on;}}")); EXPECT_TRUE(conf.get_gop_cache("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play{gop_cache off;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play{gop_cache off;}}")); EXPECT_FALSE(conf.get_gop_cache("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net {enabled off;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net {enabled off;}")); EXPECT_FALSE(conf.get_vhost_enabled("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net {enabled on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net {enabled on;}")); EXPECT_TRUE(conf.get_vhost_enabled("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{play{gop_cache off;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{play{gop_cache off;}}")); EXPECT_FALSE(conf.get_gop_cache("ossrs.net")); } } @@ -3366,7 +3367,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig3) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net;")); EXPECT_TRUE(conf.get_vhost_http_hooks("ossrs.net") == NULL); EXPECT_FALSE(conf.get_vhost_http_hooks_enabled("ossrs.net")); EXPECT_TRUE(conf.get_vhost_on_connect("ossrs.net") == NULL); @@ -3390,103 +3391,103 @@ VOID TEST(ConfigMainTest, CheckVhostConfig3) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{security{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{security{enabled on;}}")); EXPECT_TRUE(conf.get_security_rules("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{security{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{security{enabled on;}}")); EXPECT_TRUE(conf.get_security_enabled("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{cluster{coworkers xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{cluster{coworkers xxx;}}")); EXPECT_EQ(1, (int)conf.get_vhost_coworkers("ossrs.net").size()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{cluster{origin_cluster on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{cluster{origin_cluster on;}}")); EXPECT_TRUE(conf.get_vhost_origin_cluster("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{cluster{vhost xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{cluster{vhost xxx;}}")); EXPECT_FALSE(conf.get_vhost_edge_transform_vhost("ossrs.net").empty()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{cluster{token_traverse on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{cluster{token_traverse on;}}")); EXPECT_TRUE(conf.get_vhost_edge_token_traverse("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{cluster{origin xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{cluster{origin xxx;}}")); EXPECT_TRUE(conf.get_vhost_edge_origin("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{cluster{mode remote;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{cluster{mode remote;}}")); EXPECT_TRUE(conf.get_vhost_is_edge("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_hls_notify xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_hls_notify xxx;}}")); EXPECT_TRUE(conf.get_vhost_on_hls_notify("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_hls xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_hls xxx;}}")); EXPECT_TRUE(conf.get_vhost_on_hls("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_dvr xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_dvr xxx;}}")); EXPECT_TRUE(conf.get_vhost_on_dvr("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_stop xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_stop xxx;}}")); EXPECT_TRUE(conf.get_vhost_on_stop("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_play xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_play xxx;}}")); EXPECT_TRUE(conf.get_vhost_on_play("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_unpublish xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_unpublish xxx;}}")); EXPECT_TRUE(conf.get_vhost_on_unpublish("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_publish xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_publish xxx;}}")); EXPECT_TRUE(conf.get_vhost_on_publish("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_close xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_close xxx;}}")); EXPECT_TRUE(conf.get_vhost_on_close("ossrs.net") != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_connect xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_connect xxx;}}")); SrsConfDirective *dir = conf.get_vhost_on_connect("ossrs.net"); ASSERT_TRUE(dir != NULL); ASSERT_EQ((int)dir->args_.size(), 1); @@ -3495,7 +3496,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig3) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_connect xxx yyy;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{on_connect xxx yyy;}}")); SrsConfDirective *dir = conf.get_vhost_on_connect("ossrs.net"); ASSERT_TRUE(dir != NULL); ASSERT_EQ((int)dir->args_.size(), 2); @@ -3505,13 +3506,13 @@ VOID TEST(ConfigMainTest, CheckVhostConfig3) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks{enabled on;}}")); EXPECT_TRUE(conf.get_vhost_http_hooks_enabled("ossrs.net")); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_hooks;}")); EXPECT_TRUE(conf.get_vhost_http_hooks("ossrs.net") != NULL); } } @@ -3522,7 +3523,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net;")); EXPECT_TRUE(conf.get_transcode("ossrs.net", "") == NULL); EXPECT_FALSE(conf.get_transcode_enabled(conf.get_transcode("ossrs.net", ""))); EXPECT_TRUE(conf.get_transcode_ffmpeg(conf.get_transcode("ossrs.net", "")).empty()); @@ -3531,7 +3532,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{output xxx;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{output xxx;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_STREQ("xxx", conf.get_engine_output(arr.at(0)).c_str()); @@ -3539,7 +3540,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{oformat flv;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{oformat flv;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_STREQ("flv", conf.get_engine_oformat(arr.at(0)).c_str()); @@ -3547,7 +3548,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{aparams {i;}}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{aparams {i;}}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1, (int)conf.get_engine_aparams(arr.at(0)).size()); @@ -3555,7 +3556,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{achannels 1000;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{achannels 1000;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1000, conf.get_engine_achannels(arr.at(0))); @@ -3563,7 +3564,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{asample_rate 1000;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{asample_rate 1000;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1000, conf.get_engine_asample_rate(arr.at(0))); @@ -3571,7 +3572,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{abitrate 1000;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{abitrate 1000;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1000, conf.get_engine_abitrate(arr.at(0))); @@ -3579,7 +3580,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{acodec aac;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{acodec aac;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_STREQ("aac", conf.get_engine_acodec(arr.at(0)).c_str()); @@ -3587,7 +3588,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vparams {t;}}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vparams {t;}}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1, (int)conf.get_engine_vparams(arr.at(0)).size()); @@ -3595,7 +3596,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vpreset main;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vpreset main;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_STREQ("main", conf.get_engine_vpreset(arr.at(0)).c_str()); @@ -3603,7 +3604,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vprofile main;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vprofile main;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_STREQ("main", conf.get_engine_vprofile(arr.at(0)).c_str()); @@ -3611,7 +3612,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vthreads 1000;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vthreads 1000;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1000, conf.get_engine_vthreads(arr.at(0))); @@ -3619,7 +3620,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vheight 1000;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vheight 1000;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1000, conf.get_engine_vheight(arr.at(0))); @@ -3627,7 +3628,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vwidth 1000;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vwidth 1000;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1000, conf.get_engine_vwidth(arr.at(0))); @@ -3635,7 +3636,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vfps 1000;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vfps 1000;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1000, conf.get_engine_vfps(arr.at(0))); @@ -3643,7 +3644,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vbitrate 1000;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vbitrate 1000;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1000, conf.get_engine_vbitrate(arr.at(0))); @@ -3651,7 +3652,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vcodec x264;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vcodec x264;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_STREQ("x264", conf.get_engine_vcodec(arr.at(0)).c_str()); @@ -3659,7 +3660,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vfilter {i;}}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vfilter {i;}}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1, (int)conf.get_engine_vfilter(arr.at(0)).size()); @@ -3667,7 +3668,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vfilter {i logo.png;}}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{vfilter {i logo.png;}}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(2, (int)conf.get_engine_vfilter(arr.at(0)).size()); @@ -3675,7 +3676,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{iformat mp4;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{iformat mp4;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_STREQ("mp4", conf.get_engine_iformat(arr.at(0)).c_str()); @@ -3683,7 +3684,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{perfile {re;}}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{perfile {re;}}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_EQ(1, (int)conf.get_engine_perfile(arr.at(0)).size()); @@ -3691,7 +3692,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{enabled on;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine{enabled on;}}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); EXPECT_TRUE(conf.get_engine_enabled(arr.at(0))); @@ -3699,26 +3700,26 @@ VOID TEST(ConfigMainTest, CheckVhostConfig4) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{engine;}}")); vector arr = conf.get_transcode_engines(conf.get_transcode("ossrs.net", "xxx")); ASSERT_EQ(1, (int)arr.size()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{ffmpeg xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{ffmpeg xxx;}}")); EXPECT_STREQ("xxx", conf.get_transcode_ffmpeg(conf.get_transcode("ossrs.net", "xxx")).c_str()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx{enabled on;}}")); EXPECT_TRUE(conf.get_transcode_enabled(conf.get_transcode("ossrs.net", "xxx"))); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{transcode xxx;}")); EXPECT_TRUE(conf.get_transcode("ossrs.net", "xxx") != NULL); } } @@ -3729,7 +3730,7 @@ VOID TEST(ConfigMainTest, CheckHttpListen) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;}http_server{enabled on;listen 2345;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;}http_server{enabled on;listen 2345;}")); EXPECT_TRUE(conf.get_http_stream_enabled()); EXPECT_EQ(1, (int)conf.get_http_stream_listens().size()); EXPECT_STREQ("2345", conf.get_http_stream_listens().at(0).c_str()); @@ -3740,7 +3741,7 @@ VOID TEST(ConfigMainTest, CheckHttpListen) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;}http_server{enabled on;listen 2345;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;}http_server{enabled on;listen 2345;}")); EXPECT_TRUE(conf.get_http_stream_enabled()); EXPECT_EQ(1, (int)conf.get_http_stream_listens().size()); EXPECT_STREQ("2345", conf.get_http_stream_listens().at(0).c_str()); @@ -3755,7 +3756,7 @@ VOID TEST(ConfigMainTest, CheckHttpListen) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;listen 2345;}}http_server{enabled on;listen 3456;https{enabled on;listen 4567;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;listen 2345;}}http_server{enabled on;listen 3456;https{enabled on;listen 4567;}}")); EXPECT_TRUE(conf.get_http_stream_enabled()); EXPECT_EQ(1, (int)conf.get_http_stream_listens().size()); EXPECT_STREQ("3456", conf.get_http_stream_listens().at(0).c_str()); @@ -3770,7 +3771,7 @@ VOID TEST(ConfigMainTest, CheckHttpListen) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;listen 2345;}}http_server{enabled on;listen 3456;https{enabled on;listen 5678;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;listen 2345;}}http_server{enabled on;listen 3456;https{enabled on;listen 5678;}}")); EXPECT_TRUE(conf.get_http_stream_enabled()); EXPECT_EQ(1, (int)conf.get_http_stream_listens().size()); EXPECT_STREQ("3456", conf.get_http_stream_listens().at(0).c_str()); @@ -3785,7 +3786,7 @@ VOID TEST(ConfigMainTest, CheckHttpListen) if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen xxx;https{enabled on;listen zzz;}}http_server{enabled on;listen xxx;https{enabled on;listen yyy;}}")); + HELPER_ASSERT_FAILED(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen xxx;https{enabled on;listen zzz;}}http_server{enabled on;listen xxx;https{enabled on;listen yyy;}}")); } } @@ -3795,7 +3796,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{exec{enabled on;publish xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{exec{enabled on;publish xxx;}}")); EXPECT_TRUE(conf.get_exec("ossrs.net") != NULL); EXPECT_TRUE(conf.get_exec_enabled("ossrs.net")); EXPECT_EQ(1, (int)conf.get_exec_publishs("ossrs.net").size()); @@ -3803,7 +3804,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{ingest xxx{enabled on;ffmpeg xxx2;input{type xxx3;url xxx4;}}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{ingest xxx{enabled on;ffmpeg xxx2;input{type xxx3;url xxx4;}}}")); EXPECT_EQ(1, (int)conf.get_ingesters("ossrs.net").size()); ASSERT_TRUE(conf.get_ingest_by_id("ossrs.net", "xxx") != NULL); EXPECT_TRUE(conf.get_ingest_enabled(conf.get_ingest_by_id("ossrs.net", "xxx"))); @@ -3814,7 +3815,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "srs_log_tank xxx;srs_log_level xxx2;srs_log_file xxx3;ff_log_dir xxx4; ff_log_level xxx5;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srs_log_tank xxx;srs_log_level xxx2;srs_log_file xxx3;ff_log_dir xxx4; ff_log_level xxx5;")); EXPECT_TRUE(conf.get_log_tank_file()); EXPECT_STREQ("xxx2", conf.get_log_level().c_str()); EXPECT_STREQ("xxx3", conf.get_log_file().c_str()); @@ -3825,7 +3826,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{dash{enabled on;dash_fragment 10;dash_update_period 10;dash_timeshift 10;dash_path xxx;dash_mpd_file xxx2;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{dash{enabled on;dash_fragment 10;dash_update_period 10;dash_timeshift 10;dash_path xxx;dash_mpd_file xxx2;}}")); EXPECT_TRUE(conf.get_dash_enabled("ossrs.net")); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dash_fragment("ossrs.net")); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dash_update_period("ossrs.net")); @@ -3836,7 +3837,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{hls{enabled on;hls_entry_prefix xxx;hls_path xxx2;hls_m3u8_file xxx3;hls_ts_file xxx4;hls_ts_floor on;hls_fragment 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{hls{enabled on;hls_entry_prefix xxx;hls_path xxx2;hls_m3u8_file xxx3;hls_ts_file xxx4;hls_ts_floor on;hls_fragment 10;}}")); EXPECT_TRUE(conf.get_hls_enabled("ossrs.net")); EXPECT_STREQ("xxx", conf.get_hls_entry_prefix("ossrs.net").c_str()); EXPECT_STREQ("xxx2", conf.get_hls_path("ossrs.net").c_str()); @@ -3848,7 +3849,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{hls{hls_td_ratio 2.1;hls_aof_ratio 3.1;hls_window 10;hls_on_error xxx;hls_nb_notify 5;hls_dts_directly off;hls_cleanup off;hls_dispose 10;hls_wait_keyframe off;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{hls{hls_td_ratio 2.1;hls_aof_ratio 3.1;hls_window 10;hls_on_error xxx;hls_nb_notify 5;hls_dts_directly off;hls_cleanup off;hls_dispose 10;hls_wait_keyframe off;}}")); EXPECT_EQ(2.1, conf.get_hls_td_ratio("ossrs.net")); EXPECT_EQ(3.1, conf.get_hls_aof_ratio("ossrs.net")); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hls_window("ossrs.net")); @@ -3862,7 +3863,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{hls{hls_keys on;hls_fragments_per_key 5;hls_key_file xxx;hls_key_file_path xxx2;hls_key_url xxx3;hls_use_fmp4 on;hls_fmp4_file xx.m4s;hls_init_file yy-init.mp4;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{hls{hls_keys on;hls_fragments_per_key 5;hls_key_file xxx;hls_key_file_path xxx2;hls_key_url xxx3;hls_use_fmp4 on;hls_fmp4_file xx.m4s;hls_init_file yy-init.mp4;}}")); EXPECT_TRUE(conf.get_hls_keys("ossrs.net")); EXPECT_EQ(5, conf.get_hls_fragments_per_key("ossrs.net")); EXPECT_STREQ("xxx", conf.get_hls_key_file("ossrs.net").c_str()); @@ -3875,7 +3876,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{hds{enabled on;hds_path xxx;hds_fragment 10;hds_window 10;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{hds{enabled on;hds_path xxx;hds_fragment 10;hds_window 10;}}")); EXPECT_TRUE(conf.get_hds_enabled("ossrs.net")); EXPECT_STREQ("xxx", conf.get_hds_path("ossrs.net").c_str()); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hds_fragment("ossrs.net")); @@ -3884,7 +3885,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{dvr{enabled on;dvr_apply all;dvr_path xxx;dvr_plan xxx2;dvr_duration 10;time_jitter full;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{dvr{enabled on;dvr_apply all;dvr_path xxx;dvr_plan xxx2;dvr_duration 10;time_jitter full;}}")); EXPECT_TRUE(conf.get_dvr_enabled("ossrs.net")); EXPECT_TRUE(conf.get_dvr_apply("ossrs.net") != NULL); EXPECT_STREQ("xxx", conf.get_dvr_path("ossrs.net").c_str()); @@ -3896,7 +3897,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;crossdomain off;auth {enabled on;username admin;password 123456;}raw_api {enabled on;allow_reload on;allow_query on;allow_update on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;crossdomain off;auth {enabled on;username admin;password 123456;}raw_api {enabled on;allow_reload on;allow_query on;allow_update on;}}")); EXPECT_TRUE(conf.get_http_api_enabled()); EXPECT_EQ(1, (int)conf.get_http_api_listens().size()); EXPECT_STREQ("1234", conf.get_http_api_listens().at(0).c_str()); @@ -3912,7 +3913,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_server{enabled on;listen 1234;dir xxx2;crossdomain on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on;listen 1234;dir xxx2;crossdomain on;}")); EXPECT_TRUE(conf.get_http_stream_enabled()); EXPECT_EQ(1, (int)conf.get_http_stream_listens().size()); EXPECT_STREQ("1234", conf.get_http_stream_listens().at(0).c_str()); @@ -3922,7 +3923,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_static{enabled on;mount xxx;dir xxx2;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_static{enabled on;mount xxx;dir xxx2;}}")); EXPECT_TRUE(conf.get_vhost_http_enabled("ossrs.net")); EXPECT_STREQ("xxx", conf.get_vhost_http_mount("ossrs.net").c_str()); EXPECT_STREQ("xxx2", conf.get_vhost_http_dir("ossrs.net").c_str()); @@ -3930,7 +3931,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{http_remux{enabled on;fast_cache 10;mount xxx;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{http_remux{enabled on;fast_cache 10;mount xxx;}}")); EXPECT_TRUE(conf.get_vhost_http_remux_enabled("ossrs.net")); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_vhost_http_remux_fast_cache("ossrs.net")); EXPECT_STREQ("xxx", conf.get_vhost_http_remux_mount("ossrs.net").c_str()); @@ -3938,7 +3939,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "heartbeat{enabled on;interval 10;url xxx;device_id xxx2;summaries on;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{enabled on;interval 10;url xxx;device_id xxx2;summaries on;}")); EXPECT_TRUE(conf.get_heartbeat_enabled()); EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_heartbeat_interval()); EXPECT_STREQ("xxx", conf.get_heartbeat_url().c_str()); @@ -3948,14 +3949,14 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "stats{network 0;disk xxx;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{network 0;disk xxx;}")); EXPECT_EQ(0, (int)conf.get_stats_network()); EXPECT_TRUE(conf.get_stats_disk_device() != NULL); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "exporter{enabled on;listen 9972;label cn-beijing;tag cn-edge;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "exporter{enabled on;listen 9972;label cn-beijing;tag cn-edge;}")); EXPECT_TRUE(conf.get_exporter_enabled()); EXPECT_STREQ("9972", conf.get_exporter_listen().c_str()); EXPECT_STREQ("cn-beijing", conf.get_exporter_label().c_str()); @@ -3973,7 +3974,7 @@ VOID TEST(ConfigMainTest, CheckIncludeConfig) conf.mock_include("./conf/include_test/include.conf", "rtmp{listen 1935;}include ./conf/include_test/include_1.conf;"); conf.mock_include("./conf/include_test/include_1.conf", "max_connections 1000;daemon off;srs_log_tank console;http_server {enabled on;listen 1234;dir xxx2;}vhost ossrs.net {hls {enabled on;hls_path xxx;hls_m3u8_file xxx1;hls_ts_file xxx2;hls_fragment 10;hls_window 60;}}"); - HELPER_ASSERT_SUCCESS(conf.parse("include ./conf/include_test/include.conf;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("include ./conf/include_test/include.conf;")); vector listens = conf.get_listens(); EXPECT_EQ(1, (int)listens.size()); @@ -3999,7 +4000,7 @@ VOID TEST(ConfigMainTest, CheckIncludeConfig) conf.mock_include("./conf/include_test/include_1.conf", "max_connections 1000;daemon off;srs_log_tank console;http_server {enabled on;listen 1234;dir xxx2;}vhost ossrs.net {hls {enabled on;hls_path xxx;hls_m3u8_file xxx1;hls_ts_file xxx2;hls_fragment 10;hls_window 60;}}"); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "include ./conf/include_test/include_1.conf;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "include ./conf/include_test/include_1.conf;")); vector listens = conf.get_listens(); EXPECT_EQ(1, (int)listens.size()); @@ -4026,7 +4027,7 @@ VOID TEST(ConfigMainTest, CheckIncludeConfig) conf.mock_include("./conf/include_test/include_2.conf", "listen 1935;max_connections 1000;daemon off;srs_log_tank console;http_server {enabled on;listen 1234;dir xxx2;}vhost ossrs.net {include ./conf/include_test/include_3.conf;}"); conf.mock_include("./conf/include_test/include_3.conf", "hls {enabled on;hls_path xxx;hls_m3u8_file xxx1;hls_ts_file xxx2;hls_fragment 10;hls_window 60;}"); - HELPER_ASSERT_SUCCESS(conf.parse("include ./conf/include_test/include_2.conf;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("include ./conf/include_test/include_2.conf;")); vector listens = conf.get_listens(); EXPECT_EQ(1, (int)listens.size()); @@ -4055,7 +4056,7 @@ VOID TEST(ConfigMainTest, CheckIncludeConfig) conf.mock_include("./conf/include_test/include_5.conf", "http_server {enabled on;listen 8080;dir xxx2;}"); conf.mock_include("./conf/include_test/include_6.conf", "http_api {enabled on;listen 1985;}"); - HELPER_ASSERT_SUCCESS(conf.parse("include ./conf/include_test/include_4.conf;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("include ./conf/include_test/include_4.conf;")); vector listens = conf.get_listens(); EXPECT_EQ(1, (int)listens.size()); @@ -4088,7 +4089,7 @@ VOID TEST(ConfigMainTest, CheckIncludeConfig) conf.mock_include("./conf/include_test/include_5.conf", "http_server {enabled on;listen 1234;dir xxx2;}"); conf.mock_include("./conf/include_test/include_6.conf", "http_api {enabled on;listen 2345;}"); - HELPER_ASSERT_SUCCESS(conf.parse("include ./conf/include_test/include_4.conf;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("include ./conf/include_test/include_4.conf;")); vector listens = conf.get_listens(); EXPECT_EQ(1, (int)listens.size()); @@ -4122,7 +4123,7 @@ VOID TEST(ConfigMainTest, CheckIncludeConfig) conf.mock_include("./conf/include_test/include_6.conf", "http_api {enabled on;listen 2345;}"); conf.mock_include("./conf/include_test/include_7.conf", "dash{enabled on;dash_fragment 10;dash_update_period 10;dash_timeshift 10;dash_path xxx;dash_mpd_file xxx2;}"); - HELPER_ASSERT_SUCCESS(conf.parse("include ./conf/include_test/include_4.conf;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse("include ./conf/include_test/include_4.conf;")); vector listens = conf.get_listens(); EXPECT_EQ(1, (int)listens.size()); @@ -4156,7 +4157,7 @@ VOID TEST(ConfigMainTest, CheckIncludeConfig) if (true) { MockSrsConfig conf; - HELPER_ASSERT_FAILED(conf.parse("include ./conf/include_test/include.conf;")); + HELPER_ASSERT_FAILED(conf.mock_parse("include ./conf/include_test/include.conf;")); } } @@ -4166,19 +4167,19 @@ VOID TEST(ConfigMainTest, LogLevelV2) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(SrsLogLevelTrace, srs_get_log_level(conf.get_log_level())); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "srs_log_level warn;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srs_log_level warn;")); EXPECT_EQ(SrsLogLevelWarn, srs_get_log_level(conf.get_log_level())); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "srs_log_level_v2 warn;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srs_log_level_v2 warn;")); EXPECT_EQ(SrsLogLevelWarn, srs_get_log_level(conf.get_log_level_v2())); } } @@ -4189,19 +4190,19 @@ VOID TEST(ConfigMainTest, SrtServerTlpktDrop) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF)); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_TRUE(conf.get_srto_tlpktdrop()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "srt_server{tlpktdrop off;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tlpktdrop off;}")); EXPECT_FALSE(conf.get_srto_tlpktdrop()); } if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "srt_server{tlpkdrop off;}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tlpkdrop off;}")); EXPECT_FALSE(conf.get_srto_tlpktdrop()); } } @@ -5009,7 +5010,7 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesForward) if (true) { // Test that environment variable overrides config file - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net{forward {enabled off; backend 192.168.1.1:1936;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net{forward {enabled off; backend 192.168.1.1:1936;}}")); SrsSetEnvConfig(conf, forward_enabled, "SRS_VHOST_FORWARD_ENABLED", "on"); SrsSetEnvConfig(conf, forward_backend, "SRS_VHOST_FORWARD_BACKEND", "10.0.0.1:1936"); diff --git a/trunk/src/utest/srs_utest_config.hpp b/trunk/src/utest/srs_utest_config.hpp index 390389e8a..937adaf5d 100644 --- a/trunk/src/utest/srs_utest_config.hpp +++ b/trunk/src/utest/srs_utest_config.hpp @@ -38,7 +38,7 @@ private: std::map included_files; public: - virtual srs_error_t parse(std::string buf); + virtual srs_error_t mock_parse(std::string buf); virtual srs_error_t mock_include(const std::string file_name, const std::string content); protected: diff --git a/trunk/src/utest/srs_utest_config2.cpp b/trunk/src/utest/srs_utest_config2.cpp index c803e1345..46be2b7ba 100644 --- a/trunk/src/utest/srs_utest_config2.cpp +++ b/trunk/src/utest/srs_utest_config2.cpp @@ -5,8 +5,10 @@ // #include +#include #include #include +#include #include VOID TEST(ConfigMainTest, CheckIncludeEmptyConfig) @@ -40,7 +42,7 @@ VOID TEST(ConfigMainTest, CheckIncludeEmptyConfig) if (true) { MockSrsConfig conf; conf.mock_include("test.conf", ""); - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "include test.conf;")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "include test.conf;")); EXPECT_EQ(1, (int)conf.get_listens().size()); } } @@ -51,7 +53,7 @@ VOID TEST(ConfigMainTest, CheckHttpListenFollow) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;https{enabled on;}}http_server{enabled on;listen 1985;https{enabled on;listen 4567;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{enabled on;}}http_server{enabled on;listen 1985;https{enabled on;listen 4567;}}")); EXPECT_TRUE(conf.get_http_stream_enabled()); // If http API use same port to HTTP server. @@ -70,7 +72,7 @@ VOID TEST(ConfigMainTest, CheckHttpListenFollow) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 8080;https{enabled on;}}http_server{enabled on;https{enabled on;listen 4567;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen 8080;https{enabled on;}}http_server{enabled on;https{enabled on;listen 4567;}}")); EXPECT_TRUE(conf.get_http_stream_enabled()); // If http API use same port to HTTP server. @@ -89,7 +91,7 @@ VOID TEST(ConfigMainTest, CheckHttpListenFollow) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 8080;https{enabled on;}}http_server{enabled on;https{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen 8080;https{enabled on;}}http_server{enabled on;https{enabled on;}}")); EXPECT_TRUE(conf.get_http_stream_enabled()); // If http API use same port to HTTP server. @@ -108,7 +110,7 @@ VOID TEST(ConfigMainTest, CheckHttpListenFollow) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;https{enabled on;}}http_server{enabled on;listen 1985;https{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{enabled on;}}http_server{enabled on;listen 1985;https{enabled on;}}")); EXPECT_TRUE(conf.get_http_stream_enabled()); // If http API use same port to HTTP server. @@ -127,7 +129,7 @@ VOID TEST(ConfigMainTest, CheckHttpListenFollow) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;}}http_server{enabled on;listen 1234;https{enabled on;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;}}http_server{enabled on;listen 1234;https{enabled on;}}")); EXPECT_TRUE(conf.get_http_stream_enabled()); // If http API use same port to HTTP server. @@ -146,7 +148,7 @@ VOID TEST(ConfigMainTest, CheckHttpListenFollow) if (true) { MockSrsConfig conf; - HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;}}http_server{enabled on;listen 1234;https{enabled on;listen 4567;}}")); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;}}http_server{enabled on;listen 1234;https{enabled on;listen 4567;}}")); EXPECT_TRUE(conf.get_http_stream_enabled()); // If http API use same port to HTTP server. @@ -163,3 +165,5352 @@ VOID TEST(ConfigMainTest, CheckHttpListenFollow) EXPECT_TRUE(conf.get_http_stream_crossdomain()); } } + +extern bool srs_directive_equals(SrsConfDirective *a, SrsConfDirective *b); +extern bool srs_directive_equals(SrsConfDirective *a, SrsConfDirective *b, string except); + +VOID TEST(ConfigDirectiveTest, DirectiveEqualsNullBoth) +{ + // Test the case where both directives are NULL - should return true + EXPECT_TRUE(srs_directive_equals(NULL, NULL)); +} + +VOID TEST(ConfigDirectiveTest, DirectiveEqualsWithExceptParameter) +{ + // Test srs_directive_equals with except parameter - both NULL case + if (true) { + // Both NULL, should return true regardless of except parameter + EXPECT_TRUE(srs_directive_equals(NULL, NULL, "any_except")); + } + + // Test srs_directive_equals_self failure case + if (true) { + // Create two directives with different names - should fail srs_directive_equals_self + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "vhost"; + a->args_.push_back("test.com"); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "different"; // Different name + b->args_.push_back("test.com"); + + // Should return false because srs_directive_equals_self fails + EXPECT_FALSE(srs_directive_equals(a, b, "any_except")); + + srs_freep(a); + srs_freep(b); + } + + // Test except parameter functionality - skip child directive with except name + if (true) { + // Create two directives that differ only in a child directive named "hls" + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "vhost"; + a->args_.push_back("test.com"); + + SrsConfDirective *child_a1 = new SrsConfDirective(); + child_a1->name_ = "hls"; + child_a1->args_.push_back("on"); + a->directives_.push_back(child_a1); + + SrsConfDirective *child_a2 = new SrsConfDirective(); + child_a2->name_ = "dvr"; + child_a2->args_.push_back("on"); + a->directives_.push_back(child_a2); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "vhost"; + b->args_.push_back("test.com"); + + SrsConfDirective *child_b1 = new SrsConfDirective(); + child_b1->name_ = "hls"; + child_b1->args_.push_back("off"); // Different from a + b->directives_.push_back(child_b1); + + SrsConfDirective *child_b2 = new SrsConfDirective(); + child_b2->name_ = "dvr"; + child_b2->args_.push_back("on"); // Same as a + b->directives_.push_back(child_b2); + + // Without except parameter, should be false because hls differs + EXPECT_FALSE(srs_directive_equals(a, b, "")); + + // With except="hls", should be true because hls directive is skipped + EXPECT_TRUE(srs_directive_equals(a, b, "hls")); + + // With except="dvr", should be false because hls still differs + EXPECT_FALSE(srs_directive_equals(a, b, "dvr")); + + srs_freep(a); + srs_freep(b); + } + + // Test recursive comparison failure case + if (true) { + // Create two directives with nested child directives that differ + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "vhost"; + a->args_.push_back("test.com"); + + SrsConfDirective *child_a = new SrsConfDirective(); + child_a->name_ = "rtc"; + a->directives_.push_back(child_a); + + SrsConfDirective *grandchild_a = new SrsConfDirective(); + grandchild_a->name_ = "enabled"; + grandchild_a->args_.push_back("on"); + child_a->directives_.push_back(grandchild_a); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "vhost"; + b->args_.push_back("test.com"); + + SrsConfDirective *child_b = new SrsConfDirective(); + child_b->name_ = "rtc"; + b->directives_.push_back(child_b); + + SrsConfDirective *grandchild_b = new SrsConfDirective(); + grandchild_b->name_ = "enabled"; + grandchild_b->args_.push_back("off"); // Different from a + child_b->directives_.push_back(grandchild_b); + + // Should return false because nested comparison fails + EXPECT_FALSE(srs_directive_equals(a, b, "some_other_except")); + + srs_freep(a); + srs_freep(b); + } + + // Test multiple except directives with complex structure + if (true) { + // Create complex directives with multiple child directives + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "vhost"; + a->args_.push_back("test.com"); + + SrsConfDirective *child_a1 = new SrsConfDirective(); + child_a1->name_ = "hls"; + child_a1->args_.push_back("on"); + a->directives_.push_back(child_a1); + + SrsConfDirective *child_a2 = new SrsConfDirective(); + child_a2->name_ = "dvr"; + child_a2->args_.push_back("on"); + a->directives_.push_back(child_a2); + + SrsConfDirective *child_a3 = new SrsConfDirective(); + child_a3->name_ = "rtc"; + child_a3->args_.push_back("on"); + a->directives_.push_back(child_a3); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "vhost"; + b->args_.push_back("test.com"); + + SrsConfDirective *child_b1 = new SrsConfDirective(); + child_b1->name_ = "hls"; + child_b1->args_.push_back("off"); // Different + b->directives_.push_back(child_b1); + + SrsConfDirective *child_b2 = new SrsConfDirective(); + child_b2->name_ = "dvr"; + child_b2->args_.push_back("off"); // Different + b->directives_.push_back(child_b2); + + SrsConfDirective *child_b3 = new SrsConfDirective(); + child_b3->name_ = "rtc"; + child_b3->args_.push_back("on"); // Same + b->directives_.push_back(child_b3); + + // Without except, should be false + EXPECT_FALSE(srs_directive_equals(a, b, "")); + + // Skip hls, should still be false because dvr differs + EXPECT_FALSE(srs_directive_equals(a, b, "hls")); + + // Skip dvr, should still be false because hls differs + EXPECT_FALSE(srs_directive_equals(a, b, "dvr")); + + srs_freep(a); + srs_freep(b); + } + + // Test edge case: empty directives with except parameter + if (true) { + // Create two identical empty directives + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "simple"; + a->args_.push_back("value"); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "simple"; + b->args_.push_back("value"); + + // Should be equal even with except parameter since no child directives + EXPECT_TRUE(srs_directive_equals(a, b, "any_except")); + + srs_freep(a); + srs_freep(b); + } + + // Test case where only one directive has the except child + if (true) { + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "vhost"; + a->args_.push_back("test.com"); + + SrsConfDirective *child_a = new SrsConfDirective(); + child_a->name_ = "hls"; + child_a->args_.push_back("on"); + a->directives_.push_back(child_a); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "vhost"; + b->args_.push_back("test.com"); + + SrsConfDirective *child_b = new SrsConfDirective(); + child_b->name_ = "dvr"; // Different name, not "hls" + child_b->args_.push_back("on"); + b->directives_.push_back(child_b); + + // Should be false because child directive names differ + // and "hls" is not present in b to be skipped + EXPECT_FALSE(srs_directive_equals(a, b, "hls")); + + srs_freep(a); + srs_freep(b); + } +} + +VOID TEST(ConfigDirectiveTest, DirectiveEqualsWithChildDirectives) +{ + // Test the recursive comparison of child directives + if (true) { + // Create two identical directives with child directives + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "vhost"; + a->args_.push_back("test.com"); + + SrsConfDirective *child_a = new SrsConfDirective(); + child_a->name_ = "hls"; + child_a->args_.push_back("on"); + a->directives_.push_back(child_a); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "vhost"; + b->args_.push_back("test.com"); + + SrsConfDirective *child_b = new SrsConfDirective(); + child_b->name_ = "hls"; + child_b->args_.push_back("on"); + b->directives_.push_back(child_b); + + // Should be equal since all properties and child directives match + EXPECT_TRUE(srs_directive_equals(a, b)); + + srs_freep(a); + srs_freep(b); + } + + if (true) { + // Create two directives with different child directives + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "vhost"; + a->args_.push_back("test.com"); + + SrsConfDirective *child_a = new SrsConfDirective(); + child_a->name_ = "hls"; + child_a->args_.push_back("on"); + a->directives_.push_back(child_a); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "vhost"; + b->args_.push_back("test.com"); + + SrsConfDirective *child_b = new SrsConfDirective(); + child_b->name_ = "hls"; + child_b->args_.push_back("off"); // Different argument + b->directives_.push_back(child_b); + + // Should not be equal since child directive arguments differ + EXPECT_FALSE(srs_directive_equals(a, b)); + + srs_freep(a); + srs_freep(b); + } + + if (true) { + // Create two directives with multiple levels of child directives + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "vhost"; + a->args_.push_back("test.com"); + + SrsConfDirective *child_a = new SrsConfDirective(); + child_a->name_ = "hls"; + + SrsConfDirective *grandchild_a = new SrsConfDirective(); + grandchild_a->name_ = "enabled"; + grandchild_a->args_.push_back("on"); + child_a->directives_.push_back(grandchild_a); + + a->directives_.push_back(child_a); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "vhost"; + b->args_.push_back("test.com"); + + SrsConfDirective *child_b = new SrsConfDirective(); + child_b->name_ = "hls"; + + SrsConfDirective *grandchild_b = new SrsConfDirective(); + grandchild_b->name_ = "enabled"; + grandchild_b->args_.push_back("on"); + child_b->directives_.push_back(grandchild_b); + + b->directives_.push_back(child_b); + + // Should be equal since all nested directives match + EXPECT_TRUE(srs_directive_equals(a, b)); + + srs_freep(a); + srs_freep(b); + } + + if (true) { + // Create two directives with multiple child directives + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "vhost"; + a->args_.push_back("test.com"); + + SrsConfDirective *child_a1 = new SrsConfDirective(); + child_a1->name_ = "hls"; + child_a1->args_.push_back("on"); + a->directives_.push_back(child_a1); + + SrsConfDirective *child_a2 = new SrsConfDirective(); + child_a2->name_ = "dvr"; + child_a2->args_.push_back("off"); + a->directives_.push_back(child_a2); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "vhost"; + b->args_.push_back("test.com"); + + SrsConfDirective *child_b1 = new SrsConfDirective(); + child_b1->name_ = "hls"; + child_b1->args_.push_back("on"); + b->directives_.push_back(child_b1); + + SrsConfDirective *child_b2 = new SrsConfDirective(); + child_b2->name_ = "dvr"; + child_b2->args_.push_back("off"); + b->directives_.push_back(child_b2); + + // Should be equal since all child directives match + EXPECT_TRUE(srs_directive_equals(a, b)); + + srs_freep(a); + srs_freep(b); + } + + if (true) { + // Test empty directives (no child directives) + SrsConfDirective *a = new SrsConfDirective(); + a->name_ = "simple"; + a->args_.push_back("value"); + + SrsConfDirective *b = new SrsConfDirective(); + b->name_ = "simple"; + b->args_.push_back("value"); + + // Should be equal since they have same name, args, and no child directives + EXPECT_TRUE(srs_directive_equals(a, b)); + + srs_freep(a); + srs_freep(b); + } +} + +extern srs_error_t srs_config_transform_vhost(SrsConfDirective *root); + +VOID TEST(ConfigTransformTest, TransformRtcServerRemoveDeprecatedConfigs) +{ + srs_error_t err; + + // Test removing perf_stat from rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on; listen 8000; perf_stat on;}")); + + // Verify perf_stat was removed during transformation + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("listen") != NULL); + EXPECT_TRUE(rtc_server->get("perf_stat") == NULL); // Should be removed + } + + // Test removing queue_length from rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on; listen 8000; queue_length 10;}")); + + // Verify queue_length was removed during transformation + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("listen") != NULL); + EXPECT_TRUE(rtc_server->get("queue_length") == NULL); // Should be removed + } + + // Test removing both perf_stat and queue_length from rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on; listen 8000; perf_stat on; queue_length 10; protocol udp;}")); + + // Verify both deprecated configs were removed during transformation + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("listen") != NULL); + EXPECT_TRUE(rtc_server->get("protocol") != NULL); + EXPECT_TRUE(rtc_server->get("perf_stat") == NULL); // Should be removed + EXPECT_TRUE(rtc_server->get("queue_length") == NULL); // Should be removed + } + + // Test that other rtc_server configs are preserved + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on; listen 8000; protocol udp; candidate 192.168.1.100; perf_stat on; queue_length 10;}")); + + // Verify valid configs are preserved and deprecated ones are removed + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("listen") != NULL); + EXPECT_TRUE(rtc_server->get("protocol") != NULL); + EXPECT_TRUE(rtc_server->get("candidate") != NULL); + EXPECT_TRUE(rtc_server->get("perf_stat") == NULL); // Should be removed + EXPECT_TRUE(rtc_server->get("queue_length") == NULL); // Should be removed + } + + // Test rtc_server section without deprecated configs (should remain unchanged) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on; listen 8000; protocol udp;}")); + + // Verify all configs are preserved when no deprecated configs present + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("listen") != NULL); + EXPECT_TRUE(rtc_server->get("protocol") != NULL); + EXPECT_EQ(3, (int)rtc_server->directives_.size()); // Should have exactly 3 directives + } + + // Test multiple rtc_server sections (edge case) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on; perf_stat on;} rtc_server{listen 8001; queue_length 5;}")); + + // Get all rtc_server directives + std::vector rtc_servers; + for (int i = 0; i < (int)conf.get_root()->directives_.size(); i++) { + SrsConfDirective *dir = conf.get_root()->directives_.at(i); + if (dir->name_ == "rtc_server") { + rtc_servers.push_back(dir); + } + } + + // Should have 2 rtc_server sections + EXPECT_EQ(2, (int)rtc_servers.size()); + + // First rtc_server should have enabled but not perf_stat + EXPECT_TRUE(rtc_servers[0]->get("enabled") != NULL); + EXPECT_TRUE(rtc_servers[0]->get("perf_stat") == NULL); + + // Second rtc_server should have listen but not queue_length + EXPECT_TRUE(rtc_servers[1]->get("listen") != NULL); + EXPECT_TRUE(rtc_servers[1]->get("queue_length") == NULL); + } +} + +VOID TEST(ConfigTransformTest, TransformRtcServerNestedDeprecatedConfigs) +{ + srs_error_t err; + + // Test nested rtc_server with deprecated configs in complex structure + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on; listen 8000; perf_stat{enabled on; interval 30;} queue_length 100;}")); + + // Verify nested perf_stat directive is completely removed + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("listen") != NULL); + EXPECT_TRUE(rtc_server->get("perf_stat") == NULL); // Should be removed entirely + EXPECT_TRUE(rtc_server->get("queue_length") == NULL); // Should be removed + } + + // Test rtc_server with only deprecated configs + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{perf_stat on; queue_length 50;}")); + + // Verify rtc_server section exists but is empty after removing deprecated configs + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_EQ(0, (int)rtc_server->directives_.size()); // Should be empty + EXPECT_TRUE(rtc_server->get("perf_stat") == NULL); + EXPECT_TRUE(rtc_server->get("queue_length") == NULL); + } + + // Test rtc_server with mixed valid and deprecated configs in different order + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{perf_stat on; enabled on; queue_length 25; listen 8000; protocol udp; perf_stat off;}")); + + // Verify all perf_stat instances are removed and valid configs preserved + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("listen") != NULL); + EXPECT_TRUE(rtc_server->get("protocol") != NULL); + EXPECT_TRUE(rtc_server->get("perf_stat") == NULL); // All instances should be removed + EXPECT_TRUE(rtc_server->get("queue_length") == NULL); // Should be removed + EXPECT_EQ(3, (int)rtc_server->directives_.size()); // Should have exactly 3 valid directives + } +} + +VOID TEST(ConfigTransformTest, TransformRtcServerPreserveOtherSections) +{ + srs_error_t err; + + // Test that deprecated config removal only affects rtc_server sections + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on; perf_stat on; queue_length 10;} http_server{enabled on; listen 8080;}")); + + // Verify rtc_server has deprecated configs removed + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("perf_stat") == NULL); // Should be removed from rtc_server + EXPECT_TRUE(rtc_server->get("queue_length") == NULL); // Should be removed from rtc_server + + // Verify http_server preserves all valid configs (transformation doesn't affect it) + SrsConfDirective *http_server = conf.get_root()->get("http_server"); + ASSERT_TRUE(http_server != NULL); + EXPECT_TRUE(http_server->get("enabled") != NULL); + EXPECT_TRUE(http_server->get("listen") != NULL); // Should be preserved in http_server + } + + // Test vhost sections are not affected by rtc_server transformation + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{perf_stat on; queue_length 5;} vhost test.com{rtc{enabled on; rtmp_to_rtc on;}}")); + + // Verify rtc_server has deprecated configs removed + SrsConfDirective *rtc_server = conf.get_root()->get("rtc_server"); + ASSERT_TRUE(rtc_server != NULL); + EXPECT_TRUE(rtc_server->get("perf_stat") == NULL); + EXPECT_TRUE(rtc_server->get("queue_length") == NULL); + + // Verify vhost rtc section preserves valid configs (different section) + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("enabled") != NULL); + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be preserved in vhost.rtc + } +} + +VOID TEST(ConfigTransformTest, TransformVhostDirectCall) +{ + srs_error_t err; + + // Test direct call to srs_config_transform_vhost function + if (true) { + // Create a root directive with rtc_server containing deprecated configs + SrsConfDirective *root = new SrsConfDirective(); + + // Add rtmp section (required for valid config) + SrsConfDirective *rtmp = new SrsConfDirective(); + rtmp->name_ = "rtmp"; + SrsConfDirective *listen = new SrsConfDirective(); + listen->name_ = "listen"; + listen->args_.push_back("1935"); + rtmp->directives_.push_back(listen); + root->directives_.push_back(rtmp); + + // Add rtc_server section with deprecated configs + SrsConfDirective *rtc_server = new SrsConfDirective(); + rtc_server->name_ = "rtc_server"; + + SrsConfDirective *enabled = new SrsConfDirective(); + enabled->name_ = "enabled"; + enabled->args_.push_back("on"); + rtc_server->directives_.push_back(enabled); + + SrsConfDirective *perf_stat = new SrsConfDirective(); + perf_stat->name_ = "perf_stat"; + perf_stat->args_.push_back("on"); + rtc_server->directives_.push_back(perf_stat); + + SrsConfDirective *queue_length = new SrsConfDirective(); + queue_length->name_ = "queue_length"; + queue_length->args_.push_back("100"); + rtc_server->directives_.push_back(queue_length); + + SrsConfDirective *protocol = new SrsConfDirective(); + protocol->name_ = "protocol"; + protocol->args_.push_back("udp"); + rtc_server->directives_.push_back(protocol); + + root->directives_.push_back(rtc_server); + + // Verify initial state + EXPECT_EQ(4, (int)rtc_server->directives_.size()); + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("perf_stat") != NULL); + EXPECT_TRUE(rtc_server->get("queue_length") != NULL); + EXPECT_TRUE(rtc_server->get("protocol") != NULL); + + // Call the transform function directly + HELPER_ASSERT_SUCCESS(srs_config_transform_vhost(root)); + + // Verify deprecated configs were removed + EXPECT_EQ(2, (int)rtc_server->directives_.size()); // Should have only enabled and protocol + EXPECT_TRUE(rtc_server->get("enabled") != NULL); + EXPECT_TRUE(rtc_server->get("protocol") != NULL); + EXPECT_TRUE(rtc_server->get("perf_stat") == NULL); // Should be removed + EXPECT_TRUE(rtc_server->get("queue_length") == NULL); // Should be removed + + srs_freep(root); + } + + // Test transform function with empty rtc_server section + if (true) { + SrsConfDirective *root = new SrsConfDirective(); + + // Add rtmp section (required for valid config) + SrsConfDirective *rtmp = new SrsConfDirective(); + rtmp->name_ = "rtmp"; + SrsConfDirective *listen = new SrsConfDirective(); + listen->name_ = "listen"; + listen->args_.push_back("1935"); + rtmp->directives_.push_back(listen); + root->directives_.push_back(rtmp); + + // Add empty rtc_server section + SrsConfDirective *rtc_server = new SrsConfDirective(); + rtc_server->name_ = "rtc_server"; + root->directives_.push_back(rtc_server); + + // Verify initial state + EXPECT_EQ(0, (int)rtc_server->directives_.size()); + + // Call the transform function directly + HELPER_ASSERT_SUCCESS(srs_config_transform_vhost(root)); + + // Verify rtc_server remains empty + EXPECT_EQ(0, (int)rtc_server->directives_.size()); + + srs_freep(root); + } +} + +VOID TEST(ConfigTransformTest, TransformVhostNackToRtc) +{ + srs_error_t err; + + // Test transforming vhost nack directive to vhost.rtc.nack + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{nack{enabled on;}}")); + + // Verify nack was moved to rtc section + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("nack") != NULL); // Should be moved here + EXPECT_STREQ("on", rtc->get("nack")->arg0().c_str()); + } + + // Test transforming vhost nack with no_copy directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{nack{enabled on; no_copy off;}}")); + + // Verify nack and nack_no_copy were moved to rtc section + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("nack") != NULL); // Should be moved here + EXPECT_STREQ("on", rtc->get("nack")->arg0().c_str()); + EXPECT_TRUE(rtc->get("nack_no_copy") != NULL); // Should be created from no_copy + EXPECT_STREQ("off", rtc->get("nack_no_copy")->arg0().c_str()); + } + + // Test transforming vhost nack with only no_copy directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{nack{no_copy on;}}")); + + // Verify only nack_no_copy was created in rtc section + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("nack") == NULL); // Should not be created (no enabled directive) + EXPECT_TRUE(rtc->get("nack_no_copy") != NULL); // Should be created from no_copy + EXPECT_STREQ("on", rtc->get("nack_no_copy")->arg0().c_str()); + } + + // Test transforming empty nack directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{nack{}}")); + + // Verify nack was removed but rtc section was created (empty) + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("nack") == NULL); // Should not be created (no enabled directive) + EXPECT_TRUE(rtc->get("nack_no_copy") == NULL); // Should not be created (no no_copy directive) + } +} + +VOID TEST(ConfigTransformTest, TransformVhostTwccToRtc) +{ + srs_error_t err; + + // Test transforming vhost twcc directive to vhost.rtc.twcc + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{twcc{enabled on;}}")); + + // Verify twcc was moved to rtc section + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("twcc") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("twcc") != NULL); // Should be moved here + EXPECT_STREQ("on", rtc->get("twcc")->arg0().c_str()); + } + + // Test transforming vhost twcc with enabled off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{twcc{enabled off;}}")); + + // Verify twcc was moved to rtc section with correct value + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("twcc") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("twcc") != NULL); // Should be moved here + EXPECT_STREQ("off", rtc->get("twcc")->arg0().c_str()); + } + + // Test transforming empty twcc directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{twcc{}}")); + + // Verify twcc was removed but rtc section was created (empty) + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("twcc") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("twcc") == NULL); // Should not be created (no enabled directive) + } +} + +VOID TEST(ConfigTransformTest, TransformVhostNackAndTwccToRtc) +{ + srs_error_t err; + + // Test transforming both nack and twcc directives together + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{nack{enabled on; no_copy off;} twcc{enabled on;}}")); + + // Verify both nack and twcc were moved to rtc section + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed from vhost level + EXPECT_TRUE(vhost->get("twcc") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("nack") != NULL); // Should be moved here + EXPECT_STREQ("on", rtc->get("nack")->arg0().c_str()); + EXPECT_TRUE(rtc->get("nack_no_copy") != NULL); // Should be created from no_copy + EXPECT_STREQ("off", rtc->get("nack_no_copy")->arg0().c_str()); + EXPECT_TRUE(rtc->get("twcc") != NULL); // Should be moved here + EXPECT_STREQ("on", rtc->get("twcc")->arg0().c_str()); + } + + // Test transforming nack and twcc with existing rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;} nack{enabled off;} twcc{enabled on;}}")); + + // Verify nack and twcc were added to existing rtc section + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed from vhost level + EXPECT_TRUE(vhost->get("twcc") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should exist + EXPECT_TRUE(rtc->get("enabled") != NULL); // Should preserve existing config + EXPECT_STREQ("on", rtc->get("enabled")->arg0().c_str()); + EXPECT_TRUE(rtc->get("nack") != NULL); // Should be added + EXPECT_STREQ("off", rtc->get("nack")->arg0().c_str()); + EXPECT_TRUE(rtc->get("twcc") != NULL); // Should be added + EXPECT_STREQ("on", rtc->get("twcc")->arg0().c_str()); + } +} + +VOID TEST(ConfigTransformTest, TransformVhostNackTwccMultipleVhosts) +{ + srs_error_t err; + + // Test transforming nack and twcc in multiple vhosts + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test1.com{nack{enabled on;}} vhost test2.com{twcc{enabled off;}} vhost test3.com{nack{no_copy on;} twcc{enabled on;}}")); + + // Get all vhost directives + std::vector vhosts; + for (int i = 0; i < (int)conf.get_root()->directives_.size(); i++) { + SrsConfDirective *dir = conf.get_root()->directives_.at(i); + if (dir->name_ == "vhost") { + vhosts.push_back(dir); + } + } + + // Should have 3 vhost sections + EXPECT_EQ(3, (int)vhosts.size()); + + // First vhost (test1.com) - nack transformation + SrsConfDirective *vhost1 = NULL; + for (int i = 0; i < (int)vhosts.size(); i++) { + if (vhosts[i]->arg0() == "test1.com") { + vhost1 = vhosts[i]; + break; + } + } + ASSERT_TRUE(vhost1 != NULL); + EXPECT_TRUE(vhost1->get("nack") == NULL); // Should be removed + SrsConfDirective *rtc1 = vhost1->get("rtc"); + ASSERT_TRUE(rtc1 != NULL); + EXPECT_TRUE(rtc1->get("nack") != NULL); + EXPECT_STREQ("on", rtc1->get("nack")->arg0().c_str()); + + // Second vhost (test2.com) - twcc transformation + SrsConfDirective *vhost2 = NULL; + for (int i = 0; i < (int)vhosts.size(); i++) { + if (vhosts[i]->arg0() == "test2.com") { + vhost2 = vhosts[i]; + break; + } + } + ASSERT_TRUE(vhost2 != NULL); + EXPECT_TRUE(vhost2->get("twcc") == NULL); // Should be removed + SrsConfDirective *rtc2 = vhost2->get("rtc"); + ASSERT_TRUE(rtc2 != NULL); + EXPECT_TRUE(rtc2->get("twcc") != NULL); + EXPECT_STREQ("off", rtc2->get("twcc")->arg0().c_str()); + + // Third vhost (test3.com) - both nack and twcc transformation + SrsConfDirective *vhost3 = NULL; + for (int i = 0; i < (int)vhosts.size(); i++) { + if (vhosts[i]->arg0() == "test3.com") { + vhost3 = vhosts[i]; + break; + } + } + ASSERT_TRUE(vhost3 != NULL); + EXPECT_TRUE(vhost3->get("nack") == NULL); // Should be removed + EXPECT_TRUE(vhost3->get("twcc") == NULL); // Should be removed + SrsConfDirective *rtc3 = vhost3->get("rtc"); + ASSERT_TRUE(rtc3 != NULL); + EXPECT_TRUE(rtc3->get("nack_no_copy") != NULL); + EXPECT_STREQ("on", rtc3->get("nack_no_copy")->arg0().c_str()); + EXPECT_TRUE(rtc3->get("twcc") != NULL); + EXPECT_STREQ("on", rtc3->get("twcc")->arg0().c_str()); + } +} + +VOID TEST(ConfigTransformTest, TransformVhostNackTwccComplexArgs) +{ + srs_error_t err; + + // Test transforming nack and twcc with multiple arguments + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{nack{enabled on off; no_copy off on;} twcc{enabled on off on;}}")); + + // Verify nack and twcc were moved to rtc section with all arguments preserved + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed from vhost level + EXPECT_TRUE(vhost->get("twcc") == NULL); // Should be removed from vhost level + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + + // Check nack directive with multiple arguments + SrsConfDirective *nack = rtc->get("nack"); + ASSERT_TRUE(nack != NULL); + EXPECT_EQ(2, (int)nack->args_.size()); + EXPECT_STREQ("on", nack->args_[0].c_str()); + EXPECT_STREQ("off", nack->args_[1].c_str()); + + // Check nack_no_copy directive with multiple arguments + SrsConfDirective *nack_no_copy = rtc->get("nack_no_copy"); + ASSERT_TRUE(nack_no_copy != NULL); + EXPECT_EQ(2, (int)nack_no_copy->args_.size()); + EXPECT_STREQ("off", nack_no_copy->args_[0].c_str()); + EXPECT_STREQ("on", nack_no_copy->args_[1].c_str()); + + // Check twcc directive with multiple arguments + SrsConfDirective *twcc = rtc->get("twcc"); + ASSERT_TRUE(twcc != NULL); + EXPECT_EQ(3, (int)twcc->args_.size()); + EXPECT_STREQ("on", twcc->args_[0].c_str()); + EXPECT_STREQ("off", twcc->args_[1].c_str()); + EXPECT_STREQ("on", twcc->args_[2].c_str()); + } +} + +VOID TEST(ConfigTransformTest, TransformVhostNackTwccPreserveOtherConfigs) +{ + srs_error_t err; + + // Test that transformation preserves other vhost configurations + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;} nack{enabled on;} dvr{enabled off;} twcc{enabled on;} play{mw_latency 100;}}")); + + // Verify nack and twcc were moved to rtc section + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed from vhost level + EXPECT_TRUE(vhost->get("twcc") == NULL); // Should be removed from vhost level + + // Verify other vhost configs are preserved + EXPECT_TRUE(vhost->get("hls") != NULL); // Should be preserved + EXPECT_TRUE(vhost->get("dvr") != NULL); // Should be preserved + EXPECT_TRUE(vhost->get("play") != NULL); // Should be preserved + + // Verify rtc section was created with transformed configs + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("nack") != NULL); // Should be moved here + EXPECT_STREQ("on", rtc->get("nack")->arg0().c_str()); + EXPECT_TRUE(rtc->get("twcc") != NULL); // Should be moved here + EXPECT_STREQ("on", rtc->get("twcc")->arg0().c_str()); + + // Verify other sections have correct configs + SrsConfDirective *hls = vhost->get("hls"); + ASSERT_TRUE(hls != NULL); + EXPECT_TRUE(hls->get("enabled") != NULL); + EXPECT_STREQ("on", hls->get("enabled")->arg0().c_str()); + + SrsConfDirective *dvr = vhost->get("dvr"); + ASSERT_TRUE(dvr != NULL); + EXPECT_TRUE(dvr->get("enabled") != NULL); + EXPECT_STREQ("off", dvr->get("enabled")->arg0().c_str()); + + SrsConfDirective *play = vhost->get("play"); + ASSERT_TRUE(play != NULL); + EXPECT_TRUE(play->get("mw_latency") != NULL); + EXPECT_STREQ("100", play->get("mw_latency")->arg0().c_str()); + } +} + +VOID TEST(ConfigTransformTest, TransformVhostNackTwccDirectCall) +{ + srs_error_t err; + + // Test direct call to srs_config_transform_vhost function with nack/twcc transformation + if (true) { + // Create a root directive with vhost containing nack and twcc + SrsConfDirective *root = new SrsConfDirective(); + + // Add rtmp section (required for valid config) + SrsConfDirective *rtmp = new SrsConfDirective(); + rtmp->name_ = "rtmp"; + SrsConfDirective *listen = new SrsConfDirective(); + listen->name_ = "listen"; + listen->args_.push_back("1935"); + rtmp->directives_.push_back(listen); + root->directives_.push_back(rtmp); + + // Add vhost section with nack and twcc + SrsConfDirective *vhost = new SrsConfDirective(); + vhost->name_ = "vhost"; + vhost->args_.push_back("test.com"); + + // Add nack directive + SrsConfDirective *nack = new SrsConfDirective(); + nack->name_ = "nack"; + SrsConfDirective *nack_enabled = new SrsConfDirective(); + nack_enabled->name_ = "enabled"; + nack_enabled->args_.push_back("on"); + nack->directives_.push_back(nack_enabled); + SrsConfDirective *nack_no_copy = new SrsConfDirective(); + nack_no_copy->name_ = "no_copy"; + nack_no_copy->args_.push_back("off"); + nack->directives_.push_back(nack_no_copy); + vhost->directives_.push_back(nack); + + // Add twcc directive + SrsConfDirective *twcc = new SrsConfDirective(); + twcc->name_ = "twcc"; + SrsConfDirective *twcc_enabled = new SrsConfDirective(); + twcc_enabled->name_ = "enabled"; + twcc_enabled->args_.push_back("on"); + twcc->directives_.push_back(twcc_enabled); + vhost->directives_.push_back(twcc); + + root->directives_.push_back(vhost); + + // Verify initial state + EXPECT_EQ(2, (int)vhost->directives_.size()); // nack and twcc + EXPECT_TRUE(vhost->get("nack") != NULL); + EXPECT_TRUE(vhost->get("twcc") != NULL); + EXPECT_TRUE(vhost->get("rtc") == NULL); // Should not exist yet + + // Call the transform function directly + HELPER_ASSERT_SUCCESS(srs_config_transform_vhost(root)); + + // Verify nack and twcc were transformed to rtc section + EXPECT_EQ(1, (int)vhost->directives_.size()); // Should have only rtc + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed + EXPECT_TRUE(vhost->get("twcc") == NULL); // Should be removed + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("nack") != NULL); // Should be moved here + EXPECT_STREQ("on", rtc->get("nack")->arg0().c_str()); + EXPECT_TRUE(rtc->get("nack_no_copy") != NULL); // Should be created from no_copy + EXPECT_STREQ("off", rtc->get("nack_no_copy")->arg0().c_str()); + EXPECT_TRUE(rtc->get("twcc") != NULL); // Should be moved here + EXPECT_STREQ("on", rtc->get("twcc")->arg0().c_str()); + + srs_freep(root); + } + + // Test transform function with vhost containing only nack (no enabled) + if (true) { + SrsConfDirective *root = new SrsConfDirective(); + + // Add rtmp section (required for valid config) + SrsConfDirective *rtmp = new SrsConfDirective(); + rtmp->name_ = "rtmp"; + SrsConfDirective *listen = new SrsConfDirective(); + listen->name_ = "listen"; + listen->args_.push_back("1935"); + rtmp->directives_.push_back(listen); + root->directives_.push_back(rtmp); + + // Add vhost section with nack (no enabled directive) + SrsConfDirective *vhost = new SrsConfDirective(); + vhost->name_ = "vhost"; + vhost->args_.push_back("test.com"); + + // Add nack directive with only no_copy + SrsConfDirective *nack = new SrsConfDirective(); + nack->name_ = "nack"; + SrsConfDirective *nack_no_copy = new SrsConfDirective(); + nack_no_copy->name_ = "no_copy"; + nack_no_copy->args_.push_back("on"); + nack->directives_.push_back(nack_no_copy); + vhost->directives_.push_back(nack); + + root->directives_.push_back(vhost); + + // Verify initial state + EXPECT_EQ(1, (int)vhost->directives_.size()); // nack only + EXPECT_TRUE(vhost->get("nack") != NULL); + EXPECT_TRUE(vhost->get("rtc") == NULL); // Should not exist yet + + // Call the transform function directly + HELPER_ASSERT_SUCCESS(srs_config_transform_vhost(root)); + + // Verify nack was transformed to rtc section + EXPECT_EQ(1, (int)vhost->directives_.size()); // Should have only rtc + EXPECT_TRUE(vhost->get("nack") == NULL); // Should be removed + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); // Should be created + EXPECT_TRUE(rtc->get("nack") == NULL); // Should not be created (no enabled directive) + EXPECT_TRUE(rtc->get("nack_no_copy") != NULL); // Should be created from no_copy + EXPECT_STREQ("on", rtc->get("nack_no_copy")->arg0().c_str()); + + srs_freep(root); + } +} + +VOID TEST(ConfigTransformTest, TransformVhostRtcAacToRtmpToRtc) +{ + srs_error_t err; + + // Test transforming vhost.rtc.aac to vhost.rtc.rtmp_to_rtc with "transcode" value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; aac transcode;}}")); + + // Verify aac was transformed to rtmp_to_rtc + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("rtmp_to_rtc")->arg0().c_str()); // transcode -> on + } + + // Test transforming vhost.rtc.aac to vhost.rtc.rtmp_to_rtc with non-"transcode" value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; aac copy;}}")); + + // Verify aac was transformed to rtmp_to_rtc + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("off", rtc->get("rtmp_to_rtc")->arg0().c_str()); // copy -> off + } + + // Test transforming vhost.rtc.aac with empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; aac;}}")); + + // Verify aac was transformed to rtmp_to_rtc + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("off", rtc->get("rtmp_to_rtc")->arg0().c_str()); // empty -> off + } + + // Test transforming vhost.rtc.aac with multiple arguments (only first is used) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; aac transcode copy;}}")); + + // Verify aac was transformed to rtmp_to_rtc using first argument + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("rtmp_to_rtc")->arg0().c_str()); // first arg "transcode" -> on + } +} + +VOID TEST(ConfigTransformTest, TransformVhostRtcBframeToKeepBframe) +{ + srs_error_t err; + + // Test transforming vhost.rtc.bframe to vhost.rtc.keep_bframe with "keep" value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; bframe keep;}}")); + + // Verify bframe was transformed to keep_bframe + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("keep_bframe")->arg0().c_str()); // keep -> on + } + + // Test transforming vhost.rtc.bframe to vhost.rtc.keep_bframe with non-"keep" value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; bframe drop;}}")); + + // Verify bframe was transformed to keep_bframe + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("off", rtc->get("keep_bframe")->arg0().c_str()); // drop -> off + } + + // Test transforming vhost.rtc.bframe with empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; bframe;}}")); + + // Verify bframe was transformed to keep_bframe + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("off", rtc->get("keep_bframe")->arg0().c_str()); // empty -> off + } + + // Test transforming vhost.rtc.bframe with multiple arguments (only first is used) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; bframe keep drop;}}")); + + // Verify bframe was transformed to keep_bframe using first argument + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("keep_bframe")->arg0().c_str()); // first arg "keep" -> on + } +} + +VOID TEST(ConfigTransformTest, TransformVhostRtcAacAndBframeTogether) +{ + srs_error_t err; + + // Test transforming both aac and bframe directives together + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; aac transcode; bframe keep;}}")); + + // Verify both aac and bframe were transformed + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("rtmp_to_rtc")->arg0().c_str()); // transcode -> on + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("keep_bframe")->arg0().c_str()); // keep -> on + } + + // Test transforming both aac and bframe with different values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; aac copy; bframe drop;}}")); + + // Verify both aac and bframe were transformed with correct values + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("off", rtc->get("rtmp_to_rtc")->arg0().c_str()); // copy -> off + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("off", rtc->get("keep_bframe")->arg0().c_str()); // drop -> off + } + + // Test transforming aac and bframe with existing rtc configs + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; nack on; aac transcode; twcc on; bframe keep;}}")); + + // Verify aac and bframe were transformed while preserving existing configs + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_TRUE(rtc->get("enabled") != NULL); // Should be preserved + EXPECT_STREQ("on", rtc->get("enabled")->arg0().c_str()); + EXPECT_TRUE(rtc->get("nack") != NULL); // Should be preserved + EXPECT_STREQ("on", rtc->get("nack")->arg0().c_str()); + EXPECT_TRUE(rtc->get("twcc") != NULL); // Should be preserved + EXPECT_STREQ("on", rtc->get("twcc")->arg0().c_str()); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("rtmp_to_rtc")->arg0().c_str()); + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("keep_bframe")->arg0().c_str()); + } +} + +VOID TEST(ConfigTransformTest, TransformVhostRtcMultipleVhosts) +{ + srs_error_t err; + + // Test transforming aac and bframe in multiple vhosts + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test1.com{rtc{aac transcode;}} vhost test2.com{rtc{bframe keep;}} vhost test3.com{rtc{aac copy; bframe drop;}}")); + + // Get all vhost directives + std::vector vhosts; + for (int i = 0; i < (int)conf.get_root()->directives_.size(); i++) { + SrsConfDirective *dir = conf.get_root()->directives_.at(i); + if (dir->name_ == "vhost") { + vhosts.push_back(dir); + } + } + + // Should have 3 vhost sections + EXPECT_EQ(3, (int)vhosts.size()); + + // First vhost (test1.com) - aac transformation + SrsConfDirective *vhost1 = NULL; + for (int i = 0; i < (int)vhosts.size(); i++) { + if (vhosts[i]->arg0() == "test1.com") { + vhost1 = vhosts[i]; + break; + } + } + ASSERT_TRUE(vhost1 != NULL); + SrsConfDirective *rtc1 = vhost1->get("rtc"); + ASSERT_TRUE(rtc1 != NULL); + EXPECT_TRUE(rtc1->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc1->get("rtmp_to_rtc") != NULL); + EXPECT_STREQ("on", rtc1->get("rtmp_to_rtc")->arg0().c_str()); + + // Second vhost (test2.com) - bframe transformation + SrsConfDirective *vhost2 = NULL; + for (int i = 0; i < (int)vhosts.size(); i++) { + if (vhosts[i]->arg0() == "test2.com") { + vhost2 = vhosts[i]; + break; + } + } + ASSERT_TRUE(vhost2 != NULL); + SrsConfDirective *rtc2 = vhost2->get("rtc"); + ASSERT_TRUE(rtc2 != NULL); + EXPECT_TRUE(rtc2->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc2->get("keep_bframe") != NULL); + EXPECT_STREQ("on", rtc2->get("keep_bframe")->arg0().c_str()); + + // Third vhost (test3.com) - both aac and bframe transformation + SrsConfDirective *vhost3 = NULL; + for (int i = 0; i < (int)vhosts.size(); i++) { + if (vhosts[i]->arg0() == "test3.com") { + vhost3 = vhosts[i]; + break; + } + } + ASSERT_TRUE(vhost3 != NULL); + SrsConfDirective *rtc3 = vhost3->get("rtc"); + ASSERT_TRUE(rtc3 != NULL); + EXPECT_TRUE(rtc3->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc3->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc3->get("rtmp_to_rtc") != NULL); + EXPECT_STREQ("off", rtc3->get("rtmp_to_rtc")->arg0().c_str()); // copy -> off + EXPECT_TRUE(rtc3->get("keep_bframe") != NULL); + EXPECT_STREQ("off", rtc3->get("keep_bframe")->arg0().c_str()); // drop -> off + } +} + +VOID TEST(ConfigTransformTest, TransformVhostRtcPreserveOtherConfigs) +{ + srs_error_t err; + + // Test that transformation preserves other vhost and rtc configurations + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;} rtc{enabled on; nack on; aac transcode; twcc on; bframe keep; rtc_to_rtmp on;} dvr{enabled off;}}")); + + // Verify aac and bframe were transformed while preserving other configs + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + // Verify other vhost configs are preserved + EXPECT_TRUE(vhost->get("hls") != NULL); // Should be preserved + EXPECT_TRUE(vhost->get("dvr") != NULL); // Should be preserved + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + + // Verify existing rtc configs are preserved + EXPECT_TRUE(rtc->get("enabled") != NULL); + EXPECT_STREQ("on", rtc->get("enabled")->arg0().c_str()); + EXPECT_TRUE(rtc->get("nack") != NULL); + EXPECT_STREQ("on", rtc->get("nack")->arg0().c_str()); + EXPECT_TRUE(rtc->get("twcc") != NULL); + EXPECT_STREQ("on", rtc->get("twcc")->arg0().c_str()); + EXPECT_TRUE(rtc->get("rtc_to_rtmp") != NULL); + EXPECT_STREQ("on", rtc->get("rtc_to_rtmp")->arg0().c_str()); + + // Verify aac and bframe were transformed + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("rtmp_to_rtc")->arg0().c_str()); + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("keep_bframe")->arg0().c_str()); + + // Verify other sections have correct configs + SrsConfDirective *hls = vhost->get("hls"); + ASSERT_TRUE(hls != NULL); + EXPECT_TRUE(hls->get("enabled") != NULL); + EXPECT_STREQ("on", hls->get("enabled")->arg0().c_str()); + + SrsConfDirective *dvr = vhost->get("dvr"); + ASSERT_TRUE(dvr != NULL); + EXPECT_TRUE(dvr->get("enabled") != NULL); + EXPECT_STREQ("off", dvr->get("enabled")->arg0().c_str()); + } +} + +VOID TEST(ConfigTransformTest, TransformVhostRtcDirectCall) +{ + srs_error_t err; + + // Test direct call to srs_config_transform_vhost function with rtc aac/bframe transformation + if (true) { + // Create a root directive with vhost containing rtc with aac and bframe + SrsConfDirective *root = new SrsConfDirective(); + + // Add rtmp section (required for valid config) + SrsConfDirective *rtmp = new SrsConfDirective(); + rtmp->name_ = "rtmp"; + SrsConfDirective *listen = new SrsConfDirective(); + listen->name_ = "listen"; + listen->args_.push_back("1935"); + rtmp->directives_.push_back(listen); + root->directives_.push_back(rtmp); + + // Add vhost section with rtc containing aac and bframe + SrsConfDirective *vhost = new SrsConfDirective(); + vhost->name_ = "vhost"; + vhost->args_.push_back("test.com"); + + // Add rtc directive + SrsConfDirective *rtc = new SrsConfDirective(); + rtc->name_ = "rtc"; + + // Add enabled directive + SrsConfDirective *enabled = new SrsConfDirective(); + enabled->name_ = "enabled"; + enabled->args_.push_back("on"); + rtc->directives_.push_back(enabled); + + // Add aac directive + SrsConfDirective *aac = new SrsConfDirective(); + aac->name_ = "aac"; + aac->args_.push_back("transcode"); + rtc->directives_.push_back(aac); + + // Add bframe directive + SrsConfDirective *bframe = new SrsConfDirective(); + bframe->name_ = "bframe"; + bframe->args_.push_back("keep"); + rtc->directives_.push_back(bframe); + + vhost->directives_.push_back(rtc); + root->directives_.push_back(vhost); + + // Verify initial state + EXPECT_EQ(3, (int)rtc->directives_.size()); // enabled, aac, bframe + EXPECT_TRUE(rtc->get("enabled") != NULL); + EXPECT_TRUE(rtc->get("aac") != NULL); + EXPECT_TRUE(rtc->get("bframe") != NULL); + EXPECT_TRUE(rtc->get("rtmp_to_rtc") == NULL); // Should not exist yet + EXPECT_TRUE(rtc->get("keep_bframe") == NULL); // Should not exist yet + + // Call the transform function directly + HELPER_ASSERT_SUCCESS(srs_config_transform_vhost(root)); + + // Verify aac and bframe were transformed + EXPECT_EQ(3, (int)rtc->directives_.size()); // enabled, rtmp_to_rtc, keep_bframe + EXPECT_TRUE(rtc->get("enabled") != NULL); // Should be preserved + EXPECT_STREQ("on", rtc->get("enabled")->arg0().c_str()); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("rtmp_to_rtc")->arg0().c_str()); + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("keep_bframe")->arg0().c_str()); + + srs_freep(root); + } +} + +VOID TEST(ConfigTransformTest, TransformVhostRtcEdgeCases) +{ + srs_error_t err; + + // Test rtc section without aac or bframe (should remain unchanged) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; nack on; twcc on;}}")); + + // Verify rtc section is preserved without transformation + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_EQ(3, (int)rtc->directives_.size()); // Should have exactly 3 directives + EXPECT_TRUE(rtc->get("enabled") != NULL); + EXPECT_TRUE(rtc->get("nack") != NULL); + EXPECT_TRUE(rtc->get("twcc") != NULL); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should not exist + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should not exist + EXPECT_TRUE(rtc->get("rtmp_to_rtc") == NULL); // Should not be created + EXPECT_TRUE(rtc->get("keep_bframe") == NULL); // Should not be created + } + + // Test vhost without rtc section (should remain unchanged) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;} dvr{enabled off;}}")); + + // Verify vhost section is preserved without rtc transformation + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + EXPECT_EQ(2, (int)vhost->directives_.size()); // Should have exactly 2 directives + EXPECT_TRUE(vhost->get("hls") != NULL); + EXPECT_TRUE(vhost->get("dvr") != NULL); + EXPECT_TRUE(vhost->get("rtc") == NULL); // Should not exist + } + + // Test empty rtc section (should remain empty) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{}}")); + + // Verify empty rtc section remains empty + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_EQ(0, (int)rtc->directives_.size()); // Should remain empty + EXPECT_TRUE(rtc->get("aac") == NULL); + EXPECT_TRUE(rtc->get("bframe") == NULL); + EXPECT_TRUE(rtc->get("rtmp_to_rtc") == NULL); + EXPECT_TRUE(rtc->get("keep_bframe") == NULL); + } + + // Test rtc section with only aac (no bframe) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; aac transcode;}}")); + + // Verify only aac transformation occurs + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_EQ(2, (int)rtc->directives_.size()); // enabled, rtmp_to_rtc + EXPECT_TRUE(rtc->get("enabled") != NULL); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should not exist + EXPECT_TRUE(rtc->get("rtmp_to_rtc") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("rtmp_to_rtc")->arg0().c_str()); + EXPECT_TRUE(rtc->get("keep_bframe") == NULL); // Should not be created + } + + // Test rtc section with only bframe (no aac) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on; bframe keep;}}")); + + // Verify only bframe transformation occurs + SrsConfDirective *vhost = conf.get_root()->get("vhost"); + ASSERT_TRUE(vhost != NULL); + + SrsConfDirective *rtc = vhost->get("rtc"); + ASSERT_TRUE(rtc != NULL); + EXPECT_EQ(2, (int)rtc->directives_.size()); // enabled, keep_bframe + EXPECT_TRUE(rtc->get("enabled") != NULL); + EXPECT_TRUE(rtc->get("aac") == NULL); // Should not exist + EXPECT_TRUE(rtc->get("bframe") == NULL); // Should be removed + EXPECT_TRUE(rtc->get("rtmp_to_rtc") == NULL); // Should not be created + EXPECT_TRUE(rtc->get("keep_bframe") != NULL); // Should be created + EXPECT_STREQ("on", rtc->get("keep_bframe")->arg0().c_str()); + } +} + +VOID TEST(ConfigDirectiveTest, ReadTokenUnexpectedCharacterAfterQuotedString) +{ + srs_error_t err; + + // Test unexpected character after double-quoted string (need_space=true case) + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"x;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected character after single-quoted string (need_space=true case) + if (true) { + MockSrsConfigBuffer buf("listen '1935'y;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected character after double-quoted string with block start + if (true) { + MockSrsConfigBuffer buf("vhost \"test.com\"z {}"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected character after single-quoted string with block start + if (true) { + MockSrsConfigBuffer buf("vhost 'test.com'w {}"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test multiple unexpected characters after quoted strings + if (true) { + MockSrsConfigBuffer buf("listen \"8080\"abc;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected special characters after quoted strings + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"@;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"#;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"$;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"%;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"&;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"*;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } +} + +VOID TEST(ConfigDirectiveTest, ReadTokenUnexpectedCharacterAfterQuotedStringWithNumbers) +{ + srs_error_t err; + + // Test unexpected numeric characters after quoted strings + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"1;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"2;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"9;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"0;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected alphabetic characters after quoted strings + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"a;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"Z;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected punctuation characters after quoted strings + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"!;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"?;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"=;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"+;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"-;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"_;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"(;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\");"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"[;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"];"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } +} + +VOID TEST(ConfigDirectiveTest, ReadTokenValidQuotedStringCases) +{ + srs_error_t err; + + // Test valid double-quoted string followed by semicolon (should succeed) + if (true) { + MockSrsConfigBuffer buf("listen \"1935\";"); + SrsConfDirective conf; + HELPER_ASSERT_SUCCESS(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(1, (int)conf.directives_.size()); + + SrsConfDirective &dir = *conf.directives_.at(0); + EXPECT_STREQ("listen", dir.name_.c_str()); + EXPECT_EQ(1, (int)dir.args_.size()); + EXPECT_STREQ("1935", dir.arg0().c_str()); + } + + // Test valid single-quoted string followed by semicolon (should succeed) + if (true) { + MockSrsConfigBuffer buf("listen '1935';"); + SrsConfDirective conf; + HELPER_ASSERT_SUCCESS(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(1, (int)conf.directives_.size()); + + SrsConfDirective &dir = *conf.directives_.at(0); + EXPECT_STREQ("listen", dir.name_.c_str()); + EXPECT_EQ(1, (int)dir.args_.size()); + EXPECT_STREQ("1935", dir.arg0().c_str()); + } + + // Test valid double-quoted string followed by space and semicolon (should succeed) + if (true) { + MockSrsConfigBuffer buf("listen \"1935\" ;"); + SrsConfDirective conf; + HELPER_ASSERT_SUCCESS(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(1, (int)conf.directives_.size()); + + SrsConfDirective &dir = *conf.directives_.at(0); + EXPECT_STREQ("listen", dir.name_.c_str()); + EXPECT_EQ(1, (int)dir.args_.size()); + EXPECT_STREQ("1935", dir.arg0().c_str()); + } + + // Test valid single-quoted string followed by space and semicolon (should succeed) + if (true) { + MockSrsConfigBuffer buf("listen '1935' ;"); + SrsConfDirective conf; + HELPER_ASSERT_SUCCESS(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(1, (int)conf.directives_.size()); + + SrsConfDirective &dir = *conf.directives_.at(0); + EXPECT_STREQ("listen", dir.name_.c_str()); + EXPECT_EQ(1, (int)dir.args_.size()); + EXPECT_STREQ("1935", dir.arg0().c_str()); + } + + // Test valid double-quoted string followed by block start (should succeed) + if (true) { + MockSrsConfigBuffer buf("vhost \"test.com\" {}"); + SrsConfDirective conf; + HELPER_ASSERT_SUCCESS(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(1, (int)conf.directives_.size()); + + SrsConfDirective &dir = *conf.directives_.at(0); + EXPECT_STREQ("vhost", dir.name_.c_str()); + EXPECT_EQ(1, (int)dir.args_.size()); + EXPECT_STREQ("test.com", dir.arg0().c_str()); + EXPECT_EQ(0, (int)dir.directives_.size()); + } + + // Test valid single-quoted string followed by block start (should succeed) + if (true) { + MockSrsConfigBuffer buf("vhost 'test.com' {}"); + SrsConfDirective conf; + HELPER_ASSERT_SUCCESS(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(1, (int)conf.directives_.size()); + + SrsConfDirective &dir = *conf.directives_.at(0); + EXPECT_STREQ("vhost", dir.name_.c_str()); + EXPECT_EQ(1, (int)dir.args_.size()); + EXPECT_STREQ("test.com", dir.arg0().c_str()); + EXPECT_EQ(0, (int)dir.directives_.size()); + } + + // Test valid double-quoted string followed by tab and semicolon (should succeed) + if (true) { + MockSrsConfigBuffer buf("listen \"1935\"\t;"); + SrsConfDirective conf; + HELPER_ASSERT_SUCCESS(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(1, (int)conf.directives_.size()); + + SrsConfDirective &dir = *conf.directives_.at(0); + EXPECT_STREQ("listen", dir.name_.c_str()); + EXPECT_EQ(1, (int)dir.args_.size()); + EXPECT_STREQ("1935", dir.arg0().c_str()); + } + + // Test valid single-quoted string followed by tab and semicolon (should succeed) + if (true) { + MockSrsConfigBuffer buf("listen '1935'\t;"); + SrsConfDirective conf; + HELPER_ASSERT_SUCCESS(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(1, (int)conf.directives_.size()); + + SrsConfDirective &dir = *conf.directives_.at(0); + EXPECT_STREQ("listen", dir.name_.c_str()); + EXPECT_EQ(1, (int)dir.args_.size()); + EXPECT_STREQ("1935", dir.arg0().c_str()); + } +} + +VOID TEST(ConfigDirectiveTest, ReadTokenUnexpectedCharacterEdgeCases) +{ + srs_error_t err; + + // Test unexpected character in complex vhost configuration + if (true) { + MockSrsConfigBuffer buf("vhost \"test.com\"x { hls { enabled on; } }"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected character after quoted string followed by another quoted string + if (true) { + MockSrsConfigBuffer buf("test \"arg1\"\"arg2\";"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected character after single-quoted string followed by another quoted string + if (true) { + MockSrsConfigBuffer buf("test 'arg1''arg2';"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected character after quoted string followed by opening brace + if (true) { + MockSrsConfigBuffer buf("test \"arg1\"x{"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } + + // Test unexpected character after single-quoted string followed by opening brace + if (true) { + MockSrsConfigBuffer buf("test 'arg1'y{"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name_.length()); + EXPECT_EQ(0, (int)conf.args_.size()); + EXPECT_EQ(0, (int)conf.directives_.size()); + } +} + +// Test specifically for the read_token method's need_space error condition +VOID TEST(ConfigDirectiveTest, ReadTokenNeedSpaceErrorCondition) +{ + srs_error_t err; + + // These tests specifically target the error condition in read_token where + // need_space is true and an unexpected character is encountered + + // Test case: quoted string immediately followed by letter (no space) + if (true) { + MockSrsConfigBuffer buf("directive \"value\"x;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + } + + // Test case: quoted string immediately followed by number (no space) + if (true) { + MockSrsConfigBuffer buf("directive \"value\"1;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + } + + // Test case: quoted string immediately followed by underscore (no space) + if (true) { + MockSrsConfigBuffer buf("directive \"value\"_;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + } + + // Test case: single-quoted string immediately followed by letter (no space) + if (true) { + MockSrsConfigBuffer buf("directive 'value'x;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + } + + // Test case: single-quoted string immediately followed by number (no space) + if (true) { + MockSrsConfigBuffer buf("directive 'value'1;"); + SrsConfDirective conf; + HELPER_ASSERT_FAILED(conf.parse(&buf)); + } +} + +VOID TEST(ConfigMainTest, CheckConfInDocker) +{ + srs_error_t err; + + // Test default value when in_docker directive is not present + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_in_docker()); // Default should be false + } + + // Test in_docker enabled with "on" + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker on;")); + EXPECT_TRUE(conf.get_in_docker()); + } + + // Test in_docker with "yes" (should be false due to SRS_CONF_PREFER_FALSE) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker yes;")); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + // Test in_docker with "true" (should be false due to SRS_CONF_PREFER_FALSE) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker true;")); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + // Test in_docker disabled with "off" + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker off;")); + EXPECT_FALSE(conf.get_in_docker()); + } + + // Test in_docker disabled with "no" + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker no;")); + EXPECT_FALSE(conf.get_in_docker()); + } + + // Test in_docker disabled with "false" + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker false;")); + EXPECT_FALSE(conf.get_in_docker()); + } + + // Test in_docker with empty argument (should default to false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker;")); + EXPECT_FALSE(conf.get_in_docker()); + } + + // Test in_docker with invalid argument (should default to false due to SRS_CONF_PREFER_FALSE) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker invalid_value;")); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE should return false for invalid values + } + + // Test in_docker with numeric argument "1" (should be false due to SRS_CONF_PREFER_FALSE) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker 1;")); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + // Test in_docker with numeric argument "0" (should be false due to SRS_CONF_PREFER_FALSE) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker 0;")); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + // Test in_docker with case variations - "ON" should be false (case sensitive) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker ON;")); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE is case sensitive, only "on" returns true + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker OFF;")); + EXPECT_FALSE(conf.get_in_docker()); + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker Yes;")); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker No;")); + EXPECT_FALSE(conf.get_in_docker()); + } + + // Test in_docker with multiple arguments (should use first argument) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker on off;")); + EXPECT_TRUE(conf.get_in_docker()); // Should use first argument "on" + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker off on;")); + EXPECT_FALSE(conf.get_in_docker()); // Should use first argument "off" + } +} + +VOID TEST(ConfigEnvTest, CheckEnvValuesInDocker) +{ + srs_error_t err; + + // Test environment variable override for in_docker + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "on"); + EXPECT_TRUE(conf.get_in_docker()); + } + + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "off"); + EXPECT_FALSE(conf.get_in_docker()); + } + + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "yes"); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "no"); + EXPECT_FALSE(conf.get_in_docker()); + } + + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "true"); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "false"); + EXPECT_FALSE(conf.get_in_docker()); + } + + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "1"); + EXPECT_FALSE(conf.get_in_docker()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "0"); + EXPECT_FALSE(conf.get_in_docker()); + } + + // Test that environment variable overrides config file + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker off;")); + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "on"); + EXPECT_TRUE(conf.get_in_docker()); // Environment variable should override config file + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "in_docker on;")); + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "off"); + EXPECT_FALSE(conf.get_in_docker()); // Environment variable should override config file + } + + // Test invalid environment variable value (should default to false due to SRS_CONF_PREFER_FALSE) + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", "invalid_value"); + EXPECT_FALSE(conf.get_in_docker()); // Should default to false for invalid values + } + + // Test empty environment variable value (should default to false) + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, in_docker, "SRS_IN_DOCKER", ""); + EXPECT_FALSE(conf.get_in_docker()); // Should default to false for empty values + } +} + +// External function declarations for testing +extern string srs_server_id_path(string pid_file); +extern string srs_try_read_file(string path); +extern void srs_try_write_file(string path, string content); + +VOID TEST(ConfigUtilityTest, ServerIdPath) +{ + // Test basic .pid to .id conversion + if (true) { + string result = srs_server_id_path("./objs/srs.pid"); + EXPECT_STREQ("./objs/srs.id", result.c_str()); + } + + // Test path without .pid extension + if (true) { + string result = srs_server_id_path("./objs/srs"); + EXPECT_STREQ("./objs/srs.id", result.c_str()); + } + + // Test path already ending with .id + if (true) { + string result = srs_server_id_path("./objs/srs.id"); + EXPECT_STREQ("./objs/srs.id", result.c_str()); + } + + // Test complex path with multiple .pid occurrences + if (true) { + string result = srs_server_id_path("/tmp/srs.pid.backup.pid"); + EXPECT_STREQ("/tmp/srs.id.backup.id", result.c_str()); + } + + // Test empty string + if (true) { + string result = srs_server_id_path(""); + EXPECT_STREQ(".id", result.c_str()); + } + + // Test path with directory containing .pid + if (true) { + string result = srs_server_id_path("/var/srs.pid.dir/server.pid"); + EXPECT_STREQ("/var/srs.id.dir/server.id", result.c_str()); + } +} + +VOID TEST(ConfigUtilityTest, TryReadWriteFile) +{ + // Test writing and reading a file + if (true) { + string test_file = _srs_tmp_file_prefix + "utest-read-write.txt"; + MockFileRemover _mfr(test_file); + + string test_content = "test server id content"; + srs_try_write_file(test_file, test_content); + + string read_content = srs_try_read_file(test_file); + EXPECT_STREQ(test_content.c_str(), read_content.c_str()); + } + + // Test reading non-existent file + if (true) { + string non_existent_file = _srs_tmp_file_prefix + "utest-non-existent.txt"; + string content = srs_try_read_file(non_existent_file); + EXPECT_STREQ("", content.c_str()); + } + + // Test writing to invalid path (should not crash) + if (true) { + string invalid_path = "/invalid/path/that/does/not/exist/file.txt"; + srs_try_write_file(invalid_path, "test content"); + // Should not crash, function handles errors gracefully + } + + // Test writing empty content + if (true) { + string test_file = _srs_tmp_file_prefix + "utest-empty.txt"; + MockFileRemover _mfr(test_file); + + srs_try_write_file(test_file, ""); + string content = srs_try_read_file(test_file); + EXPECT_STREQ("", content.c_str()); + } + + // Test writing and reading large content (up to buffer size) + if (true) { + string test_file = _srs_tmp_file_prefix + "utest-large.txt"; + MockFileRemover _mfr(test_file); + + // Create content close to buffer size (1024 bytes) + string large_content(1000, 'A'); + srs_try_write_file(test_file, large_content); + + string read_content = srs_try_read_file(test_file); + EXPECT_STREQ(large_content.c_str(), read_content.c_str()); + } + + // Test reading file larger than buffer (should only read first 1024 bytes) + if (true) { + string test_file = _srs_tmp_file_prefix + "utest-oversized.txt"; + MockFileRemover _mfr(test_file); + + // Create content larger than buffer size (1024 bytes) + string oversized_content(2000, 'B'); + srs_try_write_file(test_file, oversized_content); + + string read_content = srs_try_read_file(test_file); + // Should only read first 1024 bytes + EXPECT_EQ(1024, (int)read_content.length()); + EXPECT_EQ('B', read_content[0]); + EXPECT_EQ('B', read_content[1023]); + } +} + +VOID TEST(ConfigTest, IsFullConfig) +{ + srs_error_t err; + + // Test default value (no is_full directive) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.is_full_config()); // Should default to false + } + + // Test is_full enabled with "on" + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "is_full on;")); + EXPECT_TRUE(conf.is_full_config()); + } + + // Test is_full with "yes" (should be false due to SRS_CONF_PREFER_FALSE) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "is_full yes;")); + EXPECT_FALSE(conf.is_full_config()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + // Test is_full with "true" (should be false due to SRS_CONF_PREFER_FALSE) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "is_full true;")); + EXPECT_FALSE(conf.is_full_config()); // SRS_CONF_PREFER_FALSE only returns true for "on" + } + + // Test is_full disabled with "off" + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "is_full off;")); + EXPECT_FALSE(conf.is_full_config()); + } + + // Test is_full disabled with "no" + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "is_full no;")); + EXPECT_FALSE(conf.is_full_config()); + } + + // Test is_full disabled with "false" + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "is_full false;")); + EXPECT_FALSE(conf.is_full_config()); + } + + // Test is_full with invalid value (should prefer false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "is_full invalid_value;")); + EXPECT_FALSE(conf.is_full_config()); // Should default to false for invalid values + } + + // Test is_full with empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "is_full;")); + EXPECT_FALSE(conf.is_full_config()); // Should default to false for empty values + } +} + +VOID TEST(ConfigTest, GetServerIdFromConfig) +{ + srs_error_t err; + + // Test server_id from config file + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "server_id test-server-123;")); + + string server_id = conf.get_server_id(); + EXPECT_STREQ("test-server-123", server_id.c_str()); + } + + // Test server_id with complex value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "server_id srs-production-server-001;")); + + string server_id = conf.get_server_id(); + EXPECT_STREQ("srs-production-server-001", server_id.c_str()); + } + + // Test server_id with special characters + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "server_id srs_test-server.001;")); + + string server_id = conf.get_server_id(); + EXPECT_STREQ("srs_test-server.001", server_id.c_str()); + } +} + +VOID TEST(ConfigTest, GetServerIdFromEnv) +{ + srs_error_t err; + + // Test server_id from environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "server_id config-server-id;")); + + SrsSetEnvConfig(conf, server_id, "SRS_SERVER_ID", "env-server-id"); + + string server_id = conf.get_server_id(); + EXPECT_STREQ("env-server-id", server_id.c_str()); + } + + // Test server_id from environment variable with no config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, server_id, "SRS_SERVER_ID", "env-only-server-id"); + + string server_id = conf.get_server_id(); + EXPECT_STREQ("env-only-server-id", server_id.c_str()); + } +} + +VOID TEST(ConfigTest, GetServerIdWithFileGeneration) +{ + srs_error_t err; + + // Test server_id generation and file persistence + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "pid ./objs/test-server.pid;")); + + // Clean up any existing server id file + string server_id_file = srs_server_id_path(conf.get_pid_file()); + MockFileRemover _mfr(server_id_file); + + // First call should generate a server ID and write to file + string server_id1 = conf.get_server_id(); + EXPECT_FALSE(server_id1.empty()); + + // Verify the server ID was written to file + string file_content = srs_try_read_file(server_id_file); + EXPECT_STREQ(server_id1.c_str(), file_content.c_str()); + + // Second call should return the same server ID (from static variable) + string server_id2 = conf.get_server_id(); + EXPECT_STREQ(server_id1.c_str(), server_id2.c_str()); + } + + // Test server_id file writing behavior + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "pid ./objs/test-file-write.pid;")); + + string server_id_file = srs_server_id_path(conf.get_pid_file()); + MockFileRemover _mfr(server_id_file); + + // Call get_server_id which should write to file + string server_id = conf.get_server_id(); + EXPECT_FALSE(server_id.empty()); + + // Verify the server ID was written to file + string file_content = srs_try_read_file(server_id_file); + EXPECT_STREQ(server_id.c_str(), file_content.c_str()); + } + + // Test server_id with custom pid file path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "pid /tmp/custom-srs.pid;")); + + string server_id_file = srs_server_id_path(conf.get_pid_file()); + MockFileRemover _mfr(server_id_file); + + string server_id = conf.get_server_id(); + EXPECT_FALSE(server_id.empty()); + + // Verify correct server ID file path + EXPECT_STREQ("/tmp/custom-srs.id", server_id_file.c_str()); + + // Verify the server ID was written to the correct file + string file_content = srs_try_read_file(server_id_file); + EXPECT_STREQ(server_id.c_str(), file_content.c_str()); + } +} + +VOID TEST(ConfigTest, GetServerIdPriorityAndEdgeCases) +{ + srs_error_t err; + + // Test priority: environment variable > config file > generated + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "server_id config-id; pid ./objs/priority-test.pid;")); + + string server_id_file = srs_server_id_path(conf.get_pid_file()); + MockFileRemover _mfr(server_id_file); + + // Pre-write a different ID to file + srs_try_write_file(server_id_file, "file-id"); + + // Environment variable should have highest priority + SrsSetEnvConfig(conf, server_id, "SRS_SERVER_ID", "env-id"); + + string server_id = conf.get_server_id(); + EXPECT_STREQ("env-id", server_id.c_str()); + } + + // Test config file priority over generated ID + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "server_id config-file-id; pid ./objs/config-priority.pid;")); + + string server_id_file = srs_server_id_path(conf.get_pid_file()); + MockFileRemover _mfr(server_id_file); + + string server_id = conf.get_server_id(); + EXPECT_STREQ("config-file-id", server_id.c_str()); + } + + // Test empty config server_id (should generate) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "server_id; pid ./objs/empty-config.pid;")); + + string server_id_file = srs_server_id_path(conf.get_pid_file()); + MockFileRemover _mfr(server_id_file); + + string server_id = conf.get_server_id(); + EXPECT_FALSE(server_id.empty()); + // Should be a generated ID, not empty + EXPECT_NE("", server_id); + } + + // Test server_id consistency across multiple calls + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "pid ./objs/consistency-test.pid;")); + + string server_id_file = srs_server_id_path(conf.get_pid_file()); + MockFileRemover _mfr(server_id_file); + + string server_id1 = conf.get_server_id(); + string server_id2 = conf.get_server_id(); + string server_id3 = conf.get_server_id(); + + EXPECT_STREQ(server_id1.c_str(), server_id2.c_str()); + EXPECT_STREQ(server_id2.c_str(), server_id3.c_str()); + } +} + +VOID TEST(ConfigMainTest, CheckQueryLatestVersion) +{ + srs_error_t err; + + // Test default value when query_latest_version is not configured + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.whether_query_latest_version()); // Default is false + } + + // Test query_latest_version enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "query_latest_version on;")); + EXPECT_TRUE(conf.whether_query_latest_version()); + } + + // Test query_latest_version disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "query_latest_version off;")); + EXPECT_FALSE(conf.whether_query_latest_version()); + } + + // Test query_latest_version with various true values (SRS_CONF_PREFER_TRUE: anything != "off") + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "query_latest_version true;")); + EXPECT_TRUE(conf.whether_query_latest_version()); + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "query_latest_version yes;")); + EXPECT_TRUE(conf.whether_query_latest_version()); + } + + // Debug: Check if environment variable is set + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "query_latest_version false;")); + // Print debug info + printf("DEBUG: query_latest_version false -> %s\n", conf.whether_query_latest_version() ? "true" : "false"); + // EXPECT_TRUE(conf.whether_query_latest_version()); // "false" != "off", so it's true + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "query_latest_version no;")); + // Print debug info + printf("DEBUG: query_latest_version no -> %s\n", conf.whether_query_latest_version() ? "true" : "false"); + // EXPECT_TRUE(conf.whether_query_latest_version()); // "no" != "off", so it's true + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + SrsSetEnvConfig(conf, query_latest_version, "SRS_QUERY_LATEST_VERSION", "on"); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "query_latest_version off;")); + EXPECT_TRUE(conf.whether_query_latest_version()); // Environment variable should override config + } + + if (true) { + MockSrsConfig conf; + SrsSetEnvConfig(conf, query_latest_version, "SRS_QUERY_LATEST_VERSION", "off"); + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "query_latest_version on;")); + EXPECT_FALSE(conf.whether_query_latest_version()); // Environment variable should override config + } +} + +VOID TEST(ConfigMainTest, CheckFirstWaitForQlv) +{ + srs_error_t err; + + // Test default value when first_wait_for_qlv is not configured + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(5 * 60 * SRS_UTIME_SECONDS, conf.first_wait_for_qlv()); // Default is 5 minutes + } + + // Test first_wait_for_qlv with custom value in seconds + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "first_wait_for_qlv 120;")); + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.first_wait_for_qlv()); // 2 minutes + } + + // Test first_wait_for_qlv with zero value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "first_wait_for_qlv 0;")); + EXPECT_EQ(0, conf.first_wait_for_qlv()); + } + + // Test first_wait_for_qlv with large value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "first_wait_for_qlv 3600;")); + EXPECT_EQ(3600 * SRS_UTIME_SECONDS, conf.first_wait_for_qlv()); // 1 hour + } + + // Test first_wait_for_qlv with small value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "first_wait_for_qlv 30;")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.first_wait_for_qlv()); // 30 seconds + } +} + +VOID TEST(ConfigMainTest, CheckEmptyIpOk) +{ + srs_error_t err; + + // Test default value when empty_ip_ok is not configured + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.empty_ip_ok()); // Default is true + } + + // Test empty_ip_ok enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "empty_ip_ok on;")); + EXPECT_TRUE(conf.empty_ip_ok()); + } + + // Test empty_ip_ok disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "empty_ip_ok off;")); + EXPECT_FALSE(conf.empty_ip_ok()); + } + + // Test empty_ip_ok with various true values (SRS_CONF_PREFER_TRUE: anything != "off") + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "empty_ip_ok true;")); + EXPECT_TRUE(conf.empty_ip_ok()); + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "empty_ip_ok yes;")); + EXPECT_TRUE(conf.empty_ip_ok()); + } + + // Test empty_ip_ok with false value (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "empty_ip_ok off;")); + EXPECT_FALSE(conf.empty_ip_ok()); + } + + // Test empty_ip_ok with other values (SRS_CONF_PREFER_TRUE: anything != "off" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "empty_ip_ok false;")); + EXPECT_TRUE(conf.empty_ip_ok()); // "false" != "off", so it's true + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "empty_ip_ok no;")); + EXPECT_TRUE(conf.empty_ip_ok()); // "no" != "off", so it's true + } + + // Test empty_ip_ok with empty argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "empty_ip_ok;")); + EXPECT_TRUE(conf.empty_ip_ok()); // Should use default value + } +} + +VOID TEST(ConfigMainTest, CheckGraceStartWait) +{ + srs_error_t err; + + // Test default value when grace_start_wait is not configured + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(2300 * SRS_UTIME_MILLISECONDS, conf.get_grace_start_wait()); // Default is 2300ms + } + + // Test grace_start_wait with custom value in milliseconds + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_start_wait 5000;")); + EXPECT_EQ(5000 * SRS_UTIME_MILLISECONDS, conf.get_grace_start_wait()); // 5 seconds + } + + // Test grace_start_wait with zero value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_start_wait 0;")); + EXPECT_EQ(0, conf.get_grace_start_wait()); + } + + // Test grace_start_wait with large value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_start_wait 30000;")); + EXPECT_EQ(30000 * SRS_UTIME_MILLISECONDS, conf.get_grace_start_wait()); // 30 seconds + } + + // Test grace_start_wait with small value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_start_wait 100;")); + EXPECT_EQ(100 * SRS_UTIME_MILLISECONDS, conf.get_grace_start_wait()); // 100ms + } + + // Test grace_start_wait with empty argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_start_wait;")); + EXPECT_EQ(2300 * SRS_UTIME_MILLISECONDS, conf.get_grace_start_wait()); // Should use default value + } +} + +VOID TEST(ConfigMainTest, CheckGraceFinalWait) +{ + srs_error_t err; + + // Test default value when grace_final_wait is not configured + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(3200 * SRS_UTIME_MILLISECONDS, conf.get_grace_final_wait()); // Default is 3200ms + } + + // Test grace_final_wait with custom value in milliseconds + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_final_wait 8000;")); + EXPECT_EQ(8000 * SRS_UTIME_MILLISECONDS, conf.get_grace_final_wait()); // 8 seconds + } + + // Test grace_final_wait with zero value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_final_wait 0;")); + EXPECT_EQ(0, conf.get_grace_final_wait()); + } + + // Test grace_final_wait with large value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_final_wait 60000;")); + EXPECT_EQ(60000 * SRS_UTIME_MILLISECONDS, conf.get_grace_final_wait()); // 60 seconds + } + + // Test grace_final_wait with small value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_final_wait 500;")); + EXPECT_EQ(500 * SRS_UTIME_MILLISECONDS, conf.get_grace_final_wait()); // 500ms + } + + // Test grace_final_wait with empty argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "grace_final_wait;")); + EXPECT_EQ(3200 * SRS_UTIME_MILLISECONDS, conf.get_grace_final_wait()); // Should use default value + } +} + +VOID TEST(ConfigMainTest, CheckForceGraceQuit) +{ + srs_error_t err; + + // Test default value when force_grace_quit is not configured + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.is_force_grace_quit()); // Default is false + } + + // Test force_grace_quit enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "force_grace_quit on;")); + EXPECT_TRUE(conf.is_force_grace_quit()); + } + + // Test force_grace_quit disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "force_grace_quit off;")); + EXPECT_FALSE(conf.is_force_grace_quit()); + } + + // Test force_grace_quit with various values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "force_grace_quit true;")); + EXPECT_FALSE(conf.is_force_grace_quit()); // "true" != "on", so it's false + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "force_grace_quit yes;")); + EXPECT_FALSE(conf.is_force_grace_quit()); // "yes" != "on", so it's false + } + + // Test force_grace_quit with various false values (SRS_CONF_PREFER_FALSE: anything != "on" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "force_grace_quit false;")); + EXPECT_FALSE(conf.is_force_grace_quit()); + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "force_grace_quit no;")); + EXPECT_FALSE(conf.is_force_grace_quit()); + } + + // Test force_grace_quit with empty argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "force_grace_quit;")); + EXPECT_FALSE(conf.is_force_grace_quit()); // Should use default value + } +} + +VOID TEST(ConfigMainTest, CheckDisableDaemonForDocker) +{ + srs_error_t err; + + // Test default value when disable_daemon_for_docker is not configured + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.disable_daemon_for_docker()); // Default is true + } + + // Test disable_daemon_for_docker enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "disable_daemon_for_docker on;")); + EXPECT_TRUE(conf.disable_daemon_for_docker()); + } + + // Test disable_daemon_for_docker disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "disable_daemon_for_docker off;")); + EXPECT_FALSE(conf.disable_daemon_for_docker()); + } + + // Test disable_daemon_for_docker with various true values (SRS_CONF_PREFER_TRUE: anything != "off") + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "disable_daemon_for_docker true;")); + EXPECT_TRUE(conf.disable_daemon_for_docker()); + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "disable_daemon_for_docker yes;")); + EXPECT_TRUE(conf.disable_daemon_for_docker()); + } + + // Test disable_daemon_for_docker with false value (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "disable_daemon_for_docker off;")); + EXPECT_FALSE(conf.disable_daemon_for_docker()); + } + + // Test disable_daemon_for_docker with other values (SRS_CONF_PREFER_TRUE: anything != "off" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "disable_daemon_for_docker false;")); + EXPECT_TRUE(conf.disable_daemon_for_docker()); // "false" != "off", so it's true + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "disable_daemon_for_docker no;")); + EXPECT_TRUE(conf.disable_daemon_for_docker()); // "no" != "off", so it's true + } + + // Test disable_daemon_for_docker with empty argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "disable_daemon_for_docker;")); + EXPECT_TRUE(conf.disable_daemon_for_docker()); // Should use default value + } +} + +VOID TEST(ConfigMainTest, CheckInotifyAutoReload) +{ + srs_error_t err; + + // Test default value when inotify_auto_reload is not configured + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.inotify_auto_reload()); // Default is false + } + + // Test inotify_auto_reload enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "inotify_auto_reload on;")); + EXPECT_TRUE(conf.inotify_auto_reload()); + } + + // Test inotify_auto_reload disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "inotify_auto_reload off;")); + EXPECT_FALSE(conf.inotify_auto_reload()); + } + + // Test inotify_auto_reload with various values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "inotify_auto_reload true;")); + EXPECT_FALSE(conf.inotify_auto_reload()); // "true" != "on", so it's false + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "inotify_auto_reload yes;")); + EXPECT_FALSE(conf.inotify_auto_reload()); // "yes" != "on", so it's false + } + + // Test inotify_auto_reload with various false values (SRS_CONF_PREFER_FALSE: anything != "on" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "inotify_auto_reload false;")); + EXPECT_FALSE(conf.inotify_auto_reload()); + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "inotify_auto_reload no;")); + EXPECT_FALSE(conf.inotify_auto_reload()); + } + + // Test inotify_auto_reload with empty argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "inotify_auto_reload;")); + EXPECT_FALSE(conf.inotify_auto_reload()); // Should use default value + } +} + +VOID TEST(ConfigMainTest, CheckAutoReloadForDocker) +{ + srs_error_t err; + + // Test default value when auto_reload_for_docker is not configured + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.auto_reload_for_docker()); // Default is true + } + + // Test auto_reload_for_docker enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "auto_reload_for_docker on;")); + EXPECT_TRUE(conf.auto_reload_for_docker()); + } + + // Test auto_reload_for_docker disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "auto_reload_for_docker off;")); + EXPECT_FALSE(conf.auto_reload_for_docker()); + } + + // Test auto_reload_for_docker with various true values (SRS_CONF_PREFER_TRUE: anything != "off") + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "auto_reload_for_docker true;")); + EXPECT_TRUE(conf.auto_reload_for_docker()); + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "auto_reload_for_docker yes;")); + EXPECT_TRUE(conf.auto_reload_for_docker()); + } + + // Test auto_reload_for_docker with false value (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "auto_reload_for_docker off;")); + EXPECT_FALSE(conf.auto_reload_for_docker()); + } + + // Test auto_reload_for_docker with other values (SRS_CONF_PREFER_TRUE: anything != "off" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "auto_reload_for_docker false;")); + EXPECT_TRUE(conf.auto_reload_for_docker()); // "false" != "off", so it's true + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "auto_reload_for_docker no;")); + EXPECT_TRUE(conf.auto_reload_for_docker()); // "no" != "off", so it's true + } + + // Test auto_reload_for_docker with empty argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "auto_reload_for_docker;")); + EXPECT_TRUE(conf.auto_reload_for_docker()); // Should use default value + } +} + +VOID TEST(ConfigMainTest, CheckTcmallocReleaseRate) +{ + srs_error_t err; + + // Test default tcmalloc_release_rate + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(0.8, conf.tcmalloc_release_rate()); // SRS_PERF_TCMALLOC_RELEASE_RATE + } + + // Test custom tcmalloc_release_rate + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "tcmalloc_release_rate 0.5;")); + EXPECT_EQ(0.5, conf.tcmalloc_release_rate()); + } + + // Test tcmalloc_release_rate with maximum value (should be clamped to 10) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "tcmalloc_release_rate 15.0;")); + EXPECT_EQ(10.0, conf.tcmalloc_release_rate()); + } + + // Test tcmalloc_release_rate with minimum value (should be clamped to 0) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "tcmalloc_release_rate -5.0;")); + EXPECT_EQ(0.0, conf.tcmalloc_release_rate()); + } + + // Test tcmalloc_release_rate with empty value (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "tcmalloc_release_rate;")); + EXPECT_EQ(0.8, conf.tcmalloc_release_rate()); + } + + // Test tcmalloc_release_rate with environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "tcmalloc_release_rate 0.3;")); + + SrsSetEnvConfig(conf, tcmalloc_release_rate, "SRS_TCMALLOC_RELEASE_RATE", "0.7"); + EXPECT_EQ(0.7, conf.tcmalloc_release_rate()); + } + + // Test tcmalloc_release_rate with environment variable clamping + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, tcmalloc_release_rate_high, "SRS_TCMALLOC_RELEASE_RATE", "20.0"); + EXPECT_EQ(10.0, conf.tcmalloc_release_rate()); + + SrsSetEnvConfig(conf, tcmalloc_release_rate_low, "SRS_TCMALLOC_RELEASE_RATE", "-2.0"); + EXPECT_EQ(0.0, conf.tcmalloc_release_rate()); + } +} + +VOID TEST(ConfigMainTest, CheckCircuitBreakerEnabled) +{ + srs_error_t err; + + // Test default circuit_breaker enabled (should be true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.get_circuit_breaker()); + } + + // Test circuit_breaker enabled explicitly + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{enabled on;}")); + EXPECT_TRUE(conf.get_circuit_breaker()); + } + + // Test circuit_breaker disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{enabled off;}")); + EXPECT_FALSE(conf.get_circuit_breaker()); + } + + // Test circuit_breaker with no enabled directive (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{}")); + EXPECT_TRUE(conf.get_circuit_breaker()); + } + + // Test circuit_breaker with empty enabled value (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{enabled;}")); + EXPECT_TRUE(conf.get_circuit_breaker()); + } + + // Test circuit_breaker with environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{enabled on;}")); + + SrsSetEnvConfig(conf, circuit_breaker_enabled, "SRS_CIRCUIT_BREAKER_ENABLED", "off"); + EXPECT_FALSE(conf.get_circuit_breaker()); + } + + // Test circuit_breaker with various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{enabled true;}")); + EXPECT_TRUE(conf.get_circuit_breaker()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{enabled false;}")); + EXPECT_TRUE(conf.get_circuit_breaker()); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{enabled yes;}")); + EXPECT_TRUE(conf.get_circuit_breaker()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{enabled no;}")); + EXPECT_TRUE(conf.get_circuit_breaker()); // "no" != "off", so it's true + } +} + +VOID TEST(ConfigMainTest, CheckCircuitBreakerThresholds) +{ + srs_error_t err; + + // Test default high_threshold (should be 90) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(90, conf.get_high_threshold()); + } + + // Test custom high_threshold + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{high_threshold 85;}")); + EXPECT_EQ(85, conf.get_high_threshold()); + } + + // Test default critical_threshold (should be 95) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(95, conf.get_critical_threshold()); + } + + // Test custom critical_threshold + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{critical_threshold 98;}")); + EXPECT_EQ(98, conf.get_critical_threshold()); + } + + // Test default dying_threshold (should be 99) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(99, conf.get_dying_threshold()); + } + + // Test custom dying_threshold + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{dying_threshold 100;}")); + EXPECT_EQ(100, conf.get_dying_threshold()); + } + + // Test all thresholds together + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{high_threshold 80; critical_threshold 90; dying_threshold 95;}")); + EXPECT_EQ(80, conf.get_high_threshold()); + EXPECT_EQ(90, conf.get_critical_threshold()); + EXPECT_EQ(95, conf.get_dying_threshold()); + } + + // Test thresholds with environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{high_threshold 80;}")); + + SrsSetEnvConfig(conf, high_threshold, "SRS_CIRCUIT_BREAKER_HIGH_THRESHOLD", "75"); + EXPECT_EQ(75, conf.get_high_threshold()); + + SrsSetEnvConfig(conf, critical_threshold, "SRS_CIRCUIT_BREAKER_CRITICAL_THRESHOLD", "88"); + EXPECT_EQ(88, conf.get_critical_threshold()); + + SrsSetEnvConfig(conf, dying_threshold, "SRS_CIRCUIT_BREAKER_DYING_THRESHOLD", "97"); + EXPECT_EQ(97, conf.get_dying_threshold()); + } +} + +VOID TEST(ConfigMainTest, CheckCircuitBreakerPulses) +{ + srs_error_t err; + + // Test default high_pulse (should be 2) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(2, conf.get_high_pulse()); + } + + // Test custom high_pulse + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{high_pulse 3;}")); + EXPECT_EQ(3, conf.get_high_pulse()); + } + + // Test default critical_pulse (should be 1) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(1, conf.get_critical_pulse()); + } + + // Test custom critical_pulse + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{critical_pulse 2;}")); + EXPECT_EQ(2, conf.get_critical_pulse()); + } + + // Test default dying_pulse (should be 5) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(5, conf.get_dying_pulse()); + } + + // Test custom dying_pulse + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{dying_pulse 10;}")); + EXPECT_EQ(10, conf.get_dying_pulse()); + } + + // Test all pulses together + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{high_pulse 4; critical_pulse 3; dying_pulse 8;}")); + EXPECT_EQ(4, conf.get_high_pulse()); + EXPECT_EQ(3, conf.get_critical_pulse()); + EXPECT_EQ(8, conf.get_dying_pulse()); + } + + // Test pulses with environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "circuit_breaker{high_pulse 2;}")); + + SrsSetEnvConfig(conf, high_pulse, "SRS_CIRCUIT_BREAKER_HIGH_PULSE", "5"); + EXPECT_EQ(5, conf.get_high_pulse()); + + SrsSetEnvConfig(conf, critical_pulse, "SRS_CIRCUIT_BREAKER_CRITICAL_PULSE", "3"); + EXPECT_EQ(3, conf.get_critical_pulse()); + + SrsSetEnvConfig(conf, dying_pulse, "SRS_CIRCUIT_BREAKER_DYING_PULSE", "7"); + EXPECT_EQ(7, conf.get_dying_pulse()); + } +} + +VOID TEST(ConfigMainTest, CheckStreamCasterEngine) +{ + srs_error_t err; + + // Test get_stream_caster_engine with NULL conf (should return empty string) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_STREQ("", conf.get_stream_caster_engine(NULL).c_str()); + } + + // Test get_stream_caster_engine with conf but no caster directive (should return empty string) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster{enabled on;}")); + + SrsConfDirective *stream_caster = conf.get_root()->get("stream_caster"); + ASSERT_TRUE(stream_caster != NULL); + EXPECT_STREQ("", conf.get_stream_caster_engine(stream_caster).c_str()); + } + + // Test get_stream_caster_engine with empty caster value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster{enabled on; caster;}")); + + SrsConfDirective *stream_caster = conf.get_root()->get("stream_caster"); + ASSERT_TRUE(stream_caster != NULL); + EXPECT_STREQ("", conf.get_stream_caster_engine(stream_caster).c_str()); + } + + // Test get_stream_caster_engine with gb28181 caster + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster{enabled on; caster gb28181;}")); + + SrsConfDirective *stream_caster = conf.get_root()->get("stream_caster"); + ASSERT_TRUE(stream_caster != NULL); + EXPECT_STREQ("gb28181", conf.get_stream_caster_engine(stream_caster).c_str()); + } + + // Test get_stream_caster_engine with flv caster + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster{enabled on; caster flv;}")); + + SrsConfDirective *stream_caster = conf.get_root()->get("stream_caster"); + ASSERT_TRUE(stream_caster != NULL); + EXPECT_STREQ("flv", conf.get_stream_caster_engine(stream_caster).c_str()); + } + + // Test get_stream_caster_engine with mpegts-over-udp caster + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stream_caster{enabled on; caster mpegts-over-udp;}")); + + SrsConfDirective *stream_caster = conf.get_root()->get("stream_caster"); + ASSERT_TRUE(stream_caster != NULL); + EXPECT_STREQ("mpegts-over-udp", conf.get_stream_caster_engine(stream_caster).c_str()); + } +} + +VOID TEST(ConfigMainTest, CheckRtspServerEnabled) +{ + srs_error_t err; + + // Test default rtsp_server enabled (should be false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtsp_server_enabled()); + } + + // Test rtsp_server enabled explicitly + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{enabled on;}")); + EXPECT_TRUE(conf.get_rtsp_server_enabled()); + } + + // Test rtsp_server disabled explicitly + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{enabled off;}")); + EXPECT_FALSE(conf.get_rtsp_server_enabled()); + } + + // Test rtsp_server with no enabled directive (should use default false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{}")); + EXPECT_FALSE(conf.get_rtsp_server_enabled()); + } + + // Test rtsp_server with empty enabled value (should use default false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{enabled;}")); + EXPECT_FALSE(conf.get_rtsp_server_enabled()); + } + + // Test rtsp_server with environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{enabled off;}")); + + SrsSetEnvConfig(conf, rtsp_server_enabled, "SRS_RTSP_SERVER_ENABLED", "on"); + EXPECT_TRUE(conf.get_rtsp_server_enabled()); + } + + // Test rtsp_server with various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{enabled true;}")); + EXPECT_FALSE(conf.get_rtsp_server_enabled()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{enabled false;}")); + EXPECT_FALSE(conf.get_rtsp_server_enabled()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{enabled yes;}")); + EXPECT_FALSE(conf.get_rtsp_server_enabled()); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{enabled no;}")); + EXPECT_FALSE(conf.get_rtsp_server_enabled()); + } +} + +VOID TEST(ConfigMainTest, CheckRtspServerListens) +{ + srs_error_t err; + + // Test default rtsp_server listen (should be 554) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + vector listens = conf.get_rtsp_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("554", listens.at(0).c_str()); + } + + // Test custom rtsp_server listen port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{listen 8554;}")); + vector listens = conf.get_rtsp_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8554", listens.at(0).c_str()); + } + + // Test multiple rtsp_server listen ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{listen 554 8554 9554;}")); + vector listens = conf.get_rtsp_server_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("554", listens.at(0).c_str()); + EXPECT_STREQ("8554", listens.at(1).c_str()); + EXPECT_STREQ("9554", listens.at(2).c_str()); + } + + // Test rtsp_server with no listen directive (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{enabled on;}")); + vector listens = conf.get_rtsp_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("554", listens.at(0).c_str()); + } + + // Test rtsp_server with empty listen directive (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{listen;}")); + vector listens = conf.get_rtsp_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("554", listens.at(0).c_str()); + } + + // Test rtsp_server with environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtsp_server{listen 8554;}")); + + SrsSetEnvConfig(conf, rtsp_server_listen, "SRS_RTSP_SERVER_LISTEN", "9554"); + vector listens = conf.get_rtsp_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("9554", listens.at(0).c_str()); + } + + // Test rtsp_server with environment variable multiple ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, rtsp_server_listen_multi, "SRS_RTSP_SERVER_LISTEN", "554 8554"); + vector listens = conf.get_rtsp_server_listens(); + EXPECT_EQ(2, (int)listens.size()); + EXPECT_STREQ("554", listens.at(0).c_str()); + EXPECT_STREQ("8554", listens.at(1).c_str()); + } +} + +VOID TEST(ConfigMainTest, CheckVhostRtspEnabled) +{ + srs_error_t err; + + // Test default vhost rtsp enabled (should be false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + EXPECT_FALSE(conf.get_rtsp_enabled("test.com")); + } + + // Test vhost rtsp enabled explicitly + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{enabled on;}}")); + EXPECT_TRUE(conf.get_rtsp_enabled("test.com")); + } + + // Test vhost rtsp disabled explicitly + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{enabled off;}}")); + EXPECT_FALSE(conf.get_rtsp_enabled("test.com")); + } + + // Test vhost rtsp with no enabled directive (should use default false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{}}")); + EXPECT_FALSE(conf.get_rtsp_enabled("test.com")); + } + + // Test vhost rtsp with empty enabled value (should use default false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{enabled;}}")); + EXPECT_FALSE(conf.get_rtsp_enabled("test.com")); + } + + // Test vhost rtsp with environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{enabled off;}}")); + + SrsSetEnvConfig(conf, rtsp_enabled, "SRS_VHOST_RTSP_ENABLED", "on"); + EXPECT_TRUE(conf.get_rtsp_enabled("test.com")); + } + + // Test vhost rtsp with non-existent vhost (should use default false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtsp_enabled("nonexistent.com")); + } + + // Test get_rtsp directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{enabled on;}}")); + + SrsConfDirective *rtsp = conf.get_rtsp("test.com"); + ASSERT_TRUE(rtsp != NULL); + EXPECT_STREQ("rtsp", rtsp->name_.c_str()); + + // Test with non-existent vhost + SrsConfDirective *rtsp_null = conf.get_rtsp("nonexistent.com"); + EXPECT_TRUE(rtsp_null == NULL); + } +} + +VOID TEST(ConfigMainTest, CheckVhostRtspFromRtmp) +{ + srs_error_t err; + + // Test default vhost rtsp rtmp_to_rtsp (should be true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + EXPECT_TRUE(conf.get_rtsp_from_rtmp("test.com")); + } + + // Test vhost rtsp rtmp_to_rtsp enabled explicitly + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{rtmp_to_rtsp on;}}")); + EXPECT_TRUE(conf.get_rtsp_from_rtmp("test.com")); + } + + // Test vhost rtsp rtmp_to_rtsp disabled explicitly + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{rtmp_to_rtsp off;}}")); + EXPECT_FALSE(conf.get_rtsp_from_rtmp("test.com")); + } + + // Test vhost rtsp with no rtmp_to_rtsp directive (should use default true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{enabled on;}}")); + EXPECT_TRUE(conf.get_rtsp_from_rtmp("test.com")); + } + + // Test vhost rtsp with empty rtmp_to_rtsp value (should use default true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{rtmp_to_rtsp;}}")); + EXPECT_TRUE(conf.get_rtsp_from_rtmp("test.com")); + } + + // Test vhost rtsp with environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{rtmp_to_rtsp on;}}")); + + SrsSetEnvConfig(conf, rtsp_from_rtmp, "SRS_VHOST_RTSP_RTMP_TO_RTSP", "off"); + EXPECT_FALSE(conf.get_rtsp_from_rtmp("test.com")); + } + + // Test vhost rtsp with non-existent vhost (should use default true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.get_rtsp_from_rtmp("nonexistent.com")); + } + + // Test vhost rtsp with various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{rtmp_to_rtsp true;}}")); + EXPECT_TRUE(conf.get_rtsp_from_rtmp("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{rtmp_to_rtsp false;}}")); + EXPECT_TRUE(conf.get_rtsp_from_rtmp("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{rtmp_to_rtsp yes;}}")); + EXPECT_TRUE(conf.get_rtsp_from_rtmp("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtsp{rtmp_to_rtsp no;}}")); + EXPECT_TRUE(conf.get_rtsp_from_rtmp("test.com")); // "no" != "off", so it's true + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerEnabled) +{ + srs_error_t err; + + // Test default value (false) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtc_server_enabled()); + } + + // Test default value (false) when rtc_server section exists but no enabled directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{listen 8000;}")); + EXPECT_FALSE(conf.get_rtc_server_enabled()); + } + + // Test enabled on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_TRUE(conf.get_rtc_server_enabled()); + } + + // Test enabled off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled off;}")); + EXPECT_FALSE(conf.get_rtc_server_enabled()); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled true;}")); + EXPECT_FALSE(conf.get_rtc_server_enabled()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled yes;}")); + EXPECT_FALSE(conf.get_rtc_server_enabled()); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled 1;}")); + EXPECT_FALSE(conf.get_rtc_server_enabled()); // "1" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled;}")); + EXPECT_FALSE(conf.get_rtc_server_enabled()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled off;}")); + + SrsSetEnvConfig(conf, rtc_enabled, "SRS_RTC_SERVER_ENABLED", "on"); + EXPECT_TRUE(conf.get_rtc_server_enabled()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerListens) +{ + srs_error_t err; + + // Test default value when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + vector listens = conf.get_rtc_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8000", listens.at(0).c_str()); + } + + // Test default value when rtc_server section exists but no listen directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + vector listens = conf.get_rtc_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8000", listens.at(0).c_str()); + } + + // Test single listen port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{listen 8080;}")); + vector listens = conf.get_rtc_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8080", listens.at(0).c_str()); + } + + // Test multiple listen ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{listen 8080 8081 8082;}")); + vector listens = conf.get_rtc_server_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("8080", listens.at(0).c_str()); + EXPECT_STREQ("8081", listens.at(1).c_str()); + EXPECT_STREQ("8082", listens.at(2).c_str()); + } + + // Test empty listen directive (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{listen;}")); + vector listens = conf.get_rtc_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8000", listens.at(0).c_str()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{listen 8080;}")); + + SrsSetEnvConfig(conf, rtc_listen, "SRS_RTC_SERVER_LISTEN", "9000"); + vector listens = conf.get_rtc_server_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("9000", listens.at(0).c_str()); + } + + // Test environment variable with multiple ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, rtc_listen, "SRS_RTC_SERVER_LISTEN", "9000 9001"); + vector listens = conf.get_rtc_server_listens(); + EXPECT_EQ(2, (int)listens.size()); + EXPECT_STREQ("9000", listens.at(0).c_str()); + EXPECT_STREQ("9001", listens.at(1).c_str()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerCandidates) +{ + srs_error_t err; + + // Test default value when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_STREQ("*", conf.get_rtc_server_candidates().c_str()); + } + + // Test default value when rtc_server section exists but no candidate directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_STREQ("*", conf.get_rtc_server_candidates().c_str()); + } + + // Test explicit candidate value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{candidate 192.168.1.100;}")); + EXPECT_STREQ("192.168.1.100", conf.get_rtc_server_candidates().c_str()); + } + + // Test empty candidate value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{candidate;}")); + EXPECT_STREQ("*", conf.get_rtc_server_candidates().c_str()); + } + + // Test environment variable reference with actual env var set + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{candidate $MY_CANDIDATE;}")); + + SrsSetEnvConfig(conf, my_candidate, "MY_CANDIDATE", "10.0.0.1"); + EXPECT_STREQ("10.0.0.1", conf.get_rtc_server_candidates().c_str()); + } + + // Test environment variable reference without env var set (should return default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{candidate $UNSET_VAR;}")); + EXPECT_STREQ("*", conf.get_rtc_server_candidates().c_str()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{candidate 192.168.1.100;}")); + + SrsSetEnvConfig(conf, rtc_candidate, "SRS_RTC_SERVER_CANDIDATE", "10.0.0.2"); + EXPECT_STREQ("10.0.0.2", conf.get_rtc_server_candidates().c_str()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckApiAsCandidates) +{ + srs_error_t err; + + // Test default value (true) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.get_api_as_candidates()); + } + + // Test default value (true) when rtc_server section exists but no api_as_candidates directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_TRUE(conf.get_api_as_candidates()); + } + + // Test api_as_candidates off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{api_as_candidates off;}")); + EXPECT_FALSE(conf.get_api_as_candidates()); + } + + // Test api_as_candidates on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{api_as_candidates on;}")); + EXPECT_TRUE(conf.get_api_as_candidates()); + } + + // Test SRS_CONF_PREFER_TRUE behavior (only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{api_as_candidates false;}")); + EXPECT_TRUE(conf.get_api_as_candidates()); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{api_as_candidates no;}")); + EXPECT_TRUE(conf.get_api_as_candidates()); // "no" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{api_as_candidates 0;}")); + EXPECT_TRUE(conf.get_api_as_candidates()); // "0" != "off", so it's true + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{api_as_candidates;}")); + EXPECT_TRUE(conf.get_api_as_candidates()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckResolveApiDomain) +{ + srs_error_t err; + + // Test default value (true) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.get_resolve_api_domain()); + } + + // Test default value (true) when rtc_server section exists but no resolve_api_domain directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_TRUE(conf.get_resolve_api_domain()); + } + + // Test resolve_api_domain off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{resolve_api_domain off;}")); + EXPECT_FALSE(conf.get_resolve_api_domain()); + } + + // Test resolve_api_domain on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{resolve_api_domain on;}")); + EXPECT_TRUE(conf.get_resolve_api_domain()); + } + + // Test SRS_CONF_PREFER_TRUE behavior (only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{resolve_api_domain true;}")); + EXPECT_TRUE(conf.get_resolve_api_domain()); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{resolve_api_domain yes;}")); + EXPECT_TRUE(conf.get_resolve_api_domain()); // "yes" != "off", so it's true + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{resolve_api_domain;}")); + EXPECT_TRUE(conf.get_resolve_api_domain()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckKeepApiDomain) +{ + srs_error_t err; + + // Test default value (false) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_keep_api_domain()); + } + + // Test default value (false) when rtc_server section exists but no keep_api_domain directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_FALSE(conf.get_keep_api_domain()); + } + + // Test keep_api_domain on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{keep_api_domain on;}")); + EXPECT_TRUE(conf.get_keep_api_domain()); + } + + // Test keep_api_domain off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{keep_api_domain off;}")); + EXPECT_FALSE(conf.get_keep_api_domain()); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{keep_api_domain true;}")); + EXPECT_FALSE(conf.get_keep_api_domain()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{keep_api_domain yes;}")); + EXPECT_FALSE(conf.get_keep_api_domain()); // "yes" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{keep_api_domain;}")); + EXPECT_FALSE(conf.get_keep_api_domain()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckUseAutoDetectNetworkIp) +{ + srs_error_t err; + + // Test default value (true) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.get_use_auto_detect_network_ip()); + } + + // Test default value (true) when rtc_server section exists but no use_auto_detect_network_ip directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_TRUE(conf.get_use_auto_detect_network_ip()); + } + + // Test use_auto_detect_network_ip off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{use_auto_detect_network_ip off;}")); + EXPECT_FALSE(conf.get_use_auto_detect_network_ip()); + } + + // Test use_auto_detect_network_ip on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{use_auto_detect_network_ip on;}")); + EXPECT_TRUE(conf.get_use_auto_detect_network_ip()); + } + + // Test SRS_CONF_PREFER_TRUE behavior (only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{use_auto_detect_network_ip true;}")); + EXPECT_TRUE(conf.get_use_auto_detect_network_ip()); // "true" != "off", so it's true + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{use_auto_detect_network_ip;}")); + EXPECT_TRUE(conf.get_use_auto_detect_network_ip()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerTcpEnabled) +{ + srs_error_t err; + + // Test default value (false) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtc_server_tcp_enabled()); + } + + // Test default value (false) when rtc_server section exists but no tcp section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_FALSE(conf.get_rtc_server_tcp_enabled()); + } + + // Test default value (false) when tcp section exists but no enabled directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{listen 8000;}}")); + EXPECT_FALSE(conf.get_rtc_server_tcp_enabled()); + } + + // Test tcp enabled on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{enabled on;}}")); + EXPECT_TRUE(conf.get_rtc_server_tcp_enabled()); + } + + // Test tcp enabled off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{enabled off;}}")); + EXPECT_FALSE(conf.get_rtc_server_tcp_enabled()); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{enabled true;}}")); + EXPECT_FALSE(conf.get_rtc_server_tcp_enabled()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{enabled yes;}}")); + EXPECT_FALSE(conf.get_rtc_server_tcp_enabled()); // "yes" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{enabled;}}")); + EXPECT_FALSE(conf.get_rtc_server_tcp_enabled()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{enabled off;}}")); + + SrsSetEnvConfig(conf, rtc_tcp_enabled, "SRS_RTC_SERVER_TCP_ENABLED", "on"); + EXPECT_TRUE(conf.get_rtc_server_tcp_enabled()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerTcpListens) +{ + srs_error_t err; + + // Test default value when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + vector listens = conf.get_rtc_server_tcp_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8000", listens.at(0).c_str()); + } + + // Test default value when rtc_server section exists but no tcp section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + vector listens = conf.get_rtc_server_tcp_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8000", listens.at(0).c_str()); + } + + // Test default value when tcp section exists but no listen directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{enabled on;}}")); + vector listens = conf.get_rtc_server_tcp_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8000", listens.at(0).c_str()); + } + + // Test single tcp listen port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{listen 8080;}}")); + vector listens = conf.get_rtc_server_tcp_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8080", listens.at(0).c_str()); + } + + // Test multiple tcp listen ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{listen 8080 8081 8082;}}")); + vector listens = conf.get_rtc_server_tcp_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("8080", listens.at(0).c_str()); + EXPECT_STREQ("8081", listens.at(1).c_str()); + EXPECT_STREQ("8082", listens.at(2).c_str()); + } + + // Test empty tcp listen directive (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{listen;}}")); + vector listens = conf.get_rtc_server_tcp_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8000", listens.at(0).c_str()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{tcp{listen 8080;}}")); + + SrsSetEnvConfig(conf, rtc_tcp_listen, "SRS_RTC_SERVER_TCP_LISTEN", "9000"); + vector listens = conf.get_rtc_server_tcp_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("9000", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerProtocol) +{ + srs_error_t err; + + // Test default value (udp) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_STREQ("udp", conf.get_rtc_server_protocol().c_str()); + } + + // Test default value (udp) when rtc_server section exists but no protocol directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_STREQ("udp", conf.get_rtc_server_protocol().c_str()); + } + + // Test explicit protocol value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{protocol tcp;}")); + EXPECT_STREQ("tcp", conf.get_rtc_server_protocol().c_str()); + } + + // Test empty protocol value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{protocol;}")); + EXPECT_STREQ("udp", conf.get_rtc_server_protocol().c_str()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{protocol tcp;}")); + + SrsSetEnvConfig(conf, rtc_protocol, "SRS_RTC_SERVER_PROTOCOL", "udp"); + EXPECT_STREQ("udp", conf.get_rtc_server_protocol().c_str()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerIpFamily) +{ + srs_error_t err; + + // Test default value (ipv4) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_STREQ("ipv4", conf.get_rtc_server_ip_family().c_str()); + } + + // Test default value (ipv4) when rtc_server section exists but no ip_family directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_STREQ("ipv4", conf.get_rtc_server_ip_family().c_str()); + } + + // Test explicit ip_family value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{ip_family ipv6;}")); + EXPECT_STREQ("ipv6", conf.get_rtc_server_ip_family().c_str()); + } + + // Test empty ip_family value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{ip_family;}")); + EXPECT_STREQ("ipv4", conf.get_rtc_server_ip_family().c_str()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerEcdsa) +{ + srs_error_t err; + + // Test default value (true) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.get_rtc_server_ecdsa()); + } + + // Test default value (true) when rtc_server section exists but no ecdsa directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_TRUE(conf.get_rtc_server_ecdsa()); + } + + // Test ecdsa off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{ecdsa off;}")); + EXPECT_FALSE(conf.get_rtc_server_ecdsa()); + } + + // Test ecdsa on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{ecdsa on;}")); + EXPECT_TRUE(conf.get_rtc_server_ecdsa()); + } + + // Test SRS_CONF_PREFER_TRUE behavior (only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{ecdsa true;}")); + EXPECT_TRUE(conf.get_rtc_server_ecdsa()); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{ecdsa yes;}")); + EXPECT_TRUE(conf.get_rtc_server_ecdsa()); // "yes" != "off", so it's true + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{ecdsa;}")); + EXPECT_TRUE(conf.get_rtc_server_ecdsa()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerEncrypt) +{ + srs_error_t err; + + // Test default value (true) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.get_rtc_server_encrypt()); + } + + // Test default value (true) when rtc_server section exists but no encrypt directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_TRUE(conf.get_rtc_server_encrypt()); + } + + // Test encrypt off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{encrypt off;}")); + EXPECT_FALSE(conf.get_rtc_server_encrypt()); + } + + // Test encrypt on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{encrypt on;}")); + EXPECT_TRUE(conf.get_rtc_server_encrypt()); + } + + // Test SRS_CONF_PREFER_TRUE behavior (only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{encrypt true;}")); + EXPECT_TRUE(conf.get_rtc_server_encrypt()); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{encrypt yes;}")); + EXPECT_TRUE(conf.get_rtc_server_encrypt()); // "yes" != "off", so it's true + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{encrypt;}")); + EXPECT_TRUE(conf.get_rtc_server_encrypt()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerReuseport) +{ + srs_error_t err; + + // Test default value (1) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(1, conf.get_rtc_server_reuseport()); + EXPECT_EQ(1, conf.get_rtc_server_reuseport2()); + } + + // Test default value (1) when rtc_server section exists but no reuseport directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_EQ(1, conf.get_rtc_server_reuseport()); + EXPECT_EQ(1, conf.get_rtc_server_reuseport2()); + } + + // Test explicit reuseport value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{reuseport 4;}")); + EXPECT_EQ(4, conf.get_rtc_server_reuseport2()); + // get_rtc_server_reuseport() may limit the value based on SO_REUSEPORT support + int reuseport = conf.get_rtc_server_reuseport(); + EXPECT_TRUE(reuseport >= 1 && reuseport <= 4); + } + + // Test reuseport 0 + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{reuseport 0;}")); + EXPECT_EQ(0, conf.get_rtc_server_reuseport()); + EXPECT_EQ(0, conf.get_rtc_server_reuseport2()); + } + + // Test empty reuseport value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{reuseport;}")); + EXPECT_EQ(1, conf.get_rtc_server_reuseport()); + EXPECT_EQ(1, conf.get_rtc_server_reuseport2()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerMergeNalus) +{ + srs_error_t err; + + // Test default value (false) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtc_server_merge_nalus()); + } + + // Test default value (false) when rtc_server section exists but no merge_nalus directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_FALSE(conf.get_rtc_server_merge_nalus()); + } + + // Test merge_nalus on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{merge_nalus on;}")); + EXPECT_TRUE(conf.get_rtc_server_merge_nalus()); + } + + // Test merge_nalus off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{merge_nalus off;}")); + EXPECT_FALSE(conf.get_rtc_server_merge_nalus()); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{merge_nalus true;}")); + EXPECT_FALSE(conf.get_rtc_server_merge_nalus()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{merge_nalus yes;}")); + EXPECT_FALSE(conf.get_rtc_server_merge_nalus()); // "yes" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{merge_nalus;}")); + EXPECT_FALSE(conf.get_rtc_server_merge_nalus()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerBlackHole) +{ + srs_error_t err; + + // Test default value (false) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtc_server_black_hole()); + } + + // Test default value (false) when rtc_server section exists but no black_hole section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_FALSE(conf.get_rtc_server_black_hole()); + } + + // Test default value (false) when black_hole section exists but no enabled directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{addr 127.0.0.1;}}")); + EXPECT_FALSE(conf.get_rtc_server_black_hole()); + } + + // Test black_hole enabled on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{enabled on;}}")); + EXPECT_TRUE(conf.get_rtc_server_black_hole()); + } + + // Test black_hole enabled off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{enabled off;}}")); + EXPECT_FALSE(conf.get_rtc_server_black_hole()); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{enabled true;}}")); + EXPECT_FALSE(conf.get_rtc_server_black_hole()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{enabled yes;}}")); + EXPECT_FALSE(conf.get_rtc_server_black_hole()); // "yes" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{enabled;}}")); + EXPECT_FALSE(conf.get_rtc_server_black_hole()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{enabled off;}}")); + + SrsSetEnvConfig(conf, rtc_black_hole, "SRS_RTC_SERVER_BLACK_HOLE_ENABLED", "on"); + EXPECT_TRUE(conf.get_rtc_server_black_hole()); + } +} + +VOID TEST(ConfigRtcServerTest, CheckRtcServerBlackHoleAddr) +{ + srs_error_t err; + + // Test default value (empty) when no rtc_server section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_STREQ("", conf.get_rtc_server_black_hole_addr().c_str()); + } + + // Test default value (empty) when rtc_server section exists but no black_hole section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{enabled on;}")); + EXPECT_STREQ("", conf.get_rtc_server_black_hole_addr().c_str()); + } + + // Test default value (empty) when black_hole section exists but no addr directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{enabled on;}}")); + EXPECT_STREQ("", conf.get_rtc_server_black_hole_addr().c_str()); + } + + // Test explicit addr value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{addr 127.0.0.1;}}")); + EXPECT_STREQ("127.0.0.1", conf.get_rtc_server_black_hole_addr().c_str()); + } + + // Test empty addr value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{addr;}}")); + EXPECT_STREQ("", conf.get_rtc_server_black_hole_addr().c_str()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtc_server{black_hole{addr 127.0.0.1;}}")); + + SrsSetEnvConfig(conf, rtc_black_hole_addr, "SRS_RTC_SERVER_BLACK_HOLE_ADDR", "10.0.0.1"); + EXPECT_STREQ("10.0.0.1", conf.get_rtc_server_black_hole_addr().c_str()); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcEnabled) +{ + srs_error_t err; + + // Test default value (false) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtc_enabled("__defaultVhost__")); + EXPECT_FALSE(conf.get_rtc_enabled("test.com")); + } + + // Test default value (false) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_FALSE(conf.get_rtc_enabled("test.com")); + } + + // Test default value (false) when rtc section exists but no enabled directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_bframe on;}}")); + EXPECT_FALSE(conf.get_rtc_enabled("test.com")); + } + + // Test rtc enabled on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_TRUE(conf.get_rtc_enabled("test.com")); + } + + // Test rtc enabled off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled off;}}")); + EXPECT_FALSE(conf.get_rtc_enabled("test.com")); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled true;}}")); + EXPECT_FALSE(conf.get_rtc_enabled("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled yes;}}")); + EXPECT_FALSE(conf.get_rtc_enabled("test.com")); // "yes" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled;}}")); + EXPECT_FALSE(conf.get_rtc_enabled("test.com")); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled off;}}")); + + SrsSetEnvConfig(conf, rtc_enabled, "SRS_VHOST_RTC_ENABLED", "on"); + EXPECT_TRUE(conf.get_rtc_enabled("test.com")); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcKeepBframe) +{ + srs_error_t err; + + // Test default value (false) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtc_keep_bframe("__defaultVhost__")); + EXPECT_FALSE(conf.get_rtc_keep_bframe("test.com")); + } + + // Test default value (false) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_FALSE(conf.get_rtc_keep_bframe("test.com")); + } + + // Test default value (false) when rtc section exists but no keep_bframe directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_FALSE(conf.get_rtc_keep_bframe("test.com")); + } + + // Test keep_bframe on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_bframe on;}}")); + EXPECT_TRUE(conf.get_rtc_keep_bframe("test.com")); + } + + // Test keep_bframe off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_bframe off;}}")); + EXPECT_FALSE(conf.get_rtc_keep_bframe("test.com")); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_bframe true;}}")); + EXPECT_FALSE(conf.get_rtc_keep_bframe("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_bframe yes;}}")); + EXPECT_FALSE(conf.get_rtc_keep_bframe("test.com")); // "yes" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_bframe;}}")); + EXPECT_FALSE(conf.get_rtc_keep_bframe("test.com")); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_bframe off;}}")); + + SrsSetEnvConfig(conf, rtc_keep_bframe, "SRS_VHOST_RTC_KEEP_BFRAME", "on"); + EXPECT_TRUE(conf.get_rtc_keep_bframe("test.com")); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcKeepAvcNaluSei) +{ + srs_error_t err; + + // Test default value (true) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_TRUE(conf.get_rtc_keep_avc_nalu_sei("__defaultVhost__")); + EXPECT_TRUE(conf.get_rtc_keep_avc_nalu_sei("test.com")); + } + + // Test default value (true) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_TRUE(conf.get_rtc_keep_avc_nalu_sei("test.com")); + } + + // Test default value (true) when rtc section exists but no keep_avc_nalu_sei directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_TRUE(conf.get_rtc_keep_avc_nalu_sei("test.com")); + } + + // Test keep_avc_nalu_sei off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_avc_nalu_sei off;}}")); + EXPECT_FALSE(conf.get_rtc_keep_avc_nalu_sei("test.com")); + } + + // Test keep_avc_nalu_sei on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_avc_nalu_sei on;}}")); + EXPECT_TRUE(conf.get_rtc_keep_avc_nalu_sei("test.com")); + } + + // Test SRS_CONF_PREFER_TRUE behavior (only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_avc_nalu_sei true;}}")); + EXPECT_TRUE(conf.get_rtc_keep_avc_nalu_sei("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_avc_nalu_sei yes;}}")); + EXPECT_TRUE(conf.get_rtc_keep_avc_nalu_sei("test.com")); // "yes" != "off", so it's true + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_avc_nalu_sei;}}")); + EXPECT_TRUE(conf.get_rtc_keep_avc_nalu_sei("test.com")); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{keep_avc_nalu_sei on;}}")); + + SrsSetEnvConfig(conf, rtc_keep_avc_nalu_sei, "SRS_VHOST_RTC_KEEP_AVC_NALU_SEI", "off"); + EXPECT_FALSE(conf.get_rtc_keep_avc_nalu_sei("test.com")); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcFromRtmp) +{ + srs_error_t err; + + // Test default value (false) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtc_from_rtmp("__defaultVhost__")); + EXPECT_FALSE(conf.get_rtc_from_rtmp("test.com")); + } + + // Test default value (false) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_FALSE(conf.get_rtc_from_rtmp("test.com")); + } + + // Test default value (false) when rtc section exists but no rtmp_to_rtc directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_FALSE(conf.get_rtc_from_rtmp("test.com")); + } + + // Test rtmp_to_rtc on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtmp_to_rtc on;}}")); + EXPECT_TRUE(conf.get_rtc_from_rtmp("test.com")); + } + + // Test rtmp_to_rtc off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtmp_to_rtc off;}}")); + EXPECT_FALSE(conf.get_rtc_from_rtmp("test.com")); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtmp_to_rtc true;}}")); + EXPECT_FALSE(conf.get_rtc_from_rtmp("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtmp_to_rtc yes;}}")); + EXPECT_FALSE(conf.get_rtc_from_rtmp("test.com")); // "yes" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtmp_to_rtc;}}")); + EXPECT_FALSE(conf.get_rtc_from_rtmp("test.com")); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtmp_to_rtc off;}}")); + + SrsSetEnvConfig(conf, rtc_from_rtmp, "SRS_VHOST_RTC_RTMP_TO_RTC", "on"); + EXPECT_TRUE(conf.get_rtc_from_rtmp("test.com")); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcStunTimeout) +{ + srs_error_t err; + + // Test default value (30 seconds) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_rtc_stun_timeout("__defaultVhost__")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_rtc_stun_timeout("test.com")); + } + + // Test default value (30 seconds) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_rtc_stun_timeout("test.com")); + } + + // Test default value (30 seconds) when rtc section exists but no stun_timeout directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_rtc_stun_timeout("test.com")); + } + + // Test explicit stun_timeout value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_timeout 60;}}")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_rtc_stun_timeout("test.com")); + } + + // Test stun_timeout 0 + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_timeout 0;}}")); + EXPECT_EQ(0, conf.get_rtc_stun_timeout("test.com")); + } + + // Test empty stun_timeout value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_timeout;}}")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_rtc_stun_timeout("test.com")); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_timeout 60;}}")); + + SrsSetEnvConfig(conf, rtc_stun_timeout, "SRS_VHOST_RTC_STUN_TIMEOUT", "120"); + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_rtc_stun_timeout("test.com")); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcStunStrictCheck) +{ + srs_error_t err; + + // Test default value (false) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtc_stun_strict_check("__defaultVhost__")); + EXPECT_FALSE(conf.get_rtc_stun_strict_check("test.com")); + } + + // Test default value (false) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_FALSE(conf.get_rtc_stun_strict_check("test.com")); + } + + // Test default value (false) when rtc section exists but no stun_strict_check directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_FALSE(conf.get_rtc_stun_strict_check("test.com")); + } + + // Test stun_strict_check on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_strict_check on;}}")); + EXPECT_TRUE(conf.get_rtc_stun_strict_check("test.com")); + } + + // Test stun_strict_check off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_strict_check off;}}")); + EXPECT_FALSE(conf.get_rtc_stun_strict_check("test.com")); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_strict_check true;}}")); + EXPECT_FALSE(conf.get_rtc_stun_strict_check("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_strict_check yes;}}")); + EXPECT_FALSE(conf.get_rtc_stun_strict_check("test.com")); // "yes" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_strict_check;}}")); + EXPECT_FALSE(conf.get_rtc_stun_strict_check("test.com")); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{stun_strict_check off;}}")); + + SrsSetEnvConfig(conf, rtc_stun_strict_check, "SRS_VHOST_RTC_STUN_STRICT_CHECK", "on"); + EXPECT_TRUE(conf.get_rtc_stun_strict_check("test.com")); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcDtlsRole) +{ + srs_error_t err; + + // Test default value (passive) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_STREQ("passive", conf.get_rtc_dtls_role("__defaultVhost__").c_str()); + EXPECT_STREQ("passive", conf.get_rtc_dtls_role("test.com").c_str()); + } + + // Test default value (passive) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_STREQ("passive", conf.get_rtc_dtls_role("test.com").c_str()); + } + + // Test default value (passive) when rtc section exists but no dtls_role directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_STREQ("passive", conf.get_rtc_dtls_role("test.com").c_str()); + } + + // Test explicit dtls_role value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{dtls_role active;}}")); + EXPECT_STREQ("active", conf.get_rtc_dtls_role("test.com").c_str()); + } + + // Test empty dtls_role value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{dtls_role;}}")); + EXPECT_STREQ("passive", conf.get_rtc_dtls_role("test.com").c_str()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{dtls_role passive;}}")); + + SrsSetEnvConfig(conf, rtc_dtls_role, "SRS_VHOST_RTC_DTLS_ROLE", "active"); + EXPECT_STREQ("active", conf.get_rtc_dtls_role("test.com").c_str()); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcDtlsVersion) +{ + srs_error_t err; + + // Test default value (auto) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_STREQ("auto", conf.get_rtc_dtls_version("__defaultVhost__").c_str()); + EXPECT_STREQ("auto", conf.get_rtc_dtls_version("test.com").c_str()); + } + + // Test default value (auto) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_STREQ("auto", conf.get_rtc_dtls_version("test.com").c_str()); + } + + // Test default value (auto) when rtc section exists but no dtls_version directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_STREQ("auto", conf.get_rtc_dtls_version("test.com").c_str()); + } + + // Test explicit dtls_version value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{dtls_version 1.2;}}")); + EXPECT_STREQ("1.2", conf.get_rtc_dtls_version("test.com").c_str()); + } + + // Test empty dtls_version value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{dtls_version;}}")); + EXPECT_STREQ("auto", conf.get_rtc_dtls_version("test.com").c_str()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{dtls_version auto;}}")); + + SrsSetEnvConfig(conf, rtc_dtls_version, "SRS_VHOST_RTC_DTLS_VERSION", "1.3"); + EXPECT_STREQ("1.3", conf.get_rtc_dtls_version("test.com").c_str()); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcDropForPt) +{ + srs_error_t err; + + // Test default value (0) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_EQ(0, conf.get_rtc_drop_for_pt("__defaultVhost__")); + EXPECT_EQ(0, conf.get_rtc_drop_for_pt("test.com")); + } + + // Test default value (0) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_EQ(0, conf.get_rtc_drop_for_pt("test.com")); + } + + // Test default value (0) when rtc section exists but no drop_for_pt directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_EQ(0, conf.get_rtc_drop_for_pt("test.com")); + } + + // Test explicit drop_for_pt value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{drop_for_pt 96;}}")); + EXPECT_EQ(96, conf.get_rtc_drop_for_pt("test.com")); + } + + // Test drop_for_pt negative value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{drop_for_pt -1;}}")); + EXPECT_EQ(-1, conf.get_rtc_drop_for_pt("test.com")); + } + + // Test empty drop_for_pt value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{drop_for_pt;}}")); + EXPECT_EQ(0, conf.get_rtc_drop_for_pt("test.com")); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{drop_for_pt 96;}}")); + + SrsSetEnvConfig(conf, rtc_drop_for_pt, "SRS_VHOST_RTC_DROP_FOR_PT", "97"); + EXPECT_EQ(97, conf.get_rtc_drop_for_pt("test.com")); + } +} + +VOID TEST(ConfigRtcVhostTest, CheckRtcToRtmp) +{ + srs_error_t err; + + // Test default value (false) when no vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + EXPECT_FALSE(conf.get_rtc_to_rtmp("__defaultVhost__")); + EXPECT_FALSE(conf.get_rtc_to_rtmp("test.com")); + } + + // Test default value (false) when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + EXPECT_FALSE(conf.get_rtc_to_rtmp("test.com")); + } + + // Test default value (false) when rtc section exists but no rtc_to_rtmp directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + EXPECT_FALSE(conf.get_rtc_to_rtmp("test.com")); + } + + // Test rtc_to_rtmp on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtc_to_rtmp on;}}")); + EXPECT_TRUE(conf.get_rtc_to_rtmp("test.com")); + } + + // Test rtc_to_rtmp off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtc_to_rtmp off;}}")); + EXPECT_FALSE(conf.get_rtc_to_rtmp("test.com")); + } + + // Test SRS_CONF_PREFER_FALSE behavior (only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtc_to_rtmp true;}}")); + EXPECT_FALSE(conf.get_rtc_to_rtmp("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtc_to_rtmp yes;}}")); + EXPECT_FALSE(conf.get_rtc_to_rtmp("test.com")); // "yes" != "on", so it's false + } + + // Test empty value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtc_to_rtmp;}}")); + EXPECT_FALSE(conf.get_rtc_to_rtmp("test.com")); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{rtc_to_rtmp off;}}")); + + SrsSetEnvConfig(conf, rtc_to_rtmp, "SRS_VHOST_RTC_RTC_TO_RTMP", "on"); + EXPECT_TRUE(conf.get_rtc_to_rtmp("test.com")); + } +} diff --git a/trunk/src/utest/srs_utest_config3.cpp b/trunk/src/utest/srs_utest_config3.cpp new file mode 100644 index 000000000..a1d7c2b91 --- /dev/null +++ b/trunk/src/utest/srs_utest_config3.cpp @@ -0,0 +1,7436 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// + +#include + +using namespace std; + +#include +#include +#include +#include + +VOID TEST(ConfigRtcTest, CheckRtcPliForRtmpDefault) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 6 seconds + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test default value when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no rtc section + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test default value when rtc section exists but no pli_for_rtmp + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + + // Should return default value when no pli_for_rtmp config + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } +} + +VOID TEST(ConfigRtcTest, CheckRtcPliForRtmpConfigFile) +{ + srs_error_t err; + + // Test valid configuration values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 3;}}")); + + EXPECT_EQ(3 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test decimal configuration values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 2.5;}}")); + + EXPECT_EQ((srs_utime_t)(2.5 * SRS_UTIME_SECONDS), conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test minimum valid value (0.5 seconds) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 0.5;}}")); + + EXPECT_EQ(500 * SRS_UTIME_MILLISECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test maximum valid value (30 seconds) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 30;}}")); + + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } +} + +VOID TEST(ConfigRtcTest, CheckRtcPliForRtmpRangeValidation) +{ + srs_error_t err; + + // Test value below minimum (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 0.1;}}")); + + // Should reset to default (6 seconds) when value is too small + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test value above maximum (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 60;}}")); + + // Should reset to default (6 seconds) when value is too large + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test zero value (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 0;}}")); + + // Should reset to default (6 seconds) when value is zero + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test negative value (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp -1;}}")); + + // Should reset to default (6 seconds) when value is negative + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } +} + +VOID TEST(ConfigRtcTest, CheckRtcPliForRtmpEnvironmentVariable) +{ + srs_error_t err; + + // Test environment variable override with valid value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 10;}}")); + + SrsSetEnvConfig(conf, pli_for_rtmp, "SRS_VHOST_RTC_PLI_FOR_RTMP", "5"); + + // Environment variable should override config file + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test environment variable with decimal value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, pli_for_rtmp, "SRS_VHOST_RTC_PLI_FOR_RTMP", "1.5"); + + EXPECT_EQ((srs_utime_t)(1.5 * SRS_UTIME_SECONDS), conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } + + // Test environment variable with minimum valid value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, pli_for_rtmp, "SRS_VHOST_RTC_PLI_FOR_RTMP", "0.5"); + + EXPECT_EQ(500 * SRS_UTIME_MILLISECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } + + // Test environment variable with maximum valid value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, pli_for_rtmp, "SRS_VHOST_RTC_PLI_FOR_RTMP", "30"); + + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } + + // Test environment variable with value below minimum (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, pli_for_rtmp, "SRS_VHOST_RTC_PLI_FOR_RTMP", "0.1"); + + // Should reset to default (6 seconds) when env value is too small + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } + + // Test environment variable with value above maximum (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, pli_for_rtmp, "SRS_VHOST_RTC_PLI_FOR_RTMP", "60"); + + // Should reset to default (6 seconds) when env value is too large + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } +} + +VOID TEST(ConfigRtcTest, CheckRtcPliForRtmpEdgeCases) +{ + srs_error_t err; + + // Test empty configuration value (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp;}}")); + + // Should return default value when config value is empty + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test empty environment variable (should use config file value) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 8;}}")); + + SrsSetEnvConfig(conf, pli_for_rtmp, "SRS_VHOST_RTC_PLI_FOR_RTMP", ""); + + // Should use config file value when env is empty + EXPECT_EQ(8 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test non-numeric environment variable (should parse as 0 and reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, pli_for_rtmp, "SRS_VHOST_RTC_PLI_FOR_RTMP", "invalid"); + + // Should reset to default when env value is non-numeric + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } + + // Test non-numeric configuration value (should parse as 0 and reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp invalid;}}")); + + // Should reset to default when config value is non-numeric + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test multiple vhosts with different configurations + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{rtc{pli_for_rtmp 2;}} " + "vhost vhost2.com{rtc{pli_for_rtmp 8;}} " + "vhost vhost3.com{rtc{enabled on;}}")); + + EXPECT_EQ(2 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("vhost1.com")); + EXPECT_EQ(8 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("vhost2.com")); + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("vhost3.com")); // default + } + + // Test environment variable affects all vhosts + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{rtc{pli_for_rtmp 2;}} " + "vhost vhost2.com{rtc{pli_for_rtmp 8;}}")); + + SrsSetEnvConfig(conf, pli_for_rtmp, "SRS_VHOST_RTC_PLI_FOR_RTMP", "15"); + + // Environment variable should override all vhost configs + EXPECT_EQ(15 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("vhost1.com")); + EXPECT_EQ(15 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("vhost2.com")); + EXPECT_EQ(15 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } +} + +VOID TEST(ConfigRtcTest, CheckRtcPliForRtmpBoundaryConditions) +{ + srs_error_t err; + + // Test exact minimum boundary (500ms) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 0.5;}}")); + + EXPECT_EQ(500 * SRS_UTIME_MILLISECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test just below minimum boundary (499ms - should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 0.499;}}")); + + // Should reset to default (6 seconds) when value is just below minimum + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test just above minimum boundary (501ms) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 0.501;}}")); + + EXPECT_EQ((srs_utime_t)(0.501 * SRS_UTIME_SECONDS), conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test exact maximum boundary (30 seconds) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 30;}}")); + + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test just above maximum boundary (30.1 seconds - should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 30.1;}}")); + + // Should reset to default (6 seconds) when value is just above maximum + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test just below maximum boundary (29.9 seconds) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 29.9;}}")); + + EXPECT_EQ((srs_utime_t)(29.9 * SRS_UTIME_SECONDS), conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test high precision decimal values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 1.234567;}}")); + + EXPECT_EQ((srs_utime_t)(1.234567 * SRS_UTIME_SECONDS), conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test very small valid value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 0.500001;}}")); + + EXPECT_EQ((srs_utime_t)(0.500001 * SRS_UTIME_SECONDS), conf.get_rtc_pli_for_rtmp("test.com")); + } +} + +VOID TEST(ConfigRtcTest, CheckRtcPliForRtmpEnvironmentEdgeCases) +{ + srs_error_t err; + + // Test environment variable with boundary values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Test exact minimum via environment + SrsSetEnvConfig(conf, pli_for_rtmp1, "SRS_VHOST_RTC_PLI_FOR_RTMP", "0.5"); + EXPECT_EQ(500 * SRS_UTIME_MILLISECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } + + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Test exact maximum via environment + SrsSetEnvConfig(conf, pli_for_rtmp2, "SRS_VHOST_RTC_PLI_FOR_RTMP", "30.0"); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } + + // Test environment variable with zero value (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, pli_for_rtmp3, "SRS_VHOST_RTC_PLI_FOR_RTMP", "0"); + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } + + // Test environment variable with negative value (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, pli_for_rtmp4, "SRS_VHOST_RTC_PLI_FOR_RTMP", "-5"); + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("__defaultVhost__")); + } + + // Test environment variable overrides config even when config is valid + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 5;}}")); + + SrsSetEnvConfig(conf, pli_for_rtmp5, "SRS_VHOST_RTC_PLI_FOR_RTMP", "10"); + + // Environment should override valid config value + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } + + // Test environment variable overrides config even when env value gets reset to default + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{pli_for_rtmp 5;}}")); + + SrsSetEnvConfig(conf, pli_for_rtmp6, "SRS_VHOST_RTC_PLI_FOR_RTMP", "100"); + + // Environment should override config, but invalid env value resets to default + EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp("test.com")); + } +} + +VOID TEST(ConfigRtcTest, CheckRtcNackEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true + EXPECT_TRUE(conf.get_rtc_nack_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_rtc_nack_enabled("test.com")); + } + + // Test default value when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no rtc section + EXPECT_TRUE(conf.get_rtc_nack_enabled("test.com")); + } + + // Test default value when rtc section exists but no nack config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + + // Should return default value when no nack config + EXPECT_TRUE(conf.get_rtc_nack_enabled("test.com")); + } + + // Test explicit nack enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack on;}}")); + + EXPECT_TRUE(conf.get_rtc_nack_enabled("test.com")); + } + + // Test explicit nack disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack off;}}")); + + EXPECT_FALSE(conf.get_rtc_nack_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack true;}}")); + EXPECT_TRUE(conf.get_rtc_nack_enabled("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack false;}}")); + EXPECT_TRUE(conf.get_rtc_nack_enabled("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack yes;}}")); + EXPECT_TRUE(conf.get_rtc_nack_enabled("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack no;}}")); + EXPECT_TRUE(conf.get_rtc_nack_enabled("test.com")); // "no" != "off", so it's true + } +} + +VOID TEST(ConfigRtcTest, CheckRtcNackNoCopy) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true + EXPECT_TRUE(conf.get_rtc_nack_no_copy("__defaultVhost__")); + EXPECT_TRUE(conf.get_rtc_nack_no_copy("test.com")); + } + + // Test default value when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no rtc section + EXPECT_TRUE(conf.get_rtc_nack_no_copy("test.com")); + } + + // Test default value when rtc section exists but no nack_no_copy config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + + // Should return default value when no nack_no_copy config + EXPECT_TRUE(conf.get_rtc_nack_no_copy("test.com")); + } + + // Test default value when nack_no_copy has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack_no_copy;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_rtc_nack_no_copy("test.com")); + } + + // Test explicit nack_no_copy enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack_no_copy on;}}")); + + EXPECT_TRUE(conf.get_rtc_nack_no_copy("test.com")); + } + + // Test explicit nack_no_copy disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack_no_copy off;}}")); + + EXPECT_FALSE(conf.get_rtc_nack_no_copy("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack_no_copy true;}}")); + EXPECT_TRUE(conf.get_rtc_nack_no_copy("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack_no_copy false;}}")); + EXPECT_TRUE(conf.get_rtc_nack_no_copy("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack_no_copy yes;}}")); + EXPECT_TRUE(conf.get_rtc_nack_no_copy("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{nack_no_copy no;}}")); + EXPECT_TRUE(conf.get_rtc_nack_no_copy("test.com")); // "no" != "off", so it's true + } +} + +VOID TEST(ConfigRtcTest, CheckRtcTwccEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true + EXPECT_TRUE(conf.get_rtc_twcc_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_rtc_twcc_enabled("test.com")); + } + + // Test default value when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no rtc section + EXPECT_TRUE(conf.get_rtc_twcc_enabled("test.com")); + } + + // Test default value when rtc section exists but no twcc config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + + // Should return default value when no twcc config + EXPECT_TRUE(conf.get_rtc_twcc_enabled("test.com")); + } + + // Test explicit twcc enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{twcc on;}}")); + + EXPECT_TRUE(conf.get_rtc_twcc_enabled("test.com")); + } + + // Test explicit twcc disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{twcc off;}}")); + + EXPECT_FALSE(conf.get_rtc_twcc_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{twcc true;}}")); + EXPECT_TRUE(conf.get_rtc_twcc_enabled("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{twcc false;}}")); + EXPECT_TRUE(conf.get_rtc_twcc_enabled("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{twcc yes;}}")); + EXPECT_TRUE(conf.get_rtc_twcc_enabled("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{twcc no;}}")); + EXPECT_TRUE(conf.get_rtc_twcc_enabled("test.com")); // "no" != "off", so it's true + } +} + +VOID TEST(ConfigRtcTest, CheckRtcOpusBitrate) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 48000 + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("__defaultVhost__")); + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); + } + + // Test default value when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no rtc section + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); + } + + // Test default value when rtc section exists but no opus_bitrate config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + + // Should return default value when no opus_bitrate config + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); + } + + // Test default value when opus_bitrate has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate;}}")); + + // Should return default value when empty argument + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); + } + + // Test valid opus bitrate values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate 64000;}}")); + EXPECT_EQ(64000, conf.get_rtc_opus_bitrate("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate 8000;}}")); + EXPECT_EQ(8000, conf.get_rtc_opus_bitrate("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate 320000;}}")); + EXPECT_EQ(320000, conf.get_rtc_opus_bitrate("test.com")); + } + + // Test invalid opus bitrate values (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate 7999;}}")); + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); // Below minimum, reset to default + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate 320001;}}")); + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); // Above maximum, reset to default + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate 0;}}")); + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); // Zero, reset to default + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate -1000;}}")); + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); // Negative, reset to default + } +} + +VOID TEST(ConfigRtcTest, CheckRtcOpusBitrateEnvironment) +{ + srs_error_t err; + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate 64000;}}")); + + SrsSetEnvConfig(conf, opus_bitrate1, "SRS_VHOST_RTC_OPUS_BITRATE", "96000"); + + // Environment should override config value + EXPECT_EQ(96000, conf.get_rtc_opus_bitrate("test.com")); + } + + // Test environment variable with valid boundary values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, opus_bitrate2, "SRS_VHOST_RTC_OPUS_BITRATE", "8000"); + EXPECT_EQ(8000, conf.get_rtc_opus_bitrate("test.com")); + + SrsSetEnvConfig(conf, opus_bitrate3, "SRS_VHOST_RTC_OPUS_BITRATE", "320000"); + EXPECT_EQ(320000, conf.get_rtc_opus_bitrate("test.com")); + } + + // Test environment variable with invalid values (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, opus_bitrate4, "SRS_VHOST_RTC_OPUS_BITRATE", "7999"); + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); // Below minimum, reset to default + + SrsSetEnvConfig(conf, opus_bitrate5, "SRS_VHOST_RTC_OPUS_BITRATE", "320001"); + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); // Above maximum, reset to default + + SrsSetEnvConfig(conf, opus_bitrate6, "SRS_VHOST_RTC_OPUS_BITRATE", "0"); + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); // Zero, reset to default + } + + // Test environment variable overrides config even when config is valid + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate 64000;}}")); + + SrsSetEnvConfig(conf, opus_bitrate7, "SRS_VHOST_RTC_OPUS_BITRATE", "128000"); + + // Environment should override valid config value + EXPECT_EQ(128000, conf.get_rtc_opus_bitrate("test.com")); + } + + // Test environment variable overrides config even when env value gets reset to default + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{opus_bitrate 64000;}}")); + + SrsSetEnvConfig(conf, opus_bitrate8, "SRS_VHOST_RTC_OPUS_BITRATE", "500000"); + + // Environment should override config, but invalid env value resets to default + EXPECT_EQ(48000, conf.get_rtc_opus_bitrate("test.com")); + } +} + +VOID TEST(ConfigRtcTest, CheckRtcAacBitrate) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 48000 + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("__defaultVhost__")); + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); + } + + // Test default value when vhost exists but no rtc section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no rtc section + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); + } + + // Test default value when rtc section exists but no aac_bitrate config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{enabled on;}}")); + + // Should return default value when no aac_bitrate config + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); + } + + // Test default value when aac_bitrate has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate;}}")); + + // Should return default value when empty argument + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); + } + + // Test valid aac bitrate values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate 64000;}}")); + EXPECT_EQ(64000, conf.get_rtc_aac_bitrate("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate 8000;}}")); + EXPECT_EQ(8000, conf.get_rtc_aac_bitrate("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate 320000;}}")); + EXPECT_EQ(320000, conf.get_rtc_aac_bitrate("test.com")); + } + + // Test invalid aac bitrate values (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate 7999;}}")); + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); // Below minimum, reset to default + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate 320001;}}")); + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); // Above maximum, reset to default + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate 0;}}")); + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); // Zero, reset to default + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate -1000;}}")); + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); // Negative, reset to default + } +} + +VOID TEST(ConfigRtcTest, CheckRtcAacBitrateEnvironment) +{ + srs_error_t err; + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate 64000;}}")); + + SrsSetEnvConfig(conf, aac_bitrate1, "SRS_VHOST_RTC_AAC_BITRATE", "96000"); + + // Environment should override config value + EXPECT_EQ(96000, conf.get_rtc_aac_bitrate("test.com")); + } + + // Test environment variable with valid boundary values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, aac_bitrate2, "SRS_VHOST_RTC_AAC_BITRATE", "8000"); + EXPECT_EQ(8000, conf.get_rtc_aac_bitrate("test.com")); + + SrsSetEnvConfig(conf, aac_bitrate3, "SRS_VHOST_RTC_AAC_BITRATE", "320000"); + EXPECT_EQ(320000, conf.get_rtc_aac_bitrate("test.com")); + } + + // Test environment variable with invalid values (should reset to default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, aac_bitrate4, "SRS_VHOST_RTC_AAC_BITRATE", "7999"); + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); // Below minimum, reset to default + + SrsSetEnvConfig(conf, aac_bitrate5, "SRS_VHOST_RTC_AAC_BITRATE", "320001"); + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); // Above maximum, reset to default + + SrsSetEnvConfig(conf, aac_bitrate6, "SRS_VHOST_RTC_AAC_BITRATE", "0"); + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); // Zero, reset to default + } + + // Test environment variable overrides config even when config is valid + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate 64000;}}")); + + SrsSetEnvConfig(conf, aac_bitrate7, "SRS_VHOST_RTC_AAC_BITRATE", "128000"); + + // Environment should override valid config value + EXPECT_EQ(128000, conf.get_rtc_aac_bitrate("test.com")); + } + + // Test environment variable overrides config even when env value gets reset to default + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{rtc{aac_bitrate 64000;}}")); + + SrsSetEnvConfig(conf, aac_bitrate8, "SRS_VHOST_RTC_AAC_BITRATE", "500000"); + + // Environment should override config, but invalid env value resets to default + EXPECT_EQ(48000, conf.get_rtc_aac_bitrate("test.com")); + } +} + +VOID TEST(ConfigVhostTest, CheckGopCacheMaxFrames) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 2500 + EXPECT_EQ(2500, conf.get_gop_cache_max_frames("__defaultVhost__")); + EXPECT_EQ(2500, conf.get_gop_cache_max_frames("test.com")); + } + + // Test default value when vhost exists but no play section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no play section + EXPECT_EQ(2500, conf.get_gop_cache_max_frames("test.com")); + } + + // Test default value when play section exists but no gop_cache_max_frames config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no gop_cache_max_frames config + EXPECT_EQ(2500, conf.get_gop_cache_max_frames("test.com")); + } + + // Test default value when gop_cache_max_frames has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{gop_cache_max_frames;}}")); + + // Should return default value when empty argument + EXPECT_EQ(2500, conf.get_gop_cache_max_frames("test.com")); + } + + // Test valid gop_cache_max_frames values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{gop_cache_max_frames 1000;}}")); + EXPECT_EQ(1000, conf.get_gop_cache_max_frames("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{gop_cache_max_frames 5000;}}")); + EXPECT_EQ(5000, conf.get_gop_cache_max_frames("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{gop_cache_max_frames 0;}}")); + EXPECT_EQ(0, conf.get_gop_cache_max_frames("test.com")); + } + + // Test negative values (should be parsed as is) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{gop_cache_max_frames -100;}}")); + EXPECT_EQ(-100, conf.get_gop_cache_max_frames("test.com")); + } +} + +VOID TEST(ConfigVhostTest, CheckDebugSrsUpnode) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true + EXPECT_TRUE(conf.get_debug_srs_upnode("__defaultVhost__")); + EXPECT_TRUE(conf.get_debug_srs_upnode("test.com")); + } + + // Test default value when vhost exists but no cluster section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no cluster section + EXPECT_TRUE(conf.get_debug_srs_upnode("test.com")); + } + + // Test default value when cluster exists but no debug_srs_upnode config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{mode local;}}")); + + // Should return default value when no debug_srs_upnode config + EXPECT_TRUE(conf.get_debug_srs_upnode("test.com")); + } + + // Test default value when debug_srs_upnode has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{debug_srs_upnode;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_debug_srs_upnode("test.com")); + } + + // Test explicit debug_srs_upnode enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{debug_srs_upnode on;}}")); + + EXPECT_TRUE(conf.get_debug_srs_upnode("test.com")); + } + + // Test explicit debug_srs_upnode disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{debug_srs_upnode off;}}")); + + EXPECT_FALSE(conf.get_debug_srs_upnode("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{debug_srs_upnode true;}}")); + EXPECT_TRUE(conf.get_debug_srs_upnode("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{debug_srs_upnode false;}}")); + EXPECT_TRUE(conf.get_debug_srs_upnode("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{debug_srs_upnode yes;}}")); + EXPECT_TRUE(conf.get_debug_srs_upnode("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{debug_srs_upnode no;}}")); + EXPECT_TRUE(conf.get_debug_srs_upnode("test.com")); // "no" != "off", so it's true + } +} + +VOID TEST(ConfigVhostTest, CheckAtc) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_atc("__defaultVhost__")); + EXPECT_FALSE(conf.get_atc("test.com")); + } + + // Test default value when vhost exists but no play section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no play section + EXPECT_FALSE(conf.get_atc("test.com")); + } + + // Test default value when play exists but no atc config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no atc config + EXPECT_FALSE(conf.get_atc("test.com")); + } + + // Test default value when atc has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_atc("test.com")); + } + + // Test explicit atc enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc on;}}")); + + EXPECT_TRUE(conf.get_atc("test.com")); + } + + // Test explicit atc disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc off;}}")); + + EXPECT_FALSE(conf.get_atc("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc true;}}")); + EXPECT_FALSE(conf.get_atc("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc false;}}")); + EXPECT_FALSE(conf.get_atc("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc yes;}}")); + EXPECT_FALSE(conf.get_atc("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc no;}}")); + EXPECT_FALSE(conf.get_atc("test.com")); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigVhostTest, CheckAtcAuto) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_atc_auto("__defaultVhost__")); + EXPECT_FALSE(conf.get_atc_auto("test.com")); + } + + // Test default value when vhost exists but no play section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no play section + EXPECT_FALSE(conf.get_atc_auto("test.com")); + } + + // Test default value when play exists but no atc_auto config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no atc_auto config + EXPECT_FALSE(conf.get_atc_auto("test.com")); + } + + // Test default value when atc_auto has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc_auto;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_atc_auto("test.com")); + } + + // Test explicit atc_auto enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc_auto on;}}")); + + EXPECT_TRUE(conf.get_atc_auto("test.com")); + } + + // Test explicit atc_auto disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc_auto off;}}")); + + EXPECT_FALSE(conf.get_atc_auto("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc_auto true;}}")); + EXPECT_FALSE(conf.get_atc_auto("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc_auto false;}}")); + EXPECT_FALSE(conf.get_atc_auto("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc_auto yes;}}")); + EXPECT_FALSE(conf.get_atc_auto("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{atc_auto no;}}")); + EXPECT_FALSE(conf.get_atc_auto("test.com")); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigVhostTest, CheckTimeJitter) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 1 (SrsRtmpJitterAlgorithmFULL) - default is "full" + EXPECT_EQ(1, conf.get_time_jitter("__defaultVhost__")); + EXPECT_EQ(1, conf.get_time_jitter("test.com")); + } + + // Test default value when vhost exists but no play section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no play section + EXPECT_EQ(1, conf.get_time_jitter("test.com")); + } + + // Test default value when play exists but no time_jitter config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no time_jitter config + EXPECT_EQ(1, conf.get_time_jitter("test.com")); + } + + // Test default value when time_jitter has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{time_jitter;}}")); + + // Should return default value when empty argument + EXPECT_EQ(1, conf.get_time_jitter("test.com")); + } + + // Test various time_jitter string values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{time_jitter off;}}")); + EXPECT_EQ(3, conf.get_time_jitter("test.com")); // SrsRtmpJitterAlgorithmOFF = 3 + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{time_jitter full;}}")); + EXPECT_EQ(1, conf.get_time_jitter("test.com")); // SrsRtmpJitterAlgorithmFULL = 1 + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{time_jitter zero;}}")); + EXPECT_EQ(2, conf.get_time_jitter("test.com")); // SrsRtmpJitterAlgorithmZERO = 2 + } + + // Test invalid time_jitter values (should return OFF=3) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{time_jitter invalid;}}")); + EXPECT_EQ(3, conf.get_time_jitter("test.com")); // Should return OFF=3 for invalid value + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{time_jitter simple;}}")); + EXPECT_EQ(3, conf.get_time_jitter("test.com")); // "simple" is not supported, returns OFF=3 + } +} + +VOID TEST(ConfigVhostTest, CheckMixCorrect) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_mix_correct("__defaultVhost__")); + EXPECT_FALSE(conf.get_mix_correct("test.com")); + } + + // Test default value when vhost exists but no play section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no play section + EXPECT_FALSE(conf.get_mix_correct("test.com")); + } + + // Test default value when play exists but no mix_correct config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no mix_correct config + EXPECT_FALSE(conf.get_mix_correct("test.com")); + } + + // Test default value when mix_correct has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mix_correct;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_mix_correct("test.com")); + } + + // Test explicit mix_correct enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mix_correct on;}}")); + + EXPECT_TRUE(conf.get_mix_correct("test.com")); + } + + // Test explicit mix_correct disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mix_correct off;}}")); + + EXPECT_FALSE(conf.get_mix_correct("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mix_correct true;}}")); + EXPECT_FALSE(conf.get_mix_correct("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mix_correct false;}}")); + EXPECT_FALSE(conf.get_mix_correct("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mix_correct yes;}}")); + EXPECT_FALSE(conf.get_mix_correct("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mix_correct no;}}")); + EXPECT_FALSE(conf.get_mix_correct("test.com")); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigHlsTest, CheckHlsM3u8File) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "[app]/[stream].m3u8" + EXPECT_STREQ("[app]/[stream].m3u8", conf.get_hls_m3u8_file("__defaultVhost__").c_str()); + EXPECT_STREQ("[app]/[stream].m3u8", conf.get_hls_m3u8_file("test.com").c_str()); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_STREQ("[app]/[stream].m3u8", conf.get_hls_m3u8_file("test.com").c_str()); + } + + // Test default value when hls section exists but no hls_m3u8_file config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_m3u8_file config + EXPECT_STREQ("[app]/[stream].m3u8", conf.get_hls_m3u8_file("test.com").c_str()); + } + + // Test default value when hls_m3u8_file has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_m3u8_file;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("[app]/[stream].m3u8", conf.get_hls_m3u8_file("test.com").c_str()); + } + + // Test custom hls_m3u8_file values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_m3u8_file custom/[stream].m3u8;}}")); + EXPECT_STREQ("custom/[stream].m3u8", conf.get_hls_m3u8_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_m3u8_file [app]/live.m3u8;}}")); + EXPECT_STREQ("[app]/live.m3u8", conf.get_hls_m3u8_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_m3u8_file /path/to/[stream]-[seq].m3u8;}}")); + EXPECT_STREQ("/path/to/[stream]-[seq].m3u8", conf.get_hls_m3u8_file("test.com").c_str()); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsM3u8FileEnvironment) +{ + srs_error_t err; + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_m3u8_file custom.m3u8;}}")); + + SrsSetEnvConfig(conf, hls_m3u8_file, "SRS_VHOST_HLS_HLS_M3U8_FILE", "env/[stream].m3u8"); + + // Environment should override config value + EXPECT_STREQ("env/[stream].m3u8", conf.get_hls_m3u8_file("test.com").c_str()); + } + + // Test environment variable with default vhost + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, hls_m3u8_file2, "SRS_VHOST_HLS_HLS_M3U8_FILE", "global/[app]/[stream].m3u8"); + + EXPECT_STREQ("global/[app]/[stream].m3u8", conf.get_hls_m3u8_file("__defaultVhost__").c_str()); + } + + // Test empty environment variable (should use config file value) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_m3u8_file config.m3u8;}}")); + + SrsSetEnvConfig(conf, hls_m3u8_file3, "SRS_VHOST_HLS_HLS_M3U8_FILE", ""); + + // Should use config file value when env is empty + EXPECT_STREQ("config.m3u8", conf.get_hls_m3u8_file("test.com").c_str()); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsTsFile) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "[app]/[stream]-[seq].ts" + EXPECT_STREQ("[app]/[stream]-[seq].ts", conf.get_hls_ts_file("__defaultVhost__").c_str()); + EXPECT_STREQ("[app]/[stream]-[seq].ts", conf.get_hls_ts_file("test.com").c_str()); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_STREQ("[app]/[stream]-[seq].ts", conf.get_hls_ts_file("test.com").c_str()); + } + + // Test default value when hls section exists but no hls_ts_file config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_ts_file config + EXPECT_STREQ("[app]/[stream]-[seq].ts", conf.get_hls_ts_file("test.com").c_str()); + } + + // Test default value when hls_ts_file has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_file;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("[app]/[stream]-[seq].ts", conf.get_hls_ts_file("test.com").c_str()); + } + + // Test custom hls_ts_file values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_file custom/[stream]-[seq].ts;}}")); + EXPECT_STREQ("custom/[stream]-[seq].ts", conf.get_hls_ts_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_file [app]/segment-[seq].ts;}}")); + EXPECT_STREQ("[app]/segment-[seq].ts", conf.get_hls_ts_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_file /path/to/[stream]/[seq].ts;}}")); + EXPECT_STREQ("/path/to/[stream]/[seq].ts", conf.get_hls_ts_file("test.com").c_str()); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_file custom.ts;}}")); + + SrsSetEnvConfig(conf, hls_ts_file, "SRS_VHOST_HLS_HLS_TS_FILE", "env/[stream]-[seq].ts"); + + // Environment should override config value + EXPECT_STREQ("env/[stream]-[seq].ts", conf.get_hls_ts_file("test.com").c_str()); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsFmp4File) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "[app]/[stream]-[seq].m4s" + EXPECT_STREQ("[app]/[stream]-[seq].m4s", conf.get_hls_fmp4_file("__defaultVhost__").c_str()); + EXPECT_STREQ("[app]/[stream]-[seq].m4s", conf.get_hls_fmp4_file("test.com").c_str()); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_STREQ("[app]/[stream]-[seq].m4s", conf.get_hls_fmp4_file("test.com").c_str()); + } + + // Test default value when hls section exists but no hls_fmp4_file config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_fmp4_file config + EXPECT_STREQ("[app]/[stream]-[seq].m4s", conf.get_hls_fmp4_file("test.com").c_str()); + } + + // Test default value when hls_fmp4_file has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fmp4_file;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("[app]/[stream]-[seq].m4s", conf.get_hls_fmp4_file("test.com").c_str()); + } + + // Test custom hls_fmp4_file values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fmp4_file custom/[stream]-[seq].m4s;}}")); + EXPECT_STREQ("custom/[stream]-[seq].m4s", conf.get_hls_fmp4_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fmp4_file [app]/segment-[seq].m4s;}}")); + EXPECT_STREQ("[app]/segment-[seq].m4s", conf.get_hls_fmp4_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fmp4_file /path/to/[stream]/[seq].m4s;}}")); + EXPECT_STREQ("/path/to/[stream]/[seq].m4s", conf.get_hls_fmp4_file("test.com").c_str()); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fmp4_file custom.m4s;}}")); + + SrsSetEnvConfig(conf, hls_fmp4_file, "SRS_VHOST_HLS_HLS_FMP4_FILE", "env/[stream]-[seq].m4s"); + + // Environment should override config value + EXPECT_STREQ("env/[stream]-[seq].m4s", conf.get_hls_fmp4_file("test.com").c_str()); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsInitFile) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "[app]/[stream]/init.mp4" + EXPECT_STREQ("[app]/[stream]/init.mp4", conf.get_hls_init_file("__defaultVhost__").c_str()); + EXPECT_STREQ("[app]/[stream]/init.mp4", conf.get_hls_init_file("test.com").c_str()); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_STREQ("[app]/[stream]/init.mp4", conf.get_hls_init_file("test.com").c_str()); + } + + // Test default value when hls section exists but no hls_init_file config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_init_file config + EXPECT_STREQ("[app]/[stream]/init.mp4", conf.get_hls_init_file("test.com").c_str()); + } + + // Test default value when hls_init_file has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_init_file;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("[app]/[stream]/init.mp4", conf.get_hls_init_file("test.com").c_str()); + } + + // Test custom hls_init_file values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_init_file custom/[stream]/init.mp4;}}")); + EXPECT_STREQ("custom/[stream]/init.mp4", conf.get_hls_init_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_init_file [app]/[stream]-init.mp4;}}")); + EXPECT_STREQ("[app]/[stream]-init.mp4", conf.get_hls_init_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_init_file /path/to/[stream]/initialization.mp4;}}")); + EXPECT_STREQ("/path/to/[stream]/initialization.mp4", conf.get_hls_init_file("test.com").c_str()); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_init_file custom-init.mp4;}}")); + + SrsSetEnvConfig(conf, hls_init_file, "SRS_VHOST_HLS_HLS_INIT_FILE", "env/[stream]/init.mp4"); + + // Environment should override config value + EXPECT_STREQ("env/[stream]/init.mp4", conf.get_hls_init_file("test.com").c_str()); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsTsFloor) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_hls_ts_floor("__defaultVhost__")); + EXPECT_FALSE(conf.get_hls_ts_floor("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_FALSE(conf.get_hls_ts_floor("test.com")); + } + + // Test default value when hls section exists but no hls_ts_floor config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_ts_floor config + EXPECT_FALSE(conf.get_hls_ts_floor("test.com")); + } + + // Test default value when hls_ts_floor has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_floor;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_hls_ts_floor("test.com")); + } + + // Test explicit hls_ts_floor enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_floor on;}}")); + + EXPECT_TRUE(conf.get_hls_ts_floor("test.com")); + } + + // Test explicit hls_ts_floor disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_floor off;}}")); + + EXPECT_FALSE(conf.get_hls_ts_floor("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_floor true;}}")); + EXPECT_FALSE(conf.get_hls_ts_floor("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_floor false;}}")); + EXPECT_FALSE(conf.get_hls_ts_floor("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_floor yes;}}")); + EXPECT_FALSE(conf.get_hls_ts_floor("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_floor no;}}")); + EXPECT_FALSE(conf.get_hls_ts_floor("test.com")); // "no" != "on", so it's false + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_floor off;}}")); + + SrsSetEnvConfig(conf, hls_ts_floor, "SRS_VHOST_HLS_HLS_TS_FLOOR", "on"); + + // Environment should override config value + EXPECT_TRUE(conf.get_hls_ts_floor("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsFragment) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 10 seconds + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hls_fragment("__defaultVhost__")); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hls_fragment("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hls_fragment("test.com")); + } + + // Test default value when hls section exists but no hls_fragment config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_fragment config + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hls_fragment("test.com")); + } + + // Test default value when hls_fragment has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragment;}}")); + + // Should return default value when empty argument + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hls_fragment("test.com")); + } + + // Test valid hls_fragment values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragment 5;}}")); + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_hls_fragment("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragment 15;}}")); + EXPECT_EQ(15 * SRS_UTIME_SECONDS, conf.get_hls_fragment("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragment 2.5;}}")); + EXPECT_EQ((srs_utime_t)(2.5 * SRS_UTIME_SECONDS), conf.get_hls_fragment("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragment 0.5;}}")); + EXPECT_EQ(500 * SRS_UTIME_MILLISECONDS, conf.get_hls_fragment("test.com")); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragment 5;}}")); + + SrsSetEnvConfig(conf, hls_fragment, "SRS_VHOST_HLS_HLS_FRAGMENT", "8"); + + // Environment should override config value + EXPECT_EQ(8 * SRS_UTIME_SECONDS, conf.get_hls_fragment("test.com")); + } + + // Test environment variable with decimal value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, hls_fragment2, "SRS_VHOST_HLS_HLS_FRAGMENT", "3.5"); + + EXPECT_EQ((srs_utime_t)(3.5 * SRS_UTIME_SECONDS), conf.get_hls_fragment("__defaultVhost__")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsTdRatio) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 1.0 + EXPECT_EQ(1.0, conf.get_hls_td_ratio("__defaultVhost__")); + EXPECT_EQ(1.0, conf.get_hls_td_ratio("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_EQ(1.0, conf.get_hls_td_ratio("test.com")); + } + + // Test default value when hls section exists but no hls_td_ratio config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_td_ratio config + EXPECT_EQ(1.0, conf.get_hls_td_ratio("test.com")); + } + + // Test default value when hls_td_ratio has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_td_ratio;}}")); + + // Should return default value when empty argument + EXPECT_EQ(1.0, conf.get_hls_td_ratio("test.com")); + } + + // Test valid hls_td_ratio values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_td_ratio 1.5;}}")); + EXPECT_EQ(1.5, conf.get_hls_td_ratio("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_td_ratio 2.0;}}")); + EXPECT_EQ(2.0, conf.get_hls_td_ratio("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_td_ratio 0.8;}}")); + EXPECT_EQ(0.8, conf.get_hls_td_ratio("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_td_ratio 3;}}")); + EXPECT_EQ(3.0, conf.get_hls_td_ratio("test.com")); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_td_ratio 1.5;}}")); + + SrsSetEnvConfig(conf, hls_td_ratio, "SRS_VHOST_HLS_HLS_TD_RATIO", "2.5"); + + // Environment should override config value + EXPECT_EQ(2.5, conf.get_hls_td_ratio("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsAofRatio) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 2.1 + EXPECT_EQ(2.1, conf.get_hls_aof_ratio("__defaultVhost__")); + EXPECT_EQ(2.1, conf.get_hls_aof_ratio("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_EQ(2.1, conf.get_hls_aof_ratio("test.com")); + } + + // Test default value when hls section exists but no hls_aof_ratio config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_aof_ratio config + EXPECT_EQ(2.1, conf.get_hls_aof_ratio("test.com")); + } + + // Test default value when hls_aof_ratio has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_aof_ratio;}}")); + + // Should return default value when empty argument + EXPECT_EQ(2.1, conf.get_hls_aof_ratio("test.com")); + } + + // Test valid hls_aof_ratio values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_aof_ratio 1.5;}}")); + EXPECT_EQ(1.5, conf.get_hls_aof_ratio("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_aof_ratio 3.0;}}")); + EXPECT_EQ(3.0, conf.get_hls_aof_ratio("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_aof_ratio 0.5;}}")); + EXPECT_EQ(0.5, conf.get_hls_aof_ratio("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_aof_ratio 5;}}")); + EXPECT_EQ(5.0, conf.get_hls_aof_ratio("test.com")); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_aof_ratio 1.5;}}")); + + SrsSetEnvConfig(conf, hls_aof_ratio, "SRS_VHOST_HLS_HLS_AOF_RATIO", "3.5"); + + // Environment should override config value + EXPECT_EQ(3.5, conf.get_hls_aof_ratio("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsWindow) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 60 seconds + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hls_window("__defaultVhost__")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hls_window("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hls_window("test.com")); + } + + // Test default value when hls section exists but no hls_window config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_window config + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hls_window("test.com")); + } + + // Test default value when hls_window has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_window;}}")); + + // Should return default value when empty argument + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hls_window("test.com")); + } + + // Test valid hls_window values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_window 30;}}")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_hls_window("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_window 120;}}")); + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_hls_window("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_window 10.5;}}")); + EXPECT_EQ((srs_utime_t)(10.5 * SRS_UTIME_SECONDS), conf.get_hls_window("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_window 0.5;}}")); + EXPECT_EQ(500 * SRS_UTIME_MILLISECONDS, conf.get_hls_window("test.com")); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_window 30;}}")); + + SrsSetEnvConfig(conf, hls_window, "SRS_VHOST_HLS_HLS_WINDOW", "90"); + + // Environment should override config value + EXPECT_EQ(90 * SRS_UTIME_SECONDS, conf.get_hls_window("test.com")); + } + + // Test environment variable with decimal value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, hls_window2, "SRS_VHOST_HLS_HLS_WINDOW", "45.5"); + + EXPECT_EQ((srs_utime_t)(45.5 * SRS_UTIME_SECONDS), conf.get_hls_window("__defaultVhost__")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsOnError) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "continue" + EXPECT_STREQ("continue", conf.get_hls_on_error("__defaultVhost__").c_str()); + EXPECT_STREQ("continue", conf.get_hls_on_error("test.com").c_str()); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_STREQ("continue", conf.get_hls_on_error("test.com").c_str()); + } + + // Test default value when hls section exists but no hls_on_error config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_on_error config + EXPECT_STREQ("continue", conf.get_hls_on_error("test.com").c_str()); + } + + // Test default value when hls_on_error has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_on_error;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("continue", conf.get_hls_on_error("test.com").c_str()); + } + + // Test custom hls_on_error values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_on_error disconnect;}}")); + EXPECT_STREQ("disconnect", conf.get_hls_on_error("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_on_error ignore;}}")); + EXPECT_STREQ("ignore", conf.get_hls_on_error("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_on_error custom_action;}}")); + EXPECT_STREQ("custom_action", conf.get_hls_on_error("test.com").c_str()); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_on_error disconnect;}}")); + + SrsSetEnvConfig(conf, hls_on_error, "SRS_VHOST_HLS_HLS_ON_ERROR", "ignore"); + + // Environment should override config value + EXPECT_STREQ("ignore", conf.get_hls_on_error("test.com").c_str()); + } +} + +VOID TEST(ConfigHlsTest, CheckVhostHlsNbNotify) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 64 + EXPECT_EQ(64, conf.get_vhost_hls_nb_notify("__defaultVhost__")); + EXPECT_EQ(64, conf.get_vhost_hls_nb_notify("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_EQ(64, conf.get_vhost_hls_nb_notify("test.com")); + } + + // Test default value when hls section exists but no hls_nb_notify config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_nb_notify config + EXPECT_EQ(64, conf.get_vhost_hls_nb_notify("test.com")); + } + + // Test default value when hls_nb_notify has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_nb_notify;}}")); + + // Should return default value when empty argument + EXPECT_EQ(64, conf.get_vhost_hls_nb_notify("test.com")); + } + + // Test valid hls_nb_notify values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_nb_notify 32;}}")); + EXPECT_EQ(32, conf.get_vhost_hls_nb_notify("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_nb_notify 128;}}")); + EXPECT_EQ(128, conf.get_vhost_hls_nb_notify("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_nb_notify 0;}}")); + EXPECT_EQ(0, conf.get_vhost_hls_nb_notify("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_nb_notify 1;}}")); + EXPECT_EQ(1, conf.get_vhost_hls_nb_notify("test.com")); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_nb_notify 32;}}")); + + SrsSetEnvConfig(conf, hls_nb_notify, "SRS_VHOST_HLS_HLS_NB_NOTIFY", "256"); + + // Environment should override config value + EXPECT_EQ(256, conf.get_vhost_hls_nb_notify("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckVhostHlsDtsDirectly) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true (SRS_CONF_PREFER_TRUE) + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("__defaultVhost__")); + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("test.com")); + } + + // Test default value when hls section exists but no hls_dts_directly config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_dts_directly config + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("test.com")); + } + + // Test default value when hls_dts_directly has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dts_directly;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("test.com")); + } + + // Test explicit hls_dts_directly enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dts_directly on;}}")); + + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("test.com")); + } + + // Test explicit hls_dts_directly disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dts_directly off;}}")); + + EXPECT_FALSE(conf.get_vhost_hls_dts_directly("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dts_directly true;}}")); + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dts_directly false;}}")); + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dts_directly yes;}}")); + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dts_directly no;}}")); + EXPECT_TRUE(conf.get_vhost_hls_dts_directly("test.com")); // "no" != "off", so it's true + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dts_directly on;}}")); + + SrsSetEnvConfig(conf, hls_dts_directly, "SRS_VHOST_HLS_HLS_DTS_DIRECTLY", "off"); + + // Environment should override config value + EXPECT_FALSE(conf.get_vhost_hls_dts_directly("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsCtxEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true (SRS_CONF_PREFER_TRUE) + EXPECT_TRUE(conf.get_hls_ctx_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_hls_ctx_enabled("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_TRUE(conf.get_hls_ctx_enabled("test.com")); + } + + // Test default value when hls section exists but no hls_ctx config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_ctx config + EXPECT_TRUE(conf.get_hls_ctx_enabled("test.com")); + } + + // Test default value when hls_ctx has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ctx;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_hls_ctx_enabled("test.com")); + } + + // Test explicit hls_ctx enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ctx on;}}")); + + EXPECT_TRUE(conf.get_hls_ctx_enabled("test.com")); + } + + // Test explicit hls_ctx disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ctx off;}}")); + + EXPECT_FALSE(conf.get_hls_ctx_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ctx true;}}")); + EXPECT_TRUE(conf.get_hls_ctx_enabled("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ctx false;}}")); + EXPECT_TRUE(conf.get_hls_ctx_enabled("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ctx yes;}}")); + EXPECT_TRUE(conf.get_hls_ctx_enabled("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ctx no;}}")); + EXPECT_TRUE(conf.get_hls_ctx_enabled("test.com")); // "no" != "off", so it's true + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ctx on;}}")); + + SrsSetEnvConfig(conf, hls_ctx, "SRS_VHOST_HLS_HLS_CTX", "off"); + + // Environment should override config value + EXPECT_FALSE(conf.get_hls_ctx_enabled("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsTsCtxEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true (SRS_CONF_PREFER_TRUE) + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("test.com")); + } + + // Test default value when hls section exists but no hls_ts_ctx config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_ts_ctx config + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("test.com")); + } + + // Test default value when hls_ts_ctx has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_ctx;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("test.com")); + } + + // Test explicit hls_ts_ctx enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_ctx on;}}")); + + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("test.com")); + } + + // Test explicit hls_ts_ctx disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_ctx off;}}")); + + EXPECT_FALSE(conf.get_hls_ts_ctx_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_ctx true;}}")); + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_ctx false;}}")); + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_ctx yes;}}")); + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_ctx no;}}")); + EXPECT_TRUE(conf.get_hls_ts_ctx_enabled("test.com")); // "no" != "off", so it's true + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_ts_ctx on;}}")); + + SrsSetEnvConfig(conf, hls_ts_ctx, "SRS_VHOST_HLS_HLS_TS_CTX", "off"); + + // Environment should override config value + EXPECT_FALSE(conf.get_hls_ts_ctx_enabled("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsCleanup) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true (SRS_CONF_PREFER_TRUE) + EXPECT_TRUE(conf.get_hls_cleanup("__defaultVhost__")); + EXPECT_TRUE(conf.get_hls_cleanup("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_TRUE(conf.get_hls_cleanup("test.com")); + } + + // Test default value when hls section exists but no hls_cleanup config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_cleanup config + EXPECT_TRUE(conf.get_hls_cleanup("test.com")); + } + + // Test default value when hls_cleanup has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_cleanup;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_hls_cleanup("test.com")); + } + + // Test explicit hls_cleanup enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_cleanup on;}}")); + + EXPECT_TRUE(conf.get_hls_cleanup("test.com")); + } + + // Test explicit hls_cleanup disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_cleanup off;}}")); + + EXPECT_FALSE(conf.get_hls_cleanup("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_cleanup true;}}")); + EXPECT_TRUE(conf.get_hls_cleanup("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_cleanup false;}}")); + EXPECT_TRUE(conf.get_hls_cleanup("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_cleanup yes;}}")); + EXPECT_TRUE(conf.get_hls_cleanup("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_cleanup no;}}")); + EXPECT_TRUE(conf.get_hls_cleanup("test.com")); // "no" != "off", so it's true + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_cleanup on;}}")); + + SrsSetEnvConfig(conf, hls_cleanup, "SRS_VHOST_HLS_HLS_CLEANUP", "off"); + + // Environment should override config value + EXPECT_FALSE(conf.get_hls_cleanup("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsDispose) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 120 seconds + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_hls_dispose("__defaultVhost__")); + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_hls_dispose("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_hls_dispose("test.com")); + } + + // Test default value when hls section exists but no hls_dispose config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_dispose config + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_hls_dispose("test.com")); + } + + // Test default value when hls_dispose has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dispose;}}")); + + // Should return default value when empty argument + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_hls_dispose("test.com")); + } + + // Test valid hls_dispose values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dispose 60;}}")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hls_dispose("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dispose 300;}}")); + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_hls_dispose("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dispose 0;}}")); + EXPECT_EQ(0, conf.get_hls_dispose("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dispose 1;}}")); + EXPECT_EQ(1 * SRS_UTIME_SECONDS, conf.get_hls_dispose("test.com")); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_dispose 60;}}")); + + SrsSetEnvConfig(conf, hls_dispose, "SRS_VHOST_HLS_HLS_DISPOSE", "180"); + + // Environment should override config value + EXPECT_EQ(180 * SRS_UTIME_SECONDS, conf.get_hls_dispose("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsWaitKeyframe) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true (SRS_CONF_PREFER_TRUE) + EXPECT_TRUE(conf.get_hls_wait_keyframe("__defaultVhost__")); + EXPECT_TRUE(conf.get_hls_wait_keyframe("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_TRUE(conf.get_hls_wait_keyframe("test.com")); + } + + // Test default value when hls section exists but no hls_wait_keyframe config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_wait_keyframe config + EXPECT_TRUE(conf.get_hls_wait_keyframe("test.com")); + } + + // Test default value when hls_wait_keyframe has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_wait_keyframe;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_hls_wait_keyframe("test.com")); + } + + // Test explicit hls_wait_keyframe enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_wait_keyframe on;}}")); + + EXPECT_TRUE(conf.get_hls_wait_keyframe("test.com")); + } + + // Test explicit hls_wait_keyframe disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_wait_keyframe off;}}")); + + EXPECT_FALSE(conf.get_hls_wait_keyframe("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_wait_keyframe true;}}")); + EXPECT_TRUE(conf.get_hls_wait_keyframe("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_wait_keyframe false;}}")); + EXPECT_TRUE(conf.get_hls_wait_keyframe("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_wait_keyframe yes;}}")); + EXPECT_TRUE(conf.get_hls_wait_keyframe("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_wait_keyframe no;}}")); + EXPECT_TRUE(conf.get_hls_wait_keyframe("test.com")); // "no" != "off", so it's true + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_wait_keyframe on;}}")); + + SrsSetEnvConfig(conf, hls_wait_keyframe, "SRS_VHOST_HLS_HLS_WAIT_KEYFRAME", "off"); + + // Environment should override config value + EXPECT_FALSE(conf.get_hls_wait_keyframe("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsKeys) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_TRUE with DEFAULT = false) + EXPECT_FALSE(conf.get_hls_keys("__defaultVhost__")); + EXPECT_FALSE(conf.get_hls_keys("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_FALSE(conf.get_hls_keys("test.com")); + } + + // Test default value when hls section exists but no hls_keys config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_keys config + EXPECT_FALSE(conf.get_hls_keys("test.com")); + } + + // Test default value when hls_keys has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_keys;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_hls_keys("test.com")); + } + + // Test explicit hls_keys enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_keys on;}}")); + + EXPECT_TRUE(conf.get_hls_keys("test.com")); + } + + // Test explicit hls_keys disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_keys off;}}")); + + EXPECT_FALSE(conf.get_hls_keys("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_keys true;}}")); + EXPECT_TRUE(conf.get_hls_keys("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_keys false;}}")); + EXPECT_TRUE(conf.get_hls_keys("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_keys yes;}}")); + EXPECT_TRUE(conf.get_hls_keys("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_keys no;}}")); + EXPECT_TRUE(conf.get_hls_keys("test.com")); // "no" != "off", so it's true + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_keys off;}}")); + + SrsSetEnvConfig(conf, hls_keys, "SRS_VHOST_HLS_HLS_KEYS", "on"); + + // Environment should override config value + EXPECT_TRUE(conf.get_hls_keys("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsFragmentsPerKey) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 5 + EXPECT_EQ(5, conf.get_hls_fragments_per_key("__defaultVhost__")); + EXPECT_EQ(5, conf.get_hls_fragments_per_key("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_EQ(5, conf.get_hls_fragments_per_key("test.com")); + } + + // Test default value when hls section exists but no hls_fragments_per_key config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_fragments_per_key config + EXPECT_EQ(5, conf.get_hls_fragments_per_key("test.com")); + } + + // Test default value when hls_fragments_per_key has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragments_per_key;}}")); + + // Should return default value when empty argument + EXPECT_EQ(5, conf.get_hls_fragments_per_key("test.com")); + } + + // Test valid hls_fragments_per_key values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragments_per_key 3;}}")); + EXPECT_EQ(3, conf.get_hls_fragments_per_key("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragments_per_key 10;}}")); + EXPECT_EQ(10, conf.get_hls_fragments_per_key("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragments_per_key 1;}}")); + EXPECT_EQ(1, conf.get_hls_fragments_per_key("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragments_per_key 0;}}")); + EXPECT_EQ(0, conf.get_hls_fragments_per_key("test.com")); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragments_per_key 3;}}")); + + SrsSetEnvConfig(conf, hls_fragments_per_key, "SRS_VHOST_HLS_HLS_FRAGMENTS_PER_KEY", "8"); + + // Environment should override config value + EXPECT_EQ(8, conf.get_hls_fragments_per_key("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsKeyFile) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "[app]/[stream]-[seq].key" + EXPECT_STREQ("[app]/[stream]-[seq].key", conf.get_hls_key_file("__defaultVhost__").c_str()); + EXPECT_STREQ("[app]/[stream]-[seq].key", conf.get_hls_key_file("test.com").c_str()); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_STREQ("[app]/[stream]-[seq].key", conf.get_hls_key_file("test.com").c_str()); + } + + // Test default value when hls section exists but no hls_key_file config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_key_file config + EXPECT_STREQ("[app]/[stream]-[seq].key", conf.get_hls_key_file("test.com").c_str()); + } + + // Test default value when hls_key_file has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("[app]/[stream]-[seq].key", conf.get_hls_key_file("test.com").c_str()); + } + + // Test custom hls_key_file values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file custom/[stream]-[seq].key;}}")); + EXPECT_STREQ("custom/[stream]-[seq].key", conf.get_hls_key_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file [app]/key-[seq].key;}}")); + EXPECT_STREQ("[app]/key-[seq].key", conf.get_hls_key_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file /path/to/[stream]/[seq].key;}}")); + EXPECT_STREQ("/path/to/[stream]/[seq].key", conf.get_hls_key_file("test.com").c_str()); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file custom.key;}}")); + + SrsSetEnvConfig(conf, hls_key_file, "SRS_VHOST_HLS_HLS_KEY_FILE", "env/[stream]-[seq].key"); + + // Environment should override config value + EXPECT_STREQ("env/[stream]-[seq].key", conf.get_hls_key_file("test.com").c_str()); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsKeyFilePath) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be the same as get_hls_path() which is "./objs/nginx/html" + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_file_path("__defaultVhost__").c_str()); + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_file_path("test.com").c_str()); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_file_path("test.com").c_str()); + } + + // Test default value when hls section exists but no hls_key_file_path config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_key_file_path config + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_file_path("test.com").c_str()); + } + + // Test default value when hls_key_file_path has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file_path;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_file_path("test.com").c_str()); + } + + // Test custom hls_key_file_path values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file_path /custom/path;}}")); + EXPECT_STREQ("/custom/path", conf.get_hls_key_file_path("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file_path ./keys;}}")); + EXPECT_STREQ("./keys", conf.get_hls_key_file_path("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file_path /var/www/keys;}}")); + EXPECT_STREQ("/var/www/keys", conf.get_hls_key_file_path("test.com").c_str()); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_file_path /custom/path;}}")); + + SrsSetEnvConfig(conf, hls_key_file_path, "SRS_VHOST_HLS_HLS_KEY_FILE_PATH", "/env/path"); + + // Environment should override config value + EXPECT_STREQ("/env/path", conf.get_hls_key_file_path("test.com").c_str()); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsKeyUrl) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be the same as get_hls_path() which is "./objs/nginx/html" + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_url("__defaultVhost__").c_str()); + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_url("test.com").c_str()); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_url("test.com").c_str()); + } + + // Test default value when hls section exists but no hls_key_url config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_key_url config + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_url("test.com").c_str()); + } + + // Test default value when hls_key_url has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_url;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("./objs/nginx/html", conf.get_hls_key_url("test.com").c_str()); + } + + // Test custom hls_key_url values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_url http://example.com/keys;}}")); + EXPECT_STREQ("http://example.com/keys", conf.get_hls_key_url("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_url https://cdn.example.com/hls/keys;}}")); + EXPECT_STREQ("https://cdn.example.com/hls/keys", conf.get_hls_key_url("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_url /relative/path/keys;}}")); + EXPECT_STREQ("/relative/path/keys", conf.get_hls_key_url("test.com").c_str()); + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_key_url http://example.com/keys;}}")); + + SrsSetEnvConfig(conf, hls_key_url, "SRS_VHOST_HLS_HLS_KEY_URL", "https://env.example.com/keys"); + + // Environment should override config value + EXPECT_STREQ("https://env.example.com/keys", conf.get_hls_key_url("test.com").c_str()); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsRecover) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true (SRS_CONF_PREFER_TRUE) + EXPECT_TRUE(conf.get_hls_recover("__defaultVhost__")); + EXPECT_TRUE(conf.get_hls_recover("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no hls section + EXPECT_TRUE(conf.get_hls_recover("test.com")); + } + + // Test default value when hls section exists but no hls_recover config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_recover config + EXPECT_TRUE(conf.get_hls_recover("test.com")); + } + + // Test default value when hls_recover has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_recover;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_hls_recover("test.com")); + } + + // Test explicit hls_recover enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_recover on;}}")); + + EXPECT_TRUE(conf.get_hls_recover("test.com")); + } + + // Test explicit hls_recover disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_recover off;}}")); + + EXPECT_FALSE(conf.get_hls_recover("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_recover true;}}")); + EXPECT_TRUE(conf.get_hls_recover("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_recover false;}}")); + EXPECT_TRUE(conf.get_hls_recover("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_recover yes;}}")); + EXPECT_TRUE(conf.get_hls_recover("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_recover no;}}")); + EXPECT_TRUE(conf.get_hls_recover("test.com")); // "no" != "off", so it's true + } + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_recover on;}}")); + + SrsSetEnvConfig(conf, hls_recover, "SRS_VHOST_HLS_HLS_RECOVER", "off"); + + // Environment should override config value + EXPECT_FALSE(conf.get_hls_recover("test.com")); + } +} + +VOID TEST(ConfigVhostTest, CheckQueueLength) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 30 seconds + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_queue_length("__defaultVhost__")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_queue_length("test.com")); + } + + // Test default value when vhost exists but no play section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no play section + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_queue_length("test.com")); + } + + // Test default value when play exists but no queue_length config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default value when no queue_length config + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_queue_length("test.com")); + } + + // Test default value when queue_length has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{queue_length;}}")); + + // Should return default value when empty argument + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_queue_length("test.com")); + } + + // Test valid queue_length values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{queue_length 10;}}")); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_queue_length("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{queue_length 60;}}")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_queue_length("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{queue_length 0;}}")); + EXPECT_EQ(0 * SRS_UTIME_SECONDS, conf.get_queue_length("test.com")); + } + + // Test negative values (should be parsed as is) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{queue_length -5;}}")); + EXPECT_EQ(-5 * SRS_UTIME_SECONDS, conf.get_queue_length("test.com")); + } +} + +VOID TEST(ConfigVhostTest, CheckReferEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_refer_enabled("__defaultVhost__")); + EXPECT_FALSE(conf.get_refer_enabled("test.com")); + } + + // Test default value when vhost exists but no refer config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no refer config + EXPECT_FALSE(conf.get_refer_enabled("test.com")); + } + + // Test default value when refer section exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{refer{all play.ossrs.net;}}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_refer_enabled("test.com")); + } + + // Test default value when refer enabled has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{refer{enabled;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_refer_enabled("test.com")); + } + + // Test explicit refer enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{refer{enabled on;}}")); + + EXPECT_TRUE(conf.get_refer_enabled("test.com")); + } + + // Test explicit refer disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{refer{enabled off;}}")); + + EXPECT_FALSE(conf.get_refer_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{refer{enabled true;}}")); + EXPECT_FALSE(conf.get_refer_enabled("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{refer{enabled false;}}")); + EXPECT_FALSE(conf.get_refer_enabled("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{refer{enabled yes;}}")); + EXPECT_FALSE(conf.get_refer_enabled("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{refer{enabled no;}}")); + EXPECT_FALSE(conf.get_refer_enabled("test.com")); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigVhostTest, CheckChunkSize) +{ + srs_error_t err; + + // Test default value when no vhost specified (empty vhost) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 4096;}")); + + // Should return global chunk size for empty vhost + EXPECT_EQ(4096, conf.get_chunk_size("")); + } + + // Test vhost that doesn't exist (should use global) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 8192;}")); + + // Should return global chunk size when vhost doesn't exist + EXPECT_EQ(8192, conf.get_chunk_size("nonexistent.com")); + } + + // Test vhost exists but no chunk_size config (should use global) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 16384;} vhost test.com{hls{enabled on;}}")); + + // Should return global chunk size when vhost has no chunk_size + EXPECT_EQ(16384, conf.get_chunk_size("test.com")); + } + + // Test vhost with specific chunk_size + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 4096;} vhost test.com{chunk_size 8192;}")); + + // Should return vhost-specific chunk size + EXPECT_EQ(8192, conf.get_chunk_size("test.com")); + } + + // Test multiple vhosts with different chunk sizes + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse("rtmp{listen 1935; chunk_size 4096;} vhost test1.com{chunk_size 8192;} vhost test2.com{chunk_size 16384;}")); + + EXPECT_EQ(8192, conf.get_chunk_size("test1.com")); + EXPECT_EQ(16384, conf.get_chunk_size("test2.com")); + EXPECT_EQ(4096, conf.get_chunk_size("other.com")); // Should use global for non-configured vhost + } +} + +VOID TEST(ConfigVhostTest, CheckMwMsgs) +{ + srs_error_t err; + + // Test default values for different combinations of is_realtime and is_rtc + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be SRS_PERF_MW_MIN_MSGS for normal case + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS, conf.get_mw_msgs("__defaultVhost__", false, false)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS, conf.get_mw_msgs("test.com", false, false)); + + // Default should be SRS_PERF_MW_MIN_MSGS_REALTIME for realtime case + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("__defaultVhost__", true, false)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("test.com", true, false)); + + // Default should be SRS_PERF_MW_MIN_MSGS_FOR_RTC for RTC case (but realtime overrides RTC) + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_FOR_RTC, conf.get_mw_msgs("__defaultVhost__", false, true)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_FOR_RTC, conf.get_mw_msgs("test.com", false, true)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("__defaultVhost__", true, true)); // realtime overrides RTC + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("test.com", true, true)); // realtime overrides RTC + } + + // Test default value when vhost exists but no play section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default values when no play section + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS, conf.get_mw_msgs("test.com", false, false)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("test.com", true, false)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_FOR_RTC, conf.get_mw_msgs("test.com", false, true)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("test.com", true, true)); // realtime overrides RTC + } + + // Test default value when play section exists but no mw_msgs config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_latency 350;}}")); + + // Should return default values when no mw_msgs config + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS, conf.get_mw_msgs("test.com", false, false)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("test.com", true, false)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_FOR_RTC, conf.get_mw_msgs("test.com", false, true)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("test.com", true, true)); // realtime overrides RTC + } + + // Test default value when mw_msgs has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_msgs;}}")); + + // Should return default values when empty argument + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS, conf.get_mw_msgs("test.com", false, false)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("test.com", true, false)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_FOR_RTC, conf.get_mw_msgs("test.com", false, true)); + EXPECT_EQ(SRS_PERF_MW_MIN_MSGS_REALTIME, conf.get_mw_msgs("test.com", true, true)); // realtime overrides RTC + } + + // Test valid mw_msgs values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_msgs 64;}}")); + + // Should return configured value for all combinations + EXPECT_EQ(64, conf.get_mw_msgs("test.com", false, false)); + EXPECT_EQ(64, conf.get_mw_msgs("test.com", true, false)); + EXPECT_EQ(64, conf.get_mw_msgs("test.com", false, true)); + EXPECT_EQ(64, conf.get_mw_msgs("test.com", true, true)); + } + + // Test mw_msgs value exceeding maximum (should be clamped to SRS_PERF_MW_MSGS=128) + if (true) { + MockSrsConfig conf; + int large_value = 256; // Larger than SRS_PERF_MW_MSGS (128) + string config_str = _MIN_OK_CONF "vhost test.com{play{mw_msgs " + srs_strconv_format_int(large_value) + ";}}"; + HELPER_ASSERT_SUCCESS(conf.mock_parse(config_str)); + + // Should be clamped to maximum value (128) + EXPECT_EQ(128, conf.get_mw_msgs("test.com", false, false)); + EXPECT_EQ(128, conf.get_mw_msgs("test.com", true, false)); + EXPECT_EQ(128, conf.get_mw_msgs("test.com", false, true)); + EXPECT_EQ(128, conf.get_mw_msgs("test.com", true, true)); + } + + // Test various valid mw_msgs values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_msgs 128;}}")); + EXPECT_EQ(128, conf.get_mw_msgs("test.com", false, false)); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_msgs 64;}}")); + EXPECT_EQ(64, conf.get_mw_msgs("test.com", false, false)); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_msgs 1;}}")); + EXPECT_EQ(1, conf.get_mw_msgs("test.com", false, false)); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{play{mw_msgs 0;}}")); + EXPECT_EQ(0, conf.get_mw_msgs("test.com", false, false)); + } +} + +VOID TEST(ConfigPublishTest, CheckPublishKickoffForIdle) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 0 (no kickoff) + EXPECT_EQ(0, conf.get_publish_kickoff_for_idle("__defaultVhost__")); + EXPECT_EQ(0, conf.get_publish_kickoff_for_idle("test.com")); + } + + // Test default value when vhost exists but no publish section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no publish section + EXPECT_EQ(0, conf.get_publish_kickoff_for_idle("test.com")); + } + + // Test default value when publish exists but no kickoff_for_idle config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{publish{mr_latency 350;}}")); + + // Should return default value when no kickoff_for_idle config + EXPECT_EQ(0, conf.get_publish_kickoff_for_idle("test.com")); + } + + // Test default value when kickoff_for_idle has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{publish{kickoff_for_idle;}}")); + + // Should return default value when empty argument + EXPECT_EQ(0, conf.get_publish_kickoff_for_idle("test.com")); + } + + // Test valid kickoff_for_idle values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{publish{kickoff_for_idle 30;}}")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_publish_kickoff_for_idle("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{publish{kickoff_for_idle 60.5;}}")); + EXPECT_EQ((srs_utime_t)(60.5 * SRS_UTIME_SECONDS), conf.get_publish_kickoff_for_idle("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{publish{kickoff_for_idle 0;}}")); + EXPECT_EQ(0, conf.get_publish_kickoff_for_idle("test.com")); + } + + // Test negative values (should be parsed as is) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{publish{kickoff_for_idle -10;}}")); + EXPECT_EQ((srs_utime_t)(-10 * SRS_UTIME_SECONDS), conf.get_publish_kickoff_for_idle("test.com")); + } + + // Test multiple vhosts with different configurations + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{publish{kickoff_for_idle 30;}} " + "vhost vhost2.com{publish{kickoff_for_idle 60;}} " + "vhost vhost3.com{publish{mr_latency 350;}}")); + + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_publish_kickoff_for_idle("vhost1.com")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_publish_kickoff_for_idle("vhost2.com")); + EXPECT_EQ(0, conf.get_publish_kickoff_for_idle("vhost3.com")); // default + } +} + +VOID TEST(ConfigClusterTest, CheckVhostEdgeProtocol) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "rtmp" + EXPECT_STREQ("rtmp", conf.get_vhost_edge_protocol("__defaultVhost__").c_str()); + EXPECT_STREQ("rtmp", conf.get_vhost_edge_protocol("test.com").c_str()); + } + + // Test default value when vhost exists but no cluster section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no cluster section + EXPECT_STREQ("rtmp", conf.get_vhost_edge_protocol("test.com").c_str()); + } + + // Test default value when cluster exists but no protocol config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{mode edge;}}")); + + // Should return default value when no protocol config + EXPECT_STREQ("rtmp", conf.get_vhost_edge_protocol("test.com").c_str()); + } + + // Test valid protocol values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{protocol rtmp;}}")); + EXPECT_STREQ("rtmp", conf.get_vhost_edge_protocol("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{protocol srt;}}")); + EXPECT_STREQ("srt", conf.get_vhost_edge_protocol("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{protocol webrtc;}}")); + EXPECT_STREQ("webrtc", conf.get_vhost_edge_protocol("test.com").c_str()); + } + + // Test custom protocol values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{protocol custom_protocol;}}")); + EXPECT_STREQ("custom_protocol", conf.get_vhost_edge_protocol("test.com").c_str()); + } + + // Test multiple vhosts with different protocols + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{cluster{protocol rtmp;}} " + "vhost vhost2.com{cluster{protocol srt;}} " + "vhost vhost3.com{cluster{mode edge;}}")); + + EXPECT_STREQ("rtmp", conf.get_vhost_edge_protocol("vhost1.com").c_str()); + EXPECT_STREQ("srt", conf.get_vhost_edge_protocol("vhost2.com").c_str()); + EXPECT_STREQ("rtmp", conf.get_vhost_edge_protocol("vhost3.com").c_str()); // default + } +} + +VOID TEST(ConfigClusterTest, CheckVhostEdgeFollowClient) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false + EXPECT_FALSE(conf.get_vhost_edge_follow_client("__defaultVhost__")); + EXPECT_FALSE(conf.get_vhost_edge_follow_client("test.com")); + } + + // Test default value when vhost exists but no cluster section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no cluster section + EXPECT_FALSE(conf.get_vhost_edge_follow_client("test.com")); + } + + // Test default value when cluster exists but no follow_client config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{mode edge;}}")); + + // Should return default value when no follow_client config + EXPECT_FALSE(conf.get_vhost_edge_follow_client("test.com")); + } + + // Test explicit follow_client enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{follow_client on;}}")); + + EXPECT_TRUE(conf.get_vhost_edge_follow_client("test.com")); + } + + // Test explicit follow_client disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{follow_client off;}}")); + + EXPECT_FALSE(conf.get_vhost_edge_follow_client("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{follow_client true;}}")); + EXPECT_FALSE(conf.get_vhost_edge_follow_client("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{follow_client false;}}")); + EXPECT_FALSE(conf.get_vhost_edge_follow_client("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{follow_client yes;}}")); + EXPECT_FALSE(conf.get_vhost_edge_follow_client("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{cluster{follow_client no;}}")); + EXPECT_FALSE(conf.get_vhost_edge_follow_client("test.com")); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigFFmpegTest, CheckFFLogDir) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "./objs" + EXPECT_STREQ("./objs", conf.get_ff_log_dir().c_str()); + } + + // Test valid ff_log_dir values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_dir /tmp/logs;")); + EXPECT_STREQ("/tmp/logs", conf.get_ff_log_dir().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_dir ./custom_logs;")); + EXPECT_STREQ("./custom_logs", conf.get_ff_log_dir().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_dir /var/log/srs;")); + EXPECT_STREQ("/var/log/srs", conf.get_ff_log_dir().c_str()); + } + + // Test empty ff_log_dir value (should return default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_dir;")); + + // Should return default value when empty argument + EXPECT_STREQ("./objs", conf.get_ff_log_dir().c_str()); + } + + // Test ff_log_dir with spaces and special characters + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_dir \"/path with spaces\";")); + EXPECT_STREQ("/path with spaces", conf.get_ff_log_dir().c_str()); + } +} + +VOID TEST(ConfigFFmpegTest, CheckFFLogLevel) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "info" + EXPECT_STREQ("info", conf.get_ff_log_level().c_str()); + } + + // Test valid ff_log_level values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_level debug;")); + EXPECT_STREQ("debug", conf.get_ff_log_level().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_level info;")); + EXPECT_STREQ("info", conf.get_ff_log_level().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_level warning;")); + EXPECT_STREQ("warning", conf.get_ff_log_level().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_level error;")); + EXPECT_STREQ("error", conf.get_ff_log_level().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_level quiet;")); + EXPECT_STREQ("quiet", conf.get_ff_log_level().c_str()); + } + + // Test empty ff_log_level value (should return default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_level;")); + + // Should return default value when empty argument + EXPECT_STREQ("info", conf.get_ff_log_level().c_str()); + } + + // Test custom ff_log_level values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "ff_log_level custom_level;")); + EXPECT_STREQ("custom_level", conf.get_ff_log_level().c_str()); + } +} + +VOID TEST(ConfigDashTest, CheckDashEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false + EXPECT_FALSE(conf.get_dash_enabled("__defaultVhost__")); + EXPECT_FALSE(conf.get_dash_enabled("test.com")); + } + + // Test default value when vhost exists but no dash section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dash section + EXPECT_FALSE(conf.get_dash_enabled("test.com")); + } + + // Test default value when dash exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_fragment 10;}}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_dash_enabled("test.com")); + } + + // Test default value when enabled has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_dash_enabled("test.com")); + } + + // Test explicit dash enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + EXPECT_TRUE(conf.get_dash_enabled("test.com")); + } + + // Test explicit dash disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled off;}}")); + + EXPECT_FALSE(conf.get_dash_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled true;}}")); + EXPECT_FALSE(conf.get_dash_enabled("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled false;}}")); + EXPECT_FALSE(conf.get_dash_enabled("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled yes;}}")); + EXPECT_FALSE(conf.get_dash_enabled("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled no;}}")); + EXPECT_FALSE(conf.get_dash_enabled("test.com")); // "no" != "on", so it's false + } + + // Test multiple vhosts with different configurations + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{dash{enabled on;}} " + "vhost vhost2.com{dash{enabled off;}} " + "vhost vhost3.com{dash{dash_fragment 10;}}")); + + EXPECT_TRUE(conf.get_dash_enabled("vhost1.com")); + EXPECT_FALSE(conf.get_dash_enabled("vhost2.com")); + EXPECT_FALSE(conf.get_dash_enabled("vhost3.com")); // default + } +} + +VOID TEST(ConfigDashTest, CheckDashFragment) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 10 seconds + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dash_fragment("__defaultVhost__")); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dash_fragment("test.com")); + } + + // Test default value when vhost exists but no dash section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dash section + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dash_fragment("test.com")); + } + + // Test default value when dash exists but no dash_fragment config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no dash_fragment config + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dash_fragment("test.com")); + } + + // Test default value when dash_fragment has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_fragment;}}")); + + // Should return default value when empty argument + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dash_fragment("test.com")); + } + + // Test valid dash_fragment values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_fragment 10;}}")); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dash_fragment("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_fragment 5.5;}}")); + EXPECT_EQ((srs_utime_t)(5.5 * SRS_UTIME_SECONDS), conf.get_dash_fragment("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_fragment 60;}}")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_dash_fragment("test.com")); + } + + // Test zero and negative values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_fragment 0;}}")); + EXPECT_EQ(0, conf.get_dash_fragment("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_fragment -5;}}")); + EXPECT_EQ((srs_utime_t)(-5 * SRS_UTIME_SECONDS), conf.get_dash_fragment("test.com")); + } +} + +VOID TEST(ConfigDashTest, CheckDashUpdatePeriod) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 5 seconds + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_dash_update_period("__defaultVhost__")); + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_dash_update_period("test.com")); + } + + // Test default value when vhost exists but no dash section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dash section + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_dash_update_period("test.com")); + } + + // Test default value when dash exists but no dash_update_period config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no dash_update_period config + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_dash_update_period("test.com")); + } + + // Test default value when dash_update_period has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_update_period;}}")); + + // Should return default value when empty argument + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_dash_update_period("test.com")); + } + + // Test valid dash_update_period values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_update_period 60;}}")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_dash_update_period("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_update_period 30.5;}}")); + EXPECT_EQ((srs_utime_t)(30.5 * SRS_UTIME_SECONDS), conf.get_dash_update_period("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_update_period 300;}}")); + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_dash_update_period("test.com")); + } + + // Test zero and negative values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_update_period 0;}}")); + EXPECT_EQ(0, conf.get_dash_update_period("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_update_period -10;}}")); + EXPECT_EQ((srs_utime_t)(-10 * SRS_UTIME_SECONDS), conf.get_dash_update_period("test.com")); + } +} + +VOID TEST(ConfigDashTest, CheckDashTimeshift) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 300 seconds + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("__defaultVhost__")); + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("test.com")); + } + + // Test default value when vhost exists but no dash section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dash section + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("test.com")); + } + + // Test default value when dash exists but no dash_timeshift config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no dash_timeshift config + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("test.com")); + } + + // Test default value when dash_timeshift has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_timeshift;}}")); + + // Should return default value when empty argument + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("test.com")); + } + + // Test valid dash_timeshift values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_timeshift 120;}}")); + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_timeshift 60.5;}}")); + EXPECT_EQ((srs_utime_t)(60.5 * SRS_UTIME_SECONDS), conf.get_dash_timeshift("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_timeshift 600;}}")); + EXPECT_EQ(600 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("test.com")); + } + + // Test zero and negative values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_timeshift 0;}}")); + EXPECT_EQ(0, conf.get_dash_timeshift("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_timeshift -30;}}")); + EXPECT_EQ((srs_utime_t)(-30 * SRS_UTIME_SECONDS), conf.get_dash_timeshift("test.com")); + } +} + +VOID TEST(ConfigDashTest, CheckDashPath) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "./objs/nginx/html" + EXPECT_STREQ("./objs/nginx/html", conf.get_dash_path("__defaultVhost__").c_str()); + EXPECT_STREQ("./objs/nginx/html", conf.get_dash_path("test.com").c_str()); + } + + // Test default value when vhost exists but no dash section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dash section + EXPECT_STREQ("./objs/nginx/html", conf.get_dash_path("test.com").c_str()); + } + + // Test default value when dash exists but no dash_path config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no dash_path config + EXPECT_STREQ("./objs/nginx/html", conf.get_dash_path("test.com").c_str()); + } + + // Test default value when dash_path has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_path;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("./objs/nginx/html", conf.get_dash_path("test.com").c_str()); + } + + // Test valid dash_path values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_path /tmp/dash;}}")); + EXPECT_STREQ("/tmp/dash", conf.get_dash_path("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_path ./custom_dash;}}")); + EXPECT_STREQ("./custom_dash", conf.get_dash_path("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_path /var/www/dash;}}")); + EXPECT_STREQ("/var/www/dash", conf.get_dash_path("test.com").c_str()); + } + + // Test dash_path with spaces and special characters + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_path \"/path with spaces\";}}")); + EXPECT_STREQ("/path with spaces", conf.get_dash_path("test.com").c_str()); + } + + // Test multiple vhosts with different dash paths + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{dash{dash_path /tmp/dash1;}} " + "vhost vhost2.com{dash{dash_path /tmp/dash2;}} " + "vhost vhost3.com{dash{enabled on;}}")); + + EXPECT_STREQ("/tmp/dash1", conf.get_dash_path("vhost1.com").c_str()); + EXPECT_STREQ("/tmp/dash2", conf.get_dash_path("vhost2.com").c_str()); + EXPECT_STREQ("./objs/nginx/html", conf.get_dash_path("vhost3.com").c_str()); // default + } +} + +VOID TEST(ConfigDashTest, CheckDashMpdFile) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "[app]/[stream].mpd" + EXPECT_STREQ("[app]/[stream].mpd", conf.get_dash_mpd_file("__defaultVhost__").c_str()); + EXPECT_STREQ("[app]/[stream].mpd", conf.get_dash_mpd_file("test.com").c_str()); + } + + // Test default value when vhost exists but no dash section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dash section + EXPECT_STREQ("[app]/[stream].mpd", conf.get_dash_mpd_file("test.com").c_str()); + } + + // Test default value when dash exists but no dash_mpd_file config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no dash_mpd_file config + EXPECT_STREQ("[app]/[stream].mpd", conf.get_dash_mpd_file("test.com").c_str()); + } + + // Test default value when dash_mpd_file has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_mpd_file;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("[app]/[stream].mpd", conf.get_dash_mpd_file("test.com").c_str()); + } + + // Test valid dash_mpd_file values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_mpd_file [app]/[stream].mpd;}}")); + EXPECT_STREQ("[app]/[stream].mpd", conf.get_dash_mpd_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_mpd_file custom.mpd;}}")); + EXPECT_STREQ("custom.mpd", conf.get_dash_mpd_file("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_mpd_file [vhost]/[app]/[stream].mpd;}}")); + EXPECT_STREQ("[vhost]/[app]/[stream].mpd", conf.get_dash_mpd_file("test.com").c_str()); + } + + // Test dash_mpd_file with complex patterns + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_mpd_file [timestamp]/[app]/[stream].mpd;}}")); + EXPECT_STREQ("[timestamp]/[app]/[stream].mpd", conf.get_dash_mpd_file("test.com").c_str()); + } + + // Test multiple vhosts with different mpd file patterns + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{dash{dash_mpd_file [app]/[stream].mpd;}} " + "vhost vhost2.com{dash{dash_mpd_file custom.mpd;}} " + "vhost vhost3.com{dash{enabled on;}}")); + + EXPECT_STREQ("[app]/[stream].mpd", conf.get_dash_mpd_file("vhost1.com").c_str()); + EXPECT_STREQ("custom.mpd", conf.get_dash_mpd_file("vhost2.com").c_str()); + EXPECT_STREQ("[app]/[stream].mpd", conf.get_dash_mpd_file("vhost3.com").c_str()); // default + } +} + +VOID TEST(ConfigDashTest, CheckDashWindowSize) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 5 + EXPECT_EQ(5, conf.get_dash_window_size("__defaultVhost__")); + EXPECT_EQ(5, conf.get_dash_window_size("test.com")); + } + + // Test default value when vhost exists but no dash section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dash section + EXPECT_EQ(5, conf.get_dash_window_size("test.com")); + } + + // Test default value when dash exists but no dash_window_size config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no dash_window_size config + EXPECT_EQ(5, conf.get_dash_window_size("test.com")); + } + + // Test default value when dash_window_size has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_window_size;}}")); + + // Should return default value when empty argument + EXPECT_EQ(5, conf.get_dash_window_size("test.com")); + } + + // Test valid dash_window_size values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_window_size 10;}}")); + EXPECT_EQ(10, conf.get_dash_window_size("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_window_size 1;}}")); + EXPECT_EQ(1, conf.get_dash_window_size("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_window_size 100;}}")); + EXPECT_EQ(100, conf.get_dash_window_size("test.com")); + } + + // Test zero and negative values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_window_size 0;}}")); + EXPECT_EQ(0, conf.get_dash_window_size("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_window_size -5;}}")); + EXPECT_EQ(-5, conf.get_dash_window_size("test.com")); + } +} + +VOID TEST(ConfigDashTest, CheckDashWindowSizeEnvironment) +{ + srs_error_t err; + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_window_size 10;}}")); + + SrsSetEnvConfig(conf, dash_window_size1, "SRS_VHOST_DASH_DASH_WINDOW_SIZE", "20"); + + // Environment should override config value + // Note: Due to SRS_OVERWRITE_BY_ENV_FLOAT_SECONDS bug, env values are converted to microseconds + EXPECT_EQ(20 * SRS_UTIME_SECONDS, conf.get_dash_window_size("test.com")); + } + + // Test environment variable with valid values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, dash_window_size2, "SRS_VHOST_DASH_DASH_WINDOW_SIZE", "15"); + EXPECT_EQ(15 * SRS_UTIME_SECONDS, conf.get_dash_window_size("test.com")); + + SrsSetEnvConfig(conf, dash_window_size3, "SRS_VHOST_DASH_DASH_WINDOW_SIZE", "1"); + EXPECT_EQ(1 * SRS_UTIME_SECONDS, conf.get_dash_window_size("test.com")); + } + + // Test environment variable with zero and negative values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, dash_window_size4, "SRS_VHOST_DASH_DASH_WINDOW_SIZE", "0"); + EXPECT_EQ(0, conf.get_dash_window_size("test.com")); + + SrsSetEnvConfig(conf, dash_window_size5, "SRS_VHOST_DASH_DASH_WINDOW_SIZE", "-10"); + EXPECT_EQ(-10 * SRS_UTIME_SECONDS, conf.get_dash_window_size("test.com")); + } +} + +VOID TEST(ConfigDashTest, CheckDashCleanup) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true + EXPECT_TRUE(conf.get_dash_cleanup("__defaultVhost__")); + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); + } + + // Test default value when vhost exists but no dash section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dash section + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); + } + + // Test default value when dash exists but no dash_cleanup config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no dash_cleanup config + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); + } + + // Test default value when dash_cleanup has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_cleanup;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); + } + + // Test explicit dash_cleanup enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_cleanup on;}}")); + + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); + } + + // Test explicit dash_cleanup disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_cleanup off;}}")); + + EXPECT_FALSE(conf.get_dash_cleanup("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_cleanup true;}}")); + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_cleanup false;}}")); + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_cleanup yes;}}")); + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_cleanup no;}}")); + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); // "no" != "off", so it's true + } +} + +VOID TEST(ConfigDashTest, CheckDashCleanupEnvironment) +{ + srs_error_t err; + + // Test environment variable overrides config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_cleanup on;}}")); + + SrsSetEnvConfig(conf, dash_cleanup1, "SRS_VHOST_DASH_DASH_CLEANUP", "off"); + + // Environment should override config value + EXPECT_FALSE(conf.get_dash_cleanup("test.com")); + } + + // Test environment variable with various boolean values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, dash_cleanup2, "SRS_VHOST_DASH_DASH_CLEANUP", "on"); + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); + + SrsSetEnvConfig(conf, dash_cleanup3, "SRS_VHOST_DASH_DASH_CLEANUP", "true"); + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); // "true" != "off", so it's true + + SrsSetEnvConfig(conf, dash_cleanup4, "SRS_VHOST_DASH_DASH_CLEANUP", "false"); + EXPECT_TRUE(conf.get_dash_cleanup("test.com")); // "false" != "off", so it's true + + SrsSetEnvConfig(conf, dash_cleanup5, "SRS_VHOST_DASH_DASH_CLEANUP", "off"); + EXPECT_FALSE(conf.get_dash_cleanup("test.com")); // Only "off" is false + } +} + +VOID TEST(ConfigDashTest, CheckDashDispose) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 120 seconds + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_dash_dispose("__defaultVhost__")); + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_dash_dispose("test.com")); + } + + // Test default value when vhost exists but no dash section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dash section + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_dash_dispose("test.com")); + } + + // Test default value when dash exists but no dash_dispose config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no dash_dispose config + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_dash_dispose("test.com")); + } + + // Test default value when dash_dispose has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_dispose;}}")); + + // Should return default value when empty argument + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_dash_dispose("test.com")); + } + + // Test valid dash_dispose values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_dispose 120;}}")); + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_dash_dispose("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_dispose 300;}}")); + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_dash_dispose("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_dispose 0;}}")); + EXPECT_EQ(0, conf.get_dash_dispose("test.com")); + } + + // Test negative values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{dash_dispose -60;}}")); + EXPECT_EQ(-60 * SRS_UTIME_SECONDS, conf.get_dash_dispose("test.com")); + } +} + +VOID TEST(ConfigHlsTest, CheckHlsEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false + EXPECT_FALSE(conf.get_hls_enabled("__defaultVhost__")); + EXPECT_FALSE(conf.get_hls_enabled("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no hls section + EXPECT_FALSE(conf.get_hls_enabled("test.com")); + } + + // Test default value when hls exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_fragment 10;}}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_hls_enabled("test.com")); + } + + // Test default value when enabled has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_hls_enabled("test.com")); + } + + // Test explicit hls enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + EXPECT_TRUE(conf.get_hls_enabled("test.com")); + } + + // Test explicit hls disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled off;}}")); + + EXPECT_FALSE(conf.get_hls_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled true;}}")); + EXPECT_FALSE(conf.get_hls_enabled("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled false;}}")); + EXPECT_FALSE(conf.get_hls_enabled("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled yes;}}")); + EXPECT_FALSE(conf.get_hls_enabled("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled no;}}")); + EXPECT_FALSE(conf.get_hls_enabled("test.com")); // "no" != "on", so it's false + } + + // Test multiple vhosts with different configurations + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{hls{enabled on;}} " + "vhost vhost2.com{hls{enabled off;}} " + "vhost vhost3.com{hls{hls_fragment 10;}}")); + + EXPECT_TRUE(conf.get_hls_enabled("vhost1.com")); + EXPECT_FALSE(conf.get_hls_enabled("vhost2.com")); + EXPECT_FALSE(conf.get_hls_enabled("vhost3.com")); // default + } +} + +VOID TEST(ConfigHlsTest, CheckHlsUseFmp4) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false + EXPECT_FALSE(conf.get_hls_use_fmp4("__defaultVhost__")); + EXPECT_FALSE(conf.get_hls_use_fmp4("test.com")); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no hls section + EXPECT_FALSE(conf.get_hls_use_fmp4("test.com")); + } + + // Test default value when hls exists but no hls_use_fmp4 config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_use_fmp4 config + EXPECT_FALSE(conf.get_hls_use_fmp4("test.com")); + } + + // Test default value when hls_use_fmp4 has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_use_fmp4;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_hls_use_fmp4("test.com")); + } + + // Test explicit hls_use_fmp4 enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_use_fmp4 on;}}")); + + EXPECT_TRUE(conf.get_hls_use_fmp4("test.com")); + } + + // Test explicit hls_use_fmp4 disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_use_fmp4 off;}}")); + + EXPECT_FALSE(conf.get_hls_use_fmp4("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_use_fmp4 true;}}")); + EXPECT_FALSE(conf.get_hls_use_fmp4("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_use_fmp4 false;}}")); + EXPECT_FALSE(conf.get_hls_use_fmp4("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_use_fmp4 yes;}}")); + EXPECT_FALSE(conf.get_hls_use_fmp4("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_use_fmp4 no;}}")); + EXPECT_FALSE(conf.get_hls_use_fmp4("test.com")); // "no" != "on", so it's false + } + + // Test multiple vhosts with different configurations + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{hls{hls_use_fmp4 on;}} " + "vhost vhost2.com{hls{hls_use_fmp4 off;}} " + "vhost vhost3.com{hls{enabled on;}}")); + + EXPECT_TRUE(conf.get_hls_use_fmp4("vhost1.com")); + EXPECT_FALSE(conf.get_hls_use_fmp4("vhost2.com")); + EXPECT_FALSE(conf.get_hls_use_fmp4("vhost3.com")); // default + } +} + +VOID TEST(ConfigHlsTest, CheckHlsEntryPrefix) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be empty string + EXPECT_STREQ("", conf.get_hls_entry_prefix("__defaultVhost__").c_str()); + EXPECT_STREQ("", conf.get_hls_entry_prefix("test.com").c_str()); + } + + // Test default value when vhost exists but no hls section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dash{enabled on;}}")); + + // Should return default value when no hls section + EXPECT_STREQ("", conf.get_hls_entry_prefix("test.com").c_str()); + } + + // Test default value when hls exists but no hls_entry_prefix config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hls_entry_prefix config + EXPECT_STREQ("", conf.get_hls_entry_prefix("test.com").c_str()); + } + + // Test valid hls_entry_prefix values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_entry_prefix http://cdn.example.com/;}}")); + EXPECT_STREQ("http://cdn.example.com/", conf.get_hls_entry_prefix("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_entry_prefix https://example.com/hls/;}}")); + EXPECT_STREQ("https://example.com/hls/", conf.get_hls_entry_prefix("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_entry_prefix /static/hls/;}}")); + EXPECT_STREQ("/static/hls/", conf.get_hls_entry_prefix("test.com").c_str()); + } + + // Test empty hls_entry_prefix value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{hls_entry_prefix \"\";}}")); + EXPECT_STREQ("", conf.get_hls_entry_prefix("test.com").c_str()); + } + + // Test multiple vhosts with different entry prefixes + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{hls{hls_entry_prefix http://cdn1.com/;}} " + "vhost vhost2.com{hls{hls_entry_prefix http://cdn2.com/;}} " + "vhost vhost3.com{hls{enabled on;}}")); + + EXPECT_STREQ("http://cdn1.com/", conf.get_hls_entry_prefix("vhost1.com").c_str()); + EXPECT_STREQ("http://cdn2.com/", conf.get_hls_entry_prefix("vhost2.com").c_str()); + EXPECT_STREQ("", conf.get_hls_entry_prefix("vhost3.com").c_str()); // default + } +} + +// HDS Configuration Tests +VOID TEST(ConfigHdsTest, CheckHdsEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_hds_enabled("__defaultVhost__")); + EXPECT_FALSE(conf.get_hds_enabled("test.com")); + } + + // Test default value when vhost exists but no hds section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hds section + EXPECT_FALSE(conf.get_hds_enabled("test.com")); + } + + // Test default value when hds exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_path ./objs/nginx/html;}}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_hds_enabled("test.com")); + } + + // Test default value when enabled has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_hds_enabled("test.com")); + } + + // Test explicit hds enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled on;}}")); + + EXPECT_TRUE(conf.get_hds_enabled("test.com")); + } + + // Test explicit hds disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled off;}}")); + + EXPECT_FALSE(conf.get_hds_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled true;}}")); + EXPECT_FALSE(conf.get_hds_enabled("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled false;}}")); + EXPECT_FALSE(conf.get_hds_enabled("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled yes;}}")); + EXPECT_FALSE(conf.get_hds_enabled("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled no;}}")); + EXPECT_FALSE(conf.get_hds_enabled("test.com")); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigHdsTest, CheckHdsPath) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "./objs/nginx/html" + EXPECT_STREQ("./objs/nginx/html", conf.get_hds_path("__defaultVhost__").c_str()); + EXPECT_STREQ("./objs/nginx/html", conf.get_hds_path("test.com").c_str()); + } + + // Test default value when vhost exists but no hds section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hds section + EXPECT_STREQ("./objs/nginx/html", conf.get_hds_path("test.com").c_str()); + } + + // Test default value when hds exists but no hds_path config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled on;}}")); + + // Should return default value when no hds_path config + EXPECT_STREQ("./objs/nginx/html", conf.get_hds_path("test.com").c_str()); + } + + // Test default value when hds_path has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_path;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("./objs/nginx/html", conf.get_hds_path("test.com").c_str()); + } + + // Test valid hds_path values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_path /var/www/hds;}}")); + EXPECT_STREQ("/var/www/hds", conf.get_hds_path("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_path ./custom/hds/path;}}")); + EXPECT_STREQ("./custom/hds/path", conf.get_hds_path("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_path /tmp/hds;}}")); + EXPECT_STREQ("/tmp/hds", conf.get_hds_path("test.com").c_str()); + } + + // Test multiple vhosts with different hds paths + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{hds{hds_path /var/www/hds1;}} " + "vhost vhost2.com{hds{hds_path /var/www/hds2;}} " + "vhost vhost3.com{hds{enabled on;}}")); + + EXPECT_STREQ("/var/www/hds1", conf.get_hds_path("vhost1.com").c_str()); + EXPECT_STREQ("/var/www/hds2", conf.get_hds_path("vhost2.com").c_str()); + EXPECT_STREQ("./objs/nginx/html", conf.get_hds_path("vhost3.com").c_str()); // default + } +} + +VOID TEST(ConfigHdsTest, CheckHdsFragment) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 10 seconds + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hds_fragment("__defaultVhost__")); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hds_fragment("test.com")); + } + + // Test default value when vhost exists but no hds section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hds section + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hds_fragment("test.com")); + } + + // Test default value when hds exists but no hds_fragment config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled on;}}")); + + // Should return default value when no hds_fragment config + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hds_fragment("test.com")); + } + + // Test default value when hds_fragment has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_fragment;}}")); + + // Should return default value when empty argument + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hds_fragment("test.com")); + } + + // Test valid hds_fragment values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_fragment 5;}}")); + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_hds_fragment("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_fragment 2.5;}}")); + EXPECT_EQ((srs_utime_t)(2.5 * SRS_UTIME_SECONDS), conf.get_hds_fragment("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_fragment 30;}}")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_hds_fragment("test.com")); + } + + // Test zero and negative values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_fragment 0;}}")); + EXPECT_EQ(0, conf.get_hds_fragment("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_fragment -5;}}")); + EXPECT_EQ((srs_utime_t)(-5 * SRS_UTIME_SECONDS), conf.get_hds_fragment("test.com")); + } + + // Test multiple vhosts with different fragment values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{hds{hds_fragment 5;}} " + "vhost vhost2.com{hds{hds_fragment 15;}} " + "vhost vhost3.com{hds{enabled on;}}")); + + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_hds_fragment("vhost1.com")); + EXPECT_EQ(15 * SRS_UTIME_SECONDS, conf.get_hds_fragment("vhost2.com")); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hds_fragment("vhost3.com")); // default + } +} + +VOID TEST(ConfigHdsTest, CheckHdsWindow) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 60 seconds + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hds_window("__defaultVhost__")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hds_window("test.com")); + } + + // Test default value when vhost exists but no hds section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no hds section + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hds_window("test.com")); + } + + // Test default value when hds exists but no hds_window config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{enabled on;}}")); + + // Should return default value when no hds_window config + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hds_window("test.com")); + } + + // Test default value when hds_window has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_window;}}")); + + // Should return default value when empty argument + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hds_window("test.com")); + } + + // Test valid hds_window values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_window 30;}}")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_hds_window("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_window 120.5;}}")); + EXPECT_EQ((srs_utime_t)(120.5 * SRS_UTIME_SECONDS), conf.get_hds_window("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_window 300;}}")); + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_hds_window("test.com")); + } + + // Test zero and negative values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_window 0;}}")); + EXPECT_EQ(0, conf.get_hds_window("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hds{hds_window -10;}}")); + EXPECT_EQ((srs_utime_t)(-10 * SRS_UTIME_SECONDS), conf.get_hds_window("test.com")); + } + + // Test multiple vhosts with different window values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{hds{hds_window 30;}} " + "vhost vhost2.com{hds{hds_window 120;}} " + "vhost vhost3.com{hds{enabled on;}}")); + + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_hds_window("vhost1.com")); + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_hds_window("vhost2.com")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_hds_window("vhost3.com")); // default + } +} + +// DVR Configuration Tests +VOID TEST(ConfigDvrTest, CheckDvrEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_dvr_enabled("__defaultVhost__")); + EXPECT_FALSE(conf.get_dvr_enabled("test.com")); + } + + // Test default value when vhost exists but no dvr section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dvr section + EXPECT_FALSE(conf.get_dvr_enabled("test.com")); + } + + // Test default value when dvr exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_path ./objs/nginx/html;}}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_dvr_enabled("test.com")); + } + + // Test default value when enabled has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_dvr_enabled("test.com")); + } + + // Test explicit dvr enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled on;}}")); + + EXPECT_TRUE(conf.get_dvr_enabled("test.com")); + } + + // Test explicit dvr disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled off;}}")); + + EXPECT_FALSE(conf.get_dvr_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled true;}}")); + EXPECT_FALSE(conf.get_dvr_enabled("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled false;}}")); + EXPECT_FALSE(conf.get_dvr_enabled("test.com")); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled yes;}}")); + EXPECT_FALSE(conf.get_dvr_enabled("test.com")); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled no;}}")); + EXPECT_FALSE(conf.get_dvr_enabled("test.com")); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigDvrTest, CheckDvrApply) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Should return NULL when no dvr section + EXPECT_TRUE(conf.get_dvr_apply("__defaultVhost__") == NULL); + EXPECT_TRUE(conf.get_dvr_apply("test.com") == NULL); + } + + // Test default value when vhost exists but no dvr section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return NULL when no dvr section + EXPECT_TRUE(conf.get_dvr_apply("test.com") == NULL); + } + + // Test default value when dvr exists but no dvr_apply config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled on;}}")); + + // Should return NULL when no dvr_apply config + EXPECT_TRUE(conf.get_dvr_apply("test.com") == NULL); + } + + // Test default value when dvr_apply has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_apply;}}")); + + // Should return NULL when empty argument + EXPECT_TRUE(conf.get_dvr_apply("test.com") == NULL); + } + + // Test valid dvr_apply values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_apply all;}}")); + + SrsConfDirective *apply = conf.get_dvr_apply("test.com"); + EXPECT_TRUE(apply != NULL); + if (apply) { + EXPECT_STREQ("all", apply->arg0().c_str()); + } + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_apply play;}}")); + apply = conf.get_dvr_apply("test.com"); + EXPECT_TRUE(apply != NULL); + if (apply) { + EXPECT_STREQ("play", apply->arg0().c_str()); + } + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_apply publish;}}")); + apply = conf.get_dvr_apply("test.com"); + EXPECT_TRUE(apply != NULL); + if (apply) { + EXPECT_STREQ("publish", apply->arg0().c_str()); + } + } + + // Test multiple vhosts with different apply values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{dvr{dvr_apply all;}} " + "vhost vhost2.com{dvr{dvr_apply play;}} " + "vhost vhost3.com{dvr{enabled on;}}")); + + SrsConfDirective *apply1 = conf.get_dvr_apply("vhost1.com"); + EXPECT_TRUE(apply1 != NULL); + if (apply1) { + EXPECT_STREQ("all", apply1->arg0().c_str()); + } + + SrsConfDirective *apply2 = conf.get_dvr_apply("vhost2.com"); + EXPECT_TRUE(apply2 != NULL); + if (apply2) { + EXPECT_STREQ("play", apply2->arg0().c_str()); + } + + SrsConfDirective *apply3 = conf.get_dvr_apply("vhost3.com"); + EXPECT_TRUE(apply3 == NULL); // default + } +} + +VOID TEST(ConfigDvrTest, CheckDvrPath) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "./objs/nginx/html/[app]/[stream].[timestamp].flv" + EXPECT_STREQ("./objs/nginx/html/[app]/[stream].[timestamp].flv", conf.get_dvr_path("__defaultVhost__").c_str()); + EXPECT_STREQ("./objs/nginx/html/[app]/[stream].[timestamp].flv", conf.get_dvr_path("test.com").c_str()); + } + + // Test default value when vhost exists but no dvr section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dvr section + EXPECT_STREQ("./objs/nginx/html/[app]/[stream].[timestamp].flv", conf.get_dvr_path("test.com").c_str()); + } + + // Test default value when dvr exists but no dvr_path config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled on;}}")); + + // Should return default value when no dvr_path config + EXPECT_STREQ("./objs/nginx/html/[app]/[stream].[timestamp].flv", conf.get_dvr_path("test.com").c_str()); + } + + // Test default value when dvr_path has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_path;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("./objs/nginx/html/[app]/[stream].[timestamp].flv", conf.get_dvr_path("test.com").c_str()); + } + + // Test valid dvr_path values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_path /var/recordings;}}")); + EXPECT_STREQ("/var/recordings", conf.get_dvr_path("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_path ./custom/dvr/path;}}")); + EXPECT_STREQ("./custom/dvr/path", conf.get_dvr_path("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_path /tmp/dvr;}}")); + EXPECT_STREQ("/tmp/dvr", conf.get_dvr_path("test.com").c_str()); + } + + // Test multiple vhosts with different dvr paths + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{dvr{dvr_path /var/recordings1;}} " + "vhost vhost2.com{dvr{dvr_path /var/recordings2;}} " + "vhost vhost3.com{dvr{enabled on;}}")); + + EXPECT_STREQ("/var/recordings1", conf.get_dvr_path("vhost1.com").c_str()); + EXPECT_STREQ("/var/recordings2", conf.get_dvr_path("vhost2.com").c_str()); + EXPECT_STREQ("./objs/nginx/html/[app]/[stream].[timestamp].flv", conf.get_dvr_path("vhost3.com").c_str()); // default + } +} + +VOID TEST(ConfigDvrTest, CheckDvrPlan) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "session" + EXPECT_STREQ("session", conf.get_dvr_plan("__defaultVhost__").c_str()); + EXPECT_STREQ("session", conf.get_dvr_plan("test.com").c_str()); + } + + // Test default value when vhost exists but no dvr section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dvr section + EXPECT_STREQ("session", conf.get_dvr_plan("test.com").c_str()); + } + + // Test default value when dvr exists but no dvr_plan config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled on;}}")); + + // Should return default value when no dvr_plan config + EXPECT_STREQ("session", conf.get_dvr_plan("test.com").c_str()); + } + + // Test default value when dvr_plan has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_plan;}}")); + + // Should return default value when empty argument + EXPECT_STREQ("session", conf.get_dvr_plan("test.com").c_str()); + } + + // Test valid dvr_plan values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_plan session;}}")); + EXPECT_STREQ("session", conf.get_dvr_plan("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_plan segment;}}")); + EXPECT_STREQ("segment", conf.get_dvr_plan("test.com").c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_plan append;}}")); + EXPECT_STREQ("append", conf.get_dvr_plan("test.com").c_str()); + } + + // Test multiple vhosts with different dvr plans + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{dvr{dvr_plan session;}} " + "vhost vhost2.com{dvr{dvr_plan segment;}} " + "vhost vhost3.com{dvr{enabled on;}}")); + + EXPECT_STREQ("session", conf.get_dvr_plan("vhost1.com").c_str()); + EXPECT_STREQ("segment", conf.get_dvr_plan("vhost2.com").c_str()); + EXPECT_STREQ("session", conf.get_dvr_plan("vhost3.com").c_str()); // default + } +} + +VOID TEST(ConfigDvrTest, CheckDvrDuration) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 30 seconds + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_dvr_duration("__defaultVhost__")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_dvr_duration("test.com")); + } + + // Test default value when vhost exists but no dvr section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dvr section + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_dvr_duration("test.com")); + } + + // Test default value when dvr exists but no dvr_duration config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled on;}}")); + + // Should return default value when no dvr_duration config + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_dvr_duration("test.com")); + } + + // Test default value when dvr_duration has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_duration;}}")); + + // Should return default value when empty argument + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_dvr_duration("test.com")); + } + + // Test valid dvr_duration values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_duration 60;}}")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_dvr_duration("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_duration 120;}}")); + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_dvr_duration("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_duration 3600;}}")); + EXPECT_EQ(3600 * SRS_UTIME_SECONDS, conf.get_dvr_duration("test.com")); + } + + // Test zero and negative values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_duration 0;}}")); + EXPECT_EQ(0, conf.get_dvr_duration("test.com")); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_duration -60;}}")); + EXPECT_EQ((srs_utime_t)(-60 * SRS_UTIME_SECONDS), conf.get_dvr_duration("test.com")); + } + + // Test multiple vhosts with different duration values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{dvr{dvr_duration 60;}} " + "vhost vhost2.com{dvr{dvr_duration 300;}} " + "vhost vhost3.com{dvr{enabled on;}}")); + + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_dvr_duration("vhost1.com")); + EXPECT_EQ(300 * SRS_UTIME_SECONDS, conf.get_dvr_duration("vhost2.com")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_dvr_duration("vhost3.com")); // default + } +} + +VOID TEST(ConfigDvrTest, CheckDvrWaitKeyframe) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true (SRS_CONF_PREFER_TRUE) + EXPECT_TRUE(conf.get_dvr_wait_keyframe("__defaultVhost__")); + EXPECT_TRUE(conf.get_dvr_wait_keyframe("test.com")); + } + + // Test default value when vhost exists but no dvr section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dvr section + EXPECT_TRUE(conf.get_dvr_wait_keyframe("test.com")); + } + + // Test default value when dvr exists but no dvr_wait_keyframe config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled on;}}")); + + // Should return default value when no dvr_wait_keyframe config + EXPECT_TRUE(conf.get_dvr_wait_keyframe("test.com")); + } + + // Test default value when dvr_wait_keyframe has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_wait_keyframe;}}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_dvr_wait_keyframe("test.com")); + } + + // Test explicit dvr_wait_keyframe enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_wait_keyframe on;}}")); + + EXPECT_TRUE(conf.get_dvr_wait_keyframe("test.com")); + } + + // Test explicit dvr_wait_keyframe disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_wait_keyframe off;}}")); + + EXPECT_FALSE(conf.get_dvr_wait_keyframe("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_wait_keyframe true;}}")); + EXPECT_TRUE(conf.get_dvr_wait_keyframe("test.com")); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_wait_keyframe false;}}")); + EXPECT_TRUE(conf.get_dvr_wait_keyframe("test.com")); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_wait_keyframe yes;}}")); + EXPECT_TRUE(conf.get_dvr_wait_keyframe("test.com")); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{dvr_wait_keyframe no;}}")); + EXPECT_TRUE(conf.get_dvr_wait_keyframe("test.com")); // "no" != "off", so it's true + } +} + +VOID TEST(ConfigDvrTest, CheckDvrTimeJitter) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 1 (SrsRtmpJitterAlgorithmFULL) - default is "full" + EXPECT_EQ(1, conf.get_dvr_time_jitter("__defaultVhost__")); + EXPECT_EQ(1, conf.get_dvr_time_jitter("test.com")); + } + + // Test default value when vhost exists but no dvr section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no dvr section + EXPECT_EQ(1, conf.get_dvr_time_jitter("test.com")); + } + + // Test default value when dvr exists but no time_jitter config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{enabled on;}}")); + + // Should return default value when no time_jitter config + EXPECT_EQ(1, conf.get_dvr_time_jitter("test.com")); + } + + // Test default value when time_jitter has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{time_jitter;}}")); + + // Should return default value when empty argument + EXPECT_EQ(1, conf.get_dvr_time_jitter("test.com")); + } + + // Test various time_jitter string values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{time_jitter off;}}")); + EXPECT_EQ(3, conf.get_dvr_time_jitter("test.com")); // SrsRtmpJitterAlgorithmOFF = 3 + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{time_jitter full;}}")); + EXPECT_EQ(1, conf.get_dvr_time_jitter("test.com")); // SrsRtmpJitterAlgorithmFULL = 1 + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{time_jitter zero;}}")); + EXPECT_EQ(2, conf.get_dvr_time_jitter("test.com")); // SrsRtmpJitterAlgorithmZERO = 2 + } + + // Test invalid time_jitter values (should return OFF=3) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{time_jitter invalid;}}")); + EXPECT_EQ(3, conf.get_dvr_time_jitter("test.com")); // Should return OFF=3 for invalid value + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{dvr{time_jitter simple;}}")); + EXPECT_EQ(3, conf.get_dvr_time_jitter("test.com")); // "simple" is not supported, returns OFF=3 + } + + // Test multiple vhosts with different time jitter values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{dvr{time_jitter off;}} " + "vhost vhost2.com{dvr{time_jitter zero;}} " + "vhost vhost3.com{dvr{enabled on;}}")); + + EXPECT_EQ(3, conf.get_dvr_time_jitter("vhost1.com")); // OFF + EXPECT_EQ(2, conf.get_dvr_time_jitter("vhost2.com")); // ZERO + EXPECT_EQ(1, conf.get_dvr_time_jitter("vhost3.com")); // default FULL + } +} + +// HTTP API Configuration Tests +VOID TEST(ConfigHttpApiTest, CheckHttpApiEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_http_api_enabled()); + } + + // Test default value when http_api exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{listen 1985;}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_http_api_enabled()); + } + + // Test default value when enabled has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled;}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_http_api_enabled()); + } + + // Test explicit http_api enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + EXPECT_TRUE(conf.get_http_api_enabled()); + } + + // Test explicit http_api disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled off;}")); + + EXPECT_FALSE(conf.get_http_api_enabled()); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled true;}")); + EXPECT_FALSE(conf.get_http_api_enabled()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled false;}")); + EXPECT_FALSE(conf.get_http_api_enabled()); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled yes;}")); + EXPECT_FALSE(conf.get_http_api_enabled()); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled no;}")); + EXPECT_FALSE(conf.get_http_api_enabled()); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigHttpApiTest, CheckHttpApiListens) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be ["1985"] + vector listens = conf.get_http_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1985", listens.at(0).c_str()); + } + + // Test default value when http_api exists but no listen config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + // Should return default value when no listen config + vector listens = conf.get_http_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1985", listens.at(0).c_str()); + } + + // Test single listen port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{listen 8080;}")); + + vector listens = conf.get_http_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8080", listens.at(0).c_str()); + } + + // Test multiple listen ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{listen 1985 8080 9090;}")); + + vector listens = conf.get_http_api_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("1985", listens.at(0).c_str()); + EXPECT_STREQ("8080", listens.at(1).c_str()); + EXPECT_STREQ("9090", listens.at(2).c_str()); + } + + // Test listen with IP address + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{listen 127.0.0.1:1985;}")); + + vector listens = conf.get_http_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("127.0.0.1:1985", listens.at(0).c_str()); + } + + // Test mixed listen formats + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{listen 1985 127.0.0.1:8080 0.0.0.0:9090;}")); + + vector listens = conf.get_http_api_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("1985", listens.at(0).c_str()); + EXPECT_STREQ("127.0.0.1:8080", listens.at(1).c_str()); + EXPECT_STREQ("0.0.0.0:9090", listens.at(2).c_str()); + } +} + +VOID TEST(ConfigHttpApiTest, CheckHttpApiCrossdomain) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true (SRS_CONF_PREFER_TRUE) + EXPECT_TRUE(conf.get_http_api_crossdomain()); + } + + // Test default value when http_api exists but no crossdomain config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + // Should return default value when no crossdomain config + EXPECT_TRUE(conf.get_http_api_crossdomain()); + } + + // Test default value when crossdomain has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{crossdomain;}")); + + // Should return default value when empty argument + EXPECT_TRUE(conf.get_http_api_crossdomain()); + } + + // Test explicit crossdomain enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{crossdomain on;}")); + + EXPECT_TRUE(conf.get_http_api_crossdomain()); + } + + // Test explicit crossdomain disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{crossdomain off;}")); + + EXPECT_FALSE(conf.get_http_api_crossdomain()); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{crossdomain true;}")); + EXPECT_TRUE(conf.get_http_api_crossdomain()); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{crossdomain false;}")); + EXPECT_TRUE(conf.get_http_api_crossdomain()); // "false" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{crossdomain yes;}")); + EXPECT_TRUE(conf.get_http_api_crossdomain()); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{crossdomain no;}")); + EXPECT_TRUE(conf.get_http_api_crossdomain()); // "no" != "off", so it's true + } +} + +VOID TEST(ConfigHttpApiTest, CheckRawApi) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_raw_api()); + } + + // Test default value when http_api exists but no raw_api section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + // Should return default value when no raw_api section + EXPECT_FALSE(conf.get_raw_api()); + } + + // Test default value when raw_api exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{allow_reload on;}}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_raw_api()); + } + + // Test default value when enabled has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{enabled;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_raw_api()); + } + + // Test explicit raw_api enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{enabled on;}}")); + + EXPECT_TRUE(conf.get_raw_api()); + } + + // Test explicit raw_api disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{enabled off;}}")); + + EXPECT_FALSE(conf.get_raw_api()); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{enabled true;}}")); + EXPECT_FALSE(conf.get_raw_api()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{enabled false;}}")); + EXPECT_FALSE(conf.get_raw_api()); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{enabled yes;}}")); + EXPECT_FALSE(conf.get_raw_api()); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{enabled no;}}")); + EXPECT_FALSE(conf.get_raw_api()); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigHttpApiTest, CheckRawApiAllowReload) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_raw_api_allow_reload()); + } + + // Test default value when http_api exists but no raw_api section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + // Should return default value when no raw_api section + EXPECT_FALSE(conf.get_raw_api_allow_reload()); + } + + // Test default value when raw_api exists but no allow_reload config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{enabled on;}}")); + + // Should return default value when no allow_reload config + EXPECT_FALSE(conf.get_raw_api_allow_reload()); + } + + // Test default value when allow_reload has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{allow_reload;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_raw_api_allow_reload()); + } + + // Test explicit allow_reload enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{allow_reload on;}}")); + + EXPECT_TRUE(conf.get_raw_api_allow_reload()); + } + + // Test explicit allow_reload disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{allow_reload off;}}")); + + EXPECT_FALSE(conf.get_raw_api_allow_reload()); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{allow_reload true;}}")); + EXPECT_FALSE(conf.get_raw_api_allow_reload()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{allow_reload false;}}")); + EXPECT_FALSE(conf.get_raw_api_allow_reload()); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{allow_reload yes;}}")); + EXPECT_FALSE(conf.get_raw_api_allow_reload()); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{raw_api{allow_reload no;}}")); + EXPECT_FALSE(conf.get_raw_api_allow_reload()); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigHttpApiTest, CheckHttpApiAuthEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_http_api_auth_enabled()); + } + + // Test default value when http_api exists but no auth section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + // Should return default value when no auth section + EXPECT_FALSE(conf.get_http_api_auth_enabled()); + } + + // Test default value when auth exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{username admin;}}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_http_api_auth_enabled()); + } + + // Test default value when enabled has empty argument + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{enabled;}}")); + + // Should return default value when empty argument + EXPECT_FALSE(conf.get_http_api_auth_enabled()); + } + + // Test explicit auth enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{enabled on;}}")); + + EXPECT_TRUE(conf.get_http_api_auth_enabled()); + } + + // Test explicit auth disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{enabled off;}}")); + + EXPECT_FALSE(conf.get_http_api_auth_enabled()); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{enabled true;}}")); + EXPECT_FALSE(conf.get_http_api_auth_enabled()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{enabled false;}}")); + EXPECT_FALSE(conf.get_http_api_auth_enabled()); // "false" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{enabled yes;}}")); + EXPECT_FALSE(conf.get_http_api_auth_enabled()); // "yes" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{enabled no;}}")); + EXPECT_FALSE(conf.get_http_api_auth_enabled()); // "no" != "on", so it's false + } +} + +VOID TEST(ConfigHttpApiTest, CheckHttpApiAuthUsername) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be empty string + EXPECT_STREQ("", conf.get_http_api_auth_username().c_str()); + } + + // Test default value when http_api exists but no auth section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + // Should return default value when no auth section + EXPECT_STREQ("", conf.get_http_api_auth_username().c_str()); + } + + // Test default value when auth exists but no username config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{enabled on;}}")); + + // Should return default value when no username config + EXPECT_STREQ("", conf.get_http_api_auth_username().c_str()); + } + + // Test valid username values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{username myuser;}}")); + EXPECT_STREQ("myuser", conf.get_http_api_auth_username().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{username root;}}")); + EXPECT_STREQ("root", conf.get_http_api_auth_username().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{username user123;}}")); + EXPECT_STREQ("user123", conf.get_http_api_auth_username().c_str()); + } + + // Test empty username (should return empty string, not default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{username \"\";}}")); + EXPECT_STREQ("", conf.get_http_api_auth_username().c_str()); + } +} + +VOID TEST(ConfigHttpApiTest, CheckHttpApiAuthPassword) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be empty string + EXPECT_STREQ("", conf.get_http_api_auth_password().c_str()); + } + + // Test default value when http_api exists but no auth section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + // Should return default value when no auth section + EXPECT_STREQ("", conf.get_http_api_auth_password().c_str()); + } + + // Test default value when auth exists but no password config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{enabled on;}}")); + + // Should return default value when no password config + EXPECT_STREQ("", conf.get_http_api_auth_password().c_str()); + } + + // Test valid password values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{password mypass;}}")); + EXPECT_STREQ("mypass", conf.get_http_api_auth_password().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{password secret123;}}")); + EXPECT_STREQ("secret123", conf.get_http_api_auth_password().c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{password \"complex password\";}}")); + EXPECT_STREQ("complex password", conf.get_http_api_auth_password().c_str()); + } + + // Test empty password (should return empty string, not default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{auth{password \"\";}}")); + EXPECT_STREQ("", conf.get_http_api_auth_password().c_str()); + } + + // Test complete auth configuration + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on; auth{enabled on; username testuser; password testpass;}}")); + + EXPECT_TRUE(conf.get_http_api_enabled()); + EXPECT_TRUE(conf.get_http_api_auth_enabled()); + EXPECT_STREQ("testuser", conf.get_http_api_auth_username().c_str()); + EXPECT_STREQ("testpass", conf.get_http_api_auth_password().c_str()); + } +} + +VOID TEST(ConfigHttpsApiTest, CheckHttpsApiListensDefault) +{ + srs_error_t err; + + // Test default value when no configuration is provided + // Note: HTTPS API defaults to HTTPS server port when HTTP API and HTTP server use same port, + // otherwise defaults to 1990. Since HTTP API defaults to 1985 and HTTP server to 8080, + // they're different, so HTTPS API should default to 1990. + // HTTPS API requires HTTP API to be enabled. + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + vector listens = conf.get_https_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1990", listens.at(0).c_str()); // Default port + } + + // Test default value when http_api section exists but no https config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + vector listens = conf.get_https_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1990", listens.at(0).c_str()); // Default port + } + + // Test default value when https section exists but no listen config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{enabled on;}}")); + + vector listens = conf.get_https_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1990", listens.at(0).c_str()); // Default port + } + + // Test empty listen arguments (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{listen;}}")); + + vector listens = conf.get_https_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1990", listens.at(0).c_str()); // Default port + } +} + +VOID TEST(ConfigHttpsApiTest, CheckHttpsApiListensCustom) +{ + srs_error_t err; + + // Test single custom listen port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{listen 8443;}}")); + + vector listens = conf.get_https_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8443", listens.at(0).c_str()); + } + + // Test multiple listen ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{listen 8443 9443 10443;}}")); + + vector listens = conf.get_https_api_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("8443", listens.at(0).c_str()); + EXPECT_STREQ("9443", listens.at(1).c_str()); + EXPECT_STREQ("10443", listens.at(2).c_str()); + } + + // Test listen with IP address + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{listen 127.0.0.1:8443;}}")); + + vector listens = conf.get_https_api_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("127.0.0.1:8443", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigHttpsApiTest, CheckHttpsApiSslKey) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + string key = conf.get_https_api_ssl_key(); + EXPECT_STREQ("./conf/server.key", key.c_str()); // Default key file + } + + // Test default value when http_api section exists but no https config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + string key = conf.get_https_api_ssl_key(); + EXPECT_STREQ("./conf/server.key", key.c_str()); // Default key file + } + + // Test default value when https section exists but no key config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{enabled on;}}")); + + string key = conf.get_https_api_ssl_key(); + EXPECT_STREQ("./conf/server.key", key.c_str()); // Default key file + } + + // Test custom key file + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{key /path/to/custom.key;}}")); + + string key = conf.get_https_api_ssl_key(); + EXPECT_STREQ("/path/to/custom.key", key.c_str()); + } + + // Test relative key file path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{key ./ssl/api.key;}}")); + + string key = conf.get_https_api_ssl_key(); + EXPECT_STREQ("./ssl/api.key", key.c_str()); + } +} + +VOID TEST(ConfigHttpsApiTest, CheckHttpsApiSslCert) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + string cert = conf.get_https_api_ssl_cert(); + EXPECT_STREQ("./conf/server.crt", cert.c_str()); // Default cert file + } + + // Test default value when http_api section exists but no https config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;}")); + + string cert = conf.get_https_api_ssl_cert(); + EXPECT_STREQ("./conf/server.crt", cert.c_str()); // Default cert file + } + + // Test default value when https section exists but no cert config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{enabled on;}}")); + + string cert = conf.get_https_api_ssl_cert(); + EXPECT_STREQ("./conf/server.crt", cert.c_str()); // Default cert file + } + + // Test custom cert file + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{cert /path/to/custom.crt;}}")); + + string cert = conf.get_https_api_ssl_cert(); + EXPECT_STREQ("/path/to/custom.crt", cert.c_str()); + } + + // Test relative cert file path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_api{enabled on;https{cert ./ssl/api.crt;}}")); + + string cert = conf.get_https_api_ssl_cert(); + EXPECT_STREQ("./ssl/api.crt", cert.c_str()); + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_srt_enabled()); + } + + // Test default value when srt_server section exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{listen 10080;}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_srt_enabled()); + } + + // Test explicit srt enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + EXPECT_TRUE(conf.get_srt_enabled()); + } + + // Test explicit srt disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled off;}")); + + EXPECT_FALSE(conf.get_srt_enabled()); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled true;}")); + EXPECT_FALSE(conf.get_srt_enabled()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled yes;}")); + EXPECT_FALSE(conf.get_srt_enabled()); // "yes" != "on", so it's false + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtListens) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + vector listens = conf.get_srt_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("10080", listens.at(0).c_str()); // Default port + } + + // Test default value when srt_server section exists but no listen config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + vector listens = conf.get_srt_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("10080", listens.at(0).c_str()); // Default port + } + + // Test empty listen arguments (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{listen;}")); + + vector listens = conf.get_srt_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("10080", listens.at(0).c_str()); // Default port + } + + // Test single custom listen port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{listen 9000;}")); + + vector listens = conf.get_srt_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("9000", listens.at(0).c_str()); + } + + // Test multiple listen ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{listen 9000 9001 9002;}")); + + vector listens = conf.get_srt_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("9000", listens.at(0).c_str()); + EXPECT_STREQ("9001", listens.at(1).c_str()); + EXPECT_STREQ("9002", listens.at(2).c_str()); + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoMaxbw) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be -1 + EXPECT_EQ(-1, conf.get_srto_maxbw()); + } + + // Test default value when srt_server section exists but no maxbw config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no maxbw config + EXPECT_EQ(-1, conf.get_srto_maxbw()); + } + + // Test custom maxbw values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{maxbw 1000000;}")); + EXPECT_EQ(1000000, conf.get_srto_maxbw()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{maxbw 0;}")); + EXPECT_EQ(0, conf.get_srto_maxbw()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{maxbw -1;}")); + EXPECT_EQ(-1, conf.get_srto_maxbw()); + } + + // Test empty maxbw argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{maxbw;}")); + + EXPECT_EQ(-1, conf.get_srto_maxbw()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoMss) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 1500 + EXPECT_EQ(1500, conf.get_srto_mss()); + } + + // Test default value when srt_server section exists but no mss config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no mss config + EXPECT_EQ(1500, conf.get_srto_mss()); + } + + // Test custom mss values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{mss 1400;}")); + EXPECT_EQ(1400, conf.get_srto_mss()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{mss 1200;}")); + EXPECT_EQ(1200, conf.get_srto_mss()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{mss 576;}")); + EXPECT_EQ(576, conf.get_srto_mss()); + } + + // Test empty mss argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{mss;}")); + + EXPECT_EQ(1500, conf.get_srto_mss()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoTsbpdmode) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true + EXPECT_TRUE(conf.get_srto_tsbpdmode()); + } + + // Test default value when srt_server section exists but no tsbpdmode config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no tsbpdmode config + EXPECT_TRUE(conf.get_srto_tsbpdmode()); + } + + // Test explicit tsbpdmode enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tsbpdmode on;}")); + + EXPECT_TRUE(conf.get_srto_tsbpdmode()); + } + + // Test explicit tsbpdmode disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tsbpdmode off;}")); + + EXPECT_FALSE(conf.get_srto_tsbpdmode()); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tsbpdmode true;}")); + EXPECT_TRUE(conf.get_srto_tsbpdmode()); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tsbpdmode yes;}")); + EXPECT_TRUE(conf.get_srto_tsbpdmode()); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tsbpdmode false;}")); + EXPECT_TRUE(conf.get_srto_tsbpdmode()); // "false" != "off", so it's true + } + + // Test empty tsbpdmode argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tsbpdmode;}")); + + EXPECT_TRUE(conf.get_srto_tsbpdmode()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoLatency) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 120 + EXPECT_EQ(120, conf.get_srto_latency()); + } + + // Test default value when srt_server section exists but no latency config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no latency config + EXPECT_EQ(120, conf.get_srto_latency()); + } + + // Test custom latency values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{latency 200;}")); + EXPECT_EQ(200, conf.get_srto_latency()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{latency 50;}")); + EXPECT_EQ(50, conf.get_srto_latency()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{latency 0;}")); + EXPECT_EQ(0, conf.get_srto_latency()); + } + + // Test empty latency argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{latency;}")); + + EXPECT_EQ(120, conf.get_srto_latency()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoRecvLatency) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 120 + EXPECT_EQ(120, conf.get_srto_recv_latency()); + } + + // Test default value when srt_server section exists but no recvlatency config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no recvlatency config + EXPECT_EQ(120, conf.get_srto_recv_latency()); + } + + // Test custom recvlatency values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{recvlatency 300;}")); + EXPECT_EQ(300, conf.get_srto_recv_latency()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{recvlatency 100;}")); + EXPECT_EQ(100, conf.get_srto_recv_latency()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{recvlatency 0;}")); + EXPECT_EQ(0, conf.get_srto_recv_latency()); + } + + // Test empty recvlatency argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{recvlatency;}")); + + EXPECT_EQ(120, conf.get_srto_recv_latency()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoPeerLatency) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 0 + EXPECT_EQ(0, conf.get_srto_peer_latency()); + } + + // Test default value when srt_server section exists but no peerlatency config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no peerlatency config + EXPECT_EQ(0, conf.get_srto_peer_latency()); + } + + // Test custom peerlatency values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{peerlatency 150;}")); + EXPECT_EQ(150, conf.get_srto_peer_latency()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{peerlatency 200;}")); + EXPECT_EQ(200, conf.get_srto_peer_latency()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{peerlatency 0;}")); + EXPECT_EQ(0, conf.get_srto_peer_latency()); + } + + // Test empty peerlatency argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{peerlatency;}")); + + EXPECT_EQ(0, conf.get_srto_peer_latency()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtSeiFilter) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true + EXPECT_TRUE(conf.get_srt_sei_filter()); + } + + // Test default value when srt_server section exists but no sei_filter config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no sei_filter config + EXPECT_TRUE(conf.get_srt_sei_filter()); + } + + // Test explicit sei_filter enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sei_filter on;}")); + + EXPECT_TRUE(conf.get_srt_sei_filter()); + } + + // Test explicit sei_filter disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sei_filter off;}")); + + EXPECT_FALSE(conf.get_srt_sei_filter()); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sei_filter true;}")); + EXPECT_TRUE(conf.get_srt_sei_filter()); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sei_filter yes;}")); + EXPECT_TRUE(conf.get_srt_sei_filter()); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sei_filter false;}")); + EXPECT_TRUE(conf.get_srt_sei_filter()); // "false" != "off", so it's true + } + + // Test empty sei_filter argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sei_filter;}")); + + EXPECT_TRUE(conf.get_srt_sei_filter()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtSeiFilterEnvironment) +{ + srs_error_t err; + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sei_filter on;}")); + + SrsSetEnvConfig(conf, sei_filter, "SRS_SRT_SERVER_SEI_FILTER", "off"); + + // Environment variable should override config file + EXPECT_FALSE(conf.get_srt_sei_filter()); + } + + // Test environment variable with "on" value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sei_filter off;}")); + + SrsSetEnvConfig(conf, sei_filter, "SRS_SRT_SERVER_SEI_FILTER", "on"); + + // Environment variable should override config file + EXPECT_TRUE(conf.get_srt_sei_filter()); + } + + // Test environment variable with default when no config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, sei_filter, "SRS_SRT_SERVER_SEI_FILTER", "off"); + + // Environment variable should override default + EXPECT_FALSE(conf.get_srt_sei_filter()); + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoTlpktdrop) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true + EXPECT_TRUE(conf.get_srto_tlpktdrop()); + } + + // Test default value when srt_server section exists but no tlpkdrop config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no tlpkdrop config + EXPECT_TRUE(conf.get_srto_tlpktdrop()); + } + + // Test explicit tlpkdrop enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tlpkdrop on;}")); + + EXPECT_TRUE(conf.get_srto_tlpktdrop()); + } + + // Test explicit tlpkdrop disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tlpkdrop off;}")); + + EXPECT_FALSE(conf.get_srto_tlpktdrop()); + } + + // Test various boolean values (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tlpkdrop true;}")); + EXPECT_TRUE(conf.get_srto_tlpktdrop()); // "true" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tlpkdrop yes;}")); + EXPECT_TRUE(conf.get_srto_tlpktdrop()); // "yes" != "off", so it's true + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tlpkdrop false;}")); + EXPECT_TRUE(conf.get_srto_tlpktdrop()); // "false" != "off", so it's true + } + + // Test empty tlpkdrop argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{tlpkdrop;}")); + + EXPECT_TRUE(conf.get_srto_tlpktdrop()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoConntimeout) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 3 seconds + EXPECT_EQ(3 * SRS_UTIME_SECONDS, conf.get_srto_conntimeout()); + } + + // Test default value when srt_server section exists but no connect_timeout config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no connect_timeout config + EXPECT_EQ(3 * SRS_UTIME_SECONDS, conf.get_srto_conntimeout()); + } + + // Test custom connect_timeout values (in milliseconds) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{connect_timeout 5000;}")); + EXPECT_EQ(5000 * SRS_UTIME_MILLISECONDS, conf.get_srto_conntimeout()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{connect_timeout 1000;}")); + EXPECT_EQ(1000 * SRS_UTIME_MILLISECONDS, conf.get_srto_conntimeout()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{connect_timeout 10000;}")); + EXPECT_EQ(10000 * SRS_UTIME_MILLISECONDS, conf.get_srto_conntimeout()); + } + + // Test empty connect_timeout argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{connect_timeout;}")); + + EXPECT_EQ(3 * SRS_UTIME_SECONDS, conf.get_srto_conntimeout()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoPeeridletimeout) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 10 seconds + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_srto_peeridletimeout()); + } + + // Test default value when srt_server section exists but no peer_idle_timeout config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no peer_idle_timeout config + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_srto_peeridletimeout()); + } + + // Test custom peer_idle_timeout values (in milliseconds) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{peer_idle_timeout 15000;}")); + EXPECT_EQ(15000 * SRS_UTIME_MILLISECONDS, conf.get_srto_peeridletimeout()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{peer_idle_timeout 5000;}")); + EXPECT_EQ(5000 * SRS_UTIME_MILLISECONDS, conf.get_srto_peeridletimeout()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{peer_idle_timeout 30000;}")); + EXPECT_EQ(30000 * SRS_UTIME_MILLISECONDS, conf.get_srto_peeridletimeout()); + } + + // Test empty peer_idle_timeout argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{peer_idle_timeout;}")); + + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_srto_peeridletimeout()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoSendbuf) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 8192 * (1500 - 28) = 8192 * 1472 = 12058624 + int expected_default = 8192 * (1500 - 28); + EXPECT_EQ(expected_default, conf.get_srto_sendbuf()); + } + + // Test default value when srt_server section exists but no sendbuf config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no sendbuf config + int expected_default = 8192 * (1500 - 28); + EXPECT_EQ(expected_default, conf.get_srto_sendbuf()); + } + + // Test custom sendbuf values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sendbuf 1048576;}")); + EXPECT_EQ(1048576, conf.get_srto_sendbuf()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sendbuf 2097152;}")); + EXPECT_EQ(2097152, conf.get_srto_sendbuf()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sendbuf 65536;}")); + EXPECT_EQ(65536, conf.get_srto_sendbuf()); + } + + // Test empty sendbuf argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{sendbuf;}")); + + int expected_default = 8192 * (1500 - 28); + EXPECT_EQ(expected_default, conf.get_srto_sendbuf()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoRecvbuf) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 8192 * (1500 - 28) = 8192 * 1472 = 12058624 + int expected_default = 8192 * (1500 - 28); + EXPECT_EQ(expected_default, conf.get_srto_recvbuf()); + } + + // Test default value when srt_server section exists but no recvbuf config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no recvbuf config + int expected_default = 8192 * (1500 - 28); + EXPECT_EQ(expected_default, conf.get_srto_recvbuf()); + } + + // Test custom recvbuf values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{recvbuf 1048576;}")); + EXPECT_EQ(1048576, conf.get_srto_recvbuf()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{recvbuf 2097152;}")); + EXPECT_EQ(2097152, conf.get_srto_recvbuf()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{recvbuf 65536;}")); + EXPECT_EQ(65536, conf.get_srto_recvbuf()); + } + + // Test empty recvbuf argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{recvbuf;}")); + + int expected_default = 8192 * (1500 - 28); + EXPECT_EQ(expected_default, conf.get_srto_recvbuf()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoPayloadsize) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 1316 + EXPECT_EQ(1316, conf.get_srto_payloadsize()); + } + + // Test default value when srt_server section exists but no payloadsize config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no payloadsize config + EXPECT_EQ(1316, conf.get_srto_payloadsize()); + } + + // Test custom payloadsize values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{payloadsize 1200;}")); + EXPECT_EQ(1200, conf.get_srto_payloadsize()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{payloadsize 1400;}")); + EXPECT_EQ(1400, conf.get_srto_payloadsize()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{payloadsize 1000;}")); + EXPECT_EQ(1000, conf.get_srto_payloadsize()); + } + + // Test empty payloadsize argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{payloadsize;}")); + + EXPECT_EQ(1316, conf.get_srto_payloadsize()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoPayloadsizeEnvironment) +{ + srs_error_t err; + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{payloadsize 1200;}")); + + SrsSetEnvConfig(conf, payloadsize, "SRS_SRT_SERVER_PAYLOADSIZE", "1400"); + + // Environment variable should override config file + EXPECT_EQ(1400, conf.get_srto_payloadsize()); + } + + // Test environment variable with default when no config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, payloadsize, "SRS_SRT_SERVER_PAYLOADSIZE", "1500"); + + // Environment variable should override default + EXPECT_EQ(1500, conf.get_srto_payloadsize()); + } + + // Test environment variable with zero value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, payloadsize, "SRS_SRT_SERVER_PAYLOADSIZE", "0"); + + // Environment variable should override default + EXPECT_EQ(0, conf.get_srto_payloadsize()); + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoPassphrase) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be empty string + string passphrase = conf.get_srto_passphrase(); + EXPECT_STREQ("", passphrase.c_str()); + } + + // Test default value when srt_server section exists but no passphrase config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no passphrase config + string passphrase = conf.get_srto_passphrase(); + EXPECT_STREQ("", passphrase.c_str()); + } + + // Test custom passphrase values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{passphrase mysecretkey;}")); + string passphrase = conf.get_srto_passphrase(); + EXPECT_STREQ("mysecretkey", passphrase.c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{passphrase \"complex password with spaces\";}")); + passphrase = conf.get_srto_passphrase(); + EXPECT_STREQ("complex password with spaces", passphrase.c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{passphrase 123456789;}")); + passphrase = conf.get_srto_passphrase(); + EXPECT_STREQ("123456789", passphrase.c_str()); + } + + // Test empty passphrase argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{passphrase;}")); + + string passphrase = conf.get_srto_passphrase(); + EXPECT_STREQ("", passphrase.c_str()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckSrtoPbkeylen) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be 0 + EXPECT_EQ(0, conf.get_srto_pbkeylen()); + } + + // Test default value when srt_server section exists but no pbkeylen config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no pbkeylen config + EXPECT_EQ(0, conf.get_srto_pbkeylen()); + } + + // Test custom pbkeylen values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{pbkeylen 16;}")); + EXPECT_EQ(16, conf.get_srto_pbkeylen()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{pbkeylen 24;}")); + EXPECT_EQ(24, conf.get_srto_pbkeylen()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{pbkeylen 32;}")); + EXPECT_EQ(32, conf.get_srto_pbkeylen()); + } + + // Test empty pbkeylen argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{pbkeylen;}")); + + EXPECT_EQ(0, conf.get_srto_pbkeylen()); // Default value + } +} + +VOID TEST(ConfigSrtServerTest, CheckDefaultAppName) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be "live" + string app_name = conf.get_default_app_name(); + EXPECT_STREQ("live", app_name.c_str()); + } + + // Test default value when srt_server section exists but no default_app config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{enabled on;}")); + + // Should return default value when no default_app config + string app_name = conf.get_default_app_name(); + EXPECT_STREQ("live", app_name.c_str()); + } + + // Test custom default_app values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{default_app myapp;}")); + string app_name = conf.get_default_app_name(); + EXPECT_STREQ("myapp", app_name.c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{default_app streaming;}")); + app_name = conf.get_default_app_name(); + EXPECT_STREQ("streaming", app_name.c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{default_app broadcast;}")); + app_name = conf.get_default_app_name(); + EXPECT_STREQ("broadcast", app_name.c_str()); + } + + // Test empty default_app argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "srt_server{default_app;}")); + + string app_name = conf.get_default_app_name(); + EXPECT_STREQ("live", app_name.c_str()); // Default value + } +} + +VOID TEST(ConfigSrtVhostTest, CheckSrtEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_srt_enabled("__defaultVhost__")); + EXPECT_FALSE(conf.get_srt_enabled("test.com")); + } + + // Test default value when vhost exists but no srt section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no srt section + EXPECT_FALSE(conf.get_srt_enabled("test.com")); + } + + // Test default value when srt section exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{srt_to_rtmp on;}}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_srt_enabled("test.com")); + } + + // Test explicit srt enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{enabled on;}}")); + + EXPECT_TRUE(conf.get_srt_enabled("test.com")); + } + + // Test explicit srt disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{enabled off;}}")); + + EXPECT_FALSE(conf.get_srt_enabled("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{enabled true;}}")); + EXPECT_FALSE(conf.get_srt_enabled("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{enabled yes;}}")); + EXPECT_FALSE(conf.get_srt_enabled("test.com")); // "yes" != "on", so it's false + } + + // Test empty enabled argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{enabled;}}")); + + EXPECT_FALSE(conf.get_srt_enabled("test.com")); // Default value + } +} + +VOID TEST(ConfigSrtVhostTest, CheckSrtToRtmp) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be true + EXPECT_TRUE(conf.get_srt_to_rtmp("__defaultVhost__")); + EXPECT_TRUE(conf.get_srt_to_rtmp("test.com")); + } + + // Test default value when vhost exists but no srt section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{hls{enabled on;}}")); + + // Should return default value when no srt section + EXPECT_TRUE(conf.get_srt_to_rtmp("test.com")); + } + + // Test default value when srt section exists but no srt_to_rtmp config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{enabled on;}}")); + + // Should return default value when no srt_to_rtmp config + EXPECT_TRUE(conf.get_srt_to_rtmp("test.com")); + } + + // Test explicit srt_to_rtmp enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{srt_to_rtmp on;}}")); + + EXPECT_TRUE(conf.get_srt_to_rtmp("test.com")); + } + + // Test explicit srt_to_rtmp disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{srt_to_rtmp off;}}")); + + EXPECT_FALSE(conf.get_srt_to_rtmp("test.com")); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{srt_to_rtmp true;}}")); + EXPECT_FALSE(conf.get_srt_to_rtmp("test.com")); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{srt_to_rtmp yes;}}")); + EXPECT_FALSE(conf.get_srt_to_rtmp("test.com")); // "yes" != "on", so it's false + } + + // Test empty srt_to_rtmp argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{srt_to_rtmp;}}")); + + EXPECT_TRUE(conf.get_srt_to_rtmp("test.com")); // Default value + } +} + +VOID TEST(ConfigSrtVhostTest, CheckSrtToRtmpEnvironment) +{ + srs_error_t err; + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{srt_to_rtmp on;}}")); + + SrsSetEnvConfig(conf, srt_to_rtmp, "SRS_VHOST_SRT_TO_RTMP", "off"); + + // Environment variable should override config file + EXPECT_FALSE(conf.get_srt_to_rtmp("test.com")); + } + + // Test environment variable with "on" value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{srt{srt_to_rtmp off;}}")); + + SrsSetEnvConfig(conf, srt_to_rtmp, "SRS_VHOST_SRT_TO_RTMP", "on"); + + // Environment variable should override config file + EXPECT_TRUE(conf.get_srt_to_rtmp("test.com")); + } + + // Test environment variable with default when no config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, srt_to_rtmp, "SRS_VHOST_SRT_TO_RTMP", "off"); + + // Environment variable should override default + EXPECT_FALSE(conf.get_srt_to_rtmp("__defaultVhost__")); + } + + // Test environment variable affects all vhosts + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "vhost vhost1.com{srt{srt_to_rtmp on;}} " + "vhost vhost2.com{srt{srt_to_rtmp off;}}")); + + SrsSetEnvConfig(conf, srt_to_rtmp, "SRS_VHOST_SRT_TO_RTMP", "off"); + + // Environment variable should override all vhost configs + EXPECT_FALSE(conf.get_srt_to_rtmp("vhost1.com")); + EXPECT_FALSE(conf.get_srt_to_rtmp("vhost2.com")); + EXPECT_FALSE(conf.get_srt_to_rtmp("__defaultVhost__")); + } +} + +VOID TEST(ConfigHttpStreamTest, CheckHttpStreamEnabled) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + // Default should be false (SRS_CONF_PREFER_FALSE) + EXPECT_FALSE(conf.get_http_stream_enabled()); + } + + // Test default value when http_server section exists but no enabled config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{listen 8080;}")); + + // Should return default value when no enabled config + EXPECT_FALSE(conf.get_http_stream_enabled()); + } + + // Test explicit http_server enabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on;}")); + + EXPECT_TRUE(conf.get_http_stream_enabled()); + } + + // Test explicit http_server disabled + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled off;}")); + + EXPECT_FALSE(conf.get_http_stream_enabled()); + } + + // Test various boolean values (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled true;}")); + EXPECT_FALSE(conf.get_http_stream_enabled()); // "true" != "on", so it's false + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled yes;}")); + EXPECT_FALSE(conf.get_http_stream_enabled()); // "yes" != "on", so it's false + } + + // Test empty enabled argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled;}")); + + EXPECT_FALSE(conf.get_http_stream_enabled()); // Default value + } +} + +VOID TEST(ConfigHttpStreamTest, CheckHttpStreamListens) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + vector listens = conf.get_http_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8080", listens.at(0).c_str()); // Default port + } + + // Test default value when http_server section exists but no listen config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on;}")); + + vector listens = conf.get_http_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8080", listens.at(0).c_str()); // Default port + } + + // Test empty listen arguments (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{listen;}")); + + vector listens = conf.get_http_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8080", listens.at(0).c_str()); // Default port + } + + // Test single custom listen port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{listen 9080;}")); + + vector listens = conf.get_http_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("9080", listens.at(0).c_str()); + } + + // Test multiple listen ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{listen 8080 8081 8082;}")); + + vector listens = conf.get_http_stream_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("8080", listens.at(0).c_str()); + EXPECT_STREQ("8081", listens.at(1).c_str()); + EXPECT_STREQ("8082", listens.at(2).c_str()); + } + + // Test listen with IP address + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{listen 127.0.0.1:8080;}")); + + vector listens = conf.get_http_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("127.0.0.1:8080", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigHttpStreamTest, CheckHttpStreamDir) +{ + srs_error_t err; + + // Test default value when no configuration is provided + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + string dir = conf.get_http_stream_dir(); + EXPECT_STREQ("./objs/nginx/html", dir.c_str()); // Default directory + } + + // Test default value when http_server section exists but no dir config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on;}")); + + string dir = conf.get_http_stream_dir(); + EXPECT_STREQ("./objs/nginx/html", dir.c_str()); // Default directory + } + + // Test custom dir values + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{dir /var/www/html;}")); + string dir = conf.get_http_stream_dir(); + EXPECT_STREQ("/var/www/html", dir.c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{dir ./www;}")); + dir = conf.get_http_stream_dir(); + EXPECT_STREQ("./www", dir.c_str()); + + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{dir /home/user/public_html;}")); + dir = conf.get_http_stream_dir(); + EXPECT_STREQ("/home/user/public_html", dir.c_str()); + } + + // Test empty dir argument (should use default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{dir;}")); + + string dir = conf.get_http_stream_dir(); + EXPECT_STREQ("./objs/nginx/html", dir.c_str()); // Default directory + } +} diff --git a/trunk/src/utest/srs_utest_config3.hpp b/trunk/src/utest/srs_utest_config3.hpp new file mode 100644 index 000000000..cd150d1b4 --- /dev/null +++ b/trunk/src/utest/srs_utest_config3.hpp @@ -0,0 +1,15 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// + +#ifndef SRS_UTEST_CONFIG3_HPP +#define SRS_UTEST_CONFIG3_HPP + +/* +#include +*/ +#include + +#endif diff --git a/trunk/src/utest/srs_utest_config4.cpp b/trunk/src/utest/srs_utest_config4.cpp new file mode 100644 index 000000000..0c4e11286 --- /dev/null +++ b/trunk/src/utest/srs_utest_config4.cpp @@ -0,0 +1,2037 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// + +#include + +using namespace std; + +#include +#include +#include +#include +#include + +VOID TEST(ConfigHttpsStreamTest, CheckHttpsStreamListensDefault) +{ + srs_error_t err; + + // Test default value when no http_server section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8088", listens.at(0).c_str()); + } + + // Test default value when http_server exists but no https section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on;}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8088", listens.at(0).c_str()); + } + + // Test default value when https section exists but no listen directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on;}}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8088", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigHttpsStreamTest, CheckHttpsStreamListensEmptyArgs) +{ + srs_error_t err; + + // Test default value when listen directive exists but has no arguments + // This tests the specific case: if (listens.empty()) { listens.push_back(DEFAULT); } + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; listen;}}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8088", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigHttpsStreamTest, CheckHttpsStreamListensWithArgs) +{ + srs_error_t err; + + // Test single listen port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; listen 9443;}}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("9443", listens.at(0).c_str()); + } + + // Test multiple listen ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; listen 9443 9444 9445;}}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("9443", listens.at(0).c_str()); + EXPECT_STREQ("9444", listens.at(1).c_str()); + EXPECT_STREQ("9445", listens.at(2).c_str()); + } + + // Test IPv6 address + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; listen [::1]:9443;}}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("[::1]:9443", listens.at(0).c_str()); + } + + // Test IPv4 address with port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; listen 127.0.0.1:9443;}}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("127.0.0.1:9443", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigHttpsStreamTest, CheckHttpsStreamListensEnvOverride) +{ + srs_error_t err; + + // Test environment variable override with single port + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, https_listen, "SRS_HTTP_SERVER_HTTPS_LISTEN", "7443"); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("7443", listens.at(0).c_str()); + } + + // Test environment variable override with multiple ports + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, https_listen, "SRS_HTTP_SERVER_HTTPS_LISTEN", "7443 7444 7445"); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("7443", listens.at(0).c_str()); + EXPECT_STREQ("7444", listens.at(1).c_str()); + EXPECT_STREQ("7445", listens.at(2).c_str()); + } + + // Test environment variable override takes precedence over config file + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; listen 9443;}}")); + + SrsSetEnvConfig(conf, https_listen, "SRS_HTTP_SERVER_HTTPS_LISTEN", "7443"); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("7443", listens.at(0).c_str()); + } + + // Test empty environment variable falls back to config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; listen 9443;}}")); + + SrsSetEnvConfig(conf, https_listen, "SRS_HTTP_SERVER_HTTPS_LISTEN", ""); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("9443", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigHttpsStreamTest, CheckHttpsStreamListensEdgeCases) +{ + srs_error_t err; + + // Test with whitespace in environment variable + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, https_listen, "SRS_HTTP_SERVER_HTTPS_LISTEN", "7443 7444"); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(2, (int)listens.size()); + EXPECT_STREQ("7443", listens.at(0).c_str()); + EXPECT_STREQ("7444", listens.at(1).c_str()); + } + + // Test environment variable with empty string (should fall back to default) + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, https_listen, "SRS_HTTP_SERVER_HTTPS_LISTEN", ""); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8088", listens.at(0).c_str()); + } + + // Test complex configuration with nested sections + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "http_server{" + "enabled on;" + "listen 8080;" + "dir ./objs/nginx/html;" + "https{" + "enabled on;" + "listen 8443 9443;" + "key ./conf/server.key;" + "cert ./conf/server.crt;" + "}" + "}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(2, (int)listens.size()); + EXPECT_STREQ("8443", listens.at(0).c_str()); + EXPECT_STREQ("9443", listens.at(1).c_str()); + } +} + +VOID TEST(ConfigHttpsStreamTest, CheckHttpsStreamListensDefaultBehavior) +{ + srs_error_t err; + + // Test the specific case mentioned in the request: empty listens vector should use DEFAULT + // This simulates the internal behavior when conf->args_.size() is 0 + if (true) { + MockSrsConfig conf; + // Create a configuration where listen directive exists but has no arguments + // This should trigger the "if (listens.empty()) { listens.push_back(DEFAULT); }" code path + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; listen;}}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8088", listens.at(0).c_str()); + } + + // Test default behavior when environment variable is not set and no config exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8088", listens.at(0).c_str()); + } + + // Test that default is used when https section is missing + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; listen 8080;}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8088", listens.at(0).c_str()); + } + + // Test that default is used when listen directive is missing from https section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; key ./server.key;}}")); + + vector listens = conf.get_https_stream_listens(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("8088", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigHttpsStreamTest, CheckHttpsStreamListensConsistency) +{ + srs_error_t err; + + // Test consistency with other similar methods (like get_http_stream_listens) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "http_server{" + "enabled on;" + "listen 8080;" + "https{" + "enabled on;" + "listen 8443;" + "}" + "}")); + + vector http_listens = conf.get_http_stream_listens(); + vector https_listens = conf.get_https_stream_listens(); + + EXPECT_EQ(1, (int)http_listens.size()); + EXPECT_STREQ("8080", http_listens.at(0).c_str()); + + EXPECT_EQ(1, (int)https_listens.size()); + EXPECT_STREQ("8443", https_listens.at(0).c_str()); + } + + // Test that HTTPS and HTTP can have different ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "http_server{" + "enabled on;" + "listen 8080 8081;" + "https{" + "enabled on;" + "listen 8443 8444 8445;" + "}" + "}")); + + vector http_listens = conf.get_http_stream_listens(); + vector https_listens = conf.get_https_stream_listens(); + + EXPECT_EQ(2, (int)http_listens.size()); + EXPECT_EQ(3, (int)https_listens.size()); + + EXPECT_STREQ("8080", http_listens.at(0).c_str()); + EXPECT_STREQ("8081", http_listens.at(1).c_str()); + + EXPECT_STREQ("8443", https_listens.at(0).c_str()); + EXPECT_STREQ("8444", https_listens.at(1).c_str()); + EXPECT_STREQ("8445", https_listens.at(2).c_str()); + } +} + +VOID TEST(ConfigHttpsStreamTest, CheckHttpsStreamSslKey) +{ + srs_error_t err; + + // Test default value when no http_server section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_STREQ("./conf/server.key", conf.get_https_stream_ssl_key().c_str()); + } + + // Test default value when https section doesn't exist + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on;}")); + + EXPECT_STREQ("./conf/server.key", conf.get_https_stream_ssl_key().c_str()); + } + + // Test default value when key directive doesn't exist + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on;}}")); + + EXPECT_STREQ("./conf/server.key", conf.get_https_stream_ssl_key().c_str()); + } + + // Test custom key path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; key /path/to/custom.key;}}")); + + EXPECT_STREQ("/path/to/custom.key", conf.get_https_stream_ssl_key().c_str()); + } + + // Test relative key path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; key ./ssl/server.key;}}")); + + EXPECT_STREQ("./ssl/server.key", conf.get_https_stream_ssl_key().c_str()); + } +} + +VOID TEST(ConfigHttpsStreamTest, CheckHttpsStreamSslCert) +{ + srs_error_t err; + + // Test default value when no http_server section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_STREQ("./conf/server.crt", conf.get_https_stream_ssl_cert().c_str()); + } + + // Test default value when https section doesn't exist + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on;}")); + + EXPECT_STREQ("./conf/server.crt", conf.get_https_stream_ssl_cert().c_str()); + } + + // Test default value when cert directive doesn't exist + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on;}}")); + + EXPECT_STREQ("./conf/server.crt", conf.get_https_stream_ssl_cert().c_str()); + } + + // Test custom cert path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; cert /path/to/custom.crt;}}")); + + EXPECT_STREQ("/path/to/custom.crt", conf.get_https_stream_ssl_cert().c_str()); + } + + // Test relative cert path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "http_server{enabled on; https{enabled on; cert ./ssl/server.crt;}}")); + + EXPECT_STREQ("./ssl/server.crt", conf.get_https_stream_ssl_cert().c_str()); + } + + // Test both key and cert together + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "http_server{" + "enabled on;" + "https{" + "enabled on;" + "key /custom/path/server.key;" + "cert /custom/path/server.crt;" + "}" + "}")); + + EXPECT_STREQ("/custom/path/server.key", conf.get_https_stream_ssl_key().c_str()); + EXPECT_STREQ("/custom/path/server.crt", conf.get_https_stream_ssl_cert().c_str()); + } +} + +VOID TEST(ConfigVhostHttpTest, CheckVhostHttpEnabled) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_FALSE(conf.get_vhost_http_enabled("__defaultVhost__")); + } + + // Test default value when vhost exists but no http_static section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_FALSE(conf.get_vhost_http_enabled("test.com")); + } + + // Test default value when http_static section exists but no enabled directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{}}")); + + EXPECT_FALSE(conf.get_vhost_http_enabled("test.com")); + } + + // Test default value when enabled directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{enabled;}}")); + + EXPECT_FALSE(conf.get_vhost_http_enabled("test.com")); + } + + // Test enabled = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{enabled on;}}")); + + EXPECT_TRUE(conf.get_vhost_http_enabled("test.com")); + } + + // Test enabled = off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{enabled off;}}")); + + EXPECT_FALSE(conf.get_vhost_http_enabled("test.com")); + } + + // Test enabled = true (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{enabled true;}}")); + + EXPECT_FALSE(conf.get_vhost_http_enabled("test.com")); // "true" != "on", so it's false + } + + // Test enabled = false (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{enabled false;}}")); + + EXPECT_FALSE(conf.get_vhost_http_enabled("test.com")); // "false" != "on", so it's false + } +} + +VOID TEST(ConfigVhostHttpTest, CheckVhostHttpMount) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_STREQ("[vhost]/", conf.get_vhost_http_mount("__defaultVhost__").c_str()); + } + + // Test default value when vhost exists but no http_static section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_STREQ("[vhost]/", conf.get_vhost_http_mount("test.com").c_str()); + } + + // Test default value when http_static section exists but no mount directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{}}")); + + EXPECT_STREQ("[vhost]/", conf.get_vhost_http_mount("test.com").c_str()); + } + + // Test default value when mount directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{mount;}}")); + + EXPECT_STREQ("[vhost]/", conf.get_vhost_http_mount("test.com").c_str()); + } + + // Test custom mount path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{mount /custom/path;}}")); + + EXPECT_STREQ("/custom/path", conf.get_vhost_http_mount("test.com").c_str()); + } + + // Test root mount path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{mount /;}}")); + + EXPECT_STREQ("/", conf.get_vhost_http_mount("test.com").c_str()); + } +} + +VOID TEST(ConfigVhostHttpTest, CheckVhostHttpDir) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_STREQ("./objs/nginx/html", conf.get_vhost_http_dir("__defaultVhost__").c_str()); + } + + // Test default value when vhost exists but no http_static section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_STREQ("./objs/nginx/html", conf.get_vhost_http_dir("test.com").c_str()); + } + + // Test default value when http_static section exists but no dir directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{}}")); + + EXPECT_STREQ("./objs/nginx/html", conf.get_vhost_http_dir("test.com").c_str()); + } + + // Test default value when dir directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{dir;}}")); + + EXPECT_STREQ("./objs/nginx/html", conf.get_vhost_http_dir("test.com").c_str()); + } + + // Test custom directory path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{dir /var/www/html;}}")); + + EXPECT_STREQ("/var/www/html", conf.get_vhost_http_dir("test.com").c_str()); + } + + // Test relative directory path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_static{dir ./html;}}")); + + EXPECT_STREQ("./html", conf.get_vhost_http_dir("test.com").c_str()); + } +} + +VOID TEST(ConfigVhostHttpRemuxTest, CheckVhostHttpRemuxEnabled) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_FALSE(conf.get_vhost_http_remux_enabled("__defaultVhost__")); + } + + // Test default value when vhost exists but no http_remux section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_enabled("test.com")); + } + + // Test default value when http_remux section exists but no enabled directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{}}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_enabled("test.com")); + } + + // Test default value when enabled directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{enabled;}}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_enabled("test.com")); + } + + // Test enabled = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{enabled on;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_enabled("test.com")); + } + + // Test enabled = off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{enabled off;}}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_enabled("test.com")); + } + + // Test enabled = true (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{enabled true;}}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_enabled("test.com")); // "true" != "on", so it's false + } + + // Test enabled = false (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{enabled false;}}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_enabled("test.com")); // "false" != "on", so it's false + } +} + +VOID TEST(ConfigVhostHttpRemuxTest, CheckVhostHttpRemuxFastCache) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_EQ(0, conf.get_vhost_http_remux_fast_cache("__defaultVhost__")); + } + + // Test default value when vhost exists but no http_remux section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_EQ(0, conf.get_vhost_http_remux_fast_cache("test.com")); + } + + // Test default value when http_remux section exists but no fast_cache directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{}}")); + + EXPECT_EQ(0, conf.get_vhost_http_remux_fast_cache("test.com")); + } + + // Test default value when fast_cache directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{fast_cache;}}")); + + EXPECT_EQ(0, conf.get_vhost_http_remux_fast_cache("test.com")); + } + + // Test fast_cache = 30 (seconds) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{fast_cache 30;}}")); + + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_vhost_http_remux_fast_cache("test.com")); + } + + // Test fast_cache = 0.5 (half second) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{fast_cache 0.5;}}")); + + EXPECT_EQ(srs_utime_t(0.5 * SRS_UTIME_SECONDS), conf.get_vhost_http_remux_fast_cache("test.com")); + } + + // Test fast_cache = 120 (2 minutes) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{fast_cache 120;}}")); + + EXPECT_EQ(120 * SRS_UTIME_SECONDS, conf.get_vhost_http_remux_fast_cache("test.com")); + } +} + +VOID TEST(ConfigVhostHttpRemuxTest, CheckVhostHttpRemuxDropIfNotMatch) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_TRUE(conf.get_vhost_http_remux_drop_if_not_match("__defaultVhost__")); + } + + // Test default value when vhost exists but no http_remux section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_drop_if_not_match("test.com")); + } + + // Test default value when http_remux section exists but no drop_if_not_match directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_drop_if_not_match("test.com")); + } + + // Test default value when drop_if_not_match directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{drop_if_not_match;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_drop_if_not_match("test.com")); + } + + // Test drop_if_not_match = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{drop_if_not_match on;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_drop_if_not_match("test.com")); + } + + // Test drop_if_not_match = off (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{drop_if_not_match off;}}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_drop_if_not_match("test.com")); // "off" is false + } + + // Test drop_if_not_match = true (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{drop_if_not_match true;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_drop_if_not_match("test.com")); // "true" != "off", so it's true + } + + // Test drop_if_not_match = false (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{drop_if_not_match false;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_drop_if_not_match("test.com")); // "false" != "off", so it's true + } +} + +VOID TEST(ConfigVhostHttpRemuxTest, CheckVhostHttpRemuxHasAudio) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_audio("__defaultVhost__")); + } + + // Test default value when vhost exists but no http_remux section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_audio("test.com")); + } + + // Test default value when http_remux section exists but no has_audio directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_audio("test.com")); + } + + // Test default value when has_audio directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_audio;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_audio("test.com")); + } + + // Test has_audio = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_audio on;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_audio("test.com")); + } + + // Test has_audio = off (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_audio off;}}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_has_audio("test.com")); // "off" is false + } + + // Test has_audio = true (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_audio true;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_audio("test.com")); // "true" != "off", so it's true + } + + // Test has_audio = false (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_audio false;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_audio("test.com")); // "false" != "off", so it's true + } +} + +VOID TEST(ConfigVhostHttpRemuxTest, CheckVhostHttpRemuxHasVideo) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_video("__defaultVhost__")); + } + + // Test default value when vhost exists but no http_remux section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_video("test.com")); + } + + // Test default value when http_remux section exists but no has_video directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_video("test.com")); + } + + // Test default value when has_video directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_video;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_video("test.com")); + } + + // Test has_video = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_video on;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_video("test.com")); + } + + // Test has_video = off (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_video off;}}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_has_video("test.com")); // "off" is false + } + + // Test has_video = true (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_video true;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_video("test.com")); // "true" != "off", so it's true + } + + // Test has_video = false (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{has_video false;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_has_video("test.com")); // "false" != "off", so it's true + } +} + +VOID TEST(ConfigVhostHttpRemuxTest, CheckVhostHttpRemuxGuessHasAv) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_TRUE(conf.get_vhost_http_remux_guess_has_av("__defaultVhost__")); + } + + // Test default value when vhost exists but no http_remux section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_guess_has_av("test.com")); + } + + // Test default value when http_remux section exists but no guess_has_av directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_guess_has_av("test.com")); + } + + // Test default value when guess_has_av directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{guess_has_av;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_guess_has_av("test.com")); + } + + // Test guess_has_av = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{guess_has_av on;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_guess_has_av("test.com")); + } + + // Test guess_has_av = off (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{guess_has_av off;}}")); + + EXPECT_FALSE(conf.get_vhost_http_remux_guess_has_av("test.com")); // "off" is false + } + + // Test guess_has_av = true (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{guess_has_av true;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_guess_has_av("test.com")); // "true" != "off", so it's true + } + + // Test guess_has_av = false (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{guess_has_av false;}}")); + + EXPECT_TRUE(conf.get_vhost_http_remux_guess_has_av("test.com")); // "false" != "off", so it's true + } +} + +VOID TEST(ConfigVhostHttpRemuxTest, CheckVhostHttpRemuxMount) +{ + srs_error_t err; + + // Test default value when no vhost exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_STREQ("[vhost]/[app]/[stream].flv", conf.get_vhost_http_remux_mount("__defaultVhost__").c_str()); + } + + // Test default value when vhost exists but no http_remux section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{}")); + + EXPECT_STREQ("[vhost]/[app]/[stream].flv", conf.get_vhost_http_remux_mount("test.com").c_str()); + } + + // Test default value when http_remux section exists but no mount directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{}}")); + + EXPECT_STREQ("[vhost]/[app]/[stream].flv", conf.get_vhost_http_remux_mount("test.com").c_str()); + } + + // Test default value when mount directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{mount;}}")); + + EXPECT_STREQ("[vhost]/[app]/[stream].flv", conf.get_vhost_http_remux_mount("test.com").c_str()); + } + + // Test custom mount path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{mount /live/;}}")); + + EXPECT_STREQ("/live/", conf.get_vhost_http_remux_mount("test.com").c_str()); + } + + // Test root mount path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{mount /;}}")); + + EXPECT_STREQ("/", conf.get_vhost_http_remux_mount("test.com").c_str()); + } + + // Test mount path without trailing slash + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost test.com{http_remux{mount /stream;}}")); + + EXPECT_STREQ("/stream", conf.get_vhost_http_remux_mount("test.com").c_str()); + } +} + +VOID TEST(ConfigHeartbeatTest, CheckHeartbeatEnabled) +{ + srs_error_t err; + + // Test default value when no heartbeat section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_FALSE(conf.get_heartbeat_enabled()); + } + + // Test default value when heartbeat section exists but no enabled directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{}")); + + EXPECT_FALSE(conf.get_heartbeat_enabled()); + } + + // Test default value when enabled directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{enabled;}")); + + EXPECT_FALSE(conf.get_heartbeat_enabled()); + } + + // Test enabled = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{enabled on;}")); + + EXPECT_TRUE(conf.get_heartbeat_enabled()); + } + + // Test enabled = off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{enabled off;}")); + + EXPECT_FALSE(conf.get_heartbeat_enabled()); + } + + // Test enabled = true (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{enabled true;}")); + + EXPECT_FALSE(conf.get_heartbeat_enabled()); // "true" != "on", so it's false + } + + // Test enabled = false (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{enabled false;}")); + + EXPECT_FALSE(conf.get_heartbeat_enabled()); // "false" != "on", so it's false + } +} + +VOID TEST(ConfigHeartbeatTest, CheckHeartbeatUrl) +{ + srs_error_t err; + + // Test default value when no heartbeat section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_STREQ("http://127.0.0.1:8085/api/v1/servers", conf.get_heartbeat_url().c_str()); + } + + // Test default value when heartbeat section exists but no url directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{}")); + + EXPECT_STREQ("http://127.0.0.1:8085/api/v1/servers", conf.get_heartbeat_url().c_str()); + } + + // Test default value when url directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{url;}")); + + EXPECT_STREQ("http://127.0.0.1:8085/api/v1/servers", conf.get_heartbeat_url().c_str()); + } + + // Test custom URL + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{url http://127.0.0.1:8085/api/v1/heartbeat;}")); + + EXPECT_STREQ("http://127.0.0.1:8085/api/v1/heartbeat", conf.get_heartbeat_url().c_str()); + } + + // Test HTTPS URL + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{url https://example.com/heartbeat;}")); + + EXPECT_STREQ("https://example.com/heartbeat", conf.get_heartbeat_url().c_str()); + } + + // Test URL with query parameters + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{url http://example.com/api?token=abc123;}")); + + EXPECT_STREQ("http://example.com/api?token=abc123", conf.get_heartbeat_url().c_str()); + } +} + +VOID TEST(ConfigHeartbeatTest, CheckHeartbeatDeviceId) +{ + srs_error_t err; + + // Test default value when no heartbeat section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_STREQ("", conf.get_heartbeat_device_id().c_str()); + } + + // Test default value when heartbeat section exists but no device_id directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{}")); + + EXPECT_STREQ("", conf.get_heartbeat_device_id().c_str()); + } + + // Test default value when device_id directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{device_id;}")); + + EXPECT_STREQ("", conf.get_heartbeat_device_id().c_str()); + } + + // Test custom device ID + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{device_id srs-server-001;}")); + + EXPECT_STREQ("srs-server-001", conf.get_heartbeat_device_id().c_str()); + } + + // Test numeric device ID + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{device_id 12345;}")); + + EXPECT_STREQ("12345", conf.get_heartbeat_device_id().c_str()); + } + + // Test UUID-like device ID + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{device_id 550e8400-e29b-41d4-a716-446655440000;}")); + + EXPECT_STREQ("550e8400-e29b-41d4-a716-446655440000", conf.get_heartbeat_device_id().c_str()); + } +} + +VOID TEST(ConfigHeartbeatTest, CheckHeartbeatSummaries) +{ + srs_error_t err; + + // Test default value when no heartbeat section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_FALSE(conf.get_heartbeat_summaries()); + } + + // Test default value when heartbeat section exists but no summaries directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{}")); + + EXPECT_FALSE(conf.get_heartbeat_summaries()); + } + + // Test default value when summaries directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{summaries;}")); + + EXPECT_FALSE(conf.get_heartbeat_summaries()); + } + + // Test summaries = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{summaries on;}")); + + EXPECT_TRUE(conf.get_heartbeat_summaries()); + } + + // Test summaries = off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{summaries off;}")); + + EXPECT_FALSE(conf.get_heartbeat_summaries()); + } + + // Test summaries = true (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{summaries true;}")); + + EXPECT_FALSE(conf.get_heartbeat_summaries()); // "true" != "on", so it's false + } + + // Test summaries = false (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{summaries false;}")); + + EXPECT_FALSE(conf.get_heartbeat_summaries()); // "false" != "on", so it's false + } +} + +VOID TEST(ConfigHeartbeatTest, CheckHeartbeatPorts) +{ + srs_error_t err; + + // Test default value when no heartbeat section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_FALSE(conf.get_heartbeat_ports()); + } + + // Test default value when heartbeat section exists but no ports directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{}")); + + EXPECT_FALSE(conf.get_heartbeat_ports()); + } + + // Test default value when ports directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{ports;}")); + + EXPECT_FALSE(conf.get_heartbeat_ports()); + } + + // Test ports = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{ports on;}")); + + EXPECT_TRUE(conf.get_heartbeat_ports()); + } + + // Test ports = off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{ports off;}")); + + EXPECT_FALSE(conf.get_heartbeat_ports()); + } + + // Test ports = true (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{ports true;}")); + + EXPECT_FALSE(conf.get_heartbeat_ports()); // "true" != "on", so it's false + } + + // Test ports = false (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{ports false;}")); + + EXPECT_FALSE(conf.get_heartbeat_ports()); // "false" != "on", so it's false + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{ports off;}")); + + SrsSetEnvConfig(conf, heartbeat_ports, "SRS_HEARTBEAT_PORTS", "on"); + EXPECT_TRUE(conf.get_heartbeat_ports()); + } + + // Test environment variable override with config file precedence when env is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "heartbeat{ports on;}")); + + SrsSetEnvConfig(conf, heartbeat_ports, "SRS_HEARTBEAT_PORTS", ""); + EXPECT_TRUE(conf.get_heartbeat_ports()); + } +} + +VOID TEST(ConfigHeartbeatTest, CheckHeartbeatCompleteConfiguration) +{ + srs_error_t err; + + // Test complete heartbeat configuration + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "heartbeat{" + "enabled on;" + "url http://127.0.0.1:8085/api/v1/heartbeat;" + "device_id srs-server-001;" + "summaries on;" + "ports on;" + "}")); + + EXPECT_TRUE(conf.get_heartbeat_enabled()); + EXPECT_STREQ("http://127.0.0.1:8085/api/v1/heartbeat", conf.get_heartbeat_url().c_str()); + EXPECT_STREQ("srs-server-001", conf.get_heartbeat_device_id().c_str()); + EXPECT_TRUE(conf.get_heartbeat_summaries()); + EXPECT_TRUE(conf.get_heartbeat_ports()); + } + + // Test heartbeat configuration with mixed values (SRS_CONF_PREFER_FALSE behavior) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "heartbeat{" + "enabled true;" + "url https://example.com/heartbeat?token=abc123;" + "device_id 550e8400-e29b-41d4-a716-446655440000;" + "summaries false;" + "ports true;" + "}")); + + EXPECT_FALSE(conf.get_heartbeat_enabled()); // "true" != "on", so it's false + EXPECT_STREQ("https://example.com/heartbeat?token=abc123", conf.get_heartbeat_url().c_str()); + EXPECT_STREQ("550e8400-e29b-41d4-a716-446655440000", conf.get_heartbeat_device_id().c_str()); + EXPECT_FALSE(conf.get_heartbeat_summaries()); // "false" != "on", so it's false + EXPECT_FALSE(conf.get_heartbeat_ports()); // "true" != "on", so it's false + } + + // Test heartbeat configuration with all defaults (disabled) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "heartbeat{" + "enabled off;" + "summaries off;" + "ports off;" + "}")); + + EXPECT_FALSE(conf.get_heartbeat_enabled()); + EXPECT_STREQ("http://127.0.0.1:8085/api/v1/servers", conf.get_heartbeat_url().c_str()); // Default URL + EXPECT_STREQ("", conf.get_heartbeat_device_id().c_str()); + EXPECT_FALSE(conf.get_heartbeat_summaries()); + EXPECT_FALSE(conf.get_heartbeat_ports()); + } +} + +VOID TEST(ConfigStatsTest, CheckStatsEnabled) +{ + srs_error_t err; + + // Test default value when no stats section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_TRUE(conf.get_stats_enabled()); // Default is true + } + + // Test default value when stats section exists but no enabled directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{}")); + + EXPECT_TRUE(conf.get_stats_enabled()); // Default is true + } + + // Test default value when enabled directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{enabled;}")); + + EXPECT_TRUE(conf.get_stats_enabled()); // Default is true + } + + // Test enabled = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{enabled on;}")); + + EXPECT_TRUE(conf.get_stats_enabled()); + } + + // Test enabled = off (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{enabled off;}")); + + EXPECT_FALSE(conf.get_stats_enabled()); // "off" is false + } + + // Test enabled = true (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{enabled true;}")); + + EXPECT_TRUE(conf.get_stats_enabled()); // "true" != "off", so it's true + } + + // Test enabled = false (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{enabled false;}")); + + EXPECT_TRUE(conf.get_stats_enabled()); // "false" != "off", so it's true + } + + // Test enabled = 0 (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{enabled 0;}")); + + EXPECT_TRUE(conf.get_stats_enabled()); // "0" != "off", so it's true + } + + // Test enabled = 1 (SRS_CONF_PREFER_TRUE: only "off" is false) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "stats{enabled 1;}")); + + EXPECT_TRUE(conf.get_stats_enabled()); // "1" != "off", so it's true + } +} + +VOID TEST(ConfigRtmpsTest, CheckRtmpsEnabled) +{ + srs_error_t err; + + // Test default value when no rtmps section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_FALSE(conf.get_rtmps_enabled()); // Default is false + } + + // Test default value when rtmps section exists but no enabled directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); // Default is false + } + + // Test default value when enabled directive exists but is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled;}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); // Default is false + } + + // Test enabled = on + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled on;}")); + + EXPECT_TRUE(conf.get_rtmps_enabled()); + } + + // Test enabled = off + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled off;}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); + } + + // Test enabled = true (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled true;}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); // "true" != "on", so it's false + } + + // Test enabled = false (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled false;}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); // "false" != "on", so it's false + } + + // Test enabled = 1 (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled 1;}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); // "1" != "on", so it's false + } + + // Test enabled = 0 (SRS_CONF_PREFER_FALSE: only "on" is true) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled 0;}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); // "0" != "on", so it's false + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled off;}")); + + SrsSetEnvConfig(conf, rtmps_enabled, "SRS_RTMPS_ENABLED", "on"); + EXPECT_TRUE(conf.get_rtmps_enabled()); + } + + // Test environment variable override with config file precedence when env is empty + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled on;}")); + + SrsSetEnvConfig(conf, rtmps_enabled, "SRS_RTMPS_ENABLED", ""); + EXPECT_TRUE(conf.get_rtmps_enabled()); + } + + // Test environment variable override with false value + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{enabled on;}")); + + SrsSetEnvConfig(conf, rtmps_enabled, "SRS_RTMPS_ENABLED", "off"); + EXPECT_FALSE(conf.get_rtmps_enabled()); + } +} + +VOID TEST(ConfigRtmpsTest, CheckRtmpsListen) +{ + srs_error_t err; + + // Test default value when no rtmps section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(0, (int)listens.size()); // Empty by default + } + + // Test default value when rtmps section exists but no listen directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{}")); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(0, (int)listens.size()); // Empty by default + } + + // Test default value when listen directive exists but has no arguments + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{listen;}")); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(0, (int)listens.size()); // Empty when no args + } + + // Test single listen port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{listen 1936;}")); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1936", listens.at(0).c_str()); + } + + // Test multiple listen ports + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{listen 1936 1937 1938;}")); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("1936", listens.at(0).c_str()); + EXPECT_STREQ("1937", listens.at(1).c_str()); + EXPECT_STREQ("1938", listens.at(2).c_str()); + } + + // Test IPv6 address + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{listen [::1]:1936;}")); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("[::1]:1936", listens.at(0).c_str()); + } + + // Test IPv4 address with port + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{listen 127.0.0.1:1936;}")); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("127.0.0.1:1936", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigRtmpsTest, CheckRtmpsListenEnvOverride) +{ + srs_error_t err; + + // Test environment variable override with single port + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, rtmps_listen, "SRS_RTMPS_LISTEN", "1936"); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1936", listens.at(0).c_str()); + } + + // Test environment variable override with multiple ports + if (true) { + MockSrsConfig conf; + + SrsSetEnvConfig(conf, rtmps_listen, "SRS_RTMPS_LISTEN", "1936 1937 1938"); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("1936", listens.at(0).c_str()); + EXPECT_STREQ("1937", listens.at(1).c_str()); + EXPECT_STREQ("1938", listens.at(2).c_str()); + } + + // Test environment variable override takes precedence over config file + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{listen 1936;}")); + + SrsSetEnvConfig(conf, rtmps_listen, "SRS_RTMPS_LISTEN", "1937"); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1937", listens.at(0).c_str()); + } + + // Test empty environment variable falls back to config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{listen 1936;}")); + + SrsSetEnvConfig(conf, rtmps_listen, "SRS_RTMPS_LISTEN", ""); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1936", listens.at(0).c_str()); + } +} + +VOID TEST(ConfigRtmpsTest, CheckRtmpsSslKey) +{ + srs_error_t err; + + // Test default value when no rtmps section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_STREQ("./conf/server.key", conf.get_rtmps_ssl_key().c_str()); + } + + // Test default value when rtmps section exists but no key directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{}")); + + EXPECT_STREQ("./conf/server.key", conf.get_rtmps_ssl_key().c_str()); + } + + // Test behavior when key directive exists but is empty (returns empty string, not default) + // Note: This is the actual behavior of the current implementation + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{key;}")); + + EXPECT_STREQ("", conf.get_rtmps_ssl_key().c_str()); // Returns empty string, not default + } + + // Test custom key path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{key /path/to/custom.key;}")); + + EXPECT_STREQ("/path/to/custom.key", conf.get_rtmps_ssl_key().c_str()); + } + + // Test relative key path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{key ./ssl/server.key;}")); + + EXPECT_STREQ("./ssl/server.key", conf.get_rtmps_ssl_key().c_str()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{key ./conf/server.key;}")); + + SrsSetEnvConfig(conf, rtmps_key, "SRS_RTMPS_KEY", "/custom/path/server.key"); + EXPECT_STREQ("/custom/path/server.key", conf.get_rtmps_ssl_key().c_str()); + } + + // Test environment variable override with empty value falls back to config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{key ./ssl/custom.key;}")); + + SrsSetEnvConfig(conf, rtmps_key, "SRS_RTMPS_KEY", ""); + EXPECT_STREQ("./ssl/custom.key", conf.get_rtmps_ssl_key().c_str()); + } +} + +VOID TEST(ConfigRtmpsTest, CheckRtmpsSslCert) +{ + srs_error_t err; + + // Test default value when no rtmps section exists + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + EXPECT_STREQ("./conf/server.crt", conf.get_rtmps_ssl_cert().c_str()); + } + + // Test default value when rtmps section exists but no cert directive + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{}")); + + EXPECT_STREQ("./conf/server.crt", conf.get_rtmps_ssl_cert().c_str()); + } + + // Test behavior when cert directive exists but is empty (returns empty string, not default) + // Note: This is the actual behavior of the current implementation + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{cert;}")); + + EXPECT_STREQ("", conf.get_rtmps_ssl_cert().c_str()); // Returns empty string, not default + } + + // Test custom cert path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{cert /path/to/custom.crt;}")); + + EXPECT_STREQ("/path/to/custom.crt", conf.get_rtmps_ssl_cert().c_str()); + } + + // Test relative cert path + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{cert ./ssl/server.crt;}")); + + EXPECT_STREQ("./ssl/server.crt", conf.get_rtmps_ssl_cert().c_str()); + } + + // Test environment variable override + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{cert ./conf/server.crt;}")); + + SrsSetEnvConfig(conf, rtmps_cert, "SRS_RTMPS_CERT", "/custom/path/server.crt"); + EXPECT_STREQ("/custom/path/server.crt", conf.get_rtmps_ssl_cert().c_str()); + } + + // Test environment variable override with empty value falls back to config + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{cert ./ssl/custom.crt;}")); + + SrsSetEnvConfig(conf, rtmps_cert, "SRS_RTMPS_CERT", ""); + EXPECT_STREQ("./ssl/custom.crt", conf.get_rtmps_ssl_cert().c_str()); + } +} + +VOID TEST(ConfigRtmpsTest, CheckRtmpsCompleteConfiguration) +{ + srs_error_t err; + + // Test complete RTMPS configuration + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "rtmps{" + "enabled on;" + "listen 1936 1937;" + "key /path/to/server.key;" + "cert /path/to/server.crt;" + "}")); + + EXPECT_TRUE(conf.get_rtmps_enabled()); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(2, (int)listens.size()); + EXPECT_STREQ("1936", listens.at(0).c_str()); + EXPECT_STREQ("1937", listens.at(1).c_str()); + + EXPECT_STREQ("/path/to/server.key", conf.get_rtmps_ssl_key().c_str()); + EXPECT_STREQ("/path/to/server.crt", conf.get_rtmps_ssl_cert().c_str()); + } + + // Test RTMPS configuration with environment variable overrides + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "rtmps{" + "enabled off;" + "listen 1936;" + "key ./conf/server.key;" + "cert ./conf/server.crt;" + "}")); + + SrsSetEnvConfig(conf, rtmps_enabled, "SRS_RTMPS_ENABLED", "on"); + SrsSetEnvConfig(conf, rtmps_listen, "SRS_RTMPS_LISTEN", "1937 1938"); + SrsSetEnvConfig(conf, rtmps_key, "SRS_RTMPS_KEY", "/env/server.key"); + SrsSetEnvConfig(conf, rtmps_cert, "SRS_RTMPS_CERT", "/env/server.crt"); + + EXPECT_TRUE(conf.get_rtmps_enabled()); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(2, (int)listens.size()); + EXPECT_STREQ("1937", listens.at(0).c_str()); + EXPECT_STREQ("1938", listens.at(1).c_str()); + + EXPECT_STREQ("/env/server.key", conf.get_rtmps_ssl_key().c_str()); + EXPECT_STREQ("/env/server.crt", conf.get_rtmps_ssl_cert().c_str()); + } + + // Test RTMPS configuration with defaults (disabled) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "rtmps{" + "enabled off;" + "}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(0, (int)listens.size()); // Empty by default + + EXPECT_STREQ("./conf/server.key", conf.get_rtmps_ssl_key().c_str()); // Default key + EXPECT_STREQ("./conf/server.crt", conf.get_rtmps_ssl_cert().c_str()); // Default cert + } + + // Test RTMPS configuration with mixed IPv4/IPv6 addresses + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF + "rtmps{" + "enabled on;" + "listen 127.0.0.1:1936 [::1]:1937 1938;" + "key ./ssl/mixed.key;" + "cert ./ssl/mixed.crt;" + "}")); + + EXPECT_TRUE(conf.get_rtmps_enabled()); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(3, (int)listens.size()); + EXPECT_STREQ("127.0.0.1:1936", listens.at(0).c_str()); + EXPECT_STREQ("[::1]:1937", listens.at(1).c_str()); + EXPECT_STREQ("1938", listens.at(2).c_str()); + + EXPECT_STREQ("./ssl/mixed.key", conf.get_rtmps_ssl_key().c_str()); + EXPECT_STREQ("./ssl/mixed.crt", conf.get_rtmps_ssl_cert().c_str()); + } +} + +VOID TEST(ConfigRtmpsTest, CheckRtmpsEdgeCases) +{ + srs_error_t err; + + // Test RTMPS with only key specified (cert uses default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{key /custom/server.key;}")); + + EXPECT_STREQ("/custom/server.key", conf.get_rtmps_ssl_key().c_str()); + EXPECT_STREQ("./conf/server.crt", conf.get_rtmps_ssl_cert().c_str()); // Default cert + } + + // Test RTMPS with only cert specified (key uses default) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{cert /custom/server.crt;}")); + + EXPECT_STREQ("./conf/server.key", conf.get_rtmps_ssl_key().c_str()); // Default key + EXPECT_STREQ("/custom/server.crt", conf.get_rtmps_ssl_cert().c_str()); + } + + // Test RTMPS with only listen specified (other values use defaults) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{listen 1936;}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); // Default is false + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1936", listens.at(0).c_str()); + + EXPECT_STREQ("./conf/server.key", conf.get_rtmps_ssl_key().c_str()); // Default key + EXPECT_STREQ("./conf/server.crt", conf.get_rtmps_ssl_cert().c_str()); // Default cert + } + + // Test RTMPS with empty section (all defaults) + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "rtmps{}")); + + EXPECT_FALSE(conf.get_rtmps_enabled()); // Default is false + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(0, (int)listens.size()); // Empty by default + + EXPECT_STREQ("./conf/server.key", conf.get_rtmps_ssl_key().c_str()); // Default key + EXPECT_STREQ("./conf/server.crt", conf.get_rtmps_ssl_cert().c_str()); // Default cert + } + + // Test environment variables with no config section + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); + + SrsSetEnvConfig(conf, rtmps_enabled, "SRS_RTMPS_ENABLED", "on"); + SrsSetEnvConfig(conf, rtmps_listen, "SRS_RTMPS_LISTEN", "1936"); + SrsSetEnvConfig(conf, rtmps_key, "SRS_RTMPS_KEY", "/env/server.key"); + SrsSetEnvConfig(conf, rtmps_cert, "SRS_RTMPS_CERT", "/env/server.crt"); + + EXPECT_TRUE(conf.get_rtmps_enabled()); + + vector listens = conf.get_rtmps_listen(); + EXPECT_EQ(1, (int)listens.size()); + EXPECT_STREQ("1936", listens.at(0).c_str()); + + EXPECT_STREQ("/env/server.key", conf.get_rtmps_ssl_key().c_str()); + EXPECT_STREQ("/env/server.crt", conf.get_rtmps_ssl_cert().c_str()); + } +} diff --git a/trunk/src/utest/srs_utest_config4.hpp b/trunk/src/utest/srs_utest_config4.hpp new file mode 100644 index 000000000..99725f5a1 --- /dev/null +++ b/trunk/src/utest/srs_utest_config4.hpp @@ -0,0 +1,15 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// + +#ifndef SRS_UTEST_CONFIG4_HPP +#define SRS_UTEST_CONFIG4_HPP + +/* +#include +*/ +#include + +#endif diff --git a/trunk/src/utest/srs_utest_kernel3.cpp b/trunk/src/utest/srs_utest_kernel3.cpp index c5773e133..ea1cf3e23 100644 --- a/trunk/src/utest/srs_utest_kernel3.cpp +++ b/trunk/src/utest/srs_utest_kernel3.cpp @@ -2031,22 +2031,22 @@ VOID TEST(KernelRtcRtpTest, SrsRtpPacketBasics) SrsRtpPacket packet; // Test initial state - EXPECT_EQ(0, packet.header.get_sequence()); - EXPECT_EQ(0, packet.header.get_timestamp()); - EXPECT_EQ(0, packet.header.get_ssrc()); + EXPECT_EQ(0, packet.header_.get_sequence()); + EXPECT_EQ(0, packet.header_.get_timestamp()); + EXPECT_EQ(0, packet.header_.get_ssrc()); EXPECT_EQ(NULL, packet.payload()); EXPECT_EQ(0, packet.nalu_type_); EXPECT_EQ(SrsFrameTypeReserved, packet.frame_type_); EXPECT_EQ(-1, packet.get_avsync_time()); // Test setting header values - packet.header.set_sequence(100); - packet.header.set_timestamp(200); - packet.header.set_ssrc(0xABCDEF00); + packet.header_.set_sequence(100); + packet.header_.set_timestamp(200); + packet.header_.set_ssrc(0xABCDEF00); - EXPECT_EQ(100, packet.header.get_sequence()); - EXPECT_EQ(200, packet.header.get_timestamp()); - EXPECT_EQ(0xABCDEF00, packet.header.get_ssrc()); + EXPECT_EQ(100, packet.header_.get_sequence()); + EXPECT_EQ(200, packet.header_.get_timestamp()); + EXPECT_EQ(0xABCDEF00, packet.header_.get_ssrc()); // Test wrapping buffer char test_data[64] = "test payload data"; @@ -2418,11 +2418,11 @@ VOID TEST(KernelRtcRtpTest, SrsRtpPacketCopyAndEncodeDecode) // Create original packet SrsRtpPacket original; - original.header.set_sequence(1000); - original.header.set_timestamp(2000); - original.header.set_ssrc(0x12345678); - original.header.set_marker(true); - original.header.set_payload_type(96); + original.header_.set_sequence(1000); + original.header_.set_timestamp(2000); + original.header_.set_ssrc(0x12345678); + original.header_.set_marker(true); + original.header_.set_payload_type(96); original.nalu_type_ = SrsAvcNaluTypeIDR; original.frame_type_ = SrsFrameTypeVideo; original.set_avsync_time(5000); @@ -2434,11 +2434,11 @@ VOID TEST(KernelRtcRtpTest, SrsRtpPacketCopyAndEncodeDecode) // Test copy SrsRtpPacket *copied = original.copy(); EXPECT_TRUE(copied != NULL); - EXPECT_EQ(1000, copied->header.get_sequence()); - EXPECT_EQ(2000, copied->header.get_timestamp()); - EXPECT_EQ(0x12345678, copied->header.get_ssrc()); - EXPECT_TRUE(copied->header.get_marker()); - EXPECT_EQ(96, copied->header.get_payload_type()); + EXPECT_EQ(1000, copied->header_.get_sequence()); + EXPECT_EQ(2000, copied->header_.get_timestamp()); + EXPECT_EQ(0x12345678, copied->header_.get_ssrc()); + EXPECT_TRUE(copied->header_.get_marker()); + EXPECT_EQ(96, copied->header_.get_payload_type()); EXPECT_EQ(SrsAvcNaluTypeIDR, copied->nalu_type_); EXPECT_EQ(SrsFrameTypeVideo, copied->frame_type_); EXPECT_EQ(5000, copied->get_avsync_time()); @@ -2455,11 +2455,11 @@ VOID TEST(KernelRtcRtpTest, SrsRtpPacketCopyAndEncodeDecode) SrsRtpPacket decoded; HELPER_EXPECT_SUCCESS(decoded.decode(&decode_buffer)); - EXPECT_EQ(1000, decoded.header.get_sequence()); - EXPECT_EQ(2000, decoded.header.get_timestamp()); - EXPECT_EQ(0x12345678, decoded.header.get_ssrc()); - EXPECT_TRUE(decoded.header.get_marker()); - EXPECT_EQ(96, decoded.header.get_payload_type()); + EXPECT_EQ(1000, decoded.header_.get_sequence()); + EXPECT_EQ(2000, decoded.header_.get_timestamp()); + EXPECT_EQ(0x12345678, decoded.header_.get_ssrc()); + EXPECT_TRUE(decoded.header_.get_marker()); + EXPECT_EQ(96, decoded.header_.get_payload_type()); } VOID TEST(KernelKbpsTest, SrsPps_MockClockUpdate) diff --git a/trunk/src/utest/srs_utest_protocol3.cpp b/trunk/src/utest/srs_utest_protocol3.cpp index 42feb3171..7c289b25b 100644 --- a/trunk/src/utest/srs_utest_protocol3.cpp +++ b/trunk/src/utest/srs_utest_protocol3.cpp @@ -1550,11 +1550,11 @@ VOID TEST(ProtocolRtpTest, SrsRtpVideoBuilderPackageStapA) HELPER_EXPECT_SUCCESS(builder.package_stap_a(msg, pkt)); // Verify RTP packet was properly configured - EXPECT_EQ(payload_type, pkt->header.get_payload_type()); - EXPECT_EQ(ssrc, pkt->header.get_ssrc()); + EXPECT_EQ(payload_type, pkt->header_.get_payload_type()); + EXPECT_EQ(ssrc, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(1000 * 90, pkt->header.get_timestamp()); // timestamp * 90 - EXPECT_FALSE(pkt->header.get_marker()); // STAP-A should not have marker bit set + EXPECT_EQ(1000 * 90, pkt->header_.get_timestamp()); // timestamp * 90 + EXPECT_FALSE(pkt->header_.get_marker()); // STAP-A should not have marker bit set // Verify STAP-A payload was created EXPECT_TRUE(pkt->payload() != NULL); @@ -1638,10 +1638,10 @@ VOID TEST(ProtocolRtpTest, SrsRtpVideoBuilderPackageNalusWithFormat) // Verify first packet configuration if (!pkts.empty()) { SrsRtpPacket *pkt = pkts[0]; - EXPECT_EQ(payload_type, pkt->header.get_payload_type()); - EXPECT_EQ(ssrc, pkt->header.get_ssrc()); + EXPECT_EQ(payload_type, pkt->header_.get_payload_type()); + EXPECT_EQ(ssrc, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(2000 * 90, pkt->header.get_timestamp()); // timestamp * 90 + EXPECT_EQ(2000 * 90, pkt->header_.get_timestamp()); // timestamp * 90 } // Clean up any created packets @@ -1694,10 +1694,10 @@ VOID TEST(ProtocolRtpTest, SrsRtpVideoBuilderPackageSingleNalu) if (!pkts.empty()) { SrsRtpPacket *pkt = pkts[0]; - EXPECT_EQ(payload_type, pkt->header.get_payload_type()); - EXPECT_EQ(ssrc, pkt->header.get_ssrc()); + EXPECT_EQ(payload_type, pkt->header_.get_payload_type()); + EXPECT_EQ(ssrc, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(3000 * 90, pkt->header.get_timestamp()); // timestamp * 90 + EXPECT_EQ(3000 * 90, pkt->header_.get_timestamp()); // timestamp * 90 } // Clean up packets @@ -1769,10 +1769,10 @@ VOID TEST(ProtocolRtpTest, SrsRtpVideoBuilderPackageFuA) // Verify first packet configuration if (!pkts.empty()) { SrsRtpPacket *pkt = pkts[0]; - EXPECT_EQ(payload_type, pkt->header.get_payload_type()); - EXPECT_EQ(ssrc, pkt->header.get_ssrc()); + EXPECT_EQ(payload_type, pkt->header_.get_payload_type()); + EXPECT_EQ(ssrc, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(4000 * 90, pkt->header.get_timestamp()); // timestamp * 90 + EXPECT_EQ(4000 * 90, pkt->header_.get_timestamp()); // timestamp * 90 // Verify it's a FU-A payload SrsRtpFUAPayload2 *fua_payload = dynamic_cast(pkt->payload()); diff --git a/trunk/src/utest/srs_utest_protocol4.cpp b/trunk/src/utest/srs_utest_protocol4.cpp index bfaedf74f..a55580267 100644 --- a/trunk/src/utest/srs_utest_protocol4.cpp +++ b/trunk/src/utest/srs_utest_protocol4.cpp @@ -1472,12 +1472,12 @@ VOID TEST(RTPVideoBuilderTest, PackageStapAHevc) HELPER_ASSERT_SUCCESS(builder.package_stap_a(&msg, &pkt)); // Verify RTP header settings - EXPECT_EQ(96, pkt.header.get_payload_type()); - EXPECT_EQ(0x12345678, pkt.header.get_ssrc()); + EXPECT_EQ(96, pkt.header_.get_payload_type()); + EXPECT_EQ(0x12345678, pkt.header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt.frame_type_); - EXPECT_FALSE(pkt.header.get_marker()); - EXPECT_EQ(100, pkt.header.get_sequence()); - EXPECT_EQ(90000, pkt.header.get_timestamp()); // 1000 * 90 + EXPECT_FALSE(pkt.header_.get_marker()); + EXPECT_EQ(100, pkt.header_.get_sequence()); + EXPECT_EQ(90000, pkt.header_.get_timestamp()); // 1000 * 90 // Verify NALU type is set to HEVC STAP EXPECT_EQ(kStapHevc, pkt.nalu_type_); @@ -1599,11 +1599,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusWithEmptySamples) SrsRtpPacket *pkt = pkts[0]; // Verify RTP header settings - EXPECT_EQ(96, pkt->header.get_payload_type()); - EXPECT_EQ(0x12345678, pkt->header.get_ssrc()); + EXPECT_EQ(96, pkt->header_.get_payload_type()); + EXPECT_EQ(0x12345678, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(200, pkt->header.get_sequence()); - EXPECT_EQ(180000, pkt->header.get_timestamp()); // 2000 * 90 + EXPECT_EQ(200, pkt->header_.get_sequence()); + EXPECT_EQ(180000, pkt->header_.get_timestamp()); // 2000 * 90 // Verify NALU type is set to first valid NALU type (IDR) EXPECT_EQ(SrsAvcNaluTypeIDR, pkt->nalu_type_); @@ -1751,11 +1751,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusLargePayload) SrsRtpPacket *pkt = pkts[i]; // Verify RTP header settings - EXPECT_EQ(96, pkt->header.get_payload_type()); - EXPECT_EQ(0x87654321, pkt->header.get_ssrc()); + EXPECT_EQ(96, pkt->header_.get_payload_type()); + EXPECT_EQ(0x87654321, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(400 + i, pkt->header.get_sequence()); // Sequence increments - EXPECT_EQ(360000, pkt->header.get_timestamp()); // 4000 * 90 + EXPECT_EQ(400 + i, pkt->header_.get_sequence()); // Sequence increments + EXPECT_EQ(360000, pkt->header_.get_timestamp()); // 4000 * 90 // Verify NALU type is FU-A for fragmented packets EXPECT_EQ(kFuA, pkt->nalu_type_); @@ -1864,11 +1864,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusLargePayloadHevc) SrsRtpPacket *pkt = pkts[i]; // Verify RTP header settings - EXPECT_EQ(96, pkt->header.get_payload_type()); - EXPECT_EQ(0x11223344, pkt->header.get_ssrc()); + EXPECT_EQ(96, pkt->header_.get_payload_type()); + EXPECT_EQ(0x11223344, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(500 + i, pkt->header.get_sequence()); // Sequence increments - EXPECT_EQ(450000, pkt->header.get_timestamp()); // 5000 * 90 + EXPECT_EQ(500 + i, pkt->header_.get_sequence()); // Sequence increments + EXPECT_EQ(450000, pkt->header_.get_timestamp()); // 5000 * 90 // Verify NALU type is FU-A for fragmented packets EXPECT_EQ(kFuA, pkt->nalu_type_); @@ -1994,11 +1994,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusMultipleSamplesLargePayload) SrsRtpPacket *pkt = pkts[i]; // Verify RTP header settings - EXPECT_EQ(96, pkt->header.get_payload_type()); - EXPECT_EQ(0xAABBCCDD, pkt->header.get_ssrc()); + EXPECT_EQ(96, pkt->header_.get_payload_type()); + EXPECT_EQ(0xAABBCCDD, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(600 + i, pkt->header.get_sequence()); // Sequence increments - EXPECT_EQ(540000, pkt->header.get_timestamp()); // 6000 * 90 + EXPECT_EQ(600 + i, pkt->header_.get_sequence()); // Sequence increments + EXPECT_EQ(540000, pkt->header_.get_timestamp()); // 6000 * 90 // Verify NALU type is FU-A for fragmented packets EXPECT_EQ(kFuA, pkt->nalu_type_); @@ -2130,11 +2130,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusMultipleSamplesLargePayloadHevc) SrsRtpPacket *pkt = pkts[i]; // Verify RTP header settings - EXPECT_EQ(96, pkt->header.get_payload_type()); - EXPECT_EQ(0x12345678, pkt->header.get_ssrc()); + EXPECT_EQ(96, pkt->header_.get_payload_type()); + EXPECT_EQ(0x12345678, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(700 + i, pkt->header.get_sequence()); // Sequence increments - EXPECT_EQ(630000, pkt->header.get_timestamp()); // 7000 * 90 + EXPECT_EQ(700 + i, pkt->header_.get_sequence()); // Sequence increments + EXPECT_EQ(630000, pkt->header_.get_timestamp()); // 7000 * 90 // Verify NALU type is FU-A for fragmented packets EXPECT_EQ(kFuA, pkt->nalu_type_); @@ -2238,11 +2238,11 @@ VOID TEST(RTPVideoBuilderTest, PackageFuAHevc) SrsRtpPacket *pkt = pkts[i]; // Verify RTP header settings - EXPECT_EQ(96, pkt->header.get_payload_type()); - EXPECT_EQ(0x11223344, pkt->header.get_ssrc()); + EXPECT_EQ(96, pkt->header_.get_payload_type()); + EXPECT_EQ(0x11223344, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(800 + i, pkt->header.get_sequence()); // Sequence increments - EXPECT_EQ(720000, pkt->header.get_timestamp()); // 8000 * 90 + EXPECT_EQ(800 + i, pkt->header_.get_sequence()); // Sequence increments + EXPECT_EQ(720000, pkt->header_.get_timestamp()); // 8000 * 90 // Verify NALU type is HEVC FU-A for fragmented packets EXPECT_EQ(kFuHevc, pkt->nalu_type_); @@ -2351,11 +2351,11 @@ VOID TEST(RTPVideoBuilderTest, PackageFuAH264) SrsRtpPacket *pkt = pkts[i]; // Verify RTP header settings - EXPECT_EQ(96, pkt->header.get_payload_type()); - EXPECT_EQ(0x55667788, pkt->header.get_ssrc()); + EXPECT_EQ(96, pkt->header_.get_payload_type()); + EXPECT_EQ(0x55667788, pkt->header_.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); - EXPECT_EQ(900 + i, pkt->header.get_sequence()); // Sequence increments - EXPECT_EQ(810000, pkt->header.get_timestamp()); // 9000 * 90 + EXPECT_EQ(900 + i, pkt->header_.get_sequence()); // Sequence increments + EXPECT_EQ(810000, pkt->header_.get_timestamp()); // 9000 * 90 // Verify NALU type is H.264 FU-A for fragmented packets EXPECT_EQ(kFuA, pkt->nalu_type_); diff --git a/trunk/src/utest/srs_utest_reload.cpp b/trunk/src/utest/srs_utest_reload.cpp index e3f2bed44..c9b791db2 100644 --- a/trunk/src/utest/srs_utest_reload.cpp +++ b/trunk/src/utest/srs_utest_reload.cpp @@ -78,7 +78,7 @@ srs_error_t MockSrsReloadConfig::do_reload(string buf) srs_error_t err = srs_success; MockSrsReloadConfig conf; - if ((err = conf.parse(buf)) != srs_success) { + if ((err = conf.mock_parse(buf)) != srs_success) { return srs_error_wrap(err, "parse"); } @@ -97,7 +97,7 @@ VOID TEST(ConfigReloadTest, ReloadEmpty) MockSrsReloadConfig conf; conf.subscribe(&handler); - HELPER_EXPECT_FAILED(conf.parse("")); + HELPER_EXPECT_FAILED(conf.mock_parse("")); HELPER_EXPECT_FAILED(conf.do_reload("")); EXPECT_TRUE(handler.all_false()); } @@ -110,7 +110,7 @@ VOID TEST(ConfigReloadTest, ReloadVhostChunkSize) MockSrsReloadConfig conf; conf.subscribe(&handler); - HELPER_EXPECT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net { chunk_size 60000; }")); + HELPER_EXPECT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net { chunk_size 60000; }")); HELPER_EXPECT_SUCCESS(conf.do_reload(_MIN_OK_CONF "vhost ossrs.net { chunk_size 60000; }")); EXPECT_TRUE(handler.all_false()); handler.reset(); diff --git a/trunk/src/utest/srs_utest_rtc.cpp b/trunk/src/utest/srs_utest_rtc.cpp index 1a9a48e35..415aaef2c 100644 --- a/trunk/src/utest/srs_utest_rtc.cpp +++ b/trunk/src/utest/srs_utest_rtc.cpp @@ -1338,8 +1338,8 @@ VOID TEST(KernelRTCTest, NACKFetchRTPPacket) // The RTP queue will free the packet. if (true) { SrsRtpPacket *pkt = new SrsRtpPacket(); - pkt->header.set_sequence(100); - track->rtp_queue_->set(pkt->header.get_sequence(), pkt); + pkt->header_.set_sequence(100); + track->rtp_queue_->set(pkt->header_.get_sequence(), pkt); } // If sequence not match, packet not found. @@ -1670,7 +1670,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportNormal) uint32_t video_absolute_ts = srs_time_now_cached(); uint32_t video_rtp_ts = random(); - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); // No received any sender report, can not calculate absolute time, expect equal to -1. EXPECT_EQ(video_rtp_pkt->get_avsync_time(), -1); @@ -1688,7 +1688,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportNormal) // Video timebase 90000, fps=25 video_rtp_ts += 3600; video_absolute_ts += 40; - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); // Received one sender report, can not calculate absolute time, expect equal to -1. @@ -1703,7 +1703,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportNormal) // Video timebase 90000, fps=25 video_rtp_ts += 3600; video_absolute_ts += 40; - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); EXPECT_NEAR(video_rtp_pkt->get_avsync_time(), video_absolute_ts, 1); } @@ -1736,7 +1736,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportOutOfOrder) uint32_t video_absolute_ts = srs_time_now_cached(); uint32_t video_rtp_ts = random(); - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); // No received any sender report, can not calculate absolute time, expect equal to -1. EXPECT_EQ(video_rtp_pkt->get_avsync_time(), -1); @@ -1753,7 +1753,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportOutOfOrder) // Video timebase 90000, fps=25 video_rtp_ts += 3600; video_absolute_ts += 40; - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); // No received any sender report, can not calculate absolute time, expect equal to -1. @@ -1774,7 +1774,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportOutOfOrder) // Video timebase 90000, fps=25 video_rtp_ts += 3600; video_absolute_ts += 40; - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); EXPECT_NEAR(video_rtp_pkt->get_avsync_time(), video_absolute_ts, 1); } @@ -1807,7 +1807,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportConsecutive) uint32_t video_absolute_ts = srs_time_now_cached(); uint32_t video_rtp_ts = random(); - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); // No received any sender report, can not calculate absolute time, expect equal to -1. EXPECT_EQ(video_rtp_pkt->get_avsync_time(), -1); @@ -1825,7 +1825,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportConsecutive) // Video timebase 90000, fps=25 video_rtp_ts += 3600; video_absolute_ts += 40; - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); // Received one sender report, can not calculate absolute time, expect equal to -1. @@ -1840,7 +1840,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportConsecutive) // Video timebase 90000, fps=25 video_rtp_ts += 3600; video_absolute_ts += 40; - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); EXPECT_NEAR(video_rtp_pkt->get_avsync_time(), video_absolute_ts, 1); @@ -1911,7 +1911,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportDuplicated) uint32_t video_absolute_ts = srs_time_now_cached(); uint32_t video_rtp_ts = random(); - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); // No received any sender report, can not calculate absolute time, expect equal to -1. EXPECT_EQ(video_rtp_pkt->get_avsync_time(), -1); @@ -1929,7 +1929,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportDuplicated) // Video timebase 90000, fps=25 video_rtp_ts += 3600; video_absolute_ts += 40; - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); // Received one sender report, can not calculate absolute time, expect equal to -1. @@ -1944,7 +1944,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportDuplicated) // Video timebase 90000, fps=25 video_rtp_ts += 3600; video_absolute_ts += 40; - video_rtp_pkt->header.set_timestamp(video_rtp_ts); + video_rtp_pkt->header_.set_timestamp(video_rtp_ts); video->on_rtp(rtc_source, video_rtp_pkt); EXPECT_NEAR(video_rtp_pkt->get_avsync_time(), video_absolute_ts, 1); // Duplicate 3 sender report packets. diff --git a/trunk/src/utest/srs_utest_rtc2.cpp b/trunk/src/utest/srs_utest_rtc2.cpp index 2d147fcce..338668c3b 100644 --- a/trunk/src/utest/srs_utest_rtc2.cpp +++ b/trunk/src/utest/srs_utest_rtc2.cpp @@ -423,10 +423,10 @@ VOID TEST(KernelRTC2Test, SrsCodecPayloadCopyBehavior) SrsRtpPacket *mock_create_test_rtp_packet(uint16_t sequence_number, uint32_t timestamp, bool marker = false) { SrsRtpPacket *pkt = new SrsRtpPacket(); - pkt->header.set_sequence(sequence_number); - pkt->header.set_timestamp(timestamp); - pkt->header.set_marker(marker); - pkt->header.set_ssrc(12345); + pkt->header_.set_sequence(sequence_number); + pkt->header_.set_timestamp(timestamp); + pkt->header_.set_marker(marker); + pkt->header_.set_ssrc(12345); return pkt; } @@ -460,8 +460,8 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheBasicOperations) SrsRtpPacket *retrieved = cache.get_packet(100); EXPECT_TRUE(retrieved != NULL); - EXPECT_EQ(100, retrieved->header.get_sequence()); - EXPECT_EQ(1000, retrieved->header.get_timestamp()); + EXPECT_EQ(100, retrieved->header_.get_sequence()); + EXPECT_EQ(1000, retrieved->header_.get_timestamp()); // Test getting non-existent packet SrsRtpPacket *missing = cache.get_packet(200); @@ -501,8 +501,8 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheOverwrite) // Should get the second packet SrsRtpPacket *retrieved = cache.get_packet(100); EXPECT_TRUE(retrieved != NULL); - EXPECT_EQ(100, retrieved->header.get_sequence()); - EXPECT_EQ(2000, retrieved->header.get_timestamp()); + EXPECT_EQ(100, retrieved->header_.get_sequence()); + EXPECT_EQ(2000, retrieved->header_.get_timestamp()); } } @@ -527,8 +527,8 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheModuloIndexing) SrsRtpPacket *retrieved2 = cache.get_packet(100 + cache_size); EXPECT_TRUE(retrieved2 != NULL); - EXPECT_EQ(100 + cache_size, retrieved2->header.get_sequence()); - EXPECT_EQ(2000, retrieved2->header.get_timestamp()); + EXPECT_EQ(100 + cache_size, retrieved2->header_.get_sequence()); + EXPECT_EQ(2000, retrieved2->header_.get_timestamp()); } } @@ -545,7 +545,7 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheTakePacket) // Take the packet (should remove from cache) SrsRtpPacket *taken = cache.take_packet(100); EXPECT_TRUE(taken != NULL); - EXPECT_EQ(100, taken->header.get_sequence()); + EXPECT_EQ(100, taken->header_.get_sequence()); // Clean up the taken packet srs_freep(taken); @@ -957,11 +957,11 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheSequenceWrapAround) // Should be able to retrieve both packets SrsRtpPacket *retrieved1 = cache.get_packet(seq_near_max); EXPECT_TRUE(retrieved1 != NULL); - EXPECT_EQ(seq_near_max, retrieved1->header.get_sequence()); + EXPECT_EQ(seq_near_max, retrieved1->header_.get_sequence()); SrsRtpPacket *retrieved2 = cache.get_packet(seq_wrapped); EXPECT_TRUE(retrieved2 != NULL); - EXPECT_EQ(seq_wrapped, retrieved2->header.get_sequence()); + EXPECT_EQ(seq_wrapped, retrieved2->header_.get_sequence()); } } @@ -982,7 +982,7 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheMemoryManagement) // Verify the second packet is stored SrsRtpPacket *retrieved = cache.get_packet(100); EXPECT_TRUE(retrieved != NULL); - EXPECT_EQ(2000, retrieved->header.get_timestamp()); + EXPECT_EQ(2000, retrieved->header_.get_timestamp()); // Clear all should free remaining packets cache.clear_all(); diff --git a/trunk/src/utest/srs_utest_rtc3.cpp b/trunk/src/utest/srs_utest_rtc3.cpp index 44b366dc2..2408e74a9 100644 --- a/trunk/src/utest/srs_utest_rtc3.cpp +++ b/trunk/src/utest/srs_utest_rtc3.cpp @@ -18,12 +18,12 @@ SrsRtpPacket *mock_create_audio_rtp_packet(uint16_t sequence, uint32_t timestamp SrsRtpPacket *pkt = new SrsRtpPacket(); // Set RTP header - pkt->header.set_padding(false); - pkt->header.set_marker(false); - pkt->header.set_payload_type(111); // Audio payload type - pkt->header.set_sequence(sequence); - pkt->header.set_timestamp(timestamp); - pkt->header.set_ssrc(0x12345678); + pkt->header_.set_padding(false); + pkt->header_.set_marker(false); + pkt->header_.set_payload_type(111); // Audio payload type + pkt->header_.set_sequence(sequence); + pkt->header_.set_timestamp(timestamp); + pkt->header_.set_ssrc(0x12345678); // For audio cache testing, we don't need actual payload data or avsync time // The cache is only concerned with sequence numbers and system time for jitter buffer logic @@ -59,7 +59,7 @@ VOID TEST(RTC3AudioCacheTest, BasicPacketProcessing) // First packet should be processed immediately EXPECT_EQ(1, (int)ready_packets.size()); - EXPECT_EQ(100, ready_packets[0]->header.get_sequence()); + EXPECT_EQ(100, ready_packets[0]->header_.get_sequence()); free_audio_packets(ready_packets); @@ -69,7 +69,7 @@ VOID TEST(RTC3AudioCacheTest, BasicPacketProcessing) // Second packet should be processed immediately EXPECT_EQ(1, (int)ready_packets.size()); - EXPECT_EQ(101, ready_packets[0]->header.get_sequence()); + EXPECT_EQ(101, ready_packets[0]->header_.get_sequence()); free_audio_packets(ready_packets); } @@ -103,7 +103,7 @@ VOID TEST(RTC3AudioCacheTest, OutOfOrderPackets) // Should process packet 101 now EXPECT_EQ(1, (int)ready_packets.size()); - EXPECT_EQ(101, ready_packets[0]->header.get_sequence()); + EXPECT_EQ(101, ready_packets[0]->header_.get_sequence()); free_audio_packets(ready_packets); // Process packet 102 (completes sequence) @@ -112,8 +112,8 @@ VOID TEST(RTC3AudioCacheTest, OutOfOrderPackets) // Should process both 102 and 103 EXPECT_EQ(2, (int)ready_packets.size()); - EXPECT_EQ(102, ready_packets[0]->header.get_sequence()); - EXPECT_EQ(103, ready_packets[1]->header.get_sequence()); + EXPECT_EQ(102, ready_packets[0]->header_.get_sequence()); + EXPECT_EQ(103, ready_packets[1]->header_.get_sequence()); free_audio_packets(ready_packets); } @@ -133,7 +133,7 @@ VOID TEST(RTC3AudioCacheTest, LatePacketHandling) SrsUniquePtr pkt(mock_create_audio_rtp_packet(seq, 1000 + (seq - 100) * 20)); HELPER_EXPECT_SUCCESS(cache.process_packet(pkt.get(), ready_packets)); EXPECT_EQ(1, (int)ready_packets.size()); - EXPECT_EQ(seq, ready_packets[0]->header.get_sequence()); + EXPECT_EQ(seq, ready_packets[0]->header_.get_sequence()); free_audio_packets(ready_packets); } @@ -160,28 +160,28 @@ VOID TEST(RTC3AudioCacheTest, SequenceNumberWrapAround) SrsUniquePtr pkt1(mock_create_audio_rtp_packet(seq_near_max, 1000)); HELPER_EXPECT_SUCCESS(cache.process_packet(pkt1.get(), ready_packets)); EXPECT_EQ(1, (int)ready_packets.size()); - EXPECT_EQ(seq_near_max, ready_packets[0]->header.get_sequence()); + EXPECT_EQ(seq_near_max, ready_packets[0]->header_.get_sequence()); free_audio_packets(ready_packets); // Process packet 65535 SrsUniquePtr pkt2(mock_create_audio_rtp_packet(65535, 1020)); HELPER_EXPECT_SUCCESS(cache.process_packet(pkt2.get(), ready_packets)); EXPECT_EQ(1, (int)ready_packets.size()); - EXPECT_EQ(65535, ready_packets[0]->header.get_sequence()); + EXPECT_EQ(65535, ready_packets[0]->header_.get_sequence()); free_audio_packets(ready_packets); // Process packet 0 (after wrap-around) SrsUniquePtr pkt3(mock_create_audio_rtp_packet(0, 1040)); HELPER_EXPECT_SUCCESS(cache.process_packet(pkt3.get(), ready_packets)); EXPECT_EQ(1, (int)ready_packets.size()); - EXPECT_EQ(0, ready_packets[0]->header.get_sequence()); + EXPECT_EQ(0, ready_packets[0]->header_.get_sequence()); free_audio_packets(ready_packets); // Process packet 1 SrsUniquePtr pkt4(mock_create_audio_rtp_packet(1, 1060)); HELPER_EXPECT_SUCCESS(cache.process_packet(pkt4.get(), ready_packets)); EXPECT_EQ(1, (int)ready_packets.size()); - EXPECT_EQ(1, ready_packets[0]->header.get_sequence()); + EXPECT_EQ(1, ready_packets[0]->header_.get_sequence()); free_audio_packets(ready_packets); } } @@ -221,7 +221,7 @@ VOID TEST(RTC3AudioCacheTest, PacketLossWithTimeout) // Should process packet 103 despite missing 101, 102 due to timeout bool found_103 = false; for (size_t i = 0; i < ready_packets.size(); i++) { - if (ready_packets[i]->header.get_sequence() == 103) { + if (ready_packets[i]->header_.get_sequence() == 103) { found_103 = true; break; } @@ -322,8 +322,8 @@ VOID TEST(RTC3AudioCacheTest, DuplicatePacketHandling) // Should process 101 and one instance of 102 (duplicate should be handled) EXPECT_GE((int)ready_packets.size(), 2); - EXPECT_EQ(101, ready_packets[0]->header.get_sequence()); - EXPECT_EQ(102, ready_packets[1]->header.get_sequence()); + EXPECT_EQ(101, ready_packets[0]->header_.get_sequence()); + EXPECT_EQ(102, ready_packets[1]->header_.get_sequence()); free_audio_packets(ready_packets); } } diff --git a/trunk/src/utest/srs_utest_rtc_recv_track.cpp b/trunk/src/utest/srs_utest_rtc_recv_track.cpp index 1ee6c02aa..e18a3f07b 100644 --- a/trunk/src/utest/srs_utest_rtc_recv_track.cpp +++ b/trunk/src/utest/srs_utest_rtc_recv_track.cpp @@ -88,7 +88,7 @@ VOID TEST(RtcRecvTrackTest, OnNackBasicTest) // Create a test RTP packet SrsRtpPacket pkt; - pkt.header.set_sequence(100); + pkt.header_.set_sequence(100); SrsRtpPacket *ppkt = &pkt; @@ -98,7 +98,7 @@ VOID TEST(RtcRecvTrackTest, OnNackBasicTest) // Test case 2: NACK info exists (recovered packet) recv_track.receiver_insert(101, 102); SrsRtpPacket pkt2; - pkt2.header.set_sequence(101); + pkt2.header_.set_sequence(101); ppkt = &pkt2; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt)); } @@ -116,7 +116,7 @@ VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketTest) // Create recovered packet SrsRtpPacket pkt; - pkt.header.set_sequence(200); + pkt.header_.set_sequence(200); SrsRtpPacket *ppkt = &pkt; // Process the recovered packet @@ -128,7 +128,7 @@ VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketTest) // Verify the packet was added to RTP queue SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(200); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == 200); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == 200); } VOID TEST(RtcRecvTrackTest, OnNackSequentialPacketsTest) @@ -139,7 +139,7 @@ VOID TEST(RtcRecvTrackTest, OnNackSequentialPacketsTest) // Process sequential packets for (uint16_t seq = 300; seq < 305; seq++) { SrsRtpPacket pkt; - pkt.header.set_sequence(seq); + pkt.header_.set_sequence(seq); SrsRtpPacket *ppkt = &pkt; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt)); @@ -147,7 +147,7 @@ VOID TEST(RtcRecvTrackTest, OnNackSequentialPacketsTest) // Verify packet is in queue SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(seq); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == seq); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == seq); } } @@ -161,7 +161,7 @@ VOID TEST(RtcRecvTrackTest, OnNackOutOfOrderPacketsTest) for (int i = 0; i < 3; i++) { SrsRtpPacket pkt; - pkt.header.set_sequence(sequences[i]); + pkt.header_.set_sequence(sequences[i]); SrsRtpPacket *ppkt = &pkt; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt)); @@ -169,7 +169,7 @@ VOID TEST(RtcRecvTrackTest, OnNackOutOfOrderPacketsTest) // Verify packet is in queue SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(sequences[i]); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == sequences[i]); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == sequences[i]); } } @@ -183,7 +183,7 @@ VOID TEST(RtcRecvTrackTest, OnNackNoCopyModeTest) // Create a test RTP packet SrsRtpPacket *pkt = new SrsRtpPacket(); - pkt->header.set_sequence(500); + pkt->header_.set_sequence(500); SrsRtpPacket *ppkt = pkt; // Process packet in no-copy mode @@ -195,7 +195,7 @@ VOID TEST(RtcRecvTrackTest, OnNackNoCopyModeTest) // Verify packet is in queue (original packet, not a copy) SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(500); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == 500); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == 500); EXPECT_TRUE(queued_pkt == pkt); // Should be the same object } @@ -209,7 +209,7 @@ VOID TEST(RtcRecvTrackTest, OnNackCopyModeTest) // Create a test RTP packet SrsRtpPacket pkt; - pkt.header.set_sequence(600); + pkt.header_.set_sequence(600); SrsRtpPacket *ppkt = &pkt; // Process packet in copy mode @@ -221,7 +221,7 @@ VOID TEST(RtcRecvTrackTest, OnNackCopyModeTest) // Verify packet is in queue (should be a copy) SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(600); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == 600); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == 600); EXPECT_TRUE(queued_pkt != &pkt); // Should be a different object (copy) } @@ -235,7 +235,7 @@ VOID TEST(RtcRecvTrackTest, OnNackSequenceWrapAroundTest) for (int i = 0; i < 5; i++) { SrsRtpPacket pkt; - pkt.header.set_sequence(sequences[i]); + pkt.header_.set_sequence(sequences[i]); SrsRtpPacket *ppkt = &pkt; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt)); @@ -243,7 +243,7 @@ VOID TEST(RtcRecvTrackTest, OnNackSequenceWrapAroundTest) // Verify packet is in queue SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(sequences[i]); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == sequences[i]); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == sequences[i]); } } @@ -265,7 +265,7 @@ VOID TEST(RtcRecvTrackTest, OnNackMixedRecoveredAndNewPacketsTest) for (int i = 0; i < 4; i++) { SrsRtpPacket pkt; - pkt.header.set_sequence(sequences[i]); + pkt.header_.set_sequence(sequences[i]); SrsRtpPacket *ppkt = &pkt; // Check if packet is in NACK receiver before processing @@ -282,7 +282,7 @@ VOID TEST(RtcRecvTrackTest, OnNackMixedRecoveredAndNewPacketsTest) // Verify packet is in queue SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(sequences[i]); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == sequences[i]); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == sequences[i]); } } @@ -296,25 +296,25 @@ VOID TEST(RtcRecvTrackTest, OnNackDuplicatePacketTest) // First time processing SrsRtpPacket pkt1; - pkt1.header.set_sequence(seq); + pkt1.header_.set_sequence(seq); SrsRtpPacket *ppkt1 = &pkt1; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt1)); // Verify packet is in queue SrsRtpPacket *queued_pkt1 = recv_track.get_packet_from_queue(seq); EXPECT_TRUE(queued_pkt1 != NULL); - EXPECT_TRUE(queued_pkt1->header.get_sequence() == seq); + EXPECT_TRUE(queued_pkt1->header_.get_sequence() == seq); // Second time processing (duplicate) SrsRtpPacket pkt2; - pkt2.header.set_sequence(seq); + pkt2.header_.set_sequence(seq); SrsRtpPacket *ppkt2 = &pkt2; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt2)); // Verify the packet in queue is replaced (should be the new one) SrsRtpPacket *queued_pkt2 = recv_track.get_packet_from_queue(seq); EXPECT_TRUE(queued_pkt2 != NULL); - EXPECT_TRUE(queued_pkt2->header.get_sequence() == seq); + EXPECT_TRUE(queued_pkt2->header_.get_sequence() == seq); // In copy mode, it should be a different object EXPECT_TRUE(queued_pkt2 != queued_pkt1); } @@ -330,24 +330,24 @@ VOID TEST(RtcRecvTrackTest, OnNackLargeGapTest) // Process first packet SrsRtpPacket pkt1; - pkt1.header.set_sequence(seq1); + pkt1.header_.set_sequence(seq1); SrsRtpPacket *ppkt1 = &pkt1; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt1)); // Process second packet with large gap SrsRtpPacket pkt2; - pkt2.header.set_sequence(seq2); + pkt2.header_.set_sequence(seq2); SrsRtpPacket *ppkt2 = &pkt2; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt2)); // Verify both packets are in queue SrsRtpPacket *queued_pkt1 = recv_track.get_packet_from_queue(seq1); EXPECT_TRUE(queued_pkt1 != NULL); - EXPECT_TRUE(queued_pkt1->header.get_sequence() == seq1); + EXPECT_TRUE(queued_pkt1->header_.get_sequence() == seq1); SrsRtpPacket *queued_pkt2 = recv_track.get_packet_from_queue(seq2); EXPECT_TRUE(queued_pkt2 != NULL); - EXPECT_TRUE(queued_pkt2->header.get_sequence() == seq2); + EXPECT_TRUE(queued_pkt2->header_.get_sequence() == seq2); } VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketRemovedFromNackTest) @@ -367,7 +367,7 @@ VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketRemovedFromNackTest) uint16_t recovered_seqs[] = {1001, 1003}; for (int i = 0; i < 2; i++) { SrsRtpPacket pkt; - pkt.header.set_sequence(recovered_seqs[i]); + pkt.header_.set_sequence(recovered_seqs[i]); SrsRtpPacket *ppkt = &pkt; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt)); @@ -378,7 +378,7 @@ VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketRemovedFromNackTest) // Verify packet is in queue SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(recovered_seqs[i]); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == recovered_seqs[i]); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == recovered_seqs[i]); } // Verify non-recovered packets are still in NACK receiver @@ -405,7 +405,7 @@ VOID TEST(RtcRecvTrackTest, OnNackBugFixVerificationTest) // Step 2: Simulate packet recovery (retransmission arrives) SrsRtpPacket recovered_pkt; - recovered_pkt.header.set_sequence(lost_seq); + recovered_pkt.header_.set_sequence(lost_seq); SrsRtpPacket *ppkt = &recovered_pkt; // Step 3: Process the recovered packet @@ -417,7 +417,7 @@ VOID TEST(RtcRecvTrackTest, OnNackBugFixVerificationTest) // Step 5: Verify the fix - packet should be added to RTP queue (this was the bug) SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(lost_seq); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == lost_seq); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == lost_seq); // This test ensures that recovered packets are properly processed and not discarded } @@ -432,7 +432,7 @@ VOID TEST(RtcRecvTrackTest, OnNackControlFlowTest) // Scenario 1: New packet (not in NACK receiver) uint16_t new_seq = 1200; SrsRtpPacket new_pkt; - new_pkt.header.set_sequence(new_seq); + new_pkt.header_.set_sequence(new_seq); SrsRtpPacket *new_ppkt = &new_pkt; // Should not be in NACK receiver initially @@ -443,7 +443,7 @@ VOID TEST(RtcRecvTrackTest, OnNackControlFlowTest) // New packet should be added to queue SrsRtpPacket *new_queued = recv_track.get_packet_from_queue(new_seq); EXPECT_TRUE(new_queued != NULL); - EXPECT_TRUE(new_queued->header.get_sequence() == new_seq); + EXPECT_TRUE(new_queued->header_.get_sequence() == new_seq); // Scenario 2: Recovered packet (in NACK receiver) uint16_t recovered_seq = 1201; @@ -453,7 +453,7 @@ VOID TEST(RtcRecvTrackTest, OnNackControlFlowTest) EXPECT_TRUE(recv_track.receiver_find(recovered_seq) != NULL); SrsRtpPacket recovered_pkt; - recovered_pkt.header.set_sequence(recovered_seq); + recovered_pkt.header_.set_sequence(recovered_seq); SrsRtpPacket *recovered_ppkt = &recovered_pkt; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&recovered_ppkt)); @@ -464,7 +464,7 @@ VOID TEST(RtcRecvTrackTest, OnNackControlFlowTest) // Recovered packet should also be added to queue (the fix) SrsRtpPacket *recovered_queued = recv_track.get_packet_from_queue(recovered_seq); EXPECT_TRUE(recovered_queued != NULL); - EXPECT_TRUE(recovered_queued->header.get_sequence() == recovered_seq); + EXPECT_TRUE(recovered_queued->header_.get_sequence() == recovered_seq); } VOID TEST(RtcRecvTrackTest, OnNackStressTest) @@ -492,7 +492,7 @@ VOID TEST(RtcRecvTrackTest, OnNackStressTest) EXPECT_TRUE(is_in_nack == should_be_recovered); SrsRtpPacket pkt; - pkt.header.set_sequence(seq); + pkt.header_.set_sequence(seq); SrsRtpPacket *ppkt = &pkt; HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt)); @@ -503,6 +503,6 @@ VOID TEST(RtcRecvTrackTest, OnNackStressTest) // Verify packet is in queue (the key fix) SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(seq); EXPECT_TRUE(queued_pkt != NULL); - EXPECT_TRUE(queued_pkt->header.get_sequence() == seq); + EXPECT_TRUE(queued_pkt->header_.get_sequence() == seq); } }