From 3fcdf95ec1be02c469c1aeb6ccdc75bb6a2d1dce Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Tue, 28 Jul 2026 20:35:41 +0200 Subject: [PATCH] Make TLSRPT live fixture restart-safe --- contrib/testing/smtp-tlsrpt-delivery-check.py | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/contrib/testing/smtp-tlsrpt-delivery-check.py b/contrib/testing/smtp-tlsrpt-delivery-check.py index 8aad19c..3bf5854 100755 --- a/contrib/testing/smtp-tlsrpt-delivery-check.py +++ b/contrib/testing/smtp-tlsrpt-delivery-check.py @@ -379,6 +379,26 @@ def matching_delivery( return value +def discard_delivery(value: dict[str, object], reason: str) -> None: + delivery_id = int(value.get("id", 0)) + if delivery_id <= 0: + raise SMTP29Error("pending delivery omitted its Store identifier") + testtool("tlsrpt-finish", str(delivery_id), "2", "0", reason) + + +def purge_stale_fixture_deliveries() -> None: + """Remove leftovers from an interrupted SMTP-29 run only.""" + for _unused in range(256): + value = next_delivery(int(time.time()) + 172800) + if not value.get("present"): + return + domain = str(value.get("report_domain", "")) + if "smtp29-" not in domain: + return + discard_delivery(value, "stale SMTP-29 test fixture") + raise SMTP29Error("too many stale SMTP-29 deliveries") + + def expire_delivery(value: dict[str, object]) -> None: expires = int(value.get("expires_at", 0)) if expires <= 0: @@ -466,6 +486,7 @@ def perform_test() -> None: replace_configuration("worker", configured_worker) configuration_changed = True restart_bongo(internal_host, internal_port) + purge_stale_fixture_deliveries() now = int(time.time()) today = (now // 86400) * 86400 @@ -531,16 +552,22 @@ def perform_test() -> None: restart_bongo(internal_host, internal_port) record(event(yesterday, no_dkim_domain, no_dkim_policy)) prepare(today, int(time.time()), signing_domain) + pending_no_dkim = matching_delivery(no_dkim_domain) + if not pending_no_dkim: + raise SMTP29Error( + "prepared DKIM-required delivery is not pending: " + f"{next_delivery(int(time.time()) + 172800)!r}") + prepared.append(pending_no_dkim) request_worker() no_dkim = wait_until( lambda: matching_delivery(no_dkim_domain, minimum_attempts=1), "DKIM-required mail retry", ) - prepared.append(no_dkim) + prepared[-1] = no_dkim if captured_report(smtp_capture, no_dkim_domain) is not None: raise SMTP29Error( "TLSRPT mail was sent while DKIM was disabled") - expire_delivery(no_dkim) + discard_delivery(no_dkim, "completed DKIM-disabled SMTP-29 check") prepared.remove(no_dkim) replace_configuration("smtp", configured_smtp) restart_bongo(internal_host, internal_port) @@ -552,12 +579,18 @@ def perform_test() -> None: ) record(event(yesterday, retry_domain, retry_policy)) prepare(today, int(time.time()), signing_domain) + pending_retry = matching_delivery(retry_domain) + if not pending_retry: + raise SMTP29Error( + "prepared HTTPS retry delivery is not pending: " + f"{next_delivery(int(time.time()) + 172800)!r}") + prepared.append(pending_retry) request_worker() retry = wait_until( lambda: matching_delivery(retry_domain, minimum_attempts=1), "durable HTTPS retry", ) - prepared.append(retry) + prepared[-1] = retry retry_id = retry.get("report_id") retry_attempts = int(retry.get("attempts", -1)) restart_bongo(internal_host, internal_port) @@ -601,7 +634,7 @@ def perform_test() -> None: delayed = wait_until(delayed_delivery, "random initial delay") prepared.append(delayed) - expire_delivery(delayed) + discard_delivery(delayed, "completed SMTP-29 delay check") prepared.remove(delayed) print( @@ -620,7 +653,7 @@ def perform_test() -> None: finally: for value in prepared: try: - expire_delivery(value) + discard_delivery(value, "interrupted SMTP-29 test fixture") except Exception: pass if configuration_changed: