diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:24:08 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:24:08 +0000 |
commit | f449f278dd3c70e479a035f50a9bb817a9b433ba (patch) | |
tree | 8ca2bfb785dda9bb4d573acdf9b42aea9cd51383 /tests/libknot/test_rdataset.c | |
parent | Initial commit. (diff) | |
download | knot-upstream.tar.xz knot-upstream.zip |
Adding upstream version 3.2.6.upstream/3.2.6upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | tests/libknot/test_rdataset.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/tests/libknot/test_rdataset.c b/tests/libknot/test_rdataset.c new file mode 100644 index 0000000..d364be3 --- /dev/null +++ b/tests/libknot/test_rdataset.c @@ -0,0 +1,227 @@ +/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> +#include <string.h> + +#include "libknot/rdataset.c" +#include "libknot/libknot.h" + +// Inits rdataset with given rdata. +#define RDATASET_INIT_WITH(set, rdata) \ + knot_rdataset_clear(&set, NULL); \ + ret = knot_rdataset_add(&set, rdata, NULL); \ + assert(ret == KNOT_EOK); + +static size_t rdataset_size(const knot_rdataset_t *rrs) +{ + if (rrs == NULL || rrs->count == 0) { + return 0; + } + + const knot_rdata_t *last = rr_seek(rrs, rrs->count - 1); + return (uint8_t *)last + knot_rdata_size(last->len) - (uint8_t *)rrs->rdata; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Test init + knot_rdataset_t rdataset; + knot_rdataset_init(&rdataset); + ok(rdataset.rdata == NULL && rdataset.count == 0 && rdataset.size == 0, "rdataset: init."); + + // Test rdata addition + uint8_t buf_gt[knot_rdata_size(4)]; + knot_rdata_t *rdata_gt = (knot_rdata_t *)buf_gt; + knot_rdata_init(rdata_gt, 4, (uint8_t *)"wxyz"); + + int ret = knot_rdataset_add(NULL, NULL, NULL); + is_int(KNOT_EINVAL, ret, "rdataset: add NULL."); + ret = knot_rdataset_add(&rdataset, rdata_gt, NULL); + bool add_ok = ret == KNOT_EOK && rdataset.count == 1 && + knot_rdata_cmp(rdata_gt, rdataset.rdata) == 0; + ok(add_ok, "rdataset: add."); + + uint8_t buf_lo[knot_rdata_size(4)]; + knot_rdata_t *rdata_lo = (knot_rdata_t *)buf_lo; + knot_rdata_init(rdata_lo, 4, (uint8_t *)"abcd"); + ret = knot_rdataset_add(&rdataset, rdata_lo, NULL); + add_ok = ret == KNOT_EOK && rdataset.count == 2 && + knot_rdata_cmp(rdata_lo, rdataset.rdata) == 0; + ok(add_ok, "rdataset: add lower."); + + // Test getters + ok(knot_rdata_cmp(knot_rdataset_at(&rdataset, 0), rdata_lo) == 0 && + knot_rdata_cmp(knot_rdataset_at(&rdataset, 1), rdata_gt) == 0, + "rdataset: at."); + + ok(rdataset_size(&rdataset) == knot_rdata_size(4) * 2, + "rdataset: size."); + ok(rdataset.size == rdataset_size(&rdataset), "rdataset: size precomputed (%u %zu).", + rdataset.size, rdataset_size(&rdataset)); + + // Test copy + ok(knot_rdataset_copy(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: copy NULL."); + knot_rdataset_t copy; + ret = knot_rdataset_copy(©, &rdataset, NULL); + const bool copy_ok = ret == KNOT_EOK && copy.count == rdataset.count && + rdataset_size(©) == rdataset_size(&rdataset) && + rdataset.rdata != NULL && copy.rdata != NULL && + memcmp(rdataset.rdata, copy.rdata, + rdataset_size(&rdataset)) == 0; + ok(copy_ok, "rdataset: copy"); + ok(copy.size == rdataset_size(©), "copy: size precomputed."); + + // Test eq + ok(knot_rdataset_eq(&rdataset, ©), "rdataset: equal"); + + // Test clear + knot_rdataset_clear(©, NULL); + ok(copy.count == 0 && copy.rdata == NULL, "rdataset: clear."); + + // Test not equal (different count) + ok(!knot_rdataset_eq(&rdataset, ©), "rdataset: not equal - count"); + + // Test member + uint8_t buf_not[knot_rdata_size(1)]; + knot_rdata_t *not_a_member = (knot_rdata_t *)buf_not; + knot_rdata_init(not_a_member, 1, (uint8_t *)"?"); + ok(knot_rdataset_member(&rdataset, rdata_gt), "rdataset: is member."); + ok(!knot_rdataset_member(&rdataset, not_a_member), "rdataset: is not member."); + + // Test merge + ok(knot_rdataset_merge(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: merge NULL."); + knot_rdataset_t empty; + knot_rdataset_init(&empty); + ret = knot_rdataset_merge(&empty, &rdataset, NULL); + bool merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&empty, &rdataset); + ok(merge_ok, "rdataset: merge empty."); + knot_rdata_t *data_before = rdataset.rdata; + ret = knot_rdataset_merge(&rdataset, &rdataset, NULL); + merge_ok = ret == KNOT_EOK && rdataset.count == 2 && + data_before == rdataset.rdata; + ok(merge_ok, "rdataset: merge self."); + + knot_rdataset_clear(&empty, NULL); + + // Init structs for merge sort testing + knot_rdataset_t rdataset_lo; // "Lower" rdataset + knot_rdataset_init(&rdataset_lo); + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + knot_rdataset_t rdataset_gt; // "Greater" rdataset + knot_rdataset_init(&rdataset_gt); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + + // Test not equal - different data + ok(!knot_rdataset_eq(&rdataset_gt, &rdataset_lo), "rdataset: data not equal."); + + // Test that merge keeps the sorted order + ret = knot_rdataset_merge(&rdataset_lo, &rdataset_gt, NULL); + merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset_lo, &rdataset); + ok(merge_ok, "rdataset: merge into lower."); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + ret = knot_rdataset_merge(&rdataset_gt, &rdataset_lo, NULL); + merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset_gt, &rdataset); + ok(merge_ok, "rdataset: merge into greater."); + + // Test intersect + ok(knot_rdataset_intersect(NULL, NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: intersect NULL."); + + knot_rdataset_t intersection; + ret = knot_rdataset_intersect(&rdataset, &rdataset, &intersection, NULL); + bool intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset, &intersection); + ok(intersect_ok, "rdataset: intersect self."); + knot_rdataset_clear(&intersection, NULL); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + ret = knot_rdataset_intersect(&rdataset_lo, &rdataset_gt, &intersection, NULL); + intersect_ok = ret == KNOT_EOK && intersection.count == 0; + ok(intersect_ok, "rdataset: intersect no common."); + + ret = knot_rdataset_intersect(&rdataset, &rdataset_lo, &intersection, NULL); + intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&intersection, &rdataset_lo); + ok(intersect_ok, "rdataset: intersect normal."); + knot_rdataset_clear(&intersection, NULL); + + // Test intersect2 + ok(knot_rdataset_intersect2(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: intersect2 NULL."); + + ret = knot_rdataset_intersect2(&rdataset, &rdataset, NULL); + intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset, &rdataset); + ok(intersect_ok, "rdataset: intersect2 self."); + knot_rdataset_clear(&intersection, NULL); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + ret = knot_rdataset_intersect2(&rdataset_lo, &rdataset_gt, NULL); + intersect_ok = ret == KNOT_EOK && rdataset_lo.count == 0; + ok(intersect_ok, "rdataset: intersect2 no common."); + + ret = knot_rdataset_copy(©, &rdataset, NULL); + assert(ret == KNOT_EOK); + ret = knot_rdataset_intersect2(©, &rdataset_lo, NULL); + intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(©, &rdataset_lo); + ok(intersect_ok, "rdataset: intersect2 normal."); + knot_rdataset_clear(©, NULL); + + // Test subtract + ok(knot_rdataset_subtract(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: subtract NULL."); + ret = knot_rdataset_copy(©, &rdataset, NULL); + assert(ret == KNOT_EOK); + ok(knot_rdataset_subtract(©, ©, NULL) == KNOT_EOK && + copy.count == 0, "rdataset: subtract self."); + + ret = knot_rdataset_copy(©, &rdataset, NULL); + assert(ret == KNOT_EOK); + ret = knot_rdataset_subtract(©, &rdataset, NULL); + bool subtract_ok = ret == KNOT_EOK && copy.count == 0; + ok(subtract_ok, "rdataset: subtract identical."); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + data_before = rdataset_lo.rdata; + ret = knot_rdataset_subtract(&rdataset_lo, &rdataset_gt, NULL); + subtract_ok = ret == KNOT_EOK && rdataset_lo.count == 1 && + rdataset_lo.rdata == data_before; + ok(subtract_ok, "rdataset: subtract no common."); + + ret = knot_rdataset_subtract(&rdataset, &rdataset_gt, NULL); + subtract_ok = ret == KNOT_EOK && rdataset.count == 1; + ok(subtract_ok, "rdataset: subtract the second."); + + ret = knot_rdataset_subtract(&rdataset, &rdataset_lo, NULL); + subtract_ok = ret == KNOT_EOK && rdataset.count == 0 && + rdataset.rdata == NULL; + ok(subtract_ok, "rdataset: subtract last."); + + knot_rdataset_clear(©, NULL); + knot_rdataset_clear(&rdataset, NULL); + knot_rdataset_clear(&rdataset_lo, NULL); + knot_rdataset_clear(&rdataset_gt, NULL); + + return EXIT_SUCCESS; +} |