172 lines
6.2 KiB
Python
172 lines
6.2 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import sqlite3
|
|
import tempfile
|
|
import unittest
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
from contextlib import closing
|
|
from unittest.mock import patch
|
|
|
|
from app.rcon_admin_log_materialization import (
|
|
MATCH_RESULT_SOURCE,
|
|
initialize_rcon_materialized_storage,
|
|
)
|
|
from app.rcon_historical_backfill import (
|
|
count_recent_materialized_closed_matches,
|
|
run_rcon_historical_backfill,
|
|
select_backfill_targets,
|
|
)
|
|
from app.rcon_historical_leaderboards import list_rcon_materialized_leaderboard
|
|
|
|
|
|
TARGETS_JSON = json.dumps(
|
|
[
|
|
{
|
|
"name": "Comunidad Hispana #01",
|
|
"slug": "comunidad-hispana-01",
|
|
"external_server_id": "comunidad-hispana-01",
|
|
"host": "127.0.0.1",
|
|
"port": 7779,
|
|
"password": "secret",
|
|
},
|
|
{
|
|
"name": "Comunidad Hispana #02",
|
|
"slug": "comunidad-hispana-02",
|
|
"external_server_id": "comunidad-hispana-02",
|
|
"host": "127.0.0.1",
|
|
"port": 7879,
|
|
"password": "secret",
|
|
},
|
|
{
|
|
"name": "Comunidad Hispana #03",
|
|
"slug": "comunidad-hispana-03",
|
|
"external_server_id": "comunidad-hispana-03",
|
|
"host": "127.0.0.1",
|
|
"port": 7979,
|
|
"password": "secret",
|
|
},
|
|
]
|
|
)
|
|
|
|
|
|
class RconHistoricalBackfillTests(unittest.TestCase):
|
|
def test_monthly_window_selects_previous_month_on_days_1_to_7(self) -> None:
|
|
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmpdir:
|
|
payload = list_rcon_materialized_leaderboard(
|
|
server_key="all-servers",
|
|
timeframe="monthly",
|
|
metric="kills",
|
|
db_path=Path(tmpdir) / "historical.sqlite3",
|
|
now=datetime(2026, 5, 7, 12, tzinfo=timezone.utc),
|
|
)
|
|
|
|
self.assertEqual(payload["window_kind"], "previous-month")
|
|
self.assertEqual(payload["selected_month_start"], "2026-04-01T00:00:00Z")
|
|
self.assertEqual(payload["selected_month_end"], "2026-05-01T00:00:00Z")
|
|
|
|
def test_monthly_window_selects_current_month_on_day_8_plus(self) -> None:
|
|
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmpdir:
|
|
payload = list_rcon_materialized_leaderboard(
|
|
server_key="all-servers",
|
|
timeframe="monthly",
|
|
metric="kills",
|
|
db_path=Path(tmpdir) / "historical.sqlite3",
|
|
now=datetime(2026, 5, 8, 12, tzinfo=timezone.utc),
|
|
)
|
|
|
|
self.assertEqual(payload["window_kind"], "current-month")
|
|
self.assertEqual(payload["selected_month_start"], "2026-05-01T00:00:00Z")
|
|
|
|
def test_recent_match_ensure_stops_when_count_is_already_satisfied(self) -> None:
|
|
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmpdir, _patched_targets():
|
|
db_path = Path(tmpdir) / "historical.sqlite3"
|
|
_insert_closed_matches(db_path, 100)
|
|
|
|
payload = run_rcon_historical_backfill(
|
|
servers="comunidad-hispana-01,comunidad-hispana-02",
|
|
ensure_recent_matches=100,
|
|
dry_run=True,
|
|
db_path=db_path,
|
|
)
|
|
|
|
self.assertEqual(payload["recent_materialized_closed_match_count_before"], 100)
|
|
self.assertEqual(payload["actual_windows_scanned"], [])
|
|
|
|
def test_unknown_server_is_rejected(self) -> None:
|
|
with _patched_targets():
|
|
with self.assertRaises(ValueError):
|
|
select_backfill_targets("unknown-server")
|
|
|
|
def test_comunidad_hispana_03_is_not_included_by_default(self) -> None:
|
|
with _patched_targets():
|
|
selected = select_backfill_targets(None)
|
|
|
|
self.assertEqual(
|
|
[target.external_server_id for target in selected],
|
|
["comunidad-hispana-01", "comunidad-hispana-02"],
|
|
)
|
|
|
|
def test_dry_run_does_not_insert_data(self) -> None:
|
|
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmpdir, _patched_targets():
|
|
db_path = Path(tmpdir) / "historical.sqlite3"
|
|
payload = run_rcon_historical_backfill(
|
|
servers="comunidad-hispana-01",
|
|
ensure_current_month=True,
|
|
dry_run=True,
|
|
db_path=db_path,
|
|
)
|
|
|
|
count_after = count_recent_materialized_closed_matches(db_path=db_path)
|
|
|
|
self.assertEqual(payload["status"], "dry-run")
|
|
self.assertEqual(payload["events_inserted"], 0)
|
|
self.assertEqual(count_after, 0)
|
|
|
|
def test_backfill_output_is_json_serializable(self) -> None:
|
|
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmpdir, _patched_targets():
|
|
payload = run_rcon_historical_backfill(
|
|
servers="comunidad-hispana-01",
|
|
ensure_current_month=True,
|
|
dry_run=True,
|
|
db_path=Path(tmpdir) / "historical.sqlite3",
|
|
)
|
|
|
|
json.dumps(payload, ensure_ascii=True)
|
|
|
|
|
|
def _insert_closed_matches(db_path: Path, count: int) -> None:
|
|
initialize_rcon_materialized_storage(db_path=db_path)
|
|
with closing(sqlite3.connect(db_path)) as connection:
|
|
for index in range(count):
|
|
connection.execute(
|
|
"""
|
|
INSERT INTO rcon_materialized_matches (
|
|
target_key, external_server_id, match_key, map_name, map_pretty_name,
|
|
started_at, ended_at, confidence_mode, source_basis
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
""",
|
|
(
|
|
"comunidad-hispana-01",
|
|
"comunidad-hispana-01",
|
|
f"match-{index}",
|
|
"stmariedumont",
|
|
"ST MARIE DU MONT",
|
|
"2026-05-01T10:00:00Z",
|
|
f"2026-05-{(index % 28) + 1:02d}T12:00:00Z",
|
|
"exact",
|
|
MATCH_RESULT_SOURCE,
|
|
),
|
|
)
|
|
connection.commit()
|
|
|
|
|
|
def _patched_targets():
|
|
return patch.dict(os.environ, {"HLL_BACKEND_RCON_TARGETS": TARGETS_JSON})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|