diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4bf5b784..dd47a970 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -39,6 +39,7 @@ set (SOURCES IXWebSocketPingTest.cpp IXWebSocketTestConnectionDisconnection.cpp IXUrlParserTest.cpp + IXWebSocketMessageQTest.cpp ) # Some unittest don't work on windows yet diff --git a/test/IXWebSocketMessageQTest.cpp b/test/IXWebSocketMessageQTest.cpp new file mode 100644 index 00000000..837efe15 --- /dev/null +++ b/test/IXWebSocketMessageQTest.cpp @@ -0,0 +1,186 @@ +/* + * IXWebSocketServerTest.cpp + * Author: Korchynskyi Dmytro + * Copyright (c) 2019 Machine Zone. All rights reserved. + */ + +#include +#include +#include + +#include "IXTest.h" +#include "catch.hpp" +#include + +using namespace ix; + +namespace +{ + bool startServer(ix::WebSocketServer& server) + { + server.setOnConnectionCallback( + [&server](std::shared_ptr webSocket, + std::shared_ptr connectionState) + { + webSocket->setOnMessageCallback( + [connectionState, &server](ix::WebSocketMessageType messageType, + const std::string & str, + size_t wireSize, + const ix::WebSocketErrorInfo & error, + const ix::WebSocketOpenInfo & openInfo, + const ix::WebSocketCloseInfo & closeInfo) + { + if (messageType == ix::WebSocketMessageType::Open) + { + Logger() << "New connection"; + connectionState->computeId(); + Logger() << "id: " << connectionState->getId(); + Logger() << "Uri: " << openInfo.uri; + Logger() << "Headers:"; + for (auto it : openInfo.headers) + { + Logger() << it.first << ": " << it.second; + } + } + else if (messageType == ix::WebSocketMessageType::Close) + { + Logger() << "Closed connection"; + } + else if (messageType == ix::WebSocketMessageType::Message) + { + Logger() << "Message received: " << str; + + for (auto&& client : server.getClients()) + { + client->send(str); + } + } + } + ); + } + ); + + auto res = server.listen(); + if (!res.first) + { + Logger() << res.second; + return false; + } + + server.start(); + return true; + } + + class MsgQTestClient + { + public: + MsgQTestClient() + { + msgQ.bindWebsocket(&ws); + + msgQ.setOnMessageCallback([this](WebSocketMessageType messageType, + const std::string & str, + size_t wireSize, + const WebSocketErrorInfo & error, + const WebSocketOpenInfo & openInfo, + const WebSocketCloseInfo & closeInfo) + { + REQUIRE(mainThreadId == std::this_thread::get_id()); + + std::stringstream ss; + if (messageType == WebSocketMessageType::Open) + { + log("client connected"); + sendNextMessage(); + } + else if (messageType == WebSocketMessageType::Close) + { + log("client disconnected"); + } + else if (messageType == WebSocketMessageType::Error) + { + ss << "Error ! " << error.reason; + log(ss.str()); + testDone = true; + } + else if (messageType == WebSocketMessageType::Pong) + { + ss << "Received pong message " << str; + log(ss.str()); + } + else if (messageType == WebSocketMessageType::Ping) + { + ss << "Received ping message " << str; + log(ss.str()); + } + else if (messageType == WebSocketMessageType::Message) + { + REQUIRE(str.compare("Hey dude!") == 0); + ++receivedCount; + ss << "Received message " << str; + log(ss.str()); + sendNextMessage(); + } + else + { + ss << "Invalid WebSocketMessageType"; + log(ss.str()); + testDone = true; + } + }); + } + + void sendNextMessage() + { + if (receivedCount >= 3) + { + testDone = true; + } + else + { + auto info = ws.sendText("Hey dude!"); + if (info.success) + log("sent message"); + else + log("send failed"); + } + } + + void run(const std::string& url) + { + mainThreadId = std::this_thread::get_id(); + testDone = false; + receivedCount = 0; + + ws.setUrl(url); + ws.start(); + + while (!testDone) + { + msgQ.poll(); + msleep(50); + } + } + + private: + WebSocket ws; + WebSocketMessageQueue msgQ; + bool testDone = false; + uint32_t receivedCount = 0; + std::thread::id mainThreadId; + }; +} + +TEST_CASE("Websocket_message_queue", "[websocket_message_q]") +{ + SECTION("Send several messages") + { + int port = getFreePort(); + WebSocketServer server(port); + REQUIRE(startServer(server)); + + MsgQTestClient testClient; + testClient.run("ws://127.0.0.1:" + std::to_string(port)); + } + +}