AI: Improve coverage of app module.
This commit is contained in:
parent
10c0b66c0f
commit
a1dd73545a
2
trunk/configure
vendored
2
trunk/configure
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -86,6 +86,14 @@ public:
|
|||
// Register FFmpeg log callback funciton.
|
||||
SrsFFmpegLogHelper _srs_ffmpeg_log_helper;
|
||||
|
||||
ISrsAudioTranscoder::ISrsAudioTranscoder()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsAudioTranscoder::~ISrsAudioTranscoder()
|
||||
{
|
||||
}
|
||||
|
||||
SrsAudioTranscoder::SrsAudioTranscoder()
|
||||
{
|
||||
dec_ = NULL;
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
4816
trunk/src/utest/srs_utest_app4.cpp
Normal file
4816
trunk/src/utest/srs_utest_app4.cpp
Normal file
File diff suppressed because it is too large
Load Diff
83
trunk/src/utest/srs_utest_app4.hpp
Normal file
83
trunk/src/utest/srs_utest_app4.hpp
Normal 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
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user