many of the zones in the dnssec system test were identical or
had only trivial differences, and it would be easier to keep track
of them if they were sourced from template files.
also, the extra_artifacts have been simplified and restored to
the test files.
the shell tests that queried servers to check correct signing
behavior (using dnssec-signzone, dnssec-policy and nsupdate),
as well as "rndc signing", private-type records, rndc zonestatus,
offline keys, etc, have been moved to tests_signing.py.
the minimal update test in the dnssec_update_test.pl script
was also moved here and the perl script has been removed.
begin converting DNSSEC validation tests from shell to python,
and simplify the name servers used in the test.
ns4, the name server used for validation tests, is now configured
using jinja2 templates.
ns8, which was previously used for testing unsupported, disabled
and revoked keys and trust anchors, has been removed. we now
use a jinja2 configuration in ns5 for this purpose.
the configurations in ns7 and ns6 didn't conflict with one another,
so the two servers have been merged into one.
- dnssec tool tests (i.e., dnssec-signzone, dnssec-keygen, etc) that
don't require interaction with a running server have been moved
to a new 'dnssectools' system test directory.
- a dig formatting test has been moved to digdelv.
- a named-rrchecker test has been moved to rrchecker
the tests of "rndc nta" behavior have been moved out of the
dnssec shell test, into bin/tests/system/nta, and converted
to python. features of the dnssec test framework that were
needed for NTA testing have been moved to the nta test, and
dnssec has been correspondingly simplified.
- changed named.conf.in to named.conf.j2 in all server directories that
don't currently need to use copy_setports() during the test.
- converted the tests that use ns5 to python, and replaced
named1.conf.in and named2.conf.in with a jinja2 template instead.
the only remaining server that still needs copy_setports() is ns4.
- removed ns4/named5.conf.in, and moved its functions to ns5 (which
is supposed to be for servers with broken trust-anchor configurations,
so it should have been there in the first place). converted the tests
that used that ns4 configuration to use ns5 with jinja instead.
- revised the remaining ns4 configurations (named[1-4].conf.in) to
minimize the differences between them. this will make it easier to
convert it into a jinja2 template later.
Rather than using the dnspython's facilities and defaults to create the
queries, use the isctest.query.create function in all the cases that
don't require special handling to have consistent defaults.
Use a common function to count the number of RRs in any section of the
DNS message. For the ADDITIONAL section, stick with the dnspython
convention of not including OPT and TSIG.
added some helper functions in isctest to reduce code repetition
in dnssec-related tests:
- isctest.check.adflag() - checks that a response contains AD=1
- isctest.check.noadflag() - checks that a response contains AD=0
- isctest.check.rdflag() - checks that a response contains RD=1
- isctest.check.nordflag() - checks that a response contains RD=0
- isctest.check.answer_count_eq() - checks the answer count is correct
- isctest.check.additional_count_eq() - same for authority count
- isctest.check.authority_count_eq() - same for additional count
- isctest.check.same_data() - check that two message have the
same rcode and data
- isctest.check.same_answer() - check that two message have the same
rcode and answer
- isctest.dnssec.msg() - a wrapper for dns.message.make_query() that
creates a query message similar to dig +dnssec:
use_edns=True, want_dnssec=True,
and flags are set to (RD|AD) by default, but
options exist to disable AD or enable CD.
(to generate non-DNSSEC queries, use
message.make_query() directly.)
MR !10238 added key collision detection in the ksr system test but it
was flawed because for every "collide" in the output we also log
"Generating an new key" and for each "Generating" we add the counter
by one, nullifying the subtract by one.
Use regular expressions to search in the output and make the string
expression more strict.
Add missing type hints in the tests_nsec3.py module. Tweak the syntax
used for type hints for better consistency with other Python code in
bin/tests/system/.
Basic sanity checks - limited to responses from a single zone:
- NSEC3 type cannot be present in type bitmap:
By definition, the type bitmap describes state of the unhashed name
but NSEC3 RR is present at a different owner name. RFC 7129 section 5
- NSEC3 owner names cannot be duplicated:
Unless the response crosses zone boundary, parent zone has insecure
delegation for child, but child is signed ... don't do that.
- All parameters are consistent across all RRs present in answer:
RFC 5155 section 7.2, last paragraph - at least when we don't cross
zone boundary.
Untangling individual cases allows for clearer documentation and makes
it easier to build similar but slightly different test cases. Wildcard
NODATA answer was added.
Test all combinations of wildcard, ENT, DNAME, NS, and ordinary
TXT records.
Test zone and expected outputs are generated by another script which
encodes node content into node name. This encoding removes 'node
content' level of indirection and thus enables simpler implementation of
same logic which needs to be in ZoneAnalyzer itself.
For humans the generated zone file also lists expected 'categories' a
name belongs to as dot-separated list on right hand side of a generated
RR.
I've considered writing hypothesis test for this but I would have to
reimplement the same thing, which would probably have the same logic
bugs, so I will leave it as an exercise for someone else.
Check the correctness of NSEC3 hash generation by generating random
combinations of name, salt, and iterations and comparing the outputs
of the nsec3hash tool against the dnspython nsec3_hash function
for the same inputs.
For any given NSEC3 signed zone, when doing queries for non-existent
names, the response must contain:
- NSEC3 RR that matches the closest encloser,
- NSEC3 RR that covers the next closer name,
- NSEC3 RR that covers the wildcard.
When the tests-connreset.py module was initially implemented in commit
5c17919019, the dispatch code did not
properly apply the idle timeout to TCP connections. This allowed the
check in that test module to reset the TCP connection after 5 seconds as
named did not attempt to tear the connection down earlier than that.
However, as the dispatch code was improved, the idle timeout started
being enforced for TCP dispatches; the exact value it is set to in the
current code depends on a given server's SRTT, but it defaults to about
1.2 seconds for responsive servers. This means that the code paths
triggered by the "dispatch" system test are now different than the ones
it was originally supposed to trigger because it is now named itself
that shuts the TCP connection down cleanly before the ans3 server gets a
chance to reset it.
Account for the above by lowering the amount of time after which the
ans3 server in the "dispatch" system test resets TCP connections to just
1 second, so that the test actually does what its name implies.
Add a TCP connection handler, ConnectionReset, which enables closing TCP
connections without emptying the client socket buffer, causing the
kernel to send an RST segment to the client. This relies on a horrible
asyncio hack that can break at any point in the future due to abusing
implementation details in the Python Standard Library. Despite the eye
bleeding this code may cause, the approach it takes was still deemed
preferable to implementing an asyncio transport from scratch just to
enable triggering connection resets.
In response to client queries, AsyncDnsServer users can currently only
make the server either send a reply or silently ignore the query. In
the case of TCP queries, neither of these actions causes the client's
connection to be closed - the onus of doing that is on the client.
However, in some cases the server may be required to close the
connection on its own, so AsyncDnsServer users need to have some way of
requesting such an action.
Add a new ResponseAction subclass, ResponseDropAndCloseConnection, which
enables AsyncDnsServer users to conveniently request TCP connections to
be closed. Instead of returning the response to send,
ResponseDropAndCloseConnection raises a custom exception that
AsyncDnsServer._handle_tcp() handles accordingly.
There is only a single network manager running on top of the loop
manager (except for tests). Refactor the network manager to be a
singleton (a single instance) and change the unit tests, so that the
shorter read timeouts apply only to a specific handle, not the whole
extra 'connect_nm' network manager instance.
All the applications built on top of the loop manager were required to
create just a single instance of the loop manager. Refactor the loop
manager to not expose this instance to the callers and keep the loop
manager object internal to the isc_loop compilation unit.
This significantly simplifies a number of data structures and calls to
the isc_loop API.
The original `ans.pl` server was based on a copy of the one in
`fetchlimit`, so there are some changes:
- The server now only responds with A replies (which is the only thing
needed).
- The incrementing of the IP address goes beyond the least significant
octet (so, after 192.0.2.255 it will yield 192.0.3.0).
The LSP server (using clangd) was always complaining about:
Suspicious string literal, probably missing a comma
for the two Local IPv6 Unicast Addresses strings that spanned
across multiple lines. Disable clang-format for these two lines.
Add \007.no-apex-covering as an owner name so that the cache does
not get primed with a parent NSEC RRset to test the case where
dns_qp_lookup returns ISC_R_NOTFOUND.
The kasp test cases assume that keymgr operations on the zone under test
have been completed before the test is executed. These are typically
quite fast, but the logs need to be explicitly checked for the messages,
otherwise there's a possibility of race conditions causing the
kasp/rollover tests to become unstable.
Call the wait function in all the kasp/rollover tests where it is
expected (which is generally in each test, unless we're dealing with
unsigned zones).
Many of our test cases only use a single NamedInstance from the
`servers` fixture. Introduce `nsX` helper fixtures to simplify these
tests and reduce boilterplate code further.
Specifically, the test no longer has to either define its own variable
to extract a single server from the list, or use the longer
servers["nsX"] syntax. While this may seem minor, the amount of times it
is repeated across the tests justifies the change. It also promotes
using more explicit server identification, i.e. `nsX`, rather than
generic `server`. This also improves the clarity of the tests and may be
helpful in traceback during debugging as well.
Previously, a lot of the checking was re-implemented and duplicated from
check_rollover_step(). Use that function where possible and only
override the needed checks.
Rather than using multiple slightly modified named.conf files, use a
single template which can be rendered differently based on an input
argument -- in this case, csk_roll.
- Use WatchLog.wait_for_sequence() for the configloading test.
- Omit artifacts check, as it seems quite useless for this test case.
- Join all the tests together. The test case is fairly simple here and
this is the easiest way to ensure the log will be in a predictable
state for all tests. Previously, there was no way to ensure
test_configloading_loading() won't be executed after the other tests,
which would render the check moot. It could also be separated into
its own module, but that seems excessive for a simple test case like
this.
- Use jinja2 template for named.conf and remove setup.sh.
- Remove README and put the relevent comment directly next to the test.
- Remove _sh_ from the test filename to uphold the naming convention.
The test is troublesome, because NamedInstance(identifier) expects that
a directory with such a name exists. While it'd be possible to mock
those directories as well, it'd make the doctest overly long and
complex, which isn't justified, given that it's only testing a couple of
options. Turn it into regular documentation instead.
The buffered reading of finished lines deserves its own class to make
its function clearer, rather than bundling it within the WatchLog class.
Co-Authored-By: Michał Kępień <michal@isc.org>
Extend the WatchLog API with a couple of new matching options.
wait_for_sequence() can be used to check a specific sequence of lines
appears in the log file in the given order.
wait_for_all() ensure that all the provided patterns appear in the log
at least once.
Co-authored-by: Colin Vidal <colin@isc.org>
To allow re-use in upcoming functions, isolate the line matching logic
into a separate function. Use an instance-wide deadline attribute, which
is set by the calling function.
Rather than using two distinct functions for matching either one pattern
(wait_for_line()), or any of multiple patterns (wait_for_lines()), use a
single function that handles both in the same way.
Extend the wait_for_line() API:
1. To allow for usage of one or more FlexPatterns, i.e. either plain
strings to be matched verbatim, or regular expressions. Both can be
used interchangeably to provide the caller to write simple and
readable test code, while allowing for increased complexity to allow
special cases.
2. Always return the regex match, which allows the caller to identify
which line was matched, as well as to extract any additional
information, such as individual regex groups.
To simplify usage of multiple wait_for_*() calls, configure the timeout
value for the WatchLog instance, rather than specifying it for each
call.
This is a preparation/cleanup for implementing multiple wait_for_*()
calls in subsequent commits.
Move the line buffering functionality into _readline() to improve the
readability of code. This also allows reading the file contents from
other functions, since the line buffer is now an attribute of the class.
Fix some broken doctest in watchlog.py (no semantic error, but API
slightly changed and broke some output messags). Also add a test for a
missing failure case.
DNSKEY algorithms RSASHA1 and RSASHA-NSEC3-SHA1 and DS digest type
SHA1 are deprecated. Log when these are present in primary zone
files and when generating new DNSKEYs, DS and CDS records.