Files
ss-tools/backend/tests/test_smoke_plugins.py
busya 4205618ee6 chore: eliminate all deprecation warnings from tests and linter
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.
2026-05-26 19:18:28 +03:00

85 lines
3.0 KiB
Python

import os
from pathlib import Path
import pytest
import sys
from unittest.mock import MagicMock, patch
import tests.conftest # noqa: F401 — ensure conftest runs first
sys.path.insert(0, str(Path(__file__).parent.parent))
# ── Save original module before it gets mocked ──
_ORIG_DATABASE_MODULE = sys.modules.get('src.core.database')
@pytest.fixture(autouse=True)
def isolate_database():
"""Isolate this test module from the real database.
Saves the real src.core.database, replaces it with a MagicMock,
and restores it after the test completes. This prevents PluginLoader
imports from triggering real database initialization.
"""
# Remove real module if loaded
sys.modules.pop('src.core.database', None)
# Insert mock
mock_db = MagicMock()
sys.modules['src.core.database'] = mock_db
yield
# Restore real module
sys.modules.pop('src.core.database', None)
if _ORIG_DATABASE_MODULE is not None:
sys.modules['src.core.database'] = _ORIG_DATABASE_MODULE
class TestPluginSmoke:
"""Smoke tests for plugin loading and initialization."""
def test_plugins_load_successfully(self):
"""
Verify that all standard plugins can be discovered and instantiated
by the PluginLoader without throwing errors (e.g., missing imports,
syntax errors, missing class declarations).
"""
from src.core.plugin_loader import PluginLoader
plugin_dir = os.path.join(str(Path(__file__).parent.parent), "src", "plugins")
# This will discover and instantiate plugins
loader = PluginLoader(plugin_dir)
plugins = loader.get_all_plugin_configs()
plugin_ids = {p.id for p in plugins}
# We expect at least the migration and git plugins to be present
expected_plugins = {"superset-migration", "git-integration"}
missing_plugins = expected_plugins - plugin_ids
assert not missing_plugins, f"Missing expected plugins: {missing_plugins}"
@pytest.mark.anyio
async def test_task_manager_initializes_with_plugins(self):
"""
Verify that the TaskManager can initialize with the real PluginLoader.
"""
from src.core.plugin_loader import PluginLoader
from src.core.task_manager.manager import TaskManager
plugin_dir = os.path.join(str(Path(__file__).parent.parent), "src", "plugins")
loader = PluginLoader(plugin_dir)
# Initialize TaskManager with real loader
with patch("src.core.task_manager.manager.TaskPersistenceService") as MockPersistence, \
patch("src.core.task_manager.manager.TaskLogPersistenceService"):
MockPersistence.return_value.load_tasks.return_value = []
with patch("src.dependencies.config_manager"):
manager = TaskManager(loader)
# Stop the flusher thread to prevent hanging
manager._flusher_stop_event.set()
manager._flusher_thread.join(timeout=2)
assert manager is not None