mirror of
https://github.com/domainaware/parsedmarc.git
synced 2026-07-16 05:24:56 +00:00
* Fix failure-report timestamp skew on non-UTC hosts in ES/OS/Splunk sinks arrival_date_utc is a UTC wall-clock string (generated in parse_failure_report via an aware-UTC strftime), but elastic.py, opensearch.py, and splunk.py parsed it back into a naive datetime and called .timestamp(), which per the Python docs interprets naive values as local time (https://docs.python.org/3/library/datetime.html#datetime.datetime.timestamp). On any non-UTC host the epoch stored as the ES/OpenSearch arrival_date field, used in the failure-report dedup match query, and sent as the Splunk HEC event time was therefore off by the host's UTC offset (verified -3600 s under TZ=Europe/Warsaw in January). Add an assume_utc keyword to human_timestamp_to_datetime() / human_timestamp_to_unix_timestamp() that attaches timezone.utc to naive parses, and use it at the three arrival_date_utc call sites. Aware inputs (explicit offsets) are unaffected; all other callers keep the existing local-time semantics, whose round-trip with timestamp_to_human is self-consistent on a single host (the broader local-time output question is tracked separately in issue #811 bug 2). The three new sink regression tests fail on the unfixed code (verified by stashing the source changes) and force TZ=Europe/Warsaw via time.tzset() so they catch the skew even on UTC CI runners. Fixes half of https://github.com/domainaware/parsedmarc/issues/811. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Deduplicate TZ-forcing test boilerplate; fix unix-timestamp docstring Extract the repeated TZ=Europe/Warsaw + time.tzset() setup/cleanup from the four timestamp regression tests into a shared tests/tzutil.py force_tz() helper, and correct human_timestamp_to_unix_timestamp()'s docstring, which said the return type was float while the function returns int. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: MISAPOR LAB <misapor@lab.misapor.pl> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Sean Whalen <44679+seanthegeek@users.noreply.github.com>
31 lines
920 B
Python
31 lines
920 B
Python
"""Shared timezone-forcing helper for timestamp regression tests."""
|
|
|
|
import os
|
|
import time
|
|
import unittest
|
|
|
|
|
|
def force_tz(testcase: unittest.TestCase, tz: str = "Europe/Warsaw") -> None:
|
|
"""Set the process timezone to *tz* for the duration of *testcase*.
|
|
|
|
Registers a cleanup that restores the previous ``TZ`` value.
|
|
Requires POSIX ``time.tzset()``; guard callers with
|
|
``@unittest.skipUnless(hasattr(time, "tzset"), ...)``.
|
|
|
|
The default zone is fixed and non-UTC (UTC+1 in January, UTC+2 in
|
|
summer), so code that wrongly interprets a UTC wall-clock string as
|
|
local time produces a shifted epoch under it.
|
|
"""
|
|
old_tz = os.environ.get("TZ")
|
|
os.environ["TZ"] = tz
|
|
time.tzset()
|
|
|
|
def restore() -> None:
|
|
if old_tz is None:
|
|
os.environ.pop("TZ", None)
|
|
else:
|
|
os.environ["TZ"] = old_tz
|
|
time.tzset()
|
|
|
|
testcase.addCleanup(restore)
|