Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright chargebyte GmbH and Contributors to EVerest
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <thread>
|
||||
|
||||
#include "../helpers/WebSocketTestClient.hpp"
|
||||
#include "../server/WebsocketServer.hpp"
|
||||
|
||||
using namespace server;
|
||||
|
||||
class WebSocketServerTest : public ::testing::Test {
|
||||
protected:
|
||||
std::unique_ptr<WebSocketServer> ws_server;
|
||||
int test_port = 8080;
|
||||
|
||||
void SetUp() override {
|
||||
ws_server = std::make_unique<WebSocketServer>(false, test_port, "lo");
|
||||
lws_set_log_level(LLL_ERR | LLL_WARN, NULL);
|
||||
|
||||
ws_server->on_client_connected = [this](const TransportInterface::ClientId& client_id,
|
||||
const server::TransportInterface::Address& address) {
|
||||
// Handle client connected logic here
|
||||
std::lock_guard<std::mutex> lock(cv_mutex);
|
||||
try {
|
||||
connected_clients.push_back(client_id);
|
||||
} catch (const std::exception& e) {
|
||||
EVLOG_error << "Exception occurred while handling client connected: " << e.what();
|
||||
}
|
||||
};
|
||||
|
||||
ws_server->on_client_disconnected = [this](const TransportInterface::ClientId& client_id) {
|
||||
// Handle client disconnected logic here
|
||||
std::lock_guard<std::mutex> lock(cv_mutex);
|
||||
try {
|
||||
connected_clients.erase(std::remove(connected_clients.begin(), connected_clients.end(), client_id),
|
||||
connected_clients.end());
|
||||
} catch (const std::exception& e) {
|
||||
EVLOG_error << "Exception occurred while handling client disconnected: " << e.what();
|
||||
}
|
||||
};
|
||||
|
||||
ws_server->on_data_available = [this](const TransportInterface::ClientId& client_id,
|
||||
const server::TransportInterface::Data& data) {
|
||||
// Handle data available logic here
|
||||
std::lock_guard<std::mutex> lock(cv_mutex);
|
||||
try {
|
||||
received_data[client_id] = std::string(data.begin(), data.end());
|
||||
cv.notify_all();
|
||||
} catch (const std::exception& e) {
|
||||
EVLOG_error << "Exception occurred while handling data available: " << e.what();
|
||||
}
|
||||
};
|
||||
|
||||
ws_server->start_server();
|
||||
}
|
||||
|
||||
std::vector<TransportInterface::ClientId>& get_connected_clients() {
|
||||
std::lock_guard<std::mutex> lock(cv_mutex);
|
||||
return connected_clients;
|
||||
}
|
||||
|
||||
// Connected client id's
|
||||
std::vector<TransportInterface::ClientId> connected_clients;
|
||||
|
||||
// Condition variable to wait requests
|
||||
std::condition_variable cv;
|
||||
std::mutex cv_mutex;
|
||||
|
||||
// Received data with client id
|
||||
std::unordered_map<TransportInterface::ClientId, std::string> received_data;
|
||||
|
||||
void TearDown() override {
|
||||
ws_server->stop_server();
|
||||
}
|
||||
};
|
||||
|
||||
// Test: Start and stop WebSocket server
|
||||
TEST_F(WebSocketServerTest, WebSocketServerStarts) {
|
||||
ASSERT_TRUE(ws_server->running());
|
||||
TearDown();
|
||||
ASSERT_FALSE(ws_server->running());
|
||||
}
|
||||
|
||||
// Test: Connect WebSocket client to server
|
||||
TEST_F(WebSocketServerTest, ClientCanConnect) {
|
||||
WebSocketTestClient client("localhost", test_port);
|
||||
ASSERT_TRUE(client.connect());
|
||||
ASSERT_TRUE(client.wait_until_connected(std::chrono::milliseconds(100)));
|
||||
}
|
||||
|
||||
// Test: Connect several WebSocket clients to server
|
||||
TEST_F(WebSocketServerTest, MultipleClientsCanConnect) {
|
||||
WebSocketTestClient client1("localhost", test_port);
|
||||
WebSocketTestClient client2("localhost", test_port);
|
||||
WebSocketTestClient client3("localhost", test_port);
|
||||
|
||||
ASSERT_TRUE(client1.connect());
|
||||
ASSERT_TRUE(client2.connect());
|
||||
ASSERT_TRUE(client3.connect());
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
ASSERT_TRUE(client1.is_connected());
|
||||
ASSERT_TRUE(client2.is_connected());
|
||||
ASSERT_TRUE(client3.is_connected());
|
||||
|
||||
ASSERT_TRUE(ws_server->connections_count() == 3);
|
||||
}
|
||||
|
||||
// Test: Client can send data to server
|
||||
TEST_F(WebSocketServerTest, ClientCanSendAndReceiveData) {
|
||||
WebSocketTestClient client("localhost", test_port);
|
||||
ASSERT_TRUE(client.connect());
|
||||
ASSERT_TRUE(client.wait_until_connected(std::chrono::milliseconds(100)));
|
||||
|
||||
client.send("Hello World!");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
std::unique_lock<std::mutex> lock(cv_mutex);
|
||||
cv.wait_for(lock, std::chrono::seconds(1), [&] { return !received_data.empty(); });
|
||||
lock.unlock();
|
||||
|
||||
ASSERT_EQ(ws_server->connections_count(), 1);
|
||||
ASSERT_EQ(received_data[(get_connected_clients()[0])], "Hello World!");
|
||||
}
|
||||
|
||||
// Test: Server can send data to client
|
||||
TEST_F(WebSocketServerTest, ServerCanSendDataToClient) {
|
||||
WebSocketTestClient client("localhost", test_port);
|
||||
ASSERT_TRUE(client.connect());
|
||||
ASSERT_TRUE(client.wait_until_connected(std::chrono::milliseconds(100)));
|
||||
|
||||
std::string message = "Hello from server!";
|
||||
ws_server->send_data(get_connected_clients()[0], std::vector<uint8_t>(message.begin(), message.end()));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
std::string received_data = client.wait_for_data(std::chrono::seconds(1), false);
|
||||
|
||||
ASSERT_FALSE(received_data.empty());
|
||||
ASSERT_EQ(received_data, "Hello from server!");
|
||||
}
|
||||
|
||||
// Test: Server kills client connection
|
||||
TEST_F(WebSocketServerTest, ServerCanKillClientConnection) {
|
||||
WebSocketTestClient client("localhost", test_port);
|
||||
ASSERT_TRUE(client.connect());
|
||||
ASSERT_TRUE(client.wait_until_connected(std::chrono::milliseconds(100)));
|
||||
|
||||
client.send("Hello World!");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
client.wait_for_data(std::chrono::seconds(1));
|
||||
|
||||
ASSERT_EQ(ws_server->connections_count(), 1);
|
||||
ASSERT_EQ(received_data[get_connected_clients()[0]], "Hello World!");
|
||||
|
||||
ws_server->kill_client_connection(get_connected_clients()[0], "Test kill");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
ASSERT_EQ(ws_server->connections_count(), 0);
|
||||
ASSERT_FALSE(client.is_connected());
|
||||
}
|
||||
Reference in New Issue
Block a user