/* * BIRD Library -- Buffer Tests * * (c) 2015 CZ.NIC z.s.p.o. * * Can be freely distributed and used under the terms of the GNU GPL. */ #include #include "test/birdtest.h" #include "sysdep/config.h" #include "lib/resource.h" #include "lib/buffer.h" #define MAX_NUM 33 typedef BUFFER(int) buffer_int; int expected[MAX_NUM]; buffer_int buffer; struct pool *buffer_pool; static void show_buf(buffer_int *b) { int i; bt_debug(".used = %d, .size = %d\n", b->used, b->size); for (i = 0; i < b->used; i++) bt_debug(" .data[%3d] = %-16d expected %-16d %s\n", i, b->data[i], expected[i], (b->data[i] == expected[i] ? "OK" : "FAIL!")); } static void fill_expected_array(void) { int i; for (i = 0; i < MAX_NUM; i++) expected[i] = bt_rand_num(); } static void init_buffer(void) { buffer_pool = NULL; BUFFER_INIT(buffer, buffer_pool, MAX_NUM); } static void free_buffer(void) { free(buffer_pool); } static int is_buffer_as_expected(buffer_int *b) { show_buf(b); int i; for (i = 0; i < MAX_NUM; i++) bt_assert(b->data[i] == expected[i]); return 1; } static int t_buffer_push(void) { int i; init_buffer(); fill_expected_array(); for (i = 0; i < MAX_NUM; i++) BUFFER_PUSH(buffer) = expected[i]; is_buffer_as_expected(&buffer); free_buffer(); return BT_SUCCESS; } static int t_buffer_pop(void) { int i; init_buffer(); fill_expected_array(); /* POP a half of elements */ for (i = 0; i < MAX_NUM; i++) BUFFER_PUSH(buffer) = expected[i]; for (i = MAX_NUM-1; i >= MAX_NUM/2; i--) BUFFER_POP(buffer); for (i = MAX_NUM/2; i < MAX_NUM; i++) BUFFER_PUSH(buffer) = expected[i] = bt_rand_num(); is_buffer_as_expected(&buffer); /* POP all of elements */ for (i = MAX_NUM-1; i >= 0; i--) BUFFER_POP(buffer); bt_assert(buffer.used == 0); for (i = 0; i < MAX_NUM; i++) BUFFER_PUSH(buffer) = expected[i]; is_buffer_as_expected(&buffer); free_buffer(); return BT_SUCCESS; } static int t_buffer_resize(void) { int i; buffer_pool = NULL; BUFFER_INIT(buffer, buffer_pool, 0); fill_expected_array(); for (i = 0; i < MAX_NUM; i++) BUFFER_PUSH(buffer) = expected[i]; is_buffer_as_expected(&buffer); bt_assert(buffer.size >= MAX_NUM); free_buffer(); return BT_SUCCESS; } static int t_buffer_flush(void) { int i; init_buffer(); fill_expected_array(); for (i = 0; i < MAX_NUM; i++) BUFFER_PUSH(buffer) = expected[i]; BUFFER_FLUSH(buffer); bt_assert(buffer.used == 0); free_buffer(); return BT_SUCCESS; } int main(int argc, char *argv[]) { bt_init(argc, argv); bt_test_suite(t_buffer_push, "Pushing new elements"); bt_test_suite(t_buffer_pop, "Fill whole buffer (PUSH), a half of elements POP and PUSH new elements"); bt_test_suite(t_buffer_resize, "Init a small buffer and try overfill"); bt_test_suite(t_buffer_flush, "Fill and flush all elements"); return bt_end(); } /* Mockup */ void * mb_alloc(pool *UNUSED, unsigned size) { return (void *) malloc(size); }; /* Mockup */ #define STEP_UP(x) ((x) + (x)/2 + 4) #define MIN_(a,b) (((a)<(b))?(a):(b)) #define MIN(a,b) MIN_(a,b) void buffer_realloc(void **buf, unsigned *size, unsigned need, unsigned item_size) { unsigned nsize = MIN(*size, need); while (nsize < need) nsize = STEP_UP(nsize); *buf = realloc(*buf, nsize * item_size); *size = nsize; }