AI: Improve coverage of app module.

This commit is contained in:
OSSRS-AI 2025-09-21 09:09:39 -04:00 committed by winlin
parent 10c0b66c0f
commit a1dd73545a
22 changed files with 10367 additions and 1084 deletions

2
trunk/configure vendored
View File

@ -382,7 +382,7 @@ if [[ $SRS_UTEST == YES ]]; then
"srs_utest_st" "srs_utest_rtc2" "srs_utest_rtc3" "srs_utest_fmp4" "srs_utest_source_lock"
"srs_utest_stream_token" "srs_utest_rtc_recv_track" "srs_utest_st2" "srs_utest_hevc_structs"
"srs_utest_coworkers" "srs_utest_pithy_print" "srs_utest_kernel3" "srs_utest_protocol4"
"srs_utest_protocol3" "srs_utest_app3")
"srs_utest_protocol3" "srs_utest_app3" "srs_utest_app4")
# Always include SRT utest
MODULE_FILES+=("srs_utest_srt")
if [[ $SRS_GB28181 == YES ]]; then

View File

@ -86,6 +86,14 @@ public:
// Register FFmpeg log callback funciton.
SrsFFmpegLogHelper _srs_ffmpeg_log_helper;
ISrsAudioTranscoder::ISrsAudioTranscoder()
{
}
ISrsAudioTranscoder::~ISrsAudioTranscoder()
{
}
SrsAudioTranscoder::SrsAudioTranscoder()
{
dec_ = NULL;

View File

@ -31,7 +31,32 @@ extern "C" {
}
#endif
class SrsAudioTranscoder
// The interface for audio transcoder.
class ISrsAudioTranscoder
{
public:
ISrsAudioTranscoder();
virtual ~ISrsAudioTranscoder();
public:
// Initialize the transcoder, transcode from codec as to codec.
// The channels specifies the number of output channels for encoder, for example, 2.
// The sample_rate specifies the sample rate of encoder, for example, 48000.
// The bit_rate specifies the bitrate of encoder, for example, 48000.
virtual srs_error_t initialize(SrsAudioCodecId from, SrsAudioCodecId to, int channels, int sample_rate, int bit_rate) = 0;
// Transcode the input audio frame in, as output audio frames outs.
virtual srs_error_t transcode(SrsParsedAudioPacket *in, std::vector<SrsParsedAudioPacket *> &outs) = 0;
// Free the generated audio frames by transcode.
virtual void free_frames(std::vector<SrsParsedAudioPacket *> &frames) = 0;
public:
// Get the aac codec header, for example, FLV sequence header.
// @remark User should never free the data, it's managed by this transcoder.
virtual void aac_codec_header(uint8_t **data, int *len) = 0;
};
// The audio transcoder, transcode audio from one codec to another.
class SrsAudioTranscoder : public ISrsAudioTranscoder
{
private:
AVCodecContext *dec_;

View File

@ -28,7 +28,7 @@ class SrsMediaPacket;
class SrsRtmpCommonMessage;
class SrsMessageArray;
class SrsRtcSource;
class SrsAudioTranscoder;
class ISrsAudioTranscoder;
class SrsRtpPacket;
class SrsNaluSample;
class SrsRtcSourceDescription;
@ -345,7 +345,7 @@ private:
private:
SrsAudioCodecId latest_codec_;
SrsAudioTranscoder *codec_;
ISrsAudioTranscoder *codec_;
bool keep_bframe_;
bool keep_avc_nalu_sei_;
bool merge_nalus_;
@ -495,7 +495,7 @@ private:
private:
bool is_first_audio_;
SrsAudioTranscoder *audio_transcoder_;
ISrsAudioTranscoder *audio_transcoder_;
SrsVideoCodecId video_codec_;
private:

File diff suppressed because it is too large Load Diff

View File

@ -12,4 +12,181 @@
*/
#include <srs_utest.hpp>
#include <srs_app_circuit_breaker.hpp>
#include <srs_app_rtc_source.hpp>
#include <srs_app_stream_bridge.hpp>
#include <srs_protocol_rtmp_stack.hpp>
// Mock implementation of ISrsRtcSourceForConsumer for testing SrsRtcConsumer
class MockRtcSourceForConsumer : public ISrsRtcSourceForConsumer
{
public:
SrsContextId source_id_;
SrsContextId pre_source_id_;
int consumer_destroy_count_;
bool can_publish_;
bool is_created_;
public:
MockRtcSourceForConsumer();
virtual ~MockRtcSourceForConsumer();
virtual SrsContextId get_id();
virtual SrsContextId get_pre_source_id();
virtual void on_consumer_destroy(ISrsRtcConsumer *consumer);
virtual bool can_publish();
virtual bool is_created();
virtual SrsContextId source_id();
virtual SrsContextId pre_source_id();
};
// Mock implementation of ISrsRtcSourceChangeCallback for testing
class MockRtcSourceChangeCallback : public ISrsRtcSourceChangeCallback
{
public:
int stream_change_count_;
SrsRtcSourceDescription *last_stream_desc_;
public:
MockRtcSourceChangeCallback();
virtual ~MockRtcSourceChangeCallback();
virtual void on_stream_change(SrsRtcSourceDescription *desc);
};
// Mock implementation of ISrsRtcConsumer for testing SrsRtcSource
class MockRtcConsumer : public ISrsRtcConsumer
{
public:
int update_source_id_count_;
int stream_change_count_;
int enqueue_count_;
SrsRtcSourceDescription *last_stream_desc_;
SrsContextId source_id_;
SrsContextId consumer_id_;
bool should_update_source_id_;
srs_error_t enqueue_error_;
public:
MockRtcConsumer();
virtual ~MockRtcConsumer();
virtual SrsContextId get_id();
virtual void update_source_id();
virtual void on_stream_change(SrsRtcSourceDescription *desc);
virtual srs_error_t enqueue(SrsRtpPacket *pkt);
void set_enqueue_error(srs_error_t err);
};
// Mock implementation of ISrsRtcSourceEventHandler for testing
class MockRtcSourceEventHandler : public ISrsRtcSourceEventHandler
{
public:
int on_unpublish_count_;
int on_consumers_finished_count_;
public:
MockRtcSourceEventHandler();
virtual ~MockRtcSourceEventHandler();
virtual void on_unpublish();
virtual void on_consumers_finished();
};
// Mock implementation of ISrsRtcPublishStream for testing
class MockRtcPublishStream : public ISrsRtcPublishStream
{
public:
int request_keyframe_count_;
uint32_t last_keyframe_ssrc_;
SrsContextId last_keyframe_cid_;
SrsContextId context_id_;
public:
MockRtcPublishStream();
virtual ~MockRtcPublishStream();
virtual void request_keyframe(uint32_t ssrc, SrsContextId cid);
virtual const SrsContextId &context_id();
void set_context_id(const SrsContextId &cid);
};
// Mock implementation of ISrsCircuitBreaker for testing
class MockCircuitBreaker : public ISrsCircuitBreaker
{
public:
bool hybrid_high_water_level_;
bool hybrid_critical_water_level_;
bool hybrid_dying_water_level_;
public:
MockCircuitBreaker();
virtual ~MockCircuitBreaker();
virtual srs_error_t initialize();
virtual bool hybrid_high_water_level();
virtual bool hybrid_critical_water_level();
virtual bool hybrid_dying_water_level();
void set_hybrid_dying_water_level(bool dying);
};
// Mock implementation of ISrsRequest that can simulate copy() failure
class MockFailingRequest : public ISrsRequest
{
public:
bool should_fail_copy_;
std::string stream_url_;
public:
MockFailingRequest();
MockFailingRequest(const std::string &stream_url, bool should_fail_copy = false);
virtual ~MockFailingRequest();
virtual ISrsRequest *copy();
virtual void update_auth(ISrsRequest *req);
virtual std::string get_stream_url();
virtual void strip();
virtual ISrsRequest *as_http();
void set_should_fail_copy(bool should_fail);
};
// Mock implementation of SrsRtcSource that can simulate initialize() failure
class MockFailingRtcSource : public SrsRtcSource
{
public:
bool should_fail_initialize_;
srs_error_t initialize_error_;
public:
MockFailingRtcSource();
virtual ~MockFailingRtcSource();
virtual srs_error_t initialize(ISrsRequest *req);
void set_initialize_error(srs_error_t err);
};
// Mock implementation of ISrsRtcBridge for testing
class MockRtcBridge : public ISrsRtcBridge
{
public:
int initialize_count_;
int setup_codec_count_;
int on_publish_count_;
int on_unpublish_count_;
int on_rtp_count_;
srs_error_t initialize_error_;
srs_error_t setup_codec_error_;
srs_error_t on_publish_error_;
srs_error_t on_rtp_error_;
ISrsRequest *last_initialize_req_;
SrsAudioCodecId last_audio_codec_;
SrsVideoCodecId last_video_codec_;
SrsRtpPacket *last_rtp_packet_;
public:
MockRtcBridge();
virtual ~MockRtcBridge();
virtual srs_error_t initialize(ISrsRequest *req);
virtual srs_error_t setup_codec(SrsAudioCodecId acodec, SrsVideoCodecId vcodec);
virtual srs_error_t on_publish();
virtual void on_unpublish();
virtual srs_error_t on_rtp(SrsRtpPacket *pkt);
void set_initialize_error(srs_error_t err);
void set_setup_codec_error(srs_error_t err);
void set_on_publish_error(srs_error_t err);
void set_on_rtp_error(srs_error_t err);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -12,4 +12,89 @@
*/
#include <srs_utest.hpp>
#include <srs_app_rtmp_source.hpp>
#include <srs_app_stream_bridge.hpp>
#include <srs_kernel_rtc_rtp.hpp>
#include <srs_protocol_format.hpp>
#include <srs_protocol_rtmp_stack.hpp>
#include <srs_utest_app4.hpp>
// Forward declarations
class SrsMediaPacket;
class SrsRtpPacket;
class SrsSrtPacket;
// Mock request class for testing stream bridges
class MockStreamBridgeRequest : public ISrsRequest
{
public:
MockStreamBridgeRequest(std::string vhost = "__defaultVhost__", std::string app = "live", std::string stream = "test");
virtual ~MockStreamBridgeRequest();
virtual ISrsRequest *copy();
virtual std::string get_stream_url();
virtual void update_auth(ISrsRequest *req);
virtual void strip();
virtual ISrsRequest *as_http();
};
// Mock frame target for testing bridges
class MockFrameTarget : public ISrsFrameTarget
{
public:
int on_frame_count_;
SrsMediaPacket *last_frame_;
srs_error_t frame_error_;
public:
MockFrameTarget();
virtual ~MockFrameTarget();
virtual srs_error_t on_frame(SrsMediaPacket *frame);
void set_frame_error(srs_error_t err);
};
// Mock RTP target for testing bridges
class MockRtpTarget : public ISrsRtpTarget
{
public:
int on_rtp_count_;
SrsRtpPacket *last_rtp_;
srs_error_t rtp_error_;
public:
MockRtpTarget();
virtual ~MockRtpTarget();
virtual srs_error_t on_rtp(SrsRtpPacket *pkt);
void set_rtp_error(srs_error_t err);
};
// Mock SRT target for testing bridges
class MockSrtTarget : public ISrsSrtTarget
{
public:
int on_packet_count_;
SrsSrtPacket *last_packet_;
srs_error_t packet_error_;
public:
MockSrtTarget();
virtual ~MockSrtTarget();
virtual srs_error_t on_packet(SrsSrtPacket *pkt);
void set_packet_error(srs_error_t err);
};
// Mock live source handler for testing
class MockLiveSourceHandler : public ISrsLiveSourceHandler
{
public:
int on_publish_count_;
int on_unpublish_count_;
public:
MockLiveSourceHandler();
virtual ~MockLiveSourceHandler();
virtual srs_error_t on_publish(ISrsRequest *r);
virtual void on_unpublish(ISrsRequest *r);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
//
// Copyright (c) 2013-2025 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#ifndef SRS_UTEST_APP4_HPP
#define SRS_UTEST_APP4_HPP
/*
#include <srs_utest_app4.hpp>
*/
#include <srs_utest.hpp>
#include <srs_app_rtc_source.hpp>
#include <srs_kernel_rtc_rtp.hpp>
#include <srs_protocol_format.hpp>
#include <srs_protocol_rtmp_stack.hpp>
#include <srs_protocol_amf0.hpp>
#include <srs_app_rtc_codec.hpp>
// Forward declarations
class SrsMediaPacket;
class SrsRtpPacket;
// Mock frame target for testing SrsRtcFrameBuilder
class MockRtcFrameTarget : public ISrsFrameTarget
{
public:
int on_frame_count_;
SrsMediaPacket *last_frame_;
srs_error_t frame_error_;
public:
MockRtcFrameTarget();
virtual ~MockRtcFrameTarget();
virtual srs_error_t on_frame(SrsMediaPacket *frame);
void reset();
};
// Mock audio transcoder for testing SrsRtcFrameBuilder::transcode_audio
class MockAudioTranscoder : public ISrsAudioTranscoder
{
public:
// Control behavior
srs_error_t transcode_error_;
std::vector<SrsParsedAudioPacket *> output_packets_;
bool should_output_packets_;
uint8_t *aac_header_data_;
int aac_header_len_;
public:
MockAudioTranscoder();
virtual ~MockAudioTranscoder();
public:
// ISrsAudioTranscoder interface
virtual srs_error_t initialize(SrsAudioCodecId from, SrsAudioCodecId to, int channels, int sample_rate, int bit_rate);
virtual srs_error_t transcode(SrsParsedAudioPacket *in, std::vector<SrsParsedAudioPacket *> &outs);
virtual void free_frames(std::vector<SrsParsedAudioPacket *> &frames);
virtual void aac_codec_header(uint8_t **data, int *len);
public:
// Test helpers
void reset();
void set_output_packets(int count, const char *sample_data = NULL, int sample_size = 64);
void set_transcode_error(srs_error_t err);
};
// Mock request class for testing - implement ISrsRequest interface
class MockRtcRequest : public ISrsRequest
{
public:
MockRtcRequest(std::string vhost = "__defaultVhost__", std::string app = "live", std::string stream = "test");
virtual ~MockRtcRequest();
virtual ISrsRequest *copy();
virtual std::string get_stream_url();
virtual void update_auth(ISrsRequest *req);
virtual void strip();
virtual ISrsRequest *as_http();
};
#endif

View File

@ -18,80 +18,77 @@ using namespace std;
// Use the config from srs_utest_config.hpp
// Mock request class for testing
class MockSrsRequest : public ISrsRequest
MockSrsRequest::MockSrsRequest(std::string vhost, std::string app, std::string stream, std::string host, int port)
{
public:
MockSrsRequest(string vhost, string app, string stream, string host = "127.0.0.1", int port = 1935)
{
// Initialize base class fields
vhost_ = vhost;
app_ = app;
stream_ = stream;
host_ = host;
port_ = port;
// Initialize base class fields
vhost_ = vhost;
app_ = app;
stream_ = stream;
host_ = host;
port_ = port;
// Build URL
tcUrl_ = "rtmp://" + host + "/" + app;
schema_ = "rtmp";
param_ = "";
duration_ = 0;
args_ = NULL;
protocol_ = "rtmp";
objectEncoding_ = 0;
// Build URL
tcUrl_ = "rtmp://" + host + "/" + app;
schema_ = "rtmp";
param_ = "";
duration_ = 0;
args_ = NULL;
protocol_ = "rtmp";
objectEncoding_ = 0;
}
MockSrsRequest::~MockSrsRequest()
{
}
ISrsRequest *MockSrsRequest::copy()
{
MockSrsRequest *req = new MockSrsRequest(vhost_, app_, stream_, host_, port_);
req->tcUrl_ = tcUrl_;
req->pageUrl_ = pageUrl_;
req->swfUrl_ = swfUrl_;
req->objectEncoding_ = objectEncoding_;
req->schema_ = schema_;
req->param_ = param_;
req->ice_ufrag_ = ice_ufrag_;
req->ice_pwd_ = ice_pwd_;
req->duration_ = duration_;
req->protocol_ = protocol_;
req->ip_ = ip_;
return req;
}
std::string MockSrsRequest::get_stream_url()
{
// Use the same format as srs_net_url_encode_sid()
if (vhost_ == "__defaultVhost__" || vhost_.empty()) {
return "/" + app_ + "/" + stream_;
} else {
return vhost_ + "/" + app_ + "/" + stream_;
}
}
virtual ~MockSrsRequest() {}
virtual ISrsRequest *copy()
{
MockSrsRequest *req = new MockSrsRequest(vhost_, app_, stream_, host_, port_);
req->tcUrl_ = tcUrl_;
req->pageUrl_ = pageUrl_;
req->swfUrl_ = swfUrl_;
req->objectEncoding_ = objectEncoding_;
req->schema_ = schema_;
req->param_ = param_;
req->ice_ufrag_ = ice_ufrag_;
req->ice_pwd_ = ice_pwd_;
req->duration_ = duration_;
req->protocol_ = protocol_;
req->ip_ = ip_;
return req;
void MockSrsRequest::update_auth(ISrsRequest *req)
{
// Copy auth related fields from req
if (req) {
pageUrl_ = req->pageUrl_;
swfUrl_ = req->swfUrl_;
tcUrl_ = req->tcUrl_;
}
}
virtual string get_stream_url()
{
// Use the same format as srs_net_url_encode_sid()
if (vhost_ == "__defaultVhost__" || vhost_.empty()) {
return "/" + app_ + "/" + stream_;
} else {
return vhost_ + "/" + app_ + "/" + stream_;
}
}
void MockSrsRequest::strip()
{
// Remove sensitive information
pageUrl_ = "";
swfUrl_ = "";
}
virtual void update_auth(ISrsRequest *req)
{
// Copy auth related fields from req
if (req) {
pageUrl_ = req->pageUrl_;
swfUrl_ = req->swfUrl_;
tcUrl_ = req->tcUrl_;
}
}
virtual void strip()
{
// Remove sensitive information
pageUrl_ = "";
swfUrl_ = "";
}
virtual ISrsRequest *as_http()
{
return NULL;
}
};
ISrsRequest *MockSrsRequest::as_http()
{
return NULL;
}
VOID TEST(CoWorkersTest, Singleton)
{

View File

@ -9,4 +9,19 @@
#include <srs_utest.hpp>
#include <srs_protocol_rtmp_stack.hpp>
// Mock request class for testing
class MockSrsRequest : public ISrsRequest
{
public:
MockSrsRequest(std::string vhost, std::string app, std::string stream, std::string host = "127.0.0.1", int port = 1935);
virtual ~MockSrsRequest();
virtual ISrsRequest *copy();
virtual std::string get_stream_url();
virtual void update_auth(ISrsRequest *req);
virtual void strip();
virtual ISrsRequest *as_http();
};
#endif

View File

@ -18,62 +18,59 @@ using namespace std;
#include <srs_protocol_rtmp_stack.hpp>
#include <srs_utest_kernel.hpp>
// Mock classes for testing
class MockSrsRequest : public SrsRequest
// Mock class implementations
MockFmp4SrsRequest::MockFmp4SrsRequest()
{
public:
MockSrsRequest()
{
vhost_ = "__defaultVhost__";
app_ = "live";
stream_ = "livestream";
}
virtual ~MockSrsRequest() {}
};
vhost_ = "__defaultVhost__";
app_ = "live";
stream_ = "livestream";
}
class MockSrsFormat : public SrsFormat
MockFmp4SrsRequest::~MockFmp4SrsRequest()
{
public:
MockSrsFormat()
{
initialize();
}
// Setup video sequence header (H.264 AVC)
uint8_t video_raw[] = {
0x17,
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
on_video(0, (char *)video_raw, sizeof(video_raw));
// Setup audio sequence header (AAC)
uint8_t audio_raw[] = {
0xaf, 0x00, 0x12, 0x10};
on_audio(0, (char *)audio_raw, sizeof(audio_raw));
}
virtual ~MockSrsFormat() {}
};
class MockSrsMediaPacket : public SrsMediaPacket
MockSrsFormat::MockSrsFormat()
{
public:
MockSrsMediaPacket(bool is_video_msg, uint32_t ts)
{
timestamp_ = ts;
initialize();
// Create sample payload
char *payload = new char[1024];
memset(payload, 0x00, 1024);
SrsMediaPacket::wrap(payload, 1024);
// Setup video sequence header (H.264 AVC)
uint8_t video_raw[] = {
0x17,
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
on_video(0, (char *)video_raw, sizeof(video_raw));
if (is_video_msg) {
message_type_ = SrsFrameTypeVideo;
} else {
message_type_ = SrsFrameTypeAudio;
}
// Setup audio sequence header (AAC)
uint8_t audio_raw[] = {
0xaf, 0x00, 0x12, 0x10};
on_audio(0, (char *)audio_raw, sizeof(audio_raw));
}
MockSrsFormat::~MockSrsFormat()
{
}
MockSrsMediaPacket::MockSrsMediaPacket(bool is_video_msg, uint32_t ts)
{
timestamp_ = ts;
// Create sample payload
char *payload = new char[1024];
memset(payload, 0x00, 1024);
SrsMediaPacket::wrap(payload, 1024);
if (is_video_msg) {
message_type_ = SrsFrameTypeVideo;
} else {
message_type_ = SrsFrameTypeAudio;
}
virtual ~MockSrsMediaPacket() {}
};
}
MockSrsMediaPacket::~MockSrsMediaPacket()
{
}
VOID TEST(Fmp4Test, SrsInitMp4Segment_VideoOnly)
{
@ -297,7 +294,7 @@ VOID TEST(Fmp4Test, SrsHlsFmp4Muxer_WriteInitMp4)
SrsHlsFmp4Muxer muxer;
HELPER_ASSERT_SUCCESS(muxer.initialize(1, 2));
MockSrsRequest req;
MockFmp4SrsRequest req;
HELPER_ASSERT_SUCCESS(muxer.on_publish(&req));
HELPER_ASSERT_SUCCESS(muxer.update_config(&req));
@ -321,7 +318,7 @@ VOID TEST(Fmp4Test, SrsHlsFmp4Muxer_WriteMedia)
SrsHlsFmp4Muxer muxer;
HELPER_ASSERT_SUCCESS(muxer.initialize(1, 2));
MockSrsRequest req;
MockFmp4SrsRequest req;
HELPER_ASSERT_SUCCESS(muxer.on_publish(&req));
HELPER_ASSERT_SUCCESS(muxer.update_config(&req));
@ -380,7 +377,7 @@ VOID TEST(Fmp4Test, SrsHlsMp4Controller_PublishWorkflow)
HELPER_ASSERT_SUCCESS(controller.initialize());
// Publish stream
MockSrsRequest req;
MockFmp4SrsRequest req;
HELPER_ASSERT_SUCCESS(controller.on_publish(&req));
// Handle sequence headers
@ -716,7 +713,7 @@ VOID TEST(Fmp4Test, Configuration_TrackIdManagement)
EXPECT_FALSE(controller.has_audio_sh_);
// Set request first
MockSrsRequest req;
MockFmp4SrsRequest req;
HELPER_ASSERT_SUCCESS(controller.on_publish(&req));
MockSrsFormat fmt;
@ -744,7 +741,7 @@ VOID TEST(Fmp4Test, Configuration_SequenceHeaderValidation)
HELPER_EXPECT_FAILED(controller.on_sequence_header(&video_sh, &fmt));
// Set request and try again
MockSrsRequest req;
MockFmp4SrsRequest req;
HELPER_ASSERT_SUCCESS(controller.on_publish(&req));
HELPER_ASSERT_SUCCESS(controller.on_sequence_header(&video_sh, &fmt));
@ -758,7 +755,7 @@ VOID TEST(Fmp4Test, CodecDetection_AudioCodecUpdate)
SrsHlsMp4Controller controller;
HELPER_ASSERT_SUCCESS(controller.initialize());
MockSrsRequest req;
MockFmp4SrsRequest req;
HELPER_ASSERT_SUCCESS(controller.on_publish(&req));
// Create mock format with AAC audio codec
@ -797,7 +794,7 @@ VOID TEST(Fmp4Test, CodecDetection_VideoCodecUpdate)
SrsHlsMp4Controller controller;
HELPER_ASSERT_SUCCESS(controller.initialize());
MockSrsRequest req;
MockFmp4SrsRequest req;
HELPER_ASSERT_SUCCESS(controller.on_publish(&req));
// Create mock format with H.264 video codec
@ -836,7 +833,7 @@ VOID TEST(Fmp4Test, Performance_MultipleSegments)
SrsHlsFmp4Muxer muxer;
HELPER_ASSERT_SUCCESS(muxer.initialize(1, 2));
MockSrsRequest req;
MockFmp4SrsRequest req;
HELPER_ASSERT_SUCCESS(muxer.on_publish(&req));
HELPER_ASSERT_SUCCESS(muxer.update_config(&req));
@ -870,7 +867,7 @@ VOID TEST(Fmp4Test, Compatibility_SequenceHeaderIgnore)
SrsHlsMp4Controller controller;
HELPER_ASSERT_SUCCESS(controller.initialize());
MockSrsRequest req;
MockFmp4SrsRequest req;
HELPER_ASSERT_SUCCESS(controller.on_publish(&req));
MockSrsFormat fmt;

View File

@ -12,4 +12,29 @@
*/
#include <srs_utest.hpp>
#include <srs_kernel_codec.hpp>
#include <srs_protocol_rtmp_stack.hpp>
// Mock classes for testing
class MockFmp4SrsRequest : public SrsRequest
{
public:
MockFmp4SrsRequest();
virtual ~MockFmp4SrsRequest();
};
class MockSrsFormat : public SrsFormat
{
public:
MockSrsFormat();
virtual ~MockSrsFormat();
};
class MockSrsMediaPacket : public SrsMediaPacket
{
public:
MockSrsMediaPacket(bool is_video_msg, uint32_t ts);
virtual ~MockSrsMediaPacket();
};
#endif

View File

@ -40,120 +40,115 @@ extern void asan_report_callback(const char *str);
extern bool srs_rtp_packet_h264_is_keyframe(uint8_t nalu_type, ISrsRtpPayloader *payload);
extern bool srs_rtp_packet_h265_is_keyframe(uint8_t nalu_type, ISrsRtpPayloader *payload);
// Mock classes for IO testing
class MockSrsReader : public ISrsReader
MockSrsReader::MockSrsReader(const std::string &data) : data_(data), pos_(0), read_error_(srs_success)
{
public:
std::string data_;
size_t pos_;
srs_error_t read_error_;
}
public:
MockSrsReader(const std::string &data) : data_(data), pos_(0), read_error_(srs_success) {}
virtual ~MockSrsReader() {}
public:
virtual srs_error_t read(void *buf, size_t size, ssize_t *nread)
{
if (read_error_ != srs_success) {
return srs_error_copy(read_error_);
}
size_t available = data_.size() - pos_;
size_t to_read = std::min(size, available);
if (to_read > 0) {
memcpy(buf, data_.data() + pos_, to_read);
pos_ += to_read;
}
if (nread)
*nread = to_read;
return srs_success;
}
void set_error(srs_error_t err) { read_error_ = err; }
};
class MockSrsWriter : public ISrsWriter
MockSrsReader::~MockSrsReader()
{
public:
std::string written_data_;
srs_error_t write_error_;
}
public:
MockSrsWriter() : write_error_(srs_success) {}
virtual ~MockSrsWriter() {}
public:
virtual srs_error_t write(void *buf, size_t size, ssize_t *nwrite)
{
if (write_error_ != srs_success) {
return srs_error_copy(write_error_);
}
written_data_.append((char *)buf, size);
if (nwrite)
*nwrite = size;
return srs_success;
}
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t *nwrite)
{
if (write_error_ != srs_success) {
return srs_error_copy(write_error_);
}
ssize_t total = 0;
for (int i = 0; i < iov_size; i++) {
written_data_.append((char *)iov[i].iov_base, iov[i].iov_len);
total += iov[i].iov_len;
}
if (nwrite)
*nwrite = total;
return srs_success;
}
void set_error(srs_error_t err) { write_error_ = err; }
};
class MockSrsSeeker : public ISrsSeeker
srs_error_t MockSrsReader::read(void *buf, size_t size, ssize_t *nread)
{
public:
off_t position_;
srs_error_t seek_error_;
public:
MockSrsSeeker() : position_(0), seek_error_(srs_success) {}
virtual ~MockSrsSeeker() {}
public:
virtual srs_error_t lseek(off_t offset, int whence, off_t *seeked)
{
if (seek_error_ != srs_success) {
return srs_error_copy(seek_error_);
}
switch (whence) {
case SEEK_SET:
position_ = offset;
break;
case SEEK_CUR:
position_ += offset;
break;
case SEEK_END:
position_ = 1000 + offset; // Mock file size of 1000
break;
}
if (seeked)
*seeked = position_;
return srs_success;
if (read_error_ != srs_success) {
return srs_error_copy(read_error_);
}
void set_error(srs_error_t err) { seek_error_ = err; }
};
size_t available = data_.size() - pos_;
size_t to_read = std::min(size, available);
if (to_read > 0) {
memcpy(buf, data_.data() + pos_, to_read);
pos_ += to_read;
}
if (nread)
*nread = to_read;
return srs_success;
}
void MockSrsReader::set_error(srs_error_t err)
{
read_error_ = err;
}
MockSrsWriter::MockSrsWriter() : write_error_(srs_success)
{
}
MockSrsWriter::~MockSrsWriter()
{
}
srs_error_t MockSrsWriter::write(void *buf, size_t size, ssize_t *nwrite)
{
if (write_error_ != srs_success) {
return srs_error_copy(write_error_);
}
written_data_.append((char *)buf, size);
if (nwrite)
*nwrite = size;
return srs_success;
}
srs_error_t MockSrsWriter::writev(const iovec *iov, int iov_size, ssize_t *nwrite)
{
if (write_error_ != srs_success) {
return srs_error_copy(write_error_);
}
ssize_t total = 0;
for (int i = 0; i < iov_size; i++) {
written_data_.append((char *)iov[i].iov_base, iov[i].iov_len);
total += iov[i].iov_len;
}
if (nwrite)
*nwrite = total;
return srs_success;
}
void MockSrsWriter::set_error(srs_error_t err)
{
write_error_ = err;
}
MockSrsSeeker::MockSrsSeeker() : position_(0), seek_error_(srs_success)
{
}
MockSrsSeeker::~MockSrsSeeker()
{
}
srs_error_t MockSrsSeeker::lseek(off_t offset, int whence, off_t *seeked)
{
if (seek_error_ != srs_success) {
return srs_error_copy(seek_error_);
}
switch (whence) {
case SEEK_SET:
position_ = offset;
break;
case SEEK_CUR:
position_ += offset;
break;
case SEEK_END:
position_ = 1000 + offset; // Mock file size of 1000
break;
}
if (seeked)
*seeked = position_;
return srs_success;
}
void MockSrsSeeker::set_error(srs_error_t err)
{
seek_error_ = err;
}
// Tests for srs_kernel_io.hpp
VOID TEST(KernelIOTest, ISrsReaderInterface)
@ -348,48 +343,52 @@ VOID TEST(KernelPacketTest, SrsMediaPacketTypeChecking)
EXPECT_FALSE(packet.is_video());
}
// Mock classes for resource testing
class MockSrsResource : public ISrsResource
MockSrsResource::MockSrsResource()
{
public:
SrsContextId cid_;
std::string desc_;
desc_ = "mock resource";
}
public:
MockSrsResource()
{
desc_ = "mock resource";
}
virtual ~MockSrsResource() {}
public:
virtual const SrsContextId &get_id() { return cid_; }
virtual std::string desc() { return desc_; }
void set_id(const SrsContextId &cid) { cid_ = cid; }
void set_desc(const std::string &desc) { desc_ = desc; }
};
class MockSrsDisposingHandler : public ISrsDisposingHandler
MockSrsResource::~MockSrsResource()
{
public:
std::vector<ISrsResource *> before_dispose_calls_;
std::vector<ISrsResource *> disposing_calls_;
}
public:
MockSrsDisposingHandler() {}
virtual ~MockSrsDisposingHandler() {}
const SrsContextId &MockSrsResource::get_id()
{
return cid_;
}
public:
virtual void on_before_dispose(ISrsResource *c)
{
before_dispose_calls_.push_back(c);
}
virtual void on_disposing(ISrsResource *c)
{
disposing_calls_.push_back(c);
}
};
std::string MockSrsResource::desc()
{
return desc_;
}
void MockSrsResource::set_id(const SrsContextId &cid)
{
cid_ = cid;
}
void MockSrsResource::set_desc(const std::string &desc)
{
desc_ = desc;
}
MockSrsDisposingHandler::MockSrsDisposingHandler()
{
}
MockSrsDisposingHandler::~MockSrsDisposingHandler()
{
}
void MockSrsDisposingHandler::on_before_dispose(ISrsResource *c)
{
before_dispose_calls_.push_back(c);
}
void MockSrsDisposingHandler::on_disposing(ISrsResource *c)
{
disposing_calls_.push_back(c);
}
// Tests for srs_kernel_resource.hpp
VOID TEST(KernelResourceTest, ISrsResourceInterface)
@ -433,56 +432,47 @@ VOID TEST(KernelResourceTest, SrsSharedResourceBasic)
EXPECT_EQ("shared test", assigned_resource->desc());
}
// Mock classes for hourglass testing
class MockSrsHourGlass : public ISrsHourGlass
MockSrsHourGlass::MockSrsHourGlass()
{
public:
std::vector<int> events_;
std::vector<srs_utime_t> intervals_;
std::vector<srs_utime_t> ticks_;
}
public:
MockSrsHourGlass() {}
virtual ~MockSrsHourGlass() {}
public:
virtual srs_error_t notify(int event, srs_utime_t interval, srs_utime_t tick)
{
events_.push_back(event);
intervals_.push_back(interval);
ticks_.push_back(tick);
return srs_success;
}
void clear()
{
events_.clear();
intervals_.clear();
ticks_.clear();
}
};
class MockSrsFastTimer : public ISrsFastTimer
MockSrsHourGlass::~MockSrsHourGlass()
{
public:
std::vector<srs_utime_t> timer_calls_;
}
public:
MockSrsFastTimer() {}
virtual ~MockSrsFastTimer() {}
srs_error_t MockSrsHourGlass::notify(int event, srs_utime_t interval, srs_utime_t tick)
{
events_.push_back(event);
intervals_.push_back(interval);
ticks_.push_back(tick);
return srs_success;
}
public:
virtual srs_error_t on_timer(srs_utime_t interval)
{
timer_calls_.push_back(interval);
return srs_success;
}
void MockSrsHourGlass::clear()
{
events_.clear();
intervals_.clear();
ticks_.clear();
}
void clear()
{
timer_calls_.clear();
}
};
MockSrsFastTimer::MockSrsFastTimer()
{
}
MockSrsFastTimer::~MockSrsFastTimer()
{
}
srs_error_t MockSrsFastTimer::on_timer(srs_utime_t interval)
{
timer_calls_.push_back(interval);
return srs_success;
}
void MockSrsFastTimer::clear()
{
timer_calls_.clear();
}
// Tests for srs_kernel_hourglass.hpp
VOID TEST(KernelHourglassTest, ISrsHourGlassInterface)
@ -2743,38 +2733,31 @@ VOID TEST(KernelKbpsTest, SrsPps_MockClockUpdate)
}
}
// Mock RTP ring buffer for testing NACK receiver
class MockRtpRingBuffer : public SrsRtpRingBuffer
MockRtpRingBuffer::MockRtpRingBuffer() : SrsRtpRingBuffer(100)
{
public:
std::vector<uint16_t> dropped_seqs_;
bool nack_list_full_called_;
nack_list_full_called_ = false;
}
public:
MockRtpRingBuffer() : SrsRtpRingBuffer(100)
{
nack_list_full_called_ = false;
}
MockRtpRingBuffer::~MockRtpRingBuffer()
{
}
virtual ~MockRtpRingBuffer() {}
void MockRtpRingBuffer::notify_drop_seq(uint16_t seq)
{
dropped_seqs_.push_back(seq);
}
virtual void notify_drop_seq(uint16_t seq)
{
dropped_seqs_.push_back(seq);
}
void MockRtpRingBuffer::notify_nack_list_full()
{
nack_list_full_called_ = true;
SrsRtpRingBuffer::notify_nack_list_full();
}
virtual void notify_nack_list_full()
{
nack_list_full_called_ = true;
SrsRtpRingBuffer::notify_nack_list_full();
}
void clear_mock_data()
{
dropped_seqs_.clear();
nack_list_full_called_ = false;
}
};
void MockRtpRingBuffer::clear_mock_data()
{
dropped_seqs_.clear();
nack_list_full_called_ = false;
}
VOID TEST(KernelRTCQueueTest, SrsRtpNackForReceiver_GetNackSeqs_Debug)
{

View File

@ -12,6 +12,123 @@
*/
#include <srs_utest.hpp>
#include <srs_kernel_hourglass.hpp>
#include <srs_kernel_io.hpp>
#include <srs_kernel_resource.hpp>
#include <srs_kernel_rtc_queue.hpp>
#include <srs_utest_kernel.hpp>
// Mock classes for IO testing
class MockSrsReader : public ISrsReader
{
public:
std::string data_;
size_t pos_;
srs_error_t read_error_;
public:
MockSrsReader(const std::string &data);
virtual ~MockSrsReader();
virtual srs_error_t read(void *buf, size_t size, ssize_t *nread);
void set_error(srs_error_t err);
};
class MockSrsWriter : public ISrsWriter
{
public:
std::string written_data_;
srs_error_t write_error_;
public:
MockSrsWriter();
virtual ~MockSrsWriter();
virtual srs_error_t write(void *buf, size_t size, ssize_t *nwrite);
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t *nwrite);
void set_error(srs_error_t err);
};
class MockSrsSeeker : public ISrsSeeker
{
public:
off_t position_;
srs_error_t seek_error_;
public:
MockSrsSeeker();
virtual ~MockSrsSeeker();
virtual srs_error_t lseek(off_t offset, int whence, off_t *seeked);
void set_error(srs_error_t err);
};
// Mock classes for resource testing
class MockSrsResource : public ISrsResource
{
public:
SrsContextId cid_;
std::string desc_;
public:
MockSrsResource();
virtual ~MockSrsResource();
virtual const SrsContextId &get_id();
virtual std::string desc();
void set_id(const SrsContextId &cid);
void set_desc(const std::string &desc);
};
class MockSrsDisposingHandler : public ISrsDisposingHandler
{
public:
std::vector<ISrsResource *> before_dispose_calls_;
std::vector<ISrsResource *> disposing_calls_;
public:
MockSrsDisposingHandler();
virtual ~MockSrsDisposingHandler();
virtual void on_before_dispose(ISrsResource *c);
virtual void on_disposing(ISrsResource *c);
};
// Mock classes for hourglass testing
class MockSrsHourGlass : public ISrsHourGlass
{
public:
std::vector<int> events_;
std::vector<srs_utime_t> intervals_;
std::vector<srs_utime_t> ticks_;
public:
MockSrsHourGlass();
virtual ~MockSrsHourGlass();
virtual srs_error_t notify(int event, srs_utime_t interval, srs_utime_t tick);
void clear();
};
class MockSrsFastTimer : public ISrsFastTimer
{
public:
std::vector<srs_utime_t> timer_calls_;
public:
MockSrsFastTimer();
virtual ~MockSrsFastTimer();
virtual srs_error_t on_timer(srs_utime_t interval);
void clear();
};
// Mock RTP ring buffer for testing NACK receiver
class MockRtpRingBuffer : public SrsRtpRingBuffer
{
public:
std::vector<uint16_t> dropped_seqs_;
bool nack_list_full_called_;
public:
MockRtpRingBuffer();
virtual ~MockRtpRingBuffer();
virtual void notify_drop_seq(uint16_t seq);
virtual void notify_nack_list_full();
void clear_mock_data();
};
#endif

View File

@ -52,38 +52,43 @@ VOID TEST(ProtocolHttpTest, JsonpCallbackName)
EXPECT_FALSE(srs_is_valid_jsonp_callback("callback;"));
}
// Mock classes for testing protocol connections
class MockConnection : public ISrsConnection
// Mock class implementations
MockConnection::MockConnection(std::string ip) : ip_(ip)
{
public:
std::string ip_;
}
public:
MockConnection(std::string ip = "127.0.0.1") : ip_(ip) {}
virtual ~MockConnection() {}
public:
virtual std::string remote_ip() { return ip_; }
virtual std::string desc() { return "MockConnection"; }
virtual const SrsContextId &get_id()
{
static SrsContextId id = SrsContextId();
return id;
}
};
class MockExpire : public ISrsExpire
MockConnection::~MockConnection()
{
public:
bool expired_;
}
public:
MockExpire() : expired_(false) {}
virtual ~MockExpire() {}
std::string MockConnection::remote_ip()
{
return ip_;
}
public:
virtual void expire() { expired_ = true; }
};
std::string MockConnection::desc()
{
return "MockConnection";
}
const SrsContextId &MockConnection::get_id()
{
static SrsContextId id = SrsContextId();
return id;
}
MockExpire::MockExpire() : expired_(false)
{
}
MockExpire::~MockExpire()
{
}
void MockExpire::expire()
{
expired_ = true;
}
VOID TEST(ProtocolConnTest, ISrsConnectionInterface)
{

View File

@ -12,4 +12,35 @@
*/
#include <srs_utest_protocol.hpp>
#include <srs_protocol_conn.hpp>
// Mock classes for testing protocol connections
class MockConnection : public ISrsConnection
{
public:
std::string ip_;
public:
MockConnection(std::string ip = "127.0.0.1");
virtual ~MockConnection();
public:
virtual std::string remote_ip();
virtual std::string desc();
virtual const SrsContextId &get_id();
};
class MockExpire : public ISrsExpire
{
public:
bool expired_;
public:
MockExpire();
virtual ~MockExpire();
public:
virtual void expire();
};
#endif

View File

@ -22,49 +22,37 @@
using namespace std;
class MockPacket : public SrsRtmpCommand
MockPacket::MockPacket()
{
public:
int size;
size = 0;
}
public:
MockPacket()
{
size = 0;
}
virtual ~MockPacket()
{
}
protected:
virtual int get_size()
{
return size;
}
};
class MockPacket2 : public MockPacket
MockPacket::~MockPacket()
{
public:
char *payload;
}
public:
MockPacket2()
{
payload = NULL;
}
virtual ~MockPacket2()
{
srs_freep(payload);
}
virtual srs_error_t encode(int &size, char *&payload)
{
size = this->size;
payload = this->payload;
this->payload = NULL;
return srs_success;
}
};
int MockPacket::get_size()
{
return size;
}
MockPacket2::MockPacket2()
{
payload = NULL;
}
MockPacket2::~MockPacket2()
{
srs_freep(payload);
}
srs_error_t MockPacket2::encode(int &size, char *&payload)
{
size = this->size;
payload = this->payload;
this->payload = NULL;
return srs_success;
}
VOID TEST(ProtocolRTMPTest, PacketEncode)
{
@ -2877,18 +2865,14 @@ VOID TEST(ProtocolRTMPTest, AgentMessageTransform)
}
}
class MockMRHandler : public IMergeReadHandler
MockMRHandler::MockMRHandler() : nn(0)
{
public:
ssize_t nn;
MockMRHandler() : nn(0)
{
}
virtual void on_read(ssize_t nread)
{
nn += nread;
}
};
}
void MockMRHandler::on_read(ssize_t nread)
{
nn += nread;
}
VOID TEST(ProtocolRTMPTest, MergeReadHandler)
{

View File

@ -12,6 +12,42 @@
*/
#include <srs_utest.hpp>
#include <srs_protocol_rtmp_stack.hpp>
#include <srs_utest_protocol.hpp>
// Mock classes for RTMP testing
class MockPacket : public SrsRtmpCommand
{
public:
int size;
public:
MockPacket();
virtual ~MockPacket();
protected:
virtual int get_size();
};
class MockPacket2 : public MockPacket
{
public:
char *payload;
public:
MockPacket2();
virtual ~MockPacket2();
virtual srs_error_t encode(int &size, char *&payload);
};
class MockMRHandler : public IMergeReadHandler
{
public:
ssize_t nn;
public:
MockMRHandler();
virtual void on_read(ssize_t nread);
};
#endif

View File

@ -67,28 +67,21 @@ VOID TEST(ServiceTimeTest, TimeUnit)
EXPECT_FALSE(srs_is_never_timeout(0));
}
class MockTcpHandler : public ISrsTcpHandler
MockTcpHandler::MockTcpHandler()
{
private:
srs_netfd_t fd;
fd = NULL;
}
public:
MockTcpHandler()
{
fd = NULL;
}
virtual ~MockTcpHandler()
{
srs_close_stfd(fd);
}
MockTcpHandler::~MockTcpHandler()
{
srs_close_stfd(fd);
}
public:
virtual srs_error_t on_tcp_client(ISrsListener *listener, srs_netfd_t stfd)
{
fd = stfd;
return srs_success;
}
};
srs_error_t MockTcpHandler::on_tcp_client(ISrsListener *listener, srs_netfd_t stfd)
{
fd = stfd;
return srs_success;
}
VOID TEST(TCPServerTest, PingPong)
{
@ -992,38 +985,44 @@ VOID TEST(TCPServerTest, UDPListen)
}
}
class MockOnCycleThread : public ISrsCoroutineHandler
MockOnCycleThread::MockOnCycleThread() : trd("mock", this)
{
public:
SrsSTCoroutine trd;
srs_cond_t cond;
MockOnCycleThread() : trd("mock", this)
{
cond = srs_cond_new();
};
virtual ~MockOnCycleThread()
{
srs_cond_destroy(cond);
}
virtual srs_error_t cycle()
{
srs_error_t err = srs_success;
cond = srs_cond_new();
}
for (;;) {
srs_usleep(10 * 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.
srs_cond_signal(cond);
MockOnCycleThread::~MockOnCycleThread()
{
srs_cond_destroy(cond);
}
if ((err = trd.pull()) != srs_success) {
return err;
}
srs_error_t MockOnCycleThread::cycle()
{
srs_error_t err = srs_success;
for (;;) {
srs_usleep(10 * 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.
srs_cond_signal(cond);
if ((err = trd.pull()) != srs_success) {
return err;
}
return err;
}
};
return err;
}
srs_error_t MockOnCycleThread::start()
{
return trd.start();
}
void MockOnCycleThread::stop()
{
trd.stop();
}
VOID TEST(TCPServerTest, ThreadCondWait)
{
@ -1035,37 +1034,43 @@ VOID TEST(TCPServerTest, ThreadCondWait)
trd.trd.stop();
}
class MockOnCycleThread2 : public ISrsCoroutineHandler
MockOnCycleThread2::MockOnCycleThread2() : trd("mock", this)
{
public:
SrsSTCoroutine trd;
srs_mutex_t lock;
MockOnCycleThread2() : trd("mock", this)
{
lock = srs_mutex_new();
};
virtual ~MockOnCycleThread2()
{
srs_mutex_destroy(lock);
}
virtual srs_error_t cycle()
{
srs_error_t err = srs_success;
lock = srs_mutex_new();
}
for (;;) {
srs_mutex_lock(lock);
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
srs_mutex_unlock(lock);
MockOnCycleThread2::~MockOnCycleThread2()
{
srs_mutex_destroy(lock);
}
srs_error_t err = trd.pull();
if (err != srs_success) {
return err;
}
srs_error_t MockOnCycleThread2::cycle()
{
srs_error_t err = srs_success;
for (;;) {
srs_mutex_lock(lock);
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
srs_mutex_unlock(lock);
srs_error_t err = trd.pull();
if (err != srs_success) {
return err;
}
return err;
}
};
return err;
}
srs_error_t MockOnCycleThread2::start()
{
return trd.start();
}
void MockOnCycleThread2::stop()
{
trd.stop();
}
VOID TEST(TCPServerTest, ThreadMutexWait)
{
@ -1079,69 +1084,72 @@ VOID TEST(TCPServerTest, ThreadMutexWait)
srs_mutex_unlock(trd.lock);
}
class MockOnCycleThread3 : public ISrsCoroutineHandler
MockOnCycleThread3::MockOnCycleThread3() : trd("mock", this)
{
public:
SrsSTCoroutine trd;
srs_netfd_t fd;
MockOnCycleThread3() : trd("mock", this)
{
fd = NULL;
};
virtual ~MockOnCycleThread3()
{
trd.stop();
srs_close_stfd(fd);
fd = NULL;
}
MockOnCycleThread3::~MockOnCycleThread3()
{
trd.stop();
srs_close_stfd(fd);
}
srs_error_t MockOnCycleThread3::start(std::string ip, int port)
{
srs_error_t err = srs_success;
if ((err = srs_tcp_listen(ip, port, &fd)) != srs_success) {
return err;
}
virtual srs_error_t start(string ip, int port)
{
srs_error_t err = srs_success;
if ((err = srs_tcp_listen(ip, port, &fd)) != srs_success) {
return trd.start();
}
srs_error_t MockOnCycleThread3::do_cycle(srs_netfd_t cfd)
{
srs_error_t err = srs_success;
SrsStSocket skt(cfd);
skt.set_recv_timeout(1 * SRS_UTIME_SECONDS);
skt.set_send_timeout(1 * SRS_UTIME_SECONDS);
while (true) {
if ((err = trd.pull()) != srs_success) {
return err;
}
return trd.start();
}
virtual srs_error_t do_cycle(srs_netfd_t cfd)
{
srs_error_t err = srs_success;
SrsStSocket skt(cfd);
skt.set_recv_timeout(1 * SRS_UTIME_SECONDS);
skt.set_send_timeout(1 * SRS_UTIME_SECONDS);
while (true) {
if ((err = trd.pull()) != srs_success) {
return err;
}
char buf[5];
if ((err = skt.read_fully(buf, 5, NULL)) != srs_success) {
return err;
}
if ((err = skt.write(buf, 5, NULL)) != srs_success) {
return err;
}
}
return err;
}
virtual srs_error_t cycle()
{
srs_error_t err = srs_success;
srs_netfd_t cfd = srs_accept(fd, NULL, NULL, SRS_UTIME_NO_TIMEOUT);
if (cfd == NULL) {
char buf[5];
if ((err = skt.read_fully(buf, 5, NULL)) != srs_success) {
return err;
}
if ((err = skt.write(buf, 5, NULL)) != srs_success) {
return err;
}
}
err = do_cycle(cfd);
srs_close_stfd(cfd);
srs_freep(err);
return err;
}
srs_error_t MockOnCycleThread3::cycle()
{
srs_error_t err = srs_success;
srs_netfd_t cfd = srs_accept(fd, NULL, NULL, SRS_UTIME_NO_TIMEOUT);
if (cfd == NULL) {
return err;
}
};
err = do_cycle(cfd);
srs_close_stfd(cfd);
srs_freep(err);
return err;
}
void MockOnCycleThread3::stop()
{
trd.stop();
}
VOID TEST(TCPServerTest, TCPClientServer)
{
@ -1334,21 +1342,21 @@ VOID TEST(TCPServerTest, CoverUtility)
}
}
class MockConnectionManager : public ISrsResourceManager
MockConnectionManager::MockConnectionManager()
{
public:
MockConnectionManager()
{
}
virtual ~MockConnectionManager()
{
}
}
public:
virtual void remove(ISrsResource * /*c*/)
{
}
};
MockConnectionManager::~MockConnectionManager()
{
}
void MockConnectionManager::remove(ISrsResource * /*c*/)
{
}
void MockConnectionManager::dispose()
{
}
VOID TEST(TCPServerTest, ContextUtility)
{
@ -1428,33 +1436,30 @@ VOID TEST(TCPServerTest, ContextUtility)
}
}
class MockStopSelfThread : public ISrsCoroutineHandler
MockStopSelfThread::MockStopSelfThread() : r0(0), r1(0), trd("mock", this)
{
public:
int r0;
int r1;
SrsFastCoroutine trd;
MockStopSelfThread() : r0(0), r1(0), trd("mock", this)
{
}
virtual ~MockStopSelfThread()
{
}
srs_error_t start()
{
return trd.start();
}
void stop()
{
trd.stop();
}
virtual srs_error_t cycle()
{
r0 = st_thread_join((st_thread_t)trd.trd_, NULL);
r1 = errno;
return srs_success;
}
};
}
MockStopSelfThread::~MockStopSelfThread()
{
}
srs_error_t MockStopSelfThread::start()
{
return trd.start();
}
void MockStopSelfThread::stop()
{
trd.stop();
}
srs_error_t MockStopSelfThread::cycle()
{
r0 = st_thread_join((st_thread_t)trd.trd_, NULL);
r1 = errno;
return srs_success;
}
VOID TEST(ThreadCriticalTest, ShouldFailWhenStopSelf)
{
@ -1468,40 +1473,38 @@ VOID TEST(ThreadCriticalTest, ShouldFailWhenStopSelf)
EXPECT_EQ(EDEADLK, trd.r1);
}
class MockAsyncReaderThread : public ISrsCoroutineHandler
MockAsyncReaderThread::MockAsyncReaderThread(srs_netfd_t v) : trd("mock", this), fd(v)
{
public:
SrsFastCoroutine trd;
srs_netfd_t fd;
MockAsyncReaderThread(srs_netfd_t v) : trd("mock", this), fd(v)
{
}
virtual ~MockAsyncReaderThread()
{
}
srs_error_t start()
{
return trd.start();
}
void stop()
{
trd.stop();
}
virtual srs_error_t cycle()
{
srs_error_t err = srs_success;
while (true) {
if ((err = trd.pull()) != srs_success) {
return err;
}
char buf[16] = {0};
if (st_read((st_netfd_t)fd, buf, sizeof(buf), SRS_UTIME_NO_TIMEOUT) <= 0) {
break;
}
}
MockAsyncReaderThread::~MockAsyncReaderThread()
{
}
srs_error_t MockAsyncReaderThread::start()
{
return trd.start();
}
void MockAsyncReaderThread::stop()
{
trd.stop();
}
srs_error_t MockAsyncReaderThread::cycle()
{
srs_error_t err = srs_success;
while (true) {
if ((err = trd.pull()) != srs_success) {
return err;
}
char buf[16] = {0};
if (st_read((st_netfd_t)fd, buf, sizeof(buf), SRS_UTIME_NO_TIMEOUT) <= 0) {
break;
}
return err;
}
};
return err;
}
VOID TEST(ThreadCriticalTest, FailIfCloseActiveFD)
{

View File

@ -12,7 +12,9 @@
*/
#include <srs_utest.hpp>
#include <srs_app_listener.hpp>
#include <srs_app_st.hpp>
#include <srs_kernel_resource.hpp>
#include <srs_protocol_conn.hpp>
class MockSrsConnection : public ISrsConnection
@ -31,4 +33,88 @@ public:
virtual std::string remote_ip();
};
class MockTcpHandler : public ISrsTcpHandler
{
private:
srs_netfd_t fd;
public:
MockTcpHandler();
virtual ~MockTcpHandler();
public:
virtual srs_error_t on_tcp_client(ISrsListener *listener, srs_netfd_t stfd);
};
class MockOnCycleThread : public ISrsCoroutineHandler
{
public:
SrsSTCoroutine trd;
srs_cond_t cond;
MockOnCycleThread();
virtual ~MockOnCycleThread();
virtual srs_error_t cycle();
srs_error_t start();
void stop();
};
class MockOnCycleThread2 : public ISrsCoroutineHandler
{
public:
SrsSTCoroutine trd;
srs_mutex_t lock;
MockOnCycleThread2();
virtual ~MockOnCycleThread2();
virtual srs_error_t cycle();
srs_error_t start();
void stop();
};
class MockOnCycleThread3 : public ISrsCoroutineHandler
{
public:
SrsSTCoroutine trd;
srs_netfd_t fd;
MockOnCycleThread3();
virtual ~MockOnCycleThread3();
virtual srs_error_t cycle();
virtual srs_error_t start(std::string ip, int port);
virtual srs_error_t do_cycle(srs_netfd_t cfd);
void stop();
};
class MockConnectionManager : public ISrsResourceManager
{
public:
MockConnectionManager();
virtual ~MockConnectionManager();
virtual void remove(ISrsResource *c);
virtual void dispose();
};
class MockStopSelfThread : public ISrsCoroutineHandler
{
public:
int r0;
int r1;
SrsFastCoroutine trd;
MockStopSelfThread();
virtual ~MockStopSelfThread();
srs_error_t start();
void stop();
virtual srs_error_t cycle();
};
class MockAsyncReaderThread : public ISrsCoroutineHandler
{
public:
SrsFastCoroutine trd;
srs_netfd_t fd;
MockAsyncReaderThread(srs_netfd_t v);
virtual ~MockAsyncReaderThread();
srs_error_t start();
void stop();
virtual srs_error_t cycle();
};
#endif