mirror of
https://github.com/esphome/esphome.git
synced 2026-09-28 15:30:21 +00:00
[ci] Compile esp8266 component tests with the native toolchain (#19740)
This commit is contained in:
+15
-14
@@ -193,9 +193,10 @@ jobs:
|
||||
needs:
|
||||
- common
|
||||
# PR-branch cache saves are invisible to other PRs, so dev pushes seed
|
||||
# the shared entry test-esp8266-native restores. Only dev: the composite
|
||||
# action saves nowhere else, so a beta/release push would download the
|
||||
# toolchain and discard it.
|
||||
# the shared entry the component matrix, the memory impact jobs and
|
||||
# test-esp8266-native restore. Only dev: the composite action saves
|
||||
# nowhere else, so a beta/release push would download the toolchain and
|
||||
# discard it.
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
@@ -1127,6 +1128,11 @@ jobs:
|
||||
uses: ./.github/actions/cache-sdk-nrf
|
||||
with:
|
||||
restore-only: true
|
||||
- name: Cache the native ESP8266 toolchain
|
||||
# Only batches whose test platforms include esp8266; never saves
|
||||
# here, it reuses the install the dev seed job cached.
|
||||
if: matrix.batch.needs_arduino8266
|
||||
uses: ./.github/actions/cache-arduino8266
|
||||
- name: Validate and compile components with intelligent grouping
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
@@ -1479,12 +1485,9 @@ jobs:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
cache-key: ${{ needs.common.outputs.cache-key }}
|
||||
|
||||
- name: Cache platformio
|
||||
if: steps.check-script.outputs.skip != 'true' && steps.check-tests.outputs.skip != 'true' && steps.cache-memory-analysis.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-memory-${{ fromJSON(needs.determine-jobs.outputs.memory_impact).platform }}-${{ hashFiles('platformio.ini') }}
|
||||
- name: Cache the native ESP8266 toolchain
|
||||
if: steps.check-script.outputs.skip != 'true' && steps.check-tests.outputs.skip != 'true' && steps.cache-memory-analysis.outputs.cache-hit != 'true' && fromJSON(needs.determine-jobs.outputs.memory_impact).needs_arduino8266
|
||||
uses: ./.github/actions/cache-arduino8266
|
||||
|
||||
- name: Build, compile, and analyze memory
|
||||
if: steps.check-script.outputs.skip != 'true' && steps.check-tests.outputs.skip != 'true' && steps.cache-memory-analysis.outputs.cache-hit != 'true'
|
||||
@@ -1569,11 +1572,9 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
cache-key: ${{ needs.common.outputs.cache-key }}
|
||||
- name: Cache platformio
|
||||
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-memory-${{ fromJSON(needs.determine-jobs.outputs.memory_impact).platform }}-${{ hashFiles('platformio.ini') }}
|
||||
- name: Cache the native ESP8266 toolchain
|
||||
if: fromJSON(needs.determine-jobs.outputs.memory_impact).needs_arduino8266
|
||||
uses: ./.github/actions/cache-arduino8266
|
||||
- name: Build, compile, and analyze memory
|
||||
id: extract
|
||||
run: |
|
||||
|
||||
@@ -724,11 +724,17 @@ def _esp8266_native_path_or_file_trigger(files: list[str]) -> bool:
|
||||
|
||||
|
||||
def esp8266_native_components_to_test(branch: str | None = None) -> list[str]:
|
||||
"""Subset of ``ESP8266_NATIVE_TEST_COMPONENTS`` the job needs to
|
||||
compile (same narrowing as ``esp32_platformio_components_to_test``)."""
|
||||
return _toolchain_components_to_test(
|
||||
branch, ESP8266_NATIVE_TEST_COMPONENTS, _esp8266_native_path_or_file_trigger
|
||||
)
|
||||
"""The smoke set on a native-build change, nothing otherwise.
|
||||
|
||||
Unlike the esp32 PlatformIO job, this one does not narrow to the changed
|
||||
components: the component matrix already compiles every esp8266 fixture
|
||||
with this toolchain, so the only gap left is a change to the native build
|
||||
itself that brings no component along.
|
||||
"""
|
||||
files = changed_files(branch)
|
||||
if core_changed(files) or _esp8266_native_path_or_file_trigger(files):
|
||||
return sorted(ESP8266_NATIVE_TEST_COMPONENTS)
|
||||
return []
|
||||
|
||||
|
||||
def determine_cpp_unit_tests(
|
||||
@@ -1286,6 +1292,7 @@ def detect_memory_impact_config(
|
||||
"components": compatible_components,
|
||||
"platform": platform,
|
||||
"use_merged_config": "true",
|
||||
"needs_arduino8266": platform.startswith("esp8266"),
|
||||
}
|
||||
|
||||
|
||||
@@ -1516,12 +1523,20 @@ def main() -> None:
|
||||
for batch in batches:
|
||||
platforms: set[str] = set()
|
||||
for component in batch:
|
||||
platforms.update(get_component_test_platforms(component))
|
||||
# Variants included: the compile stage builds them, so a
|
||||
# component tested only by test-<variant>.<platform>.yaml
|
||||
# still needs that platform's toolchain
|
||||
platforms.update(
|
||||
get_component_test_platforms(component, base_only=False)
|
||||
)
|
||||
component_test_batches.append(
|
||||
{
|
||||
"components": " ".join(batch),
|
||||
"needs_idf": any(p.startswith("esp32") for p in platforms),
|
||||
"needs_nrf": any(p.startswith("nrf52") for p in platforms),
|
||||
"needs_arduino8266": any(
|
||||
p.startswith("esp8266") for p in platforms
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -250,6 +250,82 @@ def test_main_all_tests_should_run(
|
||||
assert len(batch["components"]) > 0
|
||||
assert isinstance(batch["needs_idf"], bool)
|
||||
assert isinstance(batch["needs_nrf"], bool)
|
||||
assert isinstance(batch["needs_arduino8266"], bool)
|
||||
|
||||
|
||||
def test_main_batch_flags_count_variant_tests(
|
||||
mock_determine_integration_tests: Mock,
|
||||
mock_should_run_clang_tidy: Mock,
|
||||
mock_should_run_clang_format: Mock,
|
||||
mock_should_run_python_linters: Mock,
|
||||
mock_should_run_import_time: Mock,
|
||||
mock_should_run_device_builder: Mock,
|
||||
mock_esp32_platformio_components_to_test: Mock,
|
||||
mock_esp8266_native_components_to_test: Mock,
|
||||
mock_changed_files: Mock,
|
||||
mock_determine_cpp_unit_tests: Mock,
|
||||
capsys: pytest.CaptureFixture[str],
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""The compile stage builds test-<variant>.<platform>.yaml too, so a
|
||||
component tested on esp8266 only by a variant still needs the toolchain."""
|
||||
monkeypatch.delenv("GITHUB_ACTIONS", raising=False)
|
||||
mock_determine_integration_tests.return_value = (False, [])
|
||||
mock_should_run_clang_tidy.return_value = False
|
||||
mock_should_run_clang_format.return_value = False
|
||||
mock_should_run_python_linters.return_value = False
|
||||
mock_should_run_import_time.return_value = False
|
||||
mock_should_run_device_builder.return_value = False
|
||||
mock_esp32_platformio_components_to_test.return_value = []
|
||||
mock_esp8266_native_components_to_test.return_value = []
|
||||
mock_determine_cpp_unit_tests.return_value = (False, [])
|
||||
mock_changed_files.return_value = ["esphome/components/safe_mode/__init__.py"]
|
||||
|
||||
def platforms(component: str, *, base_only: bool = True) -> set[str]:
|
||||
return set() if base_only else {"esp8266-ard"}
|
||||
|
||||
with (
|
||||
patch("sys.argv", ["determine-jobs.py"]),
|
||||
patch.object(determine_jobs, "_is_clang_tidy_full_scan", return_value=False),
|
||||
patch.object(
|
||||
determine_jobs, "get_changed_components", return_value=["safe_mode"]
|
||||
),
|
||||
patch.object(
|
||||
determine_jobs,
|
||||
"filter_component_and_test_files",
|
||||
side_effect=lambda f: f.startswith("esphome/components/"),
|
||||
),
|
||||
patch.object(
|
||||
determine_jobs,
|
||||
"get_components_with_dependencies",
|
||||
return_value=["safe_mode"],
|
||||
),
|
||||
patch.object(determine_jobs, "_component_has_tests", return_value=True),
|
||||
patch.object(
|
||||
determine_jobs,
|
||||
"detect_memory_impact_config",
|
||||
return_value={"should_run": "false"},
|
||||
),
|
||||
patch.object(
|
||||
determine_jobs,
|
||||
"create_intelligent_batches",
|
||||
return_value=([["safe_mode"]], {}),
|
||||
),
|
||||
patch.object(
|
||||
determine_jobs, "get_component_test_platforms", side_effect=platforms
|
||||
),
|
||||
):
|
||||
determine_jobs.main()
|
||||
|
||||
output = json.loads(capsys.readouterr().out)
|
||||
assert output["component_test_batches"] == [
|
||||
{
|
||||
"components": "safe_mode",
|
||||
"needs_idf": False,
|
||||
"needs_nrf": False,
|
||||
"needs_arduino8266": True,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test_main_no_tests_should_run(
|
||||
@@ -1530,6 +1606,7 @@ def test_detect_memory_impact_config_with_common_platform(tmp_path: Path) -> Non
|
||||
assert set(result["components"]) == {"wifi", "api"}
|
||||
assert result["platform"] == "esp32-idf" # Common platform
|
||||
assert result["use_merged_config"] == "true"
|
||||
assert result["needs_arduino8266"] is False
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_target_branch_dev")
|
||||
@@ -1634,6 +1711,8 @@ def test_detect_memory_impact_config_no_common_platform(tmp_path: Path) -> None:
|
||||
assert result["platform"] == "esp8266-ard"
|
||||
assert result["components"] == ["logger"]
|
||||
assert result["use_merged_config"] == "true"
|
||||
# The esp8266 build is native, so the job restores that toolchain
|
||||
assert result["needs_arduino8266"] is True
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_target_branch_dev")
|
||||
@@ -3212,13 +3291,13 @@ def test_esp8266_native_components_full_list_on_infra_change(changed: str) -> No
|
||||
@pytest.mark.parametrize(
|
||||
("changed_files", "dependency_closure", "expected"),
|
||||
[
|
||||
# Tested component changed -- narrow to the intersection.
|
||||
# A tested component alone does not schedule this job: the component
|
||||
# matrix already compiles its esp8266 fixtures with this toolchain.
|
||||
(
|
||||
["esphome/components/mqtt/mqtt_client.cpp"],
|
||||
["mqtt", "json"],
|
||||
["mqtt"],
|
||||
[],
|
||||
),
|
||||
# Components outside the test set return an empty list (job skipped).
|
||||
(
|
||||
["esphome/components/wifi/wifi_component.cpp"],
|
||||
["wifi", "network"],
|
||||
@@ -3236,7 +3315,7 @@ def test_esp8266_native_components_to_test_narrowing(
|
||||
dependency_closure: list[str],
|
||||
expected: list[str],
|
||||
) -> None:
|
||||
"""Component changes narrow the native-ESP8266 test list."""
|
||||
"""Only a native-build change schedules the native-ESP8266 job."""
|
||||
with (
|
||||
patch.object(determine_jobs, "changed_files", return_value=changed_files),
|
||||
patch.object(
|
||||
|
||||
@@ -4,6 +4,7 @@ esphome:
|
||||
|
||||
esp8266:
|
||||
board: d1_mini_pro
|
||||
toolchain: arduino
|
||||
|
||||
logger:
|
||||
level: VERY_VERBOSE
|
||||
|
||||
Reference in New Issue
Block a user