Commit Graph
11377 Commits
Author SHA1 Message Date
Petr ŠpačekandTom Krizek 37ed9ad2f8 Use raw byte format of env variables in pytest
In order to avoid issues with decoding/encoding env variables due to
different encodings on different systems, deal with the environment
variables directly as bytes.
2023-05-22 14:11:40 +02:00
Tom Krizek 0a063f51d3 Handle missing test_results due to pytest runner interrupt
If pytest execution is interrupted, the hook that exposes test_results
to the pytest session is never called so the results can't be
interpreted.
2023-05-22 14:11:40 +02:00
Tom Krizek 1cc55d01c7 Run system tests sequentially if xdist is not available 2023-05-22 14:11:39 +02:00
Petr ŠpačekandTom Krizek 8952618262 Include logs from failing tests in JUnit output 2023-05-22 14:11:39 +02:00
Petr ŠpačekandTom Krizek d0619c7a18 Enable live logging for non-parallel pytest runs
This provides incremental output when test is running _without xdist_,
just like the old runner did.

With xdist the live output is not available, I believe because of
https://github.com/pytest-dev/pytest-xdist/issues/402
https://github.com/pytest-dev/pytest-xdist/pull/883 might help with
that, but I'm not going to hold my breath until it is available on
distros we use.
2023-05-22 14:11:39 +02:00
Tom Krizek 8f57bce7af Ensure --dist=loadscope is used when running pytest in parallel
The loadscope setting is required for parallel execution of our system
tests using pytest. The option ensure that all tests within a single
(module) scope will be assigned to the same worker.

This is neccessary because the worker sets up the nameservers for all
the tests within a module scope. If tests from the same module would be
assigned to different workers, then the setup could happen multiple
times, causing a race condition. This happens because each module uses
deterministic port numbers for the nameservers.
2023-05-22 14:11:39 +02:00
Tom Krizek 4dbe8e5347 Invoke pytest runner from run.sh
Utilize developers' muscle memory to incentivize using the pytest runner
instead of the legacy one. The script also serves as basic examples of
how to run the pyest command to achieve the same results as the legacy
runner.

Invoking pytest directly should be the end goal, since it offers many
potentially useful options (refer to pytest --help).
2023-05-22 14:11:39 +02:00
Tom Krizek d1ef51f589 Add developer docs for pytest system test runner 2023-05-22 14:11:39 +02:00
Tom Krizek dc84121004 Update user docs with pytest system test runner 2023-05-22 14:11:39 +02:00
Tom Krizek 2f5bf6d971 Add pytest functions for shell system tests
In order to run the shell system tests, the pytest runner has to pick
them up somehow. Adding an extra python file with a single function
for the shell tests for each system test proved to be the most
compatible way of running the shell tests across older pytest/xdist
versions.

Modify the legacy run.sh script to ignore these pytest-runner specific
glue files when executing tests written in pytest.
2023-05-22 14:11:39 +02:00
Tom Krizek 8a406b73c9 Ignore tempdirs during pytest collection phase 2023-05-22 14:11:38 +02:00
Tom Krizek 527ac6ad26 Ensure compatiblity with older pytest
Special care needs to be taken to support older pytest / xdist versions.
The target versions are what is available in EL8, since that seems to
have the oldest versions that can be reasonably supported.
2023-05-22 14:11:38 +02:00
Tom Krizek 247e90c382 Keep the tempdir in case test setup/teardown fails
When an issue occurs inside a fixture (e.g. servers fail to start/stop),
the test result won't be detected as failed, but rather an error will be
thrown.

To ensure the tempdir is kept even if the test itself passes but the
system_test() fixture throws an error, a different mechanism is needed.
At the start of the critical test setup section, note that the fixture
hasn't finished yet. When this is detected in the system_test_dir()
fixture, it is recognized as error in test setup/teardown and the temp
directory is kept.

This may seem cumbersome, because it is. It's basically a workaround for
the way pytest handles fixtures and test errors in general.
2023-05-22 14:11:38 +02:00
Tom Krizek 2d93ed8546 Ensure tempdir is kept for failed system tests
The temporary directory contains artifacts for the pytest module. That
module may contain multiple individual tests which were executed
sequentially. The artifacts should be kept if even one of these tests
failed.

Since pytest doesn't have any facility to expose test results to
fixtures, customize the pytest_runtest_makereport() hook to enable that.
It stores the test results into a session scope variable which is
available in all fixtures.

When deciding whether to remove the temporary directory, find the
relevant test results for this module and don't remove the tmpdir if any
one the tests failed.
2023-05-22 14:11:38 +02:00
Tom Krizek 8b1a906b39 Add --noclean option to pytest runner
Support the --noclean option to allow the user to keep the artifacts
from any test run.
2023-05-22 14:11:38 +02:00
Tom Krizek c571af8c8f Run system tests inside temporary directories
For every pytest module, create a copy of its system test directory and
run the test from that directory. This makes it easier to clean up
afterwards and makes it less error-prone when re-running (failed) tests.

Configure the logger to capture the module's log output into a separate
file available from the temporary directory. This is quite convenient
for exploring failures.

Cases where temporary directory should be kept are handled in a
follow-up commits.
2023-05-22 14:11:38 +02:00
Tom Krizek 2b64618624 Execute the system test workflow in pytest runner
This is basically the pytest re-implementation of the run.sh script.

The fixture is applied to every module and ensures complete test
setup/teardown, such as starting/stopping servers, detecting coredumps
etc.

Note that the fixture system_test_dir is not defined yet. It is omitted
now for review readability and it's added in follow-up commits.
2023-05-22 14:11:37 +02:00
Tom Krizek 6886cc1826 Utility fixtures for pytest runner
Add fixtures for deriving system test name from the directory name and
for a module-specific logger.

Add fixtures to execute shell and perl scripts. Similar to how run.sh
calls commands, this functionality is also needed in pytest. The
fixtures take care of switching to a proper directory, logging
everything and handling errors.

Note that the fixture system_test_dir is not defined yet. It is omitted
now for review readability and it's added in follow-up commits.
2023-05-22 14:11:37 +02:00
Tom Krizek 0061758156 Assign unique ports to pytest modules
This is basically a pytest re-implementation of the get_ports.sh script.
The main difference is that ports are assigned on a module basis, rather
than a directory basis. Module is the new atomic unit for parallel
execution, therefore it needs to have unique ports to avoid collisions.

Each module gets its ports through the env fixture which is updated with
ports and other module-specific variables.
2023-05-22 14:11:37 +02:00
Tom Krizek ee26066897 Ensure system test programs and deps are compiled
Some system tests require extra programs and/or dependencies to be
compiled first. This is done via `make check` with the automake
framework when using check_* variables such as check_PROGRAMS.

To avoid running any tests via the automake framework, set the TESTS
env variable to empty string and utilize `make -e check` to override
default Makefile variables with environment ones. This ensures automake
will only compile the needed dependencies without running any tests.

Additional consideration needs to be taken for xdist. The compilation
command should be called just once before any tests are executed. To
achieve that, use the pytest_configure() hook and check that the
PYTEST_XDIST_WORKER env variable isn't set -- if it is, it indicates
we're in the spawned xdist worker and the compilation was already done
by the main pytest process that spawned the workers.

This is mostly done to have on-par functionality with legacy test
framework. In the future, we should get rid of the need to run "empty"
make -e check and perhaps compile test-stuff by default.
2023-05-22 14:11:37 +02:00
Tom Krizek 2f7af791a1 Obtain env vars from conf.sh in pytest runner
The commands executed by pytest during a system test need to have the
same environment variables set as if they were executed by the run.sh
shell script.

It was decided that for the moment, legacy way of executing system tests
with run.sh should be kept, which complicates things a bit. In order to
avoid duplicating the required variables in both conf.sh and pytest, it
was decided to use the existing conf.sh as the only authoritative
place for the variables.

It is necessary to process the environment variables from conf.sh right
when conftest.py is loaded, since they might be needed right away (e.g.
to test for feature support during test collection).

This solution is a bit hacky and is only meant to be used during the
transitory phase when both pytest and the legacy run.sh are both
supported. In the future, a superior pytest-only solution should be
used.

For discussion of other options, refer to
https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/6809#note_318889
2023-05-22 14:11:37 +02:00
Tom Krizek 08c4e35bc0 Collect existing tests in pytest runner
Ensure pytest picks up our python test modules, since we're using
tests_*.py convention, which is different from the default.

Configure pytest logging to display the output from all tests (even the
ones that passed). This ensures we have sufficient amount of information
to debug test post-mortem just from the artifacts.
2023-05-22 14:11:37 +02:00
Tom Krizek 30cb9b7e28 Support both pytest and legacy system test runner
The legacy system test framework uses pytest to execute some tests.
Since it'd be quite difficult to convince pytest to decide whether to
include conftest.py (or which ones to include when launching from
subdir), it makes more sense to have a shared conftest.py which is used
by both the legacy test runner invocations of pytest and the new pytest
system test runner. It is ugly, but once we drop support for the legacy
runner, we'll get rid of it.

Properly scope the *port fixtures in order to ensure they'll work as
expected with the new pytest runner. Instead of using "session" (which
means the fixture is only evaluated once for the entire execution of
pytest), use "module" scope, which is evaluated separately for each
module. The legacy runner invoked pytest for each system test
separately, while the new pytest runner is invoked once for all system
tests -- therefore it requires the more fine-grained "module" scope to
for the fixtures to work properly.

Remove python shebang, as conftest.py isn't supposed to be an executable
script.
2023-05-22 14:11:35 +02:00
Michal Nowak 0c4c7ddec4 TSAN summarising line was misplaced in get_core_dumps.sh
The line summarising TSAN reports was misplaced in the ASAN territory
and thus never used.

I also made core dumps, assertion failures, and TSAN reports detection
independent of each other.
2023-05-19 08:57:36 +02:00
Mark Andrews d360d8af8f Let RSASHA1 signing keys be ignored in FIPS mode
When the FIPS provider is available, RSASHA1 signing keys for zone
"example.com." are ignored if the zone is attempted to be signed with
the dnssec-signzone "-F" (FIPS mode) option:

    "fatal: No signing keys specified or found"
2023-05-17 23:51:39 +00:00
Evan HuntandTony Finch 6bf35c2f19 Match UQ and UR stats to domain name
The upforwd test for forwarding updates to a dead primary can continue
running a little bit past its end, causing update replies to be
recorded during a subsequent test case. Correct this by only looking
for update requests and replies for the specific domain name being
tested at any given time.
2023-05-16 13:37:07 +01:00
Tony Finch 2e96d225ae Fix the upforwd system test
After the RCU changes were merged, the `upforwd` test started
consistenly failing when run under thread sanitizer. After some
investigation, it turned out that retry attempts were continuing after
the "update forwarding to dead primary" test. This caused mismatches
in the DNSTAP message counts for the subsequent tests, because they
were also counting retries.

Fix this problem by `wait`ing for the `nsupdate` processes to exit.

While investigating the bug, I replaced several fixed 15 second delays
with `wait_for_log`, so the test runs faster.
2023-05-16 13:37:02 +01:00
Tony Finch c377e0a9e3 Help thread sanitizer to cope with liburcu
All the places the qp-trie code was using `call_rcu()` needed
`__tsan_release()` and `__tsan_acquire()` annotations, so
add a couple of wrappers to encapsulate this pattern.

With these wrappers, the tests run almost clean under thread
sanitizer. The remaining problems are due to `rcu_barrier()`
which can be suppressed using `.tsan-suppress`. It does not
suppress the whole of `liburcu`, because we would like thread
sanitizer to detect problems in `call_rcu()` callbacks, which
are called from `liburcu`.

The CI jobs have been updated to use `.tsan-suppress` by
default, except for a special-case job that needs the
additional suppressions in `.tsan-suppress-extra`.

We might be able to get rid of some of this after liburcu gains
support for thread sanitizer.

Note: the `rcu_barrier()` suppression is not entirely effective:
tsan sometimes reports races that originate inside `rcu_barrier()`
but tsan has discarded the stack so it does not have the
information required to suppress the report. These "races" can
be made much easier to reproduce by adding `atexit_sleep_ms=1000`
to `TSAN_OPTIONS`. The problem with tsan's short memory can be
addressed by increasing `history_size`: when it is large enough
(6 or 7) the `rcu_barrier()` stack usually survives long enough
for suppression to work.
2023-05-12 20:48:31 +01:00
Tony Finch 9882a6ef90 The zone table no longer depends on the loop manager
This reverts some of the changes in commit b171cacf4f
because now it isn't necessary to pass the loopmgr around.
2023-05-12 20:48:31 +01:00
Evan Hunt 922a390852 add 'rndc -t' option to set timeout
Allow an arbitrary TCP timeout value to be specified when running
rndc, so that commands that take a long time to execute (for example,
reloading a very large configuration) can be given time to do so.
2023-05-12 11:28:21 -07:00
Matthijs Mekking af15e760d7 Add test case for cdnskey no;
Change one of the test cases to disable publication of CDNSKEY.
2023-05-11 17:07:51 +02:00
Matthijs Mekking 8be61d1845 Add configuration option 'cdnskey'
Add the 'cdnskey' configuration option to 'dnssec-policy'.
2023-05-11 17:07:51 +02:00
Michal Nowak 0c05c3d97b Rewrite the ttl system test to pytest 2023-05-11 15:14:48 +02:00
Michal Nowak 31935a3537 Disable ASAN in nsupdate for fatal cases
Clang 16 LeakSanitizer reports a memory leak when dns_request_create()
returned a TLS error in the nsupdate system test. While technically a
memory leak on error handling, it's not a problem because the program is
immediately terminated; nsupdate is not expected to run for a prolonged
time.
2023-05-11 13:39:51 +02:00
Michal Nowak 5a84c7a09b Rewrite the hooks system test to pytest
Also, enable the test under TSAN.
2023-05-11 11:49:33 +02:00
Mark Andrews 9d95cd427d Check fallback on FORMERR to EDNS options 2023-05-11 10:49:39 +10:00
Mark Andrews 3328ddaf7a Add a server which returns FORMERR to all EDNS options
The server also echoes back the EDNS options and EDNS flags.
2023-05-11 09:32:02 +10:00
Aram Sargsyan e4604b71d2 dighost.c: don't call check_if_done() twice successively
The check_if_done() function can pass control back out to
dighost_shutdown() (which is part of dig.c, host.c, or nslookup.c),
and calling that twice can cause unexpected problems, if it is not
designed to be idempotent.

Since cancel_lookup() calls check_if_done() implicitly, don't call
check_if_done() again when 'next' is NULL.
2023-05-10 11:35:51 +00:00
Tom Krizek dee49b7a1f Replace dnspython resolver.query with resolver.resolve
The resolver.query() has been deprecated in favor of resolver.resolve();
used that.

This is an omission from 3b1756d450
2023-05-10 10:56:36 +02:00
Tom Krizek 836e6ed284 Ensure named always terminates in the shutdown test
Previously, if an exception would happen inside the `with` block, the
error handler would wait indefinitely for the process to end. That would
never happen, since the termination signal was never sent to named and
the test would get stuck.

Using the try-finally block ensures that the named process is always
killed and any exception or errors will be handled gracefully.
2023-05-10 10:56:22 +02:00
Tom Krizek 9d64f1c1ed Refactor shutdown test into more helper functions
Improve code readability by splitting the test into more functions. Some
could be re-used later on for more general-purpose subprocess handling
or named checks.
2023-05-10 10:56:19 +02:00
Evan Hunt 9cacf9e336 set the default rndc read timeout to 60 seconds
While the connect timeout was set to 60 seconds in rndc, the
idle read timeout was left at the default value of 30 seconds.
This commit sets it back to 60, to match the behavior in 9.16
and earlier.
2023-05-05 00:06:50 -07:00
Oliver FordandMatthijs Mekking 3f9b8b7dfa Add option to dnstap-read to print long timestamps
Adds a -t option to dnstap-read to print timestamps with
millisecond precision
2023-05-04 15:12:53 +02:00
Oliver FordandMatthijs Mekking 2e85d9faaa Change dnstap-read timestamp to millis 2023-05-04 15:02:03 +02:00
Matthijs Mekking d9b1df3b5d Add log rotation test with absolute file path
Add a test to the logfileconfig system test to test log file rotation
when using absolute file paths.
2023-05-03 09:12:11 +02:00
Matthijs Mekking 9fb9670ebc Add more log/tap rotation tests
Add more tests to the dnstap system test to roll with different values.
Touch some files to make sure the number of existing files exceed the
number that we want to keep.

Add a test to the logfileconfig system test for the increment suffix.
2023-05-03 09:12:11 +02:00
Evan Hunt 7de2d07eb0 add a regression test for duplicate NS output
check that an NS RRset with two servers is only printed once.
2023-05-02 12:42:50 -07:00
Evan Hunt 108809ae84 prevent duplicate output from delv +ns
when printing the result of a query, delv +ns repeated the
answer RRset as many times as there were records in the RRset;
this has been fixed by suppressing the printing of records with
the same name and type as the preceding one.
2023-05-02 12:42:50 -07:00
Ondřej Surý 6948060e01 Print out the Userspace-RCU flavor and version
The `named -V` now prints out the liburcu flavor used and the
compile-time version.
2023-04-27 12:38:53 +02:00
Mark Andrews ad91a70d15 Check removal of ENT when subdomains are removed
Empty-non-terminal NSEC records where not always removed when the
delegations generating them where removed via update. Check that
they now are.
2023-04-25 05:03:40 +01:00