esp-idf/tools/test_build_system/test_non_default_target.py

164 lines
8.7 KiB
Python
Raw Normal View History

# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import shutil
from pathlib import Path
from typing import List, Optional
import pytest
from test_build_system_helpers import EnvDict, IdfPyFunc, check_file_contains, run_cmake
tools: move target guessing into cmake The _guess_or_check_idf_target() function has sdkconfig and sdkconfig.defaults file names hardcoded. Since config file names may be specified with SDKCONFIG or SDKCONFIG_DEFAULTS cmake vars, directly in CMakeLists.txt or passed in with the -D cmake option, they are not respected. Problem is when SDKCONFIG or SDKCONFIG_DEFAULTS is set in CMakeLists.txt. While idf can detect cmake vars passed through it to cmake via the -D option, detecting SDKCONFIG and SDKCONFIG_DEFAULTS vars settings in CMakeLists.txt would require to parse it. This seems like error prone approach. Also if the vars defined by the -D option are passed directly to cmake, not via idf, they will not be visible to idf. It seems reasonable to move the logic into cmake, where we know the correct SDKCONFIG and SDKCONFIG_DEFAULTS values. So the IDF_TARGET detection/guessing is moved into targets.cmake, where the IDF_TARGET is actually set. The target is guessed based on the following precendence. 1) $ENV{IDF_TARGET} 2) IDF_TARGET 3) SDKCONFIG 4) sdkconfig 5) SDKCONFIG_DEFAULTS if non-empty or $ENV{SDKCONFIG_DEFAULTS} if non-empty or sdkconfig.defaults 6) esp32 All config files referred in $ENV{SDKCONFIG_DEFAULTS} and SDKCONFIG_DEFAULTS are searched, compared to the current behaviour. First target found in the above chain is used. The original _guess_or_check_idf_target() is renamed to _check_idf_target() and used for the target consistency checks only. The get_sdkconfig_filename() helper is now used to get the sdkconfig file for consistency checks. It looks in SDKCONFIG specified with the -D option and project_description.json. With this change config full paths are reported in messages, so it's clear e.g. from which config the target was guessed from or which config has consistency problem. test_non_default_target.py was adjusted to this change and also new test for testing the IDF_TARGET guessing was added. Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-02-23 04:56:06 -05:00
ESP32C3_TARGET = 'esp32c3'
ESP32C2_TARGET = 'esp32c2'
ESP32S3_TARGET = 'esp32s3'
ESP32S2_TARGET = 'esp32s2'
ESP32_TARGET = 'esp32'
def clean_app(test_app_copy: Path) -> None:
shutil.rmtree(test_app_copy / 'build')
(test_app_copy / 'sdkconfig').unlink()
@pytest.mark.usefixtures('test_app_copy')
def test_target_from_environment_cmake(default_idf_env: EnvDict) -> None:
logging.info('Can override IDF_TARGET from environment')
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))
def test_target_from_environment_idf_py(idf_py: IdfPyFunc, default_idf_env: EnvDict, test_app_copy: Path) -> None:
def reconfigure_and_check_return_values(errmsg: str, opts: Optional[List[str]] = None) -> None:
opts = opts or []
ret = idf_py(*opts, 'reconfigure', check=False)
assert ret.returncode == 2
assert errmsg in ret.stderr
idf_py('set-target', ESP32S2_TARGET)
default_idf_env.update({'IDF_TARGET': ESP32_TARGET})
cfg_path = (test_app_copy / 'sdkconfig')
tools: move target guessing into cmake The _guess_or_check_idf_target() function has sdkconfig and sdkconfig.defaults file names hardcoded. Since config file names may be specified with SDKCONFIG or SDKCONFIG_DEFAULTS cmake vars, directly in CMakeLists.txt or passed in with the -D cmake option, they are not respected. Problem is when SDKCONFIG or SDKCONFIG_DEFAULTS is set in CMakeLists.txt. While idf can detect cmake vars passed through it to cmake via the -D option, detecting SDKCONFIG and SDKCONFIG_DEFAULTS vars settings in CMakeLists.txt would require to parse it. This seems like error prone approach. Also if the vars defined by the -D option are passed directly to cmake, not via idf, they will not be visible to idf. It seems reasonable to move the logic into cmake, where we know the correct SDKCONFIG and SDKCONFIG_DEFAULTS values. So the IDF_TARGET detection/guessing is moved into targets.cmake, where the IDF_TARGET is actually set. The target is guessed based on the following precendence. 1) $ENV{IDF_TARGET} 2) IDF_TARGET 3) SDKCONFIG 4) sdkconfig 5) SDKCONFIG_DEFAULTS if non-empty or $ENV{SDKCONFIG_DEFAULTS} if non-empty or sdkconfig.defaults 6) esp32 All config files referred in $ENV{SDKCONFIG_DEFAULTS} and SDKCONFIG_DEFAULTS are searched, compared to the current behaviour. First target found in the above chain is used. The original _guess_or_check_idf_target() is renamed to _check_idf_target() and used for the target consistency checks only. The get_sdkconfig_filename() helper is now used to get the sdkconfig file for consistency checks. It looks in SDKCONFIG specified with the -D option and project_description.json. With this change config full paths are reported in messages, so it's clear e.g. from which config the target was guessed from or which config has consistency problem. test_non_default_target.py was adjusted to this change and also new test for testing the IDF_TARGET guessing was added. Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-02-23 04:56:06 -05:00
logging.info("idf.py fails if IDF_TARGET settings don't match the environment")
tools: move target guessing into cmake The _guess_or_check_idf_target() function has sdkconfig and sdkconfig.defaults file names hardcoded. Since config file names may be specified with SDKCONFIG or SDKCONFIG_DEFAULTS cmake vars, directly in CMakeLists.txt or passed in with the -D cmake option, they are not respected. Problem is when SDKCONFIG or SDKCONFIG_DEFAULTS is set in CMakeLists.txt. While idf can detect cmake vars passed through it to cmake via the -D option, detecting SDKCONFIG and SDKCONFIG_DEFAULTS vars settings in CMakeLists.txt would require to parse it. This seems like error prone approach. Also if the vars defined by the -D option are passed directly to cmake, not via idf, they will not be visible to idf. It seems reasonable to move the logic into cmake, where we know the correct SDKCONFIG and SDKCONFIG_DEFAULTS values. So the IDF_TARGET detection/guessing is moved into targets.cmake, where the IDF_TARGET is actually set. The target is guessed based on the following precendence. 1) $ENV{IDF_TARGET} 2) IDF_TARGET 3) SDKCONFIG 4) sdkconfig 5) SDKCONFIG_DEFAULTS if non-empty or $ENV{SDKCONFIG_DEFAULTS} if non-empty or sdkconfig.defaults 6) esp32 All config files referred in $ENV{SDKCONFIG_DEFAULTS} and SDKCONFIG_DEFAULTS are searched, compared to the current behaviour. First target found in the above chain is used. The original _guess_or_check_idf_target() is renamed to _check_idf_target() and used for the target consistency checks only. The get_sdkconfig_filename() helper is now used to get the sdkconfig file for consistency checks. It looks in SDKCONFIG specified with the -D option and project_description.json. With this change config full paths are reported in messages, so it's clear e.g. from which config the target was guessed from or which config has consistency problem. test_non_default_target.py was adjusted to this change and also new test for testing the IDF_TARGET guessing was added. Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-02-23 04:56:06 -05:00
reconfigure_and_check_return_values("Project sdkconfig '{}' was generated for target '{}', but environment "
"variable IDF_TARGET is set to '{}'.".format(cfg_path, ESP32S2_TARGET,
ESP32_TARGET))
logging.info("idf.py fails if IDF_TARGET settings in CMakeCache.txt don't match the environment")
(test_app_copy / 'sdkconfig').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
reconfigure_and_check_return_values("Target settings are not consistent: '{}' in the environment, "
"'{}' in CMakeCache.txt.".format(ESP32_TARGET, ESP32S2_TARGET))
logging.info("idf.py fails if IDF_TARGET settings in CMakeCache.txt don't match the sdkconfig")
default_idf_env.pop('IDF_TARGET')
tools: move target guessing into cmake The _guess_or_check_idf_target() function has sdkconfig and sdkconfig.defaults file names hardcoded. Since config file names may be specified with SDKCONFIG or SDKCONFIG_DEFAULTS cmake vars, directly in CMakeLists.txt or passed in with the -D cmake option, they are not respected. Problem is when SDKCONFIG or SDKCONFIG_DEFAULTS is set in CMakeLists.txt. While idf can detect cmake vars passed through it to cmake via the -D option, detecting SDKCONFIG and SDKCONFIG_DEFAULTS vars settings in CMakeLists.txt would require to parse it. This seems like error prone approach. Also if the vars defined by the -D option are passed directly to cmake, not via idf, they will not be visible to idf. It seems reasonable to move the logic into cmake, where we know the correct SDKCONFIG and SDKCONFIG_DEFAULTS values. So the IDF_TARGET detection/guessing is moved into targets.cmake, where the IDF_TARGET is actually set. The target is guessed based on the following precendence. 1) $ENV{IDF_TARGET} 2) IDF_TARGET 3) SDKCONFIG 4) sdkconfig 5) SDKCONFIG_DEFAULTS if non-empty or $ENV{SDKCONFIG_DEFAULTS} if non-empty or sdkconfig.defaults 6) esp32 All config files referred in $ENV{SDKCONFIG_DEFAULTS} and SDKCONFIG_DEFAULTS are searched, compared to the current behaviour. First target found in the above chain is used. The original _guess_or_check_idf_target() is renamed to _check_idf_target() and used for the target consistency checks only. The get_sdkconfig_filename() helper is now used to get the sdkconfig file for consistency checks. It looks in SDKCONFIG specified with the -D option and project_description.json. With this change config full paths are reported in messages, so it's clear e.g. from which config the target was guessed from or which config has consistency problem. test_non_default_target.py was adjusted to this change and also new test for testing the IDF_TARGET guessing was added. Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-02-23 04:56:06 -05:00
reconfigure_and_check_return_values("Project sdkconfig '{}' was generated for target '{}', but CMakeCache.txt "
"contains '{}'.".format(cfg_path, ESP32_TARGET, ESP32S2_TARGET))
logging.info('idf.py fails if IDF_TARGET is set differently in environment and with -D option')
(test_app_copy / 'sdkconfig').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
default_idf_env.update({'IDF_TARGET': ESP32S2_TARGET})
reconfigure_and_check_return_values("Target '{}' specified on command line is not consistent with target '{}' "
'in the environment.'.format(ESP32_TARGET, ESP32S2_TARGET),
['-D', 'IDF_TARGET={}'.format(ESP32_TARGET)])
logging.info('idf.py fails if IDF_TARGET is set differently in CMakeCache.txt and with -D option')
default_idf_env.pop('IDF_TARGET')
reconfigure_and_check_return_values("Target '{}' specified on command line is not consistent with "
"target '{}' in CMakeCache.txt.".format(ESP32_TARGET, ESP32S2_TARGET),
['-D', 'IDF_TARGET={}'.format(ESP32_TARGET)])
def test_target_precedence(idf_py: IdfPyFunc, default_idf_env: EnvDict, test_app_copy: Path) -> None:
logging.info('IDF_TARGET takes precedence over the value of CONFIG_IDF_TARGET in sdkconfig.defaults')
(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))
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))
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))
@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))
@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))
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))
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()))
tools: move target guessing into cmake The _guess_or_check_idf_target() function has sdkconfig and sdkconfig.defaults file names hardcoded. Since config file names may be specified with SDKCONFIG or SDKCONFIG_DEFAULTS cmake vars, directly in CMakeLists.txt or passed in with the -D cmake option, they are not respected. Problem is when SDKCONFIG or SDKCONFIG_DEFAULTS is set in CMakeLists.txt. While idf can detect cmake vars passed through it to cmake via the -D option, detecting SDKCONFIG and SDKCONFIG_DEFAULTS vars settings in CMakeLists.txt would require to parse it. This seems like error prone approach. Also if the vars defined by the -D option are passed directly to cmake, not via idf, they will not be visible to idf. It seems reasonable to move the logic into cmake, where we know the correct SDKCONFIG and SDKCONFIG_DEFAULTS values. So the IDF_TARGET detection/guessing is moved into targets.cmake, where the IDF_TARGET is actually set. The target is guessed based on the following precendence. 1) $ENV{IDF_TARGET} 2) IDF_TARGET 3) SDKCONFIG 4) sdkconfig 5) SDKCONFIG_DEFAULTS if non-empty or $ENV{SDKCONFIG_DEFAULTS} if non-empty or sdkconfig.defaults 6) esp32 All config files referred in $ENV{SDKCONFIG_DEFAULTS} and SDKCONFIG_DEFAULTS are searched, compared to the current behaviour. First target found in the above chain is used. The original _guess_or_check_idf_target() is renamed to _check_idf_target() and used for the target consistency checks only. The get_sdkconfig_filename() helper is now used to get the sdkconfig file for consistency checks. It looks in SDKCONFIG specified with the -D option and project_description.json. With this change config full paths are reported in messages, so it's clear e.g. from which config the target was guessed from or which config has consistency problem. test_non_default_target.py was adjusted to this change and also new test for testing the IDF_TARGET guessing was added. Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2023-02-23 04:56:06 -05:00
def test_target_guessing(idf_py: IdfPyFunc, test_app_copy: Path, default_idf_env: EnvDict) -> None:
"""
Tests are performed from the lowest to the highest priority, while
configs, except from the sdkconfig, and parameters of previous tests are
preserved.
"""
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))
logging.info('Can guess target from SDKCONFIG_DEFAULTS environment variable')
(test_app_copy / 'sdkconfig1').write_text('NOTHING HERE')
(test_app_copy / 'sdkconfig2').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
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))
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))
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))