import datetime import json from unittest import mock import freezegun import pytest from tadas.monitoring import sensors as monitoring @pytest.mark.parametrize( 'report_date, threshold_days, threshold_hours, now, expected', [ pytest.param( '2025-12-25', 1, 2, '2025-12-26T01:50:12Z', monitoring.CheckResult( state='HEALTHY', message='{"now": "2025-12-26T01:50:12+00:00", "latest_data": ' '"2025-12-25T00:00:00+00:00", "delta": "1 day, 1:50:12", ' '"threshold": "1 day, 2:00:00"}' ), id='fresh' ), pytest.param( '2025-12-25', 1, 2, '2025-12-26T08:50:12+07:00', monitoring.CheckResult( state='HEALTHY', message='{"now": "2025-12-26T01:50:12+00:00", "latest_data": ' '"2025-12-25T00:00:00+00:00", "delta": "1 day, 1:50:12", ' '"threshold": "1 day, 2:00:00"}' ), id='fresh - same time in other TZ - message still in UTC' ), pytest.param( '2025-12-25', 1, 2, '2025-12-26T02:05:12Z', monitoring.CheckResult( state='UNHEALTHY', message='{"now": "2025-12-26T02:05:12+00:00", "latest_data": ' '"2025-12-25T00:00:00+00:00", "delta": "1 day, 2:05:12", ' '"threshold": "1 day, 2:00:00"}' ), id='not fresh' ), pytest.param( '2025-12-25', 1, 2, '2025-12-26T09:05:12+07:00', monitoring.CheckResult( state='UNHEALTHY', message='{"now": "2025-12-26T02:05:12+00:00", "latest_data": ' '"2025-12-25T00:00:00+00:00", "delta": "1 day, 2:05:12", ' '"threshold": "1 day, 2:00:00"}' ), id='not fresh - same time in other TZ ' ), pytest.param( '2025-12-25', 1, 2, '2025-12-28T02:05:12Z', monitoring.CheckResult( state='UNHEALTHY', message='{"now": "2025-12-28T02:05:12+00:00", "latest_data": ' '"2025-12-25T00:00:00+00:00", "delta": "3 days, 2:05:12", ' '"threshold": "1 day, 2:00:00"}' ), id='way too unfresh' ), ] ) def test_freshness(report_date, threshold_days, threshold_hours, now, expected): threshold = datetime.timedelta(days=threshold_days, hours=threshold_hours) report_datetime = datetime.datetime.fromisoformat(f'{report_date}T00:00:00Z') sensor = monitoring.FreshnessSensor(threshold=threshold, name='freshness') with freezegun.freeze_time(now): assert sensor.check(report_date=report_datetime) == expected @pytest.mark.parametrize( 'report_date, threshold_delta, now, expected_freshness, expected_delta', [ pytest.param( '2025-12-25', datetime.timedelta(days=1, hours=2), '2025-12-25T00:30:00Z', 1.06, datetime.timedelta(days=1, hours=1, minutes=30), id='quite fresh' ), pytest.param( '2025-12-25', datetime.timedelta(days=1, hours=2), '2025-12-26T01:50:12Z', 0.01, datetime.timedelta(seconds=588), id='still fresh' ), pytest.param( '2025-12-25', datetime.timedelta(days=1, hours=2), '2025-12-26T02:15:00Z', -0.01, datetime.timedelta(seconds=-900), id='just expired' ), pytest.param( '2025-12-25', datetime.timedelta(days=1, hours=2), '2025-12-30T02:00:00Z', -4.0, datetime.timedelta(days=-4), id='expired 4 days ago' ), ] ) def test_freshness(capsys, report_date, threshold_delta, now, expected_freshness, expected_delta): report_datetime = datetime.date.fromisoformat(report_date) sensor = monitoring.FreshnessSensor(threshold=threshold_delta, name='tadas') context_value = {'context_k1': 'v1', 'a_the_latest_key': 'v'} with freezegun.freeze_time(now), \ mock.patch.object(monitoring.contexts, 'load_context', return_value=context_value): sensor.check(report_date=report_datetime) captured = capsys.readouterr() parsed_metrics = json.loads(captured.out) expected_parsed_metrics = { 'a_the_latest_key': 'v', 'delta_seconds': expected_delta.total_seconds(), 'context_k1': 'v1', 'object': 'tadas', 'freshness_days': expected_freshness, 'latest_report_date': report_date, 'metrics_category': 'freshness_sensor', 'now': now.replace('Z', '+00:00'), 'threshold_seconds': 93600.0, } assert parsed_metrics == expected_parsed_metrics