158 lines
4.0 KiB
C++
158 lines
4.0 KiB
C++
/**
|
|
* @file tests/can_msg_gc.cpp
|
|
* @date Mar 13, 2019
|
|
* @copyright 2019 Dual Inventive Technology Centre B.V.
|
|
*
|
|
* CAN Message buffer test
|
|
*/
|
|
#include <cstdio>
|
|
#include <di/device/uid.h>
|
|
#include "fixtures/CANTest.hpp"
|
|
|
|
extern "C" {
|
|
#include "can.c"
|
|
#include "time.c"
|
|
#include "can/msg.c"
|
|
}
|
|
|
|
/**
|
|
* Put test message into the pool for garbage collection
|
|
*/
|
|
static void test_can_msg_gc_put(DI_CAN *t, struct di_can_ctx *ctx, struct di_can_msg **msg) {
|
|
uint8_t _msg[] = "0123456789";
|
|
|
|
*msg = di_can_msg_alloc_reassemble(ctx);
|
|
if (*msg) {
|
|
ASSERT_NE((void *)NULL, (*msg)->buf);
|
|
di_buffer_memcpy((*msg)->buf, 0, _msg, sizeof(_msg));
|
|
}
|
|
|
|
DI_CAN_SET_MSGTYPE((*msg)->canid, DI_CAN_MSGTYPE_RAW);
|
|
ASSERT_NE(nullptr, *msg);
|
|
ASSERT_NE(nullptr, (*msg)->buf);
|
|
ASSERT_STREQ((const char *)_msg, (const char *)(*msg)->buf->data);
|
|
ASSERT_EQ(t->getCurrentMsgTimeout(), (*msg)->timeout);
|
|
}
|
|
|
|
/**
|
|
* Normal garbage collect test
|
|
* This uses the single garbage collect run
|
|
*/
|
|
TEST_F(DI_CAN, gc_single) {
|
|
struct di_can_msg *msg;
|
|
|
|
/* Test garbage collection on
|
|
m->timeout = 1000ms
|
|
uptime = 2000ms */
|
|
test_can_msg_gc_put(this, &_ctx, &msg);
|
|
|
|
msg->timeout = 1000;
|
|
_di_time_uptime = 2000;
|
|
di_can_msg_gc(&_ctx, DI_CAN_GC_SINGLE);
|
|
|
|
ASSERT_EQ(0U, msg->timeout);
|
|
|
|
/* Test garbage collection on
|
|
m->timeout = 1000ms
|
|
uptime = 1000ms */
|
|
test_can_msg_gc_put(this, &_ctx, &msg);
|
|
|
|
msg->timeout = 1000;
|
|
_di_time_uptime = 1000;
|
|
|
|
di_can_msg_gc(&_ctx, DI_CAN_GC_SINGLE);
|
|
|
|
ASSERT_EQ(0U, msg->timeout);
|
|
|
|
/* Test garbage collection skip on
|
|
m->timeout = 1000ms
|
|
uptime = 750ms */
|
|
test_can_msg_gc_put(this, &_ctx, &msg);
|
|
|
|
_di_time_uptime = 750;
|
|
|
|
di_can_msg_gc(&_ctx, DI_CAN_GC_SINGLE);
|
|
ASSERT_EQ(1500, msg->timeout);
|
|
|
|
/* Now garbage collect previous message
|
|
*/
|
|
_di_time_uptime = 1000;
|
|
di_can_msg_gc(&_ctx, DI_CAN_GC_SINGLE);
|
|
msg = di_can_msg_get_ready_type(&_ctx, DI_CAN_MSGTYPE_RAW);
|
|
|
|
ASSERT_EQ(nullptr, msg);
|
|
}
|
|
|
|
/**
|
|
* Test if the di_can_msg_alloc_reassemble executed the DI_CAN_GC_SINGLE
|
|
* when the message pool is depleted.
|
|
*/
|
|
TEST_F(DI_CAN, gc_single_alloc_reassemble_internal) {
|
|
struct di_can_msg *msg;
|
|
|
|
// Check if the context message timeout is set
|
|
ASSERT_EQ(DI_CAN_CFG_MSG_TIMEOUT, _ctx.msg.timeout);
|
|
|
|
// Deplete the pool
|
|
for (size_t n = 0; n < _ctx.msg.pool.size; n++) {
|
|
msg = di_can_msg_alloc_reassemble(&_ctx);
|
|
ASSERT_NE(nullptr, msg);
|
|
ASSERT_EQ(getCurrentMsgTimeout(), msg->timeout);
|
|
}
|
|
|
|
// Check if the pool is depleted by trying to alloc with gc
|
|
ASSERT_EQ(nullptr, di_can_msg_alloc_reassemble(&_ctx));
|
|
|
|
// Run GC single and check if the pool messages are stil in REASSEMBLE state
|
|
_di_can_msg_gc(&_ctx, DI_CAN_GC_ALL);
|
|
ASSERT_EQ(nullptr, di_can_msg_alloc_reassemble(&_ctx));
|
|
|
|
// Move time forward so all allocated REASSEMBLE state messages expire
|
|
_di_time_uptime = getCurrentMsgTimeout();
|
|
msg = di_can_msg_alloc_reassemble(&_ctx);
|
|
ASSERT_NE(nullptr, msg);
|
|
ASSERT_EQ(getCurrentMsgTimeout(), msg->timeout);
|
|
}
|
|
|
|
/**
|
|
* Garbage collection skip and immediate macro test
|
|
* * Put message
|
|
* * Set garbage collect to skip
|
|
* * Garbage collect
|
|
*/
|
|
TEST_F(DI_CAN, gc_timeout_skip_and_immediate) {
|
|
struct di_buffer *b;
|
|
struct di_can_msg *msg;
|
|
|
|
/* Test if message GC is skipped */
|
|
test_can_msg_gc_put(this, &_ctx, &msg);
|
|
|
|
msg->timeout = DI_CAN_TIMEOUT_GC_SKIP;
|
|
msg->state = DI_CAN_MSG_STATE_READY;
|
|
b = msg->buf;
|
|
|
|
_di_time_uptime = 1000;
|
|
di_can_msg_gc(&_ctx, DI_CAN_GC_ALL);
|
|
|
|
msg = di_can_msg_get_ready_type(&_ctx, DI_CAN_MSGTYPE_RAW);
|
|
ASSERT_NE(nullptr, msg);
|
|
ASSERT_EQ(b, msg->buf);
|
|
|
|
// Message state after get is application so the GC will not touch it
|
|
ASSERT_EQ(DI_CAN_MSG_STATE_APPLICATION, msg->state);
|
|
msg->state = DI_CAN_MSG_STATE_READY;
|
|
|
|
// Test if message GC is immediate
|
|
_di_time_uptime = 0;
|
|
DI_CAN_SET_MSGTYPE(msg->canid, DI_CAN_MSGTYPE_RAW);
|
|
msg->timeout = DI_CAN_TIMEOUT_GC_IMMEDIATE;
|
|
|
|
msg = di_can_msg_get_ready_type(&_ctx, DI_CAN_MSGTYPE_RAW);
|
|
ASSERT_NE(nullptr, msg);
|
|
|
|
di_can_msg_gc(&_ctx, DI_CAN_GC_ALL);
|
|
|
|
msg = di_can_msg_get_ready_type(&_ctx, DI_CAN_MSGTYPE_RAW);
|
|
ASSERT_EQ(nullptr, msg);
|
|
}
|