File size: 3,060 Bytes
f86fb3b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #include <gtest/gtest.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <thread>
#include <atomic>
#include "../include/gateway/io_reactor.hpp"
#include "../include/gateway/tcp_order_gateway.hpp"
using namespace quant::gateway;
using namespace quant::protocol;
using namespace quant::core;
TEST(NetworkGatewayTest, TCPOrderSubmissionAndExecution) {
IOReactor reactor;
constexpr uint16_t PORT = 19876;
TCPOrderGateway gateway(reactor, PORT);
std::atomic<bool> order_received{false};
NewOrderSinglePayload captured_order{};
gateway.set_callbacks(
[&](const NewOrderSinglePayload& ord, uint64_t, uint64_t) {
captured_order = ord;
order_received.store(true, std::memory_order_release);
},
nullptr
);
ASSERT_TRUE(gateway.start());
// Connect client socket
int client_fd = socket(AF_INET, SOCK_STREAM, 0);
ASSERT_GE(client_fd, 0);
sockaddr_in saddr{};
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
saddr.sin_port = htons(PORT);
int conn = connect(client_fd, reinterpret_cast<sockaddr*>(&saddr), sizeof(saddr));
ASSERT_EQ(conn, 0);
// Poll reactor so accept is handled
reactor.poll_events(50);
EXPECT_EQ(gateway.connected_clients_count(), 1);
// Client serializes and sends NewOrderSingle
NewOrderSinglePayload send_order{
1, 8888, Symbol("AAPL"),
static_cast<uint8_t>(Side::BUY),
static_cast<uint8_t>(OrderType::LIMIT),
1900000, 50
};
std::array<uint8_t, MAX_FRAME_SIZE> frame;
size_t len = BinaryProtocol::serialize_message(
std::span<uint8_t>(frame),
MessageType::NEW_ORDER_SINGLE,
1, 1000, send_order
);
ssize_t sent = send(client_fd, frame.data(), len, 0);
ASSERT_EQ(sent, static_cast<ssize_t>(len));
// Reactor polls and processes incoming message
for (int i = 0; i < 10 && !order_received.load(std::memory_order_acquire); ++i) {
reactor.poll_events(50);
}
EXPECT_TRUE(order_received.load());
EXPECT_EQ(captured_order.client_id, 1);
EXPECT_EQ(captured_order.client_order_id, 8888);
EXPECT_EQ(captured_order.symbol.view(), "AAPL");
EXPECT_EQ(captured_order.price_raw, 1900000);
EXPECT_EQ(captured_order.qty, 50);
// Gateway sends ExecutionReport back to client
ExecutionReportPayload exec_rep{
1, 8888, 10001, 1,
static_cast<uint8_t>(ExecType::NEW),
1900000, 0, 50, 0
};
EXPECT_TRUE(gateway.send_execution_report(exec_rep, 2));
// Read execution report from client socket
std::array<uint8_t, MAX_FRAME_SIZE> rx_buf;
ssize_t n = recv(client_fd, rx_buf.data(), rx_buf.size(), 0);
ASSERT_GT(n, 0);
auto hdr = BinaryProtocol::parse_header(std::span<const uint8_t>(rx_buf.data(), n));
ASSERT_TRUE(hdr.has_value());
EXPECT_EQ(hdr->msg_type, static_cast<uint8_t>(MessageType::EXECUTION_REPORT));
close(client_fd);
gateway.stop();
}
|