500 lines
11 KiB
C
500 lines
11 KiB
C
|
/*
|
||
|
* test_savebuffer.c
|
||
|
* Luabins SaveBuffer tests
|
||
|
* See copyright notice in luabins.h
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* TODO: Tests are tuned for old fixed-increment memory allocation strategy.
|
||
|
* Test for exponential growth corner-cases specifically.
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "lualess.h"
|
||
|
#include "savebuffer.h"
|
||
|
|
||
|
#include "test.h"
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
static size_t NOT_CHANGED = (size_t)-1;
|
||
|
static void * NOT_CHANGED_PTR = NULL;
|
||
|
|
||
|
static size_t DUMMY = (size_t)-42;
|
||
|
static void * DUMMY_PTR = NULL;
|
||
|
|
||
|
static void * g_last_ud = NULL;
|
||
|
static size_t g_last_osize = 0;
|
||
|
|
||
|
static void reset_alloc_globals()
|
||
|
{
|
||
|
g_last_ud = NOT_CHANGED_PTR;
|
||
|
g_last_osize = NOT_CHANGED;
|
||
|
}
|
||
|
|
||
|
static void init_globals()
|
||
|
{
|
||
|
NOT_CHANGED_PTR = (void *)&NOT_CHANGED;
|
||
|
DUMMY_PTR = (void *)&DUMMY;
|
||
|
|
||
|
reset_alloc_globals();
|
||
|
}
|
||
|
|
||
|
static void * dummy_alloc(
|
||
|
void * ud,
|
||
|
void * ptr,
|
||
|
size_t osize,
|
||
|
size_t nsize
|
||
|
)
|
||
|
{
|
||
|
g_last_ud = ud;
|
||
|
g_last_osize = osize;
|
||
|
|
||
|
if (nsize == 0)
|
||
|
{
|
||
|
free(ptr);
|
||
|
return NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return realloc(ptr, nsize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
static void check_alloc(void * expected_ud, size_t expected_osize)
|
||
|
{
|
||
|
if (g_last_ud != expected_ud)
|
||
|
{
|
||
|
fprintf(
|
||
|
stderr,
|
||
|
"userdata mismatch in allocator: got %p, expected %p\n",
|
||
|
g_last_ud, expected_ud
|
||
|
);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
if (g_last_osize != expected_osize)
|
||
|
{
|
||
|
fprintf(
|
||
|
stderr,
|
||
|
"old size mismatch in allocator: got %lu, expected %lu\n",
|
||
|
g_last_osize, expected_osize
|
||
|
);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
reset_alloc_globals();
|
||
|
}
|
||
|
|
||
|
static void check_buffer(
|
||
|
luabins_SaveBuffer * sb,
|
||
|
const char * expected_buf_c,
|
||
|
size_t expected_length,
|
||
|
void * expected_ud,
|
||
|
size_t expected_osize
|
||
|
)
|
||
|
{
|
||
|
const unsigned char * expected_buf = (const unsigned char *)expected_buf_c;
|
||
|
|
||
|
{
|
||
|
size_t actual_length = lbsSB_length(sb);
|
||
|
if (actual_length != expected_length)
|
||
|
{
|
||
|
fprintf(
|
||
|
stderr,
|
||
|
"lbsSB_length mismatch in allocator: got %lu, expected %lu\n",
|
||
|
actual_length, expected_length
|
||
|
);
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
{
|
||
|
size_t actual_length = (size_t)-1;
|
||
|
const unsigned char * actual_buf = lbsSB_buffer(sb, &actual_length);
|
||
|
if (actual_length != expected_length)
|
||
|
{
|
||
|
fprintf(
|
||
|
stderr,
|
||
|
"lsbSB_buffer length mismatch in allocator: got %lu, expected %lu\n",
|
||
|
actual_length, expected_length
|
||
|
);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
if (memcmp(actual_buf, expected_buf, expected_length) != 0)
|
||
|
{
|
||
|
fprintf(
|
||
|
stderr,
|
||
|
"lsbSB_buffer buf mismatch in allocator\n"
|
||
|
);
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
check_alloc(expected_ud, expected_osize);
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
TEST (test_init_destroy,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
check_buffer(&sb, "", 0, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
})
|
||
|
|
||
|
TEST (test_grow_zero,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_grow(&sb, 0);
|
||
|
check_buffer(&sb, "", 0, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
})
|
||
|
|
||
|
TEST (test_grow_bufsiz,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_grow(&sb, 1024);
|
||
|
check_buffer(&sb, "", 0, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 1344);
|
||
|
})
|
||
|
|
||
|
TEST (test_grow_one,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_grow(&sb, 1);
|
||
|
check_buffer(&sb, "", 0, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_grow_one_grow_one_noop,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_grow(&sb, 1);
|
||
|
check_buffer(&sb, "", 0, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_grow(&sb, 1);
|
||
|
check_buffer(&sb, "", 0, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_grow_one_grow_bufsiz_noop,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_grow(&sb, 1);
|
||
|
check_buffer(&sb, "", 0, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_grow(&sb, 255);
|
||
|
check_buffer(&sb, "", 0, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_grow_one_grow_bufsiz_one,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_grow(&sb, 1);
|
||
|
check_buffer(&sb, "", 0, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_grow(&sb, 257);
|
||
|
check_buffer(&sb, "", 0, DUMMY_PTR, 256);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 512);
|
||
|
})
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
TEST (test_write_empty,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"", 0);
|
||
|
check_buffer(&sb, "", 0, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
})
|
||
|
|
||
|
TEST (test_write,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"42", 3);
|
||
|
check_buffer(&sb, "42", 3, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_write_embedded_zero,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"4\02", 4);
|
||
|
check_buffer(&sb, "4\02", 4, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_write_write_smallsiz,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"01234567", 8);
|
||
|
check_buffer(&sb, "01234567", 8, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"01234567", 8);
|
||
|
check_buffer(&sb, "0123456701234567", 8 + 8, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"0123", 4);
|
||
|
check_buffer(
|
||
|
&sb,
|
||
|
"01234567012345670123",
|
||
|
8 + 8 + 4,
|
||
|
NOT_CHANGED_PTR,
|
||
|
NOT_CHANGED
|
||
|
);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"0123456789ABCDEF", 16);
|
||
|
check_buffer(
|
||
|
&sb,
|
||
|
"012345670123456701230123456789ABCDEF",
|
||
|
8 + 8 + 4 + 16,
|
||
|
NOT_CHANGED_PTR,
|
||
|
NOT_CHANGED
|
||
|
);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
TEST (test_writechar,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_writechar(&sb, 'A');
|
||
|
check_buffer(&sb, "A", 1, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_writechar_zero,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_writechar(&sb, '\0');
|
||
|
check_buffer(&sb, "\0", 1, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_write_writechar_smallsiz,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"01234567", 8);
|
||
|
check_buffer(&sb, "01234567", 8, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_writechar(&sb, 'A');
|
||
|
check_buffer(&sb, "01234567A", 8 + 1, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
TEST (test_overwrite_empty,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_overwrite(&sb, 0, (unsigned char*)"42", 3);
|
||
|
check_buffer(&sb, "42", 3, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_overwrite_inplace,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"ABCD", 4);
|
||
|
check_buffer(&sb, "ABCD", 4, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_overwrite(&sb, 1, (unsigned char*)"42", 2);
|
||
|
check_buffer(&sb, "A42D", 4, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_overwrite_overflow,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"ABCD", 4);
|
||
|
check_buffer(&sb, "ABCD", 4, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_overwrite(&sb, 3, (unsigned char*)"42", 2);
|
||
|
check_buffer(&sb, "ABC42", 5, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_overwrite_overflow_grows,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"012345", 6);
|
||
|
check_buffer(&sb, "012345", 6, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_overwrite(&sb, 4, (unsigned char*)"ABCDEF", 6);
|
||
|
check_buffer(&sb, "0123ABCDEF", 10, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_overwrite_large_offset_appends,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"012345", 6);
|
||
|
check_buffer(&sb, "012345", 6, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_overwrite(&sb, 100, (unsigned char*)"ABCDEF", 6);
|
||
|
check_buffer(&sb, "012345ABCDEF", 12, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
TEST (test_overwritechar_empty_buffer,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_overwritechar(&sb, 0, 'A');
|
||
|
check_buffer(&sb, "A", 1, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_overwritechar_inplace,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"ABCD", 4);
|
||
|
check_buffer(&sb, "ABCD", 4, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_overwritechar(&sb, 1, '!');
|
||
|
check_buffer(&sb, "A!CD", 4, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
TEST (test_overwritechar_large_offset_appends,
|
||
|
{
|
||
|
luabins_SaveBuffer sb;
|
||
|
lbsSB_init(&sb, dummy_alloc, DUMMY_PTR);
|
||
|
|
||
|
lbsSB_write(&sb, (unsigned char*)"01234567", 8);
|
||
|
check_buffer(&sb, "01234567", 8, DUMMY_PTR, 0);
|
||
|
|
||
|
lbsSB_overwritechar(&sb, 100, '!');
|
||
|
check_buffer(&sb, "01234567!", 9, NOT_CHANGED_PTR, NOT_CHANGED);
|
||
|
|
||
|
lbsSB_destroy(&sb);
|
||
|
check_alloc(DUMMY_PTR, 256);
|
||
|
})
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
void test_savebuffer()
|
||
|
{
|
||
|
init_globals();
|
||
|
|
||
|
test_init_destroy();
|
||
|
test_grow_zero();
|
||
|
test_grow_bufsiz();
|
||
|
test_grow_one();
|
||
|
test_grow_one_grow_one_noop();
|
||
|
test_grow_one_grow_bufsiz_noop();
|
||
|
test_grow_one_grow_bufsiz_one();
|
||
|
|
||
|
test_write_empty();
|
||
|
test_write();
|
||
|
test_write_embedded_zero();
|
||
|
test_write_write_smallsiz();
|
||
|
|
||
|
test_writechar();
|
||
|
test_writechar_zero();
|
||
|
test_write_writechar_smallsiz();
|
||
|
|
||
|
test_overwrite_empty();
|
||
|
test_overwrite_inplace();
|
||
|
test_overwrite_overflow();
|
||
|
test_overwrite_overflow_grows();
|
||
|
test_overwrite_large_offset_appends();
|
||
|
|
||
|
test_overwritechar_empty_buffer();
|
||
|
test_overwritechar_inplace();
|
||
|
test_overwritechar_large_offset_appends();
|
||
|
}
|