Files
boc/vims-core/tests/test_all_instances.py
T

264 lines
9.0 KiB
Python
Raw Normal View History

"""
VIMS Integration Tests
Verifierar att alla instanser är korrekt skapade och fungerar.
"""
import sys
import unittest
from pathlib import Path
# Add paths
sys.path.append(str(Path(__file__).parent.parent))
sys.path.append(str(Path(__file__).parent.parent.parent / "atm-anomaly-detection" / "src"))
from core.base_detector import VIMSInstanceRegistry
from core.database import VIMSDatabase
class TestVIMSInstances(unittest.TestCase):
"""Test alla VIMS-instanser."""
INSTANCES = [
"street-lighting",
"bridge-inspection",
"retail-analytics",
"insurance-risk",
"municipal-maintenance",
"construction-site",
"real-estate-condition",
"urban-decay",
"crowdsourced-verification",
"data-quality",
"insurance-contradiction",
"continuous-monitoring",
"decision-intelligence",
"satellite-validation",
"cost-stale-data",
"contradiction-gap",
"consensus-engine",
"official-statistics",
"preventive-maintenance",
]
ATM_INSTANCE = "atm-monitoring" # Separat i atm-anomaly-detection/
def test_all_instances_exist(self):
"""Alla instans-kataloger ska finnas."""
base_dir = Path(__file__).parent.parent / "instances"
for instance in self.INSTANCES:
instance_dir = base_dir / instance
self.assertTrue(
instance_dir.exists(),
f"Instance directory missing: {instance}"
)
def test_instance_structure(self):
"""Varje instans ska ha korrekt struktur."""
base_dir = Path(__file__).parent.parent / "instances"
for instance in self.INSTANCES:
instance_dir = base_dir / instance
# Kolla obligatoriska filer
self.assertTrue(
(instance_dir / "src" / "detector.py").exists(),
f"{instance}: detector.py saknas"
)
self.assertTrue(
(instance_dir / "src" / "database.py").exists(),
f"{instance}: database.py saknas"
)
self.assertTrue(
(instance_dir / "README.md").exists(),
f"{instance}: README.md saknas"
)
self.assertTrue(
(instance_dir / "config.yaml").exists(),
f"{instance}: config.yaml saknas"
)
def test_detector_import(self):
"""Alla detektorer ska gå att importera."""
for instance in self.INSTANCES:
detector_path = Path(__file__).parent.parent / "instances" / instance / "src"
# Läs filen direkt istället för att importera
detector_file = detector_path / "detector.py"
self.assertTrue(
detector_file.exists(),
f"{instance}: detector.py saknas"
)
content = detector_file.read_text()
# Kolla att det finns en detektor-klass
self.assertIn(
"class ", content,
f"{instance}: Ingen klass definierad"
)
self.assertIn(
"VIMSBaseDetector", content,
f"{instance}: Ärver inte från VIMSBaseDetector"
)
def test_database_creation(self):
"""Databas ska gå att skapa för varje instans."""
import tempfile
import shutil
for instance in self.INSTANCES:
# Skapa temp-db
temp_dir = tempfile.mkdtemp()
db_path = Path(temp_dir) / f"{instance}.db"
try:
db = VIMSDatabase(instance, db_dir=temp_dir)
# Läs anomaly classes från config
config_path = Path(__file__).parent.parent / "instances" / instance / "config.yaml"
if config_path.exists():
import yaml
with open(config_path) as f:
config = yaml.safe_load(f)
classes = config.get("anomaly_classes", ["test"])
else:
classes = ["test"]
# Skapa schema
db.create_schema(anomaly_classes=classes)
# Verifiera att tabeller skapades
import sqlite3
conn = sqlite3.connect(str(db_path))
cursor = conn.cursor()
cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table'")
tables = [row[0] for row in cursor.fetchall()]
expected_prefix = instance.replace("-", "_")
self.assertIn(
f"{expected_prefix}_detections",
tables,
f"{instance}: detections-tabell saknas"
)
self.assertIn(
f"{expected_prefix}_assets",
tables,
f"{instance}: assets-tabell saknas"
)
conn.close()
finally:
shutil.rmtree(temp_dir)
def test_config_validity(self):
"""Alla config-filer ska vara giltiga YAML."""
import yaml
for instance in self.INSTANCES:
config_path = Path(__file__).parent.parent / "instances" / instance / "config.yaml"
with open(config_path) as f:
config = yaml.safe_load(f)
self.assertIn("topic", config, f"{instance}: topic saknas i config")
self.assertIn("display_name", config, f"{instance}: display_name saknas")
self.assertIn("anomaly_classes", config, f"{instance}: anomaly_classes saknas")
self.assertTrue(
len(config["anomaly_classes"]) > 0,
f"{instance}: Inga anomaly_classes definierade"
)
def test_article_links(self):
"""Alla instanser ska ha giltiga artikel-länkar."""
import yaml
for instance in self.INSTANCES:
config_path = Path(__file__).parent.parent / "instances" / instance / "config.yaml"
with open(config_path) as f:
config = yaml.safe_load(f)
article_url = config.get("article_url", "")
# Kolla att artikeln finns på disk
article_path = Path(__file__).parent.parent.parent / "landvex-site" / "insights"
# Extrahera slug från URL
slug = article_url.strip("/").split("/")[-1]
if slug:
article_dir = article_path / slug
self.assertTrue(
article_dir.exists() or article_url.startswith("/insights/"),
f"{instance}: Artikel saknas: {article_url}"
)
class TestATMCore(unittest.TestCase):
"""Test ATM-anomaly kärnan."""
def test_detector_initialization(self):
"""ATM-detektor ska gå att initiera."""
# Kolla att filen finns (ultralytics krävs för att importera)
detector_file = Path(__file__).parent.parent.parent / "atm-anomaly-detection" / "src" / "models" / "anomaly_detector.py"
self.assertTrue(detector_file.exists(), "ATM detector file missing")
# Kolla att klassen finns definierad
content = detector_file.read_text()
self.assertIn("class ATMAnomalyDetector", content, "ATMAnomalyDetector class missing")
self.assertIn("CLASS_NAMES", content, "CLASS_NAMES missing")
def test_database_setup(self):
"""ATM-databas ska gå att sätta upp."""
import tempfile
import shutil
temp_dir = tempfile.mkdtemp()
try:
db = VIMSDatabase("atm-monitoring", db_dir=temp_dir)
db.create_schema(anomaly_classes=[
"skimming_device", "vandalism", "physical_damage"
])
# Verifiera
stats = db.get_stats()
self.assertIn("total_detections", stats)
finally:
shutil.rmtree(temp_dir)
class TestAPIEndpoints(unittest.TestCase):
"""Test API-endpoints."""
def test_health_endpoint(self):
"""Health endpoint ska returnera OK."""
# Detta kräver att servern körs
# Placeholder för integrationstest
pass
def run_all_tests():
"""Kör alla tester och rapportera."""
loader = unittest.TestLoader()
suite = unittest.TestSuite()
suite.addTests(loader.loadTestsFromTestCase(TestVIMSInstances))
suite.addTests(loader.loadTestsFromTestCase(TestATMCore))
suite.addTests(loader.loadTestsFromTestCase(TestAPIEndpoints))
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
return result.wasSuccessful()
if __name__ == "__main__":
success = run_all_tests()
sys.exit(0 if success else 1)