You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
orquestrador/tests/test_runtime_bootstrap.py

147 lines
5.5 KiB
Python

import json
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory
from unittest.mock import AsyncMock, patch
from app import main as main_module
from app.core.settings import Settings
from app.db import bootstrap as bootstrap_module
from app.db import init_db as init_db_module
class SettingsParsingTests(unittest.TestCase):
def test_debug_accepts_release_alias(self):
settings = Settings(
google_project_id="test-project",
debug="release",
)
self.assertFalse(settings.debug)
def test_normalizes_environment_and_backend_values(self):
settings = Settings(
google_project_id="test-project",
environment=" Production ",
conversation_state_backend=" Redis ",
)
self.assertEqual(settings.environment, "production")
self.assertEqual(settings.conversation_state_backend, "redis")
class BootstrapRuntimeTests(unittest.TestCase):
@patch.object(bootstrap_module, "seed_tools")
@patch.object(bootstrap_module, "seed_mock_data")
@patch.object(bootstrap_module, "_ensure_mock_schema_evolution")
@patch.object(bootstrap_module.MockBase.metadata, "create_all")
@patch.object(bootstrap_module.Base.metadata, "create_all")
@patch.object(bootstrap_module, "_ensure_generated_tools_runtime_package")
def test_bootstrap_databases_ensures_generated_tools_package(
self,
ensure_generated_tools_runtime_package,
tools_create_all,
mock_create_all,
ensure_mock_schema_evolution,
seed_mock_data,
seed_tools,
):
ensure_generated_tools_runtime_package.return_value = Path("generated_tools")
bootstrap_module.bootstrap_databases()
ensure_generated_tools_runtime_package.assert_called_once_with()
tools_create_all.assert_called_once()
mock_create_all.assert_called_once()
def test_ensure_generated_tools_runtime_package_creates_package_files(self):
import shutil
sandbox_root = Path.cwd() / ".tmp_test_runtime_bootstrap"
shutil.rmtree(sandbox_root, ignore_errors=True)
sandbox_root.mkdir(parents=True, exist_ok=True)
try:
with patch.object(bootstrap_module, "_PROJECT_ROOT", sandbox_root):
package_dir = bootstrap_module._ensure_generated_tools_runtime_package()
self.assertEqual(package_dir.name, "generated_tools")
self.assertTrue(package_dir.exists())
self.assertTrue((package_dir / "__init__.py").exists())
manifest_path = package_dir / "published_runtime_tools.json"
self.assertTrue(manifest_path.exists())
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
self.assertEqual(manifest["target_service"], "product")
self.assertEqual(manifest["publications"], [])
finally:
shutil.rmtree(sandbox_root, ignore_errors=True)
@patch.object(bootstrap_module, "seed_tools")
@patch.object(bootstrap_module, "seed_mock_data")
@patch.object(bootstrap_module, "_ensure_mock_schema_evolution")
@patch.object(bootstrap_module.MockBase.metadata, "create_all")
@patch.object(bootstrap_module.Base.metadata, "create_all")
def test_bootstrap_databases_respects_seed_flags(
self,
tools_create_all,
mock_create_all,
ensure_mock_schema_evolution,
seed_mock_data,
seed_tools,
):
with patch.object(bootstrap_module.settings, "auto_seed_tools", False), patch.object(
bootstrap_module.settings,
"auto_seed_mock",
False,
), patch.object(bootstrap_module.settings, "mock_seed_enabled", True):
bootstrap_module.bootstrap_databases()
tools_create_all.assert_called_once()
mock_create_all.assert_called_once()
seed_tools.assert_not_called()
seed_mock_data.assert_not_called()
@patch.object(bootstrap_module, "seed_tools")
@patch.object(bootstrap_module, "seed_mock_data")
@patch.object(bootstrap_module, "_ensure_mock_schema_evolution")
@patch.object(bootstrap_module.MockBase.metadata, "create_all")
@patch.object(bootstrap_module.Base.metadata, "create_all", side_effect=RuntimeError("tools db down"))
def test_bootstrap_databases_raises_when_any_backend_fails(
self,
tools_create_all,
mock_create_all,
ensure_mock_schema_evolution,
seed_mock_data,
seed_tools,
):
with self.assertRaisesRegex(RuntimeError, "tools=tools db down"):
bootstrap_module.bootstrap_databases()
tools_create_all.assert_called_once()
mock_create_all.assert_called_once()
seed_mock_data.assert_called_once()
seed_tools.assert_not_called()
@patch.object(init_db_module, "bootstrap_databases")
def test_init_db_wrapper_delegates_to_bootstrap_databases(self, bootstrap_databases):
init_db_module.init_db()
bootstrap_databases.assert_called_once_with()
class HttpStartupTests(unittest.IsolatedAsyncioTestCase):
async def test_startup_event_warms_llm_without_running_bootstrap(self):
with patch("app.main.LLMService") as llm_cls, patch(
"app.db.bootstrap.bootstrap_databases"
) as bootstrap_databases:
llm_cls.return_value.warmup = AsyncMock()
await main_module.startup_event()
llm_cls.return_value.warmup.assert_awaited_once()
bootstrap_databases.assert_not_called()
if __name__ == "__main__":
unittest.main()