feat: harden video analysis and runtime resilience
This commit is contained in:
1 parent
5ada543a09
commit
bb16991f2c
55 files changed
+5023
-437
No files matched your search
@@ -14,7 +14,8 @@
|
||||
|
||||
"""Unit tests for Artemis System Diagnostics & Readiness Engine."""
|
||||
|
||||
from unittest.mock import AsyncMock
|
||||
import asyncio
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
|
||||
import pytest
|
||||
from artemis.core.diagnostics.engine import ReadinessEngine
|
||||
@@ -139,6 +140,128 @@ def test_adb_probe_parses_device_lock_state(policy_output, trust_output, expecte
|
||||
assert AdbDeviceProbe._parse_device_lock_state(policy_output, trust_output) is expected
|
||||
|
||||
|
||||
def test_modern_unlock_state_is_not_overridden_by_legacy_fields():
|
||||
policy = (
|
||||
"KeyguardServiceDelegate\n"
|
||||
" showing=false\n"
|
||||
"mShowingLockscreen=true mKeyguardOccluded=false"
|
||||
)
|
||||
trust = 'User "Owner" (current): deviceLocked=0'
|
||||
|
||||
assert AdbDeviceProbe._parse_device_lock_state(policy, trust) is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_positive_lock_state_requires_confirmation(monkeypatch):
|
||||
probe = AdbDeviceProbe()
|
||||
raw_probe = AsyncMock(side_effect=[True, None])
|
||||
monkeypatch.setattr(probe, "_get_device_lock_state", raw_probe)
|
||||
|
||||
result = await probe._get_confirmed_device_lock_state("adb", "device-1")
|
||||
|
||||
assert result is None
|
||||
assert raw_probe.await_count == 2
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_dashboard_reuses_recent_confirmed_state_on_one_timeout(monkeypatch):
|
||||
probe = AdbDeviceProbe()
|
||||
confirmed_probe = AsyncMock(side_effect=[False, None])
|
||||
monkeypatch.setattr(
|
||||
probe, "_get_confirmed_device_lock_state", confirmed_probe
|
||||
)
|
||||
|
||||
assert await probe._get_dashboard_lock_state("adb", "device-1") is False
|
||||
assert await probe._get_dashboard_lock_state("adb", "device-1") is False
|
||||
assert probe._lock_state_sources["device-1"] == "recent_confirmed"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_readiness_engine_coalesces_concurrent_full_scans():
|
||||
engine = ReadinessEngine()
|
||||
result = ProbeResult(
|
||||
id="test_probe",
|
||||
category=ProbeCategory.RUNTIME,
|
||||
title="Test",
|
||||
status=ProbeStatus.PASS,
|
||||
is_blocker=True,
|
||||
summary="Ready",
|
||||
description="Ready",
|
||||
)
|
||||
|
||||
async def slow_probe():
|
||||
await asyncio.sleep(0.01)
|
||||
return result
|
||||
|
||||
probe = Mock()
|
||||
probe.probe = AsyncMock(side_effect=slow_probe)
|
||||
engine._probes = {"test_probe": probe}
|
||||
|
||||
reports = await asyncio.gather(*(engine.run_all() for _ in range(8)))
|
||||
|
||||
assert probe.probe.await_count == 1
|
||||
assert all(report.overall_ready for report in reports)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_readiness_engine_reuses_cache_until_forced():
|
||||
engine = ReadinessEngine()
|
||||
result = ProbeResult(
|
||||
id="test_probe",
|
||||
category=ProbeCategory.RUNTIME,
|
||||
title="Test",
|
||||
status=ProbeStatus.PASS,
|
||||
is_blocker=True,
|
||||
summary="Ready",
|
||||
description="Ready",
|
||||
)
|
||||
probe = Mock()
|
||||
probe.probe = AsyncMock(return_value=result)
|
||||
engine._probes = {"test_probe": probe}
|
||||
|
||||
first = await engine.run_all()
|
||||
cached = await engine.run_all()
|
||||
refreshed = await engine.run_all(force_refresh=True)
|
||||
|
||||
assert probe.probe.await_count == 2
|
||||
assert cached.timestamp == first.timestamp
|
||||
assert refreshed.timestamp >= first.timestamp
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_invalidation_prevents_in_flight_report_from_becoming_shared_cache():
|
||||
engine = ReadinessEngine()
|
||||
result = ProbeResult(
|
||||
id="test_probe",
|
||||
category=ProbeCategory.RUNTIME,
|
||||
title="Test",
|
||||
status=ProbeStatus.PASS,
|
||||
is_blocker=True,
|
||||
summary="Ready",
|
||||
description="Ready",
|
||||
)
|
||||
started = asyncio.Event()
|
||||
release = asyncio.Event()
|
||||
|
||||
async def controlled_probe():
|
||||
started.set()
|
||||
await release.wait()
|
||||
return result
|
||||
|
||||
probe = Mock()
|
||||
probe.probe = AsyncMock(side_effect=controlled_probe)
|
||||
engine._probes = {"test_probe": probe}
|
||||
|
||||
old_scan = asyncio.create_task(engine.run_all())
|
||||
await started.wait()
|
||||
engine.invalidate_cache()
|
||||
release.set()
|
||||
await old_scan
|
||||
await engine.run_all()
|
||||
|
||||
assert probe.probe.await_count == 2
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_submission_probe_skips_full_device_enrichment(monkeypatch):
|
||||
probe = AdbDeviceProbe(target_serial="device-2")
|
||||
|
||||
Reference in new issue
Block a user