[core] Configure the platform again after prefetching its packages (#18830)

This commit is contained in:
J. Nick Koston
2026-08-31 13:01:13 -05:00
committed by GitHub
parent 06d477bea7
commit ad69718ecc
2 changed files with 118 additions and 20 deletions
@@ -1417,6 +1417,76 @@ def test_prefetch_installs_cached_archives_without_downloads(
assert not (tmp_path / pf._SENTINEL_NAME).exists()
@pytest.mark.parametrize(
("platform_group", "lib_group", "expected"),
[
(
[("toolchain-x@1", _FakeSpec(name="toolchain-x"))],
[],
["configure", "install", "configure"],
),
([], [("noise-c@1.0", _FakeSpec(name="noise-c"))], ["configure", "install"]),
],
)
def test_prefetch_reconfigures_only_after_platform_installs(
tmp_path: Path, platform_group: list, lib_group: list, expected: list[str]
) -> None:
"""Installed platform packages get a second configure pass; libraries do not."""
_write_ini(tmp_path, "[env:testenv]\nplatform = fake/p@1\n")
order: list[str] = []
fake_platform = MagicMock()
fake_platform.packages = {}
fake_platform.configure_project_packages.side_effect = lambda env, targets: (
order.append("configure")
)
config = _fake_config(
tmp_path, {"platform": "fake/p@1", "lib_deps": ["esphome/noise-c@1.0"]}
)
modules = _pio_modules(tmp_path, fake_platform, MagicMock(), config)
with (
patch.dict("sys.modules", modules),
patch.object(
pf,
"_registry_jobs",
side_effect=[([], 0, platform_group), ([], 0, lib_group)],
),
patch.object(pf, "_uri_jobs", return_value=([], 0, [])),
patch.object(pf, "_preinstall", side_effect=lambda *_: order.append("install")),
):
pf._prefetch(tmp_path, "testenv")
assert order == expected
@pytest.mark.parametrize(
"err", [RuntimeError("idf_tools.py failed"), SystemExit("postinstall exited")]
)
def test_prefetch_settle_failure_warns_and_continues(
tmp_path: Path, caplog: pytest.LogCaptureFixture, err: BaseException
) -> None:
"""A failing second configure pass only costs the speedup."""
_write_ini(tmp_path, "[env:testenv]\nplatform = fake/p@1\n")
fake_platform = MagicMock()
fake_platform.packages = {}
fake_platform.configure_project_packages.side_effect = [None, err]
config = _fake_config(tmp_path, {"platform": "fake/p@1"})
modules = _pio_modules(tmp_path, fake_platform, MagicMock(), config)
with (
patch.dict("sys.modules", modules),
patch.object(
pf,
"_registry_jobs",
side_effect=[
([], 0, [("toolchain-x@1", _FakeSpec(name="toolchain-x"))]),
([], 0, []),
],
),
patch.object(pf, "_uri_jobs", return_value=([], 0, [])),
patch.object(pf, "_preinstall"),
):
pf._prefetch(tmp_path, "testenv")
assert f"Could not settle platform packages: {err}" in caplog.text
def test_preinstall_extracts_in_parallel_under_one_lock(tmp_path: Path) -> None:
"""The manager lock wraps the whole batch; per-thread managers share
its package dir; one failing install leaves the rest alone."""