diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 53dbb2250bb..a1d681e97ec 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -14,26 +14,25 @@ function build(){ local BUILD_SKETCH="${SCRIPTS_DIR}/sketch_utils.sh build" local BUILD_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh chunk_build" - local args="$ARDUINO_IDE_PATH $ARDUINO_USR_PATH" + local args="-ai $ARDUINO_IDE_PATH -au $ARDUINO_USR_PATH" - args+=" \"$fqbn\"" + args+=" -t $target -fqbn $fqbn" if [ "$OS_IS_LINUX" == "1" ]; then - args+=" $target" - args+=" $ARDUINO_ESP32_PATH/libraries" - args+=" $chunk_index $chunks_cnt" + args+=" -p $ARDUINO_ESP32_PATH/libraries" + args+=" -i $chunk_index -m $chunks_cnt" ${BUILD_SKETCHES} ${args} else - if [ "$OS_IS_WINDOWS" == "1" ]; then - local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"` - local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"` - win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version - -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version" - args+=" ${win_opts}" - fi - for sketch in ${sketches}; do - ${BUILD_SKETCH} ${args} ${sketch} + args+=" -s $(dirname $sketch)" + if [ "$OS_IS_WINDOWS" == "1" ]; then + local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"` + local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"` + win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version + -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version" + args+=" ${win_opts}" + fi + ${BUILD_SKETCH} ${args} done fi } @@ -82,7 +81,7 @@ if [ "$BUILD_PIO" -eq 0 ]; then build "esp32s3" $FQBN_ESP32S3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32 build "esp32s2" $FQBN_ESP32S2 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX build "esp32c3" $FQBN_ESP32C3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX - build "esp32" $FQBN_ESP32 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32 + build "esp32" $FQBN_ESP32 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32 else source ${SCRIPTS_DIR}/install-platformio-esp32.sh # PlatformIO ESP32 Test diff --git a/.github/scripts/sketch_utils.sh b/.github/scripts/sketch_utils.sh index abe3db2b977..e3236831309 100755 --- a/.github/scripts/sketch_utils.sh +++ b/.github/scripts/sketch_utils.sh @@ -1,43 +1,142 @@ #!/bin/bash -function build_sketch(){ # build_sketch [extra-options] - if [ "$#" -lt 4 ]; then - echo "ERROR: Illegal number of parameters" - echo "USAGE: ${0} build [extra-options]" - return 1 +function build_sketch(){ # build_sketch [extra-options] + while [ ! -z "$1" ]; do + case "$1" in + -ai ) + shift + ide_path=$1 + ;; + -au ) + shift + user_path=$1 + ;; + -t ) + shift + target=$1 + ;; + -fqbn ) + shift + fqbn=$1 + ;; + -o ) + shift + options=$1 + ;; + -s ) + shift + sketchdir=$1 + ;; + * ) + break + ;; + esac + shift + done + + xtra_opts=$* + + if [ -z $sketchdir ]; then + echo "ERROR: Sketch directory not provided" + echo "$USAGE" + exit 1 fi - local ide_path=$1 - local usr_path=$2 - local fqbn=$3 - local sketch=$4 - local xtra_opts=$5 - local win_opts=$6 + # No FQBN was passed, try to get it from other options + + if [ -z $fqbn ]; then + if [ -z $target ]; then + echo "ERROR: Unspecified chip" + echo "$USAGE" + exit 1 + fi + + # The options are either stored in the test directory, for a per test + # customization or passed as parameters. Command line options take + # precedence. Note that the following logic also falls to the default + # parameters if no arguments were passed and no file was found. + + if [ -z $options ] && [ -f $sketchdir/cfg.json ]; then + # The config file could contain multiple FQBNs for one chip. If + # that's the case we build one time for every FQBN. + + len=`jq -r --arg chip $target '.targets[] | select(.name==$chip) | .fqbn | length' $sketchdir/cfg.json` + fqbn=`jq -r --arg chip $target '.targets[] | select(.name==$chip) | .fqbn' $sketchdir/cfg.json` + else + # Since we are passing options, we will end up with only one FQBN to + # build. + + len=1 + + # Default FQBN options if none were passed in the command line. + + esp32_opts="PSRAM=enabled,PartitionScheme=huge_app" + esp32s2_opts="PSRAM=enabled,PartitionScheme=huge_app" + esp32s3_opts="PSRAM=opi,USBMode=default,PartitionScheme=huge_app" + esp32c3_opts="PartitionScheme=huge_app" + + # Select the common part of the FQBN based on the target. The rest will be + # appended depending on the passed options. + + case "$target" in + "esp32") + fqbn="espressif:esp32:esp32:${options:-$esp32_opts}" + ;; + "esp32s2") + fqbn="espressif:esp32:esp32s2:${options:-$esp32s2_opts}" + ;; + "esp32c3") + fqbn="espressif:esp32:esp32c3:${options:-$esp32c3_opts}" + ;; + "esp32s3") + fqbn="espressif:esp32:esp32s3:${options:-$esp32s3_opts}" + ;; + esac + + # Make it look like a JSON array. + + fqbn="[\"$fqbn\"]" + fi + else + # An FQBN was passed. Make it look like a JSON array. + + len=1 + fqbn="[\"$fqbn\"]" + fi + + if [ -z "$fqbn" ]; then + echo "No FQBN passed or unvalid chip: $target" + exit 1 + fi ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp" if [ -z "$ARDUINO_BUILD_DIR" ]; then - build_dir="$(dirname $sketch)/build" + build_dir="$sketchdir/build" else build_dir="$ARDUINO_BUILD_DIR" fi - echo $sketch - - rm -rf "$build_dir" - mkdir -p "$build_dir" mkdir -p "$ARDUINO_CACHE_DIR" - $ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \ - -fqbn=$fqbn \ - -warnings="all" \ - -tools "$ide_path/tools-builder" \ - -tools "$ide_path/tools" \ - -built-in-libraries "$ide_path/libraries" \ - -hardware "$ide_path/hardware" \ - -hardware "$usr_path/hardware" \ - -libraries "$usr_path/libraries" \ - -build-cache "$ARDUINO_CACHE_DIR" \ - -build-path "$build_dir" \ - $win_opts $xtra_opts "$sketch" + for i in `seq 0 $(($len - 1))` + do + rm -rf "$build_dir$i" + mkdir -p "$build_dir$i" + currfqbn=`echo $fqbn | jq -r --argjson i $i '.[$i]'` + sketchname=$(basename $sketchdir) + echo "Building $sketchname with FQBN=$currfqbn" + $ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \ + -fqbn=\"$currfqbn\" \ + -warnings="all" \ + -tools "$ide_path/tools-builder" \ + -tools "$ide_path/tools" \ + -built-in-libraries "$ide_path/libraries" \ + -hardware "$ide_path/hardware" \ + -hardware "$user_path/hardware" \ + -libraries "$user_path/libraries" \ + -build-cache "$ARDUINO_CACHE_DIR" \ + -build-path "$build_dir$i" \ + $xtra_opts "${sketchdir}/${sketchname}.ino" + done } function count_sketches(){ # count_sketches [target] @@ -73,29 +172,63 @@ function count_sketches(){ # count_sketches [target] return $sketchnum } -function build_sketches(){ # build_sketches [extra-options] - local ide_path=$1 - local usr_path=$2 - local fqbn=$3 - local target=$4 - local path=$5 - local chunk_idex=$6 - local chunks_num=$7 - local xtra_opts=$8 - - if [ "$#" -lt 7 ]; then - echo "ERROR: Illegal number of parameters" - echo "USAGE: ${0} chunk_build [ ] [extra-options]" - return 1 +function build_sketches(){ # build_sketches [extra-options] + + local args="" + while [ ! -z "$1" ]; do + case $1 in + -ai ) + shift + ide_path=$1 + ;; + -au ) + shift + user_path=$1 + ;; + -t ) + shift + target=$1 + args+=" -t $target" + ;; + -fqbn ) + shift + fqbn=$1 + args+=" -fqbn $fqbn" + ;; + -p ) + shift + path=$1 + ;; + -i ) + shift + chunk_index=$1 + ;; + -m ) + shift + chunk_max=$1 + ;; + * ) + break + ;; + esac + shift + done + + local xtra_opts=$* + + if [ -z $chunk_index ] || [ -z $chunk_max ]; then + echo "ERROR: Invalid chunk paramters" + echo "$USAGE" + exit 1 fi - if [ "$chunks_num" -le 0 ]; then + if [ "$chunk_max" -le 0 ]; then echo "ERROR: Chunks count must be positive number" return 1 fi - if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then - echo "ERROR: Chunk index must be less than chunks count" - return 1 + + if [ "$chunk_index" -gt "$chunk_max" ] && [ "$chunk_max" -ge 2 ]; then + chunk_index=$chunk_max fi set +e @@ -105,25 +238,25 @@ function build_sketches(){ # build_sketches - ${0} - " - exit 0 -fi - -target=$1 - -case "$target" in - "esp32") fqbn="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app" - ;; - "esp32s2") fqbn="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app" - ;; - "esp32c3") fqbn="espressif:esp32:esp32c3:PartitionScheme=huge_app" - ;; - "esp32s3") fqbn="espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app" - ;; -esac - -if [ -z $fqbn ]; then - echo "Unvalid chip $1" - exit 0 -fi +chunk_build=0 + +while [ ! -z "$1" ]; do + case $1 in + -c ) + chunk_build=1 + ;; + -s ) + shift + sketch=$1 + ;; + -h ) + echo "$USAGE" + exit 0 + ;; + -clean ) + clean + exit 0 + ;; + * ) + break + ;; + esac + shift +done source ${SCRIPTS_DIR}/install-arduino-ide.sh source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh -args="$ARDUINO_IDE_PATH $ARDUINO_USR_PATH \"$fqbn\"" +args="-ai $ARDUINO_IDE_PATH -au $ARDUINO_USR_PATH" if [ $chunk_build -eq 1 ]; then - chunk_index=$2 - chunk_max=$3 - - if [ "$chunk_index" -gt "$chunk_max" ] && [ "$chunk_max" -ge 2 ]; then - chunk_index=$chunk_max - fi BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh chunk_build" - args+=" $target $PWD/tests $chunk_index $chunk_max" + args+=" -p $PWD/tests" else - sketchdir=$2 BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh build" - args+=" $PWD/tests/$sketchdir/$sketchdir.ino" + args+=" -s $PWD/tests/$sketch" fi -${BUILD_CMD} ${args} +${BUILD_CMD} ${args} $* diff --git a/.github/scripts/tests_run.sh b/.github/scripts/tests_run.sh index a13f3c00c1d..94626de9c46 100755 --- a/.github/scripts/tests_run.sh +++ b/.github/scripts/tests_run.sh @@ -1,71 +1,138 @@ #!/bin/bash -target=$1 -chunk_idex=$2 -chunks_num=$3 +function run_test() { + local target=$1 + local sketch=$2 + local options=$3 + local erase_flash=$4 + local sketchdir=$(dirname $sketch) + local sketchname=$(basename $sketchdir) + + if [ $options -eq 0 ] && [ -f $sketchdir/cfg.json ]; then + len=`jq -r --arg chip $target '.targets[] | select(.name==$chip) | .fqbn | length' $sketchdir/cfg.json` + else + len=1 + fi + + for i in `seq 0 $(($len - 1))` + do + echo "Running test: $sketchname -- Config: $i" + if [ $erase_flash -eq 1 ]; then + esptool.py -c $target erase_flash + fi + + pytest tests --build-dir tests/$sketchname/build$i -k test_$sketchname --junit-xml=tests/$sketchname/$sketchname$i.xml + result=$? + if [ $result -ne 0 ]; then + return $result + fi + done +} SCRIPTS_DIR="./.github/scripts" COUNT_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh count" -source ${SCRIPTS_DIR}/install-arduino-ide.sh +chunk_run=0 +options=0 +erase=0 -if [ "$chunks_num" -le 0 ]; then - echo "ERROR: Chunks count must be positive number" - return 1 -fi -if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then - echo "ERROR: Chunk index must be less than chunks count" - return 1 -fi +while [ ! -z "$1" ]; do + case $1 in + -c ) + chunk_run=1 + ;; + -o ) + options=1 + ;; + -s ) + shift + sketch=$1 + ;; + -t ) + shift + target=$1 + ;; + -i ) + shift + chunk_index=$1 + ;; + -m ) + shift + chunk_max=$1 + ;; + -e ) + erase=1 + ;; + -h ) + echo "$USAGE" + exit 0 + ;; + * ) + break + ;; + esac + shift +done -set +e -${COUNT_SKETCHES} $PWD/tests $target -sketchcount=$? -set -e -sketches=$(cat sketches.txt) -rm -rf sketches.txt - -chunk_size=$(( $sketchcount / $chunks_num )) -all_chunks=$(( $chunks_num * $chunk_size )) -if [ "$all_chunks" -lt "$sketchcount" ]; then - chunk_size=$(( $chunk_size + 1 )) -fi +source ${SCRIPTS_DIR}/install-arduino-ide.sh -start_index=0 -end_index=0 -if [ "$chunk_idex" -ge "$chunks_num" ]; then - start_index=$chunk_idex - end_index=$sketchcount +if [ $chunk_run -eq 0 ]; then + run_test $target $PWD/tests/$sketch/$sketch.ino $options $erase else - start_index=$(( $chunk_idex * $chunk_size )) - if [ "$sketchcount" -le "$start_index" ]; then - echo "Skipping job" - return 0 - fi + if [ "$chunk_max" -le 0 ]; then + echo "ERROR: Chunks count must be positive number" + return 1 + fi - end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) - if [ "$end_index" -gt "$sketchcount" ]; then - end_index=$sketchcount - fi -fi + if [ "$chunk_index" -ge "$chunk_max" ] && [ "$chunk_max" -ge 2 ]; then + echo "ERROR: Chunk index must be less than chunks count" + return 1 + fi -start_num=$(( $start_index + 1 )) -sketchnum=0 - -for sketch in $sketches; do - sketchdir=$(dirname $sketch) - sketchdirname=$(basename $sketchdir) - sketchname=$(basename $sketch) - sketchnum=$(($sketchnum + 1)) - if [ "$sketchnum" -le "$start_index" ] \ - || [ "$sketchnum" -gt "$end_index" ]; then - continue - fi - echo "" - echo "Test for Sketch Index $(($sketchnum - 1)) - $sketchdirname" - pytest tests -k test_$sketchdirname --junit-xml=tests/$sketchdirname/$sketchdirname.xml - result=$? - if [ $result -ne 0 ]; then - return $result - fi -done + set +e + ${COUNT_SKETCHES} $PWD/tests $target + sketchcount=$? + set -e + sketches=$(cat sketches.txt) + rm -rf sketches.txt + + chunk_size=$(( $sketchcount / $chunk_max )) + all_chunks=$(( $chunk_max * $chunk_size )) + if [ "$all_chunks" -lt "$sketchcount" ]; then + chunk_size=$(( $chunk_size + 1 )) + fi + + start_index=0 + end_index=0 + if [ "$chunk_index" -ge "$chunk_max" ]; then + start_index=$chunk_index + end_index=$sketchcount + else + start_index=$(( $chunk_index * $chunk_size )) + if [ "$sketchcount" -le "$start_index" ]; then + echo "Skipping job" + return 0 + fi + + end_index=$(( $(( $chunk_index + 1 )) * $chunk_size )) + if [ "$end_index" -gt "$sketchcount" ]; then + end_index=$sketchcount + fi + fi + + start_num=$(( $start_index + 1 )) + sketchnum=0 + + for sketch in $sketches; do + + sketchnum=$(($sketchnum + 1)) + if [ "$sketchnum" -le "$start_index" ] \ + || [ "$sketchnum" -gt "$end_index" ]; then + continue + fi + echo "" + echo "Sketch Index $(($sketchnum - 1))" + + run_test $target $sketch $options $erase + done +fi diff --git a/.github/workflows/hil.yml b/.github/workflows/hil.yml index b63223d2542..600e932d82f 100644 --- a/.github/workflows/hil.yml +++ b/.github/workflows/hil.yml @@ -31,14 +31,14 @@ jobs: id: gen-chunks run: | set +e - bash .github/scripts/sketch_utils.sh count tests - sketches=$((? - 1)) - if [[ $sketches -gt ${{env.MAX_CHUNKS}} ]]; then + .github/scripts/sketch_utils.sh count tests + sketches=$? + if [[ $sketches -ge ${{env.MAX_CHUNKS}} ]]; then $sketches=${{env.MAX_CHUNKS}} fi set -e rm sketches.txt - CHUNKS=$(jq -c -n '$ARGS.positional' --args `seq 0 1 $sketches`) + CHUNKS=$(jq -c -n '$ARGS.positional' --args `seq 0 1 $((sketches - 1))`) echo "::set-output name=chunks::${CHUNKS}" Build: @@ -56,14 +56,14 @@ jobs: - name: Build sketches run: | - bash .github/scripts/tests_build.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}} + bash .github/scripts/tests_build.sh -c -t ${{matrix.chip}} -i ${{matrix.chunks}} -m ${{env.MAX_CHUNKS}} - name: Upload ${{matrix.chip}}-${{matrix.chunks}} artifacts uses: actions/upload-artifact@v2 with: name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts path: | - tests/*/build/*.bin - tests/*/build/*.json + tests/*/build*/*.bin + tests/*/build*/*.json Test: needs: [gen_chunks, Build] name: ${{matrix.chip}}-Test#${{matrix.chunks}} @@ -96,10 +96,11 @@ jobs: run: | pip install -U pip pip install -r tests/requirements.txt + apt update && apt install -y -qq jq - name: Run Tests run: | - bash .github/scripts/tests_run.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}} + bash .github/scripts/tests_run.sh -c -t ${{matrix.chip}} -i ${{matrix.chunks}} -m ${{env.MAX_CHUNKS}} -e - name: Upload test result artifacts uses: actions/upload-artifact@v2 diff --git a/tests/.gitignore b/tests/.gitignore index 3d433392930..d9333804a5c 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,2 +1,3 @@ -build/ +build*/ __pycache__/ +*.xml diff --git a/tests/democfg/cfg.json b/tests/democfg/cfg.json new file mode 100644 index 00000000000..2b9f26bf1fe --- /dev/null +++ b/tests/democfg/cfg.json @@ -0,0 +1,24 @@ +{ + "targets": [ + { + "name": "esp32", + "fqbn":[ + "espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app,FlashMode=dio", + "espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app,FlashMode=dout", + "espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app,FlashMode=qio" + ] + }, + { + "name": "esp32s2", + "fqbn": ["espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"] + }, + { + "name": "esp32c3", + "fqbn": ["espressif:esp32:esp32c3:PartitionScheme=huge_app"] + }, + { + "name": "esp32s3", + "fqbn": ["espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app"] + } + ] +} diff --git a/tests/democfg/democfg.ino b/tests/democfg/democfg.ino new file mode 100644 index 00000000000..835dc1b20b2 --- /dev/null +++ b/tests/democfg/democfg.ino @@ -0,0 +1,11 @@ +void setup(){ + Serial.begin(115200); + while (!Serial) { + ; + } + + Serial.println("Hello cfg!"); +} + +void loop(){ +} diff --git a/tests/democfg/test_democfg.py b/tests/democfg/test_democfg.py new file mode 100644 index 00000000000..0dcc877dc36 --- /dev/null +++ b/tests/democfg/test_democfg.py @@ -0,0 +1,2 @@ +def test_cfg(dut): + dut.expect('Hello cfg!')