AI: Add utest to manually verify rtc play workflow

This commit is contained in:
OSSRS-AI 2025-10-16 09:08:15 -04:00 committed by winlin
parent abaffdd4b9
commit ed120ba88b
13 changed files with 185 additions and 450 deletions

View File

@ -454,7 +454,6 @@ SrsRtcPlayStream::SrsRtcPlayStream(ISrsExecRtcAsyncTask *exec, ISrsExpire *expir
nack_enabled_ = false;
nack_no_copy_ = false;
_srs_config->subscribe(this);
nack_epp_ = new SrsErrorPithyPrint();
pli_worker_ = new SrsRtcPliWorker(this);
@ -473,8 +472,6 @@ SrsRtcPlayStream::~SrsRtcPlayStream()
exec_->exec_rtc_async_work(new SrsRtcAsyncCallOnStop(cid_, req_));
}
_srs_config->unsubscribe(this);
srs_freep(nack_epp_);
srs_freep(pli_worker_);
srs_freep(trd_);
@ -496,7 +493,9 @@ SrsRtcPlayStream::~SrsRtcPlayStream()
// update the statistic when client coveried.
// TODO: FIXME: Should finger out the err.
stat_->on_disconnect(cid_.c_str(), srs_success);
if (stat_) {
stat_->on_disconnect(cid_.c_str(), srs_success);
}
config_ = NULL;
rtc_sources_ = NULL;

View File

@ -254,7 +254,7 @@ public:
};
// A RTC play stream, client pull and play stream from SRS.
class SrsRtcPlayStream : public ISrsCoroutineHandler, public ISrsReloadHandler, public ISrsRtcPliWorkerHandler, public ISrsRtcSourceChangeCallback
class SrsRtcPlayStream : public ISrsCoroutineHandler, public ISrsRtcPliWorkerHandler, public ISrsRtcSourceChangeCallback
{
// clang-format off
SRS_DECLARE_PRIVATE: // clang-format on

View File

@ -1874,7 +1874,7 @@ VOID TEST(SrsUtilityTest, UpdateDiskStat)
SrsDiskStat first_sample = *srs_get_disk_stat();
// Wait a bit to ensure time difference
srs_usleep(100 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
// Call srs_update_disk_stat() again to calculate deltas
srs_update_disk_stat();

View File

@ -200,7 +200,7 @@ VOID TEST(UdpListenerTest, ListenAndReceivePacket)
}
// Wait a bit for the listener to receive and process the packet
srs_usleep(50 * SRS_UTIME_MILLISECONDS);
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
// Verify that the mock handler received the packet
EXPECT_TRUE(mock_handler->on_udp_packet_called_);

View File

@ -1412,7 +1412,7 @@ VOID TEST(AppCasterFlvTest, ResourceManagerDelegation)
// Verify subscription by checking that handler is notified when a resource is removed
caster->remove(resource2);
// Give time for async disposal (manager runs in coroutine)
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
// Handler should have been called (but we can't easily verify this without more complex setup)
// Test 14: unsubscribe() - should delegate to manager_->unsubscribe()
@ -1424,7 +1424,7 @@ VOID TEST(AppCasterFlvTest, ResourceManagerDelegation)
caster->remove(resource4);
// Give time for async disposal
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
// Clean up - set to NULL to avoid double-free
caster->config_ = NULL;

View File

@ -2381,6 +2381,7 @@ MockAppConfig::MockAppConfig()
api_as_candidates_ = true;
resolve_api_domain_ = true;
keep_api_domain_ = false;
mw_msgs_ = 8;
}
MockAppConfig::~MockAppConfig()
@ -2446,7 +2447,7 @@ bool MockAppConfig::get_realtime_enabled(std::string vhost, bool is_rtc)
int MockAppConfig::get_mw_msgs(std::string vhost, bool is_realtime, bool is_rtc)
{
return 8;
return mw_msgs_;
}
int MockAppConfig::get_rtc_drop_for_pt(std::string vhost)

View File

@ -326,6 +326,7 @@ public:
bool api_as_candidates_;
bool resolve_api_domain_;
bool keep_api_domain_;
int mw_msgs_;
public:
MockAppConfig();

View File

@ -2335,7 +2335,7 @@ VOID TEST(AppOriginHubTest, CreateForwardersTypicalScenario)
}
// Give coroutines time to stop
srs_usleep(10 * 1000); // 10ms
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
}
// Hub is destroyed here, before mock_config
@ -2881,7 +2881,7 @@ VOID TEST(AppOriginHubTest, CreateBackendForwardersTypicalScenario)
}
// Give coroutines time to stop
srs_usleep(10 * 1000); // 10ms
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
}
// Hub is destroyed here, before mock objects

View File

@ -7,354 +7,177 @@
#include <srs_utest_rtc_playstream.hpp>
#include <srs_app_rtc_conn.hpp>
#include <srs_app_rtc_source.hpp>
#include <srs_kernel_error.hpp>
#include <srs_utest_app.hpp>
#include <srs_utest_app6.hpp>
// Mock ISrsCoroutine implementation
MockCoroutineForPlayStream::MockCoroutineForPlayStream()
// MockRtcTrackDescriptionFactory implementation
MockRtcTrackDescriptionFactory::MockRtcTrackDescriptionFactory()
{
start_error_ = srs_success;
start_count_ = 0;
stop_count_ = 0;
interrupt_count_ = 0;
audio_ssrc_ = 12345;
video_ssrc_ = 67890;
}
MockCoroutineForPlayStream::~MockCoroutineForPlayStream()
MockRtcTrackDescriptionFactory::~MockRtcTrackDescriptionFactory()
{
srs_freep(start_error_);
}
srs_error_t MockCoroutineForPlayStream::start()
std::map<uint32_t, SrsRtcTrackDescription *> MockRtcTrackDescriptionFactory::create_audio_video_tracks()
{
start_count_++;
if (start_error_ != srs_success) {
return srs_error_copy(start_error_);
}
return srs_success;
std::map<uint32_t, SrsRtcTrackDescription *> sub_relations;
// Create audio track
SrsRtcTrackDescription *audio_desc = create_audio_track(audio_ssrc_, "audio-track-1");
sub_relations[audio_desc->ssrc_] = audio_desc;
// Create video track
SrsRtcTrackDescription *video_desc = create_video_track(video_ssrc_, "video-track-1");
sub_relations[video_desc->ssrc_] = video_desc;
return sub_relations;
}
void MockCoroutineForPlayStream::stop()
SrsRtcTrackDescription *MockRtcTrackDescriptionFactory::create_audio_track(uint32_t ssrc, std::string id)
{
stop_count_++;
SrsRtcTrackDescription *audio_desc = new SrsRtcTrackDescription();
audio_desc->type_ = "audio";
audio_desc->ssrc_ = ssrc;
audio_desc->id_ = id;
audio_desc->is_active_ = true;
audio_desc->direction_ = "sendrecv";
audio_desc->mid_ = "0";
audio_desc->media_ = new SrsAudioPayload(111, "opus", 48000, 2);
return audio_desc;
}
void MockCoroutineForPlayStream::interrupt()
SrsRtcTrackDescription *MockRtcTrackDescriptionFactory::create_video_track(uint32_t ssrc, std::string id)
{
interrupt_count_++;
}
srs_error_t MockCoroutineForPlayStream::pull()
{
return srs_success;
}
const SrsContextId &MockCoroutineForPlayStream::cid()
{
return cid_;
}
void MockCoroutineForPlayStream::set_cid(const SrsContextId &cid)
{
cid_ = cid;
}
void MockCoroutineForPlayStream::reset()
{
srs_freep(start_error_);
start_count_ = 0;
stop_count_ = 0;
interrupt_count_ = 0;
}
void MockCoroutineForPlayStream::set_start_error(srs_error_t err)
{
srs_freep(start_error_);
start_error_ = srs_error_copy(err);
}
// Mock ISrsAppFactory implementation
MockAppFactoryForPlayStream::MockAppFactoryForPlayStream()
{
mock_coroutine_ = new MockCoroutineForPlayStream();
create_coroutine_error_ = srs_success;
create_coroutine_count_ = 0;
last_coroutine_handler_ = NULL;
}
MockAppFactoryForPlayStream::~MockAppFactoryForPlayStream()
{
srs_freep(mock_coroutine_);
srs_freep(create_coroutine_error_);
}
ISrsFileWriter *MockAppFactoryForPlayStream::create_file_writer()
{
return NULL;
}
ISrsFileWriter *MockAppFactoryForPlayStream::create_enc_file_writer()
{
return NULL;
}
ISrsFileReader *MockAppFactoryForPlayStream::create_file_reader()
{
return NULL;
}
SrsPath *MockAppFactoryForPlayStream::create_path()
{
return NULL;
}
SrsLiveSource *MockAppFactoryForPlayStream::create_live_source()
{
return NULL;
}
ISrsOriginHub *MockAppFactoryForPlayStream::create_origin_hub()
{
return NULL;
}
ISrsHourGlass *MockAppFactoryForPlayStream::create_hourglass(const std::string &name, ISrsHourGlassHandler *handler, srs_utime_t interval)
{
return NULL;
}
ISrsBasicRtmpClient *MockAppFactoryForPlayStream::create_rtmp_client(std::string url, srs_utime_t cto, srs_utime_t sto)
{
return NULL;
}
ISrsHttpClient *MockAppFactoryForPlayStream::create_http_client()
{
return NULL;
}
ISrsFileReader *MockAppFactoryForPlayStream::create_http_file_reader(ISrsHttpResponseReader *r)
{
return NULL;
}
ISrsFlvDecoder *MockAppFactoryForPlayStream::create_flv_decoder()
{
return NULL;
}
#ifdef SRS_RTSP
ISrsRtspSendTrack *MockAppFactoryForPlayStream::create_rtsp_audio_send_track(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc)
{
return NULL;
}
ISrsRtspSendTrack *MockAppFactoryForPlayStream::create_rtsp_video_send_track(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc)
{
return NULL;
}
#endif
ISrsFlvTransmuxer *MockAppFactoryForPlayStream::create_flv_transmuxer()
{
return NULL;
}
ISrsMp4Encoder *MockAppFactoryForPlayStream::create_mp4_encoder()
{
return NULL;
}
ISrsDvrSegmenter *MockAppFactoryForPlayStream::create_dvr_flv_segmenter()
{
return NULL;
}
ISrsDvrSegmenter *MockAppFactoryForPlayStream::create_dvr_mp4_segmenter()
{
return NULL;
}
#ifdef SRS_GB28181
ISrsGbMediaTcpConn *MockAppFactoryForPlayStream::create_gb_media_tcp_conn()
{
return NULL;
}
ISrsGbSession *MockAppFactoryForPlayStream::create_gb_session()
{
return NULL;
}
#endif
ISrsInitMp4 *MockAppFactoryForPlayStream::create_init_mp4()
{
return NULL;
}
ISrsFragmentWindow *MockAppFactoryForPlayStream::create_fragment_window()
{
return NULL;
}
ISrsFragmentedMp4 *MockAppFactoryForPlayStream::create_fragmented_mp4()
{
return NULL;
}
ISrsIpListener *MockAppFactoryForPlayStream::create_tcp_listener(ISrsTcpHandler *handler)
{
return NULL;
}
ISrsRtcConnection *MockAppFactoryForPlayStream::create_rtc_connection(ISrsExecRtcAsyncTask *exec, const SrsContextId &cid)
{
return NULL;
}
ISrsFFMPEG *MockAppFactoryForPlayStream::create_ffmpeg(std::string ffmpeg_bin)
{
return NULL;
}
ISrsIngesterFFMPEG *MockAppFactoryForPlayStream::create_ingester_ffmpeg()
{
return NULL;
}
ISrsCoroutine *MockAppFactoryForPlayStream::create_coroutine(const std::string &name, ISrsCoroutineHandler *handler, SrsContextId cid)
{
create_coroutine_count_++;
last_coroutine_name_ = name;
last_coroutine_handler_ = handler;
last_coroutine_cid_ = cid;
if (create_coroutine_error_ != srs_success) {
return NULL;
}
return mock_coroutine_;
}
ISrsTime *MockAppFactoryForPlayStream::create_time()
{
return NULL;
}
ISrsConfig *MockAppFactoryForPlayStream::create_config()
{
return NULL;
}
ISrsCond *MockAppFactoryForPlayStream::create_cond()
{
return NULL;
}
void MockAppFactoryForPlayStream::reset()
{
mock_coroutine_->reset();
srs_freep(create_coroutine_error_);
create_coroutine_count_ = 0;
last_coroutine_name_ = "";
last_coroutine_handler_ = NULL;
}
void MockAppFactoryForPlayStream::set_create_coroutine_error(srs_error_t err)
{
srs_freep(create_coroutine_error_);
create_coroutine_error_ = srs_error_copy(err);
}
// Mock ISrsRtcPliWorker implementation
MockRtcPliWorkerForPlayStream::MockRtcPliWorkerForPlayStream()
{
start_error_ = srs_success;
start_count_ = 0;
request_keyframe_count_ = 0;
}
MockRtcPliWorkerForPlayStream::~MockRtcPliWorkerForPlayStream()
{
srs_freep(start_error_);
}
srs_error_t MockRtcPliWorkerForPlayStream::start()
{
start_count_++;
if (start_error_ != srs_success) {
return srs_error_copy(start_error_);
}
return srs_success;
}
void MockRtcPliWorkerForPlayStream::request_keyframe(uint32_t ssrc, SrsContextId cid)
{
request_keyframe_count_++;
}
srs_error_t MockRtcPliWorkerForPlayStream::cycle()
{
return srs_success;
}
void MockRtcPliWorkerForPlayStream::reset()
{
srs_freep(start_error_);
start_count_ = 0;
request_keyframe_count_ = 0;
}
void MockRtcPliWorkerForPlayStream::set_start_error(srs_error_t err)
{
srs_freep(start_error_);
start_error_ = srs_error_copy(err);
SrsRtcTrackDescription *video_desc = new SrsRtcTrackDescription();
video_desc->type_ = "video";
video_desc->ssrc_ = ssrc;
video_desc->id_ = id;
video_desc->is_active_ = true;
video_desc->direction_ = "sendrecv";
video_desc->mid_ = "1";
video_desc->media_ = new SrsVideoPayload(96, "H264", 90000);
return video_desc;
}
// Test SrsRtcPlayStream::start() - Basic success scenario
VOID TEST(RtcPlayStreamStartTest, StartSuccess)
VOID TEST(RtcPlayStreamTest, ManuallyVerifyBasicWorkflow)
{
srs_error_t err;
// Create mock objects
// Create mock objects for dependencies
MockAppConfig mock_config;
MockRtcSourceManager mock_rtc_sources;
MockRtcStatistic mock_stat;
MockRtcAsyncCallRequest mock_request("test.vhost", "live", "stream1");
MockRtcAsyncTaskExecutor mock_exec;
MockExpire mock_expire;
MockRtcPacketSender mock_sender;
MockRtcTrackDescriptionFactory track_factory;
SrsContextId cid;
cid.set_value("test-play-stream-start-cid");
// Create RTC play stream
// Create RTC play stream - uses real app_factory_ and real pli_worker_
SrsUniquePtr<SrsRtcPlayStream> play_stream(new SrsRtcPlayStream(&mock_exec, &mock_expire, &mock_sender, cid));
// Create and inject mock app factory
MockAppFactoryForPlayStream mock_factory;
play_stream->app_factory_ = &mock_factory;
// Mock the play stream object.
if (true) {
// Inject mock dependencies
play_stream->config_ = &mock_config;
play_stream->rtc_sources_ = &mock_rtc_sources;
play_stream->stat_ = &mock_stat;
// Create and inject mock PLI worker
MockRtcPliWorkerForPlayStream *mock_pli_worker = new MockRtcPliWorkerForPlayStream();
play_stream->pli_worker_ = mock_pli_worker;
// Set mw_msgs to 0 to make the consumer block until we push a packet
mock_config.mw_msgs_ = 0;
}
// Test: First call to start() should succeed
HELPER_EXPECT_SUCCESS(play_stream->start());
// Create track descriptions using factory
if (true) {
std::map<uint32_t, SrsRtcTrackDescription *> sub_relations = track_factory.create_audio_video_tracks();
// Verify coroutine was created with correct parameters
EXPECT_EQ(1, mock_factory.create_coroutine_count_);
EXPECT_STREQ("rtc_sender", mock_factory.last_coroutine_name_.c_str());
EXPECT_TRUE(mock_factory.last_coroutine_handler_ == play_stream.get());
EXPECT_EQ(0, cid.compare(mock_factory.last_coroutine_cid_));
// Initialize the play stream (it will take ownership of track descriptions)
HELPER_EXPECT_SUCCESS(play_stream->initialize(&mock_request, sub_relations));
// Verify coroutine start was called
EXPECT_EQ(1, mock_factory.mock_coroutine_->start_count_);
// Test: First call to start() should succeed
HELPER_EXPECT_SUCCESS(play_stream->start());
// Verify PLI worker start was called
EXPECT_EQ(1, mock_pli_worker->start_count_);
// Verify is_started_ flag is set
EXPECT_TRUE(play_stream->is_started_);
// Verify is_started_ flag is set
EXPECT_TRUE(play_stream->is_started_);
// Wait for coroutine to start and create consumer. Normally it should be ready
// and stopped at wait for RTP packets from consumer.
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
}
// Push a video packet to the source to feed the consumer.
if (true) {
SrsUniquePtr<SrsRtpPacket> test_pkt(new SrsRtpPacket());
test_pkt->frame_type_ = SrsFrameTypeVideo;
test_pkt->header_.set_sequence(1000);
test_pkt->header_.set_timestamp(5000);
test_pkt->header_.set_ssrc(track_factory.video_ssrc_);
// Push packet to source - this will feed all consumers including the play stream's consumer
HELPER_EXPECT_SUCCESS(play_stream->source_->on_rtp(test_pkt.get()));
}
// Verify the video packet is sent out
if (true) {
// Wait for coroutine to process the packet
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
// Check sender should have received the packet
EXPECT_EQ(mock_sender.send_packet_count_, 1);
// Check the tracks, should be a video track.
EXPECT_EQ(play_stream->video_tracks_.size(), 1);
// The packet should create a cached track for this ssrc.
EXPECT_EQ(play_stream->cache_ssrc0_, track_factory.video_ssrc_);
EXPECT_TRUE(play_stream->cache_track0_ != NULL);
// The packet should be in the nack ring buffer.
SrsRtpPacket *pkt = play_stream->cache_track0_->rtp_queue_->at(1000);
EXPECT_TRUE(pkt != NULL);
EXPECT_EQ(pkt->header_.get_ssrc(), track_factory.video_ssrc_);
}
// Push a audio packet to the source to feed the consumer.
if (true) {
SrsUniquePtr<SrsRtpPacket> test_pkt(new SrsRtpPacket());
test_pkt->frame_type_ = SrsFrameTypeAudio;
test_pkt->header_.set_sequence(1000);
test_pkt->header_.set_timestamp(5000);
test_pkt->header_.set_ssrc(track_factory.audio_ssrc_);
// Push packet to source - this will feed all consumers including the play stream's consumer
HELPER_EXPECT_SUCCESS(play_stream->source_->on_rtp(test_pkt.get()));
}
// Verify the audio packet is sent out
if (true) {
// Wait for coroutine to process the packet
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
// Check sender should have received the packet
EXPECT_EQ(mock_sender.send_packet_count_, 2);
// Check the tracks, should be a video track.
EXPECT_EQ(play_stream->audio_tracks_.size(), 1);
// The packet should create a cached track for this ssrc.
EXPECT_EQ(play_stream->cache_ssrc1_, track_factory.audio_ssrc_);
EXPECT_TRUE(play_stream->cache_track1_ != NULL);
// The packet should be in the nack ring buffer.
SrsRtpPacket *pkt = play_stream->cache_track1_->rtp_queue_->at(1000);
EXPECT_TRUE(pkt != NULL);
EXPECT_EQ(pkt->header_.get_ssrc(), track_factory.audio_ssrc_);
}
// Stop the play stream
play_stream->stop();
// Clean up - set to NULL to avoid double-free
play_stream->trd_ = NULL; // Set to NULL before mock_factory is destroyed
play_stream->app_factory_ = NULL;
play_stream->pli_worker_ = NULL;
srs_freep(mock_pli_worker);
play_stream->config_ = NULL;
play_stream->rtc_sources_ = NULL;
play_stream->stat_ = NULL;
}

View File

@ -7,121 +7,32 @@
#ifndef SRS_UTEST_RTC_PLAYSTREAM_HPP
#define SRS_UTEST_RTC_PLAYSTREAM_HPP
/*
#include <srs_utest_rtc_playstream.hpp>
*/
#include <srs_utest.hpp>
#include <map>
#include <srs_app_factory.hpp>
#include <srs_app_rtc_conn.hpp>
#include <srs_kernel_factory.hpp>
class SrsRtcTrackDescription;
// Mock ISrsCoroutine for testing SrsRtcPlayStream::start()
class MockCoroutineForPlayStream : public ISrsCoroutine
// Helper class to create mock track descriptions for testing
class MockRtcTrackDescriptionFactory
{
public:
srs_error_t start_error_;
int start_count_;
int stop_count_;
int interrupt_count_;
SrsContextId cid_;
MockRtcTrackDescriptionFactory();
virtual ~MockRtcTrackDescriptionFactory();
public:
MockCoroutineForPlayStream();
virtual ~MockCoroutineForPlayStream();
// Default SSRCs for audio and video tracks
uint32_t audio_ssrc_;
uint32_t video_ssrc_;
public:
virtual srs_error_t start();
virtual void stop();
virtual void interrupt();
virtual srs_error_t pull();
virtual const SrsContextId &cid();
virtual void set_cid(const SrsContextId &cid);
// Create a map of track descriptions with audio and video tracks
std::map<uint32_t, SrsRtcTrackDescription *> create_audio_video_tracks();
public:
void reset();
void set_start_error(srs_error_t err);
};
// Create a single audio track description
SrsRtcTrackDescription *create_audio_track(uint32_t ssrc, std::string id);
// Mock ISrsAppFactory for testing SrsRtcPlayStream::start()
class MockAppFactoryForPlayStream : public ISrsAppFactory
{
public:
MockCoroutineForPlayStream *mock_coroutine_;
srs_error_t create_coroutine_error_;
int create_coroutine_count_;
std::string last_coroutine_name_;
ISrsCoroutineHandler *last_coroutine_handler_;
SrsContextId last_coroutine_cid_;
public:
MockAppFactoryForPlayStream();
virtual ~MockAppFactoryForPlayStream();
public:
// ISrsAppFactory interface methods
virtual ISrsFileWriter *create_file_writer();
virtual ISrsFileWriter *create_enc_file_writer();
virtual ISrsFileReader *create_file_reader();
virtual SrsPath *create_path();
virtual SrsLiveSource *create_live_source();
virtual ISrsOriginHub *create_origin_hub();
virtual ISrsHourGlass *create_hourglass(const std::string &name, ISrsHourGlassHandler *handler, srs_utime_t interval);
virtual ISrsBasicRtmpClient *create_rtmp_client(std::string url, srs_utime_t cto, srs_utime_t sto);
virtual ISrsHttpClient *create_http_client();
virtual ISrsFileReader *create_http_file_reader(ISrsHttpResponseReader *r);
virtual ISrsFlvDecoder *create_flv_decoder();
#ifdef SRS_RTSP
virtual ISrsRtspSendTrack *create_rtsp_audio_send_track(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc);
virtual ISrsRtspSendTrack *create_rtsp_video_send_track(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc);
#endif
virtual ISrsFlvTransmuxer *create_flv_transmuxer();
virtual ISrsMp4Encoder *create_mp4_encoder();
virtual ISrsDvrSegmenter *create_dvr_flv_segmenter();
virtual ISrsDvrSegmenter *create_dvr_mp4_segmenter();
#ifdef SRS_GB28181
virtual ISrsGbMediaTcpConn *create_gb_media_tcp_conn();
virtual ISrsGbSession *create_gb_session();
#endif
virtual ISrsInitMp4 *create_init_mp4();
virtual ISrsFragmentWindow *create_fragment_window();
virtual ISrsFragmentedMp4 *create_fragmented_mp4();
virtual ISrsIpListener *create_tcp_listener(ISrsTcpHandler *handler);
virtual ISrsRtcConnection *create_rtc_connection(ISrsExecRtcAsyncTask *exec, const SrsContextId &cid);
virtual ISrsFFMPEG *create_ffmpeg(std::string ffmpeg_bin);
virtual ISrsIngesterFFMPEG *create_ingester_ffmpeg();
// ISrsKernelFactory interface methods
virtual ISrsCoroutine *create_coroutine(const std::string &name, ISrsCoroutineHandler *handler, SrsContextId cid);
virtual ISrsTime *create_time();
virtual ISrsConfig *create_config();
virtual ISrsCond *create_cond();
public:
void reset();
void set_create_coroutine_error(srs_error_t err);
};
// Mock ISrsRtcPliWorker for testing SrsRtcPlayStream::start()
class MockRtcPliWorkerForPlayStream : public ISrsRtcPliWorker
{
public:
srs_error_t start_error_;
int start_count_;
int request_keyframe_count_;
public:
MockRtcPliWorkerForPlayStream();
virtual ~MockRtcPliWorkerForPlayStream();
public:
virtual srs_error_t start();
virtual void request_keyframe(uint32_t ssrc, SrsContextId cid);
virtual srs_error_t cycle();
public:
void reset();
void set_start_error(srs_error_t err);
// Create a single video track description
SrsRtcTrackDescription *create_video_track(uint32_t ssrc, std::string id);
};
#endif

View File

@ -104,7 +104,7 @@ VOID TEST(TCPServerTest, PingPong)
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
EXPECT_TRUE(h.fd != NULL);
}
@ -117,7 +117,7 @@ VOID TEST(TCPServerTest, PingPong)
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
#ifdef SRS_OSX
ASSERT_TRUE(h.fd != NULL);
#endif
@ -139,7 +139,7 @@ VOID TEST(TCPServerTest, PingPong)
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
#ifdef SRS_OSX
ASSERT_TRUE(h.fd != NULL);
#endif
@ -163,7 +163,7 @@ VOID TEST(TCPServerTest, PingPong)
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
#ifdef SRS_OSX
ASSERT_TRUE(h.fd != NULL);
#endif
@ -198,7 +198,7 @@ VOID TEST(TCPServerTest, PingPongWithTimeout)
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
#ifdef SRS_OSX
ASSERT_TRUE(h.fd != NULL);
#endif
@ -220,7 +220,7 @@ VOID TEST(TCPServerTest, PingPongWithTimeout)
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
#ifdef SRS_OSX
ASSERT_TRUE(h.fd != NULL);
#endif
@ -242,7 +242,7 @@ VOID TEST(TCPServerTest, PingPongWithTimeout)
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
#ifdef SRS_OSX
ASSERT_TRUE(h.fd != NULL);
#endif
@ -437,7 +437,7 @@ VOID TEST(TCPServerTest, WritevIOVC)
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
#ifdef SRS_OSX
ASSERT_TRUE(h.fd != NULL);
#endif
@ -467,7 +467,7 @@ VOID TEST(TCPServerTest, WritevIOVC)
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
#ifdef SRS_OSX
ASSERT_TRUE(h.fd != NULL);
#endif
@ -1000,7 +1000,7 @@ srs_error_t MockOnCycleThread::cycle()
srs_error_t err = srs_success;
for (;;) {
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
srs_cond_signal(cond);
// If no one waiting on the cond, directly return event signal more than one time.
// If someone waiting, signal them more than one time.
@ -1029,7 +1029,7 @@ VOID TEST(TCPServerTest, ThreadCondWait)
MockOnCycleThread trd;
trd.trd.start();
srs_usleep(20 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
srs_cond_wait(trd.cond);
trd.trd.stop();
}
@ -1050,7 +1050,7 @@ srs_error_t MockOnCycleThread2::cycle()
for (;;) {
srs_mutex_lock(lock);
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
srs_mutex_unlock(lock);
srs_error_t err = trd.pull();
@ -1077,7 +1077,7 @@ VOID TEST(TCPServerTest, ThreadMutexWait)
MockOnCycleThread2 trd;
trd.trd.start();
srs_usleep(20 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
srs_mutex_lock(trd.lock);
trd.trd.stop();
@ -1579,7 +1579,7 @@ VOID TEST(ThreadCriticalTest, FailIfCloseActiveFD)
SrsTcpClient c0(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
HELPER_EXPECT_SUCCESS(c0.connect());
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
EXPECT_TRUE(h.fd != NULL);
MockAsyncReaderThread trd0(h.fd);
@ -1589,7 +1589,7 @@ VOID TEST(ThreadCriticalTest, FailIfCloseActiveFD)
HELPER_EXPECT_SUCCESS(trd1.start());
// Wait for all threads to run.
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
// Should fail when close, because there is 2 threads reading fd.
int r0 = st_netfd_close((st_netfd_t)h.fd);

View File

@ -26,7 +26,7 @@ VOID TEST(StTest, AnonymouseSingleCoroutine)
// Wait for coroutine to terminate. Otherwise, it will be stopped
// and terminated, which cause some of the code not executed.
srs_usleep(50 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
}
VOID TEST(StTest, AnonymouseMultipleCoroutines)
@ -42,7 +42,7 @@ VOID TEST(StTest, AnonymouseMultipleCoroutines)
// Wait for coroutine to terminate. Otherwise, it will be stopped
// and terminated, which cause some of the code not executed.
srs_usleep(50 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
}
VOID TEST(StTest, AnonymouseCoroutinePull)
@ -67,7 +67,7 @@ VOID TEST(StTest, AnonymouseCoroutinePull)
// Wait for coroutine to run and terminated, or it will crash
// because the ctx.pop is called after coroutine terminated.
srs_usleep(50 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
}
EXPECT_TRUE(counter == 1);
@ -90,12 +90,12 @@ VOID TEST(StTest, AnonymouseCoroutineWithContext)
// Wait for coroutine to run and terminated, or it will crash
// because the ctx.pop is called after coroutine terminated.
srs_usleep(50 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
EXPECT_TRUE(counter == 1);
// Wait for coroutine to terminate. Otherwise, it will be stopped
// and terminated, which cause some of the code not executed.
srs_usleep(50 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
}
VOID TEST(StTest, AnonymouseCoroutineWithSync)
@ -272,7 +272,7 @@ VOID TEST(StTest, AnonymouseBadcase2)
// Wait for coroutine to terminate. Otherwise, it will crash, for the
// coroutine is terminated while ctx.pop(), the lock is invalid.
srs_usleep(100 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
}
// Coroutine terminated, so the counter is increased.

View File

@ -414,7 +414,7 @@ VOID TEST(StreamTokenTest, RaceConditionPrevention)
}
// Wait a bit for completion
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
// Wait for all coroutines to complete
for (size_t i = 0; i < threads.size(); i++) {
@ -423,7 +423,7 @@ VOID TEST(StreamTokenTest, RaceConditionPrevention)
}
// Wait a bit for completion
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
// Check results - exactly one should succeed, others should fail
int success_count = 0;