test(cmakev2): Add pytest tests for project APIs

This commit is contained in:
Sudeep Mohanty
2026-03-04 17:42:50 +01:00
parent 131fbdd864
commit e53d8e9a74
@@ -0,0 +1,118 @@
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import json
import logging
import subprocess
from pathlib import Path
import pytest
from test_build_system_helpers import IdfPyFunc
from test_build_system_helpers import replace_in_file
@pytest.mark.usefixtures('test_app_copy')
def test_project_init_explicit_steps_without_binary(idf_py: IdfPyFunc) -> None:
"""idf_project_init() + idf_build_executable() produces ELF but no .bin when idf_build_binary() is omitted."""
logging.info('Testing idf_project_init with explicit steps but without idf_build_binary')
replace_in_file(
'CMakeLists.txt',
'idf_project_default()',
'idf_project_init()\n'
'idf_build_executable(build_test_app COMPONENTS main)\n'
'idf_build_generate_metadata(EXECUTABLE build_test_app)\n',
)
idf_py('build')
assert Path('build/project_description.json').exists(), 'project_description.json not produced'
assert Path('build/build_test_app.elf').exists(), 'ELF not created despite idf_build_executable()'
assert not Path('build/build_test_app.bin').exists(), '.bin should not exist when idf_build_binary() is omitted'
@pytest.mark.usefixtures('test_app_copy')
def test_project_default_produces_all_artifacts(idf_py: IdfPyFunc) -> None:
"""idf_project_default() should produce ELF, .bin, project_description.json,
flasher_args.json, and standard build targets (menuconfig, uf2, size)."""
logging.info('Testing idf_project_default full artifact generation')
idf_py('build')
assert Path('build/build_test_app.elf').exists(), 'ELF not produced'
assert Path('build/build_test_app.bin').exists(), '.bin not produced'
assert Path('build/project_description.json').exists(), 'project_description.json not produced'
assert Path('build/flasher_args.json').exists(), 'flasher_args.json not produced'
flasher_args = json.loads(Path('build/flasher_args.json').read_text())
assert 'flash_files' in flasher_args, 'flasher_args.json should contain flash_files'
ninja_targets_result = subprocess.run(
['ninja', '-t', 'targets', 'all'],
capture_output=True,
text=True,
cwd='build',
check=True,
)
ninja_targets = ninja_targets_result.stdout
for target in (
'menuconfig',
'confserver',
'save-defconfig',
'config-report',
'uf2',
'uf2-app',
'size',
'app-flash',
):
assert f'{target}:' in ninja_targets, f'"{target}" target not found in ninja targets'
@pytest.mark.usefixtures('test_app_copy')
def test_project_init_requires_cmake_project(idf_py: IdfPyFunc) -> None:
"""idf_project_init() called before cmake project() should fail."""
logging.info('Testing idf_project_init before project() fails')
replace_in_file('CMakeLists.txt', '# placeholder_after_include_project_cmake', 'idf_project_init()\n')
replace_in_file('CMakeLists.txt', 'idf_project_default()', '# project_default removed for ordering test\n')
cmake_content = Path('CMakeLists.txt').read_text()
assert 'idf_project_init()' in cmake_content, 'replace_in_file did not inject idf_project_init()'
with pytest.raises(subprocess.CalledProcessError):
idf_py('reconfigure')
@pytest.mark.usefixtures('test_app_copy')
def test_build_generate_flasher_args(idf_py: IdfPyFunc) -> None:
"""idf_build_generate_flasher_args() generates flasher_args.json with correct content."""
logging.info('Testing idf_build_generate_flasher_args flasher_args.json generation')
replace_in_file(
'CMakeLists.txt',
'idf_project_default()',
'idf_project_init()\n'
'idf_build_executable(build_test_app COMPONENTS main)\n'
'idf_build_binary(build_test_app\n'
' OUTPUT_FILE "${CMAKE_BINARY_DIR}/build_test_app.bin"\n'
' TARGET build_test_app_binary)\n'
'idf_flash_binary(build_test_app_binary\n'
' TARGET app-flash\n'
' NAME "app"\n'
' FLASH)\n'
'idf_check_binary_size(build_test_app_binary)\n'
'add_custom_target(app ALL DEPENDS build_test_app_binary)\n'
'idf_build_generate_metadata(BINARY build_test_app_binary)\n'
'idf_build_generate_flasher_args()\n',
)
idf_py('build')
# Verify flasher_args.json is created
flasher_args_path = Path('build/flasher_args.json')
assert flasher_args_path.exists(), 'flasher_args.json not generated by idf_build_generate_flasher_args'
# Verify flasher_args.json contains expected structure
flasher_args = json.loads(flasher_args_path.read_text())
assert 'flash_files' in flasher_args, 'flasher_args.json should contain flash_files key'
assert 'flash_settings' in flasher_args, 'flasher_args.json should contain flash_settings key'
assert 'extra_esptool_args' in flasher_args, 'flasher_args.json should contain extra_esptool_args'
assert 'chip' in flasher_args.get('extra_esptool_args', {}), 'extra_esptool_args should contain chip information'