src.dualinventive.com/fw/dncm/libdi/tests/can_msg_state.cpp

121 lines
3.5 KiB
C++

/**
* @file tests/can_msg.cpp
* @brief CAN message states unit test
* @date Jan 21, 2016
* @author jjacobs
* @copyright 2016 Dual Inventive Technology Centre B.V.
*
* CAN messsage state unit test
*/
#include <stdio.h>
#include "tests/can.h"
#include <gtest/gtest.h>
#include <di/time.h>
#include <di/buffer.h>
#include <di/can/msg.h>
extern "C" {
#include "time.c"
#include "can/msg.c"
}
static struct di_can_ctx ctx;
DI_CAN_FRAME_RX_DECL_ARRAY(can_frames, DI_CAN_CFG_FRAME_SIZE);
DI_CAN_MSG_DECL_ARRAY(can_msg_list, DI_CAN_CFG_MSG_SIZE, DI_CAN_CFG_MSG_DATA_SIZE);
/**
* Initialize the CAN stack msg subsystem
*/
TEST(can_msg_state, init) {
di_can_init(&ctx);
di_can_frame_init(&ctx, can_frames, DI_CAN_CFG_FRAME_SIZE);
DI_CAN_MSG_INIT_ARRAY(&ctx, can_msg_list, DI_CAN_CFG_MSG_SIZE, DI_CAN_CFG_MSG_DATA_SIZE);
di_can_msg_init(&ctx, can_msg_list, DI_CAN_CFG_MSG_SIZE);
}
/** Check if correct state and timeout is set after initialisation loop directly over the pool */
TEST(can_msg_state, after_init) {
di_array_foreach(ctx.msg.pool, msg, struct di_can_msg) {
ASSERT_EQ(DI_CAN_MSG_STATE_UNUSED, msg->state);
ASSERT_EQ(DI_CAN_TIMEOUT_GC_SKIP, msg->timeout);
}
}
/** Get all unused messages with internal function which changes state UNUSED -> REASSEMBLE */
TEST(can_msg_state, di_can_msg_get) {
struct di_can_msg *msg;
for (size_t i = 0; i < DI_CAN_CFG_MSG_SIZE; i++) {
// Get message UNUSED -> REASSEMBLE
msg = di_can_msg_alloc_reassemble(&ctx);
ASSERT_NE((void *)NULL, msg);
ASSERT_EQ(DI_CAN_MSG_STATE_REASSEMBLE, msg->state);
// We set the message timeout when it is being reassembled,
// this due to when the peer node resets and the message is never completed
// then the garbage collector will happily clean it
ASSERT_EQ(ctx.msg.timeout, msg->timeout);
// Mark msg to be garbage collected on next run because we lose the msg pointer on
// next itteration
msg->timeout = DI_CAN_TIMEOUT_GC_IMMEDIATE;
}
di_can_msg_gc(&ctx, DI_CAN_GC_ALL);
}
/** Mark all messages from REASSEMBLE -> READY -> APPLICATION -> DIRTY (no timeout) */
TEST(can_msg_state, di_can_msg_set_get_ready_type) {
struct di_can_msg *msg;
// UNUSED -> REASSEMBLE -> READY
for (size_t i = 0; i < DI_CAN_CFG_MSG_SIZE; i++) {
msg = di_can_msg_alloc_reassemble(&ctx);
ASSERT_NE((void *)NULL, msg);
ASSERT_EQ(DI_CAN_MSG_STATE_REASSEMBLE, msg->state);
// We set the message timeout when it is being reassembled,
// this due to when the peer node resets and the message is never completed
// then the garbage collector will happily clean it
ASSERT_EQ(ctx.msg.timeout, msg->timeout);
di_can_msg_set_ready(&msg);
ASSERT_EQ((void *)NULL, msg);
}
// READY -> APPLICATION -> DIRTY
for (size_t i = 0; i < DI_CAN_CFG_MSG_SIZE; i++) {
// We know the canid is set to zero so the msgtype is == 0 (RAW)
msg = di_can_msg_get_ready_type(&ctx, DI_CAN_MSGTYPE_RAW);
ASSERT_NE((void *)NULL, msg);
ASSERT_EQ(DI_CAN_MSG_STATE_APPLICATION, msg->state);
ASSERT_EQ(DI_CAN_TIMEOUT_GC_SKIP, msg->timeout);
di_can_msg_free(&msg);
ASSERT_EQ((void *)NULL, msg);
}
// DIRTY -> UNUSED
di_can_msg_gc(&ctx, DI_CAN_GC_ALL);
}
/** Application allocated UNUSED -> APPLICATION -> DIRTY */
TEST(can_msg_state, di_can_msg_alloc_free) {
struct di_can_msg *msg;
for (size_t i = 0; i < DI_CAN_CFG_MSG_SIZE; i++) {
msg = di_can_msg_alloc(&ctx);
ASSERT_NE((void *)NULL, msg);
ASSERT_EQ(DI_CAN_MSG_STATE_APPLICATION, msg->state);
ASSERT_EQ(DI_CAN_TIMEOUT_GC_SKIP, msg->timeout);
di_can_msg_free(&msg);
ASSERT_EQ((void *)NULL, msg);
}
di_can_msg_gc(&ctx, DI_CAN_GC_ALL);
}