From 6c6c85b7dc25e14b132f0f56ca59c63caa4af6c2 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 11 Jul 2026 16:35:50 -0600 Subject: [PATCH] Fix cross-platform flakiness in ERC root-resolution test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test_root_resolves_to_project_schematic created its project directly in tmp_path, where the autouse _set_test_search_paths fixture also drops a test_project.kicad_pro. With two .kicad_pro files in one directory, _resolve_root_schematic returns whichever os.listdir yields first — myproject on ext4, test_project on APFS — so the test passed on Linux and failed on macOS. Anchor the test's project in its own subdirectory so the root walk finds this project's .kicad_pro and stops before reaching the sibling. Product code is unchanged and correct; this was test isolation only. --- tests/test_schematic_analysis.py | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/tests/test_schematic_analysis.py b/tests/test_schematic_analysis.py index e995ec9..a9ee029 100644 --- a/tests/test_schematic_analysis.py +++ b/tests/test_schematic_analysis.py @@ -2,10 +2,6 @@ import pytest -from tests.conftest import requires_sch_api - - -@requires_sch_api @pytest.mark.unit class TestRunSchematicErc: """Tests for the run_schematic_erc tool.""" @@ -82,7 +78,6 @@ class TestErcJsonParsing: return FakeResult() with ( - patch("mckicad.tools.schematic_analysis._HAS_SCH_API", False), patch("mckicad.tools.schematic_analysis.find_kicad_cli", return_value="/usr/bin/kicad-cli"), patch("subprocess.run", side_effect=fake_subprocess_run), ): @@ -125,7 +120,6 @@ class TestErcJsonParsing: return FakeResult() with ( - patch("mckicad.tools.schematic_analysis._HAS_SCH_API", False), patch("mckicad.tools.schematic_analysis.find_kicad_cli", return_value="/usr/bin/kicad-cli"), patch("subprocess.run", side_effect=fake_subprocess_run), ): @@ -171,7 +165,6 @@ class TestErcJsonParsing: return FakeResult() with ( - patch("mckicad.tools.schematic_analysis._HAS_SCH_API", False), patch("mckicad.tools.schematic_analysis.find_kicad_cli", return_value="/usr/bin/kicad-cli"), patch("subprocess.run", side_effect=fake_subprocess_run), ): @@ -189,14 +182,22 @@ class TestErcJsonParsing: from mckicad.tools.schematic_analysis import run_schematic_erc - # Create a project structure with root + sub-sheet - pro_file = tmp_path / "myproject.kicad_pro" + # Anchor the project in its own subdirectory. The autouse + # _set_test_search_paths fixture drops a second "test_project.kicad_pro" + # into tmp_path; keeping our project one level down means the root walk + # finds *this* project's .kicad_pro and stops before it reaches (and is + # confused by) the sibling. Without this, resolution depends on + # os.listdir order, which differs between ext4 and APFS. + proj_dir = tmp_path / "myproject" + proj_dir.mkdir() + + pro_file = proj_dir / "myproject.kicad_pro" pro_file.write_text("{}") - root_sch = tmp_path / "myproject.kicad_sch" + root_sch = proj_dir / "myproject.kicad_sch" root_sch.write_text('(kicad_sch (version 20231120) (uuid "root"))\n') - sub_dir = tmp_path / "sub" + sub_dir = proj_dir / "sub" sub_dir.mkdir() sub_sch = sub_dir / "power.kicad_sch" sub_sch.write_text('(kicad_sch (version 20231120) (uuid "sub"))\n') @@ -220,7 +221,6 @@ class TestErcJsonParsing: return FakeResult() with ( - patch("mckicad.tools.schematic_analysis._HAS_SCH_API", False), patch("mckicad.tools.schematic_analysis.find_kicad_cli", return_value="/usr/bin/kicad-cli"), patch("subprocess.run", side_effect=fake_subprocess_run), ): @@ -233,7 +233,6 @@ class TestErcJsonParsing: assert captured_paths[0] == str(root_sch) -@requires_sch_api @pytest.mark.unit class TestAnalyzeConnectivity: """Tests for the analyze_connectivity tool.""" @@ -252,7 +251,6 @@ class TestAnalyzeConnectivity: assert result["success"] is False -@requires_sch_api @pytest.mark.unit class TestCheckPinConnection: """Tests for the check_pin_connection tool.""" @@ -279,7 +277,6 @@ class TestCheckPinConnection: assert "success" in result -@requires_sch_api @pytest.mark.unit class TestVerifyPinsConnected: """Tests for the verify_pins_connected tool.""" @@ -298,7 +295,6 @@ class TestVerifyPinsConnected: assert "success" in result -@requires_sch_api @pytest.mark.unit class TestGetComponentPins: """Tests for the get_component_pins tool.""" @@ -349,7 +345,6 @@ class TestExportValidation: assert "Unsupported" in result.get("error", "") -@requires_sch_api @pytest.mark.unit class TestAuditWiring: """Tests for the audit_wiring tool.""" @@ -478,7 +473,6 @@ class TestAuditWiring: assert isinstance(anomalies["auto_named_nets"], list) -@requires_sch_api @pytest.mark.unit class TestVerifyConnectivity: """Tests for the verify_connectivity tool.""" @@ -600,7 +594,6 @@ class TestValidateSchematic: return FakeResult() stack = contextlib.ExitStack() - stack.enter_context(patch("mckicad.tools.schematic_analysis._HAS_SCH_API", False)) stack.enter_context(patch("mckicad.tools.schematic_analysis.find_kicad_cli", return_value="/usr/bin/kicad-cli")) stack.enter_context(patch("subprocess.run", side_effect=fake_subprocess_run)) return stack