ci(qemu): Add QEMU emulator to CI (#9558)
* ci(qemu): Add QEMU emulator to CI * ci(qemu): Fix windows build * ci(qemu): Fix skips * ci(qemu): Skip performance tests * ci(qemu): Disable QEMU tests for now * fix(platform): Fix build script recipe number
This commit is contained in:
parent
ea27a98252
commit
e10de73e61
17 changed files with 113 additions and 9 deletions
2
.github/scripts/on-push.sh
vendored
2
.github/scripts/on-push.sh
vendored
|
|
@ -60,7 +60,7 @@ elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then
|
||||||
BUILD_PIO=1
|
BUILD_PIO=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$BUILD_LOG" -le 0 ]; then
|
if [ -z "$BUILD_LOG" ] || [ "$BUILD_LOG" -le 0 ]; then
|
||||||
BUILD_LOG=0
|
BUILD_LOG=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
4
.github/scripts/sketch_utils.sh
vendored
4
.github/scripts/sketch_utils.sh
vendored
|
|
@ -78,10 +78,10 @@ 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,PartitionScheme=huge_app"
|
esp32_opts="FlashMode=dio,PSRAM=enabled,PartitionScheme=huge_app"
|
||||||
esp32s2_opts="PSRAM=enabled,PartitionScheme=huge_app"
|
esp32s2_opts="PSRAM=enabled,PartitionScheme=huge_app"
|
||||||
esp32s3_opts="PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
|
esp32s3_opts="PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
|
||||||
esp32c3_opts="PartitionScheme=huge_app"
|
esp32c3_opts="FlashMode=dio,PartitionScheme=huge_app"
|
||||||
esp32c6_opts="PartitionScheme=huge_app"
|
esp32c6_opts="PartitionScheme=huge_app"
|
||||||
esp32h2_opts="PartitionScheme=huge_app"
|
esp32h2_opts="PartitionScheme=huge_app"
|
||||||
|
|
||||||
|
|
|
||||||
28
.github/scripts/tests_run.sh
vendored
28
.github/scripts/tests_run.sh
vendored
|
|
@ -8,7 +8,7 @@ function run_test() {
|
||||||
local sketchdir=$(dirname $sketch)
|
local sketchdir=$(dirname $sketch)
|
||||||
local sketchname=$(basename $sketchdir)
|
local sketchname=$(basename $sketchdir)
|
||||||
|
|
||||||
if [[ -f "$sketchdir/.skip.$platform" ]]; then
|
if [[ -f "$sketchdir/.skip.$platform" ]] || [[ -f "$sketchdir/.skip.$target" ]] || [[ -f "$sketchdir/.skip.$platform.$target" ]]; then
|
||||||
echo "Skipping $sketchname test for $target, platform: $platform"
|
echo "Skipping $sketchname test for $target, platform: $platform"
|
||||||
skipfile="$sketchdir/.test_skipped"
|
skipfile="$sketchdir/.test_skipped"
|
||||||
touch $skipfile
|
touch $skipfile
|
||||||
|
|
@ -45,11 +45,24 @@ function run_test() {
|
||||||
if [[ -f "$sketchdir/scenario.yaml" ]]; then
|
if [[ -f "$sketchdir/scenario.yaml" ]]; then
|
||||||
extra_args+=" --wokwi-scenario $sketchdir/scenario.yaml"
|
extra_args+=" --wokwi-scenario $sketchdir/scenario.yaml"
|
||||||
fi
|
fi
|
||||||
|
elif [ $platform == "qemu" ]; then
|
||||||
|
PATH=$HOME/qemu/bin:$PATH
|
||||||
|
extra_args="--embedded-services qemu --qemu-image-path $build_dir/$sketchname.ino.merged.bin"
|
||||||
|
|
||||||
|
if [ $target == "esp32" ] || [ $target == "esp32s3" ]; then
|
||||||
|
extra_args+=" --qemu-prog-path qemu-system-xtensa --qemu-cli-args=\"-machine $target -m 4M -nographic\""
|
||||||
|
elif [ $target == "esp32c3" ]; then
|
||||||
|
extra_args+=" --qemu-prog-path qemu-system-riscv32 --qemu-cli-args=\"-machine $target -icount 3 -nographic\""
|
||||||
|
else
|
||||||
|
echo "Unsupported QEMU target: $target"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
extra_args="--embedded-services esp,arduino"
|
extra_args="--embedded-services esp,arduino"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pytest tests --build-dir $build_dir -k test_$sketchname --junit-xml=$report_file $extra_args
|
echo "pytest tests --build-dir $build_dir -k test_$sketchname --junit-xml=$report_file $extra_args"
|
||||||
|
bash -c "pytest tests --build-dir $build_dir -k test_$sketchname --junit-xml=$report_file $extra_args"
|
||||||
result=$?
|
result=$?
|
||||||
if [ $result -ne 0 ]; then
|
if [ $result -ne 0 ]; then
|
||||||
return $result
|
return $result
|
||||||
|
|
@ -71,6 +84,13 @@ while [ ! -z "$1" ]; do
|
||||||
-c )
|
-c )
|
||||||
chunk_run=1
|
chunk_run=1
|
||||||
;;
|
;;
|
||||||
|
-q )
|
||||||
|
if [ ! -d $QEMU_PATH ]; then
|
||||||
|
echo "QEMU path $QEMU_PATH does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
platform="qemu"
|
||||||
|
;;
|
||||||
-w )
|
-w )
|
||||||
shift
|
shift
|
||||||
wokwi_timeout=$1
|
wokwi_timeout=$1
|
||||||
|
|
@ -113,7 +133,9 @@ while [ ! -z "$1" ]; do
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
source ${SCRIPTS_DIR}/install-arduino-ide.sh
|
if [ ! $platform == "qemu" ]; then
|
||||||
|
source ${SCRIPTS_DIR}/install-arduino-ide.sh
|
||||||
|
fi
|
||||||
|
|
||||||
# If sketch is provided and test type is not, test type is inferred from the sketch path
|
# If sketch is provided and test type is not, test type is inferred from the sketch path
|
||||||
if [[ $test_type == "all" ]] || [[ -z $test_type ]]; then
|
if [[ $test_type == "all" ]] || [[ -z $test_type ]]; then
|
||||||
|
|
|
||||||
78
.github/workflows/hil.yml
vendored
78
.github/workflows/hil.yml
vendored
|
|
@ -86,6 +86,83 @@ jobs:
|
||||||
~/.arduino/tests/**/build*.tmp/*.elf
|
~/.arduino/tests/**/build*.tmp/*.elf
|
||||||
~/.arduino/tests/**/build*.tmp/*.json
|
~/.arduino/tests/**/build*.tmp/*.json
|
||||||
|
|
||||||
|
qemu-test:
|
||||||
|
needs: [gen_chunks, build]
|
||||||
|
name: ${{matrix.chip}}-QEMU_Test#${{matrix.chunks}}
|
||||||
|
if: ${{ false }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
chip: ['esp32', 'esp32c3'] # Currently only ESP32 and ESP32-C3 are supported by QEMU
|
||||||
|
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
QEMU_INSTALL_PATH: "$HOME"
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Get QEMU version
|
||||||
|
uses: pozetroninc/github-action-get-latest-release@v0.7.0
|
||||||
|
id: get-qemu-version
|
||||||
|
with:
|
||||||
|
token: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
owner: espressif
|
||||||
|
repo: qemu
|
||||||
|
excludes: prerelease, draft
|
||||||
|
|
||||||
|
- name: Cache tools
|
||||||
|
id: cache-linux
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/qemu
|
||||||
|
~/.cache/pip
|
||||||
|
key: qemu-${{ steps.get-qemu-version.outputs.release }}-${{ hashFiles('.github/workflows/hil.yml') }}
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install -U pip
|
||||||
|
pip install -r tests/requirements.txt --extra-index-url https://dl.espressif.com/pypi
|
||||||
|
sudo apt update && sudo apt install libpixman-1-0 libnuma1 libglib2.0-0 libslirp0 libsdl2-2.0-0
|
||||||
|
|
||||||
|
- name: Download QEMU
|
||||||
|
if: steps.cache-linux.outputs.cache-hit != 'true'
|
||||||
|
run: |
|
||||||
|
cd ${{ env.QEMU_INSTALL_PATH }}
|
||||||
|
underscore_release=$(echo ${{ steps.get-qemu-version.outputs.release }} | sed 's/\-/_/g')
|
||||||
|
curl -L https://github.com/espressif/qemu/releases/download/${{ steps.get-qemu-version.outputs.release }}/qemu-riscv32-softmmu-${underscore_release}-x86_64-linux-gnu.tar.xz > qemu-riscv32.tar.xz
|
||||||
|
curl -L https://github.com/espressif/qemu/releases/download/${{ steps.get-qemu-version.outputs.release }}/qemu-xtensa-softmmu-${underscore_release}-x86_64-linux-gnu.tar.xz > qemu-xtensa.tar.xz
|
||||||
|
tar -xf qemu-riscv32.tar.xz
|
||||||
|
tar -xf qemu-xtensa.tar.xz
|
||||||
|
rm qemu-*
|
||||||
|
echo "QEMU_PATH=${{ env.QEMU_INSTALL_PATH }}/qemu" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Download ${{matrix.chip}}-${{matrix.chunks}} artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
|
||||||
|
path: ~/
|
||||||
|
|
||||||
|
- name: Run Tests
|
||||||
|
run: QEMU_PATH="${{env.QEMU_PATH}}" bash .github/scripts/tests_run.sh -c -t ${{matrix.chip}} -i ${{matrix.chunks}} -m ${{env.MAX_CHUNKS}} -q
|
||||||
|
|
||||||
|
- name: Check if tests were skipped
|
||||||
|
id: check-test-skipped
|
||||||
|
run: |
|
||||||
|
if [ $(find "tests" -name ".test_skipped") ]; then
|
||||||
|
echo "skipped=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "skipped=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Upload test result artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: ${{ always() && steps.check-test-skipped.outputs.skipped == 'false' }}
|
||||||
|
with:
|
||||||
|
name: qemu_results-${{matrix.chip}}-${{matrix.chunks}}
|
||||||
|
path: tests/*/*.xml
|
||||||
|
|
||||||
wokwi-test:
|
wokwi-test:
|
||||||
needs: [gen_chunks, build]
|
needs: [gen_chunks, build]
|
||||||
if: github.event_name == 'schedule'
|
if: github.event_name == 'schedule'
|
||||||
|
|
@ -205,4 +282,3 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: Event File
|
name: Event File
|
||||||
path: ${{github.event_path}}
|
path: ${{github.event_path}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,11 @@ recipe.hooks.objcopy.postobjcopy.1.pattern.windows=cmd /c if exist "{build.path}
|
||||||
recipe.hooks.objcopy.postobjcopy.2.pattern=/usr/bin/env bash -c "[ ! -d "{build.path}"/libraries/ESP_SR ] || [ ! -f "{compiler.sdk.path}"/esp_sr/srmodels.bin ] || cp -f "{compiler.sdk.path}"/esp_sr/srmodels.bin "{build.path}"/srmodels.bin"
|
recipe.hooks.objcopy.postobjcopy.2.pattern=/usr/bin/env bash -c "[ ! -d "{build.path}"/libraries/ESP_SR ] || [ ! -f "{compiler.sdk.path}"/esp_sr/srmodels.bin ] || cp -f "{compiler.sdk.path}"/esp_sr/srmodels.bin "{build.path}"/srmodels.bin"
|
||||||
recipe.hooks.objcopy.postobjcopy.2.pattern.windows=cmd /c if exist "{build.path}\libraries\ESP_SR" if exist "{compiler.sdk.path}\esp_sr\srmodels.bin" COPY /y "{compiler.sdk.path}\esp_sr\srmodels.bin" "{build.path}\srmodels.bin"
|
recipe.hooks.objcopy.postobjcopy.2.pattern.windows=cmd /c if exist "{build.path}\libraries\ESP_SR" if exist "{compiler.sdk.path}\esp_sr\srmodels.bin" COPY /y "{compiler.sdk.path}\esp_sr\srmodels.bin" "{build.path}\srmodels.bin"
|
||||||
|
|
||||||
|
# Create merged binary
|
||||||
|
recipe.hooks.objcopy.postobjcopy.3.pattern_args=--chip {build.mcu} merge_bin -o "{build.path}/{build.project_name}.merged.bin" --fill-flash-size {build.flash_size} --flash_mode keep --flash_freq keep --flash_size keep {build.bootloader_addr} "{build.path}/{build.project_name}.bootloader.bin" 0x8000 "{build.path}/{build.project_name}.partitions.bin" 0xe000 "{runtime.platform.path}/tools/partitions/boot_app0.bin" 0x10000 "{build.path}/{build.project_name}.bin"
|
||||||
|
recipe.hooks.objcopy.postobjcopy.3.pattern="{tools.esptool_py.path}/{tools.esptool_py.cmd}" {recipe.hooks.objcopy.postobjcopy.3.pattern_args}
|
||||||
|
recipe.hooks.objcopy.postobjcopy.3.pattern.linux=python3 "{tools.esptool_py.path}/{tools.esptool_py.cmd}" {recipe.hooks.objcopy.postobjcopy.3.pattern_args}
|
||||||
|
|
||||||
## Save bin
|
## Save bin
|
||||||
recipe.output.tmp_file={build.project_name}.bin
|
recipe.output.tmp_file={build.project_name}.bin
|
||||||
recipe.output.save_file={build.project_name}.{build.variant}.bin
|
recipe.output.save_file={build.project_name}.{build.variant}.bin
|
||||||
|
|
|
||||||
0
tests/performance/coremark/.skip.qemu
Normal file
0
tests/performance/coremark/.skip.qemu
Normal file
0
tests/performance/fibonacci/.skip.qemu
Normal file
0
tests/performance/fibonacci/.skip.qemu
Normal file
0
tests/performance/psramspeed/.skip.qemu
Normal file
0
tests/performance/psramspeed/.skip.qemu
Normal file
0
tests/performance/ramspeed/.skip.qemu
Normal file
0
tests/performance/ramspeed/.skip.qemu
Normal file
0
tests/performance/superpi/.skip.qemu
Normal file
0
tests/performance/superpi/.skip.qemu
Normal file
|
|
@ -1,5 +1,5 @@
|
||||||
[pytest]
|
[pytest]
|
||||||
addopts = --embedded-services esp,arduino,wokwi
|
addopts = --embedded-services esp,arduino,wokwi,qemu
|
||||||
|
|
||||||
# log related
|
# log related
|
||||||
log_cli = True
|
log_cli = True
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,4 @@ pytest-cov
|
||||||
pytest-embedded-serial-esp>=1.10.2
|
pytest-embedded-serial-esp>=1.10.2
|
||||||
pytest-embedded-arduino>=1.10.2
|
pytest-embedded-arduino>=1.10.2
|
||||||
pytest-embedded-wokwi>=1.10.2
|
pytest-embedded-wokwi>=1.10.2
|
||||||
|
pytest-embedded-qemu>=1.10.2
|
||||||
|
|
|
||||||
0
tests/validation/democfg/.skip.qemu
Normal file
0
tests/validation/democfg/.skip.qemu
Normal file
0
tests/validation/nvs/.skip.qemu
Normal file
0
tests/validation/nvs/.skip.qemu
Normal file
0
tests/validation/periman/.skip.qemu
Normal file
0
tests/validation/periman/.skip.qemu
Normal file
0
tests/validation/touch/.skip.qemu
Normal file
0
tests/validation/touch/.skip.qemu
Normal file
0
tests/validation/uart/.skip.qemu
Normal file
0
tests/validation/uart/.skip.qemu
Normal file
Loading…
Reference in a new issue