Skip to content

Commit 467e806

Browse files
authored
Merge pull request #2749 from jku/test-fixes
Unit test infrastructure fixes
2 parents 3c4fcde + 4548f38 commit 467e806

13 files changed

+36
-172
lines changed

Diff for: .github/workflows/_test.yml

+1-7
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,8 @@ jobs:
7474
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7575
COVERALLS_FLAG_NAME: ${{ runner.os }} / Python ${{ matrix.python-version }}
7676
COVERALLS_PARALLEL: true
77-
# Use cp workaround to publish coverage reports with relative paths
78-
# FIXME: Consider refactoring the tests to not require the test
79-
# aggregation script being invoked from the `tests` directory, so
80-
# that `.coverage` is written to and .coveragrc can also reside in
81-
# the project root directory as is the convention.
8277
run: |
83-
cp tests/.coverage .
84-
coveralls --service=github --rcfile=tests/.coveragerc
78+
coveralls --service=github
8579
8680
coveralls-fin:
8781
# Always run when all 'tests' jobs have finished even if they failed

Diff for: .github/workflows/specification-version-check.yml

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ jobs:
2020
python-version: "3.x"
2121
- id: get-version
2222
run: |
23-
python3 -m pip install -e .
2423
script="from tuf.api.metadata import SPECIFICATION_VERSION; \
2524
print(f\"v{'.'.join(SPECIFICATION_VERSION)}\")"
2625
ver=$(python3 -c "$script")

Diff for: docs/CONTRIBUTING.rst

+5-9
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,18 @@ you need debug/run outside ``tox``.
3939
Unit tests
4040
----------
4141

42-
More specifically, the Update Framework's test suite can be executed by invoking
43-
the test aggregation script inside the *tests* subdirectory. ``tuf`` and its
44-
dependencies must already be installed.
42+
test suite can be executed directly as well (in this case the environment managed by tox is
43+
not used):
4544
::
4645

47-
cd tests/
48-
python3 aggregate_tests.py
46+
python3 -m unittest
4947

5048

5149
Individual tests can also be executed. Optional ``-v`` flags can be added to
5250
increase log level up to DEBUG (``-vvvv``).
5351
::
5452

55-
cd tests/
56-
python3 test_updater_ng.py -v
53+
python3 tests/test_updater_ng.py -v
5754

5855

5956
Coverage
@@ -64,8 +61,7 @@ invoked with the ``coverage`` tool (requires installation of ``coverage``, e.g.
6461
via PyPI).
6562
::
6663

67-
cd tests/
68-
coverage run aggregate_tests.py && coverage report
64+
coverage run -m unittest
6965

7066

7167
Auto-formatting

Diff for: pyproject.toml

+4-6
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,6 @@ include = [
7070
"/setup.py",
7171
]
7272

73-
[tool.hatch.build.targets.wheel]
74-
# The testing phase changes the current working directory to `tests` but the test scripts import
75-
# from `tests` so the root directory must be added to Python's path for editable installations
76-
dev-mode-dirs = ["."]
77-
7873
# Ruff section
7974
# Read more here: https://docs.astral.sh/ruff/linter/#rule-selection
8075
[tool.ruff]
@@ -158,4 +153,7 @@ exclude_also = [
158153
"raise AssertionError",
159154
# imports for mypy only
160155
"if TYPE_CHECKING",
161-
]
156+
]
157+
[tool.coverage.run]
158+
branch = true
159+
omit = [ "tests/*" ]

Diff for: requirements/dev.txt

-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
# Install tuf in editable mode and requirements for local testing with tox,
2-
# and also for running test suite or individual tests manually.
3-
# The build and tox versions specified here are also used as constraints
4-
# during CI and CD Github workflows
51
-r build.txt
62
-r test.txt
73
-r lint.txt
8-
-e .

Diff for: tests/.coveragerc

-13
This file was deleted.

Diff for: tests/aggregate_tests.py

-44
This file was deleted.

Diff for: tests/generated_data/generate_md.py

+13-14
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@
5656
signers.append(CryptoSigner(private_key, key))
5757

5858
EXPIRY = datetime(2050, 1, 1, tzinfo=timezone.utc)
59-
OUT_DIR = "generated_data/ed25519_metadata"
60-
if not os.path.exists(OUT_DIR):
61-
os.mkdir(OUT_DIR)
6259

6360
SERIALIZER = JSONSerializer()
6461

@@ -80,15 +77,13 @@ def verify_generation(md: Metadata, path: str) -> None:
8077
)
8178

8279

83-
def generate_all_files(
84-
dump: bool | None = False, verify: bool | None = False
85-
) -> None:
86-
"""Generate a new repository and optionally verify it.
80+
def generate_all_files(dump: bool = False) -> None:
81+
"""Generate a new repository or verify that output has not changed.
8782
8883
Args:
89-
dump: Wheter to dump the newly generated files.
90-
verify: Whether to verify the newly generated files with the
91-
local staored.
84+
dump: If True, new files are generated. If False, existing files
85+
are compared to generated files and an exception is raised if
86+
there are differences.
9287
"""
9388
md_root = Metadata(Root(expires=EXPIRY))
9489
md_timestamp = Metadata(Timestamp(expires=EXPIRY))
@@ -103,12 +98,16 @@ def generate_all_files(
10398
for i, md in enumerate([md_root, md_timestamp, md_snapshot, md_targets]):
10499
assert isinstance(md, Metadata)
105100
md.sign(signers[i])
106-
path = os.path.join(OUT_DIR, f"{md.signed.type}_with_ed25519.json")
107-
if verify:
108-
verify_generation(md, path)
109-
101+
path = os.path.join(
102+
utils.TESTS_DIR,
103+
"generated_data",
104+
"ed25519_metadata",
105+
f"{md.signed.type}_with_ed25519.json",
106+
)
110107
if dump:
111108
md.to_file(path, SERIALIZER)
109+
else:
110+
verify_generation(md, path)
112111

113112

114113
if __name__ == "__main__":

Diff for: tests/repository_data/README.md

-48
This file was deleted.

Diff for: tests/test_fetcher_ng.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
import sys
1111
import tempfile
1212
import unittest
13-
from collections.abc import Iterator
14-
from typing import Any, ClassVar
13+
from typing import ClassVar
1514
from unittest.mock import Mock, patch
1615

1716
import requests
@@ -163,11 +162,11 @@ def test_download_file_upper_length(self) -> None:
163162
self.assertEqual(self.file_length, temp_file.tell())
164163

165164
# Download a file bigger than expected
166-
def test_download_file_length_mismatch(self) -> Iterator[Any]:
167-
with self.assertRaises(exceptions.DownloadLengthMismatchError):
168-
# Force download_file to execute and raise the error since it is a
169-
# context manager and returns Iterator[IO]
170-
yield self.fetcher.download_file(self.url, self.file_length - 4)
165+
def test_download_file_length_mismatch(self) -> None:
166+
with self.assertRaises(
167+
exceptions.DownloadLengthMismatchError
168+
), self.fetcher.download_file(self.url, self.file_length - 4):
169+
pass # we never get here as download_file() raises
171170

172171

173172
# Run unit test.

Diff for: tests/test_metadata_generation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class TestMetadataGeneration(unittest.TestCase):
1616
@staticmethod
1717
def test_compare_static_md_to_generated() -> None:
1818
# md_generator = MetadataGenerator("generated_data/ed25519_metadata")
19-
generate_all_files(dump=False, verify=True)
19+
generate_all_files(dump=False)
2020

2121

2222
# Run unit test.

Diff for: tests/test_utils.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"""
2020

2121
import logging
22+
import os
2223
import socket
2324
import sys
2425
import unittest
@@ -56,7 +57,7 @@ def test_simple_server_startup(self) -> None:
5657
def test_cleanup(self) -> None:
5758
# Test normal case
5859
server_process_handler = utils.TestServerProcess(
59-
log=logger, server="simple_server.py"
60+
log=logger, server=os.path.join(utils.TESTS_DIR, "simple_server.py")
6061
)
6162

6263
server_process_handler.clean()

Diff for: tox.ini

+4-16
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,13 @@ envlist = lint,docs,py
99
skipsdist = true
1010

1111
[testenv]
12-
# TODO: Consider refactoring the tests to not require the aggregation script
13-
# being invoked from the `tests` directory. This seems to be the convention and
14-
# would make use of other testing tools such as coverage/coveralls easier.
15-
changedir = tests
16-
1712
commands =
1813
python3 --version
19-
python3 -m coverage run aggregate_tests.py
20-
python3 -m coverage report --rcfile {toxinidir}/pyproject.toml -m --fail-under 97
14+
python3 -m coverage run -m unittest
15+
python3 -m coverage report -m --fail-under 97
2116

2217
deps =
2318
-r{toxinidir}/requirements/test.txt
24-
# Install TUF in editable mode, instead of tox default virtual environment
25-
# installation (see `skipsdist`), to get relative paths in coverage reports
26-
--editable {toxinidir}
2719

2820
install_command = python3 -m pip install {opts} {packages}
2921

@@ -37,14 +29,12 @@ commands_pre =
3729
python3 -m pip install --force-reinstall git+https://github.com/secure-systems-lab/securesystemslib.git@main#egg=securesystemslib[crypto]
3830

3931
commands =
40-
python3 -m coverage run aggregate_tests.py
41-
python3 -m coverage report --rcfile {toxinidir}/pyproject.toml -m
32+
python3 -m coverage run -m unittest
33+
python3 -m coverage report -m
4234

4335
[testenv:lint]
44-
changedir = {toxinidir}
4536
deps =
4637
-r{toxinidir}/requirements/lint.txt
47-
--editable {toxinidir}
4838
lint_dirs = tuf examples tests verify_release .github/scripts
4939
passenv = RUFF_OUTPUT_FORMAT
5040
commands =
@@ -54,7 +44,6 @@ commands =
5444
mypy {[testenv:lint]lint_dirs}
5545

5646
[testenv:fix]
57-
changedir = {toxinidir}
5847
deps = {[testenv:lint]deps}
5948
commands =
6049
ruff check --fix {[testenv:lint]lint_dirs}
@@ -64,6 +53,5 @@ commands =
6453
deps =
6554
-r{toxinidir}/requirements/docs.txt
6655

67-
changedir = {toxinidir}
6856
commands =
6957
sphinx-build -b html docs docs/build/html -W

0 commit comments

Comments
 (0)