use dynamically generated port number to configure servers in unittest
This commit is contained in:
parent
7eaea28970
commit
8983dd97a1
@ -5,5 +5,5 @@ compiler:
|
|||||||
- clang
|
- clang
|
||||||
# - gcc
|
# - gcc
|
||||||
|
|
||||||
# os: osx
|
# os: osx
|
||||||
script: make test
|
script: python test/run.py
|
||||||
|
@ -156,7 +156,9 @@ namespace ix
|
|||||||
_onCloseCallback = onCloseCallback;
|
_onCloseCallback = onCloseCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketTransport::exceedSendHeartBeatTimeOut()
|
// Only consider send time points for that computation.
|
||||||
|
// The receive time points is taken into account in Socket::poll (second parameter).
|
||||||
|
bool WebSocketTransport::heartBeatPeriodExceeded()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_lastSendTimePointMutex);
|
std::lock_guard<std::mutex> lock(_lastSendTimePointMutex);
|
||||||
auto now = std::chrono::steady_clock::now();
|
auto now = std::chrono::steady_clock::now();
|
||||||
@ -172,7 +174,7 @@ namespace ix
|
|||||||
// send for a duration exceeding our heart-beat period, send a
|
// send for a duration exceeding our heart-beat period, send a
|
||||||
// ping to the server.
|
// ping to the server.
|
||||||
if (pollResult == PollResultType_Timeout &&
|
if (pollResult == PollResultType_Timeout &&
|
||||||
exceedSendHeartBeatTimeOut())
|
heartBeatPeriodExceeded())
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << kHeartBeatPingMessage << "::" << _heartBeatPeriod << "s";
|
ss << kHeartBeatPingMessage << "::" << _heartBeatPeriod << "s";
|
||||||
|
@ -126,7 +126,7 @@ namespace ix
|
|||||||
std::chrono::time_point<std::chrono::steady_clock> _lastSendTimePoint;
|
std::chrono::time_point<std::chrono::steady_clock> _lastSendTimePoint;
|
||||||
|
|
||||||
// No data was send through the socket for longer that the hearbeat period
|
// No data was send through the socket for longer that the hearbeat period
|
||||||
bool exceedSendHeartBeatTimeOut();
|
bool heartBeatPeriodExceeded();
|
||||||
|
|
||||||
void sendOnSocket();
|
void sendOnSocket();
|
||||||
WebSocketSendInfo sendData(wsheader_type::opcode_type type,
|
WebSocketSendInfo sendData(wsheader_type::opcode_type type,
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "IXTest.h"
|
#include "IXTest.h"
|
||||||
#include <ixwebsocket/IXWebSocket.h>
|
#include <ixwebsocket/IXWebSocket.h>
|
||||||
|
#include <ixwebsocket/IXNetSystem.h>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -14,12 +15,14 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
std::atomic<size_t> incomingBytes(0);
|
std::atomic<size_t> incomingBytes(0);
|
||||||
std::atomic<size_t> outgoingBytes(0);
|
std::atomic<size_t> outgoingBytes(0);
|
||||||
std::mutex Logger::_mutex;
|
std::mutex Logger::_mutex;
|
||||||
|
std::stack<int> freePorts;
|
||||||
|
|
||||||
void setupWebSocketTrafficTrackerCallback()
|
void setupWebSocketTrafficTrackerCallback()
|
||||||
{
|
{
|
||||||
@ -66,4 +69,52 @@ namespace ix
|
|||||||
Logger() << msg;
|
Logger() << msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getFreePort()
|
||||||
|
{
|
||||||
|
int defaultPort = 8090;
|
||||||
|
|
||||||
|
int sockfd;
|
||||||
|
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||||
|
{
|
||||||
|
log("Cannot compute a free port. socket error.");
|
||||||
|
return defaultPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
int enable = 1;
|
||||||
|
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
|
||||||
|
(char*) &enable, sizeof(enable)) < 0)
|
||||||
|
{
|
||||||
|
log("Cannot compute a free port. setsockopt error.");
|
||||||
|
return defaultPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind to port 0. This is the standard way to get a free port.
|
||||||
|
struct sockaddr_in server; // server address information
|
||||||
|
server.sin_family = AF_INET;
|
||||||
|
server.sin_port = htons(0);
|
||||||
|
server.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
|
|
||||||
|
if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
|
||||||
|
{
|
||||||
|
log("Cannot compute a free port. bind error.");
|
||||||
|
|
||||||
|
::close(sockfd);
|
||||||
|
return defaultPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in sa; // server address information
|
||||||
|
unsigned int len;
|
||||||
|
if (getsockname(sockfd, (struct sockaddr *) &sa, &len) < 0)
|
||||||
|
{
|
||||||
|
log("Cannot compute a free port. getsockname error.");
|
||||||
|
|
||||||
|
::close(sockfd);
|
||||||
|
return defaultPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
int port = ntohs(sa.sin_port);
|
||||||
|
::close(sockfd);
|
||||||
|
|
||||||
|
return port;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,4 +51,7 @@ namespace ix
|
|||||||
};
|
};
|
||||||
|
|
||||||
void log(const std::string& msg);
|
void log(const std::string& msg);
|
||||||
|
|
||||||
|
bool computeFreePorts(int count);
|
||||||
|
int getFreePort();
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ TEST_CASE("Websocket_heartbeat", "[heartbeat]")
|
|||||||
{
|
{
|
||||||
ix::setupWebSocketTrafficTrackerCallback();
|
ix::setupWebSocketTrafficTrackerCallback();
|
||||||
|
|
||||||
int port = 8093;
|
int port = getFreePort();
|
||||||
ix::WebSocketServer server(port);
|
ix::WebSocketServer server(port);
|
||||||
std::atomic<int> serverReceivedPingMessages(0);
|
std::atomic<int> serverReceivedPingMessages(0);
|
||||||
REQUIRE(startServer(server, serverReceivedPingMessages));
|
REQUIRE(startServer(server, serverReceivedPingMessages));
|
||||||
|
@ -75,7 +75,7 @@ TEST_CASE("Websocket_server", "[websocket_server]")
|
|||||||
{
|
{
|
||||||
SECTION("Connect to the server, do not send anything. Should timeout and return 400")
|
SECTION("Connect to the server, do not send anything. Should timeout and return 400")
|
||||||
{
|
{
|
||||||
int port = 8091;
|
int port = getFreePort();
|
||||||
ix::WebSocketServer server(port);
|
ix::WebSocketServer server(port);
|
||||||
REQUIRE(startServer(server));
|
REQUIRE(startServer(server));
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ TEST_CASE("Websocket_server", "[websocket_server]")
|
|||||||
|
|
||||||
SECTION("Connect to the server. Send GET request without header. Should return 400")
|
SECTION("Connect to the server. Send GET request without header. Should return 400")
|
||||||
{
|
{
|
||||||
int port = 8092;
|
int port = getFreePort();
|
||||||
ix::WebSocketServer server(port);
|
ix::WebSocketServer server(port);
|
||||||
REQUIRE(startServer(server));
|
REQUIRE(startServer(server));
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ TEST_CASE("Websocket_server", "[websocket_server]")
|
|||||||
|
|
||||||
SECTION("Connect to the server. Send GET request with correct header")
|
SECTION("Connect to the server. Send GET request with correct header")
|
||||||
{
|
{
|
||||||
int port = 8093;
|
int port = getFreePort();
|
||||||
ix::WebSocketServer server(port);
|
ix::WebSocketServer server(port);
|
||||||
REQUIRE(startServer(server));
|
REQUIRE(startServer(server));
|
||||||
|
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
* Copyright (c) 2017 Machine Zone. All rights reserved.
|
* Copyright (c) 2017 Machine Zone. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Simple chat program that talks to the node.js server at
|
||||||
|
// websocket_chat_server/broacast-server.js
|
||||||
|
//
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@ -24,7 +29,8 @@ namespace
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WebSocketChat(const std::string& user,
|
WebSocketChat(const std::string& user,
|
||||||
const std::string& session);
|
const std::string& session,
|
||||||
|
int port);
|
||||||
|
|
||||||
void subscribe(const std::string& channel);
|
void subscribe(const std::string& channel);
|
||||||
void start();
|
void start();
|
||||||
@ -40,6 +46,7 @@ namespace
|
|||||||
private:
|
private:
|
||||||
std::string _user;
|
std::string _user;
|
||||||
std::string _session;
|
std::string _session;
|
||||||
|
int _port;
|
||||||
|
|
||||||
ix::WebSocket _webSocket;
|
ix::WebSocket _webSocket;
|
||||||
|
|
||||||
@ -47,9 +54,11 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
WebSocketChat::WebSocketChat(const std::string& user,
|
WebSocketChat::WebSocketChat(const std::string& user,
|
||||||
const std::string& session) :
|
const std::string& session,
|
||||||
|
int port) :
|
||||||
_user(user),
|
_user(user),
|
||||||
_session(session)
|
_session(session),
|
||||||
|
_port(port)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -71,7 +80,16 @@ namespace
|
|||||||
|
|
||||||
void WebSocketChat::start()
|
void WebSocketChat::start()
|
||||||
{
|
{
|
||||||
std::string url("ws://localhost:8090/");
|
std::string url;
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "ws://localhost:"
|
||||||
|
<< _port
|
||||||
|
<< "/";
|
||||||
|
|
||||||
|
url = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
_webSocket.setUrl(url);
|
_webSocket.setUrl(url);
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@ -226,8 +244,8 @@ TEST_CASE("Websocket_chat", "[websocket_chat]")
|
|||||||
REQUIRE(startServer(server));
|
REQUIRE(startServer(server));
|
||||||
|
|
||||||
std::string session = ix::generateSessionId();
|
std::string session = ix::generateSessionId();
|
||||||
WebSocketChat chatA("jean", session);
|
WebSocketChat chatA("jean", session, port);
|
||||||
WebSocketChat chatB("paul", session);
|
WebSocketChat chatB("paul", session, port);
|
||||||
|
|
||||||
chatA.start();
|
chatA.start();
|
||||||
chatB.start();
|
chatB.start();
|
||||||
|
@ -34,6 +34,10 @@ if osName == 'Linux':
|
|||||||
|
|
||||||
sanitizerFlags = sanitizersFlags[sanitizer]
|
sanitizerFlags = sanitizersFlags[sanitizer]
|
||||||
|
|
||||||
|
# if osName == 'Windows':
|
||||||
|
# os.environ['CC'] = 'clang-cl'
|
||||||
|
# os.environ['CXX'] = 'clang-cl'
|
||||||
|
|
||||||
cmakeCmd = 'cmake -DCMAKE_BUILD_TYPE=Debug {} {} ..'.format(generator, sanitizerFlags)
|
cmakeCmd = 'cmake -DCMAKE_BUILD_TYPE=Debug {} {} ..'.format(generator, sanitizerFlags)
|
||||||
print(cmakeCmd)
|
print(cmakeCmd)
|
||||||
ret = os.system(cmakeCmd)
|
ret = os.system(cmakeCmd)
|
||||||
|
Loading…
Reference in New Issue
Block a user