1
1
#define _CRT_RAND_S // For Windows, rand_s
2
2
3
3
#include <gtest/gtest.h>
4
+
#include <array>
4
5
#include <chrono>
5
6
#include <future>
7
+
#include <random>
6
8
7
9
#ifdef _WIN32
8
10
#include <stdlib.h>
@@ -49,40 +51,36 @@ class TestConnection
49
51
50
52
m_sa.sin_family = AF_INET;
51
53
m_sa.sin_addr.s_addr = INADDR_ANY;
52
-
m_udp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
53
-
ASSERT_NE(m_udp_sock, -1);
54
54
55
-
// Find unused a port not used by any other service.
56
-
// Otherwise srt_connect may actually connect.
57
-
int bind_res = -1;
55
+
m_server_sock = srt_create_socket();
56
+
ASSERT_NE(m_server_sock, SRT_INVALID_SOCK);
57
+
58
+
// Find a port not used by another service.
59
+
int bind_res = 0;
58
60
const sockaddr* psa = reinterpret_cast<const sockaddr*>(&m_sa);
59
-
for (int port = 5000; port <= 5555; ++port)
61
+
for (int port = 5000; port <= 5100; ++port)
60
62
{
61
63
m_sa.sin_port = htons(port);
62
-
bind_res = ::bind(m_udp_sock, psa, sizeof m_sa);
63
-
if (bind_res >= 0)
64
+
65
+
bind_res = srt_bind(m_server_sock, psa, sizeof m_sa);
66
+
if (bind_res == 0)
64
67
{
65
68
cerr << "Running test on port " << port << "\n";
66
69
break;
67
70
}
68
71
}
69
72
70
-
// Close the socket to free the port.
71
-
ASSERT_NE(closesocket(m_udp_sock), -1);
72
-
ASSERT_GE(bind_res, 0);
73
+
ASSERT_GE(bind_res, 0) << "srt_bind returned " << bind_res << ": " << srt_getlasterror_str();
73
74
ASSERT_EQ(inet_pton(AF_INET, "127.0.0.1", &m_sa.sin_addr), 1);
74
75
75
76
// Fill the buffer with random data
76
-
time_t now;
77
-
time(&now);
78
-
unsigned int randseed = now % 255;
79
-
srand(randseed);
80
-
for (int i = 0; i < SRT_LIVE_DEF_PLSIZE; ++i)
81
-
buf[i] = rand_r(&randseed) % 255;
77
+
std::random_device rnd_device;
78
+
std::mt19937 gen(rnd_device());
79
+
std::uniform_int_distribution<short> dis(-128, 127);
80
+
std::generate(m_buf.begin(), m_buf.end(), [dis, gen]() mutable { return (char)dis(gen); });
82
81
83
-
m_server_sock = srt_create_socket();
82
+
cout << "Generated: " << static_cast<int>(m_buf[0]) << ", " << static_cast<int>(m_buf[1]) << std::endl;
84
83
85
-
ASSERT_NE(srt_bind(m_server_sock, psa, sizeof m_sa), -1);
86
84
ASSERT_NE(srt_listen(m_server_sock, NSOCK), -1);
87
85
}
88
86
@@ -93,7 +91,6 @@ class TestConnection
93
91
94
92
void AcceptLoop()
95
93
{
96
-
//cerr << "[T] Accepting connections\n";
97
94
for (;;)
98
95
{
99
96
sockaddr_any addr;
@@ -102,18 +99,16 @@ class TestConnection
102
99
if (acp == -1)
103
100
{
104
101
cerr << "[T] Accept error at " << m_accepted.size()
105
-
<< "/" << NSOCK << ": " << srt_getlasterror_str() << endl;
102
+
<< "/" << NSOCK << ": " << srt_getlasterror_str() << endl;
106
103
break;
107
104
}
108
-
//cerr << "[T] Got new acp @" << acp << endl;
109
105
m_accepted.push_back(acp);
110
106
}
111
107
112
-
m_accept_exit = true;
113
-
114
108
cerr << "[T] Closing those accepted ones\n";
109
+
m_accept_exit = true;
115
110
116
-
for (auto s: m_accepted)
111
+
for (const auto s : m_accepted)
117
112
{
118
113
srt_close(s);
119
114
}
@@ -122,68 +117,65 @@ class TestConnection
122
117
}
123
118
124
119
protected:
125
-
SOCKET m_udp_sock = INVALID_SOCKET;
126
120
sockaddr_in m_sa = sockaddr_in();
127
121
SRTSOCKET m_server_sock = SRT_INVALID_SOCK;
128
122
vector<SRTSOCKET> m_accepted;
129
-
char buf[SRT_LIVE_DEF_PLSIZE];
130
-
SRTSOCKET srt_socket_list[NSOCK];
123
+
std::array<char, SRT_LIVE_DEF_PLSIZE> m_buf;
124
+
SRTSOCKET m_connections[NSOCK];
131
125
volatile bool m_accept_exit = false;
132
126
};
133
127
134
128
135
129
136
130
TEST_F(TestConnection, Multiple)
137
131
{
138
-
size_t size = SRT_LIVE_DEF_PLSIZE;
139
-
140
-
sockaddr_in lsa = m_sa;
141
-
132
+
const sockaddr_in lsa = m_sa;
142
133
const sockaddr* psa = reinterpret_cast<const sockaddr*>(&lsa);
143
134
144
135
auto ex = std::async([this] { return AcceptLoop(); });
145
136
146
-
cout << "Opening " << NSOCK << " connections\n";
137
+
cerr << "Opening " << NSOCK << " connections\n";
147
138
148
139
for (size_t i = 0; i < NSOCK; i++)
149
140
{
150
-
srt_socket_list[i] = srt_create_socket();
141
+
m_connections[i] = srt_create_socket();
142
+
EXPECT_NE(m_connections[i], SRT_INVALID_SOCK);
151
143
152
144
// Give it 60s timeout, many platforms fail to process
153
145
// so many connections in a short time.
154
146
int conntimeo = 60;
155
-
srt_setsockflag(srt_socket_list[i], SRTO_CONNTIMEO, &conntimeo, sizeof conntimeo);
147
+
srt_setsockflag(m_connections[i], SRTO_CONNTIMEO, &conntimeo, sizeof conntimeo);
156
148
157
149
//cerr << "Connecting #" << i << " to " << sockaddr_any(psa).str() << "...\n";
158
150
//cerr << "Connecting to: " << sockaddr_any(psa).str() << endl;
159
-
ASSERT_NE(srt_connect(srt_socket_list[i], psa, sizeof lsa), SRT_ERROR);
151
+
ASSERT_NE(srt_connect(m_connections[i], psa, sizeof lsa), SRT_ERROR);
160
152
161
153
// Set now async sending so that sending isn't blocked
162
154
int no = 0;
163
-
ASSERT_NE(srt_setsockflag(srt_socket_list[i], SRTO_SNDSYN, &no, sizeof no), -1);
155
+
ASSERT_NE(srt_setsockflag(m_connections[i], SRTO_SNDSYN, &no, sizeof no), -1);
164
156
}
165
157
166
158
for (size_t j = 1; j <= 100; j++)
167
159
{
168
160
for (size_t i = 0; i < NSOCK; i++)
169
161
{
170
-
EXPECT_GT(srt_send(srt_socket_list[i], buf, size), 0);
162
+
EXPECT_GT(srt_send(m_connections[i], m_buf.data(), (int) m_buf.size()), 0);
171
163
}
172
164
}
173
-
cout << "Sending finished, closing caller sockets\n";
165
+
cerr << "Sending finished, closing caller sockets\n";
174
166
175
167
for (size_t i = 0; i < NSOCK; i++)
176
168
{
177
-
EXPECT_EQ(srt_close(srt_socket_list[i]), SRT_SUCCESS);
169
+
EXPECT_EQ(srt_close(m_connections[i]), SRT_SUCCESS);
178
170
}
179
-
// Up to this moment the server sock should survive
180
-
cout << "Closing server socket\n";
181
-
182
-
EXPECT_EQ(m_accept_exit, false);
183
171
172
+
EXPECT_FALSE(m_accept_exit) << "AcceptLoop already broken for some reason!";
173
+
// Up to this moment the server sock should survive
174
+
cerr << "Closing server socket\n";
184
175
// Close server socket to break the accept loop
185
176
EXPECT_EQ(srt_close(m_server_sock), 0);
186
177
178
+
cerr << "Synchronize with the accepting thread\n";
187
179
ex.wait();
188
180
}
189
181
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4