src.dualinventive.com/dinet/libdi-php/libdi/tests/can_callback.cpp

206 lines
5.8 KiB
C++

/**
* @file tests/can_callback.cpp
* @brief brief
* @date Feb 10, 2016
* @author jjacobs
* @copyright 2016 Dual Inventive Technology Centre B.V.
*
* descr
*/
#include <inttypes.h>
#include "tests/can.h"
#include <di/can/callback.h>
#include <di/can.h>
#include <gtest/gtest.h>
TEST_CAN_INIT_DECL
static unsigned int cb_test_12345678_cnt = 0;
static unsigned int cb_test_send_msg_cnt = 0;
static void cb_test_12345678(const struct di_can_msg *msg, struct di_can_ctx *ctx)
{
(void)ctx;
printf("%s: msg: %p\n", __func__, (void *)msg);
cb_test_12345678_cnt++;
}
static void cb_test_send_msg(const struct di_can_msg *msg, struct di_can_ctx *ctx)
{
(void)msg;
(void)ctx;
//ASSERT_EQ(DNOK, di_can_send(&msg));
cb_test_send_msg_cnt++;
}
static struct di_can_callback callbacks[] = {
{ 0x12345678, cb_test_12345678 },
{ 0xdeadbeef, cb_test_send_msg }
};
TEST(can_callback, CANID)
{
uint32_t canid = DI_CAN_CALLBACK_CANID(DI_CAN_MSGTYPE_NET, DI_CAN_TRANSFERTYPE_PUBLISH, 0x7c1);
ASSERT_EQ(0x17C1C000, canid);
}
/** Test if di_can_callback_init wont crash */
TEST(can_callback, init_invalid) {
struct di_can_ctx _ctx;
di_can_init(&_ctx);
di_can_frame_init(&_ctx, can_frames, DI_CAN_CFG_FRAME_SIZE);
di_can_msg_init(&_ctx, can_msg_list, DI_CAN_CFG_MSG_SIZE);
ASSERT_EQ(DNE_PARAM, di_can_callback_init(NULL, NULL, 0));
ASSERT_EQ(DNE_PARAM, di_can_callback_init(NULL, callbacks, 0));
ASSERT_EQ(DNE_PARAM, di_can_callback_init(&_ctx, NULL, 0));
ASSERT_EQ(DNE_PARAM, di_can_callback_init(&_ctx, NULL, 1));
ASSERT_EQ(DNE_PARAM, di_can_callback_init(&_ctx, callbacks, 0));
}
/** Test if invalid send and receive callbacks wont crash */
TEST(can_callback, set_send_recv_invalid) {
can_ctx.send = test_can_send_callback;
can_ctx.recv = test_can_recv_callback;
// Check if invalid set doesn't overwrite existing callback pointer
di_can_callback_set_send(NULL, NULL);
di_can_callback_set_send(&can_ctx, NULL);
ASSERT_EQ(&test_can_send_callback, can_ctx.send);
// Reset callback to NULL, then set with function and check
can_ctx.send = NULL;
di_can_callback_set_send(&can_ctx, test_can_send_callback);
ASSERT_EQ(&test_can_send_callback, can_ctx.send);
// Check if invalid set doesn't overwrite existing callback pointer
di_can_callback_set_recv(NULL, NULL);
di_can_callback_set_recv(&can_ctx, NULL);
ASSERT_EQ(&test_can_recv_callback, can_ctx.recv);
// Reset callback to NULL, then set with function and check
can_ctx.recv = NULL;
di_can_callback_set_recv(&can_ctx, test_can_recv_callback);
ASSERT_EQ(&test_can_recv_callback, can_ctx.recv);
}
/** Test if di_can_execute wont crash */
TEST(can_callback, execute_invalid) {
struct di_can_ctx _ctx;
di_can_init(&_ctx);
di_can_frame_init(&_ctx, can_frames, DI_CAN_CFG_FRAME_SIZE);
di_can_msg_init(&_ctx, can_msg_list, DI_CAN_CFG_MSG_SIZE);
di_can_callback_execute(NULL, NULL);
di_can_callback_execute(&_ctx, NULL);
di_can_callback_init(&_ctx, callbacks, 0);
di_can_callback_execute(&_ctx, NULL);
}
/** Test if initialisation sets the correct fields in the context */
TEST(can_callback, init_check) {
di_can_callback_init(&can_ctx, callbacks, DI_ARRAY_SIZE(callbacks));
ASSERT_EQ(callbacks, can_ctx.msg.callback.begin);
ASSERT_EQ(DI_ARRAY_SIZE(callbacks), can_ctx.msg.callback.size);
}
/** Execute callback for canid 0x12345678 on one single message */
TEST(can_callback, execute_single) {
struct di_can_msg *msg;
msg = di_can_msg_alloc_reassemble(&can_ctx);
ASSERT_NE((void *)NULL, msg);
msg->canid = 0x12345678;
msg->size = 0;
di_can_msg_set_ready(&msg);
msg = di_can_recv(&can_ctx, DI_CAN_MSGTYPE_ANY);
ASSERT_EQ(DNOK, di_can_callback_execute(&can_ctx, msg));
di_can_msg_free(&msg);
ASSERT_EQ(1, cb_test_12345678_cnt);
cb_test_12345678_cnt = 0;
}
/** Check if NULL callback will return the message back to the pool as ready
*/
TEST(can_callback, execute_null_cb_single) {
struct di_can_msg *msg;
msg = di_can_msg_alloc_reassemble(&can_ctx);
ASSERT_NE((void *)NULL, msg);
msg->canid = 0x12345678;
msg->size = 0;
di_can_msg_set_ready(&msg);
// Set callback pointer to NULL
callbacks[0].callback = NULL;
msg = di_can_recv(&can_ctx, DI_CAN_MSGTYPE_ANY);
ASSERT_EQ(DNE_OPNOTSUPP, di_can_callback_execute(&can_ctx, msg));
ASSERT_EQ(0, cb_test_12345678_cnt);
// Restore callback pointer
callbacks[0].callback = cb_test_12345678;
ASSERT_EQ(DNOK, di_can_callback_execute(&can_ctx, msg));
di_can_msg_free(&msg);
ASSERT_EQ(1, cb_test_12345678_cnt);
cb_test_12345678_cnt = 0;
}
/** Execute callback for canid 0x12345678 on all messages in the pool */
TEST(can_callback, execute_multiple) {
struct di_can_msg *msg;
/* Deplete pool with only messages for callback 0x12345678 */
for (size_t n = 0; n < can_ctx.msg.pool.size; n++) {
msg = di_can_msg_alloc_reassemble(&can_ctx);
ASSERT_NE((void *)NULL, msg);
msg->canid = 0x12345678;
msg->size = 0;
di_can_msg_set_ready(&msg);
}
for (size_t n = 0; n < can_ctx.msg.pool.size; n++) {
msg = di_can_recv(&can_ctx, DI_CAN_MSGTYPE_ANY);
ASSERT_EQ(DNOK, di_can_callback_execute(&can_ctx, msg));
di_can_msg_free(&msg);
}
ASSERT_EQ(can_ctx.msg.pool.size, cb_test_12345678_cnt);
cb_test_12345678_cnt = 0;
}
/** Execute callback for canid 0xdeadbeef on one single message,
* which will send the message. The callback runs di_can_send and the
* stack will return the message to the pool. When the callback execution
* has finished it is freed again because we have currently no signal of
* the callback that it has consumed the message.
*/
TEST(can_callback, execute_single_reuse_msg) {
struct di_can_msg *msg;
msg = di_can_msg_alloc_reassemble(&can_ctx);
ASSERT_NE((void *)NULL, msg);
msg->canid = 0xdeadbeef;
msg->size = 0;
di_can_msg_set_ready(&msg);
msg = di_can_recv(&can_ctx, DI_CAN_MSGTYPE_ANY);
ASSERT_EQ(DNOK, di_can_callback_execute(&can_ctx, msg));
di_can_msg_free(&msg);
ASSERT_EQ(1, cb_test_send_msg_cnt);
cb_test_send_msg_cnt = 0;
}