Remediate the 2026-09-03 feature-test findings
This commit is contained in:
@@ -272,3 +272,66 @@ def test_fleet_list_route_resolves_without_trailing_slash():
|
||||
endpoint_slash, _ = adapter.match('/api/endpoints/', method='GET')
|
||||
assert endpoint_slash.endswith('list_endpoints')
|
||||
|
||||
|
||||
|
||||
# --- agent timestamps are UTC on the wire and UTC in the column --------------
|
||||
#
|
||||
# _parse_dt used astimezone(tz=None), which converts to the SERVER's local
|
||||
# zone. An agent reporting 17:26:16Z was stored as 13:26:16 on an EDT server
|
||||
# and re-served labelled 'Z', while the same row's server-written
|
||||
# lastreportedat stayed true UTC - one row, two time bases, four hours apart.
|
||||
# The dashboard's 48-hour stability window compares a real UTC cutoff against
|
||||
# these values, so events left it four hours early.
|
||||
#
|
||||
# It is invisible on a UTC server, which is how it survived, and nothing in the
|
||||
# Dockerfile, the compose files or the Windows deploy pins TZ.
|
||||
|
||||
def _in_zone(zonename, call):
|
||||
"""Run call() with the process in a named zone, then put it back."""
|
||||
import os
|
||||
import time
|
||||
|
||||
before = os.environ.get('TZ')
|
||||
os.environ['TZ'] = zonename
|
||||
time.tzset()
|
||||
try:
|
||||
return call()
|
||||
finally:
|
||||
if before is None:
|
||||
os.environ.pop('TZ', None)
|
||||
else:
|
||||
os.environ['TZ'] = before
|
||||
time.tzset()
|
||||
|
||||
|
||||
def test_a_utc_timestamp_survives_a_non_utc_server():
|
||||
from datetime import datetime
|
||||
|
||||
from plugins.endpoints.plugin import _parse_dt
|
||||
|
||||
parsed = _in_zone('America/New_York',
|
||||
lambda: _parse_dt('2026-09-03T17:26:16Z'))
|
||||
assert parsed == datetime(2026, 9, 3, 17, 26, 16), \
|
||||
'the wire value is UTC and the column is UTC; no local conversion'
|
||||
|
||||
|
||||
def test_an_offset_timestamp_is_converted_to_utc_not_to_server_local():
|
||||
from datetime import datetime
|
||||
|
||||
from plugins.endpoints.plugin import _parse_dt
|
||||
|
||||
parsed = _in_zone('America/New_York',
|
||||
lambda: _parse_dt('2026-09-03T17:26:16+05:00'))
|
||||
assert parsed == datetime(2026, 9, 3, 12, 26, 16)
|
||||
|
||||
|
||||
def test_a_naive_timestamp_is_taken_as_utc_already():
|
||||
"""AGENT-CONTRACT.md mandates UTC on the wire, so a value with no offset is
|
||||
UTC rather than a guess about the agent's zone."""
|
||||
from datetime import datetime
|
||||
|
||||
from plugins.endpoints.plugin import _parse_dt
|
||||
|
||||
parsed = _in_zone('Asia/Tokyo',
|
||||
lambda: _parse_dt('2026-09-03T17:26:16'))
|
||||
assert parsed == datetime(2026, 9, 3, 17, 26, 16)
|
||||
|
||||
Reference in New Issue
Block a user