Files
tracer-cloud--opensre/tests/scheduler/test_store.py
T
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

181 lines
5.7 KiB
Python

"""Tests for the JSON-backed task store."""
from __future__ import annotations
from pathlib import Path
import pytest
from platform.scheduler.claim_store import get_runs, try_claim
from platform.scheduler.store import (
add_task,
get_task,
list_tasks,
remove_task,
update_task,
)
from platform.scheduler.types import Provider, ScheduledTask, TaskKind
@pytest.fixture()
def store_path(tmp_path: Path) -> Path:
return tmp_path / "scheduler_tasks.json"
def _db_path(store_path: Path) -> Path:
return store_path.with_name("scheduler.db")
class TestStore:
def test_list_empty(self, store_path: Path) -> None:
tasks = list_tasks(store_path)
assert tasks == []
def test_add_and_list(self, store_path: Path) -> None:
task = ScheduledTask(
kind=TaskKind.DAILY_SUMMARY,
cron="0 9 * * 1-5",
provider=Provider.TELEGRAM,
chat_id="-100123",
)
added = add_task(task, store_path)
assert added.id == task.id
tasks = list_tasks(store_path)
assert len(tasks) == 1
assert tasks[0].id == task.id
assert tasks[0].kind == TaskKind.DAILY_SUMMARY
def test_get_task(self, store_path: Path) -> None:
task = ScheduledTask(
kind=TaskKind.WEEKLY_AUDIT,
cron="0 8 * * 1",
provider=Provider.SLACK,
chat_id="C123",
)
add_task(task, store_path)
found = get_task(task.id, store_path)
assert found is not None
assert found.kind == TaskKind.WEEKLY_AUDIT
def test_get_task_not_found(self, store_path: Path) -> None:
assert get_task("nonexistent", store_path) is None
def test_remove_task(self, store_path: Path) -> None:
task = ScheduledTask(
kind=TaskKind.DAILY_SUMMARY,
cron="0 9 * * *",
provider=Provider.TELEGRAM,
chat_id="-100",
)
add_task(task, store_path)
assert remove_task(task.id, store_path) is True
assert list_tasks(store_path) == []
def test_remove_task_cascade_deletes_runs(self, store_path: Path) -> None:
"""Removing a task must also remove its TaskRun records."""
task = ScheduledTask(
kind=TaskKind.DAILY_SUMMARY,
cron="0 9 * * *",
provider=Provider.TELEGRAM,
chat_id="-100",
)
add_task(task, store_path)
db_path = _db_path(store_path)
try_claim(task.id, "2026-01-01T09:00", db_path=db_path)
try_claim(task.id, "2026-01-01T10:00", db_path=db_path)
assert remove_task(task.id, store_path) is True
assert get_runs(task.id, db_path=db_path) == []
def test_remove_task_cascade_does_not_affect_other_tasks(self, store_path: Path) -> None:
"""Removing one task's runs must not delete another task's runs."""
task_a = ScheduledTask(
id="task-a",
kind=TaskKind.DAILY_SUMMARY,
cron="0 9 * * *",
provider=Provider.TELEGRAM,
chat_id="-100",
)
task_b = ScheduledTask(
id="task-b",
kind=TaskKind.WEEKLY_AUDIT,
cron="0 8 * * 1",
provider=Provider.SLACK,
chat_id="C123",
)
add_task(task_a, store_path)
add_task(task_b, store_path)
db_path = _db_path(store_path)
try_claim("task-a", "2026-01-01T09:00", db_path=db_path)
try_claim("task-b", "2026-01-01T09:00", db_path=db_path)
assert remove_task("task-a", store_path) is True
assert get_runs("task-a", db_path=db_path) == []
assert len(get_runs("task-b", db_path=db_path)) == 1
def test_remove_nonexistent(self, store_path: Path) -> None:
assert remove_task("nonexistent", store_path) is False
def test_update_task(self, store_path: Path) -> None:
task = ScheduledTask(
kind=TaskKind.DAILY_SUMMARY,
cron="0 9 * * *",
provider=Provider.TELEGRAM,
chat_id="-100",
)
add_task(task, store_path)
task.enabled = False
assert update_task(task, store_path) is True
updated = get_task(task.id, store_path)
assert updated is not None
assert updated.enabled is False
def test_update_nonexistent(self, store_path: Path) -> None:
task = ScheduledTask(
id="nonexistent",
kind=TaskKind.DAILY_SUMMARY,
cron="0 9 * * *",
provider=Provider.TELEGRAM,
)
assert update_task(task, store_path) is False
def test_multiple_tasks(self, store_path: Path) -> None:
for i in range(3):
task = ScheduledTask(
kind=TaskKind.DAILY_SUMMARY,
cron=f"{i} 9 * * *",
provider=Provider.TELEGRAM,
chat_id=f"-{i}",
)
add_task(task, store_path)
tasks = list_tasks(store_path)
assert len(tasks) == 3
def test_corrupted_store_returns_empty(self, store_path: Path) -> None:
store_path.parent.mkdir(parents=True, exist_ok=True)
store_path.write_text("not valid json", encoding="utf-8")
tasks = list_tasks(store_path)
assert tasks == []
def test_store_with_invalid_entries_skips_them(self, store_path: Path) -> None:
import json
store_path.parent.mkdir(parents=True, exist_ok=True)
data = [
{"id": "valid1", "kind": "daily_summary", "cron": "0 9 * * *", "provider": "telegram"},
{"invalid": "entry"},
]
store_path.write_text(json.dumps(data), encoding="utf-8")
tasks = list_tasks(store_path)
assert len(tasks) == 1
assert tasks[0].id == "valid1"