mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 15:45:25 +00:00
convert rbt_serialize_test
This commit is contained in:
@@ -10,17 +10,23 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* ! \file */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <atf-c.h>
|
#if HAVE_CMOCKA
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#define UNIT_TESTING
|
||||||
|
#include <cmocka.h>
|
||||||
|
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/random.h>
|
#include <isc/random.h>
|
||||||
@@ -55,6 +61,27 @@
|
|||||||
#define MAP_FILE 0
|
#define MAP_FILE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
_setup(void **state) {
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
result = dns_test_begin(NULL, false);
|
||||||
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_teardown(void **state) {
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
dns_test_end();
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct data_holder {
|
typedef struct data_holder {
|
||||||
int len;
|
int len;
|
||||||
const char *data;
|
const char *data;
|
||||||
@@ -117,8 +144,9 @@ write_data(FILE *file, unsigned char *datap, void *arg, uint64_t *crc) {
|
|||||||
(data->len != 0 && data->data != NULL));
|
(data->len != 0 && data->data != NULL));
|
||||||
|
|
||||||
result = isc_stdio_tell(file, &where);
|
result = isc_stdio_tell(file, &where);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS) {
|
||||||
return (result);
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
temp = *data;
|
temp = *data;
|
||||||
temp.data = (data->len == 0
|
temp.data = (data->len == 0
|
||||||
@@ -127,22 +155,22 @@ write_data(FILE *file, unsigned char *datap, void *arg, uint64_t *crc) {
|
|||||||
|
|
||||||
isc_crc64_update(crc, (void *)&temp, sizeof(temp));
|
isc_crc64_update(crc, (void *)&temp, sizeof(temp));
|
||||||
ret = fwrite(&temp, sizeof(data_holder_t), 1, file);
|
ret = fwrite(&temp, sizeof(data_holder_t), 1, file);
|
||||||
if (ret != 1)
|
if (ret != 1) {
|
||||||
return (ISC_R_FAILURE);
|
return (ISC_R_FAILURE);
|
||||||
|
}
|
||||||
if (data->len > 0) {
|
if (data->len > 0) {
|
||||||
isc_crc64_update(crc, (const void *)data->data, data->len);
|
isc_crc64_update(crc, (const void *)data->data, data->len);
|
||||||
ret = fwrite(data->data, data->len, 1, file);
|
ret = fwrite(data->data, data->len, 1, file);
|
||||||
if (ret != 1)
|
if (ret != 1) {
|
||||||
return (ISC_R_FAILURE);
|
return (ISC_R_FAILURE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
fix_data(dns_rbtnode_t *p, void *base, size_t max, void *arg,
|
fix_data(dns_rbtnode_t *p, void *base, size_t max, void *arg, uint64_t *crc) {
|
||||||
uint64_t *crc)
|
|
||||||
{
|
|
||||||
data_holder_t *data = p->data;
|
data_holder_t *data = p->data;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
@@ -154,31 +182,29 @@ fix_data(dns_rbtnode_t *p, void *base, size_t max, void *arg,
|
|||||||
REQUIRE(p != NULL);
|
REQUIRE(p != NULL);
|
||||||
|
|
||||||
|
|
||||||
if (data == NULL)
|
|
||||||
printf("fixing data: data NULL\n");
|
|
||||||
else
|
|
||||||
printf("fixing data: len %d, data %p\n", data->len, data->data);
|
|
||||||
|
|
||||||
if (data == NULL ||
|
if (data == NULL ||
|
||||||
(data->len == 0 && data->data != NULL) ||
|
(data->len == 0 && data->data != NULL) ||
|
||||||
(data->len != 0 && data->data == NULL))
|
(data->len != 0 && data->data == NULL))
|
||||||
|
{
|
||||||
return (ISC_R_INVALIDFILE);
|
return (ISC_R_INVALIDFILE);
|
||||||
|
}
|
||||||
|
|
||||||
size = max - ((char *)p - (char *)base);
|
size = max - ((char *)p - (char *)base);
|
||||||
|
|
||||||
if (data->len > (int) size || data->data > (const char *) max) {
|
if (data->len > (int) size || data->data > (const char *) max) {
|
||||||
printf("data invalid\n");
|
|
||||||
return (ISC_R_INVALIDFILE);
|
return (ISC_R_INVALIDFILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_crc64_update(crc, (void *)data, sizeof(*data));
|
isc_crc64_update(crc, (void *)data, sizeof(*data));
|
||||||
|
|
||||||
data->data = (data->len == 0)
|
data->data = NULL;
|
||||||
? NULL
|
if (data->len != 0) {
|
||||||
: (char *)data + sizeof(data_holder_t);
|
data->data = (char *)data + sizeof(data_holder_t);
|
||||||
|
}
|
||||||
|
|
||||||
if (data->len > 0)
|
if (data->len > 0) {
|
||||||
isc_crc64_update(crc, (const void *)data->data, data->len);
|
isc_crc64_update(crc, (const void *)data->data, data->len);
|
||||||
|
}
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
@@ -212,7 +238,7 @@ add_test_data(isc_mem_t *mymctx, dns_rbt_t *rbt) {
|
|||||||
|
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
result = dns_rbt_addname(rbt, name, &testdatap->data);
|
result = dns_rbt_addname(rbt, name, &testdatap->data);
|
||||||
ATF_CHECK_STREQ(dns_result_totext(result), "success");
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
testdatap++;
|
testdatap++;
|
||||||
}
|
}
|
||||||
@@ -254,25 +280,22 @@ check_test_data(dns_rbt_t *rbt) {
|
|||||||
data = NULL;
|
data = NULL;
|
||||||
result = dns_rbt_findname(rbt, name, 0, foundname,
|
result = dns_rbt_findname(rbt, name, 0, foundname,
|
||||||
(void *) &data);
|
(void *) &data);
|
||||||
ATF_CHECK_STREQ(dns_result_totext(result), "success");
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
testdatap++;
|
testdatap++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
data_printer(FILE *out, void *datap)
|
data_printer(FILE *out, void *datap) {
|
||||||
{
|
|
||||||
data_holder_t *data = (data_holder_t *)datap;
|
data_holder_t *data = (data_holder_t *)datap;
|
||||||
|
|
||||||
fprintf(out, "%d bytes, %s", data->len, data->data);
|
fprintf(out, "%d bytes, %s", data->len, data->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ATF_TC(serialize);
|
/* Test writing an rbt to file */
|
||||||
ATF_TC_HEAD(serialize, tc) {
|
static void
|
||||||
atf_tc_set_md_var(tc, "descr", "Test writing an rbt to file");
|
serialize_test(void **state) {
|
||||||
}
|
|
||||||
ATF_TC_BODY(serialize, tc) {
|
|
||||||
dns_rbt_t *rbt = NULL;
|
dns_rbt_t *rbt = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
FILE *rbtfile = NULL;
|
FILE *rbtfile = NULL;
|
||||||
@@ -282,14 +305,12 @@ ATF_TC_BODY(serialize, tc) {
|
|||||||
off_t filesize = 0;
|
off_t filesize = 0;
|
||||||
char *base;
|
char *base;
|
||||||
|
|
||||||
UNUSED(tc);
|
UNUSED(state);
|
||||||
|
|
||||||
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
||||||
|
|
||||||
result = dns_test_begin(NULL, true);
|
|
||||||
ATF_CHECK_STREQ(dns_result_totext(result), "success");
|
|
||||||
result = dns_rbt_create(mctx, delete_data, NULL, &rbt);
|
result = dns_rbt_create(mctx, delete_data, NULL, &rbt);
|
||||||
ATF_CHECK_STREQ(dns_result_totext(result), "success");
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
add_test_data(mctx, rbt);
|
add_test_data(mctx, rbt);
|
||||||
|
|
||||||
@@ -298,28 +319,22 @@ ATF_TC_BODY(serialize, tc) {
|
|||||||
/*
|
/*
|
||||||
* Serialize the tree.
|
* Serialize the tree.
|
||||||
*/
|
*/
|
||||||
printf("serialization begins.\n");
|
|
||||||
rbtfile = fopen("./zone.bin", "w+b");
|
rbtfile = fopen("./zone.bin", "w+b");
|
||||||
ATF_REQUIRE(rbtfile != NULL);
|
assert_non_null(rbtfile);
|
||||||
result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL,
|
result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL,
|
||||||
&offset);
|
&offset);
|
||||||
ATF_REQUIRE(result == ISC_R_SUCCESS);
|
assert_true(result == ISC_R_SUCCESS);
|
||||||
dns_rbt_destroy(&rbt);
|
dns_rbt_destroy(&rbt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deserialize the tree
|
* Deserialize the tree.
|
||||||
*/
|
|
||||||
printf("deserialization begins.\n");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map in the whole file in one go
|
* Map in the whole file in one go
|
||||||
*/
|
*/
|
||||||
fd = open("zone.bin", O_RDWR);
|
fd = open("zone.bin", O_RDWR);
|
||||||
isc_file_getsizefd(fd, &filesize);
|
isc_file_getsizefd(fd, &filesize);
|
||||||
base = mmap(NULL, filesize,
|
base = mmap(NULL, filesize, PROT_READ|PROT_WRITE,
|
||||||
PROT_READ|PROT_WRITE,
|
|
||||||
MAP_FILE|MAP_PRIVATE, fd, 0);
|
MAP_FILE|MAP_PRIVATE, fd, 0);
|
||||||
ATF_REQUIRE(base != NULL && base != MAP_FAILED);
|
assert_true(base != NULL && base != MAP_FAILED);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
result = dns_rbt_deserialize_tree(base, filesize, 0, mctx,
|
result = dns_rbt_deserialize_tree(base, filesize, 0, mctx,
|
||||||
@@ -327,9 +342,10 @@ ATF_TC_BODY(serialize, tc) {
|
|||||||
NULL, &rbt_deserialized);
|
NULL, &rbt_deserialized);
|
||||||
|
|
||||||
/* Test to make sure we have a valid tree */
|
/* Test to make sure we have a valid tree */
|
||||||
ATF_REQUIRE(result == ISC_R_SUCCESS);
|
assert_true(result == ISC_R_SUCCESS);
|
||||||
if (rbt_deserialized == NULL)
|
if (rbt_deserialized == NULL) {
|
||||||
atf_tc_fail("deserialized rbt is null!"); /* Abort execution. */
|
fail_msg("deserialized rbt is null!"); /* Abort execution. */
|
||||||
|
}
|
||||||
|
|
||||||
check_test_data(rbt_deserialized);
|
check_test_data(rbt_deserialized);
|
||||||
|
|
||||||
@@ -338,14 +354,11 @@ ATF_TC_BODY(serialize, tc) {
|
|||||||
dns_rbt_destroy(&rbt_deserialized);
|
dns_rbt_destroy(&rbt_deserialized);
|
||||||
munmap(base, filesize);
|
munmap(base, filesize);
|
||||||
unlink("zone.bin");
|
unlink("zone.bin");
|
||||||
dns_test_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ATF_TC(deserialize_corrupt);
|
/* Test reading a corrupt map file */
|
||||||
ATF_TC_HEAD(deserialize_corrupt, tc) {
|
static void
|
||||||
atf_tc_set_md_var(tc, "descr", "Test reading a corrupt map file");
|
deserialize_corrupt_test(void **state) {
|
||||||
}
|
|
||||||
ATF_TC_BODY(deserialize_corrupt, tc) {
|
|
||||||
dns_rbt_t *rbt = NULL;
|
dns_rbt_t *rbt = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
FILE *rbtfile = NULL;
|
FILE *rbtfile = NULL;
|
||||||
@@ -355,23 +368,20 @@ ATF_TC_BODY(deserialize_corrupt, tc) {
|
|||||||
char *base, *p, *q;
|
char *base, *p, *q;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
UNUSED(tc);
|
UNUSED(state);
|
||||||
|
|
||||||
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
||||||
|
|
||||||
result = dns_test_begin(NULL, true);
|
|
||||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
|
||||||
|
|
||||||
/* Set up map file */
|
/* Set up map file */
|
||||||
result = dns_rbt_create(mctx, delete_data, NULL, &rbt);
|
result = dns_rbt_create(mctx, delete_data, NULL, &rbt);
|
||||||
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
add_test_data(mctx, rbt);
|
add_test_data(mctx, rbt);
|
||||||
rbtfile = fopen("./zone.bin", "w+b");
|
rbtfile = fopen("./zone.bin", "w+b");
|
||||||
ATF_REQUIRE(rbtfile != NULL);
|
assert_non_null(rbtfile);
|
||||||
result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL,
|
result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL,
|
||||||
&offset);
|
&offset);
|
||||||
ATF_REQUIRE(result == ISC_R_SUCCESS);
|
assert_true(result == ISC_R_SUCCESS);
|
||||||
dns_rbt_destroy(&rbt);
|
dns_rbt_destroy(&rbt);
|
||||||
|
|
||||||
/* Read back with random fuzzing */
|
/* Read back with random fuzzing */
|
||||||
@@ -380,10 +390,9 @@ ATF_TC_BODY(deserialize_corrupt, tc) {
|
|||||||
|
|
||||||
fd = open("zone.bin", O_RDWR);
|
fd = open("zone.bin", O_RDWR);
|
||||||
isc_file_getsizefd(fd, &filesize);
|
isc_file_getsizefd(fd, &filesize);
|
||||||
base = mmap(NULL, filesize,
|
base = mmap(NULL, filesize, PROT_READ|PROT_WRITE,
|
||||||
PROT_READ|PROT_WRITE,
|
|
||||||
MAP_FILE|MAP_PRIVATE, fd, 0);
|
MAP_FILE|MAP_PRIVATE, fd, 0);
|
||||||
ATF_REQUIRE(base != NULL && base != MAP_FAILED);
|
assert_true(base != NULL && base != MAP_FAILED);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
/* Randomly fuzz a portion of the memory */
|
/* Randomly fuzz a portion of the memory */
|
||||||
@@ -398,54 +407,64 @@ ATF_TC_BODY(deserialize_corrupt, tc) {
|
|||||||
delete_data, NULL,
|
delete_data, NULL,
|
||||||
fix_data, NULL,
|
fix_data, NULL,
|
||||||
NULL, &rbt_deserialized);
|
NULL, &rbt_deserialized);
|
||||||
printf("%d: %s\n", i, isc_result_totext(result));
|
|
||||||
|
|
||||||
/* Test to make sure we have a valid tree */
|
/* Test to make sure we have a valid tree */
|
||||||
ATF_REQUIRE(result == ISC_R_SUCCESS ||
|
assert_true(result == ISC_R_SUCCESS ||
|
||||||
result == ISC_R_INVALIDFILE);
|
result == ISC_R_INVALIDFILE);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS) {
|
||||||
ATF_REQUIRE(rbt_deserialized == NULL);
|
assert_null(rbt_deserialized);
|
||||||
|
}
|
||||||
|
|
||||||
if (rbt_deserialized != NULL)
|
if (rbt_deserialized != NULL) {
|
||||||
dns_rbt_destroy(&rbt_deserialized);
|
dns_rbt_destroy(&rbt_deserialized);
|
||||||
|
}
|
||||||
|
|
||||||
munmap(base, filesize);
|
munmap(base, filesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink("zone.bin");
|
unlink("zone.bin");
|
||||||
dns_test_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test the dns_rbt_serialize_align() function */
|
||||||
|
static void
|
||||||
|
serialize_align_test(void **state) {
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
ATF_TC(serialize_align);
|
assert_true(dns_rbt_serialize_align(0) == 0);
|
||||||
ATF_TC_HEAD(serialize_align, tc) {
|
assert_true(dns_rbt_serialize_align(1) == 8);
|
||||||
atf_tc_set_md_var(tc, "descr",
|
assert_true(dns_rbt_serialize_align(2) == 8);
|
||||||
"Test the dns_rbt_serialize_align() function.");
|
assert_true(dns_rbt_serialize_align(3) == 8);
|
||||||
}
|
assert_true(dns_rbt_serialize_align(4) == 8);
|
||||||
ATF_TC_BODY(serialize_align, tc) {
|
assert_true(dns_rbt_serialize_align(5) == 8);
|
||||||
UNUSED(tc);
|
assert_true(dns_rbt_serialize_align(6) == 8);
|
||||||
|
assert_true(dns_rbt_serialize_align(7) == 8);
|
||||||
ATF_CHECK(dns_rbt_serialize_align(0) == 0);
|
assert_true(dns_rbt_serialize_align(8) == 8);
|
||||||
ATF_CHECK(dns_rbt_serialize_align(1) == 8);
|
assert_true(dns_rbt_serialize_align(9) == 16);
|
||||||
ATF_CHECK(dns_rbt_serialize_align(2) == 8);
|
assert_true(dns_rbt_serialize_align(0xff) == 0x100);
|
||||||
ATF_CHECK(dns_rbt_serialize_align(3) == 8);
|
assert_true(dns_rbt_serialize_align(0x301) == 0x308);
|
||||||
ATF_CHECK(dns_rbt_serialize_align(4) == 8);
|
|
||||||
ATF_CHECK(dns_rbt_serialize_align(5) == 8);
|
|
||||||
ATF_CHECK(dns_rbt_serialize_align(6) == 8);
|
|
||||||
ATF_CHECK(dns_rbt_serialize_align(7) == 8);
|
|
||||||
ATF_CHECK(dns_rbt_serialize_align(8) == 8);
|
|
||||||
ATF_CHECK(dns_rbt_serialize_align(9) == 16);
|
|
||||||
ATF_CHECK(dns_rbt_serialize_align(0xff) == 0x100);
|
|
||||||
ATF_CHECK(dns_rbt_serialize_align(0x301) == 0x308);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int
|
||||||
* Main
|
main(void) {
|
||||||
*/
|
const struct CMUnitTest tests[] = {
|
||||||
ATF_TP_ADD_TCS(tp) {
|
cmocka_unit_test_setup_teardown(serialize_test,
|
||||||
ATF_TP_ADD_TC(tp, serialize);
|
_setup, _teardown),
|
||||||
ATF_TP_ADD_TC(tp, deserialize_corrupt);
|
cmocka_unit_test_setup_teardown(deserialize_corrupt_test,
|
||||||
ATF_TP_ADD_TC(tp, serialize_align);
|
_setup, _teardown),
|
||||||
|
cmocka_unit_test(serialize_align_test),
|
||||||
|
};
|
||||||
|
|
||||||
return (atf_no_error());
|
return (cmocka_run_group_tests(tests, NULL, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* HAVE_CMOCKA */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void) {
|
||||||
|
printf("1..0 # Skipped: cmocka not available\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Reference in New Issue
Block a user