You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
4.8 KiB
174 lines
4.8 KiB
// test_serialize.c - Unit tests for serialize library with dynamic allocation |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <assert.h> |
|
|
|
#include "../lib/serialize.h" |
|
|
|
#define TEST(name) do { \ |
|
printf("TEST: %-40s ", name); fflush(stdout); \ |
|
} while(0) |
|
|
|
#define PASS() do { puts("PASS"); } while(0) |
|
#define FAIL(msg) do { printf("FAIL: %s\n", msg); exit(1); } while(0) |
|
|
|
#pragma pack(push, 1) |
|
typedef struct { |
|
uint8_t id; |
|
uint16_t port; |
|
uint32_t ip; |
|
uint64_t big_val; |
|
int8_t signed_val; |
|
int32_t signed32; |
|
uint8_t name_len; |
|
char* name; |
|
uint8_t addr_cnt; |
|
uint8_t* addrs; |
|
} TestStruct; |
|
#pragma pack(pop) |
|
|
|
static const struct SerializeField test_fields[] = { |
|
{offsetof(TestStruct, id), 0, 0, 0, 0, 0}, |
|
{offsetof(TestStruct, port), 0, 0, 0, 0, 0}, |
|
{offsetof(TestStruct, ip), 0, 0, 0, 0, 0}, |
|
{offsetof(TestStruct, big_val), 0, 0, 0, 0, 0}, |
|
{offsetof(TestStruct, signed_val), 0, 0, 0, 0, 0}, |
|
{offsetof(TestStruct, signed32), 0, 0, 0, 0, 0}, |
|
{offsetof(TestStruct, name), 1, 64, 1, 1, offsetof(TestStruct, name_len)}, |
|
{offsetof(TestStruct, addrs), 1, 16, 1, 1, offsetof(TestStruct, addr_cnt)}, |
|
}; |
|
|
|
static const struct SerializeSchema test_schema = { |
|
.field_count = sizeof(test_fields) / sizeof(test_fields[0]), |
|
.struct_size = sizeof(TestStruct), |
|
.header_len = 4, |
|
.fields = test_fields |
|
}; |
|
|
|
/* ------------------------------------------------------------------ */ |
|
static void test_alloc_roundtrip(void) { |
|
uint8_t* buf = NULL; |
|
size_t len; |
|
|
|
TestStruct orig = { |
|
.id = 1, |
|
.port = 443, |
|
.ip = 0x01020304, |
|
.big_val = 100, |
|
.signed_val = 10, |
|
.signed32 = 5000, |
|
}; |
|
orig.name = strdup("hello"); |
|
orig.name_len = 5; |
|
orig.addrs = u_malloc(8); |
|
orig.addrs[0] = 192; |
|
orig.addrs[1] = 168; |
|
orig.addrs[2] = 1; |
|
orig.addrs[3] = 1; |
|
orig.addrs[4] = 10; |
|
orig.addrs[5] = 0; |
|
orig.addrs[6] = 0; |
|
orig.addrs[7] = 1; |
|
orig.addr_cnt = 8; |
|
|
|
uint8_t header[] = {0x01, 0x02, 0x03, 0x04}; |
|
TEST("serialize_encode with header"); |
|
int r = serialize_encode(&orig, &test_schema, header, &buf, &len); |
|
if (r != SERIALIZE_ERR_OK) FAIL("serialize_encode failed"); |
|
PASS(); |
|
|
|
TestStruct* restored = NULL; |
|
TEST("serialize_decode (data without header)"); |
|
uint8_t* data_ptr = buf + test_schema.header_len; |
|
r = serialize_decode(data_ptr, len - test_schema.header_len, &test_schema, (void**)&restored); |
|
if (r != SERIALIZE_ERR_OK) FAIL("serialize_decode failed"); |
|
PASS(); |
|
|
|
TEST("check restored not NULL"); |
|
if (!restored) FAIL("restored is NULL"); |
|
PASS(); |
|
|
|
TEST("check id"); |
|
if (restored->id != orig.id) FAIL("id mismatch"); |
|
PASS(); |
|
|
|
TEST("check port"); |
|
if (restored->port != orig.port) FAIL("port mismatch"); |
|
PASS(); |
|
|
|
TEST("check asciiz"); |
|
if (!restored->name || strcmp(restored->name, "hello") != 0) FAIL("name mismatch"); |
|
PASS(); |
|
|
|
TEST("check array"); |
|
if (!restored->addrs || restored->addrs[0] != 192) FAIL("addrs[0] mismatch"); |
|
PASS(); |
|
|
|
TEST("check name_len"); |
|
if (restored->name_len != 5) FAIL("name_len mismatch"); |
|
PASS(); |
|
|
|
TEST("check addr_cnt"); |
|
if (restored->addr_cnt != 8) FAIL("addr_cnt mismatch"); |
|
PASS(); |
|
|
|
TEST("serialize_free"); |
|
serialize_free(&test_schema, (void**)&restored); |
|
if (restored) FAIL("ptr should be NULL"); |
|
PASS(); |
|
|
|
u_free(buf); |
|
} |
|
|
|
static void test_free(void) { |
|
uint8_t* buf = NULL; |
|
size_t len; |
|
|
|
TestStruct orig = { |
|
.id = 2, |
|
.port = 9000, |
|
}; |
|
orig.name = strdup("test"); |
|
orig.name_len = 4; |
|
orig.addrs = u_malloc(4); |
|
orig.addrs[0] = 10; |
|
orig.addrs[1] = 0; |
|
orig.addrs[2] = 0; |
|
orig.addrs[3] = 1; |
|
orig.addr_cnt = 4; |
|
|
|
uint8_t header2[] = {0xFF, 0xEE, 0xDD, 0xCC}; |
|
TEST("serialize_encode for free"); |
|
int r = serialize_encode(&orig, &test_schema, header2, &buf, &len); |
|
if (r != SERIALIZE_ERR_OK) FAIL("serialize_encode failed"); |
|
PASS(); |
|
|
|
TestStruct* restored = NULL; |
|
TEST("serialize_decode for free"); |
|
uint8_t* data_ptr2 = buf + test_schema.header_len; |
|
r = serialize_decode(data_ptr2, len - test_schema.header_len, &test_schema, (void**)&restored); |
|
if (r != SERIALIZE_ERR_OK) FAIL("serialize_decode failed"); |
|
PASS(); |
|
|
|
TEST("serialize_free"); |
|
serialize_free(&test_schema, (void**)&restored); |
|
if (restored) FAIL("ptr should be NULL"); |
|
PASS(); |
|
|
|
u_free(buf); |
|
free(orig.name); |
|
u_free(orig.addrs); |
|
} |
|
|
|
/* ------------------------------------------------------------------ */ |
|
int main(void) { |
|
printf("=== Serialize Library Tests ===\n\n"); |
|
|
|
test_alloc_roundtrip(); |
|
test_free(); |
|
|
|
printf("\n=== All tests passed ===\n"); |
|
return 0; |
|
} |