121 lines
3.5 KiB
C++
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);
|
|
}
|