mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Tools: Rewrite build system unit tests to python - cmake libraries and Kconfig
This commit is contained in:
parent
51772f4fb5
commit
b4446e1748
@ -47,20 +47,22 @@ Can guess target from sdkconfig, if CMakeCache does not exist | test_non_default
|
||||
Can set the default target using sdkconfig.defaults | test_non_default_target.py::test_target_using_sdkconfig |
|
||||
IDF_TARGET takes precedence over the value of CONFIG_IDF_TARGET in sdkconfig.defaults | test_non_default_target.py::test_target_precedence |
|
||||
idf.py fails if IDF_TARGET settings don't match in sdkconfig, CMakeCache.txt, and the environment | test_non_default_target.py::test_target_from_environment_idf_py |
|
||||
Setting EXTRA_COMPONENT_DIRS works | |
|
||||
Non-existent paths in EXTRA_COMPONENT_DIRS are not allowed | |
|
||||
Component names may contain spaces | |
|
||||
Setting EXTRA_COMPONENT_DIRS works | test_components.py::test_component_extra_dirs |
|
||||
Non-existent paths in EXTRA_COMPONENT_DIRS are not allowed | test_components.py::test_component_nonexistent_extra_dirs_not_allowed |
|
||||
Component names may contain spaces | test_components.py::test_component_names_contain_spaces |
|
||||
sdkconfig should have contents of all files: sdkconfig, sdkconfig.defaults, sdkconfig.defaults.IDF_TARGET | |
|
||||
Test if it can build the example to run on host | |
|
||||
Test build ESP-IDF as a library to a custom CMake projects for all targets | |
|
||||
Building a project with CMake library imported and PSRAM workaround, all files compile with workaround | |
|
||||
Test for external libraries in custom CMake projects with ESP-IDF components linked | |
|
||||
Test for external libraries in custom CMake projects with PSRAM strategy $strat | |
|
||||
Cleaning Python bytecode | |
|
||||
Displays partition table when executing target partition_table | |
|
||||
Make sure a full build never runs '/usr/bin/env python' or similar | |
|
||||
Handling deprecated Kconfig options | |
|
||||
Handling deprecated Kconfig options in sdkconfig.defaults | |
|
||||
Test build ESP-IDF as a library to a custom CMake projects for all targets | test_cmake.py::test_build_custom_cmake_project |
|
||||
Building a project with CMake library imported and PSRAM workaround, all files compile with workaround | test_cmake.py::test_build_cmake_library_psram_workaround |
|
||||
Test for external libraries in custom CMake projects with ESP-IDF components linked | test_cmake.py::test_build_custom_cmake_project |
|
||||
Test for external libraries in custom CMake projects with PSRAM strategy $strat | test_cmake.py::test_build_cmake_library_psram_strategies |
|
||||
Cleaning Python bytecode | test_common.py::test_python_clean |
|
||||
Displays partition table when executing target partition_table | test_common.py::test_partition_table |
|
||||
Make sure a full build never runs '/usr/bin/env python' or similar | test_common.py::test_python_interpreter_unix, test_common.py::test_python_interpreter_win |
|
||||
Handling deprecated Kconfig options | test_kconfig.py::test_kconfig_deprecated_options |
|
||||
Handling deprecated Kconfig options in sdkconfig.defaults | test_kconfig.py::test_kconfig_deprecated_options |
|
||||
Can have multiple deprecated Kconfig options map to a single new option | test_kconfig.py::test_kconfig_multiple_and_target_specific_options |
|
||||
Can have target specific deprecated Kconfig options | test_kconfig.py::test_kconfig_multiple_and_target_specific_options |
|
||||
Confserver can be invoked by idf.py | |
|
||||
Check ccache is used to build | |
|
||||
Custom bootloader overrides original | |
|
||||
|
@ -5,23 +5,12 @@ import logging
|
||||
import os
|
||||
import sys
|
||||
import textwrap
|
||||
import typing
|
||||
from pathlib import Path
|
||||
from typing import List, Union
|
||||
|
||||
import pytest
|
||||
from test_build_system_helpers import (APP_BINS, BOOTLOADER_BINS, PARTITION_BIN, EnvDict, IdfPyFunc, append_to_file,
|
||||
check_file_contains, get_idf_build_env, replace_in_file, run_cmake)
|
||||
|
||||
|
||||
def run_cmake_and_build(*cmake_args: str, env: typing.Optional[EnvDict] = None) -> None:
|
||||
"""
|
||||
Run cmake command with given arguments and build afterwards, raise an exception on failure
|
||||
:param cmake_args: arguments to pass cmake
|
||||
:param env: environment variables to run the cmake with; if not set, the default environment is used
|
||||
"""
|
||||
run_cmake(*cmake_args, env=env)
|
||||
run_cmake('--build', '.')
|
||||
from test_build_system_helpers import (APP_BINS, BOOTLOADER_BINS, PARTITION_BIN, IdfPyFunc, append_to_file,
|
||||
file_contains, get_idf_build_env, replace_in_file, run_cmake_and_build)
|
||||
|
||||
|
||||
def assert_built(paths: Union[List[str], List[Path]]) -> None:
|
||||
@ -65,7 +54,7 @@ def test_build_with_generator_ninja(idf_py: IdfPyFunc) -> None:
|
||||
idf_py('-G', 'Ninja', 'build')
|
||||
cmake_cache_file = Path('build', 'CMakeCache.txt')
|
||||
assert_built([cmake_cache_file])
|
||||
check_file_contains(cmake_cache_file, 'CMAKE_GENERATOR:INTERNAL=Ninja')
|
||||
assert file_contains(cmake_cache_file, 'CMAKE_GENERATOR:INTERNAL=Ninja')
|
||||
assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN)
|
||||
|
||||
|
||||
@ -76,7 +65,7 @@ def test_build_with_generator_makefile(idf_py: IdfPyFunc) -> None:
|
||||
idf_py('-G', 'Unix Makefiles', 'build')
|
||||
cmake_cache_file = Path('build', 'CMakeCache.txt')
|
||||
assert_built([cmake_cache_file])
|
||||
check_file_contains(cmake_cache_file, 'CMAKE_GENERATOR:INTERNAL=Unix Makefiles')
|
||||
assert file_contains(cmake_cache_file, 'CMAKE_GENERATOR:INTERNAL=Unix Makefiles')
|
||||
assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN)
|
||||
|
||||
|
||||
|
@ -2,12 +2,14 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
from .build_constants import ALL_ARTIFACTS, APP_BINS, BOOTLOADER_BINS, JSON_METADATA, PARTITION_BIN
|
||||
from .editing import append_to_file, replace_in_file
|
||||
from .idf_utils import EXT_IDF_PATH, EnvDict, IdfPyFunc, check_file_contains, get_idf_build_env, run_cmake, run_idf_py
|
||||
from .idf_utils import (EXT_IDF_PATH, EnvDict, IdfPyFunc, file_contains, find_python, get_idf_build_env, run_cmake,
|
||||
run_cmake_and_build, run_idf_py)
|
||||
from .snapshot import Snapshot, get_snapshot
|
||||
|
||||
__all__ = [
|
||||
'append_to_file', 'replace_in_file',
|
||||
'get_idf_build_env', 'run_idf_py', 'EXT_IDF_PATH', 'EnvDict', 'IdfPyFunc',
|
||||
'Snapshot', 'get_snapshot', 'run_cmake', 'APP_BINS', 'BOOTLOADER_BINS',
|
||||
'PARTITION_BIN', 'JSON_METADATA', 'ALL_ARTIFACTS', 'check_file_contains'
|
||||
'PARTITION_BIN', 'JSON_METADATA', 'ALL_ARTIFACTS',
|
||||
'run_cmake_and_build', 'find_python', 'file_contains'
|
||||
]
|
||||
|
@ -60,7 +60,8 @@ def run_idf_py(*args: str,
|
||||
env: typing.Optional[EnvDict] = None,
|
||||
idf_path: typing.Optional[typing.Union[str,Path]] = None,
|
||||
workdir: typing.Optional[str] = None,
|
||||
check: bool = True) -> subprocess.CompletedProcess:
|
||||
check: bool = True,
|
||||
python: typing.Optional[str] = None) -> subprocess.CompletedProcess:
|
||||
"""
|
||||
Run idf.py command with given arguments, raise an exception on failure
|
||||
:param args: arguments to pass to idf.py
|
||||
@ -68,6 +69,7 @@ def run_idf_py(*args: str,
|
||||
:param idf_path: path to the IDF copy to use; if not set, IDF_PATH from the 'env' argument is used
|
||||
:param workdir: directory where to run the build; if not set, the current directory is used
|
||||
:param check: check process exits with a zero exit code, if false all retvals are accepted without failing the test
|
||||
:param python: absolute path to python interpreter
|
||||
"""
|
||||
env_dict = dict(**os.environ)
|
||||
if env is not None:
|
||||
@ -79,8 +81,8 @@ def run_idf_py(*args: str,
|
||||
idf_path = env_dict.get('IDF_PATH')
|
||||
if not idf_path:
|
||||
raise ValueError('IDF_PATH must be set in the env array if idf_path argument is not set')
|
||||
|
||||
python = find_python(env_dict['PATH'])
|
||||
if python is None:
|
||||
python = find_python(env_dict['PATH'])
|
||||
|
||||
cmd = [
|
||||
python,
|
||||
@ -115,10 +117,25 @@ def run_cmake(*cmake_args: str, env: typing.Optional[EnvDict] = None,
|
||||
text=True, encoding='utf-8', errors='backslashreplace')
|
||||
|
||||
|
||||
def check_file_contains(filename: Union[str, Path], what: Union[str, Pattern]) -> None:
|
||||
def run_cmake_and_build(*cmake_args: str, env: typing.Optional[EnvDict] = None) -> None:
|
||||
"""
|
||||
Run cmake command with given arguments and build afterwards, raise an exception on failure
|
||||
:param cmake_args: arguments to pass cmake
|
||||
:param env: environment variables to run the cmake with; if not set, the default environment is used
|
||||
"""
|
||||
run_cmake(*cmake_args, env=env)
|
||||
run_cmake('--build', '.')
|
||||
|
||||
|
||||
def file_contains(filename: Union[str, Path], what: Union[str, Pattern]) -> bool:
|
||||
"""
|
||||
Returns true if file contains required object
|
||||
:param filename: path to file where lookup is executed
|
||||
:param what: searched substring or regex object
|
||||
"""
|
||||
with open(filename, 'r', encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
if isinstance(what, str):
|
||||
assert what in data
|
||||
return what in data
|
||||
else:
|
||||
assert re.search(what, data) is not None
|
||||
return re.search(what, data) is not None
|
||||
|
49
tools/test_build_system/test_cmake.py
Normal file
49
tools/test_build_system/test_cmake.py
Normal file
@ -0,0 +1,49 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from test_build_system_helpers import IdfPyFunc, file_contains, run_cmake, run_cmake_and_build
|
||||
|
||||
|
||||
def test_build_custom_cmake_project(test_app_copy: Path) -> None:
|
||||
for target in ['esp32', 'esp32s3', 'esp32c6', 'esp32h4']:
|
||||
logging.info(f'Test build ESP-IDF as a library to a custom CMake projects for {target}')
|
||||
idf_path = Path(os.environ['IDF_PATH'])
|
||||
run_cmake_and_build(str(idf_path / 'examples' / 'build_system' / 'cmake' / 'idf_as_lib'),
|
||||
'-DCMAKE_TOOLCHAIN_FILE={}'.format(idf_path / 'tools' / 'cmake' / f'toolchain-{target}.cmake'), f'-DTARGET={target}')
|
||||
assert file_contains((test_app_copy / 'build' / 'compile_commands.json'), '"command"')
|
||||
shutil.rmtree(test_app_copy / 'build')
|
||||
|
||||
|
||||
def test_build_cmake_library_psram_workaround(test_app_copy: Path) -> None:
|
||||
logging.info('Building a project with CMake library imported and PSRAM workaround, all files compile with workaround')
|
||||
idf_path = Path(os.environ['IDF_PATH'])
|
||||
(test_app_copy / 'sdkconfig.defaults').write_text('\n'.join(['CONFIG_SPIRAM=y',
|
||||
'CONFIG_SPIRAM_CACHE_WORKAROUND=y']))
|
||||
run_cmake('-G', 'Ninja', '-DSDKCONFIG_DEFAULTS={}'.format(test_app_copy / 'sdkconfig.defaults'),
|
||||
str(idf_path / 'examples' / 'build_system' / 'cmake' / 'import_lib'))
|
||||
with open((test_app_copy / 'build' / 'compile_commands.json'), 'r', encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
res = re.findall(r'.*\"command\".*', data)
|
||||
for r in res:
|
||||
assert 'mfix-esp32-psram-cache-issue' in r, 'All commands in compile_commands.json should use PSRAM cache workaround'
|
||||
|
||||
|
||||
def test_build_cmake_library_psram_strategies(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
for strategy in ['DUPLDST', 'NOPS', 'MEMW']:
|
||||
logging.info(f'Test for external libraries in custom CMake projects with PSRAM strategy {strategy}')
|
||||
(test_app_copy / 'sdkconfig.defaults').write_text('\n'.join(['CONFIG_SPIRAM=y',
|
||||
f'CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_{strategy}=y',
|
||||
'CONFIG_SPIRAM_CACHE_WORKAROUND=y']))
|
||||
idf_py('reconfigure')
|
||||
with open((test_app_copy / 'build' / 'compile_commands.json'), 'r', encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
res = re.findall(r'.*\"command\".*', data)
|
||||
for r in res:
|
||||
assert f'mfix-esp32-psram-cache-strategy={strategy.lower()}' in r, ('All commands in compile_commands.json '
|
||||
'should use PSRAM cache workaround strategy')
|
||||
(test_app_copy / 'sdkconfig').unlink()
|
@ -1,12 +1,30 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
import pytest
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
from test_build_system_helpers import IdfPyFunc, get_snapshot, replace_in_file
|
||||
from test_build_system_helpers import IdfPyFunc, find_python, get_snapshot, replace_in_file, run_idf_py
|
||||
|
||||
|
||||
def get_subdirs_absolute_paths(path: Path) -> List[str]:
|
||||
"""
|
||||
Get a list of files with absolute path in a given `path` folder
|
||||
"""
|
||||
return [
|
||||
'{}/{}'.format(dir_path, file_name)
|
||||
for dir_path, _, file_names in os.walk(path)
|
||||
for file_name in file_names
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
@ -88,3 +106,55 @@ def test_efuse_symmary_cmake_functions(
|
||||
def test_custom_build_folder(test_app_copy: Path, idf_py: IdfPyFunc) -> None:
|
||||
idf_py('-BBuiLDdiR', 'build')
|
||||
assert (test_app_copy / 'BuiLDdiR').is_dir()
|
||||
|
||||
|
||||
def test_python_clean(idf_py: IdfPyFunc) -> None:
|
||||
logging.info('Cleaning Python bytecode')
|
||||
idf_path = Path(os.environ['IDF_PATH'])
|
||||
abs_paths = get_subdirs_absolute_paths(idf_path)
|
||||
abs_paths_suffix = [path for path in abs_paths if path.endswith(('.pyc', '.pyo'))]
|
||||
assert len(abs_paths_suffix) != 0
|
||||
idf_py('python-clean')
|
||||
abs_paths = get_subdirs_absolute_paths(idf_path)
|
||||
abs_paths_suffix = [path for path in abs_paths if path.endswith(('.pyc', '.pyo'))]
|
||||
assert len(abs_paths_suffix) == 0
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_partition_table(idf_py: IdfPyFunc) -> None:
|
||||
logging.info('Displays partition table when executing target partition_table')
|
||||
output = idf_py('partition-table')
|
||||
assert re.search('# ESP-IDF.+Partition Table', output.stdout)
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.platform == 'win32', reason='Windows does not support executing bash script')
|
||||
def test_python_interpreter_unix(test_app_copy: Path) -> None:
|
||||
logging.info("Make sure idf.py never runs '/usr/bin/env python' or similar")
|
||||
env_dict = dict(**os.environ)
|
||||
python = find_python(env_dict['PATH'])
|
||||
(test_app_copy / 'python').write_text(textwrap.dedent("""#!/bin/sh
|
||||
echo "idf.py has executed '/usr/bin/env python' or similar"
|
||||
exit 1
|
||||
"""))
|
||||
st = os.stat(test_app_copy / 'python')
|
||||
# equivalent to 'chmod +x ./python'
|
||||
os.chmod((test_app_copy / 'python'), st.st_mode | stat.S_IEXEC)
|
||||
|
||||
env_dict['PATH'] = str(test_app_copy) + os.pathsep + env_dict['PATH']
|
||||
# python is loaded from env:$PATH, but since false interpreter is provided there, python needs to be specified as argument
|
||||
# if idf.py is reconfigured during it's execution, it would load a false interpreter
|
||||
run_idf_py('reconfigure', env=env_dict, python=python)
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.platform != 'win32', reason='Linux does not support executing .exe files')
|
||||
def test_python_interpreter_win(test_app_copy: Path) -> None:
|
||||
logging.info('Make sure idf.py never runs false python interpreter')
|
||||
env_dict = dict(**os.environ)
|
||||
python = find_python(env_dict['PATH'])
|
||||
|
||||
# on windows python interpreter has compiled code '.exe' format, so this false file can be empty
|
||||
(test_app_copy / 'python.exe').write_text('')
|
||||
env_dict['PATH'] = str(test_app_copy) + os.pathsep + env_dict['PATH']
|
||||
# python is loaded from env:$PATH, but since false interpreter is provided there, python needs to be specified as argument
|
||||
# if idf.py is reconfigured during it's execution, it would load a false interpreter
|
||||
run_idf_py('reconfigure', env=env_dict, python=python)
|
||||
|
32
tools/test_build_system/test_components.py
Normal file
32
tools/test_build_system/test_components.py
Normal file
@ -0,0 +1,32 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import logging
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from test_build_system_helpers import IdfPyFunc, replace_in_file
|
||||
|
||||
|
||||
def test_component_extra_dirs(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
logging.info('Setting EXTRA_COMPONENT_DIRS works')
|
||||
shutil.move(test_app_copy / 'main', test_app_copy / 'different_main' / 'main')
|
||||
replace_in_file((test_app_copy / 'CMakeLists.txt'), '# placeholder_before_include_project_cmake',
|
||||
'set(EXTRA_COMPONENT_DIRS {})'.format(Path('different_main', 'main')))
|
||||
ret = idf_py('reconfigure')
|
||||
assert str(test_app_copy / 'different_main' / 'main') in ret.stdout
|
||||
assert str(test_app_copy / 'main') not in ret.stdout
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_component_nonexistent_extra_dirs_not_allowed(idf_py: IdfPyFunc) -> None:
|
||||
ret = idf_py('reconfigure', '-DEXTRA_COMPONENT_DIRS="nonexistent_dir"', check=False)
|
||||
assert ret.returncode != 0
|
||||
|
||||
|
||||
def test_component_names_contain_spaces(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
logging.info('Component names may contain spaces')
|
||||
(test_app_copy / 'extra component').mkdir()
|
||||
(test_app_copy / 'extra component' / 'CMakeLists.txt').write_text('idf_component_register')
|
||||
idf_py('-DEXTRA_COMPONENT_DIRS="extra component;main"')
|
126
tools/test_build_system/test_kconfig.py
Normal file
126
tools/test_build_system/test_kconfig.py
Normal file
@ -0,0 +1,126 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import textwrap
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from typing import Iterator
|
||||
|
||||
import pytest
|
||||
from test_build_system_helpers import IdfPyFunc, append_to_file, file_contains
|
||||
|
||||
|
||||
@contextmanager
|
||||
def backup_required_files(test_app_copy: Path) -> Iterator[None]:
|
||||
idf_path = Path(os.environ['IDF_PATH'])
|
||||
|
||||
sdk_rename_backup = (idf_path / 'sdkconfig.rename').read_text()
|
||||
kconfig_backup = (idf_path / 'Kconfig').read_text()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
(idf_path / 'sdkconfig.rename').write_text(sdk_rename_backup)
|
||||
(idf_path / 'Kconfig').write_text(kconfig_backup)
|
||||
shutil.rmtree(test_app_copy / 'build', ignore_errors=True)
|
||||
if (test_app_copy / 'sdkconfig').exists():
|
||||
(test_app_copy / 'sdkconfig').unlink()
|
||||
|
||||
|
||||
# For this and the following test function, there are actually two logical
|
||||
# tests in one test function. It would be better to have every check in a separate
|
||||
# test case, but that would mean doing idf_copy each time, and copying takes most of the time
|
||||
@pytest.mark.usefixtures('idf_copy')
|
||||
def test_kconfig_deprecated_options(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
idf_path = Path(os.environ['IDF_PATH'])
|
||||
|
||||
with backup_required_files(test_app_copy):
|
||||
logging.info('Handling deprecated Kconfig options')
|
||||
(idf_path / 'sdkconfig.rename').write_text('')
|
||||
idf_py('reconfigure')
|
||||
append_to_file((test_app_copy / 'sdkconfig'), 'CONFIG_TEST_OLD_OPTION=y')
|
||||
(idf_path / 'sdkconfig.rename').write_text('CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION')
|
||||
append_to_file((idf_path / 'Kconfig'), textwrap.dedent("""
|
||||
menu "test"
|
||||
config TEST_NEW_OPTION
|
||||
bool "test"
|
||||
default "n"
|
||||
help
|
||||
TEST_NEW_OPTION description
|
||||
endmenu
|
||||
"""))
|
||||
idf_py('reconfigure')
|
||||
assert all([file_contains((test_app_copy / 'sdkconfig'), x) for x in ['CONFIG_TEST_OLD_OPTION=y',
|
||||
'CONFIG_TEST_NEW_OPTION=y']])
|
||||
assert all([file_contains((test_app_copy / 'build' / 'config' / 'sdkconfig.h'), x) for x in ['#define CONFIG_TEST_NEW_OPTION 1',
|
||||
'#define CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION']])
|
||||
assert all([file_contains((test_app_copy / 'build' / 'config' / 'sdkconfig.cmake'), x) for x in ['set(CONFIG_TEST_OLD_OPTION "y")',
|
||||
'set(CONFIG_TEST_NEW_OPTION "y")']])
|
||||
|
||||
logging.info('Handling deprecated Kconfig options in sdkconfig.defaults')
|
||||
(test_app_copy / 'sdkconfig.defaults').write_text('CONFIG_TEST_OLD_OPTION=7')
|
||||
(idf_path / 'sdkconfig.rename').write_text('CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION')
|
||||
append_to_file((idf_path / 'Kconfig'), textwrap.dedent("""
|
||||
menu "test"
|
||||
config TEST_NEW_OPTION
|
||||
int "TEST_NEW_OPTION"
|
||||
range 0 10
|
||||
default 5
|
||||
help
|
||||
TEST_NEW_OPTION description
|
||||
endmenu
|
||||
"""))
|
||||
idf_py('reconfigure')
|
||||
assert all([file_contains((test_app_copy / 'sdkconfig'), x) for x in ['CONFIG_TEST_OLD_OPTION=7',
|
||||
'CONFIG_TEST_NEW_OPTION=7']])
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('idf_copy')
|
||||
def test_kconfig_multiple_and_target_specific_options(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
idf_path = Path(os.environ['IDF_PATH'])
|
||||
|
||||
with backup_required_files(test_app_copy):
|
||||
logging.info('Can have multiple deprecated Kconfig options map to a single new option')
|
||||
(idf_path / 'sdkconfig.rename').write_text('')
|
||||
idf_py('reconfigure')
|
||||
append_to_file((test_app_copy / 'sdkconfig'), 'CONFIG_TEST_NEW_OPTION=y')
|
||||
append_to_file((idf_path / 'sdkconfig.rename'), '\n'.join(['CONFIG_TEST_OLD_OPTION_1 CONFIG_TEST_NEW_OPTION',
|
||||
'CONFIG_TEST_OLD_OPTION_2 CONFIG_TEST_NEW_OPTION']))
|
||||
append_to_file((idf_path / 'Kconfig'), textwrap.dedent("""
|
||||
menu "test"
|
||||
config TEST_NEW_OPTION
|
||||
bool "test"
|
||||
default "n"
|
||||
help
|
||||
TEST_NEW_OPTION description
|
||||
endmenu
|
||||
"""))
|
||||
idf_py('reconfigure')
|
||||
assert all([file_contains((test_app_copy / 'sdkconfig'), x) for x in ['CONFIG_TEST_OLD_OPTION_1=y',
|
||||
'CONFIG_TEST_OLD_OPTION_2=y']])
|
||||
assert all([file_contains((test_app_copy / 'build' / 'config' / 'sdkconfig.h'), x) for x in ['#define CONFIG_TEST_OLD_OPTION_1 CONFIG_TEST_NEW_OPTION',
|
||||
'#define CONFIG_TEST_OLD_OPTION_2 CONFIG_TEST_NEW_OPTION'
|
||||
]])
|
||||
assert all([file_contains((test_app_copy / 'build' / 'config' / 'sdkconfig.cmake'), x) for x in ['set(CONFIG_TEST_OLD_OPTION_1 "y")',
|
||||
'set(CONFIG_TEST_OLD_OPTION_2 "y")']])
|
||||
|
||||
logging.info('Can have target specific deprecated Kconfig options')
|
||||
(test_app_copy / 'sdkconfig').write_text('CONFIG_TEST_OLD_OPTION=y')
|
||||
append_to_file((idf_path / 'components' / 'esp_system' / 'sdkconfig.rename.esp32s2'), 'CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION')
|
||||
append_to_file((idf_path / 'Kconfig'), textwrap.dedent("""
|
||||
menu "test"
|
||||
config TEST_NEW_OPTION
|
||||
bool "TEST_NEW_OPTION"
|
||||
default y
|
||||
help
|
||||
TEST_NEW_OPTION description
|
||||
endmenu
|
||||
"""))
|
||||
idf_py('set-target', 'esp32')
|
||||
assert not file_contains((test_app_copy / 'sdkconfig'), 'CONFIG_TEST_OLD_OPTION=y')
|
||||
assert file_contains((test_app_copy / 'sdkconfig'), 'CONFIG_TEST_NEW_OPTION=y')
|
||||
(test_app_copy / 'sdkconfig').unlink()
|
||||
idf_py('set-target', 'esp32s2')
|
||||
assert all([file_contains((test_app_copy / 'sdkconfig'), x) for x in ['CONFIG_TEST_NEW_OPTION=y',
|
||||
'CONFIG_TEST_OLD_OPTION=y']])
|
@ -7,7 +7,7 @@ from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
import pytest
|
||||
from test_build_system_helpers import EnvDict, IdfPyFunc, check_file_contains, run_cmake
|
||||
from test_build_system_helpers import EnvDict, IdfPyFunc, file_contains, run_cmake
|
||||
|
||||
ESP32C3_TARGET = 'esp32c3'
|
||||
ESP32C2_TARGET = 'esp32c2'
|
||||
@ -27,8 +27,8 @@ def test_target_from_environment_cmake(default_idf_env: EnvDict) -> None:
|
||||
env = default_idf_env
|
||||
env.update({'IDF_TARGET': ESP32S2_TARGET})
|
||||
run_cmake('-G', 'Ninja', '..', env=env)
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
|
||||
|
||||
def test_target_from_environment_idf_py(idf_py: IdfPyFunc, default_idf_env: EnvDict, test_app_copy: Path) -> None:
|
||||
@ -113,52 +113,52 @@ def test_target_precedence(idf_py: IdfPyFunc, default_idf_env: EnvDict, test_app
|
||||
(test_app_copy / 'sdkconfig.defaults').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
default_idf_env.update({'IDF_TARGET': ESP32_TARGET})
|
||||
idf_py('reconfigure')
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET_{}=y'.format(ESP32_TARGET.upper()))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET_{}=y'.format(ESP32_TARGET.upper()))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32_TARGET))
|
||||
|
||||
|
||||
def test_target_using_D_parameter(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
logging.info('Can set target using idf.py -D')
|
||||
idf_py('-DIDF_TARGET={}'.format(ESP32S2_TARGET), 'reconfigure')
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
|
||||
logging.info('Can set target using -D as subcommand parameter for idf.py')
|
||||
clean_app(test_app_copy)
|
||||
idf_py('reconfigure', '-DIDF_TARGET={}'.format(ESP32S2_TARGET))
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_target_using_settarget_parameter_alternative_name(idf_py: IdfPyFunc) -> None:
|
||||
logging.info('idf.py understands alternative target names')
|
||||
idf_py('set-target', ESP32S2_TARGET.upper())
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_target_using_settarget_parameter(idf_py: IdfPyFunc) -> None:
|
||||
logging.info('Can set target using idf.py set-target')
|
||||
idf_py('set-target', ESP32S2_TARGET)
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
|
||||
logging.info('Can guess target from sdkconfig, if CMakeCache does not exist')
|
||||
idf_py('fullclean')
|
||||
idf_py('reconfigure')
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
|
||||
|
||||
def test_target_using_sdkconfig(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
logging.info('Can set the default target using sdkconfig.defaults')
|
||||
(test_app_copy / 'sdkconfig.defaults').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
idf_py('reconfigure')
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET_{}=y'.format(ESP32S2_TARGET.upper()))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET_{}=y'.format(ESP32S2_TARGET.upper()))
|
||||
|
||||
|
||||
def test_target_guessing(idf_py: IdfPyFunc, test_app_copy: Path, default_idf_env: EnvDict) -> None:
|
||||
@ -171,8 +171,8 @@ def test_target_guessing(idf_py: IdfPyFunc, test_app_copy: Path, default_idf_env
|
||||
logging.info('Can guess target from sdkconfig.defaults')
|
||||
(test_app_copy / 'sdkconfig.defaults').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
|
||||
idf_py('reconfigure')
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32_TARGET))
|
||||
|
||||
logging.info('Can guess target from SDKCONFIG_DEFAULTS environment variable')
|
||||
(test_app_copy / 'sdkconfig1').write_text('NOTHING HERE')
|
||||
@ -180,20 +180,20 @@ def test_target_guessing(idf_py: IdfPyFunc, test_app_copy: Path, default_idf_env
|
||||
clean_app(test_app_copy)
|
||||
default_idf_env.update({'SDKCONFIG_DEFAULTS': 'sdkconfig1;sdkconfig2'})
|
||||
idf_py('reconfigure')
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
|
||||
|
||||
logging.info('Can guess target from SDKCONFIG_DEFAULTS using -D')
|
||||
(test_app_copy / 'sdkconfig3').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
|
||||
(test_app_copy / 'sdkconfig4').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S3_TARGET))
|
||||
clean_app(test_app_copy)
|
||||
idf_py('-D', 'SDKCONFIG_DEFAULTS=sdkconfig4;sdkconfig3', 'reconfigure')
|
||||
check_file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S3_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S3_TARGET))
|
||||
assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S3_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S3_TARGET))
|
||||
|
||||
logging.info('Can guess target from custom sdkconfig')
|
||||
(test_app_copy / 'sdkconfig5').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32C3_TARGET))
|
||||
clean_app(test_app_copy)
|
||||
idf_py('-D', 'SDKCONFIG=sdkconfig5', '-D', 'SDKCONFIG_DEFAULTS=sdkconfig4;sdkconfig3', 'reconfigure')
|
||||
check_file_contains('sdkconfig5', 'CONFIG_IDF_TARGET="{}"'.format(ESP32C3_TARGET))
|
||||
check_file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32C3_TARGET))
|
||||
assert file_contains('sdkconfig5', 'CONFIG_IDF_TARGET="{}"'.format(ESP32C3_TARGET))
|
||||
assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32C3_TARGET))
|
||||
|
Loading…
Reference in New Issue
Block a user