Add simple Redis Server which is only capable of doing publish / subscribe. New ws redis_server sub-command to use it. The server is used in the unittest, so that we can run on CI in environment where redis isn not available like github actions env.

This commit is contained in:
Benjamin Sergeant
2019-09-23 21:04:01 -07:00
parent 8f8385f8f8
commit fbf80f4ab1
20 changed files with 497 additions and 27 deletions

View File

@ -4,13 +4,14 @@
* Copyright (c) 2017 Machine Zone. All rights reserved.
*/
#include <ixsnake/IXSnakeServer.h>
#include "IXTest.h"
#include "catch.hpp"
#include <chrono>
#include <iostream>
#include <ixcobra/IXCobraConnection.h>
#include <ixcrypto/IXUuid.h>
#include <ixsnake/IXRedisServer.h>
#include <ixsnake/IXSnakeServer.h>
using namespace ix;
@ -166,14 +167,6 @@ namespace
//
void SatoriChat::run()
{
snake::AppConfig appConfig = makeSnakeServerConfig(8008);
// Display config on the terminal for debugging
dumpConfig(appConfig);
snake::SnakeServer snakeServer(appConfig);
snakeServer.run();
// "chat" conf
std::string appkey("FC2F10139A2BAc53BB72D9db967b024f");
std::string channel = _session;
@ -186,12 +179,16 @@ namespace
_conn.setEventCallback([this, channel](ix::CobraConnectionEventType eventType,
const std::string& errMsg,
const ix::WebSocketHttpHeaders& /*headers*/,
const ix::WebSocketHttpHeaders& headers,
const std::string& subscriptionId,
CobraConnection::MsgId msgId) {
if (eventType == ix::CobraConnection_EventType_Open)
{
log("Subscriber connected: " + _user);
for (auto&& it : headers)
{
log("Headers " + it.first + " " + it.second);
}
}
else if (eventType == ix::CobraConnection_EventType_Authenticated)
{
@ -253,8 +250,6 @@ namespace
const ix::WebSocketHttpHeaders& /*headers*/,
const std::string& /*subscriptionId*/,
CobraConnection::MsgId /*msgId*/) { ; });
snakeServer.stop();
}
} // namespace
@ -264,6 +259,14 @@ TEST_CASE("Cobra_chat", "[cobra_chat]")
{
int port = getFreePort();
snake::AppConfig appConfig = makeSnakeServerConfig(port);
// Start a redis server
ix::RedisServer redisServer(appConfig.redisPort);
auto res = redisServer.listen();
REQUIRE(res.first);
redisServer.start();
// Start a snake server
snake::SnakeServer snakeServer(appConfig);
snakeServer.run();
@ -293,6 +296,7 @@ TEST_CASE("Cobra_chat", "[cobra_chat]")
if (timeout <= 0)
{
snakeServer.stop();
redisServer.stop();
REQUIRE(false); // timeout
}
}
@ -317,6 +321,7 @@ TEST_CASE("Cobra_chat", "[cobra_chat]")
if (timeout <= 0)
{
snakeServer.stop();
redisServer.stop();
REQUIRE(false); // timeout
}
}
@ -327,15 +332,18 @@ TEST_CASE("Cobra_chat", "[cobra_chat]")
chatA.stop();
chatB.stop();
// FIXME: improve this and make it exact matches
// we get unreliable result set
REQUIRE(chatA.getReceivedMessagesCount() == 2);
REQUIRE(chatB.getReceivedMessagesCount() == 3);
std::cout << incomingBytes << std::endl;
std::cout << "Incoming bytes: " << incomingBytes << std::endl;
std::cout << "Outgoing bytes: " << outgoingBytes << std::endl;
std::cerr << "Stopping snake server... ";
snakeServer.stop();
std::cerr << "OK" << std::endl;
std::cerr << "Stopping redis server... ";
redisServer.stop();
std::cerr << "OK" << std::endl;
}
}

View File

@ -8,6 +8,7 @@
#include <iostream>
#include <ixcobra/IXCobraMetricsPublisher.h>
#include <ixcrypto/IXUuid.h>
#include <ixsnake/IXRedisServer.h>
#include <ixsnake/IXSnakeServer.h>
#include <set>
@ -15,6 +16,23 @@ using namespace ix;
namespace
{
std::atomic<size_t> incomingBytes(0);
std::atomic<size_t> outgoingBytes(0);
void setupTrafficTrackerCallback()
{
ix::CobraConnection::setTrafficTrackerCallback([](size_t size, bool incoming) {
if (incoming)
{
incomingBytes += size;
}
else
{
outgoingBytes += size;
}
});
}
//
// This project / appkey is configure on cobra to not do any batching.
// This way we can start a subscriber and receive all messages as they come in.
@ -53,12 +71,16 @@ namespace
conn.setEventCallback([&conn](ix::CobraConnectionEventType eventType,
const std::string& errMsg,
const ix::WebSocketHttpHeaders& /*headers*/,
const ix::WebSocketHttpHeaders& headers,
const std::string& subscriptionId,
CobraConnection::MsgId msgId) {
if (eventType == ix::CobraConnection_EventType_Open)
{
Logger() << "Subscriber connected:";
for (auto&& it : headers)
{
log("Headers " + it.first + " " + it.second);
}
}
if (eventType == ix::CobraConnection_EventType_Error)
{
@ -123,9 +145,19 @@ TEST_CASE("Cobra_Metrics_Publisher", "[cobra]")
{
int port = getFreePort();
snake::AppConfig appConfig = makeSnakeServerConfig(port);
// Start a redis server
ix::RedisServer redisServer(appConfig.redisPort);
auto res = redisServer.listen();
REQUIRE(res.first);
redisServer.start();
// Start a snake server
snake::SnakeServer snakeServer(appConfig);
snakeServer.run();
setupTrafficTrackerCallback();
std::stringstream ss;
ss << "ws://localhost:" << port;
std::string endpoint = ss.str();
@ -147,6 +179,8 @@ TEST_CASE("Cobra_Metrics_Publisher", "[cobra]")
timeout -= 10;
if (timeout <= 0)
{
snakeServer.stop();
redisServer.stop();
REQUIRE(false); // timeout
}
}
@ -233,5 +267,14 @@ TEST_CASE("Cobra_Metrics_Publisher", "[cobra]")
CHECK(gIds.count("sms_set_rate_control_id") == 1);
CHECK(gIds.count("sms_set_blacklist_id") == 1);
std::cout << "Incoming bytes: " << incomingBytes << std::endl;
std::cout << "Outgoing bytes: " << outgoingBytes << std::endl;
std::cerr << "Stopping snake server... ";
snakeServer.stop();
std::cerr << "OK" << std::endl;
std::cerr << "Stopping redis server... ";
redisServer.stop();
std::cerr << "OK" << std::endl;
}

View File

@ -155,7 +155,7 @@ namespace ix
appConfig.port = port;
appConfig.hostname = "127.0.0.1";
appConfig.verbose = true;
appConfig.redisPort = 6379;
appConfig.redisPort = getFreePort();
appConfig.redisPassword = "";
appConfig.redisHosts.push_back("localhost"); // only one host supported now

View File

@ -6,9 +6,9 @@
#pragma once
#include <ixsnake/IXAppConfig.h>
#include "IXGetFreePort.h"
#include <iostream>
#include <ixsnake/IXAppConfig.h>
#include <ixwebsocket/IXWebSocketServer.h>
#include <mutex>
#include <spdlog/spdlog.h>