From 1d34d80df4e64599e92264c00eb2b494f770cedd Mon Sep 17 00:00:00 2001 From: Jan Kadlec Date: Tue, 20 May 2014 16:54:35 +0200 Subject: [PATCH] unittests: unit tests for new node API --- Knot.files | 1 + src/knot/zone/node.c | 2 + tests/Makefile.am | 1 + tests/node.c | 159 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+) create mode 100644 tests/node.c diff --git a/Knot.files b/Knot.files index 728ee642e..439bed6e9 100644 --- a/Knot.files +++ b/Knot.files @@ -331,3 +331,4 @@ tests/slab.c tests/wire.c tests/zonedb.c tests/ztree.c +tests/node.c diff --git a/src/knot/zone/node.c b/src/knot/zone/node.c index c7a8db120..1860b4f64 100644 --- a/src/knot/zone/node.c +++ b/src/knot/zone/node.c @@ -114,6 +114,8 @@ void node_free_rrsets(zone_node_t *node) for (uint16_t i = 0; i < node->rrset_count; ++i) { rr_data_clear(&node->rrs[i], NULL); } + + node->rrset_count = 0; } void node_free(zone_node_t **node) diff --git a/tests/Makefile.am b/tests/Makefile.am index ba2cabb0b..5840b209a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -30,6 +30,7 @@ check_PROGRAMS = \ dnssec_sign \ dnssec_zone_nsec \ rrset \ + node \ pkt \ process_query \ process_answer \ diff --git a/tests/node.c b/tests/node.c new file mode 100644 index 000000000..d55570d05 --- /dev/null +++ b/tests/node.c @@ -0,0 +1,159 @@ +/* Copyright (C) 2011 CZ.NIC, z.s.p.o. + + 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 . + */ + +#include +#include +#include + +#include "knot/zone/node.h" +#include "common/errcode.h" + +static knot_rrset_t *create_dummy_rrset(const knot_dname_t *owner, + uint16_t type) +{ + knot_rrset_t *r = knot_rrset_new(owner, type, + KNOT_CLASS_IN, NULL); + assert(r); + uint8_t wire[16] = { 0 }; + memcpy(wire, "testtest", strlen("testtest")); + int ret = knot_rrset_add_rdata(r, wire, strlen("testtest"), 3600, NULL); + assert(ret == KNOT_EOK); + return r; +} + +static knot_rrset_t *create_dummy_rrsig(const knot_dname_t *owner, + uint16_t type) +{ + knot_rrset_t *r = knot_rrset_new(owner, KNOT_RRTYPE_RRSIG, + KNOT_CLASS_IN, NULL); + assert(r); + uint8_t wire[sizeof(uint16_t)]; + knot_wire_write_u16(wire, type); + int ret = knot_rrset_add_rdata(r, wire, sizeof(uint16_t), 3600, NULL); + assert(ret == KNOT_EOK); + return r; +} + +int main(int argc, char *argv[]) +{ + plan(23); + + knot_dname_t *dummy_owner = knot_dname_from_str("test."); + // Test new + zone_node_t *node = node_new(dummy_owner); + ok(node != NULL, "Node: new"); + assert(node); + ok(knot_dname_is_equal(node->owner, dummy_owner), "Node: new - set fields"); + + // Test parent setting + zone_node_t *parent = node_new(dummy_owner); + assert(parent); + node_set_parent(node, parent); + ok(node->parent == parent && parent->children == 1, "Node: set parent."); + + node_free(&parent); + + // Test RRSet addition + knot_rrset_t *dummy_rrset = create_dummy_rrset(dummy_owner, KNOT_RRTYPE_TXT); + int ret = node_add_rrset(node, dummy_rrset); + ok(ret == KNOT_EOK && node->rrset_count == 1 && + knot_rdataset_eq(&dummy_rrset->rrs, &node->rrs[0].rrs), "Node: add RRSet."); + + // Test shallow copy + node->flags |= NODE_FLAGS_DELEG; + zone_node_t *copy = node_shallow_copy(node); + ok(copy != NULL, "Node: shallow copy."); + assert(copy); + const bool copy_ok = knot_dname_is_equal(copy->owner, node->owner) && + copy->rrset_count == node->rrset_count && + memcmp(copy->rrs, node->rrs, + copy->rrset_count * sizeof(struct rr_data)) == 0 && + copy->flags == node->flags; + ok(copy_ok, "Node: shallow copy - set fields."); + + node_free(©); + + // Test RRSet getters + knot_rrset_t *n_rrset = node_create_rrset(node, KNOT_RRTYPE_TXT); + ok(n_rrset && knot_rrset_equal(n_rrset, dummy_rrset, KNOT_RRSET_COMPARE_WHOLE), + "Node: create existing RRSet."); + + knot_rrset_free(&n_rrset, NULL); + + n_rrset = node_create_rrset(node, KNOT_RRTYPE_SOA); + ok(n_rrset == NULL, "Node: create non-existing RRSet."); + + knot_rrset_t stack_rrset = node_rrset(node, KNOT_RRTYPE_TXT); + ok(knot_rrset_equal(&stack_rrset, dummy_rrset, + KNOT_RRSET_COMPARE_WHOLE), "Node: get existing RRSet."); + stack_rrset = node_rrset(node, KNOT_RRTYPE_SOA); + ok(knot_rrset_empty(&stack_rrset), "Node: get non-existent RRSet."); + + knot_rdataset_t *n_rdataset = node_rdataset(node, KNOT_RRTYPE_TXT); + ok(n_rdataset && knot_rdataset_eq(n_rdataset, &dummy_rrset->rrs), + "Node: get existing rdataset."); + n_rdataset = node_rdataset(node, KNOT_RRTYPE_SOA); + ok(n_rrset == NULL, "Node: get non-existing rdataset."); + + stack_rrset = node_rrset_at(node, 0); + ok(knot_rrset_equal(&stack_rrset, dummy_rrset, KNOT_RRSET_COMPARE_WHOLE), + "Node: get existing position."); + stack_rrset = node_rrset_at(node, 1); + ok(knot_rrset_empty(&stack_rrset), "Node: get non-existent position."); + + // Test TTL mismatch + knot_rdata_t *data = knot_rdataset_at(&dummy_rrset->rrs, 0); + knot_rdata_set_ttl(data, 1800); + ret = node_add_rrset(node, dummy_rrset); + ok(ret == KNOT_ETTL && node->rrset_count == 1, + "Node: add RRSet, TTL mismatch."); + + knot_rrset_free(&dummy_rrset, NULL); + + // Test bool functions + ok(node_rrtype_exists(node, KNOT_RRTYPE_TXT), "Node: type exists."); + ok(!node_rrtype_exists(node, KNOT_RRTYPE_AAAA), "Node: type does not exist."); + ok(!node_rrtype_is_signed(node, KNOT_RRTYPE_TXT), "Node: type is not signed."); + + dummy_rrset = create_dummy_rrsig(dummy_owner, KNOT_RRTYPE_TXT); + ret = node_add_rrset(node, dummy_rrset); + assert(ret == KNOT_EOK); + + ok(node_rrtype_is_signed(node, KNOT_RRTYPE_TXT), "Node: type is signed."); + + knot_rrset_free(&dummy_rrset, NULL); + + + // Test remove RRset + node_remove_rdataset(node, KNOT_RRTYPE_AAAA); + ok(node->rrset_count == 2, "Node: remove non-existent rdataset."); + void *to_free = node_rdataset(node, KNOT_RRTYPE_TXT)->data; + node_remove_rdataset(node, KNOT_RRTYPE_TXT); + ok(node->rrset_count == 1, "Node: remove existing rdataset."); + + free(to_free); + + // "Test" freeing + node_free_rrsets(node); + ok(node->rrset_count == 0, "Node: free RRSets."); + + node_free(&node); + ok(node == NULL, "Node: free."); + + knot_dname_free(&dummy_owner, NULL); + + return 0; +}