Commit graph

91 commits

Author SHA1 Message Date
Nicki Křížek
7853dbac43 Create zone setup helpers in isctest.zone
System tests that set up zones — especially DNSSEC tests — require a
chain of common operations: rendering zone files from templates,
generating keys, signing, and propagating DS records to parent zones.
Implement these as methods on isctest.zone.Zone so individual tests
don't need to repeat the logic in shell or ad-hoc Python.

isctest.zone.Zone is a plain class that holds the zone's data and
accumulated state (delegations, keys) alongside the methods that operate
on it. It is intentionally separate from isctest.template.Zone, which
remains a dumb data container for jinja2 template rendering.

Key design points:
- zone.Zone.name is the text form without trailing dot ("." for root);
  zone.Zone.dname holds the dns.name.Name for DNS-level operations;
  zone.Zone.basename is the filesystem-safe name ("root" for ".").
- filepath_unsigned / filepath_signed are both always available.
  filepath returns the appropriate one based on zone.Zone.signed.
- The zones/ subdirectory is the default (subdir="zones"); old-style
  tests that place zone files directly in the ns workdir can pass
  subdir=None.
- Signing is opt-in via signed=True; configure() auto-detects whether to
  generate keys and sign based on this flag, so the same method handles
  both signed and unsigned zones.
- delegations and keys are mutable list attributes; callers append to
  them before calling configure() rather than threading them through
  every call.

Also:
- Add isctest.template.zones() as a bridge from a list of zone.Zone to a
  {name: template.Zone} dict suitable for use as the ``zones`` template
  variable. template.zones() resolves filepath to the actual zone file
  so templates don't need to know whether a zone is signed.

Assisted-by: Claude:claude-opus-4-8
2026-06-04 18:33:09 +02:00
Michal Nowak
4eb893020e Fix pytest-xdist loadscope splitting on "::" in params
LoadScopeScheduling._split_scope() uses rsplit("::", 1) to
extract the test file scope from a node ID.  When parametrized
test values contain "::" (IPv6 addresses like "cafe:cafe::cafe"
or "::1"), the split lands inside the parameter instead of at
the .py:: boundary.  This creates spurious scopes that get
assigned to different workers, each triggering a full fixture
setup (starting named instances).

Override _split_scope() in conftest.py to split on ".py::"
which is unambiguous.

Six tests in synthrecord/tests_synthrecord.py are affected.
A verification script is included in util/.

Assisted-by: Claude:claude-opus-4-7
2026-05-28 18:00:17 +02:00
Michal Nowak
5e3c0b8463 Prioritize the 10 slowest system test scopes
Update PRIORITY_TESTS with the 10 longest-running test
scopes measured from CI (job 7468217).  These get scheduled
first so that with --dist=loadscope they land on separate
workers instead of piling up at the end.

Also fix "serve-stale/" to "serve_stale/" to match the
actual directory name, and add a startup check that fails
if any PRIORITY_TESTS entry does not match an existing
directory.

Assisted-by: Claude:claude-opus-4-7
2026-05-28 16:52:53 +02:00
Nicki Křížek
fa3a59e70c Improve isctest.template dataclasses' defaults
Extend the Nameserver to generate the default IPv4/IPv6 values, add NSX
values for the predefined nameservers (there are 11 of them, as per
bin/tests/system/ifconfig.sh.in max value). Add the missing ns11
fixture.

Extend the Zone to derive the zone filename by default, unless
specified.

Adjust the existing uses of these classes to utilize the simplified
defaults.
2026-05-27 14:19:31 +00:00
Štěpán Balážik
b31f058ad0 Move pytest requirements check to pytest_configure hook
Logging from a pytest hook looks better.

Reorder the check for presence of `featuretest` before `init_vars` to
produce more sensible errors.
2026-05-26 15:24:07 +00:00
Štěpán Balážik
261185ecb5 Log the Python interpreter used to run the system tests during setup
This is useful when running in an virtual environment or on a machine
where multiple Python versions are installed.
2026-04-15 15:12:38 +02:00
Nicki Křížek
9f4c1d1993 Use underscore for system test names
Change the convention for system test directory names to always use an
underscore rather than a hyphen. Names using underscore are valid python
package names and can be used with standard `import` facilities in
python, which allows easier code reuse.

The temporary directories for test execution and their convenience
symlinks have been switched to using hyphens rather than underscores to
keep the pytest collection, filtering and .gitignore working as
expected.
2026-03-18 14:32:33 +01:00
Štěpán Balážik
ef21b77912 Make default_algorithm accessible through a fixture and method
Importing pytest fixture trips up static analysis tools, so move
default_algorithm to conftest.py and use it instead of os.environ
accesses in various system tests.

For use outside test function, use Algorithm.default().
2026-02-20 15:17:32 +01:00
Štěpán Balážik
2b9c5ccd77 Define __all__ in __init__.py files
Fix ruff's F401 unused-import errors in these files.

Also sort them with: ruff check --extend-select RUF022 --fix.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
ffd5b6ac26 Automatically sort imports in Python code
Generated with: ruff check --extend-select I --fix (with the changes to
pyproject.toml applied).
2026-02-20 15:17:32 +01:00
Štěpán Balážik
57ecaee95d Fix vulture warnings and tweak ignore lists
Run vulture on the whole repository, fix most errors in previously
unchecked code, adjust ignore lists.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
c47b076494 Set dist=loadscope for pytest in pytest.ini
Previously there was some handling of old pytest-xdist versions which is
no longer needed.
2026-02-20 15:17:31 +01:00
Štěpán Balážik
4253d7298c Fix 'Import should be placed at the top of the module'
In preparation for running pylint on more Python code.
2026-02-20 15:17:31 +01:00
Nicki Křížek
b1e3469059 Resolve the system_test_dir in pytest
If the system_test_dir contains a symlink, then it might cause issues
further down when using relative_to(), unless it is resolved first. This
has been observed on FreeBSD13 in CI where /home is a symlink to
/usr/home.
2026-01-27 11:05:18 +01:00
Nicki Křížek
bb6d7a0fc3 Apply black formatting changes
Generated by black 26.1.0 which got updated in CI.
2026-01-22 09:41:21 +01:00
Nicki Křížek
ac8e2905b8 Bump the minimum required python version to 3.10
Drop support of EoL python versions for running system tests. The
maintenance cost of supporting end of life ecosystem, especially Python
3.6 on EL8 and the related outdated packages (pytest, dnspython, ...),
has become unreasonable.
2026-01-21 16:07:31 +01:00
Nicki Křížek
e276c3d5bd Remove pytest<7 compatibility hacks
Minimum pytest version has been bumped to 7.0.0, thus these are no
longer needed.
2026-01-21 16:07:31 +01:00
Nicki Křížek
093bef9211 Add support for pytest>=9.0.0
Use collection_path rather than the deprecated path argument for
pytest_ignore_collect() hook.

The collection_path argument was added in pytest 7.0.0, which is the
minimum supported pytest version from now on.
2026-01-21 16:07:31 +01:00
Michal Nowak
ce23dd4dd3
Add TSAN report and core file globs to expected artifacts 2025-12-15 19:42:50 +01:00
Nicki Křížek
d6d6db52e3 Allow any named*.conf file as a system test artifact
This allows rendering multiple named*.conf files using the jinja2
template engine at test start and then simply copying the required
config to named.conf as needed.
2025-12-09 14:23:14 +01:00
Nicki Křížek
ac7127d620 Use Re() for creating regular expressions
It's a fairly common pattern to use regular expression in our tests.
Instead of using the fairly verbose re.compile(), import that function
as Re() instead to allow for more brevity in the test syntax.
2025-12-08 14:57:47 +01:00
Nicki Křížek
7474d38295 Add module-specific python setup to system tests
During the system test execution, allow use of module-specific
bootstrap() function in addition to the setup.sh script which this
function should ultimately replace.

The purpose of bootstrap() is two-fold. First, it can execute any
commands needed to create the initial conditions for the test, such as
creating key materials, manipulating files etc. Second, it should return
any test-specific template values as a dictionary. Those will be used to
render the jinja2 templates.
2025-10-21 15:07:49 +02:00
Nicki Křížek
fe55342916 Add nsX fixtures to system tests
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.
2025-07-18 14:37:32 +02:00
Nicki Křížek
927dc5bc2b Check for FEATURETEST before running pytest
When compiling with meson, it may be easy to forget to compile system
test dependencies before running the tests. In that case, the test
results would be quite incosistent and unpredictable, with some tests
ending up with ERROR, some with FAILURE and others PASS, without a clear
indication that something is off before running the entire machinery.

Add a check to fail early on if the FEATURETEST binary isn't available,
indicating that system test dependencies were most likely not compiled.
2025-07-10 17:13:05 +02:00
Nicki Křížek
fcf31417dd Log assertion failures right after test result
The extra messages are typically traceback from assertion failures.
Previously, they'd be printed only after all individual test case
results have been printed. That made it difficult to pair the traceback
to the failing test in some cases, as the node information (aka test
name) might not always be present.

Instead, log any extra messages related to a particular test failure
directly after reporting its result, making the failure details more
readily available and easy to connect with a particular test case.
2025-06-27 16:31:49 +02:00
Nicki Křížek
0a6b0cf68c Don't log empty test result messages
The messages obtained from test results may contain stuff like detailed
failure/error information, tracebacks etc. In many cases, the message
will be empty, in which case it doesn't need to be logged.

For an example, run test with many test cases, e.g.
verify/test_verify.py, and inspect the tail of the pytest.log.txt before
and after this commit.
2025-06-27 16:31:49 +02:00
Nicki Křížek
c06dc71cd5 Make extra_artifacts check optional
There is an ongoing debate about the usefulness of the extra artifacts
check. While it might be useful to detect unexpected behaviour in some
tests, it feels extraneous in many cases. This change provides a middle
ground by making the artifact checking optional. This might be
especially useful for writing new tests, since the author gets to decide
whether the check is useful -- and can utilize it, or can skip it for
sake of brevity.
2025-06-24 16:56:53 +02:00
Aydın Mercan
5cd6c173ff
replace the build system with meson
Meson is a modern build system that has seen a rise in adoption and some
version of it is available in almost every platform supported.

Compared to automake, meson has the following advantages:

* Meson provides a significant boost to the build and configuration time
  by better exploiting parallelism.

* Meson is subjectively considered to be better in readability.

These merits alone justify experimenting with meson as a way of
improving development time and ergonomics. However, there are some
compromises to ensure the transition goes relatively smooth:

* The system tests currently rely on various files within the source
  directory. Changing this requirement is a non-trivial task that can't
  be currently justified. Currently the last compiled build directory
  writes into the source tree which is in turn used by pytest.

* The minimum version supported has been fixed at 0.61. Increasing this
  value will require choosing a baseline of distributions that can
  package with meson. On the contrary, there will likely be an attempt
  to decrease this value to ensure almost universal support for building
  BIND 9 with meson.
2025-06-11 10:30:12 +03:00
Michal Nowak
84c565878e
Revert "Ignore .hypothesis files created by system tests"
This reverts commit f413ddbe5f.
2025-05-13 17:03:21 +02:00
Michał Kępień
f413ddbe5f
Ignore .hypothesis files created by system tests
Some versions of the Hypothesis Python library - notably the one
included in stock OS repositories for Ubuntu 20.04 Focal Fossa - cause a
.hypothesis file to be created in a Python script's working directory
when the hypothesis module is present in its import chain.  Ignore such
files by adding them to the list of expected test artifacts to prevent
pytest teardown checks from failing due to these files appearing in the
file system after running system tests.
2025-03-18 06:19:01 +01:00
Nicki Křížek
b6d645410c Move shell and perl util functions to isctest.run
Previously, these functions have been provided as fixtures. This was
limiting re-use, because it wasn't possible to call these outside of
tests / other fixtures without passing these utility functions around.
Move them into isctest.run package instead.
2025-02-04 12:35:38 +00:00
Nicki Křížek
a72ff9fd57 Make servers fixture in pytest module-wide
The servers are setup and torn down once per each test module. All the
logs and server state persists between individual tests within the same
module. The servers fixture representing these servers should be
module-wide as well.
2025-01-24 08:45:51 +00:00
Michal Nowak
c607237b77
Add rr-related common test artifacts 2024-12-10 17:31:35 +01:00
Nicki Křížek
cf606a9ead Ignore test artifacts in .libs
Some tests may leave artifacts in the .libs directory. Ignore this
directory when detecting expected artifacts.
2024-11-26 09:05:15 +00:00
Nicki Křížek
b66fb31dcb Ensure pytest runner get proper outcome from flaky reruns
When a test is re-run by the flaky plugin, the TestReport outcomes
collected in the pytest_runtest_makereport() hook should be overriden.
Each of the setup/call/teardown phases is reported again and since we
care about the overall outcome, their respective results should be
overriden so that only the outcome from the final test (re)run gets
reported.

Prior to this change, it lead to a situation where an extra_artifact
generated during the test might be ignored. This was caused because the
check was skipped, since the test was incorrectly considered as "failed"
in the case where the test would fail on the first run, but pass on a
subsequent flaky rerun.
2024-11-12 10:19:03 +01:00
Nicki Křížek
f2cb2e5723 Remove invocations and mentions of clean.sh 2024-11-08 10:54:24 +01:00
Michał Kępień
3a9f4edddc Add pytest fixture for checking test artifacts
Prior to introducing the pytest runner, clean.sh files were used as a
list of files that the test is expected to leave around as artifacts and
check that no extra files were created.

With the pytest runner, those scripts are no longer used, but the
ability to detect extraneous files is still useful. Add a new
"extra_artifacts" mark which can be used for the same purpose.
2024-11-08 10:54:24 +01:00
Nicki Křížek
60e118c4fb Support jinja2 templates in pytest runner
Configuration files in system tests which require some variables (e.g.
port numbers) filled in during test setup, can now use jinja2 templates
when `jinja2` python package is available.

Any `*.j2` file found within the system test directory will be
automatically rendered with the environment variables into a file
without the `.j2` extension by the pytest runner. E.g.
`ns1/named.conf.j2` will become `ns1/named.conf` during test setup. To
avoid automatic rendering, use `.j2.manual` extension and render the
files manually at test time.

New `templates` pytest fixture has been added. Its `render()` function
can be used to render a template with custom test variables. This can be
useful to fill in different config options during the test. With
advanced jinja2 template syntax, it can also be used to include/omit
entire sections of the config file rather than using `named1.conf.in`,
`named2.conf.in` etc.
2024-10-30 18:00:20 +01:00
Nicki Křížek
7118cbed98 Make system tests compatible with pytest 8.0.0+
The pytest collection mechanism has been overhauled in pytest 8.0.0,
resulting in a different node tree when collecting the tests. Ensure the
paths / names we're using that are derived from the node tree are
consistent across different pytest versions.

Particularly, this has affected the convenience symlink name (which is
supposed to be in the form of e.g. dns64_sh_dns64 for the dns64 module
and tests_sh_dns64.py module) and the test name that's logged at the
start of the test, which is supposed to include the system test
directory relative to the root system test directory as well as the
module name (e.g. dns64/tests_sh_dns64.py).

Related https://github.com/pytest-dev/pytest/issues/7777
2024-10-24 13:13:13 +02:00
Nicki Křížek
7639c58c48 Disable too-many/too-few pylint checks
Enforcing pylint standards and default for our test code seems
counter-productive. Since most of the newly added code are tests or is
test-related, encountering these checks rarely make us refactor the code
in other ways and we just disable these checks individually. Code that
is too complex or convoluted will be pointed out in reviews anyways.
2024-10-17 11:01:44 +02:00
Tom Krizek
8302db407c
Move test algorithm configuration to isctest
Instead of invoking get_algorithms.py script repeatedly (which may yield
different results), move the algorithm configuration to an isctest
module. This ensures the variables are consistent across the entire test
run.
2024-07-31 10:50:09 +02:00
Nicki Křížek
ac7c657d19
Move isctest.var initialization to conftest.py
The environment variable initialization requires logging to be set up
first. Ensure the initialization is delayed until loggers have been set
up.
2024-05-09 17:08:11 +02:00
Tom Krizek
2d1f348483
Move env var initialization to isctest.vars
Make sure all initialization takes place in isctest.vars.__init__ and
export the initial env vars there. Remove the no longer needed env
fixture and use os.environ instead.
2024-05-09 17:08:10 +02:00
Tom Krizek
1f6f2234d8
Move dir env var handling to isctest.vars.dirs 2024-05-09 17:08:10 +02:00
Tom Krizek
41cb553bdd
Move port env vars into isctest.vars.ports module
The fixture for port assignment isn't needed, replace it with the common
way of handling environment variables.
2024-05-09 17:08:10 +02:00
Tom Krizek
46433ae17b
Coalesce system test variables
Provide a single point of access to all the variables used by tests. Use
a custom dict-like structure to access the underlying data without
making a copy. This allows the individual modules to update the contents
at runtime, which is used for some variables.
2024-05-09 17:08:09 +02:00
Tom Krizek
ab27f504ca
Move environment variables from conf.sh to pytest
Remove conf.sh.in and move the environment variables into isctest/vars
python package. This enabled the removal of an ugly pytest hack which
loaded and parsed these variables from the environment.
2024-05-09 17:08:08 +02:00
Tom Krizek
673387c4d5
Move conftest log initialization to conftest.py
Initializing the conftest logging upon importing the isctest package
isn't practical when there are standalone pieces which can be used
outside of the testing framework, such as the asyncdnsserver module.
2024-03-20 09:22:36 +01:00
Tom Krizek
c60975f108
Add utility logging functions to isctest.log
Unify the different loggers (conftest, module, test) into a single
interface. Remove the need to select the proper logger by automatically
selecting the most-specific logger currently available.

This also removes the need to use the logger/mlogger fixtures manually
and pass these around. This was especially annoying and unwieldy when
splitting the test cases into functions, because logger had to always be
passed around. Instead, it is now possible to use the
isctest.log.(debug,info,warning,error) functions.
2024-02-16 14:56:00 +01:00
Michał Kępień
662a88055c
Add wait_for_zones_loaded fixture
The wait_for_zones_loaded fixture waits for the "all zones loaded"
message in the named log file before the test function can proceed.
2023-12-22 15:02:58 +01:00