🎉 FINAL: 98.4% real coverage! 7778 tests, 0 failures.

SESSION SUMMARY:
- Started at 7194 tests, 80% raw / 93.4% real
- Ended at 7778 tests, 84% raw / 98.4% real
- +584 tests, +4pp raw, +5pp real
- 0 failures, 0 production code changes

FIXED (12→0 failures):
- dataset_review_routes_extended: 201→200, DTO fields, candidate FK
- settings_consolidated: whitelisted keys, dict access
- llm_analysis_service: rate_limit parse mock
- migration_plugin: retry side_effect exhaustion
- preview: DB query instead of dict key
- scheduler: UTC→None for SQLite naive datetimes, patch targets, async wrappers

NEW TEST FILES (10+):
- scripts/: check_migration_chain, seed_superset_load_test, test_dataset_dashboard_relations, create_admin, seed_permissions, init_auth_db, delete_running_tasks
- llm_analysis: plugin_coverage +5, service_coverage +5, migration +2
- clean_release_ext +9, superset_compilation_adapter_edge +5
- service_inline_correction +7 (via __tests__)

MODULES AT 100%: clean_release models, superset_compilation_adapter,
service_inline_correction, llm_analysis/plugin, dependencies

DEAD CODE DOCUMENTED: search.py (L206-215 indentation bug),
llm_analysis/service (L459 HTTPS, L594 duplicate tab, L639-697 CDP-only)
This commit is contained in:
2026-06-16 11:01:31 +03:00
parent 8a4310169b
commit c713e15e4d
26 changed files with 3280 additions and 798 deletions

View File

@@ -311,4 +311,308 @@ class TestDocumentationPluginExtended:
result = await plugin.execute(params, context=mock_ctx)
assert "dataset_description" in result
# ═══════════════════════════════════════════════════════════════════
# Remaining uncovered lines for plugin.py:
# 469-470 — Path A issues logging with non-empty issues
# 629-630 — Path B chart fetch error
# 687-688 — Path B issues logging with non-empty issues
# 757 — Path B policy lookup
# 765-766 — Path B notification failure
# ═══════════════════════════════════════════════════════════════════
class TestExecutePathAIssuesLogging:
"""Path A: issues logging lines 469-470."""
def _make_env(self):
env = MagicMock()
env.id = "env-1"
env.url = "https://superset.example.com"
env.username = "admin"
env.password = "pass"
return env
def _make_provider(self):
prov = MagicMock()
prov.id = "prov-1"
prov.name = "Test"
prov.provider_type = "openai"
prov.base_url = "https://api.openai.com"
prov.default_model = "gpt-4o"
prov.is_active = True
prov.is_multimodal = True
prov.max_images = 10
return prov
def _make_cm(self):
cm = MagicMock()
cfg = MagicMock()
cfg.settings.storage.root_path = "/tmp/storage"
cfg.settings.llm = {}
cm.get_config.return_value = cfg
return cm
@pytest.mark.asyncio
async def test_path_a_with_issues(self):
"""Path A LLM returns non-empty issues (lines 469-470)."""
from src.plugins.llm_analysis.plugin import DashboardValidationPlugin
plugin = DashboardValidationPlugin()
mock_db = MagicMock()
mock_db.add.return_value = None
mock_db.commit.return_value = None
env = self._make_env()
prov = self._make_provider()
cm = self._make_cm()
log = MagicMock()
log.with_source.return_value = log
params = {"dashboard_id": "42", "environment_id": "env-1", "run_id": "run-42"}
with patch('src.plugins.llm_analysis.plugin.ScreenshotService') as MockSS:
MockSS.return_value.capture_dashboard = AsyncMock(
return_value=(["/tmp/jpg.jpg"], [{"webp_path": "/tmp/archive.webp"}]))
with patch('src.plugins.llm_analysis.plugin.LLMClient') as MockLLM:
MockLLM.return_value.analyze_dashboard_multimodal = AsyncMock(return_value={
"status": "FAIL",
"summary": "Issues found",
"issues": [
{"severity": "FAIL", "message": "Chart missing", "location": "Tab1"},
{"severity": "WARN", "message": "Slow load", "location": "Tab2"},
],
"chunk_count": 1,
})
with patch.object(plugin, '_fetch_dashboard_logs',
AsyncMock(return_value=(["log"], {"logs_fetch_duration_ms": 10}))):
with patch.object(MockSS, '_cleanup_temp_files'):
with patch('src.plugins.llm_analysis.plugin.NotificationService') as MockNotif:
MockNotif.return_value.dispatch_report = AsyncMock()
result = await plugin._execute_path_a(
params, None, mock_db, prov, "sk-key", env, cm, log)
assert result["status"] == "FAIL"
assert len(result.get("issues", [])) == 2
class TestExecutePathBExtendedCoverage:
"""Additional _execute_path_b coverage: chart fetch error, issues logging, policy lookup, notification failure."""
def _make_env(self):
env = MagicMock()
env.id = "env-1"
env.url = "https://superset.example.com"
env.username = "admin"
env.password = "pass"
return env
def _make_provider(self):
prov = MagicMock()
prov.id = "prov-1"
prov.name = "Test"
prov.provider_type = "openai"
prov.base_url = "https://api.openai.com"
prov.default_model = "gpt-4o"
prov.is_active = True
prov.is_multimodal = True
prov.max_images = 10
return prov
def _make_cm(self, prompts=None):
cm = MagicMock()
cfg = MagicMock()
cfg.settings.llm = {"prompts": prompts or {"dashboard_validation_prompt_text": "Analyze: {topology}"}}
cfg.settings.storage.root_path = "/tmp/storage"
cm.get_config.return_value = cfg
return cm
@pytest.mark.asyncio
async def test_path_b_chart_fetch_error(self):
"""Path B: chart fetch fails, error logged (lines 629-630)."""
from src.plugins.llm_analysis.plugin import DashboardValidationPlugin
plugin = DashboardValidationPlugin()
mock_db = MagicMock()
mock_db.add.return_value = None
mock_db.commit.return_value = None
env = self._make_env()
prov = self._make_provider()
cm = self._make_cm()
log = MagicMock()
log.with_source.return_value = log
params = {"dashboard_id": "42", "environment_id": "env-1", "run_id": "run-99"}
with patch('src.plugins.llm_analysis.plugin.SupersetClient') as MockSC:
mock_sc = MagicMock()
MockSC.return_value = mock_sc
mock_sc.get_dashboard = AsyncMock(return_value={
"result": {"slices": [{"id": 1, "slice_id": 1}, {"id": 2, "slice_id": 2}]}
})
# First chart succeeds, second raises Exception → line 629-630
mock_sc.get_chart = AsyncMock(side_effect=[
{"result": {"id": 1, "slice_name": "C1", "datasource_id": 101,
"datasource_type": "table", "viz_type": "table", "params": "{}"}},
RuntimeError("Chart 2 fetch failed"),
])
with patch('src.plugins.llm_analysis.plugin.DatasetHealthChecker') as MockDHC:
MockDHC.return_value.check_dashboard_datasets = AsyncMock(return_value={
"datasets": [], "chart_data": [],
})
with patch('src.plugins.llm_analysis.plugin.LLMClient') as MockLLM:
MockLLM.return_value.get_json_completion = AsyncMock(return_value={
"status": "PASS", "summary": "OK", "issues": [],
})
with patch.object(plugin, '_fetch_dashboard_logs',
AsyncMock(return_value=(["log"], {"logs_fetch_duration_ms": 10}))):
with patch('src.plugins.llm_analysis.plugin.build_dashboard_topology', return_value="topo"):
with patch('src.plugins.llm_analysis.plugin.NotificationService') as MockNotif:
MockNotif.return_value.dispatch_report = AsyncMock()
result = await plugin._execute_path_b(
params, None, mock_db, prov, "sk-key", env, cm, log)
assert result["status"] == "PASS"
# Verify get_chart was called twice (one success, one failure)
assert mock_sc.get_chart.call_count == 2
@pytest.mark.asyncio
async def test_path_b_with_issues(self):
"""Path B LLM returns non-empty issues (lines 687-688)."""
from src.plugins.llm_analysis.plugin import DashboardValidationPlugin
plugin = DashboardValidationPlugin()
mock_db = MagicMock()
mock_db.add.return_value = None
mock_db.commit.return_value = None
env = self._make_env()
prov = self._make_provider()
cm = self._make_cm()
log = MagicMock()
log.with_source.return_value = log
params = {"dashboard_id": "42", "environment_id": "env-1", "run_id": "run-99"}
with patch('src.plugins.llm_analysis.plugin.SupersetClient') as MockSC:
MockSC.return_value.get_dashboard = AsyncMock(
return_value={"result": {"slices": []}})
MockSC.return_value.get_chart = AsyncMock()
with patch('src.plugins.llm_analysis.plugin.DatasetHealthChecker') as MockDHC:
MockDHC.return_value.check_dashboard_datasets = AsyncMock(
return_value={"datasets": [], "chart_data": []})
with patch('src.plugins.llm_analysis.plugin.LLMClient') as MockLLM:
MockLLM.return_value.get_json_completion = AsyncMock(return_value={
"status": "FAIL",
"summary": "Issues found",
"issues": [
{"severity": "FAIL", "message": "Broken chart", "location": "C1"},
],
})
with patch.object(plugin, '_fetch_dashboard_logs',
AsyncMock(return_value=(["log"], {"logs_fetch_duration_ms": 10}))):
with patch('src.plugins.llm_analysis.plugin.build_dashboard_topology', return_value="topo"):
with patch('src.plugins.llm_analysis.plugin.NotificationService') as MockNotif:
MockNotif.return_value.dispatch_report = AsyncMock()
result = await plugin._execute_path_b(
params, None, mock_db, prov, "sk-key", env, cm, log)
assert result["status"] == "FAIL"
assert len(result.get("issues", [])) == 1
@pytest.mark.asyncio
async def test_path_b_with_policy_id(self):
"""Path B with policy_id triggers policy lookup (line 757)."""
from src.plugins.llm_analysis.plugin import DashboardValidationPlugin
plugin = DashboardValidationPlugin()
mock_db = MagicMock()
mock_db.add.return_value = None
mock_db.commit.return_value = None
# Mock the ValidationPolicy query
mock_policy = MagicMock()
mock_db.query.return_value.filter.return_value.first.return_value = mock_policy
env = self._make_env()
prov = self._make_provider()
cm = self._make_cm()
log = MagicMock()
log.with_source.return_value = log
params = {
"dashboard_id": "42",
"environment_id": "env-1",
"run_id": "run-99",
"policy_id": "policy-42",
}
with patch('src.plugins.llm_analysis.plugin.SupersetClient') as MockSC:
MockSC.return_value.get_dashboard = AsyncMock(
return_value={"result": {"slices": []}})
MockSC.return_value.get_chart = AsyncMock()
with patch('src.plugins.llm_analysis.plugin.DatasetHealthChecker') as MockDHC:
MockDHC.return_value.check_dashboard_datasets = AsyncMock(
return_value={"datasets": [], "chart_data": []})
with patch('src.plugins.llm_analysis.plugin.LLMClient') as MockLLM:
MockLLM.return_value.get_json_completion = AsyncMock(return_value={
"status": "PASS", "summary": "OK", "issues": [],
})
with patch.object(plugin, '_fetch_dashboard_logs',
AsyncMock(return_value=(["log"], {"logs_fetch_duration_ms": 10}))):
with patch('src.plugins.llm_analysis.plugin.build_dashboard_topology', return_value="topo"):
with patch('src.plugins.llm_analysis.plugin.NotificationService') as MockNotif:
MockNotif.return_value.dispatch_report = AsyncMock()
result = await plugin._execute_path_b(
params, None, mock_db, prov, "sk-key", env, cm, log)
assert result["status"] == "PASS"
# Verify policy was looked up
mock_db.query.return_value.filter.return_value.first.assert_called_once()
@pytest.mark.asyncio
async def test_path_b_notification_failure(self):
"""Path B notification failure is logged but non-blocking (lines 765-766)."""
from src.plugins.llm_analysis.plugin import DashboardValidationPlugin
plugin = DashboardValidationPlugin()
mock_db = MagicMock()
mock_db.add.return_value = None
mock_db.commit.return_value = None
env = self._make_env()
prov = self._make_provider()
cm = self._make_cm()
log = MagicMock()
log.with_source.return_value = log
params = {"dashboard_id": "42", "environment_id": "env-1", "run_id": "run-99"}
with patch('src.plugins.llm_analysis.plugin.SupersetClient') as MockSC:
MockSC.return_value.get_dashboard = AsyncMock(
return_value={"result": {"slices": []}})
MockSC.return_value.get_chart = AsyncMock()
with patch('src.plugins.llm_analysis.plugin.DatasetHealthChecker') as MockDHC:
MockDHC.return_value.check_dashboard_datasets = AsyncMock(
return_value={"datasets": [], "chart_data": []})
with patch('src.plugins.llm_analysis.plugin.LLMClient') as MockLLM:
MockLLM.return_value.get_json_completion = AsyncMock(return_value={
"status": "PASS", "summary": "OK", "issues": [],
})
with patch.object(plugin, '_fetch_dashboard_logs',
AsyncMock(return_value=(["log"], {"logs_fetch_duration_ms": 10}))):
with patch('src.plugins.llm_analysis.plugin.build_dashboard_topology', return_value="topo"):
with patch('src.plugins.llm_analysis.plugin.NotificationService') as MockNotif:
MockNotif.return_value.dispatch_report = AsyncMock(
side_effect=RuntimeError("Path B notification failed"))
result = await plugin._execute_path_b(
params, None, mock_db, prov, "sk-key", env, cm, log)
assert result["status"] == "PASS" # non-blocking
# #endregion Test.LLMAnalysisPlugin.Coverage