Tools: Rewrite build system unit tests to python - cmake libraries and Kconfig

This commit is contained in:
Marek Fiala 2023-02-08 19:27:01 +01:00
parent 51772f4fb5
commit b4446e1748
9 changed files with 349 additions and 62 deletions

View File

@ -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 | |

View File

@ -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)

View File

@ -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'
]

View File

@ -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

View 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()

View File

@ -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)

View 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"')

View 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']])

View File

@ -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))