src.dualinventive.com/jjacobs/dinetrpcll-sniffer/libdi/tests/config.cpp

347 lines
10 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 <di/array.h>
#include <di/buffer.h>
#include <di/config.h>
#include <gtest/gtest.h>
#include "tests/buffer.h"
extern "C" {
#include "config.c"
}
// Common test setup for buffer, callbacks, items
#define TEST_CONFIG_SETUP(bufferSize) \
uint8_t buf_data[bufferSize]; \
struct di_buffer buf; \
struct di_config_ctx conf; \
di_buffer_init(&buf, buf_data, bufferSize); \
memset(buf_data, 0x55, sizeof(buf_data)); \
di_config_init(&conf); \
di_config_set_items(&conf, items, DI_ARRAY_SIZE(items)); \
di_config_set_size(&conf, sizeof(buf_data)); \
di_config_set_private_data(&conf, &buf); \
di_config_set_read(&conf, &read_cb); \
di_config_set_write(&conf, &write_cb);
/** Unit test configuration item uids */
enum item_uids {
ITEM_TOKEN = 1,
ITEM_ACTIVATION = 2,
ITEM_STRING = 3
};
#define ITEM_TOKEN_DEFAULT 0x5f5f5f5f
/** Unit test configuration items list */
static const struct di_config_item items[] {
{ ITEM_TOKEN, sizeof(uint32_t), DI_CONFIG_ITEM_DEFAULT_UINT32(ITEM_TOKEN_DEFAULT) },
{ ITEM_ACTIVATION, sizeof(bool), DI_CONFIG_ITEM_DEFAULT_TYPE_BOOL, { 0 } },
{ ITEM_STRING, 32, DI_CONFIG_ITEM_DEFAULT_STR("deadbeef") }
};
/** Lowlevel configuration driver to read from a di_buffer */
di_errno_t read_cb(struct di_config_ctx *ctx, uint32_t offset, void *data, size_t len)
{
memcpy(data, ((struct di_buffer *)ctx->private_data)->data + offset, len);
return DNOK;
}
/** Lowlevel configuration driver to write into a di_buffer */
di_errno_t write_cb(struct di_config_ctx *ctx, uint32_t offset, const void *data, size_t len)
{
di_buffer_memcpy((struct di_buffer *)ctx->private_data, offset, data, len);
return DNOK;
}
/**
* Check if initialisation of a item list with duplicates unsets the configuration context
* and returns a error code.
*/
TEST(config, set_items_duplicate_uid) {
struct di_config_ctx conf;
static struct di_config_item itemsWithDup[4] {
{ 1, sizeof(uint32_t), DI_CONFIG_ITEM_DEFAULT_TYPE_UINT32, { 0 } },
{ 2, sizeof(uint32_t), DI_CONFIG_ITEM_DEFAULT_TYPE_UINT32, { 0 } },
{ 1, sizeof(bool), DI_CONFIG_ITEM_DEFAULT_TYPE_BOOL, { 0 } },
{ 2, sizeof(bool), DI_CONFIG_ITEM_DEFAULT_TYPE_BOOL, { 0 } }
};
di_config_init(&conf);
// Initialize with correct config item list
EXPECT_EQ(DNOK, di_config_set_items(&conf, items, DI_ARRAY_SIZE(items)));
EXPECT_EQ(items, conf.items.begin);
EXPECT_EQ(DI_ARRAY_SIZE(items), conf.items.size);
// Try to initialize with item list with duplicates, this will reset the conf->items array
EXPECT_EQ(DNE_PARAM, di_config_set_items(&conf, itemsWithDup, DI_ARRAY_SIZE(itemsWithDup)));
EXPECT_EQ(nullptr, conf.items.begin);
EXPECT_EQ(0U, conf.items.size);
}
/**
* Test writing 4 lowlevel blobs and check if CRC16 CCIT and buffer is correct
*/
TEST(config, write) {
TEST_CONFIG_SETUP(64);
di_buffer_flush(&buf); // Flush buffer to zero, then we can use string compare
// Write offset (keep 2 byte crc offset in mind...), blob, size
// We use the ITEM_TOKEN because its size is 4 bytes, no fill is appended
EXPECT_EQ(DNOK, di_config_write(&conf, ITEM_TOKEN, 0, "1234", 4));
EXPECT_EQ(DNOK, di_config_write(&conf, ITEM_TOKEN, 6, "5678", 4));
EXPECT_EQ(DNOK, di_config_write(&conf, ITEM_TOKEN, 12, "9ABC", 4));
EXPECT_EQ(DNOK, di_config_write(&conf, ITEM_TOKEN, 18, "DEF0", 4));
EXPECT_STREQ("\x49\x53""1234"
"\x30\x48""5678"
"\xca\x62""9ABC"
"\xc9\x47""DEF0", (const char *)buf_data);
test_buffer_dump(&buf);
}
/** Check if correct byte offset is calculated for the items */
TEST(config, uid_get_offset) {
uint32_t offset;
TEST_CONFIG_SETUP(64);
/* ITEM_TOKEN is located at offset: 0 */
EXPECT_EQ(DNOK, di_config_uid_get_offset(&conf, ITEM_TOKEN, &offset));
EXPECT_EQ(0U, offset);
/* ITEM_ACTIVATION is located at offset: DI_CONFIG_CRC_CCIT16_OFFSET + sizeof(uint32_t) */
EXPECT_EQ(DNOK, di_config_uid_get_offset(&conf, ITEM_ACTIVATION, &offset));
EXPECT_EQ(DI_CONFIG_CRC_CCIT16_OFFSET + sizeof(uint32_t), offset);
/* ITEM_STRING is located at offset:
* * ITEM_TOKEN: DI_CONFIG_CRC_CCIT16_OFFSET + sizeof(uint32_t) +
* * ITEM_ACTIVATION: DI_CONFIG_CRC_CCIT16_OFFSET + sizeof(bool)
*/
EXPECT_EQ(DNOK, di_config_uid_get_offset(&conf, ITEM_STRING, &offset));
EXPECT_EQ(DI_CONFIG_CRC_CCIT16_OFFSET + sizeof(bool) +
DI_CONFIG_CRC_CCIT16_OFFSET + sizeof(uint32_t), offset);
}
/** Set/get ITEM_ACTIVATION boolean */
TEST(config, set_get_bool_activation) {
TEST_CONFIG_SETUP(32);
// Set
bool val_bool = true;
EXPECT_EQ(DNOK, di_config_set(&conf, ITEM_ACTIVATION, val_bool));
// Get
val_bool = false;
EXPECT_EQ(DNOK, di_config_get(&conf, ITEM_ACTIVATION, &val_bool));
EXPECT_EQ(true, val_bool);
test_buffer_dump(&buf);
}
/** Set/get ITEM_TOKEN */
TEST(config, set_get_u32_token) {
TEST_CONFIG_SETUP(32);
// Set
uint32_t val_u32 = 0xAABBCCDD;
EXPECT_EQ(DNOK, di_config_set(&conf, ITEM_TOKEN, val_u32));
// Get
val_u32 = 0;
EXPECT_EQ(DNOK, di_config_get(&conf, ITEM_TOKEN, &val_u32));
EXPECT_EQ(0xAABBCCDD, val_u32);
test_buffer_dump(&buf);
}
/** Try to write more data than the configuration item TOKEN can hold (write u64 while max item size is u32) */
TEST(config, set_u32_token_overflow_with_u64) {
TEST_CONFIG_SETUP(32);
// Set fails because item is u32 and action is u64
uint64_t val_u64 = 0xABABABABABABABAB;
EXPECT_EQ(DNE_RANGE, di_config_set(&conf, ITEM_TOKEN, val_u64));
// Get, this fails due to invalid size. Item is u32 action is u64
val_u64 = 0;
EXPECT_EQ(DNE_RANGE, di_config_get(&conf, ITEM_TOKEN, &val_u64));
EXPECT_EQ(0U, val_u64);
test_buffer_dump(&buf);
}
/**
* Set and get string
* 1. Set string (const char *), which is smaller than the item size (32byte)
* 2. Get string, buffer is the same size as the item size!
*/
TEST(config, set_get_string) {
TEST_CONFIG_SETUP(64);
// Set
const char *val_str = "foo-bar-baz";
EXPECT_EQ(DNOK, di_config_set(&conf, ITEM_STRING, val_str));
// Get
char val_str_buf[32]; // Same size as ITEM_STRING size !
memset(val_str_buf, 0xab, sizeof(val_str_buf));
EXPECT_EQ(DNOK, di_config_get_string(&conf, ITEM_STRING, val_str_buf, sizeof(val_str_buf)));
EXPECT_STREQ(val_str, val_str_buf);
test_buffer_dump(&buf);
}
/**
* Set string default value and check if get returns correct
*/
TEST(config, set_default_get_string) {
TEST_CONFIG_SETUP(64);
// Set default
EXPECT_EQ(DNOK, di_config_set_default(&conf, ITEM_STRING));
// Get string
char val_str_buf[32]; // Same size as ITEM_STRING size !
memset(val_str_buf, 0, sizeof(val_str_buf));
EXPECT_EQ(DNOK, di_config_get_string(&conf, ITEM_STRING, val_str_buf, sizeof(val_str_buf)));
EXPECT_STREQ("deadbeef", val_str_buf);
test_buffer_dump(&buf);
}
/**
* Get or set default string value
*/
TEST(config, get_or_set_default_string) {
TEST_CONFIG_SETUP(64);
char val_str_buf[32]; // Same size as ITEM_STRING size !
memset(val_str_buf, 0, sizeof(val_str_buf));
// Get (unwritten)
EXPECT_EQ(DNE_CHECKSUM, di_config_get_string(&conf, ITEM_STRING, val_str_buf, sizeof(val_str_buf)));
// Get or set default
EXPECT_EQ(DNOK, di_config_get_or_load_default_string(&conf, ITEM_STRING, val_str_buf, sizeof(val_str_buf)));
test_buffer_dump(&buf);
// Get
EXPECT_EQ(DNOK, di_config_get_string(&conf, ITEM_STRING, val_str_buf, sizeof(val_str_buf)));
EXPECT_STREQ("deadbeef", val_str_buf);
test_buffer_dump(&buf);
}
/**
* Check if set and get return DNE_NOTFOUND when uid is not known
*/
TEST(config, uid_not_found) {
TEST_CONFIG_SETUP(64);
uint32_t val = 666;
EXPECT_EQ(DNE_NOTFOUND, di_config_set(&conf, 1234, val));
EXPECT_EQ(DNE_NOTFOUND, di_config_get(&conf, 1234, &val));
}
/**
* Check if read or write is not set the operations return DNE_OPNOTSUPP
*/
TEST(config, set_get_operation_not_supported) {
TEST_CONFIG_SETUP(64);
di_config_set_read(&conf, NULL);
di_config_set_write(&conf, NULL);
uint32_t val = 666;
EXPECT_EQ(DNE_OPNOTSUPP, di_config_set(&conf, ITEM_TOKEN, val));
EXPECT_EQ(DNE_OPNOTSUPP, di_config_get(&conf, ITEM_TOKEN, &val));
}
/**
* Check if lowlevel buffer is to small the operation is denied with DNE_RANGE
*/
TEST(config, lowlevel_size_to_small) {
TEST_CONFIG_SETUP(4);
uint32_t val = 666;
EXPECT_EQ(DNE_RANGE, di_config_set(&conf, ITEM_TOKEN, val));
EXPECT_EQ(DNE_RANGE, di_config_get(&conf, ITEM_TOKEN, &val));
}
/**
* Check if default value is correctly saved and returned to the application
* 1. Write token with manual value
* 2. Corrupt token CRC
* 3. Try to get corrupt token, check for error
* 4. Get token and load default
*/
TEST(config, load_default) {
TEST_CONFIG_SETUP(32);
di_buffer_flush(&buf); // Flush buffer to zero, then we can use string compare
// Set token
uint32_t val = 666;
EXPECT_EQ(DNOK, di_config_set(&conf, ITEM_TOKEN, val));
// Corrupt crc
buf_data[0] = 0xaa;
// Try to get corrupt value
val = 0;
EXPECT_EQ(DNE_CHECKSUM, di_config_get(&conf, ITEM_TOKEN, &val));
// Load "default" value from macro
EXPECT_EQ(DNOK, di_config_get_or_load_default(&conf, ITEM_TOKEN, &val));
EXPECT_EQ(ITEM_TOKEN_DEFAULT, val);
// Check buffer is filled as we expect
// String: "____", CRC-CCIT16: 0xe271
EXPECT_STREQ("\x71\xe2\x5f\x5f\x5f\x5f", (const char *)buf_data);
test_buffer_dump(&buf);
}
/**
* Check if default u32 value is read from the config item
*/
TEST(config, get_default_u32) {
TEST_CONFIG_SETUP(32);
di_buffer_flush(&buf); // Flush buffer to zero, then we can use string compare
// Get default token value
uint32_t val_u32 = 0;
EXPECT_EQ(DNOK, di_config_get_default(&conf, ITEM_TOKEN, &val_u32));
EXPECT_EQ(ITEM_TOKEN_DEFAULT, val_u32);
}
/**
* Check if default string value is read from the config item
*/
TEST(config, get_default_string) {
TEST_CONFIG_SETUP(32);
di_buffer_flush(&buf); // Flush buffer to zero, then we can use string compare
// Get default string value
char val_str[16];
memset(val_str, 0, sizeof(val_str));
EXPECT_EQ(DNOK, di_config_get_default_string(&conf, ITEM_STRING, val_str, sizeof(val_str)));
EXPECT_STREQ("deadbeef",(const char *)val_str);
// Check if to small buffer returns an error and doesn't write anything
memset(val_str, 0, sizeof(val_str));
}