kopia lustrzana https://github.com/espressif/esp-idf
CI: add size info for binaries
rodzic
789e99a37d
commit
6885421976
|
@ -107,7 +107,7 @@ void ets_secure_boot_verify_boot_bootloader(void);
|
|||
* @return true if is Secure boot v2 has been enabled
|
||||
* False if Secure boot v2 has not been enabled.
|
||||
*/
|
||||
bool ets_use_secure_boot_v2();
|
||||
bool ets_use_secure_boot_v2(void);
|
||||
|
||||
#endif /* CONFIG_ESP32_REV_MIN_3 */
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import ttfw_idf
|
||||
|
||||
|
||||
@ttfw_idf.idf_example_test(env_tag="Example_GENERIC", target=['esp32', 'esp32s2'], ci_target=['esp32'])
|
||||
def test_examples_hello_world(env, extra_data):
|
||||
app_name = 'hello_world'
|
||||
dut = env.get_dut(app_name, "examples/get-started/hello_world")
|
||||
dut.start_app()
|
||||
res = dut.expect(ttfw_idf.MINIMUM_FREE_HEAP_SIZE_RE)
|
||||
if not res:
|
||||
raise ValueError('Maximum heap size info not found')
|
||||
ttfw_idf.print_heap_size(app_name, dut.app.config_name, dut.TARGET, res[0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_examples_hello_world()
|
|
@ -31,7 +31,7 @@ void app_main(void)
|
|||
printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
|
||||
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
|
||||
|
||||
printf("Free heap: %d\n", esp_get_free_heap_size());
|
||||
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
|
||||
|
||||
for (int i = 10; i >= 0; i--) {
|
||||
printf("Restarting in %d seconds...\n", i);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import ttfw_idf
|
||||
|
||||
|
||||
@ttfw_idf.idf_example_test(env_tag="Example_TWAI1", target=['esp32', 'esp32s2'], ci_target=['esp32'])
|
||||
def test_examples_gpio(env, extra_data):
|
||||
app_name = "gpio"
|
||||
dut = env.get_dut(app_name, "examples/peripherals/gpio")
|
||||
dut.start_app()
|
||||
res = dut.expect(ttfw_idf.MINIMUM_FREE_HEAP_SIZE_RE)
|
||||
if not res:
|
||||
raise ValueError('Maximum heap size info not found')
|
||||
ttfw_idf.print_heap_size(app_name, dut.app.config_name, dut.TARGET, res[0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_examples_gpio()
|
|
@ -103,6 +103,8 @@ void app_main(void)
|
|||
//hook isr handler for specific gpio pin again
|
||||
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
|
||||
|
||||
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
|
||||
|
||||
int cnt = 0;
|
||||
while(1) {
|
||||
printf("cnt: %d\n", cnt++);
|
||||
|
|
|
@ -65,6 +65,11 @@ def main():
|
|||
type=argparse.FileType("w"),
|
||||
help="If specified, the list of builds (with all the placeholders expanded) will be written to this file.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--size-info",
|
||||
type=argparse.FileType("a"),
|
||||
help="If specified, the test case name and size info json will be written to this file"
|
||||
)
|
||||
parser.add_argument(
|
||||
"build_list",
|
||||
type=argparse.FileType("r"),
|
||||
|
@ -119,6 +124,8 @@ def main():
|
|||
else:
|
||||
raise SystemExit(1)
|
||||
else:
|
||||
if args.size_info:
|
||||
build_info.write_size_info(args.size_info)
|
||||
if not build_info.preserve:
|
||||
logging.info("Removing build directory {}".format(build_info.build_dir))
|
||||
# we only remove binaries here, log files are still needed by check_build_warnings.py
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build all examples from the examples directory, in BUILD_PATH to
|
||||
# ensure they can run when copied to a new directory.
|
||||
#
|
||||
# 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 ${BUILD_PATH} ] && die "BUILD_PATH is not set"
|
||||
[ -z ${IDF_TARGET} ] && die "IDF_TARGET is not set"
|
||||
[ -z ${EXAMPLE_TEST_BUILD_SYSTEM} ] && die "EXAMPLE_TEST_BUILD_SYSTEM is not set"
|
||||
[ -z ${SCAN_EXAMPLE_TEST_JSON} ] && die "SCAN_EXAMPLE_TEST_JSON is not set"
|
||||
[ -d ${LOG_PATH} ] || mkdir -p ${LOG_PATH}
|
||||
[ -d ${BUILD_PATH} ] || mkdir -p ${BUILD_PATH}
|
||||
|
||||
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
|
||||
|
||||
|
||||
export EXTRA_CFLAGS="${PEDANTIC_CFLAGS:-}"
|
||||
export EXTRA_CXXFLAGS="${PEDANTIC_CXXFLAGS:-}"
|
||||
|
||||
set -o nounset # Exit if variable not set.
|
||||
|
||||
export REALPATH=realpath
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
export REALPATH=grealpath
|
||||
fi
|
||||
|
||||
# Convert LOG_PATH and BUILD_PATH to relative, to make the json file less verbose.
|
||||
LOG_PATH=$(${REALPATH} --relative-to ${IDF_PATH} ${LOG_PATH})
|
||||
BUILD_PATH=$(${REALPATH} --relative-to ${IDF_PATH} ${BUILD_PATH})
|
||||
|
||||
ALL_BUILD_LIST_JSON="${BUILD_PATH}/list.json"
|
||||
JOB_BUILD_LIST_JSON="${BUILD_PATH}/list_job_${CI_NODE_INDEX}.json"
|
||||
|
||||
echo "build_examples running for target $IDF_TARGET"
|
||||
|
||||
cd ${IDF_PATH}
|
||||
|
||||
# This part of the script produces the same result for all the example 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.
|
||||
|
||||
# If changing the work-dir or build-dir format, remember to update the "artifacts" in gitlab-ci configs, and IDFApp.py.
|
||||
|
||||
${IDF_PATH}/tools/find_apps.py \
|
||||
-vv \
|
||||
--format json \
|
||||
--work-dir "${BUILD_PATH}/@f/@w/@t" \
|
||||
--build-dir build \
|
||||
--build-log "${LOG_PATH}/@f_@w.txt" \
|
||||
--output ${ALL_BUILD_LIST_JSON} \
|
||||
--config 'sdkconfig.ci=default' \
|
||||
--config 'sdkconfig.ci.*=' \
|
||||
--config '=default' \
|
||||
--app-list ${SCAN_EXAMPLE_TEST_JSON}
|
||||
|
||||
# --config rules above explained:
|
||||
# 1. If sdkconfig.ci exists, use it build the example with configuration name "default"
|
||||
# 2. If sdkconfig.ci.* exists, use it to build the "*" configuration
|
||||
# 3. If none of the above exist, build the default configuration under the name "default"
|
||||
|
||||
# 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}\
|
||||
|
||||
|
||||
# Check for build warnings
|
||||
${IDF_PATH}/tools/ci/check_build_warnings.py -vv ${JOB_BUILD_LIST_JSON}
|
|
@ -1,100 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build test apps
|
||||
#
|
||||
# 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 ${BUILD_PATH} ] && die "BUILD_PATH is not set"
|
||||
[ -z ${IDF_TARGET} ] && die "IDF_TARGET is not set"
|
||||
[ -z ${SCAN_CUSTOM_TEST_JSON} ] && die "SCAN_CUSTOM_TEST_JSON is not set"
|
||||
[ -d ${LOG_PATH} ] || mkdir -p ${LOG_PATH}
|
||||
[ -d ${BUILD_PATH} ] || mkdir -p ${BUILD_PATH}
|
||||
|
||||
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})
|
||||
BUILD_PATH=$(realpath --relative-to ${IDF_PATH} ${BUILD_PATH})
|
||||
|
||||
ALL_BUILD_LIST_JSON="${BUILD_PATH}/list.json"
|
||||
JOB_BUILD_LIST_JSON="${BUILD_PATH}/list_job_${CI_NODE_INDEX}.json"
|
||||
|
||||
echo "build_test_apps running for target $IDF_TARGET"
|
||||
|
||||
cd ${IDF_PATH}
|
||||
|
||||
# This part of the script produces the same result for all the 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.
|
||||
|
||||
# If changing the work-dir or build-dir, remember to update the "artifacts" in gitlab-ci configs, and IDFApp.py.
|
||||
|
||||
${IDF_PATH}/tools/find_apps.py \
|
||||
-vv \
|
||||
--format json \
|
||||
--work-dir "${BUILD_PATH}/@f/@w/@t" \
|
||||
--build-dir build \
|
||||
--build-log "${LOG_PATH}/@f_@w.txt" \
|
||||
--output ${ALL_BUILD_LIST_JSON} \
|
||||
--config 'sdkconfig.ci=default' \
|
||||
--config 'sdkconfig.ci.*=' \
|
||||
--config '=default' \
|
||||
--app-list ${SCAN_CUSTOM_TEST_JSON}
|
||||
|
||||
# --config rules above explained:
|
||||
# 1. If sdkconfig.ci exists, use it build the example with configuration name "default"
|
||||
# 2. If sdkconfig.ci.* exists, use it to build the "*" configuration
|
||||
# 3. If none of the above exist, build the default configuration under the name "default"
|
||||
# --work-dir and --build-log above uses "placeholders" @x:
|
||||
# - @f: full path to the test with slashes replaced with underscores
|
||||
# - @w: wildcard used as config name
|
||||
# - @t: target name
|
||||
# so the workdir .../@f/@w/@t would expand to e.g. tools_test_apps_system_startup/default/esp32
|
||||
|
||||
# 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}\
|
||||
|
||||
|
||||
# Check for build warnings
|
||||
${IDF_PATH}/tools/ci/check_build_warnings.py -vv ${JOB_BUILD_LIST_JSON}
|
|
@ -1,108 +0,0 @@
|
|||
#!/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 \
|
||||
-p 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}
|
|
@ -6,6 +6,7 @@
|
|||
variables:
|
||||
BATCH_BUILD: "1"
|
||||
V: "0"
|
||||
SIZE_INFO_LOCATION: "$CI_PROJECT_DIR/size_info.txt"
|
||||
|
||||
.build_ssc_template:
|
||||
extends: .build_template
|
||||
|
@ -45,8 +46,10 @@ build_ssc_esp32s2:
|
|||
paths:
|
||||
- tools/unit-test-app/output/${IDF_TARGET}
|
||||
- tools/unit-test-app/builds/${IDF_TARGET}/*.json
|
||||
- tools/unit-test-app/builds/${IDF_TARGET}/*/size.json
|
||||
- components/idf_test/unit_test/*.yml
|
||||
- ${LOG_PATH}
|
||||
- $LOG_PATH
|
||||
- $SIZE_INFO_LOCATION
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
only:
|
||||
|
@ -58,16 +61,17 @@ build_ssc_esp32s2:
|
|||
- $BOT_LABEL_REGULAR_TEST
|
||||
variables:
|
||||
LOG_PATH: "$CI_PROJECT_DIR/log_ut_cmake"
|
||||
BUILD_PATH: ${CI_PROJECT_DIR}/tools/unit-test-app/builds
|
||||
OUTPUT_PATH: ${CI_PROJECT_DIR}/tools/unit-test-app/output
|
||||
BUILD_SYSTEM: "cmake"
|
||||
TEST_TYPE: "unit_test"
|
||||
script:
|
||||
# RISC-V toolchain is optional but ULP may need it, so install:
|
||||
- $IDF_PATH/tools/idf_tools.py install riscv-none-embed-gcc
|
||||
- . $IDF_PATH/export.sh
|
||||
- export EXTRA_CFLAGS=${PEDANTIC_CFLAGS}
|
||||
- export EXTRA_CXXFLAGS=${PEDANTIC_CXXFLAGS}
|
||||
- mkdir -p ${LOG_PATH}
|
||||
- ${CI_PROJECT_DIR}/tools/ci/build_unit_test.sh
|
||||
- ${IDF_PATH}/tools/ci/find_apps_build_apps.sh
|
||||
- cd $CI_PROJECT_DIR/tools/unit-test-app
|
||||
- python tools/UnitTestParser.py
|
||||
- python tools/UnitTestParser.py ${BUILD_PATH}
|
||||
|
||||
build_esp_idf_tests_cmake_esp32:
|
||||
extends: .build_esp_idf_tests_cmake
|
||||
|
@ -85,8 +89,6 @@ build_esp_idf_tests_cmake_esp32s2:
|
|||
artifacts:
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
variables:
|
||||
SCAN_EXAMPLE_TEST_JSON: ${CI_PROJECT_DIR}/examples/test_configs/scan_${IDF_TARGET}_${EXAMPLE_TEST_BUILD_SYSTEM}.json
|
||||
only:
|
||||
# Here both 'variables' and 'refs' conditions are given. They are combined with "AND" logic.
|
||||
variables:
|
||||
|
@ -95,15 +97,16 @@ build_esp_idf_tests_cmake_esp32s2:
|
|||
- $BOT_LABEL_EXAMPLE_TEST
|
||||
- $BOT_LABEL_REGULAR_TEST
|
||||
- $BOT_LABEL_WEEKEND_TEST
|
||||
variables:
|
||||
SCAN_TEST_JSON: ${CI_PROJECT_DIR}/examples/test_configs/scan_${IDF_TARGET}_${BUILD_SYSTEM}.json
|
||||
TEST_TYPE: "example_test"
|
||||
script:
|
||||
# RISC-V toolchain is optional but ULP may need it, so install:
|
||||
# RISC-V toolchain is optional but ULP may need it, so install:
|
||||
- $IDF_PATH/tools/idf_tools.py install riscv-none-embed-gcc
|
||||
- . $IDF_PATH/export.sh
|
||||
# it's not possible to build 100% out-of-tree and have the "artifacts"
|
||||
# mechanism work, but this is the next best thing
|
||||
- mkdir ${BUILD_PATH}
|
||||
- mkdir -p ${LOG_PATH}
|
||||
- ${IDF_PATH}/tools/ci/build_examples.sh
|
||||
- ${IDF_PATH}/tools/ci/find_apps_build_apps.sh
|
||||
|
||||
build_examples_make:
|
||||
extends: .build_examples_template
|
||||
|
@ -113,10 +116,12 @@ build_examples_make:
|
|||
artifacts:
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
- build_examples/*/*/*/build/size.json
|
||||
- $SIZE_INFO_LOCATION
|
||||
variables:
|
||||
LOG_PATH: "${CI_PROJECT_DIR}/log_examples_make"
|
||||
BUILD_PATH: "${CI_PROJECT_DIR}/build_examples_make"
|
||||
EXAMPLE_TEST_BUILD_SYSTEM: "make"
|
||||
BUILD_SYSTEM: "make"
|
||||
IDF_TARGET: "esp32" # currently we only support esp32
|
||||
only:
|
||||
refs:
|
||||
|
@ -138,6 +143,7 @@ build_examples_make:
|
|||
- build_examples/list.json
|
||||
- build_examples/list_job_*.json
|
||||
- build_examples/*/*/*/sdkconfig
|
||||
- build_examples/*/*/*/build/size.json
|
||||
- build_examples/*/*/*/build/*.bin
|
||||
- build_examples/*/*/*/build/*.elf
|
||||
- build_examples/*/*/*/build/*.map
|
||||
|
@ -145,10 +151,11 @@ build_examples_make:
|
|||
- build_examples/*/*/*/build/bootloader/*.bin
|
||||
- build_examples/*/*/*/build/partition_table/*.bin
|
||||
- $LOG_PATH
|
||||
- $SIZE_INFO_LOCATION
|
||||
variables:
|
||||
LOG_PATH: "${CI_PROJECT_DIR}/log_examples"
|
||||
BUILD_PATH: "${CI_PROJECT_DIR}/build_examples"
|
||||
EXAMPLE_TEST_BUILD_SYSTEM: "cmake"
|
||||
BUILD_SYSTEM: "cmake"
|
||||
|
||||
build_examples_cmake_esp32:
|
||||
extends: .build_examples_cmake
|
||||
|
@ -170,20 +177,23 @@ build_examples_cmake_esp32s2:
|
|||
paths:
|
||||
- build_test_apps/list.json
|
||||
- build_test_apps/list_job_*.json
|
||||
- build_test_apps/*/*/*/build/*.bin
|
||||
- build_test_apps/*/*/*/sdkconfig
|
||||
- build_test_apps/*/*/*/build/size.json
|
||||
- build_test_apps/*/*/*/build/*.bin
|
||||
- build_test_apps/*/*/*/build/*.elf
|
||||
- build_test_apps/*/*/*/build/*.map
|
||||
- build_test_apps/*/*/*/build/flasher_args.json
|
||||
- build_test_apps/*/*/*/build/bootloader/*.bin
|
||||
- build_test_apps/*/*/*/build/partition_table/*.bin
|
||||
- $LOG_PATH
|
||||
- $SIZE_INFO_LOCATION
|
||||
expire_in: 3 days
|
||||
variables:
|
||||
LOG_PATH: "${CI_PROJECT_DIR}/log_test_apps"
|
||||
BUILD_PATH: "${CI_PROJECT_DIR}/build_test_apps"
|
||||
CUSTOM_TEST_BUILD_SYSTEM: "cmake"
|
||||
SCAN_CUSTOM_TEST_JSON: ${CI_PROJECT_DIR}/tools/test_apps/test_configs/scan_${IDF_TARGET}_${CUSTOM_TEST_BUILD_SYSTEM}.json
|
||||
BUILD_SYSTEM: "cmake"
|
||||
SCAN_TEST_JSON: ${CI_PROJECT_DIR}/tools/test_apps/test_configs/scan_${IDF_TARGET}_${BUILD_SYSTEM}.json
|
||||
TEST_TYPE: custom_test
|
||||
only:
|
||||
variables:
|
||||
- $BOT_TRIGGER_WITH_LABEL == null
|
||||
|
@ -192,9 +202,7 @@ build_examples_cmake_esp32s2:
|
|||
- $BOT_LABEL_CUSTOM_TEST
|
||||
- $BOT_LABEL_WEEKEND_TEST
|
||||
script:
|
||||
- mkdir -p ${BUILD_PATH}
|
||||
- mkdir -p ${LOG_PATH}
|
||||
- ${IDF_PATH}/tools/ci/build_test_apps.sh
|
||||
- ${IDF_PATH}/tools/ci/find_apps_build_apps.sh
|
||||
|
||||
build_test_apps_esp32:
|
||||
extends: .build_test_apps
|
||||
|
|
|
@ -224,7 +224,7 @@ example_test_001B:
|
|||
|
||||
example_test_001C:
|
||||
extends: .example_test_template
|
||||
parallel: 2
|
||||
parallel: 3
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_GENERIC
|
||||
|
|
|
@ -33,10 +33,6 @@ tools/build_apps.py
|
|||
tools/check_kconfigs.py
|
||||
tools/check_python_dependencies.py
|
||||
tools/ci/apply_bot_filter.py
|
||||
tools/ci/build_examples.sh
|
||||
tools/ci/build_examples_cmake.sh
|
||||
tools/ci/build_test_apps.sh
|
||||
tools/ci/build_unit_test.sh
|
||||
tools/ci/check-executable.sh
|
||||
tools/ci/check-line-endings.sh
|
||||
tools/ci/check_build_warnings.py
|
||||
|
@ -50,6 +46,7 @@ tools/ci/check_ut_cmake_make.sh
|
|||
tools/ci/checkout_project_ref.py
|
||||
tools/ci/deploy_docs.py
|
||||
tools/ci/envsubst.py
|
||||
tools/ci/find_apps_build_apps.sh
|
||||
tools/ci/fix_empty_prototypes.sh
|
||||
tools/ci/get-full-sources.sh
|
||||
tools/ci/get_supported_examples.sh
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Find apps and build apps for example_test, custom_test, and unit_test
|
||||
#
|
||||
# Runs as part of CI process.
|
||||
#
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Safety settings (see https://gist.github.com/ilg-ul/383869cbb01f61a51c4d).
|
||||
|
||||
if [[ -n ${DEBUG_SHELL} ]]; then
|
||||
set -x # Activate the expand mode if DEBUG is anything but empty.
|
||||
fi
|
||||
|
||||
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 errexit # Exit if command failed.
|
||||
set -o pipefail # Exit if pipe failed.
|
||||
set -o nounset # Exit if variable not set.
|
||||
|
||||
export PATH="$IDF_PATH/tools/ci:$IDF_PATH/tools:$PATH"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
die() {
|
||||
echo "${1:-"Unknown Error"}" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ -d ${BUILD_PATH} ] || mkdir -p ${BUILD_PATH}
|
||||
[ -d ${LOG_PATH} ] || mkdir -p ${LOG_PATH}
|
||||
[ -f ${SIZE_INFO_LOCATION} ] && rm ${SIZE_INFO_LOCATION}
|
||||
|
||||
export REALPATH=realpath
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
export REALPATH=grealpath
|
||||
fi
|
||||
|
||||
# Convert LOG_PATH and BUILD_PATH to relative, to make the json file less verbose.
|
||||
BUILD_PATH=$(${REALPATH} --relative-to ${IDF_PATH} ${BUILD_PATH})
|
||||
LOG_PATH=$(${REALPATH} --relative-to ${IDF_PATH} ${LOG_PATH})
|
||||
|
||||
ALL_BUILD_LIST_JSON="${BUILD_PATH}/list.json"
|
||||
JOB_BUILD_LIST_JSON="${BUILD_PATH}/list_job_${CI_NODE_INDEX}.json"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# common variables, will specify special cases later
|
||||
WORK_DIR="--work-dir ${BUILD_PATH}/@f/@w/@t"
|
||||
BUILD_DIR="build"
|
||||
BUILD_LOG="${LOG_PATH}/@f_@w.txt"
|
||||
CONFIG="--config sdkconfig.ci=default
|
||||
--config sdkconfig.ci.*=
|
||||
--config =default"
|
||||
|
||||
export EXTRA_CFLAGS="${PEDANTIC_CFLAGS}"
|
||||
export EXTRA_CXXFLAGS="${PEDANTIC_CXXFLAGS}"
|
||||
|
||||
# --config rules above explained:
|
||||
# 1. If sdkconfig.ci exists, use it build the example with configuration name "default"
|
||||
# 2. If sdkconfig.ci.* exists, use it to build the "*" configuration
|
||||
# 3. If none of the above exist, build the default configuration under the name "default"
|
||||
# --work-dir and --build-log above uses "placeholders" @x:
|
||||
# - @f: full path to the test with slashes replaced with underscores
|
||||
# - @w: wildcard used as config name
|
||||
# - @t: target name
|
||||
# so the workdir .../@f/@w/@t would expand to e.g. tools_test_apps_system_startup/default/esp32
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Example tests specific settings
|
||||
if [ "${TEST_TYPE}" = "example_test" ]; then
|
||||
export EXTRA_CFLAGS="${PEDANTIC_CFLAGS:-}"
|
||||
export EXTRA_CXXFLAGS="${PEDANTIC_CXXFLAGS:-}"
|
||||
|
||||
EXTRA_ARGS="--app-list ${SCAN_TEST_JSON}"
|
||||
# -----------------------------------------------------------------------------
|
||||
# Custom tests specific settings
|
||||
elif [ "${TEST_TYPE}" = "custom_test" ]; then
|
||||
EXTRA_ARGS="--app-list ${SCAN_TEST_JSON}"
|
||||
# -----------------------------------------------------------------------------
|
||||
# Unit tests specific settings
|
||||
elif [ "${TEST_TYPE}" = "unit_test" ]; then
|
||||
ALL_BUILD_LIST_JSON="${BUILD_PATH}/${IDF_TARGET}/list.json"
|
||||
JOB_BUILD_LIST_JSON="${BUILD_PATH}/${IDF_TARGET}/list_job_${CI_NODE_INDEX}.json"
|
||||
|
||||
mkdir -p ${BUILD_PATH}/${IDF_TARGET}
|
||||
mkdir -p ${OUTPUT_PATH}/${IDF_TARGET}
|
||||
|
||||
WORK_DIR=""
|
||||
BUILD_DIR="builds/@t/@w"
|
||||
BUILD_LOG="${LOG_PATH}/@w.txt"
|
||||
|
||||
APP_FOLDER="tools/unit-test-app"
|
||||
|
||||
EXTRA_ARGS="
|
||||
-p ${APP_FOLDER}
|
||||
--build-system ${BUILD_SYSTEM}
|
||||
--target ${IDF_TARGET}
|
||||
--recursive
|
||||
"
|
||||
CONFIG="--config configs/*="
|
||||
# -----------------------------------------------------------------------------
|
||||
else
|
||||
die "TEST_TYPE should only be one of {example_test, custom_test, unit_test}"
|
||||
fi
|
||||
|
||||
echo "$TEST_TYPE running for target $IDF_TARGET"
|
||||
cd ${IDF_PATH}
|
||||
|
||||
# This part of the script produces the same result for all the 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.
|
||||
#
|
||||
# If changing the work-dir or build-dir, remember to update the "artifacts" in
|
||||
# gitlab-ci configs, and IDFApp.py.
|
||||
|
||||
${IDF_PATH}/tools/find_apps.py \
|
||||
-vv \
|
||||
--format json \
|
||||
${WORK_DIR} \
|
||||
--build-dir ${BUILD_DIR} \
|
||||
--build-log ${BUILD_LOG} \
|
||||
--output ${ALL_BUILD_LIST_JSON} \
|
||||
${EXTRA_ARGS} \
|
||||
${CONFIG}
|
||||
|
||||
# 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} \
|
||||
--size-info ${SIZE_INFO_LOCATION} \
|
||||
${ALL_BUILD_LIST_JSON}
|
||||
|
||||
# Check for build warnings
|
||||
${IDF_PATH}/tools/ci/check_build_warnings.py -vv ${JOB_BUILD_LIST_JSON}
|
||||
|
||||
if [ "${TEST_TYPE}" = "unit_test" ]; then
|
||||
# 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
|
||||
fi
|
|
@ -63,6 +63,7 @@ def local_test_check(decorator_target):
|
|||
if os.getenv('CI_JOB_ID'): # Only auto-detect target when running locally
|
||||
return idf_target
|
||||
|
||||
decorator_target = upper_list_or_str(decorator_target)
|
||||
expected_json_path = os.path.join('build', 'config', 'sdkconfig.json')
|
||||
if os.path.exists(expected_json_path):
|
||||
sdkconfig = json.load(open(expected_json_path))
|
||||
|
@ -262,3 +263,22 @@ def check_performance(item, value, target):
|
|||
_check_perf(op, value)
|
||||
# if no exception was thrown then the performance is met and no need to continue
|
||||
break
|
||||
|
||||
|
||||
MINIMUM_FREE_HEAP_SIZE_RE = re.compile(r'Minimum free heap size: (\d+) bytes')
|
||||
|
||||
|
||||
def print_heap_size(app_name, config_name, target, minimum_free_heap_size):
|
||||
"""
|
||||
Do not change the print output in case you really need to.
|
||||
The result is parsed by ci-dashboard project
|
||||
"""
|
||||
print('------ heap size info ------\n'
|
||||
'[app_name] {}\n'
|
||||
'[config_name] {}\n'
|
||||
'[target] {}\n'
|
||||
'[minimum_free_heap_size] {} Bytes\n'
|
||||
'------ heap size end ------'.format(app_name,
|
||||
'' if not config_name else config_name,
|
||||
target,
|
||||
minimum_free_heap_size))
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import logging
|
||||
import shutil
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from .common import BuildSystem, BuildItem, BuildError
|
||||
|
||||
BUILD_SYSTEM_CMAKE = "cmake"
|
||||
IDF_PY = "idf.py"
|
||||
IDF_PY = os.path.join(os.environ["IDF_PATH"], "tools", "idf.py")
|
||||
|
||||
# While ESP-IDF component CMakeLists files can be identified by the presence of 'idf_component_register' string,
|
||||
# there is no equivalent for the project CMakeLists files. This seems to be the best option...
|
||||
|
@ -30,8 +30,7 @@ class CMakeBuildSystem(BuildSystem):
|
|||
build_path, work_path, extra_cmakecache_items = cls.build_prepare(build_item)
|
||||
# Prepare the build arguments
|
||||
args = [
|
||||
# Assume it is the responsibility of the caller to
|
||||
# set up the environment (run . ./export.sh)
|
||||
sys.executable,
|
||||
IDF_PY,
|
||||
"-B",
|
||||
build_path,
|
||||
|
@ -73,6 +72,7 @@ class CMakeBuildSystem(BuildSystem):
|
|||
os.path.join(work_path, "sdkconfig"),
|
||||
os.path.join(build_path, "sdkconfig"),
|
||||
)
|
||||
build_item.size_json_fp = build_item.get_size_json_fp()
|
||||
finally:
|
||||
if log_file:
|
||||
log_file.close()
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
# coding=utf-8
|
||||
import fnmatch
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
from abc import abstractmethod
|
||||
from collections import namedtuple
|
||||
import logging
|
||||
import json
|
||||
import typing
|
||||
from io import open
|
||||
|
||||
import typing
|
||||
|
||||
DEFAULT_TARGET = "esp32"
|
||||
|
||||
TARGET_PLACEHOLDER = "@t"
|
||||
|
@ -18,6 +21,8 @@ NAME_PLACEHOLDER = "@n"
|
|||
FULL_NAME_PLACEHOLDER = "@f"
|
||||
INDEX_PLACEHOLDER = "@i"
|
||||
|
||||
IDF_SIZE_PY = os.path.join(os.environ["IDF_PATH"], "tools", "idf_size.py")
|
||||
|
||||
SDKCONFIG_LINE_REGEX = re.compile(r"^([^=]+)=\"?([^\"\n]*)\"?\n*$")
|
||||
|
||||
# If these keys are present in sdkconfig.defaults, they will be extracted and passed to CMake
|
||||
|
@ -55,6 +60,14 @@ def config_rules_from_str(rule_strings): # type: (typing.List[str]) -> typing.L
|
|||
return rules
|
||||
|
||||
|
||||
def find_first_match(pattern, path):
|
||||
for root, _, files in os.walk(path):
|
||||
res = fnmatch.filter(files, pattern)
|
||||
if res:
|
||||
return os.path.join(root, res[0])
|
||||
return None
|
||||
|
||||
|
||||
class BuildItem(object):
|
||||
"""
|
||||
Instance of this class represents one build of an application.
|
||||
|
@ -88,6 +101,7 @@ class BuildItem(object):
|
|||
self.preserve = preserve_artifacts
|
||||
|
||||
self._app_name = os.path.basename(os.path.normpath(app_path))
|
||||
self.size_json_fp = None
|
||||
|
||||
# Some miscellaneous build properties which are set later, at the build stage
|
||||
self.index = None
|
||||
|
@ -95,6 +109,14 @@ class BuildItem(object):
|
|||
self.dry_run = False
|
||||
self.keep_going = False
|
||||
|
||||
self.work_path = self.work_dir or self.app_dir
|
||||
if not self.build_dir:
|
||||
self.build_path = os.path.join(self.work_path, "build")
|
||||
elif os.path.isabs(self.build_dir):
|
||||
self.build_path = self.build_dir
|
||||
else:
|
||||
self.build_path = os.path.normpath(os.path.join(self.work_path, self.build_dir))
|
||||
|
||||
@property
|
||||
def app_dir(self):
|
||||
"""
|
||||
|
@ -208,6 +230,39 @@ class BuildItem(object):
|
|||
path = os.path.expandvars(path)
|
||||
return path
|
||||
|
||||
def get_size_json_fp(self):
|
||||
if self.size_json_fp and os.path.exists(self.size_json_fp):
|
||||
return self.size_json_fp
|
||||
|
||||
assert os.path.exists(self.build_path)
|
||||
assert os.path.exists(self.work_path)
|
||||
|
||||
map_file = find_first_match('*.map', self.build_path)
|
||||
if not map_file:
|
||||
raise ValueError('.map file not found under "{}"'.format(self.build_path))
|
||||
|
||||
size_json_fp = os.path.join(self.build_path, 'size.json')
|
||||
idf_size_args = [
|
||||
sys.executable,
|
||||
IDF_SIZE_PY,
|
||||
'--json',
|
||||
'-o', size_json_fp,
|
||||
map_file
|
||||
]
|
||||
subprocess.check_call(idf_size_args)
|
||||
return size_json_fp
|
||||
|
||||
def write_size_info(self, size_info_fs):
|
||||
if not self.size_json_fp or (not os.path.exists(self.size_json_fp)):
|
||||
raise OSError('Run get_size_json_fp() for app {} after built binary'.format(self.app_dir))
|
||||
size_info_dict = {
|
||||
'app_name': self._app_name,
|
||||
'config_name': self.config_name,
|
||||
'target': self.target,
|
||||
'path': self.size_json_fp,
|
||||
}
|
||||
size_info_fs.write(json.dumps(size_info_dict) + '\n')
|
||||
|
||||
|
||||
class BuildSystem(object):
|
||||
"""
|
||||
|
@ -221,13 +276,8 @@ class BuildSystem(object):
|
|||
@classmethod
|
||||
def build_prepare(cls, build_item):
|
||||
app_path = build_item.app_dir
|
||||
work_path = build_item.work_dir or app_path
|
||||
if not build_item.build_dir:
|
||||
build_path = os.path.join(work_path, "build")
|
||||
elif os.path.isabs(build_item.build_dir):
|
||||
build_path = build_item.build_dir
|
||||
else:
|
||||
build_path = os.path.join(work_path, build_item.build_dir)
|
||||
work_path = build_item.work_path
|
||||
build_path = build_item.build_path
|
||||
|
||||
if work_path != app_path:
|
||||
if os.path.exists(work_path):
|
||||
|
|
|
@ -48,6 +48,8 @@ class MakeBuildSystem(BuildSystem):
|
|||
log_file.close()
|
||||
raise BuildError("Build failed with exit code {}".format(e.returncode))
|
||||
|
||||
build_item.size_json_fp = build_item.get_size_json_fp()
|
||||
|
||||
@staticmethod
|
||||
def is_app(path):
|
||||
makefile_path = os.path.join(path, "Makefile")
|
||||
|
|
|
@ -10,18 +10,18 @@
|
|||
|
||||
/* utility functions */
|
||||
static void die(const char* msg) __attribute__ ((noreturn));
|
||||
static const char* get_test_name();
|
||||
static const char* get_test_name(void);
|
||||
|
||||
/* functions which cause an exception/panic in different ways */
|
||||
static void test_abort();
|
||||
static void test_int_wdt();
|
||||
static void test_task_wdt();
|
||||
static void test_storeprohibited();
|
||||
static void test_cache_error();
|
||||
static void test_int_wdt_cache_disabled();
|
||||
static void test_stack_overflow();
|
||||
static void test_illegal_instruction();
|
||||
static void test_instr_fetch_prohibited();
|
||||
static void test_abort(void);
|
||||
static void test_int_wdt(void);
|
||||
static void test_task_wdt(void);
|
||||
static void test_storeprohibited(void);
|
||||
static void test_cache_error(void);
|
||||
static void test_int_wdt_cache_disabled(void);
|
||||
static void test_stack_overflow(void);
|
||||
static void test_illegal_instruction(void);
|
||||
static void test_instr_fetch_prohibited(void);
|
||||
|
||||
|
||||
void app_main(void)
|
||||
|
@ -60,12 +60,12 @@ void app_main(void)
|
|||
|
||||
/* implementations of the test functions */
|
||||
|
||||
static void test_abort()
|
||||
static void test_abort(void)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
static void test_int_wdt()
|
||||
static void test_int_wdt(void)
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
while (true) {
|
||||
|
@ -73,25 +73,25 @@ static void test_int_wdt()
|
|||
}
|
||||
}
|
||||
|
||||
static void test_task_wdt()
|
||||
static void test_task_wdt(void)
|
||||
{
|
||||
while (true) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_storeprohibited()
|
||||
static void test_storeprohibited(void)
|
||||
{
|
||||
*(int*) 0x1 = 0;
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_cache_error()
|
||||
static IRAM_ATTR void test_cache_error(void)
|
||||
{
|
||||
esp_flash_default_chip->os_func->start(esp_flash_default_chip->os_func_data);
|
||||
die("this should not be printed");
|
||||
}
|
||||
|
||||
static void IRAM_ATTR test_int_wdt_cache_disabled()
|
||||
static void IRAM_ATTR test_int_wdt_cache_disabled(void)
|
||||
{
|
||||
esp_flash_default_chip->os_func->start(esp_flash_default_chip->os_func_data);
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
@ -100,7 +100,7 @@ static void IRAM_ATTR test_int_wdt_cache_disabled()
|
|||
}
|
||||
}
|
||||
|
||||
static void test_stack_overflow()
|
||||
static void test_stack_overflow(void)
|
||||
{
|
||||
volatile uint8_t stuff[CONFIG_ESP_MAIN_TASK_STACK_SIZE * 2];
|
||||
for (int i = 0; i < sizeof(stuff); ++i) {
|
||||
|
@ -108,12 +108,12 @@ static void test_stack_overflow()
|
|||
}
|
||||
}
|
||||
|
||||
static void test_illegal_instruction()
|
||||
static void test_illegal_instruction(void)
|
||||
{
|
||||
__asm__ __volatile__("ill");
|
||||
}
|
||||
|
||||
static void test_instr_fetch_prohibited()
|
||||
static void test_instr_fetch_prohibited(void)
|
||||
{
|
||||
typedef void (*fptr_t)(void);
|
||||
volatile fptr_t fptr = (fptr_t) 0x4;
|
||||
|
@ -124,7 +124,7 @@ static void test_instr_fetch_prohibited()
|
|||
|
||||
#define BOOT_CMD_MAX_LEN (128)
|
||||
|
||||
static const char* get_test_name()
|
||||
static const char* get_test_name(void)
|
||||
{
|
||||
static char test_name_str[BOOT_CMD_MAX_LEN] = {0};
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
|
||||
import yaml
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from copy import deepcopy
|
||||
import CreateSectionTable
|
||||
|
@ -45,7 +47,6 @@ class Parser(object):
|
|||
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_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"
|
||||
|
@ -55,12 +56,15 @@ class Parser(object):
|
|||
"esp32s2": "xtensa-esp32s2-elf-",
|
||||
}
|
||||
|
||||
def __init__(self, idf_path=os.getenv("IDF_PATH"), idf_target=os.getenv("IDF_TARGET")):
|
||||
def __init__(self, binary_folder):
|
||||
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.ut_bin_folder = binary_folder
|
||||
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)
|
||||
|
@ -300,19 +304,19 @@ 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, self.idf_target)
|
||||
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:
|
||||
config_output_folder = os.path.join(output_folder, config)
|
||||
config_output_folder = os.path.join(output_folder, 'build', config)
|
||||
if os.path.exists(config_output_folder):
|
||||
test_cases.extend(self.parse_test_cases_for_one_config(configs_folder, config_output_folder, config))
|
||||
test_cases.sort(key=lambda x: x["config"] + x["summary"])
|
||||
self.dump_test_cases(test_cases)
|
||||
|
||||
|
||||
def test_parser():
|
||||
parser = Parser()
|
||||
def test_parser(binary_folder):
|
||||
parser = Parser(binary_folder)
|
||||
# test parsing tags
|
||||
# parsing module only and module in module list
|
||||
prop = parser.parse_case_properities("[esp32]")
|
||||
|
@ -353,20 +357,12 @@ def test_parser():
|
|||
assert sorted(tags) == ['a', 'd', 'f'] # sorted is required for older Python3, e.g. 3.4.8
|
||||
|
||||
|
||||
def main():
|
||||
test_parser()
|
||||
def main(binary_folder):
|
||||
assert os.getenv('IDF_PATH'), 'IDF_PATH must be set to use this script'
|
||||
assert os.getenv('IDF_TARGET'), 'IDF_TARGET must be set to use this script'
|
||||
test_parser(binary_folder)
|
||||
|
||||
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)
|
||||
|
||||
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 = Parser(binary_folder)
|
||||
parser.parse_test_cases()
|
||||
parser.copy_module_def_file()
|
||||
if len(parser.parsing_errors) > 0:
|
||||
|
@ -376,4 +372,7 @@ def main():
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('bin_dir', help='Binary Folder')
|
||||
args = parser.parse_args()
|
||||
main(args.bin_dir)
|
||||
|
|
Ładowanie…
Reference in New Issue