Merge branch 'feature/ut_parallel_build' into 'master'

unit_test: ut parallel build

Closes IDF-1570

See merge request espressif/esp-idf!8338
This commit is contained in:
Ivan Grokhotkov
2020-05-04 15:52:59 +08:00
48 changed files with 292 additions and 123 deletions

4
.gitignore vendored
View File

@@ -40,6 +40,10 @@ tools/unit-test-app/sdkconfig.old
tools/unit-test-app/build tools/unit-test-app/build
tools/unit-test-app/builds tools/unit-test-app/builds
tools/unit-test-app/output tools/unit-test-app/output
tools/unit-test-app/test_configs
# Unit Test CMake compile log folder
log_ut_cmake
# IDF monitor test # IDF monitor test
tools/test_idf_monitor/outputs tools/test_idf_monitor/outputs

View File

@@ -33,7 +33,6 @@ variables:
# tell build system do not check submodule update as we download archive instead of clone # tell build system do not check submodule update as we download archive instead of clone
IDF_SKIP_CHECK_SUBMODULES: 1 IDF_SKIP_CHECK_SUBMODULES: 1
UNIT_TEST_BUILD_SYSTEM: cmake
EXAMPLE_TEST_BUILD_SYSTEM: cmake EXAMPLE_TEST_BUILD_SYSTEM: cmake
IDF_PATH: "$CI_PROJECT_DIR" IDF_PATH: "$CI_PROJECT_DIR"
BATCH_BUILD: "1" BATCH_BUILD: "1"

View File

@@ -112,7 +112,7 @@ def main():
try: try:
build_system_class.build(build_info) build_system_class.build(build_info)
except BuildError as e: except BuildError as e:
logging.error(e.message) logging.error(str(e))
if args.keep_going: if args.keep_going:
failed_builds.append(build_info) failed_builds.append(build_info)
else: else:

107
tools/ci/build_unit_test.sh Executable file
View File

@@ -0,0 +1,107 @@
#!/bin/bash
#
# Build unit test app
#
# Runs as part of CI process.
#
# -----------------------------------------------------------------------------
# Safety settings (see https://gist.github.com/ilg-ul/383869cbb01f61a51c4d).
if [[ ! -z ${DEBUG_SHELL} ]]
then
set -x # Activate the expand mode if DEBUG is anything but empty.
fi
set -o errexit # Exit if command failed.
set -o pipefail # Exit if pipe failed.
export PATH="$IDF_PATH/tools/ci:$IDF_PATH/tools:$PATH"
# -----------------------------------------------------------------------------
die() {
echo "${1:-"Unknown Error"}" 1>&2
exit 1
}
[ -z ${IDF_PATH} ] && die "IDF_PATH is not set"
[ -z ${LOG_PATH} ] && die "LOG_PATH is not set"
[ -z ${IDF_TARGET} ] && die "IDF_TARGET is not set"
[ -d ${LOG_PATH} ] || mkdir -p ${LOG_PATH}
# Relative to IDF_PATH
# If changing the BUILD_PATH, remember to update the "artifacts" in gitlab-ci configs, and IDFApp.py.
BUILD_PATH=${IDF_PATH}/tools/unit-test-app/builds
OUTPUT_PATH=${IDF_PATH}/tools/unit-test-app/output
mkdir -p ${BUILD_PATH}/${IDF_TARGET}
mkdir -p ${OUTPUT_PATH}/${IDF_TARGET}
if [ -z ${CI_NODE_TOTAL} ]; then
CI_NODE_TOTAL=1
echo "Assuming CI_NODE_TOTAL=${CI_NODE_TOTAL}"
fi
if [ -z ${CI_NODE_INDEX} ]; then
# Gitlab uses a 1-based index
CI_NODE_INDEX=1
echo "Assuming CI_NODE_INDEX=${CI_NODE_INDEX}"
fi
set -o nounset # Exit if variable not set.
# Convert LOG_PATH to relative, to make the json file less verbose.
LOG_PATH=$(realpath --relative-to ${IDF_PATH} ${LOG_PATH})
ALL_BUILD_LIST_JSON="${BUILD_PATH}/${IDF_TARGET}/list.json"
JOB_BUILD_LIST_JSON="${BUILD_PATH}/${IDF_TARGET}/list_job_${CI_NODE_INDEX}.json"
echo "build_unit_test running for target $IDF_TARGET"
cd ${IDF_PATH}
# This part of the script produces the same result for all the unit test app build jobs. It may be moved to a separate stage
# (pre-build) later, then the build jobs will receive ${BUILD_LIST_JSON} file as an artifact.
${IDF_PATH}/tools/find_apps.py tools/unit-test-app \
-vv \
--format json \
--build-system cmake \
--target ${IDF_TARGET} \
--recursive \
--build-dir "builds/@t/@w" \
--build-log "${LOG_PATH}/@w.txt" \
--output ${ALL_BUILD_LIST_JSON} \
--config 'configs/*='
# The part below is where the actual builds happen
${IDF_PATH}/tools/build_apps.py \
-vv \
--format json \
--keep-going \
--parallel-count ${CI_NODE_TOTAL} \
--parallel-index ${CI_NODE_INDEX} \
--output-build-list ${JOB_BUILD_LIST_JSON} \
${ALL_BUILD_LIST_JSON}\
# Copy build artifacts to output directory
build_names=$(cd ${BUILD_PATH}/${IDF_TARGET}; find . -maxdepth 1 \! -name . -prune -type d | cut -c 3-)
for build_name in $build_names; do
src=${BUILD_PATH}/${IDF_TARGET}/${build_name}
dst=${OUTPUT_PATH}/${IDF_TARGET}/${build_name}
echo "Copying artifacts from ${src} to ${dst}"
rm -rf ${dst}
mkdir -p ${dst}
cp ${src}/{*.bin,*.elf,*.map,sdkconfig,flasher_args.json} ${dst}/
mkdir -p ${dst}/bootloader
cp ${src}/bootloader/*.bin ${dst}/bootloader/
mkdir -p ${dst}/partition_table
cp ${src}/partition_table/*.bin ${dst}/partition_table/
done
# Check for build warnings
${IDF_PATH}/tools/ci/check_build_warnings.py -vv ${JOB_BUILD_LIST_JSON}

View File

@@ -1,4 +1,3 @@
assign_test: assign_test:
tags: tags:
- assign_test - assign_test
@@ -8,12 +7,13 @@ assign_test:
# we have a lot build example jobs. now we don't use dependencies, just download all artifacts of build stage. # we have a lot build example jobs. now we don't use dependencies, just download all artifacts of build stage.
dependencies: dependencies:
- build_ssc_esp32 - build_ssc_esp32
- build_esp_idf_tests_cmake - build_esp_idf_tests_cmake_esp32
- build_esp_idf_tests_cmake_esp32s2
variables: variables:
SUBMODULES_TO_FETCH: "components/esptool_py/esptool" SUBMODULES_TO_FETCH: "components/esptool_py/esptool"
EXAMPLE_CONFIG_OUTPUT_PATH: "$CI_PROJECT_DIR/examples/test_configs" EXAMPLE_CONFIG_OUTPUT_PATH: "$CI_PROJECT_DIR/examples/test_configs"
TEST_APP_CONFIG_OUTPUT_PATH: "$CI_PROJECT_DIR/tools/test_apps/test_configs" TEST_APP_CONFIG_OUTPUT_PATH: "$CI_PROJECT_DIR/tools/test_apps/test_configs"
UNIT_TEST_CASE_FILE: "${CI_PROJECT_DIR}/components/idf_test/unit_test/TestCaseAll.yml" UNIT_TEST_CASE_FILE: "${CI_PROJECT_DIR}/components/idf_test/unit_test"
artifacts: artifacts:
paths: paths:
- components/idf_test/*/CIConfigs - components/idf_test/*/CIConfigs
@@ -55,8 +55,8 @@ update_test_cases:
- master - master
- schedules - schedules
dependencies: dependencies:
- build_esp_idf_tests_make - build_esp_idf_tests_cmake_esp32
- build_esp_idf_tests_cmake - build_esp_idf_tests_cmake_esp32s2
artifacts: artifacts:
when: always when: always
paths: paths:
@@ -64,7 +64,7 @@ update_test_cases:
expire_in: 1 week expire_in: 1 week
variables: variables:
SUBMODULES_TO_FETCH: "components/esptool_py/esptool" SUBMODULES_TO_FETCH: "components/esptool_py/esptool"
UNIT_TEST_CASE_FILE: "${CI_PROJECT_DIR}/components/idf_test/unit_test/TestCaseAll.yml" UNIT_TEST_CASE_DIR: "${CI_PROJECT_DIR}/components/idf_test/unit_test"
BOT_ACCOUNT_CONFIG_FILE: "${CI_PROJECT_DIR}/test-management/Config/Account.local.yml" BOT_ACCOUNT_CONFIG_FILE: "${CI_PROJECT_DIR}/test-management/Config/Account.local.yml"
AUTO_TEST_SCRIPT_PATH: "${CI_PROJECT_DIR}/auto_test_script" AUTO_TEST_SCRIPT_PATH: "${CI_PROJECT_DIR}/auto_test_script"
PYTHON_VER: 3 PYTHON_VER: 3
@@ -75,7 +75,8 @@ update_test_cases:
- cd test-management - cd test-management
- echo $BOT_JIRA_ACCOUNT > ${BOT_ACCOUNT_CONFIG_FILE} - echo $BOT_JIRA_ACCOUNT > ${BOT_ACCOUNT_CONFIG_FILE}
# update unit test cases # update unit test cases
- python ImportTestCase.py $JIRA_TEST_MANAGEMENT_PROJECT unity -d $UNIT_TEST_CASE_FILE -r $GIT_SHA - export UNIT_TEST_CASE_FILES=$(find $UNIT_TEST_CASE_DIR -maxdepth 1 -name "*.yml" | xargs)
- python ImportTestCase.py $JIRA_TEST_MANAGEMENT_PROJECT unity -d $UNIT_TEST_CASE_FILES -r $GIT_SHA
# update example test cases # update example test cases
- python ImportTestCase.py $JIRA_TEST_MANAGEMENT_PROJECT tiny_test_fw -d ${CI_PROJECT_DIR}/examples -r $GIT_SHA - python ImportTestCase.py $JIRA_TEST_MANAGEMENT_PROJECT tiny_test_fw -d ${CI_PROJECT_DIR}/examples -r $GIT_SHA
# organize test cases # organize test cases

View File

@@ -8,27 +8,6 @@
BATCH_BUILD: "1" BATCH_BUILD: "1"
V: "0" V: "0"
.build_esp_idf_unit_test_template:
extends: .build_template
artifacts:
paths:
- components/idf_test/unit_test/TestCaseAll.yml
# Keep only significant files in the output folder (mainly to get rid of .map files)
- tools/unit-test-app/output/*/*.bin
- tools/unit-test-app/output/*/sdkconfig
- tools/unit-test-app/output/*/*.elf
- tools/unit-test-app/output/*/flasher_args.json
- tools/unit-test-app/output/*/bootloader/*.bin
- tools/unit-test-app/output/*/partition_table/*.bin
expire_in: 4 days
only:
variables:
- $BOT_TRIGGER_WITH_LABEL == null
- $BOT_LABEL_BUILD
- $BOT_LABEL_UNIT_TEST
- $BOT_LABEL_UNIT_TEST_S2
- $BOT_LABEL_REGULAR_TEST
.build_ssc_template: .build_ssc_template:
extends: .build_template extends: .build_template
parallel: 3 parallel: 3
@@ -61,36 +40,42 @@ build_ssc_esp32s2:
variables: variables:
TARGET_NAME: "ESP32S2" TARGET_NAME: "ESP32S2"
build_esp_idf_tests_make: .build_esp_idf_tests_cmake:
extends: .build_esp_idf_unit_test_template extends: .build_template
artifacts:
paths:
- tools/unit-test-app/output/${IDF_TARGET}
- tools/unit-test-app/builds/${IDF_TARGET}/*.json
- components/idf_test/unit_test/*.yml
- ${LOG_PATH}
when: always
expire_in: 4 days
only:
variables:
- $BOT_TRIGGER_WITH_LABEL == null
- $BOT_LABEL_BUILD
- $BOT_LABEL_UNIT_TEST
- $BOT_LABEL_UNIT_TEST_S2
- $BOT_LABEL_REGULAR_TEST
variables:
LOG_PATH: "$CI_PROJECT_DIR/log_ut_cmake"
script: script:
- export EXTRA_CFLAGS=${PEDANTIC_CFLAGS} - export EXTRA_CFLAGS=${PEDANTIC_CFLAGS}
- export EXTRA_CXXFLAGS=${PEDANTIC_CXXFLAGS} - export EXTRA_CXXFLAGS=${PEDANTIC_CXXFLAGS}
- export IDF_TARGET=esp32 - mkdir -p ${LOG_PATH}
- ${CI_PROJECT_DIR}/tools/ci/build_unit_test.sh
- cd $CI_PROJECT_DIR/tools/unit-test-app - cd $CI_PROJECT_DIR/tools/unit-test-app
- MAKEFLAGS= make help # make sure kconfig tools are built in single process
- make ut-clean-all-configs
- make ut-build-all-configs
- python tools/UnitTestParser.py - python tools/UnitTestParser.py
# Check if the tests demand Make built binaries. If not, delete them
- if [ "$UNIT_TEST_BUILD_SYSTEM" == "make" ]; then exit 0; fi
- rm -rf builds output sdkconfig
- rm $CI_PROJECT_DIR/components/idf_test/unit_test/TestCaseAll.yml
build_esp_idf_tests_cmake: build_esp_idf_tests_cmake_esp32:
extends: .build_esp_idf_unit_test_template extends: .build_esp_idf_tests_cmake
script: variables:
- export PATH="$IDF_PATH/tools:$PATH" IDF_TARGET: esp32
- export EXTRA_CFLAGS=${PEDANTIC_CFLAGS}
- export EXTRA_CXXFLAGS=${PEDANTIC_CXXFLAGS} build_esp_idf_tests_cmake_esp32s2:
- cd $CI_PROJECT_DIR/tools/unit-test-app extends: .build_esp_idf_tests_cmake
- idf.py ut-clean-all-configs variables:
- idf.py ut-build-all-configs IDF_TARGET: esp32s2
- python tools/UnitTestParser.py
# Check if the tests demand CMake built binaries. If not, delete them
- if [ "$UNIT_TEST_BUILD_SYSTEM" == "cmake" ]; then exit 0; fi
- rm -rf builds output sdkconfig
- rm $CI_PROJECT_DIR/components/idf_test/unit_test/TestCaseAll.yml
build_examples_make: build_examples_make:
extends: .build_template extends: .build_template

View File

@@ -110,8 +110,7 @@
stage: target_test stage: target_test
dependencies: dependencies:
- assign_test - assign_test
- build_esp_idf_tests_make - build_esp_idf_tests_cmake_esp32
- build_esp_idf_tests_cmake
only: only:
refs: refs:
- master - master
@@ -499,6 +498,9 @@ UT_034:
.unit_test_s2_template: .unit_test_s2_template:
extends: .unit_test_template extends: .unit_test_template
dependencies:
- assign_test
- build_esp_idf_tests_cmake_esp32s2
only: only:
refs: refs:
# Due to lack of runners, the tests are only done by manual trigger # Due to lack of runners, the tests are only done by manual trigger

View File

@@ -36,6 +36,7 @@ tools/ci/apply_bot_filter.py
tools/ci/build_examples.sh tools/ci/build_examples.sh
tools/ci/build_examples_cmake.sh tools/ci/build_examples_cmake.sh
tools/ci/build_test_apps.sh tools/ci/build_test_apps.sh
tools/ci/build_unit_test.sh
tools/ci/check-executable.sh tools/ci/check-executable.sh
tools/ci/check-line-endings.sh tools/ci/check-line-endings.sh
tools/ci/check_build_warnings.py tools/ci/check_build_warnings.py
@@ -43,7 +44,6 @@ tools/ci/check_deprecated_kconfigs.py
tools/ci/check_examples_cmake_make.sh tools/ci/check_examples_cmake_make.sh
tools/ci/check_examples_rom_header.sh tools/ci/check_examples_rom_header.sh
tools/ci/check_idf_version.sh tools/ci/check_idf_version.sh
tools/ci/check_public_headers.sh
tools/ci/check_ut_cmake_make.sh tools/ci/check_ut_cmake_make.sh
tools/ci/checkout_project_ref.py tools/ci/checkout_project_ref.py
tools/ci/deploy_docs.py tools/ci/deploy_docs.py

View File

@@ -53,7 +53,6 @@ from . import (CaseConfig, SearchCases, GitlabCIJob, console_log)
class Group(object): class Group(object):
MAX_EXECUTION_TIME = 30 MAX_EXECUTION_TIME = 30
MAX_CASE = 15 MAX_CASE = 15
SORT_KEYS = ["env_tag"] SORT_KEYS = ["env_tag"]

View File

@@ -1,7 +1,7 @@
""" """
Command line tool to assign unit tests to CI test jobs. Command line tool to assign unit tests to CI test jobs.
""" """
import os
import re import re
import argparse import argparse
@@ -46,7 +46,7 @@ class Group(CIAssignTest.Group):
for key in self.filters: for key in self.filters:
if self._get_case_attr(case, key) != self.filters[key]: if self._get_case_attr(case, key) != self.filters[key]:
if key == "tags": if key == "tags":
if self._get_case_attr(case, key).issubset(self.filters[key]): if set(self._get_case_attr(case, key)).issubset(set(self.filters[key])):
continue continue
break break
else: else:
@@ -145,15 +145,33 @@ class UnitTestAssignTest(CIAssignTest.AssignTest):
The unit test cases is stored in a yaml file which is created in job build-idf-test. The unit test cases is stored in a yaml file which is created in job build-idf-test.
""" """
try: def find_by_suffix(suffix, path):
with open(test_case_path, "r") as f: res = []
raw_data = yaml.load(f, Loader=Loader) for root, _, files in os.walk(path):
test_cases = raw_data["test cases"] for file in files:
for case in test_cases: if file.endswith(suffix):
case["tags"] = set(case["tags"]) res.append(os.path.join(root, file))
except IOError: return res
def get_test_cases_from_yml(yml_file):
try:
with open(yml_file) as fr:
raw_data = yaml.load(fr, Loader=Loader)
test_cases = raw_data['test cases']
except (IOError, KeyError):
return []
else:
return test_cases
test_cases = []
if os.path.isdir(test_case_path):
for yml_file in find_by_suffix('.yml', test_case_path):
test_cases.extend(get_test_cases_from_yml(yml_file))
elif os.path.isfile(test_case_path):
test_cases.extend(get_test_cases_from_yml(test_case_path))
else:
print("Test case path is invalid. Should only happen when use @bot to skip unit test.") print("Test case path is invalid. Should only happen when use @bot to skip unit test.")
test_cases = []
# filter keys are lower case. Do map lower case keys with original keys. # filter keys are lower case. Do map lower case keys with original keys.
try: try:
key_mapping = {x.lower(): x for x in test_cases[0].keys()} key_mapping = {x.lower(): x for x in test_cases[0].keys()}

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

@@ -35,7 +35,10 @@ def dict_from_sdkconfig(path):
for line in f: for line in f:
m = regex.match(line) m = regex.match(line)
if m: if m:
result[m.group(1)] = m.group(2) val = m.group(2)
if val.startswith('"') and val.endswith('"'):
val = val[1:-1]
result[m.group(1)] = val
return result return result

View File

@@ -15,12 +15,21 @@ IDF_PY = "idf.py"
CMAKE_PROJECT_LINE = r"include($ENV{IDF_PATH}/tools/cmake/project.cmake)" CMAKE_PROJECT_LINE = r"include($ENV{IDF_PATH}/tools/cmake/project.cmake)"
SUPPORTED_TARGETS_REGEX = re.compile(r'Supported [Tt]argets((?:[\s|]+(?:ESP[0-9A-Z\-]+))+)') SUPPORTED_TARGETS_REGEX = re.compile(r'Supported [Tt]argets((?:[\s|]+(?:ESP[0-9A-Z\-]+))+)')
SDKCONFIG_LINE_REGEX = re.compile(r"^([^=]+)=\"?([^\"\n]*)\"?\n*$")
FORMAL_TO_USUAL = { FORMAL_TO_USUAL = {
'ESP32': 'esp32', 'ESP32': 'esp32',
'ESP32-S2': 'esp32s2', 'ESP32-S2': 'esp32s2',
} }
# If these keys are present in sdkconfig.defaults, they will be extracted and passed to CMake
SDKCONFIG_TEST_OPTS = [
"EXCLUDE_COMPONENTS",
"TEST_EXCLUDE_COMPONENTS",
"TEST_COMPONENTS",
"TEST_GROUPS"
]
class CMakeBuildSystem(BuildSystem): class CMakeBuildSystem(BuildSystem):
NAME = BUILD_SYSTEM_CMAKE NAME = BUILD_SYSTEM_CMAKE
@@ -69,6 +78,7 @@ class CMakeBuildSystem(BuildSystem):
if not build_item.dry_run: if not build_item.dry_run:
os.unlink(sdkconfig_file) os.unlink(sdkconfig_file)
extra_cmakecache_items = {}
logging.debug("Creating sdkconfig file: {}".format(sdkconfig_file)) logging.debug("Creating sdkconfig file: {}".format(sdkconfig_file))
if not build_item.dry_run: if not build_item.dry_run:
with open(sdkconfig_file, "w") as f_out: with open(sdkconfig_file, "w") as f_out:
@@ -81,13 +91,11 @@ class CMakeBuildSystem(BuildSystem):
for line in f_in: for line in f_in:
if not line.endswith("\n"): if not line.endswith("\n"):
line += "\n" line += "\n"
m = SDKCONFIG_LINE_REGEX.match(line)
if m and m.group(1) in SDKCONFIG_TEST_OPTS:
extra_cmakecache_items[m.group(1)] = m.group(2)
continue
f_out.write(os.path.expandvars(line)) f_out.write(os.path.expandvars(line))
# Also save the sdkconfig file in the build directory
shutil.copyfile(
os.path.join(work_path, "sdkconfig"),
os.path.join(build_path, "sdkconfig"),
)
else: else:
for sdkconfig_name in sdkconfig_defaults_list: for sdkconfig_name in sdkconfig_defaults_list:
sdkconfig_path = os.path.join(app_path, sdkconfig_name) sdkconfig_path = os.path.join(app_path, sdkconfig_name)
@@ -109,6 +117,11 @@ class CMakeBuildSystem(BuildSystem):
work_path, work_path,
"-DIDF_TARGET=" + build_item.target, "-DIDF_TARGET=" + build_item.target,
] ]
for key, val in extra_cmakecache_items.items():
args.append("-D{}={}".format(key, val))
if "TEST_EXCLUDE_COMPONENTS" in extra_cmakecache_items \
and "TEST_COMPONENTS" not in extra_cmakecache_items:
args.append("-DTESTS_ALL=1")
if build_item.verbose: if build_item.verbose:
args.append("-v") args.append("-v")
args.append("build") args.append("build")
@@ -131,6 +144,12 @@ class CMakeBuildSystem(BuildSystem):
subprocess.check_call(args, stdout=build_stdout, stderr=build_stderr) subprocess.check_call(args, stdout=build_stdout, stderr=build_stderr)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
raise BuildError("Build failed with exit code {}".format(e.returncode)) raise BuildError("Build failed with exit code {}".format(e.returncode))
else:
# Also save the sdkconfig file in the build directory
shutil.copyfile(
os.path.join(work_path, "sdkconfig"),
os.path.join(build_path, "sdkconfig"),
)
finally: finally:
if log_file: if log_file:
log_file.close() log_file.close()

View File

@@ -1,3 +1,4 @@
# This config is for all targets
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update test_utils TEST_EXCLUDE_COMPONENTS=libsodium bt app_update test_utils
TEST_COMPONENTS=mbedtls TEST_COMPONENTS=mbedtls
CONFIG_MBEDTLS_HARDWARE_AES=n CONFIG_MBEDTLS_HARDWARE_AES=n

View File

@@ -1,4 +0,0 @@
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update test_utils
TEST_COMPONENTS=mbedtls
CONFIG_MBEDTLS_HARDWARE_AES=n
CONFIG_IDF_TARGET="esp32s2"

View File

@@ -1,3 +1,5 @@
# This config is split between targets since different component needs to be excluded (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=app_update TEST_COMPONENTS=app_update
TEST_EXCLUDE_COMPONENTS=libsodium bt TEST_EXCLUDE_COMPONENTS=libsodium bt
CONFIG_UNITY_FREERTOS_STACK_SIZE=12288 CONFIG_UNITY_FREERTOS_STACK_SIZE=12288

View File

@@ -1,3 +1,5 @@
# This config is split between targets since different component needs to be excluded (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32s2"
TEST_COMPONENTS=app_update TEST_COMPONENTS=app_update
TEST_EXCLUDE_COMPONENTS=libsodium bt TEST_EXCLUDE_COMPONENTS=libsodium bt
CONFIG_UNITY_FREERTOS_STACK_SIZE=12288 CONFIG_UNITY_FREERTOS_STACK_SIZE=12288
@@ -11,4 +13,3 @@ CONFIG_BOOTLOADER_HOLD_TIME_GPIO=2
CONFIG_BOOTLOADER_OTA_DATA_ERASE=y CONFIG_BOOTLOADER_OTA_DATA_ERASE=y
CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET=4 CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET=4
CONFIG_BOOTLOADER_NUM_PIN_APP_TEST=18 CONFIG_BOOTLOADER_NUM_PIN_APP_TEST=18
CONFIG_IDF_TARGET="esp32s2"

View File

@@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=bt TEST_COMPONENTS=bt
TEST_EXCLUDE_COMPONENTS=app_update TEST_EXCLUDE_COMPONENTS=app_update
CONFIG_BT_ENABLED=y CONFIG_BT_ENABLED=y

View File

@@ -1,2 +1,4 @@
# Only need to test this for one target (e.g. ESP32)
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=cxx TEST_COMPONENTS=cxx
CONFIG_COMPILER_CXX_EXCEPTIONS=y CONFIG_COMPILER_CXX_EXCEPTIONS=y

View File

@@ -1,3 +1,5 @@
# Only need to test this for one target (e.g. ESP32)
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=cxx TEST_COMPONENTS=cxx
CONFIG_COMPILER_CXX_EXCEPTIONS=y CONFIG_COMPILER_CXX_EXCEPTIONS=y
CONFIG_COMPILER_CXX_RTTI=y CONFIG_COMPILER_CXX_RTTI=y

View File

@@ -1 +1,3 @@
# This config is split between targets since different component needs to be included (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=freertos esp32 esp_timer driver heap pthread soc spi_flash vfs TEST_COMPONENTS=freertos esp32 esp_timer driver heap pthread soc spi_flash vfs

View File

@@ -1 +1,3 @@
# This config is split between targets since different component needs to be excluded (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32"
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_timer driver heap pthread soc spi_flash vfs test_utils TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_timer driver heap pthread soc spi_flash vfs test_utils

View File

@@ -1,2 +1,3 @@
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs # This config is split between targets since different component needs to be excluded (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32s2" CONFIG_IDF_TARGET="esp32s2"
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs

View File

@@ -1,2 +1,3 @@
TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs # This config is split between targets since different component needs to be included (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32s2" CONFIG_IDF_TARGET="esp32s2"
TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs

View File

@@ -1,3 +1,5 @@
# This config is for ESP32 only (no ESP32-S2 flash encryption support yet)
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=spi_flash TEST_COMPONENTS=spi_flash
TEST_GROUPS=flash_encryption TEST_GROUPS=flash_encryption
CONFIG_SECURE_FLASH_ENC_ENABLED=y CONFIG_SECURE_FLASH_ENC_ENABLED=y

View File

@@ -1,2 +1,4 @@
# This config is split between targets since different component needs to be included (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=driver esp32 esp_timer spi_flash TEST_COMPONENTS=driver esp32 esp_timer spi_flash
CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y

View File

@@ -1,3 +1,4 @@
# This config is split between targets since different component needs to be included (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32s2"
TEST_COMPONENTS=driver esp32s2 esp_timer spi_flash TEST_COMPONENTS=driver esp32s2 esp_timer spi_flash
CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y
CONFIG_IDF_TARGET="esp32s2"

View File

@@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=libsodium TEST_COMPONENTS=libsodium
TEST_EXCLUDE_COMPONENTS=bt app_update TEST_EXCLUDE_COMPONENTS=bt app_update
CONFIG_UNITY_FREERTOS_STACK_SIZE=12288 CONFIG_UNITY_FREERTOS_STACK_SIZE=12288

View File

@@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32"
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update driver esp32 esp_timer mbedtls spi_flash test_utils heap pthread soc TEST_EXCLUDE_COMPONENTS=libsodium bt app_update driver esp32 esp_timer mbedtls spi_flash test_utils heap pthread soc
CONFIG_ESP32_SPIRAM_SUPPORT=y CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 CONFIG_ESP_INT_WDT_TIMEOUT_MS=800

View File

@@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=esp32 esp_timer mbedtls spi_flash heap pthread soc TEST_COMPONENTS=esp32 esp_timer mbedtls spi_flash heap pthread soc
CONFIG_ESP32_SPIRAM_SUPPORT=y CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 CONFIG_ESP_INT_WDT_TIMEOUT_MS=800

View File

@@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=driver TEST_COMPONENTS=driver
CONFIG_ESP32_SPIRAM_SUPPORT=y CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 CONFIG_ESP_INT_WDT_TIMEOUT_MS=800

View File

@@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=esp32 esp_timer TEST_COMPONENTS=esp32 esp_timer
CONFIG_ESP32_SPIRAM_SUPPORT=y CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_BANKSWITCH_ENABLE=y CONFIG_SPIRAM_BANKSWITCH_ENABLE=y

View File

@@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=esp32 TEST_COMPONENTS=esp32
TEST_GROUPS=psram_4m TEST_GROUPS=psram_4m
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y

View File

@@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=esp32 TEST_COMPONENTS=esp32
TEST_GROUPS=psram_4m TEST_GROUPS=psram_4m
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y

View File

@@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=freertos esp32 esp_timer driver heap pthread soc spi_flash vfs TEST_COMPONENTS=freertos esp32 esp_timer driver heap pthread soc spi_flash vfs
CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y

View File

@@ -1,3 +1,5 @@
# This config is split between targets since different component needs to be included (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32"
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_timer driver heap pthread soc spi_flash vfs test_utils TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_timer driver heap pthread soc spi_flash vfs test_utils
CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y

View File

@@ -1,5 +1,6 @@
# This config is split between targets since different component needs to be excluded (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32s2"
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs test_utils TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs test_utils
CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_IDF_TARGET="esp32s2"

View File

@@ -1,5 +1,6 @@
# This config is split between targets since different component needs to be included (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32s2"
TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs
CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_IDF_TARGET="esp32s2"

View File

@@ -1,3 +1,5 @@
# This config is split between targets since different component needs to be included (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32"
TEST_COMPONENTS=freertos esp32 esp_timer driver heap pthread soc spi_flash vfs TEST_COMPONENTS=freertos esp32 esp_timer driver heap pthread soc spi_flash vfs
CONFIG_MEMMAP_SMP=n CONFIG_MEMMAP_SMP=n
CONFIG_FREERTOS_UNICORE=y CONFIG_FREERTOS_UNICORE=y

View File

@@ -1,3 +1,5 @@
# This config is split between targets since different component needs to be excluded (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32"
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_timer driver heap pthread soc spi_flash vfs test_utils TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_timer driver heap pthread soc spi_flash vfs test_utils
CONFIG_MEMMAP_SMP=n CONFIG_MEMMAP_SMP=n
CONFIG_FREERTOS_UNICORE=y CONFIG_FREERTOS_UNICORE=y

View File

@@ -1,5 +1,6 @@
# This config is split between targets since different component needs to be excluded (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32s2"
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs
CONFIG_MEMMAP_SMP=n CONFIG_MEMMAP_SMP=n
CONFIG_FREERTOS_UNICORE=y CONFIG_FREERTOS_UNICORE=y
CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y
CONFIG_IDF_TARGET="esp32s2"

View File

@@ -1,5 +1,6 @@
# This config is split between targets since different component needs to be included (esp32, esp32s2)
CONFIG_IDF_TARGET="esp32s2"
TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs test_utils TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs test_utils
CONFIG_MEMMAP_SMP=n CONFIG_MEMMAP_SMP=n
CONFIG_FREERTOS_UNICORE=y CONFIG_FREERTOS_UNICORE=y
CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y
CONFIG_IDF_TARGET="esp32s2"

View File

@@ -1,3 +1,4 @@
# This config is for all targets
TEST_COMPONENTS=spi_flash TEST_COMPONENTS=spi_flash
CONFIG_ESP32_SPIRAM_SUPPORT=y CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y

View File

@@ -1,4 +0,0 @@
TEST_COMPONENTS=spi_flash
CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y
CONFIG_IDF_TARGET="esp32s2"

View File

@@ -1,3 +1,4 @@
# This config is for all targets
# The test is isolated as it requires particular memory layout # The test is isolated as it requires particular memory layout
TEST_COMPONENTS=test_utils TEST_COMPONENTS=test_utils
CONFIG_ESP_IPC_TASK_STACK_SIZE=2048 CONFIG_ESP_IPC_TASK_STACK_SIZE=2048

View File

@@ -1,3 +1,5 @@
# This config is for esp32 only
CONFIG_IDF_TARGET="esp32"
# The test is isolated as it requires particular memory layout # The test is isolated as it requires particular memory layout
TEST_COMPONENTS=test_utils TEST_COMPONENTS=test_utils
CONFIG_ESP_IPC_TASK_STACK_SIZE=2048 CONFIG_ESP_IPC_TASK_STACK_SIZE=2048

View File

@@ -1,5 +0,0 @@
# The test is isolated as it requires particular memory layout
TEST_COMPONENTS=test_utils
CONFIG_ESP_IPC_TASK_STACK_SIZE=2048
CONFIG_IDF_TARGET="esp32s2"

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__':