8#include "utils/HubDeviceSelect.hxx"
9#include "utils/async_if_test_helper.hxx"
13using ::testing::SaveArg;
14using ::testing::StrictMock;
22 MOCK_METHOD2(
send,
void(
const string &message,
unsigned priority));
31 "[sent] 0x%012" PRIx64
" -> %012" PRIx64
" MTI %03x payload %s",
33 string_to_hex(actual.
payload).c_str());
43 static int local_node_count;
65 EXPECT_CALL(listenPort_,
send(_, _)).WillOnce(SaveArg<0>(&
lastPacket_));
71 EXPECT_CALL(listenPort_,
send(_, _)).Times(AtLeast(0));
77 EXPECT_CALL(listenPort_,
send(_, _))
78 .WillRepeatedly(WithArg<0>(
79 Invoke([
this](
const string &d) {
allPackets_.push_back(d); })));
90 msg.reset(std::forward<Args>(args)...);
91 auto *b = device_.
alloc();
93 b->data()->skipMember_ = &listenPort_;
111 template <
typename... Args>
115 auto *b = f->
alloc();
116 b->data()->reset(std::forward<Args>(args)...);
121#define expect_packet_is(pkt, x...) \
126 EXPECT_TRUE(TcpDefs::parse_tcp_message(pkt, &actual)); \
127 GenMessage expected; \
129 EXPECT_EQ(expected.mti, actual.mti); \
130 EXPECT_EQ(expected.src, actual.src); \
131 EXPECT_EQ(expected.dst.id, actual.dst.id); \
132 EXPECT_EQ(expected.payload, actual.payload); \
142 template <
class NodeType = DefaultNode>
144 std::unique_ptr<NodeType> *p,
NodeID node_id,
IfTcp *iface =
nullptr)
153 Mock::VerifyAndClear(&listenPort_);
165 void wait_for_notification()
173 ::testing::StrictMock<MockHubPort> listenPort_;
179 static constexpr NodeID TEST_NODE_ID = 0x101212231225ULL;
180 static constexpr NodeID REMOTE_NODE_ID = 0x050902030405ULL;
181 static constexpr NodeID INPUT_GW_NODE_ID = 0x101112131415ULL;
182 static constexpr NodeID GW_NODE_ID = 0x101112131415ULL;
184 IfTcp ifTcp_{GW_NODE_ID, &device_, local_node_count};
187constexpr NodeID TcpIfTest::TEST_NODE_ID;
188constexpr NodeID TcpIfTest::REMOTE_NODE_ID;
189constexpr NodeID TcpIfTest::INPUT_GW_NODE_ID;
190constexpr NodeID TcpIfTest::GW_NODE_ID;
192int TcpIfTest::local_node_count = 9;
202 std::unique_ptr<DefaultNode> ownedNode_;
214 signal(SIGPIPE, SIG_IGN);
233 fcntl(fds_[0], F_GETFL, 0) | O_NONBLOCK));
235 fcntl(fds_[1], F_GETFL, 0) | O_NONBLOCK));
243 IfTcp ifTcp_{nodeId_, &device_, parent_->local_node_count};
246 void add_client(
NodeID node_id)
248 clients_.emplace_back(
new ClientIf(
this, node_id));
251 vector<std::unique_ptr<ClientIf>> clients_;
int fcntl(int fd, int cmd,...)
Manipulate a file descriptor.
ssize_t send(int socket, const void *buffer, size_t length, int flags)
Initiate transmission of a message from the specified socket.
A BarrierNotifiable allows to create a number of child Notifiable and wait for all of them to finish.
BarrierNotifiable * reset(Notifiable *done)
Resets the barrier. Returns &*this. Asserts that is_done().
Base class for all QMember types that hold data in an expandable format.
void unref()
Decrement count.
T * data()
get a pointer to the start of the data.
MessageType * alloc()
Synchronously allocates a message buffer from the pool of this flow.
void register_port(port_type *port)
Adds a new port.
void unregister_port(port_type *port)
Removes a previously added port.
A Notifiable for synchronously waiting for a notification.
void wait_for_notification()
Blocks the current thread until the notification is delivered.
void send(MessageType *msg, unsigned priority=UINT_MAX) OVERRIDE
Sends a message to the state flow for processing.
Trivial implementation of a virtual Node.
Network interface class for a character stream link that speaks the (point-to-point) TcpTransfer prot...
void add_network_fd(int fd, Notifiable *on_error=nullptr)
Adds a network client connection to the device.
MessageHandler * global_message_write_flow()
void send(Buffer< HubData > *b, unsigned priority) override
Entry point to the flow.
Base class for NMRAnet nodes conforming to the asynchronous interface.
static void render_tcp_message(const GenMessage &msg, NodeID gateway_node_id, long long sequence, string *tgt)
Renders a TCP message into a single buffer, ready to transmit.
static bool parse_tcp_message(const string &src, GenMessage *tgt)
Parses a TCP message format (from binary payload) into a general OpenLCB message.
void ignore_all_packets()
Instructs the mock device to ignore all sent packets.
void capture_next_packet()
Instructs the mock device to save the next sent packet.
void generate_output_message(Args &&... args)
Creates a GenMessage and sends it out via the IfTcp.
string lastPacket_
Stores the data from capture_next_packet.
void generate_output_message(IfTcp *iface, Args &&... args)
Creates a GenMessage and sends it out via the IfTcp.
void generate_input_message(Args &&... args)
Creates a GenMessage, renders it to binary format, and injects it as if it came as an input from the ...
void capture_all_packets()
Instructs the mock device to ignore all sent packets.
Node * create_new_node(std::unique_ptr< NodeType > *p, NodeID node_id, IfTcp *iface=nullptr)
Helper function to create a new virtual node.
vector< string > allPackets_
Stores data from capture all packets.
#define ERRNOCHECK(where, x...)
Calls the function x, and if the return value is negative, prints errno as error message to stderr an...
#define LOG(level, message...)
Conditionally write a message to the logging output.
static const int INFO
Loglevel that is printed by default, reporting some status information.
string node_id_to_buffer(NodeID id)
Convenience function to render a 48-bit NMRAnet node ID into a new buffer.
uint64_t NodeID
48-bit NMRAnet Node ID type
#define SOCK_STREAM
TCP Socket.
@ MTI_INITIALIZATION_COMPLETE
initialization complete
This class is used in the dispatching of incoming or outgoing NMRAnet messages to the message handler...
NodeHandle dst
Destination node.
NodeHandle src
Source node.
Defs::MTI mti
OpenLCB MTI of the incoming message.
string payload
Data content in the message body.
NodeID id
48-bit NMRAnet Node ID
void wait_for_main_executor()
Blocks the current thread until the main executor has run out of work.