refactor(tools): Updated tests to corespond with massage changes

This commit is contained in:
Jakub Kocka
2025-08-12 10:55:05 +02:00
parent 7b65c5e0b7
commit 2affbb9509
2 changed files with 73 additions and 49 deletions

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import json
import logging
@@ -9,28 +9,23 @@ import subprocess
import sys
import textwrap
from pathlib import Path
from typing import List
import pytest
from test_build_system_helpers import append_to_file
from test_build_system_helpers import EnvDict
from test_build_system_helpers import IdfPyFunc
from test_build_system_helpers import append_to_file
from test_build_system_helpers import file_contains
from test_build_system_helpers import find_python
from test_build_system_helpers import get_snapshot
from test_build_system_helpers import IdfPyFunc
from test_build_system_helpers import replace_in_file
from test_build_system_helpers import run_idf_py
def get_subdirs_absolute_paths(path: Path) -> List[str]:
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
]
return [f'{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')
@@ -51,10 +46,11 @@ def test_hints_no_color_output_when_noninteractive(idf_py: IdfPyFunc) -> None:
"""Check that idf.py hints don't include color escape codes in non-interactive builds"""
# make the build fail in such a way that idf.py shows a hint
replace_in_file('main/build_test_app.c', '// placeholder_inside_main',
'esp_chip_info_t chip_info; esp_chip_info(&chip_info);')
replace_in_file(
'main/build_test_app.c', '// placeholder_inside_main', 'esp_chip_info_t chip_info; esp_chip_info(&chip_info);'
)
with (pytest.raises(subprocess.CalledProcessError)) as exc_info:
with pytest.raises(subprocess.CalledProcessError) as exc_info:
idf_py('build')
# Should not actually include a color escape sequence!
@@ -70,10 +66,7 @@ def test_idf_copy(idf_copy: Path, idf_py: IdfPyFunc) -> None:
idf_py('build')
def test_idf_build_with_env_var_sdkconfig_defaults(
test_app_copy: Path,
default_idf_env: EnvDict
) -> None:
def test_idf_build_with_env_var_sdkconfig_defaults(test_app_copy: Path, default_idf_env: EnvDict) -> None:
with open(test_app_copy / 'sdkconfig.test', 'w') as fw:
fw.write('CONFIG_BT_ENABLED=y')
@@ -86,9 +79,7 @@ def test_idf_build_with_env_var_sdkconfig_defaults(
@pytest.mark.usefixtures('test_app_copy')
@pytest.mark.test_app_copy('examples/system/efuse')
def test_efuse_summary_cmake_functions(
default_idf_env: EnvDict
) -> None:
def test_efuse_summary_cmake_functions(default_idf_env: EnvDict) -> None:
default_idf_env['IDF_CI_BUILD'] = '1'
output = run_idf_py('efuse-filter', env=default_idf_env)
assert 'FROM_CMAKE: MAC: 00:00:00:00:00:00' in output.stdout
@@ -117,16 +108,22 @@ 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
"""))
(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
# 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)
@@ -140,7 +137,8 @@ def test_python_interpreter_win(test_app_copy: Path) -> None:
# 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
# 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)
@@ -172,7 +170,7 @@ def test_ccache_used_to_build(test_app_copy: Path) -> None:
def test_toolchain_prefix_in_description_file(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
logging.info('Toolchain prefix is set in project description file')
idf_py('reconfigure')
data = json.load(open(test_app_copy / 'build' / 'project_description.json', 'r'))
data = json.load(open(test_app_copy / 'build' / 'project_description.json'))
assert 'monitor_toolprefix' in data
@@ -195,8 +193,10 @@ def test_subcommands_with_options(idf_py: IdfPyFunc, default_idf_env: EnvDict) -
def test_fallback_to_build_system_target(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
logging.info('idf.py fallback to build system target')
msg = 'Custom target is running'
append_to_file(test_app_copy / 'CMakeLists.txt',
'add_custom_target(custom_target COMMAND ${{CMAKE_COMMAND}} -E echo "{}")'.format(msg))
append_to_file(
test_app_copy / 'CMakeLists.txt',
f'add_custom_target(custom_target COMMAND ${{CMAKE_COMMAND}} -E echo "{msg}")',
)
ret = idf_py('custom_target')
assert msg in ret.stdout, 'Custom target did not produce expected output'
@@ -205,10 +205,16 @@ def test_create_component_project(idf_copy: Path) -> None:
logging.info('Create project and component using idf.py and build it')
run_idf_py('-C', 'projects', 'create-project', 'temp_test_project', workdir=idf_copy)
run_idf_py('-C', 'components', 'create-component', 'temp_test_component', workdir=idf_copy)
replace_in_file(idf_copy / 'projects' / 'temp_test_project' / 'main' / 'temp_test_project.c', '{\n\n}',
'\n'.join(['{', '\tfunc();', '}']))
replace_in_file(idf_copy / 'projects' / 'temp_test_project' / 'main' / 'temp_test_project.c', '#include <stdio.h>',
'\n'.join(['#include <stdio.h>', '#include "temp_test_component.h"']))
replace_in_file(
idf_copy / 'projects' / 'temp_test_project' / 'main' / 'temp_test_project.c',
'{\n\n}',
'\n'.join(['{', '\tfunc();', '}']),
)
replace_in_file(
idf_copy / 'projects' / 'temp_test_project' / 'main' / 'temp_test_project.c',
'#include <stdio.h>',
'\n'.join(['#include <stdio.h>', '#include "temp_test_component.h"']),
)
run_idf_py('build', workdir=(idf_copy / 'projects' / 'temp_test_project'))
@@ -244,6 +250,7 @@ def test_create_project_with_idf_readonly(idf_copy: Path) -> None:
if '/bin/' in path:
continue # skip executables
os.chmod(os.path.join(root, name), file_permission)
logging.info('Check that command for creating new project will success if the IDF itself is readonly.')
change_file_permissions(idf_copy, write_permission=False)
try:
@@ -267,7 +274,18 @@ def test_docs_command(idf_py: IdfPyFunc) -> None:
assert 'https://docs.espressif.com/projects/esp-idf/en/v4.2.1' in ret.stdout
ret = idf_py('docs', '--no-browser', '--language', 'en', '--version', 'v4.2.1', '--target', 'esp32')
assert 'https://docs.espressif.com/projects/esp-idf/en/v4.2.1/esp32' in ret.stdout
ret = idf_py('docs', '--no-browser', '--language', 'en', '--version', 'v4.2.1', '--target', 'esp32', '--starting-page', 'get-started')
ret = idf_py(
'docs',
'--no-browser',
'--language',
'en',
'--version',
'v4.2.1',
'--target',
'esp32',
'--starting-page',
'get-started',
)
assert 'https://docs.espressif.com/projects/esp-idf/en/v4.2.1/esp32/get-started' in ret.stdout
@@ -285,25 +303,31 @@ def test_deprecation_warning(idf_py: IdfPyFunc) -> None:
def test_save_defconfig_check(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
logging.info('Save-defconfig checks')
(test_app_copy / 'sdkconfig').write_text('\n'.join(['CONFIG_COMPILER_OPTIMIZATION_SIZE=y',
'CONFIG_ESPTOOLPY_FLASHFREQ_80M=y']))
(test_app_copy / 'sdkconfig').write_text(
'\n'.join(['CONFIG_COMPILER_OPTIMIZATION_SIZE=y', 'CONFIG_ESPTOOLPY_FLASHFREQ_80M=y'])
)
idf_py('save-defconfig')
assert not file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_IDF_TARGET'), \
assert not file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_IDF_TARGET'), (
'CONFIG_IDF_TARGET should not be in sdkconfig.defaults'
assert file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_COMPILER_OPTIMIZATION_SIZE=y'), \
)
assert file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_COMPILER_OPTIMIZATION_SIZE=y'), (
'Missing CONFIG_COMPILER_OPTIMIZATION_SIZE=y in sdkconfig.defaults'
assert file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_ESPTOOLPY_FLASHFREQ_80M=y'), \
)
assert file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_ESPTOOLPY_FLASHFREQ_80M=y'), (
'Missing CONFIG_ESPTOOLPY_FLASHFREQ_80M=y in sdkconfig.defaults'
)
idf_py('fullclean')
(test_app_copy / 'sdkconfig').unlink()
(test_app_copy / 'sdkconfig.defaults').unlink()
idf_py('set-target', 'esp32c3')
(test_app_copy / 'sdkconfig').write_text('CONFIG_PARTITION_TABLE_OFFSET=0x8001')
idf_py('save-defconfig')
assert file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_IDF_TARGET="esp32c3"'), \
assert file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_IDF_TARGET="esp32c3"'), (
'Missing CONFIG_IDF_TARGET="esp32c3" in sdkconfig.defaults'
assert file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_PARTITION_TABLE_OFFSET=0x8001'), \
)
assert file_contains(test_app_copy / 'sdkconfig.defaults', 'CONFIG_PARTITION_TABLE_OFFSET=0x8001'), (
'Missing CONFIG_PARTITION_TABLE_OFFSET=0x8001 in sdkconfig.defaults'
)
def test_merge_bin_cmd(idf_py: IdfPyFunc, test_app_copy: Path) -> None:

View File

@@ -204,7 +204,8 @@ class TestDeprecations(TestWithoutExtensions):
[sys.executable, idf_py_path, '-C', current_dir, 'test-2'], env=os.environ, stderr=subprocess.STDOUT
)
except subprocess.CalledProcessError as e:
self.assertIn('Error: Command "test-2" is deprecated and was removed.', e.output.decode('utf-8', 'ignore'))
output = e.output.decode('utf-8', 'ignore').replace('\r\n', '\n')
self.assertIn('Error: Command "test-2" is deprecated and was removed\n', output)
def test_exit_with_error_for_option(self):
try:
@@ -239,7 +240,6 @@ class TestDeprecations(TestWithoutExtensions):
env=os.environ,
stderr=subprocess.STDOUT,
).decode('utf-8', 'ignore')
self.assertIn('Warning: Option "test_sub_1" is deprecated and will be removed in future versions.', output)
self.assertIn(
'Warning: Command "test-1" is deprecated and will be removed in future versions. '
@@ -374,8 +374,8 @@ class TestWrapperCommands(TestCase):
class TestEFuseCommands(TestWrapperCommands):
"""
Test if wrapper commands for espefuse.py are working as expected.
The goal is NOT to test the functionality of espefuse.py, but to test if the wrapper commands
are working as expected.
The goal is NOT to test the functionality of espefuse.py
but to test if the wrapper commands are working as expected.
"""
def test_efuse_summary(self):
@@ -438,8 +438,8 @@ class TestEFuseCommands(TestWrapperCommands):
class TestSecureCommands(TestWrapperCommands):
"""
Test if wrapper commands for espsecure.py are working as expected.
The goal is NOT to test the functionality of espsecure.py, but to test if the wrapper commands are
working as expected.
The goal is NOT to test the functionality of espsecure.py
but to test if the wrapper commands are working as expected.
"""
@classmethod
@@ -577,8 +577,8 @@ class TestSecureCommands(TestWrapperCommands):
class TestMergeBinCommands(TestWrapperCommands):
"""
Test if merge-bin command is invoked as expected.
This test is not testing the functionality of esptool.py merge_bin command, but the invocation of
the command from idf.py.
This test is not testing the functionality of esptool.py merge_bin command
but the invocation of the command from idf.py.
"""
def test_merge_bin(self):