Skip to content

Commit

Permalink
[tests] Added epoll NotifyConnectionBreak test
Browse files Browse the repository at this point in the history
  • Loading branch information
maxsharabayko authored and rndi committed May 31, 2019
1 parent 6f6b76b commit 0c7d994
Showing 1 changed file with 117 additions and 0 deletions.
117 changes: 117 additions & 0 deletions test/test_epoll.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#include <chrono>
#include <future>
#include <thread>
#include "gtest/gtest.h"
#include "api.h"
#include "epoll.h"
Expand Down Expand Up @@ -230,3 +233,117 @@ TEST(CEPoll, HandleEpollEvent)

EXPECT_EQ(srt_cleanup(), 0);
}



// In this test case a caller connects to a listener on a localhost.
// Then the caller closes the connection, and listener is expected to
// be notified about connection break via polling the accepted socket.
TEST(CEPoll, NotifyConnectionBreak)
{
ASSERT_EQ(srt_startup(), 0);

// 1. Prepare client
SRTSOCKET client_sock = srt_socket(AF_INET, SOCK_DGRAM, 0);
ASSERT_NE(client_sock, SRT_ERROR);

const int yes = 1;
const int no = 0;
ASSERT_NE(srt_setsockopt(client_sock, 0, SRTO_RCVSYN, &no, sizeof no), SRT_ERROR); // for async connect
ASSERT_NE(srt_setsockopt(client_sock, 0, SRTO_SNDSYN, &no, sizeof no), SRT_ERROR); // for async connect

const int client_epoll_id = srt_epoll_create();
ASSERT_GE(client_epoll_id, 0);

const int epoll_out = SRT_EPOLL_OUT | SRT_EPOLL_ERR;
/* We intentionally pass the wrong socket ID. The error should be returned.*/
EXPECT_EQ(srt_epoll_add_usock(client_epoll_id, client_sock, &epoll_out), SRT_SUCCESS);

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

// 2. Prepare server
SRTSOCKET server_sock = srt_socket(AF_INET, SOCK_DGRAM, 0);
ASSERT_NE(server_sock, SRT_ERROR);

ASSERT_NE(srt_setsockopt(server_sock, 0, SRTO_RCVSYN, &no, sizeof no), SRT_ERROR); // for async connect
ASSERT_NE(srt_setsockopt(server_sock, 0, SRTO_SNDSYN, &no, sizeof no), SRT_ERROR); // for async connect

const int server_epoll_id = srt_epoll_create();
ASSERT_GE(server_epoll_id, 0);

int epoll_mode = SRT_EPOLL_IN | SRT_EPOLL_ERR;
srt_epoll_add_usock(server_epoll_id, server_sock, &epoll_mode);

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

srt_bind(server_sock, (sockaddr*)& sa, sizeof(sa));
srt_listen(server_sock, 1);


auto connect_res = std::async(std::launch::async, [&client_sock, &sa]() {
return srt_connect(client_sock, (sockaddr*)& sa, sizeof(sa));
});


const int default_len = 3;
int rlen = default_len;
SRTSOCKET read[default_len];
int wlen = default_len;
SRTSOCKET write[default_len];
// Wait on epoll for connection
const int epoll_res = srt_epoll_wait(server_epoll_id, read, &rlen,
write, &wlen,
5000, /* timeout */
0, 0, 0, 0);

EXPECT_EQ(epoll_res, 1);
if (epoll_res == SRT_ERROR)
{
std::cerr << "Epoll returned error: " << srt_getlasterror_str() << " (code " << srt_getlasterror(NULL) << ")\n";
}

// Wait for the caller connection thread to return connection result
EXPECT_EQ(connect_res.get(), SRT_SUCCESS);

sockaddr_in scl;
int sclen = sizeof scl;
SRTSOCKET sock = srt_accept(server_sock, (sockaddr*)& scl, &sclen);
EXPECT_NE(sock, SRT_INVALID_SOCK);

int epoll_io = srt_epoll_create();
int modes = SRT_EPOLL_IN | SRT_EPOLL_OUT | SRT_EPOLL_ERR;
EXPECT_NE(srt_epoll_add_usock(epoll_io, sock, &modes), SRT_ERROR);

// The caller will close connection after 1 second
auto close_res = std::async(std::launch::async, [&client_sock]() {
this_thread::sleep_for(chrono::seconds(1));
cout << "Closing client connection\n";
return srt_close(client_sock);
});

int timeout_ms = -1;
int ready[2] = { SRT_INVALID_SOCK, SRT_INVALID_SOCK };
int len = 2;
const int epoll_wait_res = srt_epoll_wait(epoll_io, ready, &len, nullptr, nullptr, timeout_ms, 0, 0, 0, 0);
if (epoll_wait_res == SRT_ERROR)
cerr << "socket::read::epoll " << to_string(srt_getlasterror(nullptr));
EXPECT_EQ(epoll_wait_res, 1);
EXPECT_EQ(len, 1);
EXPECT_EQ(ready[0], sock);

// Wait for the caller to close connection
// There should be no wait, as epoll should wait untill connection is closed.
EXPECT_EQ(close_res.get(), SRT_SUCCESS);
EXPECT_EQ(srt_getsockstate(sock), SRTS_BROKEN);

EXPECT_EQ(srt_cleanup(), 0);
}

0 comments on commit 0c7d994

Please sign in to comment.