232 lines
5.5 KiB
C++
232 lines
5.5 KiB
C++
/**
|
|
* @file tests/can_frame.cpp
|
|
* @brief brief
|
|
* @date Aug 25, 2015
|
|
* @author rheijden
|
|
* @copyright 2015 Dual Inventive Technology Centre B.V.
|
|
*
|
|
* @todo add GC tests
|
|
* descr
|
|
*/
|
|
#include "tests/can.h"
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <di/can/frame.h>
|
|
|
|
extern "C" {
|
|
#include "time.c"
|
|
#include "can/frame.c"
|
|
}
|
|
|
|
static struct di_can_ctx ctx;
|
|
DI_CAN_FRAME_RX_DECL_ARRAY(test_can_frames, DI_CAN_CFG_FRAME_SIZE);
|
|
|
|
TEST(time, init) {
|
|
di_time_init();
|
|
}
|
|
|
|
/**
|
|
* Test if NULL, 0 initialization resets the context
|
|
* and the other functions dont crash or return incorrect pointers
|
|
*/
|
|
TEST(can_frame, init_null) {
|
|
struct di_can_frame_rx *f;
|
|
|
|
di_can_frame_init(NULL, NULL, 0);
|
|
|
|
di_can_frame_init(&ctx, NULL, 0);
|
|
ASSERT_EQ(0U, ctx.frame.pool.size);
|
|
ASSERT_EQ((void *)NULL, ctx.frame.pool.begin);
|
|
|
|
di_can_frame_init(&ctx, NULL, 10);
|
|
ASSERT_EQ(0U, ctx.frame.pool.size);
|
|
ASSERT_EQ((void *)NULL, ctx.frame.pool.begin);
|
|
|
|
di_can_frame_init(&ctx, (struct di_can_frame_rx *)0x1234567, 0);
|
|
ASSERT_EQ(0U, ctx.frame.pool.size);
|
|
ASSERT_EQ((void *)NULL, ctx.frame.pool.begin);
|
|
|
|
f = di_can_frame_get_unused(&ctx);
|
|
ASSERT_EQ((void *)NULL, f);
|
|
|
|
f = di_can_frame_get_ready(&ctx);
|
|
ASSERT_EQ((void *)NULL, f);
|
|
}
|
|
|
|
/**
|
|
* Initialize the frame subsystem, then try to initialize again (with other parameters)
|
|
*/
|
|
TEST(can_frame, init) {
|
|
/* Initialize */
|
|
di_can_frame_init(&ctx, test_can_frames, DI_CAN_CFG_FRAME_SIZE);
|
|
ASSERT_EQ(DI_CAN_CFG_FRAME_SIZE, ctx.frame.pool.size);
|
|
ASSERT_EQ(&test_can_frames, ctx.frame.pool.begin);
|
|
}
|
|
|
|
/**
|
|
* Initialize again
|
|
*/
|
|
TEST(can_frame, init_again) {
|
|
/* Initialize again with invalid parameters and see if nothing changed */
|
|
di_can_frame_init(&ctx, NULL, 0);
|
|
ASSERT_EQ(DI_CAN_CFG_FRAME_SIZE, ctx.frame.pool.size);
|
|
ASSERT_EQ(&test_can_frames, ctx.frame.pool.begin);
|
|
|
|
/* Set frame.pool.begin = NULL, dont touch size */
|
|
ctx.frame.pool.begin = NULL;
|
|
|
|
di_can_frame_init(&ctx, test_can_frames, DI_CAN_CFG_FRAME_SIZE);
|
|
ASSERT_EQ(DI_CAN_CFG_FRAME_SIZE, ctx.frame.pool.size);
|
|
ASSERT_EQ(&test_can_frames, ctx.frame.pool.begin);
|
|
|
|
/* Set frame.pool.size = 0, dont touch begin */
|
|
ctx.frame.pool.size = 0;
|
|
|
|
di_can_frame_init(&ctx, test_can_frames, DI_CAN_CFG_FRAME_SIZE);
|
|
ASSERT_EQ(DI_CAN_CFG_FRAME_SIZE, ctx.frame.pool.size);
|
|
ASSERT_EQ(&test_can_frames, ctx.frame.pool.begin);
|
|
}
|
|
|
|
/**
|
|
* Get free and return a single buffer
|
|
*/
|
|
TEST(can_frame, get_unused__return_ready) {
|
|
struct di_can_frame_rx *f;
|
|
|
|
f = di_can_frame_get_unused(&ctx);
|
|
ASSERT_NE((void *)NULL, f);
|
|
ASSERT_TRUE(DI_BIT_SET(f->flags, DI_CAN_FRAME_FLAGS_BIT_USED));
|
|
|
|
f->canid = 0x12345678;
|
|
f->size = 8;
|
|
memset(&f->buf, 0x55, 8);
|
|
|
|
di_can_frame_return_ready(f);
|
|
ASSERT_TRUE(DI_BIT_SET(f->flags, DI_CAN_FRAME_FLAGS_BIT_USED));
|
|
ASSERT_TRUE(DI_BIT_SET(f->flags, DI_CAN_FRAME_FLAGS_BIT_READY));
|
|
}
|
|
|
|
/**
|
|
* Get used frame from previous test
|
|
*/
|
|
TEST(can_frame, get_ready__return_unused) {
|
|
struct di_can_frame_rx *f;
|
|
|
|
f = di_can_frame_get_ready(&ctx);
|
|
ASSERT_NE((void *)NULL, f);
|
|
ASSERT_TRUE(DI_BIT_SET(f->flags, DI_CAN_FRAME_FLAGS_BIT_USED));
|
|
ASSERT_TRUE(DI_BIT_SET(f->flags, DI_CAN_FRAME_FLAGS_BIT_READY));
|
|
ASSERT_EQ(0x12345678U, f->canid);
|
|
ASSERT_EQ(8U, f->size);
|
|
for (size_t n = 0; n < f->size; n++)
|
|
ASSERT_EQ(0x55, f->buf[n]);
|
|
|
|
di_can_frame_return_unused(f);
|
|
}
|
|
|
|
/**
|
|
* Deplete pool and check if null is returned
|
|
*/
|
|
TEST(can_frame, get_unused_null) {
|
|
struct di_can_frame_rx *f;
|
|
|
|
/* Get all frames with unused flag */
|
|
for (size_t n = 0; n < DI_CAN_CFG_FRAME_SIZE; n++) {
|
|
f = di_can_frame_get_unused(&ctx);
|
|
ASSERT_NE((void *)NULL, f);
|
|
di_can_frame_return_ready(f);
|
|
}
|
|
|
|
/* Check if pool is empty */
|
|
f = di_can_frame_get_unused(&ctx);
|
|
ASSERT_EQ((void *)NULL, f);
|
|
|
|
/* Return all ready frames back to ready */
|
|
for (size_t n = 0; n < DI_CAN_CFG_FRAME_SIZE; n++) {
|
|
f = di_can_frame_get_ready(&ctx);
|
|
ASSERT_NE((void *)NULL, f);
|
|
di_can_frame_return_unused(f);
|
|
}
|
|
|
|
/* Check if pool is usable again */
|
|
f = di_can_frame_get_unused(&ctx);
|
|
ASSERT_NE((void *)NULL, f);
|
|
di_can_frame_return_unused(f);
|
|
}
|
|
|
|
/**
|
|
* Check if get_ready returns null
|
|
*/
|
|
TEST(can_frame, get_ready_null) {
|
|
struct di_can_frame_rx *f;
|
|
|
|
f = di_can_frame_get_ready(&ctx);
|
|
ASSERT_EQ((void *)NULL, f);
|
|
}
|
|
|
|
/**
|
|
* Non-behaviour test of gc
|
|
*/
|
|
TEST(can_frame, gc) {
|
|
di_can_frame_gc(&ctx, DI_CAN_GC_SINGLE);
|
|
di_can_frame_gc(&ctx, DI_CAN_GC_ALL);
|
|
}
|
|
|
|
/**
|
|
* Test GC
|
|
*/
|
|
TEST(can_frame, gc_all) {
|
|
_di_time_uptime = 1234;
|
|
|
|
for (size_t n = 0; n < ctx.frame.pool.size; n++) {
|
|
struct di_can_frame_rx *f = di_can_frame_get_unused(&ctx);
|
|
ASSERT_NE((void *)NULL, f);
|
|
di_can_frame_return_ready(f);
|
|
}
|
|
|
|
_di_time_uptime += ctx.frame.timeout + 1;
|
|
|
|
di_can_frame_gc(&ctx, DI_CAN_GC_SINGLE);
|
|
di_can_frame_gc(&ctx, DI_CAN_GC_ALL);
|
|
}
|
|
|
|
/**
|
|
* Check if the correct application specific private_data pointer is returned
|
|
*/
|
|
static di_errno_t test_private_data_can_recv_cb(struct di_can_frame_rx *frame)
|
|
{
|
|
bool *is_ok = static_cast<bool *>(di_can_frame_rx_get_private_data(frame));
|
|
|
|
*is_ok = true;
|
|
return DNOK;
|
|
}
|
|
|
|
static di_errno_t test_private_data_can_send_cb(const struct di_can_frame_tx *frame)
|
|
{
|
|
bool *is_ok = static_cast<bool *>(di_can_frame_tx_get_private_data(frame));
|
|
|
|
*is_ok = true;
|
|
return DNOK;
|
|
}
|
|
|
|
TEST(can_frame, private_data) {
|
|
bool is_ok = false;
|
|
|
|
di_can_callback_set_recv(&ctx, test_private_data_can_recv_cb);
|
|
di_can_callback_set_send(&ctx, test_private_data_can_send_cb);
|
|
|
|
di_can_set_private_data(&ctx, &is_ok);
|
|
|
|
di_can_lowlevel_recv(&ctx);
|
|
ASSERT_TRUE(is_ok);
|
|
is_ok = false;
|
|
|
|
struct di_can_frame_tx tx;
|
|
|
|
tx.canid = 0;
|
|
tx.ctx = &ctx;
|
|
|
|
di_can_lowlevel_send(&ctx, &tx);
|
|
ASSERT_TRUE(is_ok);
|
|
}
|