mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'feat/bdl_ioctl_checker' into 'master'
feat(esp_blockdev): add build-time ioctl command reservation overlap checker Closes IDF-15799 See merge request espressif/esp-idf!49670
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
"""Build-system integration tests for the esp_blockdev ioctl overlap checker (cmakev2)."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from test_build_system_helpers import IdfPyFunc
|
||||
from test_build_system_helpers import replace_in_file
|
||||
|
||||
COMP_A_DEFS_NO_OVERLAP = """\
|
||||
#include "esp_blockdev.h"
|
||||
|
||||
ESP_BLOCKDEV_RESERVE_CMD_RANGE(comp_a, 0x10, 0x1F);
|
||||
"""
|
||||
|
||||
COMP_B_DEFS_NO_OVERLAP = """\
|
||||
#include "esp_blockdev.h"
|
||||
|
||||
ESP_BLOCKDEV_RESERVE_CMD_RANGE(comp_b, 0x20, 0x2F);
|
||||
"""
|
||||
|
||||
COMP_B_DEFS_OVERLAP = """\
|
||||
#include "esp_blockdev.h"
|
||||
|
||||
ESP_BLOCKDEV_RESERVE_CMD_RANGE(comp_b, 0x18, 0x2F);
|
||||
"""
|
||||
|
||||
COMPONENT_CMAKELISTS = """\
|
||||
idf_component_register()
|
||||
|
||||
idf_build_set_property(
|
||||
ESP_BLOCKDEV_IOCTL_DEF_FILES
|
||||
"${{CMAKE_CURRENT_LIST_DIR}}/include/{filename}"
|
||||
APPEND
|
||||
)
|
||||
"""
|
||||
|
||||
|
||||
def _add_component(app_path: Path, name: str, defs_content: str) -> None:
|
||||
comp_dir = app_path / 'components' / name
|
||||
comp_dir.mkdir(parents=True, exist_ok=True)
|
||||
include_dir = comp_dir / 'include'
|
||||
include_dir.mkdir(exist_ok=True)
|
||||
|
||||
filename = f'{name}_ioctl_defs.h'
|
||||
(include_dir / filename).write_text(defs_content)
|
||||
(comp_dir / 'CMakeLists.txt').write_text(COMPONENT_CMAKELISTS.format(filename=filename))
|
||||
|
||||
|
||||
def _wire_components(app_path: Path) -> None:
|
||||
replace_in_file(
|
||||
app_path / 'main' / 'CMakeLists.txt',
|
||||
'# placeholder_inside_idf_component_register',
|
||||
'REQUIRES esp_blockdev comp_a comp_b\n # placeholder_inside_idf_component_register',
|
||||
)
|
||||
|
||||
|
||||
def test_ioctl_overlap_checker_passes_clean_build_v2(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
"""Build succeeds when registered ioctl ranges do not overlap (cmakev2)."""
|
||||
_add_component(test_app_copy, 'comp_a', COMP_A_DEFS_NO_OVERLAP)
|
||||
_add_component(test_app_copy, 'comp_b', COMP_B_DEFS_NO_OVERLAP)
|
||||
_wire_components(test_app_copy)
|
||||
|
||||
ret = idf_py('build')
|
||||
assert ret.returncode == 0
|
||||
|
||||
|
||||
def test_ioctl_overlap_checker_fails_on_overlap_v2(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
"""Build fails when registered ioctl ranges overlap (cmakev2)."""
|
||||
_add_component(test_app_copy, 'comp_a', COMP_A_DEFS_NO_OVERLAP)
|
||||
_add_component(test_app_copy, 'comp_b', COMP_B_DEFS_OVERLAP)
|
||||
_wire_components(test_app_copy)
|
||||
|
||||
ret = idf_py('build', check=False)
|
||||
assert ret.returncode != 0
|
||||
output = ret.stdout + ret.stderr
|
||||
assert 'ioctl reservation overlap' in output
|
||||
assert 'comp_a' in output
|
||||
assert 'comp_b' in output
|
||||
@@ -0,0 +1,85 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
"""Build-system integration tests for the esp_blockdev ioctl overlap checker."""
|
||||
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from test_build_system_helpers import IdfPyFunc
|
||||
from test_build_system_helpers import replace_in_file
|
||||
|
||||
COMP_A_DEFS_NO_OVERLAP = """\
|
||||
#include "esp_blockdev.h"
|
||||
|
||||
ESP_BLOCKDEV_RESERVE_CMD_RANGE(comp_a, 0x10, 0x1F);
|
||||
"""
|
||||
|
||||
COMP_B_DEFS_NO_OVERLAP = """\
|
||||
#include "esp_blockdev.h"
|
||||
|
||||
ESP_BLOCKDEV_RESERVE_CMD_RANGE(comp_b, 0x20, 0x2F);
|
||||
"""
|
||||
|
||||
COMP_B_DEFS_OVERLAP = """\
|
||||
#include "esp_blockdev.h"
|
||||
|
||||
ESP_BLOCKDEV_RESERVE_CMD_RANGE(comp_b, 0x18, 0x2F);
|
||||
"""
|
||||
|
||||
COMPONENT_CMAKELISTS = """\
|
||||
idf_component_register()
|
||||
|
||||
idf_build_set_property(
|
||||
ESP_BLOCKDEV_IOCTL_DEF_FILES
|
||||
"${{CMAKE_CURRENT_LIST_DIR}}/include/{filename}"
|
||||
APPEND
|
||||
)
|
||||
"""
|
||||
|
||||
|
||||
def _add_component(app_path: Path, name: str, defs_content: str) -> None:
|
||||
comp_dir = app_path / 'components' / name
|
||||
comp_dir.mkdir(parents=True, exist_ok=True)
|
||||
include_dir = comp_dir / 'include'
|
||||
include_dir.mkdir(exist_ok=True)
|
||||
|
||||
filename = f'{name}_ioctl_defs.h'
|
||||
(include_dir / filename).write_text(defs_content)
|
||||
(comp_dir / 'CMakeLists.txt').write_text(COMPONENT_CMAKELISTS.format(filename=filename))
|
||||
|
||||
|
||||
def _wire_components(app_path: Path) -> None:
|
||||
replace_in_file(
|
||||
app_path / 'main' / 'CMakeLists.txt',
|
||||
'# placeholder_inside_idf_component_register',
|
||||
'REQUIRES esp_blockdev comp_a comp_b\n # placeholder_inside_idf_component_register',
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_ioctl_overlap_checker_passes_clean_build(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
"""Build succeeds when registered ioctl ranges do not overlap."""
|
||||
logging.info('Testing ioctl overlap checker with non-overlapping ranges')
|
||||
_add_component(test_app_copy, 'comp_a', COMP_A_DEFS_NO_OVERLAP)
|
||||
_add_component(test_app_copy, 'comp_b', COMP_B_DEFS_NO_OVERLAP)
|
||||
_wire_components(test_app_copy)
|
||||
|
||||
ret = idf_py('build')
|
||||
assert ret.returncode == 0
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_ioctl_overlap_checker_fails_on_overlap(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
"""Build fails when registered ioctl ranges overlap."""
|
||||
logging.info('Testing ioctl overlap checker detects overlapping ranges')
|
||||
_add_component(test_app_copy, 'comp_a', COMP_A_DEFS_NO_OVERLAP)
|
||||
_add_component(test_app_copy, 'comp_b', COMP_B_DEFS_OVERLAP)
|
||||
_wire_components(test_app_copy)
|
||||
|
||||
ret = idf_py('build', check=False)
|
||||
assert ret.returncode != 0
|
||||
output = ret.stdout + ret.stderr
|
||||
assert 'ioctl reservation overlap' in output
|
||||
assert 'comp_a' in output
|
||||
assert 'comp_b' in output
|
||||
Reference in New Issue
Block a user