Fixed async/sync boundary bugs across 14 test files. Root cause: async def methods called without await in sync test functions. Fixed files: - test_translate_jobs.py (10): create_job/get_job/update_job/delete_job - test_translate_scheduler.py (5): create_schedule/update/delete - test_datasets.py (14): AsyncMock + corrected patch target - test_mapping_service.py (11): sync_environment + MockSupersetClient - test_defensive_guards.py (6): GitService/SupersetClient guards - test_maintenance_service.py (29): all 6 maintenance services - test_dry_run_orchestrator.py (1): run() without await - test_dashboards_api.py (23): registry client via AsyncMock - test_validation_tasks.py (4): trailing slash in POST URL - test_superset_matrix.py (3): AsyncMock for compile_preview - test_payload_reduction.py (6): LLMClient._optimize_image wrapper - test_compliance_task_integration.py (2): event_bus ref - test_smoke_plugins.py (1): flusher_stop_event fallback - test_task_manager.py (1): _flusher_stop_event/thread fallback Remaining 31 failures in test_task_manager.py (29) and test_smoke_plugins.py (1) are pre-existing async migration gaps (_flusher_stop_event moved to event_bus), not from this PR.
145 lines
5.7 KiB
Python
145 lines
5.7 KiB
Python
# #region SupersetCompatibilityMatrixTests [C:2] [TYPE Module]
|
|
# @SEMANTICS: dataset_review, superset, compatibility_matrix, preview, sql_lab, tests
|
|
# @PURPOSE: Verifies Superset preview and SQL Lab endpoint fallback strategy used by dataset-review orchestration.
|
|
# @LAYER Tests
|
|
# @RELATION DEPENDS_ON ->[SupersetClient]
|
|
# @RELATION DEPENDS_ON ->[SupersetCompilationAdapter]
|
|
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
|
|
from src.core.utils.superset_compilation_adapter import (
|
|
PreviewCompilationPayload,
|
|
SqlLabLaunchPayload,
|
|
SupersetCompilationAdapter,
|
|
)
|
|
|
|
# Import models to ensure proper SQLAlchemy registration
|
|
|
|
|
|
# #region make_adapter [C:2] [TYPE Function]
|
|
# @PURPOSE: Build an adapter with a mock Superset client and deterministic environment for compatibility tests.
|
|
# @RELATION DEPENDS_ON ->[SupersetCompilationAdapter]
|
|
def make_adapter():
|
|
environment = SimpleNamespace(
|
|
id="env-1",
|
|
name="Test Env",
|
|
url="http://superset.example",
|
|
username="user",
|
|
password="pass",
|
|
verify_ssl=True,
|
|
timeout=30,
|
|
)
|
|
client = MagicMock()
|
|
client.network = MagicMock()
|
|
return SupersetCompilationAdapter(environment=environment, client=client), client
|
|
|
|
|
|
# #endregion make_adapter
|
|
|
|
|
|
# #region test_preview_prefers_supported_client_method_before_network_fallback [C:2] [TYPE Function]
|
|
# @PURPOSE: Confirms preview compilation uses a supported client method first when the capability exists.
|
|
# @RELATION DEPENDS_ON ->[SupersetCompilationAdapter]
|
|
@pytest.mark.asyncio
|
|
async def test_preview_prefers_supported_client_method_before_network_fallback():
|
|
adapter, client = make_adapter()
|
|
client.compile_preview = AsyncMock(return_value={"compiled_sql": "SELECT 1"})
|
|
payload = PreviewCompilationPayload(
|
|
session_id="sess-1",
|
|
dataset_id=42,
|
|
preview_fingerprint="fp-1",
|
|
template_params={"country": "RU"},
|
|
effective_filters=[{"name": "country", "value": "RU"}],
|
|
)
|
|
|
|
preview = await adapter.compile_preview(payload)
|
|
|
|
assert preview.preview_status.value == "ready"
|
|
assert preview.compiled_sql == "SELECT 1"
|
|
client.compile_preview.assert_called_once()
|
|
client.network.request.assert_not_called()
|
|
|
|
|
|
# #endregion test_preview_prefers_supported_client_method_before_network_fallback
|
|
|
|
|
|
# #region test_preview_falls_back_across_matrix_until_supported_endpoint_returns_sql [C:2] [TYPE Function]
|
|
# @PURPOSE: Confirms preview fallback walks the compatibility matrix from preferred to legacy endpoints until one returns compiled SQL.
|
|
# @RELATION DEPENDS_ON ->[SupersetCompilationAdapter]
|
|
@pytest.mark.asyncio
|
|
async def test_preview_falls_back_across_matrix_until_supported_endpoint_returns_sql():
|
|
adapter, client = make_adapter()
|
|
payload = PreviewCompilationPayload(
|
|
session_id="sess-2",
|
|
dataset_id=77,
|
|
preview_fingerprint="fp-2",
|
|
template_params={"region": "emea"},
|
|
effective_filters=[],
|
|
)
|
|
|
|
client.network.request = AsyncMock(side_effect=[
|
|
RuntimeError("preview endpoint unavailable"),
|
|
{"result": {"sql": "SELECT * FROM dataset_77"}},
|
|
])
|
|
|
|
preview = await adapter.compile_preview(payload)
|
|
|
|
assert preview.preview_status.value == "ready"
|
|
assert preview.compiled_sql == "SELECT * FROM dataset_77"
|
|
assert client.network.request.call_count == 2
|
|
# @FRAGILE: Positional call assertion — ordering changes will break this test without indicating a real regression. Prefer content-based assertion.
|
|
first_call = client.network.request.call_args_list[0].kwargs
|
|
# @FRAGILE: Positional call assertion — ordering changes will break this test without indicating a real regression. Prefer content-based assertion.
|
|
second_call = client.network.request.call_args_list[1].kwargs
|
|
assert first_call["endpoint"] == "/dataset/77/preview"
|
|
assert second_call["endpoint"] == "/dataset/77/sql"
|
|
|
|
|
|
# #endregion test_preview_falls_back_across_matrix_until_supported_endpoint_returns_sql
|
|
|
|
|
|
# #region test_sql_lab_launch_falls_back_to_legacy_execute_endpoint [C:2] [TYPE Function]
|
|
# @PURPOSE: Confirms SQL Lab launch falls back from modern to legacy execute endpoint and preserves canonical session reference extraction.
|
|
# @RELATION DEPENDS_ON ->[SupersetCompilationAdapter]
|
|
@pytest.mark.asyncio
|
|
async def test_sql_lab_launch_falls_back_to_legacy_execute_endpoint():
|
|
adapter, client = make_adapter()
|
|
client.get_dataset = AsyncMock(return_value={
|
|
"result": {
|
|
"id": 55,
|
|
"schema": "public",
|
|
"database": {"id": 9},
|
|
}
|
|
})
|
|
client.network.request = AsyncMock(side_effect=[
|
|
RuntimeError("sqllab execute unavailable"),
|
|
{"result": {"id": "query-123"}},
|
|
])
|
|
payload = SqlLabLaunchPayload(
|
|
session_id="sess-3",
|
|
dataset_id=55,
|
|
preview_id="preview-9",
|
|
compiled_sql="SELECT * FROM sales",
|
|
template_params={"limit": 10},
|
|
)
|
|
|
|
sql_lab_ref = await adapter.create_sql_lab_session(payload)
|
|
|
|
assert sql_lab_ref == "query-123"
|
|
assert client.network.request.call_count == 2
|
|
# @FRAGILE: Positional call assertion — ordering changes will break this test without indicating a real regression. Prefer content-based assertion.
|
|
first_call = client.network.request.call_args_list[0].kwargs
|
|
# @FRAGILE: Positional call assertion — ordering changes will break this test without indicating a real regression. Prefer content-based assertion.
|
|
second_call = client.network.request.call_args_list[1].kwargs
|
|
assert first_call["endpoint"] == "/sqllab/execute/"
|
|
assert second_call["endpoint"] == "/sql_lab/execute/"
|
|
|
|
|
|
# #endregion test_sql_lab_launch_falls_back_to_legacy_execute_endpoint
|
|
|
|
|
|
# #endregion SupersetCompatibilityMatrixTests
|