from __future__ import annotations import sys import tempfile import textwrap import unittest from pathlib import Path from backend import server_runtime class _FakeLogger: def __init__(self) -> None: self.warnings: list[tuple[str, tuple[object, ...]]] = [] def warning(self, msg: str, *args: object, **kwargs: object) -> None: self.warnings.append((msg, args)) class ServerRuntimeTests(unittest.TestCase): def test_bootstrap_runtime_port_sets_huggingface_default(self) -> None: env = {"SPACE_ID": "demo-space"} server_runtime.bootstrap_runtime_port(env, huggingface_port=7860) self.assertEqual(env["PORT"], "7860") def test_bootstrap_runtime_port_keeps_existing_port(self) -> None: env = {"SPACE_HOST": "space.example", "PORT": "9000"} server_runtime.bootstrap_runtime_port(env, huggingface_port=7860) self.assertEqual(env["PORT"], "9000") def test_resolve_server_port_keeps_configured_port_when_available(self) -> None: env = {"PORT": "8000"} port = server_runtime.resolve_server_port( "127.0.0.1", env=env, port_checker=lambda host, value: host == "127.0.0.1" and value == 8000, free_port_finder=lambda host: 8123, ) self.assertEqual(port, 8000) self.assertEqual(env["PORT"], "8000") def test_resolve_server_port_falls_back_when_configured_port_is_busy(self) -> None: env = {"PORT": "8000"} logger = _FakeLogger() port = server_runtime.resolve_server_port( "127.0.0.1", env=env, logger=logger, port_checker=lambda host, value: False, free_port_finder=lambda host: 8123, ) self.assertEqual(port, 8123) self.assertEqual(env["PORT"], "8123") self.assertEqual(len(logger.warnings), 1) def test_resolve_server_port_uses_huggingface_default_when_missing(self) -> None: env = {"SPACE_ID": "demo-space"} port = server_runtime.resolve_server_port( "0.0.0.0", env=env, port_checker=lambda host, value: False, free_port_finder=lambda host: 8123, ) self.assertEqual(port, 7860) self.assertEqual(env["PORT"], "7860") def test_load_runtime_env_returns_false_for_missing_file(self) -> None: with tempfile.TemporaryDirectory() as temp_dir: env_file = Path(temp_dir) / "missing-aiforecast.env" self.assertFalse(server_runtime.load_runtime_env(env_file)) def test_load_fastapi_app_imports_requested_module_attribute(self) -> None: with tempfile.TemporaryDirectory() as temp_dir: project_root = Path(temp_dir) module_name = "temp_runtime_app_module" module_path = project_root / f"{module_name}.py" module_path.write_text( textwrap.dedent( """ app = {"name": "demo-app"} """ ).strip(), encoding="utf-8", ) try: app = server_runtime.load_fastapi_app( project_root, module_name=module_name, attr_name="app", ) self.assertEqual(app, {"name": "demo-app"}) self.assertIn(str(project_root), sys.path) finally: sys.modules.pop(module_name, None) if __name__ == "__main__": unittest.main()