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

279 lines
7.2 KiB
C++

#include <cstdint>
#include <iostream>
#include <di/buffer.h>
#include <gtest/gtest.h>
using namespace std;
static bool ret;
#define POOL_SIZE 4U
#define POOL_CHUNK_SIZE 16U
DI_BUFFER_DECL(buf, 256);
DI_BUFFER_LIST_DECL(pool, POOL_SIZE, POOL_CHUNK_SIZE);
static void test_expect_init(void)
{
EXPECT_EQ(0U, buf.used);
EXPECT_EQ(buf_data, buf.cur);
EXPECT_EQ(buf_data, buf.data);
EXPECT_EQ(sizeof(buf_data), buf.size);
}
static void test_expect_destroy(void)
{
EXPECT_EQ(NULL, buf.cur);
EXPECT_EQ(NULL, buf.data);
EXPECT_EQ(0U, buf.size);
}
static void test_expect_element(size_t n)
{
EXPECT_EQ(n, buf.used);
EXPECT_EQ(&buf_data[n], buf.cur);
EXPECT_EQ(buf_data, buf.data);
EXPECT_EQ(sizeof(buf_data), buf.size);
}
TEST(buffer, init) {
di_buffer_init(&buf, buf_data, sizeof(buf_data));
test_expect_init();
}
TEST(buffer, destroy)
{
di_buffer_destroy(&buf);
test_expect_destroy();
}
TEST(buffer, write_u8) {
di_buffer_init(&buf, buf_data, sizeof(buf_data));
di_buffer_write_u8(&buf, 'a');
di_buffer_write_u8(&buf, 'b');
di_buffer_write_u8(&buf, 'c');
di_buffer_write_u8(&buf, 'd');
di_buffer_write_u8(&buf, 0);
ASSERT_STREQ("abcd", (const char *)buf.data);
}
TEST(buffer, write_data) {
di_buffer_init(&buf, buf_data, sizeof(buf_data));
/* Write string with null termination */
di_buffer_write_data(&buf, "1234", 5);
ASSERT_STREQ("1234", (const char *)buf.data);
ASSERT_EQ(5U, buf.used);
/* Set buffer to fake size of 3 bytes */
di_buffer_init(&buf, buf_data, 3);
/* Write more data then size of buffer */
di_buffer_write_data(&buf, "1234", 5);
/* Null terminate so we can check with STREQ */
*buf.cur = 0;
ASSERT_STREQ("12", (const char *)buf.data);
}
TEST(buffer, next_reset) {
di_buffer_init(&buf, buf_data, sizeof(buf_data));
ret = di_buffer_next(&buf);
EXPECT_TRUE(ret);
test_expect_element(1);
di_buffer_reset(&buf);
test_expect_init();
}
TEST(buffer, next_until_end) {
di_buffer_init(&buf, buf_data, sizeof(buf_data));
for (size_t n = 0; n < sizeof(buf_data) - 1; n++)
ret = di_buffer_next(&buf);
EXPECT_TRUE(ret);
test_expect_element(255);
}
TEST(buffer, next_overflow_check) {
di_buffer_init(&buf, buf_data, sizeof(buf_data));
for (size_t n = 0; n < sizeof(buf_data) * 2; n++)
ret = di_buffer_next(&buf);
EXPECT_FALSE(ret);
test_expect_element(255);
}
TEST(buffer, next_pos_overflow_check) {
di_buffer_init(&buf, buf_data, sizeof(buf_data));
EXPECT_EQ(0U, buf.used);
EXPECT_EQ(buf_data, buf.cur);
buf.used = SIZE_MAX;
ret = di_buffer_next(&buf);
EXPECT_FALSE(ret);
EXPECT_EQ(buf.used, SIZE_MAX);
EXPECT_EQ(buf_data, buf.cur);
}
TEST(buffer, size_inuse_free) {
const size_t in_use = 8U;
di_buffer_init(&buf, buf_data, sizeof(buf_data));
for (size_t n = 0; n < in_use; n++)
ret = di_buffer_next(&buf);
EXPECT_TRUE(ret);
EXPECT_EQ(sizeof(buf_data), di_buffer_size_free(&buf) + di_buffer_size_inuse(&buf));
EXPECT_EQ(in_use, di_buffer_size_inuse(&buf));
EXPECT_EQ(sizeof(buf_data) - in_use, di_buffer_size_free(&buf));
}
TEST(buffer, memcpy) {
uint8_t data[16];
uint8_t _expect[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
struct di_buffer b;
size_t offset = 8;
di_buffer_init(&b, data, sizeof(data));
di_buffer_flush(&b);
/* Write first 8 byte chunk with testdata */
offset = 0;
ASSERT_EQ(sizeof(_expect), di_buffer_memcpy(&b, offset, _expect, sizeof(_expect)));
ASSERT_EQ(0, memcmp((uint8_t *)b.data + offset, _expect, sizeof(_expect)));
//test_printf_buf(&b);
di_buffer_flush(&b);
/* Write first 8 byte chunk with testdata at offset 1 */
offset = 1;
ASSERT_EQ(sizeof(_expect), di_buffer_memcpy(&b, offset, _expect, sizeof(_expect)));
ASSERT_EQ(0, memcmp((uint8_t *)b.data + offset, _expect, sizeof(_expect)));
//test_printf_buf(&b);
di_buffer_flush(&b);
/* Write second 8 byte chunk with testdata at offset 7 (one byte before end of di_buffer) */
offset = 7;
ASSERT_EQ(sizeof(_expect), di_buffer_memcpy(&b, offset, _expect, sizeof(_expect)));
ASSERT_EQ(0, memcmp((uint8_t *)b.data + offset, _expect, sizeof(_expect)));
//test_printf_buf(&b);
di_buffer_flush(&b);
/* Wright second 8 byte chunk with testdata */
offset = 8;
ASSERT_EQ(sizeof(_expect), di_buffer_memcpy(&b, offset, _expect, sizeof(_expect)));
ASSERT_EQ(0, memcmp((uint8_t *)b.data + offset, _expect, sizeof(_expect)));
//test_printf_buf(&b);
di_buffer_flush(&b);
/* Try to memcpy one byte to much */
offset = 9;
ASSERT_EQ(0U, di_buffer_memcpy(&b, offset, _expect, sizeof(_expect)));
}
TEST(buffer, memmem) {
void *ptr = NULL;
const uint8_t buffer[] = "\x11\x12\x13\x14";
const uint8_t search[] = "\x13";
/* Match */
ptr = di_buffer_memmem(reinterpret_cast<const void *>(buffer), sizeof(buffer) - 1, reinterpret_cast<const void *>(search), sizeof(search) - 1);
EXPECT_EQ(&buffer[2], ptr);
/* 0-length for l_len */
ptr = di_buffer_memmem(reinterpret_cast<const void *>(buffer), 0, reinterpret_cast<const void *>(search), sizeof(search) - 1);
EXPECT_EQ(NULL, ptr);
/* 0-length for s_len */
ptr = di_buffer_memmem(reinterpret_cast<const void *>(buffer), sizeof(buffer) - 1, reinterpret_cast<const void *>(search), 0);
EXPECT_EQ(NULL, ptr);
/* Check length boundary isn't exceeded */
const uint8_t bufabc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const uint8_t searchbuf[] = "U";
ptr = di_buffer_memmem(reinterpret_cast<const void *>(bufabc), 10, reinterpret_cast<const void *>(searchbuf), 1);
EXPECT_EQ(NULL, ptr);
}
TEST(buffer, list_init) {
DI_BUFFER_LIST_INIT(pool, POOL_SIZE, POOL_CHUNK_SIZE);
// Test if the pool buffer pointer is correctly set
EXPECT_EQ(pool.buffer, pool_buffer);
for (size_t n = 0; n < POOL_SIZE; n++) {
EXPECT_FALSE(pool.buffer[n].in_use);
EXPECT_EQ(0U, pool.buffer[n].used);
EXPECT_EQ(POOL_CHUNK_SIZE, pool.buffer[n].size);
EXPECT_EQ(pool_data[n], pool.buffer[n].data);
EXPECT_EQ(pool_data[n], pool.buffer[n].cur);
}
}
TEST(buffer, list_get_return) {
for (size_t n = 0; n < POOL_SIZE; n++) {
EXPECT_FALSE(pool.buffer[n].in_use);
EXPECT_EQ(&pool.buffer[n], di_buffer_list_get(&pool));
EXPECT_TRUE(pool.buffer[n].in_use);
}
for (size_t n = 0; n < POOL_SIZE; n++) {
struct di_buffer *b = &pool.buffer[n];
di_buffer_list_return(&pool, &b);
EXPECT_FALSE(pool.buffer[n].in_use);
}
}
TEST(buffer, list_get_null) {
for (size_t n = 0; n < POOL_SIZE; n++) {
EXPECT_FALSE(pool.buffer[n].in_use);
EXPECT_EQ(&pool.buffer[n], di_buffer_list_get(&pool));
EXPECT_TRUE(pool.buffer[n].in_use);
}
EXPECT_EQ(NULL, di_buffer_list_get(&pool));
}
TEST(buffer, list_return_invalid) {
di_buffer_list_return(NULL, static_cast<struct di_buffer **>(NULL));
di_buffer_list_return(&pool, static_cast<struct di_buffer **>(NULL));
}
/** Check if buf->data is not flushed on reset
*/
TEST(buffer, reset) {
const char *text = "Hello World!";
const size_t size = strlen(text) + 1;
di_buffer_init(&buf, buf_data, sizeof(buf_data));
ASSERT_EQ(size, di_buffer_memcpy(&buf, 0, text, size));
ASSERT_STREQ(text, (const char *)buf.data);
di_buffer_reset(&buf);
ASSERT_STREQ(text, (const char *)buf.data);
test_expect_init();
}
/** Check if reset sets the pos, used and cur members */
TEST(buffer, reset_members) {
di_buffer_init(&buf, buf_data, sizeof(buf_data));
buf.used = 1234;
buf.cur = (uint8_t *)&buf_data + 10;
di_buffer_reset(&buf);
ASSERT_EQ(0U, buf.used);
ASSERT_EQ(buf_data, buf.cur);
}