Use IDF_TARGET to determine the build method and the output file name

This commit is contained in:
Fu Hanxi
2020-04-29 10:47:20 +08:00
committed by bot
parent 01ff4f621f
commit 7709d4ccfd
2 changed files with 28 additions and 25 deletions

View File

@@ -385,7 +385,7 @@ class UT(IDFApp):
return path return path
# ``make ut-build-all-configs`` or ``make ut-build-CONFIG`` will copy binary to output folder # ``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): if os.path.exists(path):
return path return path

View File

@@ -4,6 +4,7 @@ import os
import re import re
import shutil import shutil
import subprocess import subprocess
import sys
from copy import deepcopy from copy import deepcopy
import CreateSectionTable import CreateSectionTable
@@ -43,18 +44,24 @@ class Parser(object):
MODULE_DEF_FILE = os.path.join("tools", "unit-test-app", "tools", "ModuleDefinition.yml") 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") CONFIG_DEPENDENCY_FILE = os.path.join("tools", "unit-test-app", "tools", "ConfigDependency.yml")
MODULE_ARTIFACT_FILE = os.path.join("components", "idf_test", "ModuleDefinition.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_BIN_FOLDER = os.path.join("tools", "unit-test-app", "output")
UT_CONFIG_FOLDER = os.path.join("tools", "unit-test-app", "configs") UT_CONFIG_FOLDER = os.path.join("tools", "unit-test-app", "configs")
ELF_FILE = "unit-test-app.elf" ELF_FILE = "unit-test-app.elf"
SDKCONFIG_FILE = "sdkconfig" SDKCONFIG_FILE = "sdkconfig"
STRIP_CONFIG_PATTERN = re.compile(r"(.+?)(_\d+)?$") 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.test_env_tags = {}
self.unit_jobs = {} self.unit_jobs = {}
self.file_name_cache = {} self.file_name_cache = {}
self.idf_path = idf_path 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.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.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"), 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): 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 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_output_folder: build folder of this config
:param config_name: built unit test config name :param config_name: built unit test config name
""" """
tags = self.parse_tags(os.path.join(config_output_folder, self.SDKCONFIG_FILE)) tags = self.parse_tags(os.path.join(config_output_folder, self.SDKCONFIG_FILE))
print("Tags of config %s: %s" % (config_name, tags)) 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)) test_groups = self.get_test_groups(os.path.join(configs_folder, config_name))
elf_file = os.path.join(config_output_folder, self.ELF_FILE) 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) 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") table = CreateSectionTable.SectionTable("section_table.tmp")
test_cases = [] test_cases = []
@@ -105,13 +104,11 @@ class Parser(object):
name_addr = table.get_unsigned_int(section, test_addr, 4) name_addr = table.get_unsigned_int(section, test_addr, 4)
desc_addr = table.get_unsigned_int(section, test_addr + 4, 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) function_count = table.get_unsigned_int(section, test_addr + 20, 4)
name = table.get_string("any", name_addr) name = table.get_string("any", name_addr)
desc = table.get_string("any", desc_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 # check if duplicated case names
# we need to use it to select case, # 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 :param sdkconfig_file: sdk config file of the unit test config
:return: required tags for runners :return: required tags for runners
""" """
with open(sdkconfig_file, "r") as f: with open(sdkconfig_file, "r") as f:
configs_raw_data = f.read() configs_raw_data = f.read()
@@ -250,12 +246,11 @@ class Parser(object):
return match.group(1).split(' ') return match.group(1).split(' ')
return None 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 parse one test case
:param name: test case name (summary) :param name: test case name (summary)
:param description: test case description (tag string) :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 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 stripped_config_name: strip suffix from config name because they're the same except test components
:param tags: tags to select runners :param tags: tags to select runners
@@ -279,7 +274,7 @@ class Parser(object):
"multi_stage": prop["multi_stage"], "multi_stage": prop["multi_stage"],
"timeout": int(prop["timeout"]), "timeout": int(prop["timeout"]),
"tags": tags, "tags": tags,
"chip_target": target}) "chip_target": self.idf_target})
return test_case return test_case
def dump_test_cases(self, test_cases): 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 dump parsed test cases to YAML file for test bench input
:param test_cases: parsed test cases :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: try:
os.mkdir(os.path.dirname(filename)) os.mkdir(os.path.dirname(filename))
except OSError: except OSError:
@@ -305,7 +300,7 @@ class Parser(object):
""" parse test cases from multiple built unit test apps """ """ parse test cases from multiple built unit test apps """
test_cases = [] 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) configs_folder = os.path.join(self.idf_path, self.UT_CONFIG_FOLDER)
test_configs = os.listdir(output_folder) test_configs = os.listdir(output_folder)
for config in test_configs: for config in test_configs:
@@ -362,14 +357,22 @@ def main():
test_parser() test_parser()
idf_path = os.getenv("IDF_PATH") 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.parse_test_cases()
parser.copy_module_def_file() parser.copy_module_def_file()
if len(parser.parsing_errors) > 0: if len(parser.parsing_errors) > 0:
for error in parser.parsing_errors: for error in parser.parsing_errors:
print(error) print(error)
exit(-1) exit(1)
if __name__ == '__main__': if __name__ == '__main__':