Browse Source

[2480] unified test data.

the previously hardcoded zone data are mostly moved to two new files:
query_testzone_data.txt and query_testzone_data_nsec3.txt.

A new helper python script, gen-query-testdata.py, converts them into
DNS zone files and C++ files defining some C-string variables for the RRs.
The latter will be included from query_unittest.cc (instead of the hardcoded
variables).

Generated zone files are loaded via include-only zone files: example.zone
and example-nsec3.zone.

For the next step corresponding sqlite3 DB file is also generated.
JINMEI Tatuya 12 years ago
parent
commit
5deb6bbc2d

+ 2 - 0
configure.ac

@@ -1358,6 +1358,8 @@ AC_OUTPUT([doc/version.ent
            src/bin/msgq/run_msgq.sh
            src/bin/auth/auth.spec.pre
            src/bin/auth/spec_config.h.pre
+           src/bin/auth/tests/testdata/example.zone
+           src/bin/auth/tests/testdata/example-nsec3.zone
            src/bin/dhcp4/spec_config.h.pre
            src/bin/dhcp6/spec_config.h.pre
            src/bin/tests/process_rename_test.py

+ 2 - 0
src/bin/auth/tests/.gitignore

@@ -1 +1,3 @@
 /run_unittests
+/example_base_inc.cc
+/example_nsec3_inc.cc

+ 23 - 1
src/bin/auth/tests/Makefile.am

@@ -7,7 +7,7 @@ AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
 AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CPPFLAGS += -DAUTH_OBJ_DIR=\"$(abs_top_builddir)/src/bin/auth\"
 AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(abs_top_srcdir)/src/lib/testutils/testdata\"
-AM_CPPFLAGS += -DTEST_OWN_DATA_DIR=\"$(abs_top_srcdir)/src/bin/auth/tests/testdata\"
+AM_CPPFLAGS += -DTEST_OWN_DATA_DIR=\"$(abs_builddir)/testdata\"
 AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/testutils/testdata\"
 AM_CPPFLAGS += -DDSRC_DIR=\"$(abs_top_builddir)/src/lib/datasrc\"
 AM_CPPFLAGS += -DPLUGIN_DATA_PATH=\"$(abs_top_builddir)/src/bin/cfgmgr/plugins\"
@@ -81,6 +81,28 @@ run_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
 run_unittests_LDADD += $(GTEST_LDADD)
 run_unittests_LDADD += $(SQLITE_LIBS)
 
+# The following are definitions for auto-generating test data for query
+# tests.
+BUILT_SOURCES = testdata/example-base.zone example_base_inc.cc
+BUILT_SOURCES += testdata/example-nsec3-inc.zone example_nsec3_inc.cc
+BUILT_SOURCES += testdata/example-base.sqlite3
+
+CLEANFILES += example_base_inc.cc example_nsec3_inc.cc
+
+testdata/example-base.zone example_base_inc.cc: testdata/query_testzone_data.txt
+	$(PYTHON) ./gen-query-testdata.py testdata/query_testzone_data.txt \
+		testdata/example-base.zone example_base_inc.cc
+
+testdata/example-nsec3-inc.zone example_nsec3_inc.cc: testdata/query_testzone_data_nsec3.txt
+	$(PYTHON) ./gen-query-testdata.py \
+		testdata/query_testzone_data_nsec3.txt \
+		testdata/example-nsec3-inc.zone example_nsec3_inc.cc
+
+testdata/example-base.sqlite3: testdata/example-base.zone
+	$(SHELL) $(top_builddir)/src/bin/loadzone/run_loadzone.sh \
+		-c "{\"database_file\": \"$(builddir)/testdata/example-base.sqlite3\"}" \
+		example.com testdata/example-base.zone
+
 check-local:
 	B10_FROM_BUILD=${abs_top_builddir} ./run_unittests
 

+ 104 - 0
src/bin/auth/tests/gen-query-testdata.py

@@ -0,0 +1,104 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+"""\
+This is a supplemental script to generate various forms of test data
+from a unified source file.
+
+Usage: python gen-query-testdata.py source_file output-zonefile output--cc-file
+
+The usage doesn't matter much, though, because it's expected to be invoked
+from Makefile, and that would be only use case of this script.
+"""
+
+import sys
+import re
+
+# Skip lines starting with '##' (comments) or empty lines
+re_skip = re.compile('(^##)|(^\s*$)')
+
+# Markup for variable definition
+re_start_rr = re.compile('^#var=(.*)')
+
+def parse_input(input_file):
+    '''Build an internal list of RR data from the input source file.
+
+    It generates a list of (variable_name, list of RR) tuples, where
+    variable_name is the expected C++ variable name for the subsequent RRs
+    if they are expected to be named.  It can be an empty string if the RRs
+    are only expected to appear in the zone file.
+    The second element of the tuple is a list of strings, each of which
+    represents a single RR, e.g., "example.com 3600 IN A 192.0.2.1".
+
+    '''
+    result = []
+    rrs = None
+    with open(input_file) as f:
+        for line in f:
+            if re_skip.match(line):
+                continue
+            m = re_start_rr.match(line)
+            if m:
+                if rrs is not None:
+                    result.append((rr_varname, rrs))
+                rrs = []
+                rr_varname = m.group(1)
+            else:
+                rrs.append(line.rstrip('\n'))
+
+        # if needed, store the last RRs (they are not followed by 'var=' mark)
+        if rrs is not None:
+            result.append((rr_varname, rrs))
+
+    return result
+
+def generate_variables(out_file, rrsets_data):
+    '''Generate a C++ source file containing a C-string variables for RRs.
+
+    This produces a definition of C-string for each RRset that is expected
+    to be named as follows:
+    const char* const var_name =
+        "example.com. 3600 IN A 192.0.2.1\n"
+        "example.com. 3600 IN A 192.0.2.2\n";
+
+    Escape character '\' in the string will be further escaped so it will
+    compile.
+
+    '''
+    with open(out_file, 'w') as out:
+        for (var_name, rrs) in rrsets_data:
+            if len(var_name) > 0:
+                out.write('const char* const ' + var_name + ' =\n')
+                # Combine all RRs, escaping '\' as a C-string
+                out.write('\n'.join(['    \"%s\\n\"' %
+                                     (rr.replace('\\', '\\\\'))
+                                     for rr in rrs]))
+                out.write(';\n')
+
+def generate_zonefile(out_file, rrsets_data):
+    '''Generate a DNS zone file for the given set of RRs.'''
+    with open(out_file, 'w') as out:
+        for (_, rrs) in rrsets_data:
+            out.write('\n'.join(rrs) + '\n')
+
+if __name__ == "__main__":
+    if len(sys.argv) < 4:
+        sys.stderr.write('gen-query-testdata.py require 3 args\n')
+        sys.exit(1)
+    rrsets_data = parse_input(sys.argv[1])
+    generate_zonefile(sys.argv[2], rrsets_data)
+    generate_variables(sys.argv[3], rrsets_data)
+

+ 31 - 194
src/bin/auth/tests/query_unittest.cc

@@ -24,9 +24,11 @@
 
 #include <dns/masterload.h>
 #include <dns/message.h>
+#include <dns/master_loader.h>
 #include <dns/name.h>
 #include <dns/opcode.h>
 #include <dns/rcode.h>
+#include <dns/rrcollator.h>
 #include <dns/rrttl.h>
 #include <dns/rrtype.h>
 #include <dns/rdataclass.h>
@@ -79,150 +81,21 @@ private:
     DataSourceClient& client_;
 };
 
+// These are commonly used data (auto-generated).  There are some exceptional
+// data that are only used in a limited scenario, which are defined separately
+// below.
+#include <auth/tests/example_base_inc.cc>
+#include <auth/tests/example_nsec3_inc.cc>
 
-// This is the content of the mock zone (see below).
-// It's a sequence of textual RRs that is supposed to be parsed by
-// dns::masterLoad().  Some of the RRs are also used as the expected
-// data in specific tests, in which case they are referenced via specific
-// local variables (such as soa_txt).
-//
-// For readability consistency, all strings are placed in a separate line,
-// even if they are very short and can reasonably fit in a single line with
-// the corresponding variable.  For example, we write
-// const char* const foo_txt =
-//  "foo.example.com. 3600 IN AAAA 2001:db8::1\n";
-// instead of
-// const char* const foo_txt = "foo.example.com. 3600 IN AAAA 2001:db8::1\n";
-const char* const soa_txt =
-    "example.com. 3600 IN SOA . . 0 0 0 0 0\n";
-const char* const zone_ns_txt =
-    "example.com. 3600 IN NS glue.delegation.example.com.\n"
-    "example.com. 3600 IN NS noglue.example.com.\n"
-    "example.com. 3600 IN NS example.net.\n";
+// This is used only in one pathological test case.
 const char* const zone_ds_txt =
     "example.com. 3600 IN DS 57855 5 1 "
         "B6DCD485719ADCA18E5F3D48A2331627FDD3 636B\n";
-const char* const ns_addrs_txt =
-    "glue.delegation.example.com. 3600 IN A 192.0.2.153\n"
-    "glue.delegation.example.com. 3600 IN AAAA 2001:db8::53\n"
-    "noglue.example.com. 3600 IN A 192.0.2.53\n";
-const char* const delegation_txt =
-    "delegation.example.com. 3600 IN NS glue.delegation.example.com.\n"
-    "delegation.example.com. 3600 IN NS noglue.example.com.\n"
-    "delegation.example.com. 3600 IN NS cname.example.com.\n"
-    "delegation.example.com. 3600 IN NS example.org.\n";
-// Borrowed from the RFC4035
-const char* const delegation_ds_txt =
-    "delegation.example.com. 3600 IN DS 57855 5 1 "
-        "B6DCD485719ADCA18E5F3D48A2331627FDD3 636B\n";
-const char* const mx_txt =
-    "mx.example.com. 3600 IN MX 10 www.example.com.\n"
-    "mx.example.com. 3600 IN MX 20 mailer.example.org.\n"
-    "mx.example.com. 3600 IN MX 30 mx.delegation.example.com.\n";
-const char* const www_a_txt =
-    "www.example.com. 3600 IN A 192.0.2.80\n";
-const char* const cname_txt =
-    "cname.example.com. 3600 IN CNAME www.example.com.\n";
-const char* const cname_nxdom_txt =
-    "cnamenxdom.example.com. 3600 IN CNAME nxdomain.example.com.\n";
-// CNAME Leading out of zone
-const char* const cname_out_txt =
-    "cnameout.example.com. 3600 IN CNAME www.example.org.\n";
-// The DNAME to do tests against
-const char* const dname_txt =
-    "dname.example.com. 3600 IN DNAME "
-    "somethinglong.dnametarget.example.com.\n";
-// Some data at the dname node (allowed by RFC 2672)
-const char* const dname_a_txt =
-    "dname.example.com. 3600 IN A 192.0.2.5\n";
+
 // This is not inside the zone, this is created at runtime
 const char* const synthetized_cname_txt =
     "www.dname.example.com. 3600 IN CNAME "
     "www.somethinglong.dnametarget.example.com.\n";
-// The rest of data won't be referenced from the test cases.
-const char* const other_zone_rrs =
-    "cnamemailer.example.com. 3600 IN CNAME www.example.com.\n"
-    "cnamemx.example.com. 3600 IN MX 10 cnamemailer.example.com.\n"
-    "mx.delegation.example.com. 3600 IN A 192.0.2.100\n";
-// Wildcards
-const char* const wild_txt =
-    "*.wild.example.com. 3600 IN A 192.0.2.7\n";
-const char* const nsec_wild_txt =
-    "*.wild.example.com. 3600 IN NSEC www.example.com. A NSEC RRSIG\n";
-const char* const cnamewild_txt =
-    "*.cnamewild.example.com. 3600 IN CNAME www.example.org.\n";
-const char* const nsec_cnamewild_txt =
-    "*.cnamewild.example.com. 3600 IN NSEC "
-    "delegation.example.com. CNAME NSEC RRSIG\n";
-// Wildcard_nxrrset
-const char* const wild_txt_nxrrset =
-    "*.uwild.example.com. 3600 IN A 192.0.2.9\n";
-const char* const nsec_wild_txt_nxrrset =
-    "*.uwild.example.com. 3600 IN NSEC www.uwild.example.com. A NSEC RRSIG\n";
-const char* const wild_txt_next =
-    "www.uwild.example.com. 3600 IN A 192.0.2.11\n";
-const char* const nsec_wild_txt_next =
-    "www.uwild.example.com. 3600 IN NSEC *.wild.example.com. A NSEC RRSIG\n";
-// Wildcard empty
-const char* const empty_txt =
-    "b.*.t.example.com. 3600 IN A 192.0.2.13\n";
-const char* const nsec_empty_txt =
-    "b.*.t.example.com. 3600 IN NSEC *.uwild.example.com. A NSEC RRSIG\n";
-const char* const empty_prev_txt =
-    "t.example.com. 3600 IN A 192.0.2.15\n";
-const char* const nsec_empty_prev_txt =
-    "t.example.com. 3600 IN NSEC b.*.t.example.com. A NSEC RRSIG\n";
-// Used in NXDOMAIN proof test.  We are going to test some unusual case where
-// the best possible wildcard is below the "next domain" of the NSEC RR that
-// proves the NXDOMAIN, i.e.,
-// mx.example.com. (exist)
-// (.no.example.com. (qname, NXDOMAIN)
-// ).no.example.com. (exist)
-// *.no.example.com. (best possible wildcard, not exist)
-const char* const no_txt =
-    ").no.example.com. 3600 IN AAAA 2001:db8::53\n";
-// NSEC records.
-const char* const nsec_apex_txt =
-    "example.com. 3600 IN NSEC cname.example.com. NS SOA NSEC RRSIG\n";
-const char* const nsec_mx_txt =
-    "mx.example.com. 3600 IN NSEC ).no.example.com. MX NSEC RRSIG\n";
-const char* const nsec_no_txt =
-    ").no.example.com. 3600 IN NSEC nz.no.example.com. AAAA NSEC RRSIG\n";
-// We'll also test the case where a single NSEC proves both NXDOMAIN and the
-// non existence of wildcard.  The following records will be used for that
-// test.
-// ).no.example.com. (exist, whose NSEC proves everything)
-// *.no.example.com. (best possible wildcard, not exist)
-// nx.no.example.com. (NXDOMAIN)
-// nz.no.example.com. (exist)
-const char* const nz_txt =
-    "nz.no.example.com. 3600 IN AAAA 2001:db8::5300\n";
-const char* const nsec_nz_txt =
-    "nz.no.example.com. 3600 IN NSEC noglue.example.com. AAAA NSEC RRSIG\n";
-const char* const nsec_nxdomain_txt =
-    "noglue.example.com. 3600 IN NSEC nonsec.example.com. A\n";
-
-// NSEC for the normal NXRRSET case
-const char* const nsec_www_txt =
-    "www.example.com. 3600 IN NSEC example.com. A NSEC RRSIG\n";
-
-// Authoritative data without NSEC
-const char* const nonsec_a_txt =
-    "nonsec.example.com. 3600 IN A 192.0.2.0\n";
-
-// NSEC3 RRs.  You may also need to add mapping to MockZoneFinder::hash_map_.
-const string nsec3_apex_txt =
-    "0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example.com. 3600 IN NSEC3 1 1 12 "
-    "aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA NSEC3PARAM RRSIG\n";
-const string nsec3_apex_rrsig_txt =
-    "0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example.com. 3600 IN RRSIG NSEC3 5 3 "
-    "3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE";
-const string nsec3_www_txt =
-    "q04jkcevqvmu85r014c7dkba38o0ji5r.example.com. 3600 IN NSEC3 1 1 12 "
-    "aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG\n";
-const string nsec3_www_rrsig_txt =
-    "q04jkcevqvmu85r014c7dkba38o0ji5r.example.com. 3600 IN RRSIG NSEC3 5 3 "
-    "3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE";
 
 // NSEC3 for wild.example.com (used in wildcard tests, will be added on
 // demand not to confuse other tests)
@@ -246,42 +119,13 @@ const char* const nsec3_uwild_txt =
     "t644ebqk9bibcna874givr6joj62mlhv.example.com. 3600 IN NSEC3 1 1 12 "
     "aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG\n";
 
-// (Secure) delegation data; Delegation with DS record
-const char* const signed_delegation_txt =
-    "signed-delegation.example.com. 3600 IN NS ns.example.net.\n";
-const char* const signed_delegation_ds_txt =
-    "signed-delegation.example.com. 3600 IN DS 12345 8 2 "
-    "764501411DE58E8618945054A3F620B36202E115D015A7773F4B78E0F952CECA\n";
-
 // (Secure) delegation data; Delegation without DS record (and both NSEC
 // and NSEC3 denying its existence)
-const char* const unsigned_delegation_txt =
-    "unsigned-delegation.example.com. 3600 IN NS ns.example.net.\n";
-const char* const unsigned_delegation_nsec_txt =
-    "unsigned-delegation.example.com. 3600 IN NSEC "
-    "unsigned-delegation-optout.example.com. NS RRSIG NSEC\n";
 // This one will be added on demand
 const char* const unsigned_delegation_nsec3_txt =
     "q81r598950igr1eqvc60aedlq66425b5.example.com. 3600 IN NSEC3 1 1 12 "
     "aabbccdd 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom NS RRSIG\n";
 
-// Delegation without DS record, and no direct matching NSEC3 record
-const char* const unsigned_delegation_optout_txt =
-    "unsigned-delegation-optout.example.com. 3600 IN NS ns.example.net.\n";
-const char* const unsigned_delegation_optout_nsec_txt =
-    "unsigned-delegation-optout.example.com. 3600 IN NSEC "
-    "*.uwild.example.com. NS RRSIG NSEC\n";
-
-// (Secure) delegation data; Delegation where the DS lookup will raise an
-// exception.
-const char* const bad_delegation_txt =
-    "bad-delegation.example.com. 3600 IN NS ns.example.net.\n";
-
-// Delegation from an unsigned parent.  There's no DS, and there's no NSEC
-// or NSEC3 that proves it.
-const char* const nosec_delegation_txt =
-    "nosec-delegation.example.com. 3600 IN NS ns.nosec.example.net.\n";
-
 // A helper function that generates a textual representation of RRSIG RDATA
 // for the given covered type.  The resulting RRSIG may not necessarily make
 // sense in terms of the DNSSEC protocol, but for our testing purposes it's
@@ -340,26 +184,12 @@ public:
         nsec3_fake_(NULL),
         nsec3_name_(NULL)
     {
-        stringstream zone_stream;
-        zone_stream << soa_txt << zone_ns_txt << ns_addrs_txt <<
-            delegation_txt << delegation_ds_txt << mx_txt << www_a_txt <<
-            cname_txt << cname_nxdom_txt << cname_out_txt << dname_txt <<
-            dname_a_txt << other_zone_rrs << no_txt << nz_txt <<
-            nsec_apex_txt << nsec_mx_txt << nsec_no_txt << nsec_nz_txt <<
-            nsec_nxdomain_txt << nsec_www_txt << nonsec_a_txt <<
-            wild_txt << nsec_wild_txt << cnamewild_txt << nsec_cnamewild_txt <<
-            wild_txt_nxrrset << nsec_wild_txt_nxrrset << wild_txt_next <<
-            nsec_wild_txt_next << empty_txt << nsec_empty_txt <<
-            empty_prev_txt << nsec_empty_prev_txt <<
-            nsec3_apex_txt << nsec3_www_txt <<
-            signed_delegation_txt << signed_delegation_ds_txt <<
-            unsigned_delegation_txt << unsigned_delegation_nsec_txt <<
-            unsigned_delegation_optout_txt <<
-            unsigned_delegation_optout_nsec_txt <<
-            bad_delegation_txt << nosec_delegation_txt;
-
-        masterLoad(zone_stream, origin_, rrclass_,
-                   boost::bind(&MockZoneFinder::loadRRset, this, _1));
+        RRCollator collator(boost::bind(&MockZoneFinder::loadRRset, this, _1));
+        MasterLoader loader(TEST_OWN_DATA_DIR "/example-nsec3.zone",
+                            origin_, rrclass_,
+                            MasterLoaderCallbacks::getNullCallbacks(),
+                            collator.getCallback());
+        loader.load();
 
         empty_nsec_rrset_ = ConstRRsetPtr(new RRset(Name::ROOT_NAME(),
                                                     RRClass::IN(),
@@ -513,6 +343,13 @@ private:
     };
 
     void loadRRset(RRsetPtr rrset) {
+        // For simplicity we dynamically generate RRSIGs and add them below.
+        // The RRSIG RDATA should be consistent with that defined in the
+        // zone file.
+        if (rrset->getType() == RRType::RRSIG()) {
+            return;
+        }
+
         if (rrset->getType() == RRType::NSEC3()) {
             // NSEC3 should go to the dedicated table
             nsec3_domains_[rrset->getName()][rrset->getType()] = rrset;
@@ -900,12 +737,12 @@ enum DataSrcType {
 
 boost::shared_ptr<ClientList>
 createDataSrcClientList(DataSrcType type, DataSourceClient& client) {
+    boost::shared_ptr<ConfigurableClientList> list;
     switch (type) {
     case MOCK:
         return (boost::shared_ptr<ClientList>(new SingletonList(client)));
     case INMEMORY:
-        boost::shared_ptr<ConfigurableClientList> list(
-            new ConfigurableClientList(RRClass::IN()));
+        list.reset(new ConfigurableClientList(RRClass::IN()));
         list->configure(isc::data::Element::fromJSON(
                             "[{\"type\": \"MasterFiles\","
                             "  \"cache-enable\": true, "
@@ -2126,7 +1963,7 @@ TEST_P(QueryTest, findNSEC3) {
     {
         SCOPED_TRACE("apex, non recursive");
         nsec3Check(true, expected_closest_labels,
-                   nsec3_apex_txt + "\n" + nsec3_apex_rrsig_txt,
+                   string(nsec3_apex_txt) + "\n" + nsec3_apex_rrsig_txt,
                    mock_finder->findNSEC3(Name("example.com"), false));
     }
 
@@ -2134,7 +1971,7 @@ TEST_P(QueryTest, findNSEC3) {
     {
         SCOPED_TRACE("apex, recursive");
         nsec3Check(true, expected_closest_labels,
-                   nsec3_apex_txt + "\n" + nsec3_apex_rrsig_txt,
+                   string(nsec3_apex_txt) + "\n" + nsec3_apex_rrsig_txt,
                    mock_finder->findNSEC3(Name("example.com"), true));
     }
 
@@ -2143,7 +1980,7 @@ TEST_P(QueryTest, findNSEC3) {
     {
         SCOPED_TRACE("nxdomain, non recursive");
         nsec3Check(false, 4,
-                   nsec3_www_txt + "\n" + nsec3_www_rrsig_txt,
+                   string(nsec3_www_txt) + "\n" + nsec3_www_rrsig_txt,
                    mock_finder->findNSEC3(Name("nxdomain.example.com"),
                                           false));
     }
@@ -2153,7 +1990,7 @@ TEST_P(QueryTest, findNSEC3) {
     {
         SCOPED_TRACE("nxdomain, recursive");
         nsec3Check(true, expected_closest_labels,
-                   nsec3_apex_txt + "\n" + nsec3_apex_rrsig_txt + "\n" +
+                   string(nsec3_apex_txt) + "\n" + nsec3_apex_rrsig_txt + "\n" +
                    nsec3_www_txt + "\n" + nsec3_www_rrsig_txt,
                    mock_finder->findNSEC3(Name("nxdomain.example.com"), true));
     }
@@ -2163,7 +2000,7 @@ TEST_P(QueryTest, findNSEC3) {
     {
         SCOPED_TRACE("nxdomain, next closer != qname");
         nsec3Check(true, expected_closest_labels,
-                   nsec3_apex_txt + "\n" + nsec3_apex_rrsig_txt + "\n" +
+                   string(nsec3_apex_txt) + "\n" + nsec3_apex_rrsig_txt + "\n" +
                    nsec3_www_txt + "\n" + nsec3_www_rrsig_txt,
                    mock_finder->findNSEC3(Name("nx.domain.example.com"),
                                           true));
@@ -2173,14 +2010,14 @@ TEST_P(QueryTest, findNSEC3) {
     {
         SCOPED_TRACE("largest");
         nsec3Check(false, 4,
-                   nsec3_apex_txt + "\n" + nsec3_apex_rrsig_txt,
+                   string(nsec3_apex_txt) + "\n" + nsec3_apex_rrsig_txt,
                    mock_finder->findNSEC3(Name("nxdomain2.example.com"),
                                           false));
     }
     {
         SCOPED_TRACE("smallest");
         nsec3Check(false, 4,
-                   nsec3_www_txt + "\n" + nsec3_www_rrsig_txt,
+                   string(nsec3_www_txt) + "\n" + nsec3_www_rrsig_txt,
                    mock_finder->findNSEC3(Name("nxdomain3.example.com"),
                                           false));
     }

+ 5 - 0
src/bin/auth/tests/testdata/.gitignore

@@ -6,3 +6,8 @@
 /shortanswer_fromWire.wire
 /simplequery_fromWire.wire
 /simpleresponse_fromWire.wire
+/example-base.zone
+/example-nsec3-inc.zone
+/example-base.sqlite3
+/example-nsec3.zone
+/example-base.zone

+ 3 - 0
src/bin/auth/tests/testdata/Makefile.am

@@ -1,4 +1,5 @@
 CLEANFILES = *.wire
+CLEANFILES += example-base.zone example-nsec3-inc.zone example-base.sqlite3
 
 BUILT_SOURCES = badExampleQuery_fromWire.wire examplequery_fromWire.wire
 BUILT_SOURCES += iqueryresponse_fromWire.wire multiquestion_fromWire.wire
@@ -24,5 +25,7 @@ EXTRA_DIST += example.com
 EXTRA_DIST += example.zone
 EXTRA_DIST += example.sqlite3
 
+EXTRA_DIST += query_testzone_data.txt query_testzone_data_nsec3.txt
+
 .spec.wire:
 	$(PYTHON) $(top_builddir)/src/lib/util/python/gen_wiredata.py -o $@ $<

+ 7 - 0
src/bin/auth/tests/testdata/example-nsec3.zone.in

@@ -0,0 +1,7 @@
+;;
+;; This is a complete (but crafted and somewhat broken) zone file used
+;; in query tests including NSEC3 records, making the zone is "NSEC3 signed".
+;;
+
+$INCLUDE @abs_builddir@/example-base.zone
+$INCLUDE @abs_builddir@/example-nsec3-inc.zone

+ 6 - 0
src/bin/auth/tests/testdata/example.zone.in

@@ -0,0 +1,6 @@
+;;
+;; This is a complete (but crafted and somewhat broken) zone file used
+;; in query tests, excluding NSEC3 records.
+;;
+
+$INCLUDE @abs_builddir@/example-base.zone

+ 148 - 70
src/bin/auth/tests/testdata/example.zone

@@ -1,144 +1,222 @@
-;;
-;; This is a complete (but crafted and somewhat broken) zone file used
-;; in query tests.
-;;
+## This file defines a set of RRs commonly used in query tests.
+## It's a sequence of the following pattern:
+## #var=<var_name>
+## RR_1
+## RR_2
+## ..
+## RR_n
+##
+## where var_name is a string that can be used as a variable name in a
+## C/C++ source file or an empty string.  RR_x is a single-line
+## textual representation of an arbitrary DNS RR.
+##
+## If var_name is non empty, the generator script will define a C
+## variable of C-string type for that set of RRs so that it can be referred
+## to in the test source file.
+##
+## These RRs will be loaded into in-memory data source in that order.
+## Note that it may impose stricter restriction on the order of RRs.
+## In general, each RRset of the same name and type and its RRSIG (if
+## any) is expected to be grouped.
+##
+## Lines beginning with '##' or empty lines will be ignored by the
+## generator script.
 
+#var=soa_txt
 example.com. 3600 IN SOA . . 0 0 0 0 0
-example.com. 3600 IN RRSIG SOA 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+#var=zone_ns_txt
 example.com. 3600 IN NS glue.delegation.example.com.
 example.com. 3600 IN NS noglue.example.com.
 example.com. 3600 IN NS example.net.
+
+#var=
+example.com. 3600 IN RRSIG SOA 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 example.com. 3600 IN RRSIG NS 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
-;; This is used only for pathological case
-;;example.com. 3600 IN DS 57855 5 1 B6DCD485719ADCA18E5F3D48A2331627FDD3 636B
+
+#var=
+noglue.example.com. 3600 IN RRSIG A 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+
+#var=ns_addrs_txt
+noglue.example.com. 3600 IN A 192.0.2.53
 glue.delegation.example.com. 3600 IN A 192.0.2.153
-glue.delegation.example.com. 3600 IN RRSIG A 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 glue.delegation.example.com. 3600 IN AAAA 2001:db8::53
+
+#var=
+glue.delegation.example.com. 3600 IN RRSIG A 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 glue.delegation.example.com. 3600 IN RRSIG AAAA 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
-noglue.example.com. 3600 IN A 192.0.2.53
-noglue.example.com. 3600 IN RRSIG A 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+
+#var=delegation_txt
 delegation.example.com. 3600 IN NS glue.delegation.example.com.
 delegation.example.com. 3600 IN NS noglue.example.com.
 delegation.example.com. 3600 IN NS cname.example.com.
 delegation.example.com. 3600 IN NS example.org.
-;; Borrowed from the RFC4035
-delegation.example.com. 3600 IN DS 57855 5 1 B6DCD485719ADCA18E5F3D48A2331627FDD3 636B
+
+#var=
 delegation.example.com. 3600 IN RRSIG DS 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+
+## Borrowed from the RFC4035
+#var=delegation_ds_txt
+delegation.example.com. 3600 IN DS 57855 5 1 B6DCD485719ADCA18E5F3D48A2331627FDD3 636B
+#var=mx_txt
 mx.example.com. 3600 IN MX 10 www.example.com.
 mx.example.com. 3600 IN MX 20 mailer.example.org.
 mx.example.com. 3600 IN MX 30 mx.delegation.example.com.
+#var=www_a_txt
 www.example.com. 3600 IN A 192.0.2.80
+
+#var=
 www.example.com. 3600 IN RRSIG A 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+
+#var=cname_txt
 cname.example.com. 3600 IN CNAME www.example.com.
+#var=cname_nxdom_txt
 cnamenxdom.example.com. 3600 IN CNAME nxdomain.example.com.
-;; CNAME Leading out of zone
+## CNAME Leading out of zone
+#var=cname_out_txt
 cnameout.example.com. 3600 IN CNAME www.example.org.
-;; The DNAME to do tests against
+## The DNAME to do tests against
+#var=dname_txt
 dname.example.com. 3600 IN DNAME somethinglong.dnametarget.example.com.
-;; Some data at the dname node (allowed by RFC 2672)
+## Some data at the dname node (allowed by RFC 2672)
+#var=dname_a_txt
 dname.example.com. 3600 IN A 192.0.2.5
-;; The rest of data won't be referenced from the test cases.
+## This is not inside the zone, this is created at runtime
+## www.dname.example.com. 3600 IN CNAME www.somethinglong.dnametarget.example.com.
+## The rest of data won't be referenced from the test cases.
+#var=other_zone_rrs
 cnamemailer.example.com. 3600 IN CNAME www.example.com.
 cnamemx.example.com. 3600 IN MX 10 cnamemailer.example.com.
 mx.delegation.example.com. 3600 IN A 192.0.2.100
-;; Wildcards
+## Wildcards
+#var=wild_txt
 *.wild.example.com. 3600 IN A 192.0.2.7
-*.wild.example.com. 3600 IN RRSIG A 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+#var=nsec_wild_txt
 *.wild.example.com. 3600 IN NSEC www.example.com. A NSEC RRSIG
+
+#var=
+*.wild.example.com. 3600 IN RRSIG A 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 *.wild.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+
+#var=cnamewild_txt
 *.cnamewild.example.com. 3600 IN CNAME www.example.org.
-*.cnamewild.example.com. 3600 IN RRSIG CNAME 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+#var=nsec_cnamewild_txt
 *.cnamewild.example.com. 3600 IN NSEC delegation.example.com. CNAME NSEC RRSIG
+
+#var=
+*.cnamewild.example.com. 3600 IN RRSIG CNAME 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 *.cnamewild.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
-;; Wildcard_nxrrset
+
+## Wildcard_nxrrset
+#var=wild_txt_nxrrset
 *.uwild.example.com. 3600 IN A 192.0.2.9
+#var=nsec_wild_txt_nxrrset
 *.uwild.example.com. 3600 IN NSEC www.uwild.example.com. A NSEC RRSIG
+#var=wild_txt_next
 www.uwild.example.com. 3600 IN A 192.0.2.11
+#var=nsec_wild_txt_next
 www.uwild.example.com. 3600 IN NSEC *.wild.example.com. A NSEC RRSIG
-;; Wildcard empty
+## Wildcard empty
+#var=empty_txt
 b.*.t.example.com. 3600 IN A 192.0.2.13
+#var=nsec_empty_txt
 b.*.t.example.com. 3600 IN NSEC *.uwild.example.com. A NSEC RRSIG
+
+#var=
 b.*.t.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+
+#var=empty_prev_txt
 t.example.com. 3600 IN A 192.0.2.15
+#var=nsec_empty_prev_txt
 t.example.com. 3600 IN NSEC b.*.t.example.com. A NSEC RRSIG
+
+#var=
 t.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
-;; Used in NXDOMAIN proof test.  We are going to test some unusual case where
-;; the best possible wildcard is below the "next domain" of the NSEC RR that
-;; proves the NXDOMAIN, i.e.,
-;; mx.example.com. (exist)
-;; (.no.example.com. (qname, NXDOMAIN)
-;; ).no.example.com. (exist)
-;; *.no.example.com. (best possible wildcard, not exist)
+
+## Used in NXDOMAIN proof test.  We are going to test some unusual case where
+## the best possible wildcard is below the "next domain" of the NSEC RR that
+## proves the NXDOMAIN, i.e.,
+## mx.example.com. (exist)
+## (.no.example.com. (qname, NXDOMAIN)
+## ).no.example.com. (exist)
+## *.no.example.com. (best possible wildcard, not exist)
+#var=no_txt
 \).no.example.com. 3600 IN AAAA 2001:db8::53
-;; NSEC records.
+## NSEC records.
+#var=nsec_apex_txt
 example.com. 3600 IN NSEC cname.example.com. NS SOA NSEC RRSIG
+#var=
 example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
-
+#var=nsec_mx_txt
 mx.example.com. 3600 IN NSEC \).no.example.com. MX NSEC RRSIG
+
+#var=
 mx.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+
+#var=nsec_no_txt
 \).no.example.com. 3600 IN NSEC nz.no.example.com. AAAA NSEC RRSIG
+
+#var=
 \).no.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
-;; We'll also test the case where a single NSEC proves both NXDOMAIN and the
-;; non existence of wildcard.  The following records will be used for that
-;; test.
-;; ).no.example.com. (exist, whose NSEC proves everything)
-;; *.no.example.com. (best possible wildcard, not exist)
-;; nx.no.example.com. (NXDOMAIN)
-;; nz.no.example.com. (exist)
+
+## We'll also test the case where a single NSEC proves both NXDOMAIN and the
+## non existence of wildcard.  The following records will be used for that
+## test.
+## ).no.example.com. (exist, whose NSEC proves everything)
+## *.no.example.com. (best possible wildcard, not exist)
+## nx.no.example.com. (NXDOMAIN)
+## nz.no.example.com. (exist)
+#var=nz_txt
 nz.no.example.com. 3600 IN AAAA 2001:db8::5300
+#var=nsec_nz_txt
 nz.no.example.com. 3600 IN NSEC noglue.example.com. AAAA NSEC RRSIG
+#var=nsec_nxdomain_txt
 noglue.example.com. 3600 IN NSEC nonsec.example.com. A
+
+#var=
 noglue.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 
-;; NSEC for the normal NXRRSET case
+## NSEC for the normal NXRRSET case
+#var=nsec_www_txt
 www.example.com. 3600 IN NSEC example.com. A NSEC RRSIG
+
+#var=
 www.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 
-;; Authoritative data without NSEC
+## Authoritative data without NSEC
+#var=nonsec_a_txt
 nonsec.example.com. 3600 IN A 192.0.2.0
 
-;; NSEC3 RRs.  You may also need to add mapping to MockZoneFinder::hash_map_.
-;; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example.com. 3600 IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA NSEC3PARAM RRSIG
-;; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example.com. 3600 IN RRSIG NSEC3 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
-;; q04jkcevqvmu85r014c7dkba38o0ji5r.example.com. 3600 IN NSEC3 1 1 12 aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG
-;; q04jkcevqvmu85r014c7dkba38o0ji5r.example.com. 3600 IN RRSIG NSEC3 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
-
-;; NSEC3 for wild.example.com (used in wildcard tests, will be added on
-;; demand not to confuse other tests)
-;; ji6neoaepv8b5o6k4ev33abha8ht9fgc.example.com. 3600 IN NSEC3 1 1 12 aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en
-
-;; NSEC3 for cnamewild.example.com (used in wildcard tests, will be added on
-;; demand not to confuse other tests)
-;; k8udemvp1j2f7eg6jebps17vp3n8i58h.example.com. 3600 IN NSEC3 1 1 12 aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en
-
-;; NSEC3 for *.uwild.example.com (will be added on demand not to confuse
-;; other tests)
-;; b4um86eghhds6nea196smvmlo4ors995.example.com. 3600 IN NSEC3 1 1 12 aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG
-;; NSEC3 for uwild.example.com. (will be added on demand)
-;; t644ebqk9bibcna874givr6joj62mlhv.example.com. 3600 IN NSEC3 1 1 12 aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG
-
-;; (Secure) delegation data; Delegation with DS record
+## (Secure) delegation data; Delegation with DS record
+#var=signed_delegation_txt
 signed-delegation.example.com. 3600 IN NS ns.example.net.
+#var=signed_delegation_ds_txt
 signed-delegation.example.com. 3600 IN DS 12345 8 2 764501411DE58E8618945054A3F620B36202E115D015A7773F4B78E0F952CECA
+
+#var=
 signed-delegation.example.com. 3600 IN RRSIG DS 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 
-;; (Secure) delegation data; Delegation without DS record (and both NSEC
-;; and NSEC3 denying its existence)
+## (Secure) delegation data; Delegation without DS record (and both NSEC
+## and NSEC3 denying its existence)
+#var=unsigned_delegation_txt
 unsigned-delegation.example.com. 3600 IN NS ns.example.net.
+#var=unsigned_delegation_nsec_txt
 unsigned-delegation.example.com. 3600 IN NSEC unsigned-delegation-optout.example.com. NS RRSIG NSEC
-unsigned-delegation.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 
-;; This one will be added on demand
-; q81r598950igr1eqvc60aedlq66425b5.example.com. 3600 IN NSEC3 1 1 12 aabbccdd 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom NS RRSIG
+#var=
+unsigned-delegation.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 
-;; Delegation without DS record, and no direct matching NSEC3 record
+## Delegation without DS record, and no direct matching NSEC3 record
+#var=unsigned_delegation_optout_txt
 unsigned-delegation-optout.example.com. 3600 IN NS ns.example.net.
+#var=unsigned_delegation_optout_nsec_txt
 unsigned-delegation-optout.example.com. 3600 IN NSEC *.uwild.example.com. NS RRSIG NSEC
 
-;; (Secure) delegation data; Delegation where the DS lookup will raise an
-;; exception.
+## (Secure) delegation data; Delegation where the DS lookup will raise an
+## exception.
+#var=bad_delegation_txt
 bad-delegation.example.com. 3600 IN NS ns.example.net.
 
-;; Delegation from an unsigned parent.  There's no DS, and there's no NSEC
-;; or NSEC3 that proves it.
+## Delegation from an unsigned parent.  There's no DS, and there's no NSEC
+## or NSEC3 that proves it.
+#var=nosec_delegation_txt
 nosec-delegation.example.com. 3600 IN NS ns.nosec.example.net.

+ 11 - 0
src/bin/auth/tests/testdata/query_testzone_data_nsec3.txt

@@ -0,0 +1,11 @@
+## See query_testzone_data.txt for general notes.
+
+## NSEC3 RRs.  You may also need to add mapping to MockZoneFinder::hash_map_.
+#var=nsec3_apex_txt
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example.com. 3600 IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA NSEC3PARAM RRSIG
+#var=nsec3_apex_rrsig_txt
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example.com. 3600 IN RRSIG NSEC3 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+#var=nsec3_www_txt
+q04jkcevqvmu85r014c7dkba38o0ji5r.example.com. 3600 IN NSEC3 1 1 12 aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG
+#var=nsec3_www_rrsig_txt
+q04jkcevqvmu85r014c7dkba38o0ji5r.example.com. 3600 IN RRSIG NSEC3 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE