diff --git a/tools/ci/python_packages/ttfw_idf/IDFApp.py b/tools/ci/python_packages/ttfw_idf/IDFApp.py index 461e66730..386ab1679 100644 --- a/tools/ci/python_packages/ttfw_idf/IDFApp.py +++ b/tools/ci/python_packages/ttfw_idf/IDFApp.py @@ -385,7 +385,7 @@ class UT(IDFApp): return path # ``make ut-build-all-configs`` or ``make ut-build-CONFIG`` will copy binary to output folder - path = os.path.join(self.idf_path, "tools", "unit-test-app", "output", config_name) + path = os.path.join(self.idf_path, "tools", "unit-test-app", "output", target, config_name) if os.path.exists(path): return path diff --git a/tools/unit-test-app/tools/UnitTestParser.py b/tools/unit-test-app/tools/UnitTestParser.py index 31b485c64..e174f3cfd 100644 --- a/tools/unit-test-app/tools/UnitTestParser.py +++ b/tools/unit-test-app/tools/UnitTestParser.py @@ -4,6 +4,7 @@ import os import re import shutil import subprocess +import sys from copy import deepcopy import CreateSectionTable @@ -43,18 +44,24 @@ class Parser(object): MODULE_DEF_FILE = os.path.join("tools", "unit-test-app", "tools", "ModuleDefinition.yml") CONFIG_DEPENDENCY_FILE = os.path.join("tools", "unit-test-app", "tools", "ConfigDependency.yml") MODULE_ARTIFACT_FILE = os.path.join("components", "idf_test", "ModuleDefinition.yml") - TEST_CASE_FILE = os.path.join("components", "idf_test", "unit_test", "TestCaseAll.yml") + TEST_CASE_FILE_DIR = os.path.join("components", "idf_test", "unit_test") UT_BIN_FOLDER = os.path.join("tools", "unit-test-app", "output") UT_CONFIG_FOLDER = os.path.join("tools", "unit-test-app", "configs") ELF_FILE = "unit-test-app.elf" SDKCONFIG_FILE = "sdkconfig" STRIP_CONFIG_PATTERN = re.compile(r"(.+?)(_\d+)?$") + TOOLCHAIN_FOR_TARGET = { + "esp32": "xtensa-esp32-elf-", + "esp32s2": "xtensa-esp32s2-elf-", + } - def __init__(self, idf_path=os.getenv("IDF_PATH")): + def __init__(self, idf_path=os.getenv("IDF_PATH"), idf_target=os.getenv("IDF_TARGET")): self.test_env_tags = {} self.unit_jobs = {} self.file_name_cache = {} self.idf_path = idf_path + self.idf_target = idf_target + self.objdump = Parser.TOOLCHAIN_FOR_TARGET.get(idf_target, "") + "objdump" self.tag_def = yaml.load(open(os.path.join(idf_path, self.TAG_DEF_FILE), "r"), Loader=Loader) self.module_map = yaml.load(open(os.path.join(idf_path, self.MODULE_DEF_FILE), "r"), Loader=Loader) self.config_dependencies = yaml.load(open(os.path.join(idf_path, self.CONFIG_DEPENDENCY_FILE), "r"), @@ -66,27 +73,19 @@ class Parser(object): def parse_test_cases_for_one_config(self, configs_folder, config_output_folder, config_name): """ parse test cases from elf and save test cases need to be executed to unit test folder - :param configs_folder: folder where per-config sdkconfig framents are located (i.e. tools/unit-test-app/configs) + :param configs_folder: folder where per-config sdkconfig fragments are located (i.e. tools/unit-test-app/configs) :param config_output_folder: build folder of this config :param config_name: built unit test config name """ tags = self.parse_tags(os.path.join(config_output_folder, self.SDKCONFIG_FILE)) print("Tags of config %s: %s" % (config_name, tags)) - # Search in tags to set the target - target_tag_dict = {"ESP32_IDF": "esp32", "ESP32S2_IDF": "esp32s2"} - for tag in target_tag_dict: - if tag in tags: - target = target_tag_dict[tag] - break - else: - target = "esp32" test_groups = self.get_test_groups(os.path.join(configs_folder, config_name)) elf_file = os.path.join(config_output_folder, self.ELF_FILE) - subprocess.check_output('xtensa-esp32-elf-objdump -t {} | grep test_desc > case_address.tmp'.format(elf_file), + subprocess.check_output('{} -t {} | grep test_desc > case_address.tmp'.format(self.objdump, elf_file), shell=True) - subprocess.check_output('xtensa-esp32-elf-objdump -s {} > section_table.tmp'.format(elf_file), shell=True) + subprocess.check_output('{} -s {} > section_table.tmp'.format(self.objdump, elf_file), shell=True) table = CreateSectionTable.SectionTable("section_table.tmp") test_cases = [] @@ -105,13 +104,11 @@ class Parser(object): name_addr = table.get_unsigned_int(section, test_addr, 4) desc_addr = table.get_unsigned_int(section, test_addr + 4, 4) - file_name_addr = table.get_unsigned_int(section, test_addr + 12, 4) function_count = table.get_unsigned_int(section, test_addr + 20, 4) name = table.get_string("any", name_addr) desc = table.get_string("any", desc_addr) - file_name = table.get_string("any", file_name_addr) - tc = self.parse_one_test_case(name, desc, file_name, config_name, stripped_config_name, tags, target) + tc = self.parse_one_test_case(name, desc, config_name, stripped_config_name, tags) # check if duplicated case names # we need to use it to select case, @@ -229,7 +226,6 @@ class Parser(object): :param sdkconfig_file: sdk config file of the unit test config :return: required tags for runners """ - with open(sdkconfig_file, "r") as f: configs_raw_data = f.read() @@ -250,12 +246,11 @@ class Parser(object): return match.group(1).split(' ') return None - def parse_one_test_case(self, name, description, file_name, config_name, stripped_config_name, tags, target): + def parse_one_test_case(self, name, description, config_name, stripped_config_name, tags): """ parse one test case :param name: test case name (summary) :param description: test case description (tag string) - :param file_name: the file defines this test case :param config_name: built unit test app name :param stripped_config_name: strip suffix from config name because they're the same except test components :param tags: tags to select runners @@ -279,7 +274,7 @@ class Parser(object): "multi_stage": prop["multi_stage"], "timeout": int(prop["timeout"]), "tags": tags, - "chip_target": target}) + "chip_target": self.idf_target}) return test_case def dump_test_cases(self, test_cases): @@ -287,7 +282,7 @@ class Parser(object): dump parsed test cases to YAML file for test bench input :param test_cases: parsed test cases """ - filename = os.path.join(self.idf_path, self.TEST_CASE_FILE) + filename = os.path.join(self.idf_path, self.TEST_CASE_FILE_DIR, self.idf_target + ".yml") try: os.mkdir(os.path.dirname(filename)) except OSError: @@ -305,7 +300,7 @@ class Parser(object): """ parse test cases from multiple built unit test apps """ test_cases = [] - output_folder = os.path.join(self.idf_path, self.UT_BIN_FOLDER) + output_folder = os.path.join(self.idf_path, self.UT_BIN_FOLDER, self.idf_target) configs_folder = os.path.join(self.idf_path, self.UT_CONFIG_FOLDER) test_configs = os.listdir(output_folder) for config in test_configs: @@ -362,14 +357,22 @@ def main(): test_parser() idf_path = os.getenv("IDF_PATH") + if not idf_path: + print("IDF_PATH must be set to use this script", file=sys.stderr) + raise SystemExit(1) - parser = Parser(idf_path) + idf_target = os.getenv("IDF_TARGET") + if not idf_target: + print("IDF_TARGET must be set to use this script", file=sys.stderr) + raise SystemExit(1) + + parser = Parser(idf_path, idf_target) parser.parse_test_cases() parser.copy_module_def_file() if len(parser.parsing_errors) > 0: for error in parser.parsing_errors: print(error) - exit(-1) + exit(1) if __name__ == '__main__':