From 33c4b05756d13374fcd3346a588e74bf716b8411 Mon Sep 17 00:00:00 2001 From: Cyber MacGeddon Date: Tue, 14 Apr 2026 10:39:16 +0100 Subject: [PATCH] Fix test suite Prometheus registry pollution and remove default coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test_metrics.py fixture (added in 4e63dbda) deleted class-level metric singleton attributes without restoring them. This stripped the hasattr() guards that prevent duplicate Prometheus registration, so every subsequent Processor construction in the test run raised ValueError: Duplicated timeseries. Fix by saving and restoring the original attributes around each test. Remove --cov=trustgraph from pytest.ini defaults — the coverage import hooks interact badly with the trustgraph namespace package, causing duplicate class loading. Coverage can still be requested explicitly via the command line. Also fix missing newline at end of test_subscriber_graceful_shutdown.py. --- tests/pytest.ini | 5 +---- tests/unit/test_base/test_metrics.py | 14 ++++++++++++++ .../test_base/test_subscriber_graceful_shutdown.py | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/tests/pytest.ini b/tests/pytest.ini index b032a9d4..8541bd8f 100644 --- a/tests/pytest.ini +++ b/tests/pytest.ini @@ -4,14 +4,11 @@ python_paths = . python_files = test_*.py python_classes = Test* python_functions = test_* -addopts = +addopts = -v --tb=short --strict-markers --disable-warnings - --cov=trustgraph - --cov-report=html - --cov-report=term-missing # --cov-fail-under=80 asyncio_mode = auto markers = diff --git a/tests/unit/test_base/test_metrics.py b/tests/unit/test_base/test_metrics.py index b5a792a1..0496db20 100644 --- a/tests/unit/test_base/test_metrics.py +++ b/tests/unit/test_base/test_metrics.py @@ -7,6 +7,14 @@ from trustgraph.base import metrics @pytest.fixture(autouse=True) def reset_metric_singletons(): + """Temporarily remove metric singletons so each test can inject mocks. + + Saves any existing class-level metrics and restores them after the test + so that later tests in the same process still find the hasattr() guard + intact — deleting without restoring causes every subsequent Processor() + construction to re-register the same Prometheus metric name, which raises + ValueError: Duplicated timeseries. + """ classes_and_attrs = { metrics.ConsumerMetrics: [ "state_metric", @@ -23,18 +31,24 @@ def reset_metric_singletons(): ], } + saved = {} for cls, attrs in classes_and_attrs.items(): for attr in attrs: if hasattr(cls, attr): + saved[(cls, attr)] = getattr(cls, attr) delattr(cls, attr) yield + # Remove anything the test may have set, then restore originals for cls, attrs in classes_and_attrs.items(): for attr in attrs: if hasattr(cls, attr): delattr(cls, attr) + for (cls, attr), value in saved.items(): + setattr(cls, attr, value) + def test_consumer_metrics_reuses_singletons_and_records_events(monkeypatch): enum_factory = MagicMock() diff --git a/tests/unit/test_base/test_subscriber_graceful_shutdown.py b/tests/unit/test_base/test_subscriber_graceful_shutdown.py index 1a59f970..cbd4d535 100644 --- a/tests/unit/test_base/test_subscriber_graceful_shutdown.py +++ b/tests/unit/test_base/test_subscriber_graceful_shutdown.py @@ -412,4 +412,4 @@ async def test_subscriber_multiple_subscribers(): msg1 = await queue1.get() msg_all = await queue_all.get() assert msg1 == {"data": "broadcast"} - assert msg_all == {"data": "broadcast"} \ No newline at end of file + assert msg_all == {"data": "broadcast"}