"""Tests for Baota bootstrap background scheduling.""" from datetime import datetime, timedelta, timezone from unittest.mock import AsyncMock, patch import pytest from server.application.services.btpanel_bootstrap_schedule import ( bootstrap_batch_size, is_auto_bootstrap_enabled, run_bootstrap_tick, ) from server.domain.models import Server @pytest.mark.parametrize("value,expected", [ ("true", True), ("false", False), ("0", False), ]) def test_is_auto_bootstrap_enabled(value, expected, monkeypatch): monkeypatch.setattr( "server.application.services.btpanel_bootstrap_schedule.settings.BT_PANEL_AUTO_BOOTSTRAP_ENABLED", value, ) assert is_auto_bootstrap_enabled() is expected def test_bootstrap_batch_size_clamped(monkeypatch): monkeypatch.setattr( "server.application.services.btpanel_bootstrap_schedule.settings.BT_PANEL_BOOTSTRAP_BATCH", 999, ) assert bootstrap_batch_size() == 100 @pytest.mark.asyncio async def test_run_bootstrap_tick_disabled(monkeypatch): monkeypatch.setattr( "server.application.services.btpanel_bootstrap_schedule.is_auto_bootstrap_enabled", lambda: False, ) assert await run_bootstrap_tick() == 0 @pytest.mark.asyncio async def test_run_bootstrap_tick_processes_due_servers(monkeypatch): past = (datetime.now(timezone.utc) - timedelta(minutes=1)).isoformat().replace("+00:00", "Z") servers = [ Server( id=1, name="a", domain="1.1.1.1", extra_attrs={"bt_panel": { "bootstrap_state": "pending", "bootstrap_next_attempt_at": past, "auto_bootstrap": True, }}, ), ] class _Repo: async def get_all(self): return servers class _Session: async def __aenter__(self): return self async def __aexit__(self, *args): return False monkeypatch.setattr( "server.application.services.btpanel_bootstrap_schedule.is_auto_bootstrap_enabled", lambda: True, ) monkeypatch.setattr( "server.application.services.btpanel_bootstrap_schedule.AsyncSessionLocal", lambda: _Session(), ) monkeypatch.setattr( "server.application.services.btpanel_bootstrap_schedule.ServerRepositoryImpl", lambda _db: _Repo(), ) bootstrap_mock = AsyncMock(return_value={"ok": True}) with patch("server.application.services.btpanel_service.BtPanelService") as mock_cls: mock_cls.return_value.bootstrap_server = bootstrap_mock count = await run_bootstrap_tick() assert count == 1