From dee68823c09459405b60101f44a75e487b226d66 Mon Sep 17 00:00:00 2001 From: Qian Zhang Date: Thu, 22 Oct 2026 16:11:51 -0400 Subject: [PATCH] Match the 13-bus redirect to IEEELineCodes.DSS so it compiles on Linux Both IEEE 13-bus masters said `redirect IEEELineCodes.dss`, but the file ships as `IEEELineCodes.DSS`. Windows and macOS resolve that; Linux does not, so OpenDSS compiles the circuit without its line codes. The new test checks every redirect/compile/BusCoords target in the shipped .dss files by exact name, so it fails on any platform, not only Linux. Co-Authored-By: Claude Opus 5.5 --- OpenDSS/13Bus/IEEE13Nodeckt.dss | 2 +- OpenDSS/13Bus/IEEE13Nodeckt_com_loadshape.dss | 2 +- tests/test_opendss_case_files.py | 49 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 tests/test_opendss_case_files.py diff --git a/OpenDSS/13Bus/IEEE13Nodeckt.dss b/OpenDSS/13Bus/IEEE13Nodeckt.dss index 84fff803..6814fbfb 100644 --- a/OpenDSS/13Bus/IEEE13Nodeckt.dss +++ b/OpenDSS/13Bus/IEEE13Nodeckt.dss @@ -43,7 +43,7 @@ New Transformer.XFM1 Phases=3 Windings=2 XHL=2 !LINE CODES -redirect IEEELineCodes.dss +redirect IEEELineCodes.DSS // these are local matrix line codes // corrected 9-14-2011 diff --git a/OpenDSS/13Bus/IEEE13Nodeckt_com_loadshape.dss b/OpenDSS/13Bus/IEEE13Nodeckt_com_loadshape.dss index b60f2b68..45ec9eaf 100644 --- a/OpenDSS/13Bus/IEEE13Nodeckt_com_loadshape.dss +++ b/OpenDSS/13Bus/IEEE13Nodeckt_com_loadshape.dss @@ -43,7 +43,7 @@ New Transformer.XFM1 Phases=3 Windings=2 XHL=2 !LINE CODES -redirect IEEELineCodes.dss +redirect IEEELineCodes.DSS // these are local matrix line codes // corrected 9-14-2011 diff --git a/tests/test_opendss_case_files.py b/tests/test_opendss_case_files.py new file mode 100644 index 00000000..9e552619 --- /dev/null +++ b/tests/test_opendss_case_files.py @@ -0,0 +1,49 @@ +"""The shipped OpenDSS cases must compile on case-sensitive filesystems. + +Windows and macOS resolve ``redirect IEEELineCodes.dss`` against a file named +``IEEELineCodes.DSS``; Linux does not, and OpenDSS then leaves a circuit with +no line codes. Compare names exactly so the check fails on every platform. +""" + +from __future__ import annotations + +import re +from pathlib import Path + +import pytest + +OPENDSS_DIR = Path(__file__).resolve().parents[1] / "OpenDSS" +_FILE_COMMAND = re.compile(r"^\s*(redirect|compile|buscoords)\s+(\S+)", re.IGNORECASE) + + +def _dss_files(): + return sorted(p for p in OPENDSS_DIR.rglob("*") if p.suffix.lower() == ".dss") + + +def _referenced_files(dss_file: Path): + for line in dss_file.read_text(errors="replace").splitlines(): + match = _FILE_COMMAND.match(line) + if match: + yield match.group(2).strip("\"'()[]") + + +def _exists_with_exact_case(base: Path, relative: str) -> bool: + current = base + for part in Path(relative.replace("\\", "/")).parts: + if part in (".", ".."): + current = current / part + continue + if not current.is_dir() or part not in {entry.name for entry in current.iterdir()}: + return False + current = current / part + return current.is_file() + + +@pytest.mark.parametrize("dss_file", _dss_files(), ids=lambda p: str(p.relative_to(OPENDSS_DIR))) +def test_referenced_files_match_case_exactly(dss_file): + missing = [ + target + for target in _referenced_files(dss_file) + if not _exists_with_exact_case(dss_file.parent, target) + ] + assert not missing, f"{dss_file.name} references files that do not exist with this exact case: {missing}"