Warnings fixed: - datetime.utcnow() → datetime.now(UTC) across 48+ files (src/ + tests/) - datetime.utcnow (callback ref) → lambda: datetime.now(UTC) in model fields (18 files) - Pydantic class Config → model_config = ConfigDict(...) (16 files) - Pydantic .dict() → .model_dump() (8 files) - ConfigDict(allow_population_by_field_name=True) → validate_by_name=True - SQLAlchemy declarative_base() import path updated - FastAPI on_event → lifespan context manager (app.py) - Import sorting (ruff I001) auto-fixed across all files - Fixed broken re-export chains that ruff F401 cleanup broke: _validate_bcp47: service.py now imports from dictionary_validation directly job_to_response: _job_routes.py and test imports from service_utils directly fetch_datasource_metadata: restored re-export in service.py - Added missing TranslateJobService import in _job_routes.py (was deleted by F401) - Added ConfigDict(protected_namespaces=()) for DashboardDatasetItem schema field - pytest.ini: replaced deprecated importmode with asyncio_mode All 440 tests pass with zero deprecation warnings.
83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
# #region TestSmokeApp [C:2] [TYPE Module]
|
|
# @SEMANTICS: tests, smoke, app, imports, fastapi
|
|
# @PURPOSE: Minimal smoke tests that verify the full application import chain
|
|
# succeeds without SyntaxError, IndentationError, ImportError, or
|
|
# NameError in any module.
|
|
# @LAYER Tests (Smoke)
|
|
# @RELATION BINDS_TO -> src/app.py
|
|
# @RELATION BINDS_TO -> src/core/cot_logger.py
|
|
# @INVARIANT: All tests must pass without a running PostgreSQL instance.
|
|
#
|
|
# @RATIONALE: Uses SQLite in-memory database URLs to avoid requiring a live
|
|
# PostgreSQL server during smoke testing. The database module's
|
|
# _build_engine() already supports SQLite with
|
|
# check_same_thread=False.
|
|
|
|
"""Smoke test: verify the full application imports without errors.
|
|
|
|
Catches: SyntaxError, IndentationError, ImportError, NameError in any module
|
|
that is part of the application import chain.
|
|
|
|
Database dependency:
|
|
The application's database module (src.core.database) creates SQLAlchemy
|
|
engines at import time. To avoid needing a running PostgreSQL instance,
|
|
environment variables are set to SQLite in-memory databases before the
|
|
app is imported.
|
|
"""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Database URL override: use SQLite in-memory so no PostgreSQL is needed.
|
|
# Must happen before ANY application module is imported.
|
|
# ---------------------------------------------------------------------------
|
|
os.environ.setdefault("DATABASE_URL", "sqlite:///:memory:")
|
|
os.environ.setdefault("TASKS_DATABASE_URL", "sqlite:///:memory:")
|
|
os.environ.setdefault("AUTH_DATABASE_URL", "sqlite:///:memory:")
|
|
|
|
# Ensure the backend root is on sys.path so `src` package is importable
|
|
_src_path = str(Path(__file__).resolve().parent.parent)
|
|
if _src_path not in sys.path:
|
|
sys.path.insert(0, _src_path)
|
|
|
|
|
|
def test_app_imports_cleanly():
|
|
"""The application module tree imports without errors."""
|
|
from src.app import app
|
|
|
|
assert app is not None
|
|
assert app.title == "Superset Tools API"
|
|
|
|
|
|
def test_app_has_expected_middleware():
|
|
"""TraceContextMiddleware is registered (trace_id propagation)."""
|
|
from src.app import app
|
|
|
|
middleware_classes = [m.cls.__name__ for m in app.user_middleware]
|
|
assert "TraceContextMiddleware" in middleware_classes, (
|
|
f"TraceContextMiddleware not found in app middleware: {middleware_classes}"
|
|
)
|
|
|
|
|
|
def test_cot_logger_imports():
|
|
"""Core logging infrastructure is importable."""
|
|
from src.core.cot_logger import (
|
|
get_trace_id,
|
|
log,
|
|
pop_span,
|
|
push_span,
|
|
seed_trace_id,
|
|
)
|
|
|
|
tid = seed_trace_id()
|
|
assert tid is not None
|
|
assert get_trace_id() == tid
|
|
log("test", "REASON", "Smoke test log entry", {"ok": True})
|
|
|
|
# Verify push_span / pop_span round-trip
|
|
prev = push_span("test_span")
|
|
assert prev == "" # default empty span
|
|
pop_span(prev)
|