mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 04:59:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			73 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
 | |
| # SPDX-License-Identifier: Apache-2.0
 | |
| # This test checks the behavior of reproducible builds option.
 | |
| import logging
 | |
| import os
 | |
| import shutil
 | |
| import subprocess
 | |
| from pathlib import Path
 | |
| 
 | |
| import pytest
 | |
| from test_build_system_helpers import append_to_file
 | |
| from test_build_system_helpers import bin_files_differ
 | |
| from test_build_system_helpers import BOOTLOADER_BINS
 | |
| from test_build_system_helpers import IdfPyFunc
 | |
| 
 | |
| 
 | |
| @pytest.mark.parametrize(
 | |
|     'app_name', [
 | |
|         pytest.param('blink', marks=[pytest.mark.test_app_copy('examples/get-started/blink')]),
 | |
|         pytest.param('blecent', marks=[pytest.mark.test_app_copy('examples/bluetooth/nimble/blecent')]),
 | |
|     ]
 | |
| )
 | |
| def test_reproducible_builds(app_name: str, idf_py: IdfPyFunc, test_app_copy: Path) -> None:
 | |
|     append_to_file(test_app_copy / 'sdkconfig', 'CONFIG_APP_REPRODUCIBLE_BUILD=y')
 | |
|     build_first = test_app_copy / 'build_first'
 | |
|     build_second = test_app_copy / 'build_second'
 | |
| 
 | |
|     logging.info(f'Building in {build_first} directory')
 | |
|     idf_py('-B', str(build_first), 'build')
 | |
| 
 | |
|     elf_file = build_first / f'{app_name}.elf'
 | |
|     logging.info(f'Checking that various paths are not included in the ELF file')
 | |
|     strings_output = subprocess.check_output(
 | |
|         ['xtensa-esp32-elf-strings', str(elf_file)],
 | |
|         encoding='utf-8'
 | |
|     )
 | |
|     idf_path = os.environ['IDF_PATH']
 | |
|     assert str(idf_path) not in strings_output, f'{idf_path} found in {elf_file}'
 | |
|     assert str(test_app_copy) not in strings_output, f'{test_app_copy} found in {elf_file}'
 | |
|     compiler_path = shutil.which('xtensa-esp32-elf-gcc')
 | |
|     assert compiler_path is not None, 'failed to determine compiler path'
 | |
|     toolchain_path = Path(compiler_path).parent.parent
 | |
|     assert str(toolchain_path) not in strings_output, f'{toolchain_path} found in {elf_file}'
 | |
| 
 | |
|     logging.info(f'Building in {build_second} directory')
 | |
|     idf_py('-B', str(build_second), 'build')
 | |
| 
 | |
|     logging.info(f'Comparing build artifacts')
 | |
|     artifacts_to_check = [
 | |
|         f'build/{app_name}.map',
 | |
|         f'build/{app_name}.elf',
 | |
|         f'build/{app_name}.bin',
 | |
|     ] + BOOTLOADER_BINS
 | |
| 
 | |
|     for artifact in artifacts_to_check:
 | |
|         path_first = artifact.replace('build/', f'{build_first}/')
 | |
|         path_second = artifact.replace('build/', f'{build_second}/')
 | |
| 
 | |
|         assert not bin_files_differ(path_first, path_second), f'{path_first} and {path_second} differ'
 | |
| 
 | |
|     logging.info(f'Checking that GDB works with CONFIG_APP_REPRODUCIBLE_BUILD=y')
 | |
|     gdb_output = subprocess.check_output([
 | |
|         'xtensa-esp32-elf-gdb',
 | |
|         '--batch', '--quiet',
 | |
|         '-x', f'{build_first}/prefix_map_gdbinit',
 | |
|         '-ex', 'set logging enabled',
 | |
|         '-ex', 'set pagination off',
 | |
|         '-ex', 'list app_main',
 | |
|         str(elf_file)
 | |
|     ], encoding='utf-8', stderr=subprocess.STDOUT, cwd=str(build_first))
 | |
| 
 | |
|     assert 'No such file or directory' not in gdb_output, f'GDB failed to find app_main in {elf_file}:\n{gdb_output}'
 | 
