conftest.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. from __future__ import annotations
  2. import sys
  3. from dataclasses import dataclass
  4. from pathlib import Path
  5. from typing import Any
  6. REPO_ROOT = Path(__file__).resolve().parents[1]
  7. @dataclass(frozen=True)
  8. class ServiceImportConfig:
  9. service_name: str
  10. libs: tuple[str, ...]
  11. SERVICE_IMPORT_CONFIGS: dict[str, ServiceImportConfig] = {
  12. "agent-service": ServiceImportConfig(
  13. service_name="agent-service",
  14. libs=("core-domain", "core-shared", "core-db", "core-events")),
  15. "auth-service": ServiceImportConfig(
  16. service_name="auth-service",
  17. libs=("core-domain", "core-shared", "core-db")),
  18. "knowledge-service": ServiceImportConfig(
  19. service_name="knowledge-service",
  20. libs=("core-domain", "core-shared", "core-db")),
  21. "model-gateway-service": ServiceImportConfig(
  22. service_name="model-gateway-service",
  23. libs=("core-domain", "core-shared", "core-db")),
  24. "runtime-service": ServiceImportConfig(
  25. service_name="runtime-service",
  26. libs=("core-domain", "core-shared", "core-db", "core-events", "core-dsl")),
  27. "tool-service": ServiceImportConfig(
  28. service_name="tool-service",
  29. libs=("core-domain", "core-shared", "core-db")),
  30. "team-service": ServiceImportConfig(
  31. service_name="team-service",
  32. libs=("core-domain", "core-shared", "core-db", "core-events")),
  33. "workflow-service": ServiceImportConfig(
  34. service_name="workflow-service",
  35. libs=("core-domain", "core-shared", "core-db", "core-dsl")),
  36. }
  37. def prepare_service_import(
  38. service_name: str,
  39. *,
  40. libs: tuple[str, ...]) -> None:
  41. for module_name in list(sys.modules):
  42. if module_name == "app" or module_name.startswith("app."):
  43. del sys.modules[module_name]
  44. _clear_shared_sqlalchemy_metadata()
  45. for lib_name in libs:
  46. lib_path = REPO_ROOT / "libs" / lib_name / "src"
  47. _prepend_sys_path(lib_path)
  48. _prepend_sys_path(REPO_ROOT / "services" / service_name)
  49. def prepare_known_service_import(service_name: str) -> None:
  50. config = SERVICE_IMPORT_CONFIGS[service_name]
  51. prepare_service_import(config.service_name, libs=config.libs)
  52. def build_sqlite_database_url(tmp_path: Path, filename: str) -> str:
  53. return f"sqlite:///{tmp_path / filename}"
  54. def _prepend_sys_path(path: Path) -> None:
  55. path_text = str(path)
  56. if path_text in sys.path:
  57. sys.path.remove(path_text)
  58. sys.path.insert(0, path_text)
  59. def _clear_shared_sqlalchemy_metadata() -> None:
  60. try:
  61. from core_db import Base
  62. except ImportError:
  63. return
  64. Base.registry.dispose()
  65. Base.metadata.clear()
  66. def build_fastapi_test_client(app: Any) -> Any:
  67. _patch_httpx_testclient_compatibility()
  68. from fastapi.testclient import TestClient
  69. return TestClient(app)
  70. def _patch_httpx_testclient_compatibility() -> None:
  71. import inspect
  72. import httpx
  73. if "app" in inspect.signature(httpx.Client.__init__).parameters:
  74. return
  75. if getattr(httpx.Client.__init__, "_agent_platform_patched", False):
  76. return
  77. original_init = httpx.Client.__init__
  78. def patched_init(self: httpx.Client, *args: Any, **kwargs: Any) -> None:
  79. kwargs.pop("app", None)
  80. original_init(self, *args, **kwargs)
  81. patched_init._agent_platform_patched = True
  82. httpx.Client.__init__ = patched_init