Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tests] Extending socket options test to group options. #3086

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

# Ignore any folder starting from underscore
_*/
venv/
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is to be removed. Slipped through.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
venv/


# Ignode Visual Studio Code temp folder
.vs/
Expand Down
10 changes: 6 additions & 4 deletions srtcore/group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ template <size_t N>
static void importStringOption(vector<CUDTGroup::ConfigItem>& storage, SRT_SOCKOPT optname, const StringStorage<N>& optval)
{
if (optval.empty())
return;
return;

// Store the option when:
// - option has a value (default is empty).
Expand Down Expand Up @@ -615,9 +615,11 @@ bool CUDTGroup::applyFlags(uint32_t flags, HandshakeSide)
template <class Type>
struct Value
{
static int fill(void* optval, int, const Type& value)
static int fill(void* optval, int len, const Type& value)
{
// XXX assert size >= sizeof(Type) ?
if (size_t(len) < sizeof(Type))
return 0;

*(Type*)optval = value;
return sizeof(Type);
}
Expand Down Expand Up @@ -671,7 +673,7 @@ static bool getOptDefault(SRT_SOCKOPT optname, void* pw_optval, int& w_optlen)

case SRTO_SNDBUF:
case SRTO_RCVBUF:
w_optlen = fillValue((pw_optval), w_optlen, CSrtConfig::DEF_BUFFER_SIZE * (CSrtConfig::DEF_MSS - CPacket::UDP_HDR_SIZE));
w_optlen = fillValue<int>((pw_optval), w_optlen, CSrtConfig::DEF_BUFFER_SIZE * (CSrtConfig::DEF_MSS - CPacket::UDP_HDR_SIZE));
break;

case SRTO_LINGER:
Expand Down
11 changes: 11 additions & 0 deletions test/test_bonding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,18 @@ TEST(Bonding, Options)
uint32_t val = 16;
EXPECT_NE(srt_setsockflag(grp, SRTO_PBKEYLEN, &val, (int) sizeof val), SRT_ERROR);

const bool bfalse = true;
EXPECT_EQ(srt_setsockflag(grp, SRTO_RENDEZVOUS, &bfalse, (int)sizeof bfalse), SRT_ERROR);

#ifdef ENABLE_AEAD_API_PREVIEW
val = 1;
EXPECT_NE(srt_setsockflag(grp, SRTO_CRYPTOMODE, &val, sizeof val), SRT_ERROR);
#endif
#endif

const string packet_filter = "fec,cols:10,rows:5";
EXPECT_NE(srt_setsockflag(grp, SRTO_PACKETFILTER, packet_filter.c_str(), (int)packet_filter.size()), SRT_ERROR);

// ================
// Linger is an option of a trivial type, but differes from other integer-typed options.
// Therefore checking it specifically.
Expand Down Expand Up @@ -437,6 +443,11 @@ TEST(Bonding, Options)

check_streamid(gs);

std::array<char, 800> tmpbuf;
auto opt_len = (int)tmpbuf.size();
EXPECT_EQ(srt_getsockflag(gs, SRTO_PACKETFILTER, tmpbuf.data(), &opt_len), SRT_SUCCESS);
std::cout << "Packet filter: " << std::string(tmpbuf.data(), opt_len) << '\n';

// Connected, wait to close
latch.wait(ux);

Expand Down
27 changes: 27 additions & 0 deletions test/test_group_options.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* SRT - Secure, Reliable, Transport
* Copyright (c) 2019 Haivision Systems Inc.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Written by:
* Haivision Systems Inc.
*/

#include <array>
#include <future>
#include <thread>
#include <string>
#include <gtest/gtest.h>
#include "test_env.h"

// SRT includes
#include "any.hpp"
#include "socketconfig.h"
#include "srt.h"

using namespace std;
using namespace srt;

127 changes: 113 additions & 14 deletions test/test_socket_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,95 @@ class TestSocketOptions
int m_pollid = 0;
};

// Test group options
class TestGroupOptions
: public ::srt::Test
{
protected:
TestGroupOptions() = default;
~TestGroupOptions() override = default;

public:
void BindListener() const
{
// Specify address of the listener
const auto* psa = (const sockaddr*)&m_sa;
ASSERT_NE(srt_bind(m_listen_sock, psa, sizeof m_sa), SRT_ERROR);
}

void StartListener() const
{
BindListener();
srt_listen(m_listen_sock, 1);
}

int Connect() const
{
const auto* psa = (const sockaddr*)&m_sa;
return srt_connect(m_caller_sock, psa, sizeof m_sa);
}

SRTSOCKET EstablishConnection()
{
auto accept_async = [](SRTSOCKET listen_sock) {
sockaddr_in client_address;
int length = sizeof(sockaddr_in);
const SRTSOCKET accepted_socket = srt_accept(listen_sock, (sockaddr*)&client_address, &length);
return accepted_socket;
};
auto accept_res = async(launch::async, accept_async, m_listen_sock);

// Make sure the thread was kicked
this_thread::yield();

const int connect_res = Connect();
EXPECT_EQ(connect_res, SRT_SUCCESS);

const SRTSOCKET accepted_sock = accept_res.get();
EXPECT_NE(accepted_sock, SRT_INVALID_SOCK);

return accepted_sock;
}

protected:
// Is run immediately before a test starts.
void setup() override
{
const int yes = 1;

memset(&m_sa, 0, sizeof m_sa);
m_sa.sin_family = AF_INET;
m_sa.sin_port = htons(5200);
ASSERT_EQ(inet_pton(AF_INET, "127.0.0.1", &m_sa.sin_addr), 1);

m_caller_sock = srt_create_group(SRT_GTYPE_BROADCAST);
ASSERT_NE(m_caller_sock, SRT_INVALID_SOCK);
ASSERT_EQ(srt_setsockopt(m_caller_sock, 0, SRTO_RCVSYN, &yes, sizeof yes), SRT_SUCCESS); // for async connect
ASSERT_EQ(srt_setsockopt(m_caller_sock, 0, SRTO_SNDSYN, &yes, sizeof yes), SRT_SUCCESS); // for async connect

m_listen_sock = srt_create_socket();
ASSERT_NE(m_listen_sock, SRT_INVALID_SOCK);
ASSERT_EQ(srt_setsockopt(m_listen_sock, 0, SRTO_RCVSYN, &yes, sizeof yes), SRT_SUCCESS); // for async connect
ASSERT_EQ(srt_setsockopt(m_listen_sock, 0, SRTO_SNDSYN, &yes, sizeof yes), SRT_SUCCESS); // for async connect
ASSERT_EQ(srt_setsockflag(m_listen_sock, SRTO_GROUPCONNECT, &yes, sizeof yes), SRT_SUCCESS);

}

void teardown() override
{
// Code here will be called just after the test completes.
// OK to throw exceptions from here if needed.
EXPECT_NE(srt_close(m_caller_sock), SRT_ERROR);
EXPECT_NE(srt_close(m_listen_sock), SRT_ERROR);
}

sockaddr_in m_sa;
SRTSOCKET m_caller_sock = SRT_INVALID_SOCK;
SRTSOCKET m_listen_sock = SRT_INVALID_SOCK;

int m_pollid = 0;
};

enum class RestrictionType
{
PREBIND = 0,
Expand Down Expand Up @@ -353,26 +442,26 @@ bool CheckInvalidValues(const OptionTestEntry& entry, SRTSOCKET sock, const char
return true;
}

TEST_F(TestSocketOptions, DefaultVals)
void TestDefaultValues(SRTSOCKET s)
{
for (const auto& entry : g_test_matrix_options)
{
const char* test_desc = "[Caller, default]";
if (entry.dflt_val.type() == typeid(bool))
{
EXPECT_TRUE(CheckDefaultValue<bool>(entry, m_caller_sock, test_desc));
EXPECT_TRUE(CheckDefaultValue<bool>(entry, s, test_desc));
}
else if (entry.dflt_val.type() == typeid(int))
{
EXPECT_TRUE(CheckDefaultValue<int>(entry, m_caller_sock, test_desc));
EXPECT_TRUE(CheckDefaultValue<int>(entry, s, test_desc));
}
else if (entry.dflt_val.type() == typeid(int64_t))
{
EXPECT_TRUE(CheckDefaultValue<int64_t>(entry, m_caller_sock, test_desc));
EXPECT_TRUE(CheckDefaultValue<int64_t>(entry, s, test_desc));
}
else if (entry.dflt_val.type() == typeid(const char*))
{
EXPECT_TRUE(CheckDefaultValue<const char*>(entry, m_caller_sock, test_desc));
EXPECT_TRUE(CheckDefaultValue<const char*>(entry, s, test_desc));
}
else
{
Expand All @@ -381,6 +470,16 @@ TEST_F(TestSocketOptions, DefaultVals)
}
}

TEST_F(TestSocketOptions, DefaultVals)
{
TestDefaultValues(m_caller_sock);
}

TEST_F(TestGroupOptions, DefaultVals)
{
TestDefaultValues(m_caller_sock);
}

TEST_F(TestSocketOptions, MaxVals)
{
// Note: Changing SRTO_FC changes SRTO_RCVBUF limitation
Expand Down Expand Up @@ -471,15 +570,15 @@ TEST_F(TestSocketOptions, InvalidVals)
const char* StateToStr(SRT_SOCKSTATUS st)
{
std::map<SRT_SOCKSTATUS, const char* const> st_to_str = {
{ SRTS_INIT, "SRTS_INIT" },
{ SRTS_OPENED, "SRTS_OPENED" },
{ SRTS_LISTENING, "SRTS_LISTENING" },
{ SRTS_INIT, "SRTS_INIT" },
{ SRTS_OPENED, "SRTS_OPENED" },
{ SRTS_LISTENING, "SRTS_LISTENING" },
{ SRTS_CONNECTING, "SRTS_CONNECTING" },
{ SRTS_CONNECTED, "SRTS_CONNECTED" },
{ SRTS_BROKEN, "SRTS_BROKEN" },
{ SRTS_CLOSING, "SRTS_CLOSING" },
{ SRTS_CLOSED, "SRTS_CLOSED" },
{ SRTS_NONEXIST, "SRTS_NONEXIST" }
{ SRTS_CONNECTED, "SRTS_CONNECTED" },
{ SRTS_BROKEN, "SRTS_BROKEN" },
{ SRTS_CLOSING, "SRTS_CLOSING" },
{ SRTS_CLOSED, "SRTS_CLOSED" },
{ SRTS_NONEXIST, "SRTS_NONEXIST" }
};

return st_to_str.find(st) != st_to_str.end() ? st_to_str.at(st) : "INVALID";
Expand Down Expand Up @@ -871,7 +970,7 @@ TEST_F(TestSocketOptions, StreamIDOdd)

EXPECT_EQ(srt_setsockopt(m_caller_sock, 0, SRTO_STREAMID, sid_odd.c_str(), (int)sid_odd.size()), SRT_SUCCESS);

array<char, CSrtConfig::MAX_SID_LENGTH + 135> buffer;
std::array<char, CSrtConfig::MAX_SID_LENGTH + 135> buffer;
auto buffer_len = (int) buffer.size();
EXPECT_EQ(srt_getsockopt(m_caller_sock, 0, SRTO_STREAMID, buffer.data(), &buffer_len), SRT_SUCCESS);
EXPECT_EQ(std::string(buffer.data()), sid_odd);
Expand Down
Loading