src.dualinventive.com/jjacobs/dinetrpcll-sniffer/libdi/tests/can_net_node_events.cpp

141 lines
4.7 KiB
C++

/**
* @file tests/can_net_node_events.cpp
* @brief CAN Net node events (for application)
* @date Dec 14, 2016
* @author jjacobs
* @copyright 2016 Dual Inventive Technology Centre B.V.
*/
#include "fixtures/CANTest.hpp"
/**
* Verify if the correct node role events are emitted
* We fake a node on the network which publishes its type/role using the heartbeat publish message
*/
void net_node_events_event_cb(const struct di_can_net *ctx,
const enum di_can_net_node_events ev,
const struct di_can_net_node *node)
{
(void)ctx;
static size_t idx = 0;
static const struct _tv {
const enum di_can_net_node_events ev;
const enum di_can_net_node_roles role;
} tv[] = {
// The NEW and PASSIVE events are emitted by the new node detection
{ DI_CAN_NET_NODE_EVENT_NEW, DI_CAN_NET_NODE_ROLE_PASSIVE },
{ DI_CAN_NET_NODE_EVENT_ROLE_PASSIVE, DI_CAN_NET_NODE_ROLE_PASSIVE },
// Node transition events PASSIVE -> FOLLOWER-> LEADER
{ DI_CAN_NET_NODE_EVENT_ROLE_FOLLOWER, DI_CAN_NET_NODE_ROLE_PASSIVE },
{ DI_CAN_NET_NODE_EVENT_ROLE_LEADER, DI_CAN_NET_NODE_ROLE_FOLLOWER }
};
printf("event[%zu](%d): node: %04x, type: %02x, role: %02x\n", idx, ev, node->nodeid, node->type, node->role);
ASSERT_EQ(0xcafebabe, node->nodeid);
ASSERT_EQ(DI_CAN_NET_NODE_TYPE_UNKNOWN, node->type);
ASSERT_GT(DI_ARRAY_SIZE(tv), idx);
ASSERT_EQ(node->role, tv[idx].role);
ASSERT_EQ(ev, tv[idx].ev);
idx++;
}
TEST_F(DI_CAN, net_node_events) {
static struct di_can_callback msg_callbacks[] = {
DI_CAN_NET_CALLBACK_HEARTBEAT_PUBLISH_ITEM
};
SetNodeid(0xdead1337);
di_can_callback_init(&_ctx, msg_callbacks, DI_ARRAY_SIZE(msg_callbacks));
di_can_net_node_set_event_callback(&_ctx, net_node_events_event_cb);
/* Fake role PASSIVE, FOLLOWER publishes */
SetNodeid(0xcafebabe);
_ctx.net.self.role = DI_CAN_NET_NODE_ROLE_UNKNOWN;
ASSERT_EQ(DNOK, di_can_net_self_set_node_role(&_ctx, DI_CAN_NET_NODE_ROLE_PASSIVE));
ASSERT_EQ(DNOK, di_can_net_self_set_node_role(&_ctx, DI_CAN_NET_NODE_ROLE_FOLLOWER));
/* Fake role LEADER publish */
_ctx.net.self.role = DI_CAN_NET_NODE_ROLE_LEADER;
ASSERT_EQ(DNOK, di_can_net_self_publish_heartbeat(&_ctx));
/* Recv all messages (we need to reset to the "real/receiving" nodeid */
SetNodeid(0xdead1337);
struct di_can_msg *msg = di_can_recv(&_ctx, DI_CAN_MSGTYPE_NET);
do {
ASSERT_EQ(DNOK, di_can_callback_execute(&_ctx, msg));
di_can_msg_free(&msg);
msg = di_can_recv(&_ctx, DI_CAN_MSGTYPE_NET);
} while (msg);
PrintNetNodes();
}
/**
* When the discovery is missed on the peer node the leader node is not seen.
* We expect after the first leader heartbeat to receive a NEW and ROLE_LEADER event.
* @note This test is created to make sure Jira issue TWS-23 fix works
*/
static size_t g_net_node_events_event_leader_ping_cb_idx = 0;
void net_node_events_event_leader_ping_cb(const struct di_can_net *ctx,
const enum di_can_net_node_events ev,
const struct di_can_net_node *node)
{
(void)ctx;
static const struct _tv {
const enum di_can_net_node_events ev;
const enum di_can_net_node_roles role;
} tv[] = {
{ DI_CAN_NET_NODE_EVENT_NEW, DI_CAN_NET_NODE_ROLE_LEADER },
{ DI_CAN_NET_NODE_EVENT_ROLE_LEADER, DI_CAN_NET_NODE_ROLE_LEADER }
};
printf("event[%zu](%d): node: %04x, type: %02x, role: %02x\n",
g_net_node_events_event_leader_ping_cb_idx,
ev, node->nodeid, node->type, node->role);
ASSERT_EQ(0xcafebabe, node->nodeid);
ASSERT_EQ(DI_CAN_NET_NODE_TYPE_UNKNOWN, node->type);
ASSERT_GT(DI_ARRAY_SIZE(tv), g_net_node_events_event_leader_ping_cb_idx);
ASSERT_EQ(tv[g_net_node_events_event_leader_ping_cb_idx].ev, ev);
ASSERT_EQ(tv[g_net_node_events_event_leader_ping_cb_idx].role, node->role);
g_net_node_events_event_leader_ping_cb_idx++;
}
TEST_F(DI_CAN, net_node_event_new_leader_ping) {
static struct di_can_callback msg_callbacks[] = {
DI_CAN_NET_CALLBACK_HEARTBEAT_PUBLISH_ITEM
};
SetNodeid(0xdead1337);
di_can_callback_init(&_ctx, msg_callbacks, DI_ARRAY_SIZE(msg_callbacks));
di_can_net_node_set_event_callback(&_ctx, net_node_events_event_leader_ping_cb);
/* Fake role PASSIVE, FOLLOWER publishes */
SetNodeid(0xcafebabe);
_ctx.net.self.role = DI_CAN_NET_NODE_ROLE_LEADER;
/* Fake role LEADER publish */
_ctx.net.self.role = DI_CAN_NET_NODE_ROLE_LEADER;
ASSERT_EQ(DNOK, di_can_net_self_publish_heartbeat(&_ctx));
/* Recv all messages (we need to reset to the "real/receiving" nodeid */
SetNodeid(0xdead1337);
struct di_can_msg *msg = di_can_recv(&_ctx, DI_CAN_MSGTYPE_NET);
do {
ASSERT_EQ(DNOK, di_can_callback_execute(&_ctx, msg));
di_can_msg_free(&msg);
msg = di_can_recv(&_ctx, DI_CAN_MSGTYPE_NET);
} while (msg);
EXPECT_EQ(2U, g_net_node_events_event_leader_ping_cb_idx);
PrintNetNodes();
}