9 #include <boost/test/unit_test.hpp> 16 create_mold_udp_packet(std::uint64_t sequence_number,
int message_count) {
17 std::size_t
const max_packet_size = 1 << 16;
18 char packet[max_packet_size] = {0};
21 max_packet_size, packet,
28 boost::asio::mutable_buffer dst(packet, packet_size);
32 for (
int i = 0; i != message_count; ++i) {
38 max_packet_size, packet, packet_size, message.size());
40 boost::asio::buffer_copy(dst + packet_size, boost::asio::buffer(message));
41 packet_size += message.size();
43 return std::vector<char>(packet, packet + packet_size);
61 std::string select_localhost_address(boost::asio::io_service& io) {
62 for (
auto const& addr : {
"::1",
"127.0.0.1"}) {
64 BOOST_TEST_CHECKPOINT(
"Checking " << addr <<
" as the localhost address");
71 BOOST_TEST_MESSAGE(
"No valid localhost address found, aborting");
72 throw std::runtime_error(
"Cannot find valid IPv6 or IPv4 address");
87 boost::asio::error::make_error_code(boost::asio::error::network_down),
99 struct mock_function {
103 std::size_t, std::string, std::size_t));
106 auto adapter = [&mock](
108 std::size_t offset,
char const* msg, std::size_t msgsize) {
109 mock.method(ts, seqno, offset, std::string(msg, msgsize), msgsize);
112 using boost::asio::ip::udp;
114 boost::asio::io_service io;
115 auto local = select_localhost_address(io);
116 BOOST_TEST_MESSAGE(
"Running test on " << local);
121 udp::resolver resolver(io);
122 udp::endpoint send_to;
123 udp::endpoint send_from;
124 auto d_address = boost::asio::ip::address::from_string(local);
125 if (d_address.is_v6()) {
126 BOOST_TEST_CHECKPOINT(
127 "Resolving dst/src IPv6 addresses for " << local <<
":50000");
128 send_to = *resolver.resolve({udp::v6(), local,
"50000"});
129 send_from = udp::endpoint(udp::v6(), 0);
131 BOOST_TEST_CHECKPOINT(
132 "Resolving dst/src IPv4 addresses for " << local <<
":50000");
133 send_to = *resolver.resolve({udp::v4(), local,
"50000"});
134 send_from = udp::endpoint(udp::v4(), 0);
136 udp::socket socket(io, send_from);
138 using namespace ::testing;
139 EXPECT_CALL(mock, method(_, _, _, _, _)).Times(3);
140 auto packet = create_mold_udp_packet(0, 3);
141 socket.send_to(boost::asio::buffer(packet), send_to);
144 EXPECT_CALL(mock, method(_, _, _, _, _)).Times(3);
145 packet = create_mold_udp_packet(0, 3);
146 socket.send_to(boost::asio::buffer(packet), send_to);
149 EXPECT_CALL(mock, method(_, _, _, _, _)).Times(2);
150 packet = create_mold_udp_packet(9, 2);
151 socket.send_to(boost::asio::buffer(packet), send_to);
154 EXPECT_CALL(mock, method(_, _, _, _, _)).Times(1);
155 packet = create_mold_udp_packet(12, 1);
156 socket.send_to(boost::asio::buffer(packet), send_to);
159 EXPECT_CALL(mock, method(_, _, _, _, _)).Times(0);
160 packet = create_mold_udp_packet(13, 0);
161 socket.send_to(boost::asio::buffer(packet), send_to);
171 std::size_t offset,
char const* msg, std::size_t msgsize) {};
173 using boost::asio::ip::udp;
175 boost::asio::io_service io;
176 auto local = select_localhost_address(io);
clock_type::time_point time_point
A convenience alias for clock_type::time_point.
static void w(std::size_t size, void *msg, std::size_t offset, T const &x)
Write a single message or field to a buffer.
socket_t make_socket_udp_recv(boost::asio::io_service &io, udp_receiver_config const &cfg)
Create a socket given the configuration parameters.
std::function< void(std::chrono::steady_clock::time_point, std::uint64_t, std::size_t, char const *, std::size_t)> buffer_handler
A callback function type to process any received ITCH-5.0 messages.
static void call_with_error_code(mold_udp_channel &tested)
constexpr std::size_t sequence_number_offset
The location of the sequence number field within the header.
BOOST_AUTO_TEST_CASE(itch5_mold_udp_channel_basic)
void handle_received(boost::system::error_code const &ec, size_t bytes_received)
The Boost.ASIO callback for I/O events.
Break encapsulation in jb::itch5::mold_udp_channel for testing purposes.
Represent a ITCH-5.0 timestamp.
std::vector< char > create_message(int message_type, jb::itch5::timestamp ts, std::size_t total_size)
Generate test messages with a more-or-less valid header.
Initialize GMock to work with Boost.Test.
static void call_with_empty_packet(mold_udp_channel &tested)
constexpr std::size_t header_size
The total size of the MoldUDP64 header.
constexpr std::size_t block_count_offset
The location of the block count field within the header.
A configuration object for UDP receivers.
Create and manage a socket to receive MoldUDP64 packets.
The top-level namespace for the JayBeams library.