2019-10-23 01:26:10 +00:00
|
|
|
/*
|
|
|
|
The MIT License (MIT)
|
|
|
|
|
|
|
|
Copyright (c) 2013-2019 Winlin
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
|
this software and associated documentation files (the "Software"), to deal in
|
|
|
|
the Software without restriction, including without limitation the rights to
|
|
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
|
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
|
|
subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
|
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
|
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
#include <srs_utest_protostack.hpp>
|
|
|
|
|
2019-10-28 00:41:49 +00:00
|
|
|
#include <srs_utest_protocol.hpp>
|
2019-10-23 01:26:10 +00:00
|
|
|
|
|
|
|
#include <srs_kernel_error.hpp>
|
|
|
|
#include <srs_core_autofree.hpp>
|
|
|
|
#include <srs_protocol_utility.hpp>
|
|
|
|
#include <srs_rtmp_msg_array.hpp>
|
|
|
|
#include <srs_rtmp_stack.hpp>
|
|
|
|
#include <srs_kernel_utility.hpp>
|
|
|
|
#include <srs_app_st.hpp>
|
|
|
|
#include <srs_protocol_amf0.hpp>
|
|
|
|
#include <srs_rtmp_stack.hpp>
|
|
|
|
#include <srs_service_http_conn.hpp>
|
2019-10-25 00:18:21 +00:00
|
|
|
#include <srs_kernel_buffer.hpp>
|
2019-10-23 01:26:10 +00:00
|
|
|
|
2019-10-28 00:41:49 +00:00
|
|
|
using namespace std;
|
|
|
|
|
2019-11-05 02:17:06 +00:00
|
|
|
class MockPacket : public SrsPacket
|
2019-10-23 01:26:10 +00:00
|
|
|
{
|
2019-11-05 02:17:06 +00:00
|
|
|
public:
|
|
|
|
int size;
|
|
|
|
public:
|
|
|
|
MockPacket() {
|
|
|
|
size = 0;
|
|
|
|
}
|
|
|
|
virtual ~MockPacket() {
|
|
|
|
}
|
2019-10-25 00:18:21 +00:00
|
|
|
protected:
|
|
|
|
virtual int get_size() {
|
2019-11-05 02:17:06 +00:00
|
|
|
return size;
|
2019-10-25 00:18:21 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-11-05 02:17:06 +00:00
|
|
|
class MockPacket2 : public MockPacket
|
2019-11-05 01:55:45 +00:00
|
|
|
{
|
2019-11-05 02:17:06 +00:00
|
|
|
public:
|
|
|
|
char* payload;
|
|
|
|
public:
|
|
|
|
MockPacket2() {
|
|
|
|
payload = NULL;
|
|
|
|
}
|
|
|
|
virtual ~MockPacket2() {
|
|
|
|
srs_freep(payload);
|
|
|
|
}
|
2019-11-05 01:55:45 +00:00
|
|
|
virtual srs_error_t encode(int& size, char*& payload) {
|
2019-11-05 02:17:06 +00:00
|
|
|
size = this->size;
|
|
|
|
payload = this->payload;
|
|
|
|
this->payload = NULL;
|
2019-11-05 01:55:45 +00:00
|
|
|
return srs_success;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-10-25 00:18:21 +00:00
|
|
|
VOID TEST(ProtoStackTest, PacketEncode)
|
|
|
|
{
|
|
|
|
srs_error_t err;
|
|
|
|
|
|
|
|
int size;
|
|
|
|
char* payload;
|
|
|
|
|
|
|
|
if (true) {
|
2019-11-05 02:17:06 +00:00
|
|
|
MockPacket pkt;
|
|
|
|
pkt.size = 1024;
|
|
|
|
|
2019-10-25 00:18:21 +00:00
|
|
|
HELPER_EXPECT_FAILED(pkt.encode(size, payload));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
2019-11-05 02:17:06 +00:00
|
|
|
MockPacket pkt;
|
|
|
|
pkt.size = 1024;
|
|
|
|
|
2019-10-25 00:18:21 +00:00
|
|
|
SrsBuffer b;
|
|
|
|
HELPER_EXPECT_FAILED(pkt.decode(&b));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
SrsPacket pkt;
|
|
|
|
EXPECT_EQ(0, pkt.get_prefer_cid());
|
|
|
|
EXPECT_EQ(0, pkt.get_message_type());
|
|
|
|
EXPECT_EQ(0, pkt.get_size());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
2019-11-05 02:17:06 +00:00
|
|
|
MockPacket pkt;
|
|
|
|
pkt.size = 1024;
|
|
|
|
|
2019-10-25 00:18:21 +00:00
|
|
|
EXPECT_EQ(1024, pkt.get_size());
|
|
|
|
}
|
2019-10-23 01:26:10 +00:00
|
|
|
}
|
|
|
|
|
2019-10-28 00:41:49 +00:00
|
|
|
VOID TEST(ProtoStackTest, ManualFlush)
|
|
|
|
{
|
|
|
|
srs_error_t err;
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
// Always response ACK message.
|
|
|
|
HELPER_EXPECT_SUCCESS(p.set_in_window_ack_size(1));
|
|
|
|
|
|
|
|
// Default is auto response.
|
|
|
|
HELPER_EXPECT_SUCCESS(p.response_acknowledgement_message());
|
|
|
|
EXPECT_EQ(12+4, io.out_buffer.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
// Always response ACK message.
|
|
|
|
HELPER_EXPECT_SUCCESS(p.set_in_window_ack_size(1));
|
|
|
|
|
|
|
|
p.set_auto_response(true);
|
|
|
|
HELPER_EXPECT_SUCCESS(p.response_acknowledgement_message());
|
|
|
|
EXPECT_EQ(12+4, io.out_buffer.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
// Always response ACK message.
|
|
|
|
HELPER_EXPECT_SUCCESS(p.set_in_window_ack_size(1));
|
|
|
|
|
|
|
|
// When not auto response, need to flush it manually.
|
|
|
|
p.set_auto_response(false);
|
|
|
|
HELPER_EXPECT_SUCCESS(p.response_acknowledgement_message());
|
|
|
|
EXPECT_EQ(0, io.out_buffer.length());
|
|
|
|
|
|
|
|
HELPER_EXPECT_SUCCESS(p.manual_response_flush());
|
|
|
|
EXPECT_EQ(12+4, io.out_buffer.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
// Always response ACK message.
|
|
|
|
HELPER_EXPECT_SUCCESS(p.set_in_window_ack_size(1));
|
|
|
|
|
|
|
|
HELPER_EXPECT_SUCCESS(p.response_ping_message(1024));
|
|
|
|
EXPECT_EQ(12+6, io.out_buffer.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
// Always response ACK message.
|
|
|
|
HELPER_EXPECT_SUCCESS(p.set_in_window_ack_size(1));
|
|
|
|
|
|
|
|
// When not auto response, need to flush it manually.
|
|
|
|
p.set_auto_response(false);
|
|
|
|
HELPER_EXPECT_SUCCESS(p.response_ping_message(1024));
|
|
|
|
EXPECT_EQ(0, io.out_buffer.length());
|
|
|
|
|
|
|
|
HELPER_EXPECT_SUCCESS(p.manual_response_flush());
|
|
|
|
EXPECT_EQ(12+6, io.out_buffer.length());
|
|
|
|
}
|
2019-10-28 00:57:11 +00:00
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
// Always response ACK message.
|
|
|
|
HELPER_EXPECT_SUCCESS(p.set_in_window_ack_size(1));
|
|
|
|
|
|
|
|
// When not auto response, need to flush it manually.
|
|
|
|
p.set_auto_response(false);
|
|
|
|
HELPER_EXPECT_SUCCESS(p.response_ping_message(1024));
|
|
|
|
EXPECT_EQ(0, io.out_buffer.length());
|
|
|
|
|
|
|
|
// If not flushed, the packets will be destroyed.
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
p.set_recv_buffer(0);
|
|
|
|
p.set_recv_buffer(131072 * 10);
|
|
|
|
|
|
|
|
p.set_merge_read(true, NULL);
|
|
|
|
p.set_merge_read(false, NULL);
|
|
|
|
}
|
2019-10-28 00:41:49 +00:00
|
|
|
}
|
|
|
|
|
2019-11-05 01:55:45 +00:00
|
|
|
VOID TEST(ProtoStackTest, SendPacketsError)
|
|
|
|
{
|
|
|
|
srs_error_t err;
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
2019-11-05 02:17:06 +00:00
|
|
|
MockPacket* pkt = new MockPacket();
|
|
|
|
pkt->size = 1024;
|
2019-11-05 01:55:45 +00:00
|
|
|
HELPER_EXPECT_FAILED(p.send_and_free_packet(pkt, 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
SrsPacket* pkt = new SrsPacket();
|
|
|
|
HELPER_EXPECT_SUCCESS(p.send_and_free_packet(pkt, 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
2019-11-05 02:17:06 +00:00
|
|
|
MockPacket2* pkt = new MockPacket2();
|
|
|
|
pkt->size = 1024;
|
2019-11-05 01:55:45 +00:00
|
|
|
HELPER_EXPECT_SUCCESS(p.send_and_free_packet(pkt, 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-05 02:17:06 +00:00
|
|
|
VOID TEST(ProtoStackTest, SendHugePacket)
|
|
|
|
{
|
|
|
|
srs_error_t err;
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
MockPacket2* pkt = new MockPacket2();
|
|
|
|
pkt->size = 1024;
|
|
|
|
pkt->payload = new char[1024];
|
|
|
|
HELPER_EXPECT_SUCCESS(p.send_and_free_packet(pkt, 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
MockPacket2* pkt = new MockPacket2();
|
|
|
|
pkt->size = 16;
|
|
|
|
pkt->payload = new char[16];
|
|
|
|
|
|
|
|
io.out_err = srs_error_new(1, "fail");
|
|
|
|
HELPER_EXPECT_FAILED(p.send_and_free_packet(pkt, 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-29 02:02:03 +00:00
|
|
|
VOID TEST(ProtoStackTest, SendZeroMessages)
|
|
|
|
{
|
|
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
HELPER_EXPECT_SUCCESS(p.send_and_free_message(NULL, 0));
|
|
|
|
}
|
2019-11-04 01:31:30 +00:00
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
SrsSharedPtrMessage* msg = new SrsSharedPtrMessage();
|
|
|
|
HELPER_EXPECT_SUCCESS(p.send_and_free_message(msg, 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
SrsSharedPtrMessage* msgs[1024];
|
|
|
|
for (int i = 0; i < 1024; i++) {
|
|
|
|
msgs[i] = new SrsSharedPtrMessage();
|
|
|
|
}
|
|
|
|
HELPER_EXPECT_SUCCESS(p.send_and_free_messages(msgs, 1024, 0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID TEST(ProtoStackTest, HugeMessages)
|
|
|
|
{
|
|
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
SrsCommonMessage pkt;
|
|
|
|
pkt.header.initialize_audio(200, 1000, 1);
|
|
|
|
pkt.create_payload(256);
|
|
|
|
pkt.size = 256;
|
|
|
|
|
|
|
|
SrsSharedPtrMessage* msg = new SrsSharedPtrMessage();
|
|
|
|
msg->create(&pkt);
|
|
|
|
|
|
|
|
HELPER_EXPECT_SUCCESS(p.send_and_free_message(msg, 1));
|
|
|
|
EXPECT_EQ(269, io.out_buffer.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
SrsCommonMessage pkt;
|
|
|
|
pkt.header.initialize_audio(200, 1000, 1);
|
|
|
|
pkt.create_payload(256);
|
|
|
|
pkt.size = 256;
|
|
|
|
|
|
|
|
SrsSharedPtrMessage* msg = new SrsSharedPtrMessage();
|
|
|
|
msg->create(&pkt);
|
|
|
|
SrsAutoFree(SrsSharedPtrMessage, msg);
|
|
|
|
|
|
|
|
SrsSharedPtrMessage* msgs[1024];
|
|
|
|
for (int i = 0; i < 1024; i++) {
|
|
|
|
msgs[i] = msg->copy();
|
|
|
|
}
|
|
|
|
|
|
|
|
HELPER_EXPECT_SUCCESS(p.send_and_free_messages(msgs, 1024, 1));
|
|
|
|
EXPECT_EQ(269*1024, io.out_buffer.length());
|
|
|
|
}
|
2019-11-05 02:31:21 +00:00
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
SrsCommonMessage pkt;
|
|
|
|
pkt.header.initialize_audio(200, 1000, 1);
|
|
|
|
pkt.create_payload(256);
|
|
|
|
pkt.size = 256;
|
|
|
|
|
|
|
|
SrsSharedPtrMessage* msg = new SrsSharedPtrMessage();
|
|
|
|
msg->create(&pkt);
|
|
|
|
SrsAutoFree(SrsSharedPtrMessage, msg);
|
|
|
|
|
|
|
|
SrsSharedPtrMessage* msgs[10240];
|
|
|
|
for (int i = 0; i < 10240; i++) {
|
|
|
|
msgs[i] = msg->copy();
|
|
|
|
}
|
|
|
|
|
|
|
|
HELPER_EXPECT_SUCCESS(p.send_and_free_messages(msgs, 10240, 1));
|
|
|
|
EXPECT_EQ(269*10240, io.out_buffer.length());
|
|
|
|
}
|
2019-10-29 02:02:03 +00:00
|
|
|
}
|
|
|
|
|
2019-11-05 01:55:45 +00:00
|
|
|
VOID TEST(ProtoStackTest, DecodeMessages)
|
|
|
|
{
|
|
|
|
srs_error_t err;
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
MockBufferIO io;
|
|
|
|
SrsProtocol p(&io);
|
|
|
|
|
|
|
|
// AMF0 message with 1B should fail.
|
|
|
|
SrsCommonMessage msg;
|
|
|
|
msg.header.initialize_amf0_script(1, 1);
|
|
|
|
msg.create_payload(1);
|
|
|
|
msg.size = 1;
|
|
|
|
|
|
|
|
SrsPacket* pkt;
|
|
|
|
HELPER_EXPECT_FAILED(p.decode_message(&msg, &pkt));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|