test: verify realtime snapshots are fresh

This commit is contained in:
lingniu
2026-07-02 08:43:27 +08:00
parent c211447747
commit 8def635bf5
4 changed files with 81 additions and 7 deletions

View File

@@ -15,6 +15,7 @@ from typing import Any
SHANGHAI = dt.timezone(dt.timedelta(hours=8))
DEFAULT_BASE_URL = "http://115.29.187.205:20210"
DEFAULT_REALTIME_MAX_AGE_MINUTES = 15.0
@dataclass(frozen=True)
@@ -192,9 +193,28 @@ def metric_formula_message(items: list[Any]) -> str:
return f"metric_formula mismatch value={metric_value:.3f} expected={expected:.3f}"
def check_realtime(name: str, payload: dict[str, Any]) -> Check:
def check_realtime(
name: str,
payload: dict[str, Any],
max_age_minutes: float | None = None,
now: dt.datetime | None = None,
) -> Check:
if payload.get("online") is False:
return Check(name, "fail", 0, 1, "online=false")
updated_message = ""
if max_age_minutes is not None:
updated_age = realtime_updated_age_minutes(payload, now)
if updated_age is None:
return Check(name, "fail", 0, 1, "missing updated_at_ms")
updated_message = f"updated_age_minutes={updated_age:.1f}"
if updated_age > max_age_minutes:
return Check(
name,
"fail",
0,
1,
updated_message + f"; expected <= {max_age_minutes:.1f}",
)
identifier = payload.get("vin") or payload.get("vehicle_key") or ""
protocols = payload.get("protocols") or []
protocol = payload.get("protocol") or ""
@@ -214,9 +234,23 @@ def check_realtime(name: str, payload: dict[str, Any]) -> Check:
ensure_ascii=False,
sort_keys=True,
)
if updated_message:
message = updated_message + "; " + message
return Check(name, "pass", 1, 1, message)
def realtime_updated_age_minutes(payload: dict[str, Any], now: dt.datetime | None = None) -> float | None:
try:
updated_ms = int(payload.get("updated_at_ms"))
except (TypeError, ValueError):
return None
current = now or dt.datetime.now(tz=dt.timezone.utc)
if current.tzinfo is None:
current = current.replace(tzinfo=dt.timezone.utc)
updated = dt.datetime.fromtimestamp(updated_ms / 1000, tz=dt.timezone.utc)
return max(0.0, (current.astimezone(dt.timezone.utc) - updated).total_seconds() / 60)
def sample_summary(items: list[Any]) -> str:
if not items:
return "{}"
@@ -372,9 +406,23 @@ def build_realtime_specs(payloads: dict[str, dict[str, Any]]) -> list[CheckSpec]
encoded = urllib.parse.quote(identifier, safe="")
base_path = "/api/realtime/vehicles/" + encoded
specs.extend([
CheckSpec(prefix + ".realtime", base_path, {}, 1, "realtime"),
CheckSpec(
prefix + ".realtime",
base_path,
{},
1,
"realtime",
max_age_minutes=DEFAULT_REALTIME_MAX_AGE_MINUTES,
),
CheckSpec(prefix + ".realtime_online", base_path + "/online", {}, 1, "realtime"),
CheckSpec(prefix + ".realtime_protocol", base_path + "/protocols/" + protocol, {}, 1, "realtime"),
CheckSpec(
prefix + ".realtime_protocol",
base_path + "/protocols/" + protocol,
{},
1,
"realtime",
max_age_minutes=DEFAULT_REALTIME_MAX_AGE_MINUTES,
),
])
return specs
@@ -385,7 +433,7 @@ def run_checks(base_url: str, specs: list[CheckSpec], timeout: float) -> list[Ch
try:
payload = query_json(base_url, spec.path, spec.params, timeout)
if spec.kind == "realtime":
checks.append(check_realtime(spec.name, payload))
checks.append(check_realtime(spec.name, payload, spec.max_age_minutes))
else:
checks.append(check_total(
spec.name,

View File

@@ -140,6 +140,32 @@ class GoNativeProdSmokeTest(unittest.TestCase):
self.assertEqual(check.status, "fail")
self.assertIn("online=false", check.message)
def test_realtime_check_fails_when_snapshot_is_stale(self):
now = dt.datetime(2026, 7, 2, 0, 30, 0, tzinfo=dt.timezone.utc)
check = smoke.check_realtime(
"jt808.realtime",
{"vehicle_key": "JT808:013307811170", "updated_at_ms": 1782950400000},
max_age_minutes=15,
now=now,
)
self.assertEqual(check.status, "fail")
self.assertIn("updated_age_minutes=30.0", check.message)
def test_realtime_check_passes_when_snapshot_is_fresh(self):
now = dt.datetime(2026, 7, 2, 0, 30, 0, tzinfo=dt.timezone.utc)
check = smoke.check_realtime(
"jt808.realtime",
{"vehicle_key": "JT808:013307811170", "updated_at_ms": 1782951600000},
max_age_minutes=15,
now=now,
)
self.assertEqual(check.status, "pass")
self.assertIn("updated_age_minutes=10.0", check.message)
def test_parse_tdengine_utc_timestamp_as_aware_utc(self):
parsed = smoke.parse_tdengine_utc_timestamp("2026-07-01 17:36:02")