Merge branch 'master' into release/v3.1.x

This commit is contained in:
Lucas Saavedra Vaz 2024-10-21 10:20:31 -03:00
commit 03bfa52d49
No known key found for this signature in database
GPG key ID: 9CAE85DC84A38188
24 changed files with 279 additions and 99 deletions

View file

@ -18,7 +18,7 @@ indent_size = 2
indent_style = space indent_style = space
[*.{bash,sh}] [*.{bash,sh}]
indent_size = 2 indent_size = 4
indent_style = space indent_style = space
[*.{c,cc,cp,cpp,cxx,h,hh,hpp,hxx,ii,inl,ino,ixx,pde,tpl,tpp,txx}] [*.{c,cc,cp,cpp,cxx,h,hh,hpp,hxx,ii,inl,ino,ixx,pde,tpl,tpp,txx}]

View file

@ -41,6 +41,8 @@ body:
options: options:
- latest master (checkout manually) - latest master (checkout manually)
- latest development Release Candidate (RC-X) - latest development Release Candidate (RC-X)
- v3.0.6
- v3.0.5
- v3.0.4 - v3.0.4
- v3.0.3 - v3.0.3
- v3.0.2 - v3.0.2

View file

@ -96,9 +96,9 @@ function count_sketches(){ # count_sketches <examples-path>
continue continue
fi fi
# Check if the sketch requires any configuration options # Check if the sketch requires any configuration options (AND)
requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json) requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json)
if [[ "$requirements" != "null" ]] || [[ "$requirements" != "" ]]; then if [[ "$requirements" != "null" && "$requirements" != "" ]]; then
for requirement in $requirements; do for requirement in $requirements; do
requirement=$(echo $requirement | xargs) requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" "$SDKCONFIG_DIR/esp32/sdkconfig") found_line=$(grep -E "^$requirement" "$SDKCONFIG_DIR/esp32/sdkconfig")
@ -107,6 +107,23 @@ function count_sketches(){ # count_sketches <examples-path>
fi fi
done done
fi fi
# Check if the sketch requires any configuration options (OR)
requirements_or=$(jq -r '.requires_any[]? // empty' $sketchdir/ci.json)
if [[ "$requirements_or" != "null" && "$requirements_or" != "" ]]; then
found=false
for requirement in $requirements_or; do
requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" "$SDKCONFIG_DIR/esp32/sdkconfig")
if [[ "$found_line" != "" ]]; then
found=true
break
fi
done
if [[ "$found" == "false" ]]; then
continue
fi
fi
fi fi
echo $sketch >> sketches.txt echo $sketch >> sketches.txt
@ -187,9 +204,9 @@ function build_pio_sketches(){ # build_pio_sketches <board> <options> <examples-
continue continue
fi fi
# Check if the sketch requires any configuration options # Check if the sketch requires any configuration options (AND)
requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json) requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json)
if [[ "$requirements" != "null" ]] || [[ "$requirements" != "" ]]; then if [[ "$requirements" != "null" && "$requirements" != "" ]]; then
for requirement in $requirements; do for requirement in $requirements; do
requirement=$(echo $requirement | xargs) requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" "$SDKCONFIG_DIR/esp32/sdkconfig") found_line=$(grep -E "^$requirement" "$SDKCONFIG_DIR/esp32/sdkconfig")
@ -198,6 +215,23 @@ function build_pio_sketches(){ # build_pio_sketches <board> <options> <examples-
fi fi
done done
fi fi
# Check if the sketch requires any configuration options (OR)
requirements_or=$(jq -r '.requires_any[]? // empty' $sketchdir/ci.json)
if [[ "$requirements_or" != "null" && "$requirements_or" != "" ]]; then
found=false
for requirement in $requirements_or; do
requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" "$SDKCONFIG_DIR/esp32/sdkconfig")
if [[ "$found_line" != "" ]]; then
found=true
break
fi
done
if [[ "$found" == "false" ]]; then
continue
fi
fi
fi fi
sketchnum=$(($sketchnum + 1)) sketchnum=$(($sketchnum + 1))

View file

@ -98,38 +98,47 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
# Default FQBN options if none were passed in the command line. # Default FQBN options if none were passed in the command line.
esp32_opts="PSRAM=enabled,FlashMode=dio${fqbn_append:+,$fqbn_append}" esp32_opts="PSRAM=enabled${fqbn_append:+,$fqbn_append}"
esp32s2_opts="PSRAM=enabled,FlashMode=dio${fqbn_append:+,$fqbn_append}" esp32s2_opts="PSRAM=enabled${fqbn_append:+,$fqbn_append}"
esp32s3_opts="PSRAM=opi,USBMode=default,FlashMode=dio${fqbn_append:+,$fqbn_append}" esp32s3_opts="PSRAM=opi,USBMode=default${fqbn_append:+,$fqbn_append}"
esp32c3_opts="FlashMode=dio${fqbn_append:+,$fqbn_append}" esp32c3_opts="$fqbn_append"
esp32c6_opts="FlashMode=dio${fqbn_append:+,$fqbn_append}" esp32c6_opts="$fqbn_append"
esp32h2_opts="FlashMode=dio${fqbn_append:+,$fqbn_append}" esp32h2_opts="$fqbn_append"
esp32p4_opts="FlashMode=dio,USBMode=default${fqbn_append:+,$fqbn_append}" esp32p4_opts="USBMode=default${fqbn_append:+,$fqbn_append}"
# Select the common part of the FQBN based on the target. The rest will be # Select the common part of the FQBN based on the target. The rest will be
# appended depending on the passed options. # appended depending on the passed options.
opt=""
case "$target" in case "$target" in
"esp32") "esp32")
fqbn="espressif:esp32:esp32:${options:-$esp32_opts}" [ -n "${options:-$esp32_opts}" ] && opt=":${options:-$esp32_opts}"
fqbn="espressif:esp32:esp32$opt"
;; ;;
"esp32s2") "esp32s2")
fqbn="espressif:esp32:esp32s2:${options:-$esp32s2_opts}" [ -n "${options:-$esp32s2_opts}" ] && opt=":${options:-$esp32s2_opts}"
fqbn="espressif:esp32:esp32s2$opt"
;; ;;
"esp32c3") "esp32c3")
fqbn="espressif:esp32:esp32c3:${options:-$esp32c3_opts}" [ -n "${options:-$esp32c3_opts}" ] && opt=":${options:-$esp32c3_opts}"
fqbn="espressif:esp32:esp32c3$opt"
;; ;;
"esp32s3") "esp32s3")
fqbn="espressif:esp32:esp32s3:${options:-$esp32s3_opts}" [ -n "${options:-$esp32s3_opts}" ] && opt=":${options:-$esp32s3_opts}"
fqbn="espressif:esp32:esp32s3$opt"
;; ;;
"esp32c6") "esp32c6")
fqbn="espressif:esp32:esp32c6:${options:-$esp32c6_opts}" [ -n "${options:-$esp32c6_opts}" ] && opt=":${options:-$esp32c6_opts}"
fqbn="espressif:esp32:esp32c6$opt"
;; ;;
"esp32h2") "esp32h2")
fqbn="espressif:esp32:esp32h2:${options:-$esp32h2_opts}" [ -n "${options:-$esp32h2_opts}" ] && opt=":${options:-$esp32h2_opts}"
fqbn="espressif:esp32:esp32h2$opt"
;; ;;
"esp32p4") "esp32p4")
fqbn="espressif:esp32:esp32p4:${options:-$esp32p4_opts}" [ -n "${options:-$esp32p4_opts}" ] && opt=":${options:-$esp32p4_opts}"
fqbn="espressif:esp32:esp32p4$opt"
;; ;;
esac esac
@ -167,9 +176,9 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
exit 0 exit 0
fi fi
# Check if the sketch requires any configuration options # Check if the sketch requires any configuration options (AND)
requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json) requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json)
if [[ "$requirements" != "null" ]] || [[ "$requirements" != "" ]]; then if [[ "$requirements" != "null" && "$requirements" != "" ]]; then
for requirement in $requirements; do for requirement in $requirements; do
requirement=$(echo $requirement | xargs) requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" "$SDKCONFIG_DIR/$target/sdkconfig") found_line=$(grep -E "^$requirement" "$SDKCONFIG_DIR/$target/sdkconfig")
@ -179,6 +188,24 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
fi fi
done done
fi fi
# Check if the sketch excludes any configuration options (OR)
requirements_or=$(jq -r '.requires_any[]? // empty' $sketchdir/ci.json)
if [[ "$requirements_or" != "null" && "$requirements_or" != "" ]]; then
found=false
for requirement in $requirements_or; do
requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" "$SDKCONFIG_DIR/$target/sdkconfig")
if [[ "$found_line" != "" ]]; then
found=true
break
fi
done
if [[ "$found" == "false" ]]; then
echo "Target $target meets none of the requirements in requires_any for $sketchname. Skipping."
exit 0
fi
fi
fi fi
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp" ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
@ -217,9 +244,9 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
--build-cache-path "$ARDUINO_CACHE_DIR" \ --build-cache-path "$ARDUINO_CACHE_DIR" \
--build-path "$build_dir" \ --build-path "$build_dir" \
$xtra_opts "${sketchdir}" \ $xtra_opts "${sketchdir}" \
> $output_file 2>&1 | tee $output_file
exit_status=$? exit_status=${PIPESTATUS[0]}
if [ $exit_status -ne 0 ]; then if [ $exit_status -ne 0 ]; then
echo "ERROR: Compilation failed with error code $exit_status" echo "ERROR: Compilation failed with error code $exit_status"
exit $exit_status exit $exit_status
@ -326,9 +353,9 @@ function count_sketches(){ # count_sketches <path> [target] [file] [ignore-requi
fi fi
if [ "$ignore_requirements" != "1" ]; then if [ "$ignore_requirements" != "1" ]; then
# Check if the sketch requires any configuration options # Check if the sketch requires any configuration options (AND)
requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json) requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json)
if [[ "$requirements" != "null" ]] || [[ "$requirements" != "" ]]; then if [[ "$requirements" != "null" && "$requirements" != "" ]]; then
for requirement in $requirements; do for requirement in $requirements; do
requirement=$(echo $requirement | xargs) requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" $SDKCONFIG_DIR/$target/sdkconfig) found_line=$(grep -E "^$requirement" $SDKCONFIG_DIR/$target/sdkconfig)
@ -337,6 +364,23 @@ function count_sketches(){ # count_sketches <path> [target] [file] [ignore-requi
fi fi
done done
fi fi
# Check if the sketch excludes any configuration options (OR)
requirements_or=$(jq -r '.requires_any[]? // empty' $sketchdir/ci.json)
if [[ "$requirements_or" != "null" && "$requirements_or" != "" ]]; then
found=false
for requirement in $requirements_or; do
requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" $SDKCONFIG_DIR/$target/sdkconfig)
if [[ "$found_line" != "" ]]; then
found=true
break
fi
done
if [[ "$found" == "false" ]]; then
continue 2
fi
fi
fi fi
fi fi
echo $sketch >> sketches.txt echo $sketch >> sketches.txt

26
.github/scripts/tests_matrix.sh vendored Normal file
View file

@ -0,0 +1,26 @@
#!/bin/bash
build_types="'validation'"
hw_types="'validation'"
wokwi_types="'validation'"
qemu_types="'validation'"
if [[ $IS_PR != 'true' ]] || [[ $PERFORMANCE_ENABLED == 'true' ]]; then
build_types+=",'performance'"
hw_types+=",'performance'"
#wokwi_types+=",'performance'"
#qemu_types+=",'performance'"
fi
targets="'esp32','esp32s2','esp32s3','esp32c3','esp32c6','esp32h2'"
mkdir -p info
echo "[$wokwi_types]" > info/wokwi_types.txt
echo "[$targets]" > info/targets.txt
echo "build-types=[$build_types]" >> $GITHUB_OUTPUT
echo "hw-types=[$hw_types]" >> $GITHUB_OUTPUT
echo "wokwi-types=[$wokwi_types]" >> $GITHUB_OUTPUT
echo "qemu-types=[$qemu_types]" >> $GITHUB_OUTPUT
echo "targets=[$targets]" >> $GITHUB_OUTPUT

View file

@ -36,9 +36,9 @@ function run_test() {
return 0 return 0
fi fi
# Check if the sketch requires any configuration options # Check if the sketch requires any configuration options (AND)
requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json) requirements=$(jq -r '.requires[]? // empty' $sketchdir/ci.json)
if [[ "$requirements" != "null" ]] || [[ "$requirements" != "" ]]; then if [[ "$requirements" != "null" && "$requirements" != "" ]]; then
for requirement in $requirements; do for requirement in $requirements; do
requirement=$(echo $requirement | xargs) requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" "$SDKCONFIG_PATH") found_line=$(grep -E "^$requirement" "$SDKCONFIG_PATH")
@ -49,6 +49,25 @@ function run_test() {
fi fi
done done
fi fi
# Check if the sketch requires any configuration options (OR)
requirements_or=$(jq -r '.requires_any[]? // empty' $sketchdir/ci.json)
if [[ "$requirements_or" != "null" && "$requirements_or" != "" ]]; then
found=false
for requirement in $requirements_or; do
requirement=$(echo $requirement | xargs)
found_line=$(grep -E "^$requirement" "$SDKCONFIG_PATH")
if [[ "$found_line" != "" ]]; then
found=true
break
fi
done
if [[ "$found" == "false" ]]; then
printf "\033[93mTarget $target meets none of the requirements in requires_any for $sketchname. Skipping.\033[0m\n"
printf "\n\n\n"
return 0
fi
fi
fi fi
if [ $len -eq 1 ]; then if [ $len -eq 1 ]; then

View file

@ -20,3 +20,5 @@ jobs:
uses: espressif/shared-github-dangerjs@v1 uses: espressif/shared-github-dangerjs@v1
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
rule-max-commits: 'false'
commit-messages-min-summary-length: '10'

View file

@ -57,29 +57,25 @@ jobs:
hw-types: ${{ steps.set-matrix.outputs.hw-types }} hw-types: ${{ steps.set-matrix.outputs.hw-types }}
wokwi-types: ${{ steps.set-matrix.outputs.wokwi-types }} wokwi-types: ${{ steps.set-matrix.outputs.wokwi-types }}
qemu-types: ${{ steps.set-matrix.outputs.qemu-types }} qemu-types: ${{ steps.set-matrix.outputs.qemu-types }}
targets: ${{ steps.set-matrix.outputs.targets }}
env:
IS_PR: ${{ github.event.pull_request.number != null }}
PERFORMANCE_ENABLED: ${{ contains(github.event.pull_request.labels.*.name, 'perf_test') }}
steps: steps:
- name: Checkout
uses: actions/checkout@v4
with:
sparse-checkout: .github/scripts/tests_matrix.sh
- name: Set matrix - name: Set matrix
id: set-matrix id: set-matrix
run: | run: bash .github/scripts/tests_matrix.sh
build_types='["validation"'
hw_types='["validation"'
wokwi_types='["validation"'
qemu_types='["validation"'
is_pr=${{ github.event.pull_request.number != null }} - name: Upload
is_performance_enabled=${{ contains(github.event.pull_request.labels.*.name, 'perf_test') }} uses: actions/upload-artifact@v4
with:
if [[ $is_pr != 'true' ]] || [[ $is_performance_enabled == 'true' ]]; then name: matrix_info
build_types+=',"performance"' path: info/*
hw_types+=',"performance"'
#wokwi_types+=',"performance"'
#qemu_types+=',"performance"'
fi
echo "build-types=$build_types]" >> $GITHUB_OUTPUT
echo "hw-types=$hw_types]" >> $GITHUB_OUTPUT
echo "wokwi-types=$wokwi_types]" >> $GITHUB_OUTPUT
echo "qemu-types=$qemu_types]" >> $GITHUB_OUTPUT
call-build-tests: call-build-tests:
name: Build name: Build
@ -88,7 +84,7 @@ jobs:
strategy: strategy:
matrix: matrix:
type: ${{ fromJson(needs.gen-matrix.outputs.build-types) }} type: ${{ fromJson(needs.gen-matrix.outputs.build-types) }}
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32p4'] chip: ${{ fromJson(needs.gen-matrix.outputs.targets) }}
with: with:
type: ${{ matrix.type }} type: ${{ matrix.type }}
chip: ${{ matrix.chip }} chip: ${{ matrix.chip }}
@ -105,7 +101,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
type: ${{ fromJson(needs.gen-matrix.outputs.hw-types) }} type: ${{ fromJson(needs.gen-matrix.outputs.hw-types) }}
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32p4'] chip: ${{ fromJson(needs.gen-matrix.outputs.targets) }}
with: with:
type: ${{ matrix.type }} type: ${{ matrix.type }}
chip: ${{ matrix.chip }} chip: ${{ matrix.chip }}

View file

@ -79,6 +79,7 @@ jobs:
event_name: ${{ env.original_event }} event_name: ${{ env.original_event }}
files: ./artifacts/**/*.xml files: ./artifacts/**/*.xml
action_fail: true action_fail: true
compare_to_earlier_commit: false
- name: Fail if tests failed - name: Fail if tests failed
if: ${{ env.original_conclusion == 'failure' || env.original_conclusion == 'timed_out' || github.event.workflow_run.conclusion == 'failure' || github.event.workflow_run.conclusion == 'timed_out' }} if: ${{ env.original_conclusion == 'failure' || env.original_conclusion == 'timed_out' || github.event.workflow_run.conclusion == 'failure' || github.event.workflow_run.conclusion == 'timed_out' }}

View file

@ -22,6 +22,9 @@ jobs:
outputs: outputs:
pr_num: ${{ steps.set-ref.outputs.pr_num }} pr_num: ${{ steps.set-ref.outputs.pr_num }}
ref: ${{ steps.set-ref.outputs.ref }} ref: ${{ steps.set-ref.outputs.ref }}
base: ${{ steps.set-ref.outputs.base }}
targets: ${{ steps.set-ref.outputs.targets }}
types: ${{ steps.set-ref.outputs.types }}
steps: steps:
- name: Report pending - name: Report pending
uses: actions/github-script@v7 uses: actions/github-script@v7
@ -51,10 +54,18 @@ jobs:
name: event_file name: event_file
path: artifacts/event_file path: artifacts/event_file
- name: Download and extract matrix info
uses: actions/download-artifact@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
name: matrix_info
path: artifacts/matrix_info
- name: Try to read PR number - name: Try to read PR number
id: set-ref id: set-ref
run: | run: |
pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json) pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json | tr -cd "[:digit:]")
if [ -z "$pr_num" ] || [ "$pr_num" == "null" ]; then if [ -z "$pr_num" ] || [ "$pr_num" == "null" ]; then
pr_num="" pr_num=""
fi fi
@ -64,11 +75,22 @@ jobs:
ref=${{ github.ref }} ref=${{ github.ref }}
fi fi
action=$(jq -r '.action' artifacts/event_file/event.json) action=$(jq -r '.action' artifacts/event_file/event.json | tr -cd "[:alpha:]_")
if [ "$action" == "null" ]; then if [ "$action" == "null" ]; then
action="" action=""
fi fi
base=$(jq -r '.pull_request.base.ref' artifacts/event_file/event.json | tr -cd "[:alnum:]/_.-")
if [ -z "$base" ] || [ "$base" == "null" ]; then
base=${{ github.ref }}
fi
types=$(cat artifacts/matrix_info/wokwi_types.txt | tr -cd "[:alpha:],[]'")
targets=$(cat artifacts/matrix_info/targets.txt | tr -cd "[:alnum:],[]'")
echo "base = $base"
echo "targets = $targets"
echo "types = $types"
echo "pr_num = $pr_num" echo "pr_num = $pr_num"
printf "$ref" >> artifacts/ref.txt printf "$ref" >> artifacts/ref.txt
@ -98,6 +120,9 @@ jobs:
cat artifacts/conclusion.txt cat artifacts/conclusion.txt
echo "pr_num=$pr_num" >> $GITHUB_OUTPUT echo "pr_num=$pr_num" >> $GITHUB_OUTPUT
echo "base=$base" >> $GITHUB_OUTPUT
echo "targets=$targets" >> $GITHUB_OUTPUT
echo "types=$types" >> $GITHUB_OUTPUT
echo "ref=$ref" >> $GITHUB_OUTPUT echo "ref=$ref" >> $GITHUB_OUTPUT
- name: Download and extract parent hardware results - name: Download and extract parent hardware results
@ -164,8 +189,8 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
type: ['validation'] type: ${{ fromJson(needs.get-artifacts.outputs.types) }}
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32p4'] chip: ${{ fromJson(needs.get-artifacts.outputs.targets) }}
steps: steps:
- name: Report pending - name: Report pending
uses: actions/github-script@v7 uses: actions/github-script@v7
@ -211,9 +236,12 @@ jobs:
echo "enabled=$enabled" >> $GITHUB_OUTPUT echo "enabled=$enabled" >> $GITHUB_OUTPUT
# Note that changes to the workflows and tests will only be picked up after the PR is merged # Note that changes to the workflows and tests will only be picked up after the PR is merged
# DO NOT CHECKOUT THE USER'S REPOSITORY IN THIS WORKFLOW. IT HAS HIGH SECURITY RISKS.
- name: Checkout repository - name: Checkout repository
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
ref: ${{ needs.get-artifacts.outputs.base || github.ref }}
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}

View file

@ -172,13 +172,13 @@ And in the ``README.md`` file:
By default, the CI system will use the FQBNs specified in the ``.github/scripts/sketch_utils.sh`` file to compile the sketches. By default, the CI system will use the FQBNs specified in the ``.github/scripts/sketch_utils.sh`` file to compile the sketches.
Currently, the default FQBNs are: Currently, the default FQBNs are:
* ``espressif:esp32:esp32:PSRAM=enabled,FlashMode=dio`` * ``espressif:esp32:esp32:PSRAM=enabled``
* ``espressif:esp32:esp32s2:PSRAM=enabled,FlashMode=dio`` * ``espressif:esp32:esp32s2:PSRAM=enabled``
* ``espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,FlashMode=dio`` * ``espressif:esp32:esp32s3:PSRAM=opi,USBMode=default``
* ``espressif:esp32:esp32c3:FlashMode=dio`` * ``espressif:esp32:esp32c3``
* ``espressif:esp32:esp32c6:FlashMode=dio`` * ``espressif:esp32:esp32c6``
* ``espressif:esp32:esp32h2:FlashMode=dio`` * ``espressif:esp32:esp32h2``
* ``espressif:esp32:esp32p4:FlashMode=dio,USBMode=default`` * ``espressif:esp32:esp32p4:USBMode=default``
There are two ways to alter the FQBNs used to compile the sketches: by using the ``fqbn`` or ``fqbn_append`` fields in the ``ci.json`` file. There are two ways to alter the FQBNs used to compile the sketches: by using the ``fqbn`` or ``fqbn_append`` fields in the ``ci.json`` file.
@ -409,7 +409,9 @@ CI JSON File
The ``ci.json`` file is used to specify how the test suite and sketches will handled by the CI system. It can contain the following fields: The ``ci.json`` file is used to specify how the test suite and sketches will handled by the CI system. It can contain the following fields:
* ``requires``: A list of configurations in ``sdkconfig`` that are required to run the test suite. The test suite will only run on the targets * ``requires``: A list of configurations in ``sdkconfig`` that are required to run the test suite. The test suite will only run on the targets
that have the required configurations. By default, no configurations are required. that have **ALL** the required configurations. By default, no configurations are required.
* ``requires_any``: A list of configurations in ``sdkconfig`` that are required to run the test suite. The test suite will only run on the targets
that have **ANY** of the required configurations. By default, no configurations are required.
* ``targets``: A dictionary that specifies the targets for which the tests will be run. The key is the target name and the value is a boolean * ``targets``: A dictionary that specifies the targets for which the tests will be run. The key is the target name and the value is a boolean
that specifies if the test should be run for that target. By default, all targets are enabled as long as they have the required configurations that specifies if the test should be run for that target. By default, all targets are enabled as long as they have the required configurations
specified in the ``requires`` field. This field is also valid for examples. specified in the ``requires`` field. This field is also valid for examples.

View file

@ -40,7 +40,7 @@ void setup() {
Serial.printf("Cores: %d\n", CONFIG_SOC_CPU_CORES_NUM); Serial.printf("Cores: %d\n", CONFIG_SOC_CPU_CORES_NUM);
Serial.flush(); Serial.flush();
for (int i = 0; i < N_RUNS; i++) { for (int i = 0; i < N_RUNS; i++) {
Serial.printf("Run %d", i); Serial.printf("Run %d\n", i);
coremark_main(); coremark_main();
Serial.flush(); Serial.flush();
} }

View file

@ -31,7 +31,7 @@ void setup() {
Serial.printf("N: %d\n", FIB_N); Serial.printf("N: %d\n", FIB_N);
Serial.flush(); Serial.flush();
for (int i = 0; i < N_RUNS; i++) { for (int i = 0; i < N_RUNS; i++) {
Serial.printf("Run %d", i); Serial.printf("Run %d\n", i);
unsigned long start = millis(); unsigned long start = millis();
fibonacci = fib(FIB_N); fibonacci = fib(FIB_N);
unsigned long elapsed = millis() - start; unsigned long elapsed = millis() - start;

View file

@ -2,24 +2,21 @@ import json
import logging import logging
import os import os
fib_results = {}
def fib(n):
if n < 2:
return n
elif str(n) in fib_results:
return fib_results[str(n)]
else:
fib_results[str(n)] = fib(n - 1) + fib(n - 2)
return fib_results[str(n)]
def test_fibonacci(dut, request): def test_fibonacci(dut, request):
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
# Fibonacci results starting from fib(35) to fib(45)
fib_results = [
9227465,
14930352,
24157817,
39088169,
63245986,
102334155,
165580141,
267914296,
433494437,
701408733,
]
# Match "Runs: %d" # Match "Runs: %d"
res = dut.expect(r"Runs: (\d+)", timeout=60) res = dut.expect(r"Runs: (\d+)", timeout=60)
runs = int(res.group(0).decode("utf-8").split(" ")[1]) runs = int(res.group(0).decode("utf-8").split(" ")[1])
@ -30,7 +27,11 @@ def test_fibonacci(dut, request):
res = dut.expect(r"N: (\d+)", timeout=300) res = dut.expect(r"N: (\d+)", timeout=300)
fib_n = int(res.group(0).decode("utf-8").split(" ")[1]) fib_n = int(res.group(0).decode("utf-8").split(" ")[1])
LOGGER.info("Calculating Fibonacci({})".format(fib_n)) LOGGER.info("Calculating Fibonacci({})".format(fib_n))
assert fib_n > 30 and fib_n < 50, "Invalid Fibonacci number" assert fib_n > 0, "Invalid Fibonacci number"
# Calculate Fibonacci results
expected_result = fib(fib_n)
LOGGER.info("Expected Fibonacci result: {}".format(expected_result))
list_time = [] list_time = []
@ -48,7 +49,7 @@ def test_fibonacci(dut, request):
assert fib_result > 0, "Invalid Fibonacci result" assert fib_result > 0, "Invalid Fibonacci result"
# Check if the result is correct # Check if the result is correct
assert fib_result == fib_results[fib_n - 35] assert fib_result == expected_result
# Match "Time: %lu.%03lu s" # Match "Time: %lu.%03lu s"
res = dut.expect(r"Time: (\d+)\.(\d+) s", timeout=300) res = dut.expect(r"Time: (\d+)\.(\d+) s", timeout=300)

View file

@ -3,9 +3,7 @@
"qemu": false, "qemu": false,
"wokwi": false "wokwi": false
}, },
"targets": { "requires": [
"esp32c3": false, "CONFIG_SPIRAM=y"
"esp32c6": false, ]
"esp32h2": false
}
} }

View file

@ -252,7 +252,7 @@ void setup() {
Serial.printf("Max test size: %d\n", MAX_TEST_SIZE); Serial.printf("Max test size: %d\n", MAX_TEST_SIZE);
Serial.flush(); Serial.flush();
for (int i = 0; i < N_RUNS; i++) { for (int i = 0; i < N_RUNS; i++) {
Serial.printf("Run %d", i); Serial.printf("Run %d\n", i);
memcpy_speed_test(dest, src, MAX_TEST_SIZE, N_COPIES); memcpy_speed_test(dest, src, MAX_TEST_SIZE, N_COPIES);
Serial.flush(); Serial.flush();
memset_speed_test(dest, FILL_VALUE, MAX_TEST_SIZE, N_COPIES); memset_speed_test(dest, FILL_VALUE, MAX_TEST_SIZE, N_COPIES);

View file

@ -248,7 +248,7 @@ void setup() {
Serial.printf("Max test size: %d\n", MAX_TEST_SIZE); Serial.printf("Max test size: %d\n", MAX_TEST_SIZE);
Serial.flush(); Serial.flush();
for (int i = 0; i < N_RUNS; i++) { for (int i = 0; i < N_RUNS; i++) {
Serial.printf("Run %d", i); Serial.printf("Run %d\n", i);
memcpy_speed_test(dest, src, MAX_TEST_SIZE, N_COPIES); memcpy_speed_test(dest, src, MAX_TEST_SIZE, N_COPIES);
Serial.flush(); Serial.flush();
memset_speed_test(dest, FILL_VALUE, MAX_TEST_SIZE, N_COPIES); memset_speed_test(dest, FILL_VALUE, MAX_TEST_SIZE, N_COPIES);

View file

@ -25,7 +25,7 @@ void setup() {
Serial.printf("Digits: %d\n", DIGITS); Serial.printf("Digits: %d\n", DIGITS);
Serial.flush(); Serial.flush();
for (int i = 0; i < N_RUNS; i++) { for (int i = 0; i < N_RUNS; i++) {
Serial.printf("Run %d", i); Serial.printf("Run %d\n", i);
unsigned long start = millis(); unsigned long start = millis();
pi_calc(DIGITS); pi_calc(DIGITS);
unsigned long elapsed = millis() - start; unsigned long elapsed = millis() - start;

View file

@ -1,7 +1,7 @@
cryptography==43.0.1 cryptography==43.0.1
--only-binary cryptography --only-binary cryptography
pytest-cov==5.0.0 pytest-cov==5.0.0
pytest-embedded-serial-esp==1.11.5 pytest-embedded-serial-esp==1.11.6
pytest-embedded-arduino==1.11.5 pytest-embedded-arduino==1.11.6
pytest-embedded-wokwi==1.11.5 pytest-embedded-wokwi==1.11.6
pytest-embedded-qemu==1.11.5 pytest-embedded-qemu==1.11.6

View file

@ -1,5 +1,15 @@
import logging
def test_gpio(dut): def test_gpio(dut):
LOGGER = logging.getLogger(__name__)
dut.expect_exact("Button test") dut.expect_exact("Button test")
LOGGER.info("Expecting button press 1")
dut.expect_exact("Button pressed 1 times") dut.expect_exact("Button pressed 1 times")
LOGGER.info("Expecting button press 2")
dut.expect_exact("Button pressed 2 times") dut.expect_exact("Button pressed 2 times")
LOGGER.info("Expecting button press 3")
dut.expect_exact("Button pressed 3 times") dut.expect_exact("Button pressed 3 times")

View file

@ -1,4 +1,13 @@
import logging
def test_nvs(dut): def test_nvs(dut):
LOGGER = logging.getLogger(__name__)
LOGGER.info("Expecting counter value 0")
dut.expect_exact("Current counter value: 0") dut.expect_exact("Current counter value: 0")
LOGGER.info("Expecting counter value 1")
dut.expect_exact("Current counter value: 1") dut.expect_exact("Current counter value: 1")
LOGGER.info("Expecting counter value 2")
dut.expect_exact("Current counter value: 2") dut.expect_exact("Current counter value: 2")

View file

@ -1,4 +1,7 @@
import logging
def test_periman(dut): def test_periman(dut):
LOGGER = logging.getLogger(__name__)
peripherals = [ peripherals = [
"GPIO", "GPIO",
"SigmaDelta", "SigmaDelta",
@ -29,9 +32,10 @@ def test_periman(dut):
if peripheral in peripherals: if peripheral in peripherals:
if "not" in console_output: if "not" in console_output:
assert False, f"Peripheral {peripheral} printed when it should not" assert False, f"Output printed when it should not after peripheral {peripheral}"
LOGGER.info(f"Correct output after peripheral: {peripheral}")
peripherals.remove(peripheral) peripherals.remove(peripheral)
else: else:
assert False, f"Unknown peripheral: {peripheral}" assert False, f"Unknown peripheral: {peripheral}"
assert peripherals == [], f"Missing peripherals output: {peripherals}" assert peripherals == [], f"Missing output after peripherals: {peripherals}"

View file

@ -5,10 +5,5 @@
}, },
"requires": [ "requires": [
"CONFIG_SPIRAM=y" "CONFIG_SPIRAM=y"
], ]
"targets": {
"esp32c3": false,
"esp32c6": false,
"esp32h2": false
}
} }

View file

@ -1,6 +1,15 @@
import logging
def test_wifi(dut): def test_wifi(dut):
LOGGER = logging.getLogger(__name__)
LOGGER.info("Starting WiFi Scan")
dut.expect_exact("Scan start") dut.expect_exact("Scan start")
dut.expect_exact("Scan done") dut.expect_exact("Scan done")
dut.expect_exact("Wokwi-GUEST") dut.expect_exact("Wokwi-GUEST")
LOGGER.info("WiFi Scan done")
LOGGER.info("Connecting to WiFi")
dut.expect_exact("WiFi connected") dut.expect_exact("WiFi connected")
dut.expect_exact("IP address:") dut.expect_exact("IP address:")
LOGGER.info("WiFi connected")