66 lines
2.3 KiB
Python
66 lines
2.3 KiB
Python
"""Discovery tests (opc/discovery.py).
|
|
|
|
Pure tests run on any OS; the registry/COM scans are Windows-only and skip
|
|
elsewhere (IMPLEMENTATION_PLAN §9: COM adapters are import-guarded).
|
|
"""
|
|
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
from opcda_diagnozer.opc.base import OpcError
|
|
from opcda_diagnozer.opc.discovery import (
|
|
DA_CATEGORIES,
|
|
ServerInfo,
|
|
list_servers,
|
|
normalize_string_array,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("raw", "expected"),
|
|
[
|
|
(None, []),
|
|
("", []),
|
|
("One.Server.1", ["One.Server.1"]),
|
|
(("A.Sim.1", "A.Sim.2"), ["A.Sim.1", "A.Sim.2"]),
|
|
(("A.Sim.1", " A.Sim.1 ", "A.Sim.2"), ["A.Sim.1", "A.Sim.2"]), # dedupe + trim
|
|
((1, None, "A.Sim.1"), ["A.Sim.1"]), # non-strings dropped
|
|
([], []),
|
|
],
|
|
)
|
|
def test_normalize_string_array(raw: object, expected: list[str]) -> None:
|
|
assert normalize_string_array(raw) == expected
|
|
|
|
|
|
def test_registry_source_rejects_remote_host() -> None:
|
|
with pytest.raises(OpcError, match="local"):
|
|
list_servers(host="REMOTE-HOST", source="registry")
|
|
|
|
|
|
def test_unknown_source_rejected() -> None:
|
|
with pytest.raises(ValueError, match="unknown source"):
|
|
list_servers(source="nonsense") # type: ignore[arg-type]
|
|
|
|
|
|
@pytest.mark.skipif(sys.platform != "win32", reason="winreg scan is Windows-only")
|
|
def test_registry_scan_local_structural() -> None:
|
|
servers = list_servers(source="registry")
|
|
assert isinstance(servers, list)
|
|
for server in servers:
|
|
assert server.source == "registry"
|
|
assert server.prog_id # non-empty ProgID (or CLSID fallback)
|
|
assert server.clsid is not None
|
|
assert server.clsid.startswith("{") and server.clsid.endswith("}")
|
|
assert set(server.da_versions) <= set(DA_CATEGORIES.values())
|
|
assert [s.prog_id.lower() for s in servers] == sorted(s.prog_id.lower() for s in servers)
|
|
|
|
|
|
@pytest.mark.skipif(sys.platform != "win32", reason="COM enumeration needs Windows + pywin32")
|
|
def test_automation_enumeration_smoke() -> None:
|
|
"""Live smoke test — requires a registered Automation Wrapper (dev box)."""
|
|
try:
|
|
servers = list_servers(source="automation")
|
|
except OpcError as exc:
|
|
pytest.skip(f"Automation Wrapper not usable on this machine: {exc}")
|
|
assert all(s.source == "automation" and s.prog_id for s in servers) |