AI: Add utest to manually verify rtc play workflow
This commit is contained in:
parent
abaffdd4b9
commit
ed120ba88b
|
|
@ -454,7 +454,6 @@ SrsRtcPlayStream::SrsRtcPlayStream(ISrsExecRtcAsyncTask *exec, ISrsExpire *expir
|
||||||
nack_enabled_ = false;
|
nack_enabled_ = false;
|
||||||
nack_no_copy_ = false;
|
nack_no_copy_ = false;
|
||||||
|
|
||||||
_srs_config->subscribe(this);
|
|
||||||
nack_epp_ = new SrsErrorPithyPrint();
|
nack_epp_ = new SrsErrorPithyPrint();
|
||||||
pli_worker_ = new SrsRtcPliWorker(this);
|
pli_worker_ = new SrsRtcPliWorker(this);
|
||||||
|
|
||||||
|
|
@ -473,8 +472,6 @@ SrsRtcPlayStream::~SrsRtcPlayStream()
|
||||||
exec_->exec_rtc_async_work(new SrsRtcAsyncCallOnStop(cid_, req_));
|
exec_->exec_rtc_async_work(new SrsRtcAsyncCallOnStop(cid_, req_));
|
||||||
}
|
}
|
||||||
|
|
||||||
_srs_config->unsubscribe(this);
|
|
||||||
|
|
||||||
srs_freep(nack_epp_);
|
srs_freep(nack_epp_);
|
||||||
srs_freep(pli_worker_);
|
srs_freep(pli_worker_);
|
||||||
srs_freep(trd_);
|
srs_freep(trd_);
|
||||||
|
|
@ -496,7 +493,9 @@ SrsRtcPlayStream::~SrsRtcPlayStream()
|
||||||
|
|
||||||
// update the statistic when client coveried.
|
// update the statistic when client coveried.
|
||||||
// TODO: FIXME: Should finger out the err.
|
// 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;
|
config_ = NULL;
|
||||||
rtc_sources_ = NULL;
|
rtc_sources_ = NULL;
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// A RTC play stream, client pull and play stream from SRS.
|
// 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
|
// clang-format off
|
||||||
SRS_DECLARE_PRIVATE: // clang-format on
|
SRS_DECLARE_PRIVATE: // clang-format on
|
||||||
|
|
|
||||||
|
|
@ -1874,7 +1874,7 @@ VOID TEST(SrsUtilityTest, UpdateDiskStat)
|
||||||
SrsDiskStat first_sample = *srs_get_disk_stat();
|
SrsDiskStat first_sample = *srs_get_disk_stat();
|
||||||
|
|
||||||
// Wait a bit to ensure time difference
|
// 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
|
// Call srs_update_disk_stat() again to calculate deltas
|
||||||
srs_update_disk_stat();
|
srs_update_disk_stat();
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ VOID TEST(UdpListenerTest, ListenAndReceivePacket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait a bit for the listener to receive and process the packet
|
// 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
|
// Verify that the mock handler received the packet
|
||||||
EXPECT_TRUE(mock_handler->on_udp_packet_called_);
|
EXPECT_TRUE(mock_handler->on_udp_packet_called_);
|
||||||
|
|
|
||||||
|
|
@ -1412,7 +1412,7 @@ VOID TEST(AppCasterFlvTest, ResourceManagerDelegation)
|
||||||
// Verify subscription by checking that handler is notified when a resource is removed
|
// Verify subscription by checking that handler is notified when a resource is removed
|
||||||
caster->remove(resource2);
|
caster->remove(resource2);
|
||||||
// Give time for async disposal (manager runs in coroutine)
|
// 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)
|
// Handler should have been called (but we can't easily verify this without more complex setup)
|
||||||
|
|
||||||
// Test 14: unsubscribe() - should delegate to manager_->unsubscribe()
|
// Test 14: unsubscribe() - should delegate to manager_->unsubscribe()
|
||||||
|
|
@ -1424,7 +1424,7 @@ VOID TEST(AppCasterFlvTest, ResourceManagerDelegation)
|
||||||
caster->remove(resource4);
|
caster->remove(resource4);
|
||||||
|
|
||||||
// Give time for async disposal
|
// 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
|
// Clean up - set to NULL to avoid double-free
|
||||||
caster->config_ = NULL;
|
caster->config_ = NULL;
|
||||||
|
|
|
||||||
|
|
@ -2381,6 +2381,7 @@ MockAppConfig::MockAppConfig()
|
||||||
api_as_candidates_ = true;
|
api_as_candidates_ = true;
|
||||||
resolve_api_domain_ = true;
|
resolve_api_domain_ = true;
|
||||||
keep_api_domain_ = false;
|
keep_api_domain_ = false;
|
||||||
|
mw_msgs_ = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
MockAppConfig::~MockAppConfig()
|
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)
|
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)
|
int MockAppConfig::get_rtc_drop_for_pt(std::string vhost)
|
||||||
|
|
|
||||||
|
|
@ -326,6 +326,7 @@ public:
|
||||||
bool api_as_candidates_;
|
bool api_as_candidates_;
|
||||||
bool resolve_api_domain_;
|
bool resolve_api_domain_;
|
||||||
bool keep_api_domain_;
|
bool keep_api_domain_;
|
||||||
|
int mw_msgs_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MockAppConfig();
|
MockAppConfig();
|
||||||
|
|
|
||||||
|
|
@ -2335,7 +2335,7 @@ VOID TEST(AppOriginHubTest, CreateForwardersTypicalScenario)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give coroutines time to stop
|
// Give coroutines time to stop
|
||||||
srs_usleep(10 * 1000); // 10ms
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
}
|
}
|
||||||
// Hub is destroyed here, before mock_config
|
// Hub is destroyed here, before mock_config
|
||||||
|
|
||||||
|
|
@ -2881,7 +2881,7 @@ VOID TEST(AppOriginHubTest, CreateBackendForwardersTypicalScenario)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give coroutines time to stop
|
// Give coroutines time to stop
|
||||||
srs_usleep(10 * 1000); // 10ms
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
}
|
}
|
||||||
// Hub is destroyed here, before mock objects
|
// Hub is destroyed here, before mock objects
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,354 +7,177 @@
|
||||||
#include <srs_utest_rtc_playstream.hpp>
|
#include <srs_utest_rtc_playstream.hpp>
|
||||||
|
|
||||||
#include <srs_app_rtc_conn.hpp>
|
#include <srs_app_rtc_conn.hpp>
|
||||||
|
#include <srs_app_rtc_source.hpp>
|
||||||
#include <srs_kernel_error.hpp>
|
#include <srs_kernel_error.hpp>
|
||||||
#include <srs_utest_app.hpp>
|
#include <srs_utest_app.hpp>
|
||||||
#include <srs_utest_app6.hpp>
|
#include <srs_utest_app6.hpp>
|
||||||
|
|
||||||
// Mock ISrsCoroutine implementation
|
// MockRtcTrackDescriptionFactory implementation
|
||||||
MockCoroutineForPlayStream::MockCoroutineForPlayStream()
|
MockRtcTrackDescriptionFactory::MockRtcTrackDescriptionFactory()
|
||||||
{
|
{
|
||||||
start_error_ = srs_success;
|
audio_ssrc_ = 12345;
|
||||||
start_count_ = 0;
|
video_ssrc_ = 67890;
|
||||||
stop_count_ = 0;
|
|
||||||
interrupt_count_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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_++;
|
std::map<uint32_t, SrsRtcTrackDescription *> sub_relations;
|
||||||
if (start_error_ != srs_success) {
|
|
||||||
return srs_error_copy(start_error_);
|
// Create audio track
|
||||||
}
|
SrsRtcTrackDescription *audio_desc = create_audio_track(audio_ssrc_, "audio-track-1");
|
||||||
return srs_success;
|
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_++;
|
SrsRtcTrackDescription *video_desc = new SrsRtcTrackDescription();
|
||||||
}
|
video_desc->type_ = "video";
|
||||||
|
video_desc->ssrc_ = ssrc;
|
||||||
srs_error_t MockCoroutineForPlayStream::pull()
|
video_desc->id_ = id;
|
||||||
{
|
video_desc->is_active_ = true;
|
||||||
return srs_success;
|
video_desc->direction_ = "sendrecv";
|
||||||
}
|
video_desc->mid_ = "1";
|
||||||
|
video_desc->media_ = new SrsVideoPayload(96, "H264", 90000);
|
||||||
const SrsContextId &MockCoroutineForPlayStream::cid()
|
return video_desc;
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test SrsRtcPlayStream::start() - Basic success scenario
|
// Test SrsRtcPlayStream::start() - Basic success scenario
|
||||||
VOID TEST(RtcPlayStreamStartTest, StartSuccess)
|
VOID TEST(RtcPlayStreamTest, ManuallyVerifyBasicWorkflow)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
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;
|
MockRtcAsyncTaskExecutor mock_exec;
|
||||||
MockExpire mock_expire;
|
MockExpire mock_expire;
|
||||||
MockRtcPacketSender mock_sender;
|
MockRtcPacketSender mock_sender;
|
||||||
|
MockRtcTrackDescriptionFactory track_factory;
|
||||||
SrsContextId cid;
|
SrsContextId cid;
|
||||||
cid.set_value("test-play-stream-start-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));
|
SrsUniquePtr<SrsRtcPlayStream> play_stream(new SrsRtcPlayStream(&mock_exec, &mock_expire, &mock_sender, cid));
|
||||||
|
|
||||||
// Create and inject mock app factory
|
// Mock the play stream object.
|
||||||
MockAppFactoryForPlayStream mock_factory;
|
if (true) {
|
||||||
play_stream->app_factory_ = &mock_factory;
|
// 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
|
// Set mw_msgs to 0 to make the consumer block until we push a packet
|
||||||
MockRtcPliWorkerForPlayStream *mock_pli_worker = new MockRtcPliWorkerForPlayStream();
|
mock_config.mw_msgs_ = 0;
|
||||||
play_stream->pli_worker_ = mock_pli_worker;
|
}
|
||||||
|
|
||||||
// Test: First call to start() should succeed
|
// Create track descriptions using factory
|
||||||
HELPER_EXPECT_SUCCESS(play_stream->start());
|
if (true) {
|
||||||
|
std::map<uint32_t, SrsRtcTrackDescription *> sub_relations = track_factory.create_audio_video_tracks();
|
||||||
|
|
||||||
// Verify coroutine was created with correct parameters
|
// Initialize the play stream (it will take ownership of track descriptions)
|
||||||
EXPECT_EQ(1, mock_factory.create_coroutine_count_);
|
HELPER_EXPECT_SUCCESS(play_stream->initialize(&mock_request, sub_relations));
|
||||||
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_));
|
|
||||||
|
|
||||||
// Verify coroutine start was called
|
// Test: First call to start() should succeed
|
||||||
EXPECT_EQ(1, mock_factory.mock_coroutine_->start_count_);
|
HELPER_EXPECT_SUCCESS(play_stream->start());
|
||||||
|
|
||||||
// Verify PLI worker start was called
|
// Verify is_started_ flag is set
|
||||||
EXPECT_EQ(1, mock_pli_worker->start_count_);
|
EXPECT_TRUE(play_stream->is_started_);
|
||||||
|
|
||||||
// Verify is_started_ flag is set
|
// Wait for coroutine to start and create consumer. Normally it should be ready
|
||||||
EXPECT_TRUE(play_stream->is_started_);
|
// 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
|
// Clean up - set to NULL to avoid double-free
|
||||||
play_stream->trd_ = NULL; // Set to NULL before mock_factory is destroyed
|
play_stream->config_ = NULL;
|
||||||
play_stream->app_factory_ = NULL;
|
play_stream->rtc_sources_ = NULL;
|
||||||
play_stream->pli_worker_ = NULL;
|
play_stream->stat_ = NULL;
|
||||||
srs_freep(mock_pli_worker);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,121 +7,32 @@
|
||||||
#ifndef SRS_UTEST_RTC_PLAYSTREAM_HPP
|
#ifndef SRS_UTEST_RTC_PLAYSTREAM_HPP
|
||||||
#define SRS_UTEST_RTC_PLAYSTREAM_HPP
|
#define SRS_UTEST_RTC_PLAYSTREAM_HPP
|
||||||
|
|
||||||
/*
|
|
||||||
#include <srs_utest_rtc_playstream.hpp>
|
|
||||||
*/
|
|
||||||
#include <srs_utest.hpp>
|
#include <srs_utest.hpp>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <srs_app_factory.hpp>
|
class SrsRtcTrackDescription;
|
||||||
#include <srs_app_rtc_conn.hpp>
|
|
||||||
#include <srs_kernel_factory.hpp>
|
|
||||||
|
|
||||||
// Mock ISrsCoroutine for testing SrsRtcPlayStream::start()
|
// Helper class to create mock track descriptions for testing
|
||||||
class MockCoroutineForPlayStream : public ISrsCoroutine
|
class MockRtcTrackDescriptionFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
srs_error_t start_error_;
|
MockRtcTrackDescriptionFactory();
|
||||||
int start_count_;
|
virtual ~MockRtcTrackDescriptionFactory();
|
||||||
int stop_count_;
|
|
||||||
int interrupt_count_;
|
|
||||||
SrsContextId cid_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MockCoroutineForPlayStream();
|
// Default SSRCs for audio and video tracks
|
||||||
virtual ~MockCoroutineForPlayStream();
|
uint32_t audio_ssrc_;
|
||||||
|
uint32_t video_ssrc_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual srs_error_t start();
|
// Create a map of track descriptions with audio and video tracks
|
||||||
virtual void stop();
|
std::map<uint32_t, SrsRtcTrackDescription *> create_audio_video_tracks();
|
||||||
virtual void interrupt();
|
|
||||||
virtual srs_error_t pull();
|
|
||||||
virtual const SrsContextId &cid();
|
|
||||||
virtual void set_cid(const SrsContextId &cid);
|
|
||||||
|
|
||||||
public:
|
// Create a single audio track description
|
||||||
void reset();
|
SrsRtcTrackDescription *create_audio_track(uint32_t ssrc, std::string id);
|
||||||
void set_start_error(srs_error_t err);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mock ISrsAppFactory for testing SrsRtcPlayStream::start()
|
// Create a single video track description
|
||||||
class MockAppFactoryForPlayStream : public ISrsAppFactory
|
SrsRtcTrackDescription *create_video_track(uint32_t ssrc, std::string id);
|
||||||
{
|
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ VOID TEST(TCPServerTest, PingPong)
|
||||||
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c.connect());
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
EXPECT_TRUE(h.fd != NULL);
|
EXPECT_TRUE(h.fd != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +117,7 @@ VOID TEST(TCPServerTest, PingPong)
|
||||||
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c.connect());
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
#ifdef SRS_OSX
|
#ifdef SRS_OSX
|
||||||
ASSERT_TRUE(h.fd != NULL);
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -139,7 +139,7 @@ VOID TEST(TCPServerTest, PingPong)
|
||||||
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c.connect());
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
#ifdef SRS_OSX
|
#ifdef SRS_OSX
|
||||||
ASSERT_TRUE(h.fd != NULL);
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -163,7 +163,7 @@ VOID TEST(TCPServerTest, PingPong)
|
||||||
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c.connect());
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
#ifdef SRS_OSX
|
#ifdef SRS_OSX
|
||||||
ASSERT_TRUE(h.fd != NULL);
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -198,7 +198,7 @@ VOID TEST(TCPServerTest, PingPongWithTimeout)
|
||||||
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c.connect());
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
#ifdef SRS_OSX
|
#ifdef SRS_OSX
|
||||||
ASSERT_TRUE(h.fd != NULL);
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -220,7 +220,7 @@ VOID TEST(TCPServerTest, PingPongWithTimeout)
|
||||||
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c.connect());
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
#ifdef SRS_OSX
|
#ifdef SRS_OSX
|
||||||
ASSERT_TRUE(h.fd != NULL);
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -242,7 +242,7 @@ VOID TEST(TCPServerTest, PingPongWithTimeout)
|
||||||
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c.connect());
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
#ifdef SRS_OSX
|
#ifdef SRS_OSX
|
||||||
ASSERT_TRUE(h.fd != NULL);
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -437,7 +437,7 @@ VOID TEST(TCPServerTest, WritevIOVC)
|
||||||
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c.connect());
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
#ifdef SRS_OSX
|
#ifdef SRS_OSX
|
||||||
ASSERT_TRUE(h.fd != NULL);
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -467,7 +467,7 @@ VOID TEST(TCPServerTest, WritevIOVC)
|
||||||
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c.connect());
|
HELPER_EXPECT_SUCCESS(c.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
#ifdef SRS_OSX
|
#ifdef SRS_OSX
|
||||||
ASSERT_TRUE(h.fd != NULL);
|
ASSERT_TRUE(h.fd != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1000,7 +1000,7 @@ srs_error_t MockOnCycleThread::cycle()
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
srs_cond_signal(cond);
|
srs_cond_signal(cond);
|
||||||
// If no one waiting on the cond, directly return event signal more than one time.
|
// If no one waiting on the cond, directly return event signal more than one time.
|
||||||
// If someone waiting, signal them more than one time.
|
// If someone waiting, signal them more than one time.
|
||||||
|
|
@ -1029,7 +1029,7 @@ VOID TEST(TCPServerTest, ThreadCondWait)
|
||||||
MockOnCycleThread trd;
|
MockOnCycleThread trd;
|
||||||
trd.trd.start();
|
trd.trd.start();
|
||||||
|
|
||||||
srs_usleep(20 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
srs_cond_wait(trd.cond);
|
srs_cond_wait(trd.cond);
|
||||||
trd.trd.stop();
|
trd.trd.stop();
|
||||||
}
|
}
|
||||||
|
|
@ -1050,7 +1050,7 @@ srs_error_t MockOnCycleThread2::cycle()
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
srs_mutex_lock(lock);
|
srs_mutex_lock(lock);
|
||||||
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
srs_mutex_unlock(lock);
|
srs_mutex_unlock(lock);
|
||||||
|
|
||||||
srs_error_t err = trd.pull();
|
srs_error_t err = trd.pull();
|
||||||
|
|
@ -1077,7 +1077,7 @@ VOID TEST(TCPServerTest, ThreadMutexWait)
|
||||||
MockOnCycleThread2 trd;
|
MockOnCycleThread2 trd;
|
||||||
trd.trd.start();
|
trd.trd.start();
|
||||||
|
|
||||||
srs_usleep(20 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
|
|
||||||
srs_mutex_lock(trd.lock);
|
srs_mutex_lock(trd.lock);
|
||||||
trd.trd.stop();
|
trd.trd.stop();
|
||||||
|
|
@ -1579,7 +1579,7 @@ VOID TEST(ThreadCriticalTest, FailIfCloseActiveFD)
|
||||||
SrsTcpClient c0(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
SrsTcpClient c0(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||||
HELPER_EXPECT_SUCCESS(c0.connect());
|
HELPER_EXPECT_SUCCESS(c0.connect());
|
||||||
|
|
||||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
EXPECT_TRUE(h.fd != NULL);
|
EXPECT_TRUE(h.fd != NULL);
|
||||||
|
|
||||||
MockAsyncReaderThread trd0(h.fd);
|
MockAsyncReaderThread trd0(h.fd);
|
||||||
|
|
@ -1589,7 +1589,7 @@ VOID TEST(ThreadCriticalTest, FailIfCloseActiveFD)
|
||||||
HELPER_EXPECT_SUCCESS(trd1.start());
|
HELPER_EXPECT_SUCCESS(trd1.start());
|
||||||
|
|
||||||
// Wait for all threads to run.
|
// 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.
|
// Should fail when close, because there is 2 threads reading fd.
|
||||||
int r0 = st_netfd_close((st_netfd_t)h.fd);
|
int r0 = st_netfd_close((st_netfd_t)h.fd);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ VOID TEST(StTest, AnonymouseSingleCoroutine)
|
||||||
|
|
||||||
// Wait for coroutine to terminate. Otherwise, it will be stopped
|
// Wait for coroutine to terminate. Otherwise, it will be stopped
|
||||||
// and terminated, which cause some of the code not executed.
|
// 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)
|
VOID TEST(StTest, AnonymouseMultipleCoroutines)
|
||||||
|
|
@ -42,7 +42,7 @@ VOID TEST(StTest, AnonymouseMultipleCoroutines)
|
||||||
|
|
||||||
// Wait for coroutine to terminate. Otherwise, it will be stopped
|
// Wait for coroutine to terminate. Otherwise, it will be stopped
|
||||||
// and terminated, which cause some of the code not executed.
|
// 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)
|
VOID TEST(StTest, AnonymouseCoroutinePull)
|
||||||
|
|
@ -67,7 +67,7 @@ VOID TEST(StTest, AnonymouseCoroutinePull)
|
||||||
|
|
||||||
// Wait for coroutine to run and terminated, or it will crash
|
// Wait for coroutine to run and terminated, or it will crash
|
||||||
// because the ctx.pop is called after coroutine terminated.
|
// 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);
|
EXPECT_TRUE(counter == 1);
|
||||||
|
|
@ -90,12 +90,12 @@ VOID TEST(StTest, AnonymouseCoroutineWithContext)
|
||||||
|
|
||||||
// Wait for coroutine to run and terminated, or it will crash
|
// Wait for coroutine to run and terminated, or it will crash
|
||||||
// because the ctx.pop is called after coroutine terminated.
|
// 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);
|
EXPECT_TRUE(counter == 1);
|
||||||
|
|
||||||
// Wait for coroutine to terminate. Otherwise, it will be stopped
|
// Wait for coroutine to terminate. Otherwise, it will be stopped
|
||||||
// and terminated, which cause some of the code not executed.
|
// 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)
|
VOID TEST(StTest, AnonymouseCoroutineWithSync)
|
||||||
|
|
@ -272,7 +272,7 @@ VOID TEST(StTest, AnonymouseBadcase2)
|
||||||
|
|
||||||
// Wait for coroutine to terminate. Otherwise, it will crash, for the
|
// Wait for coroutine to terminate. Otherwise, it will crash, for the
|
||||||
// coroutine is terminated while ctx.pop(), the lock is invalid.
|
// 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.
|
// Coroutine terminated, so the counter is increased.
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,7 @@ VOID TEST(StreamTokenTest, RaceConditionPrevention)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait a bit for completion
|
// Wait a bit for completion
|
||||||
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
|
srs_usleep(1 * SRS_UTIME_MILLISECONDS);
|
||||||
|
|
||||||
// Wait for all coroutines to complete
|
// Wait for all coroutines to complete
|
||||||
for (size_t i = 0; i < threads.size(); i++) {
|
for (size_t i = 0; i < threads.size(); i++) {
|
||||||
|
|
@ -423,7 +423,7 @@ VOID TEST(StreamTokenTest, RaceConditionPrevention)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait a bit for completion
|
// 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
|
// Check results - exactly one should succeed, others should fail
|
||||||
int success_count = 0;
|
int success_count = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user