Files
OpenBK7231T_App/.github/workflows/workflow.yaml
Bartosz Nitka 92ea9cd8ab Ability to run linux tests with AddressSanitizer (#1651)
* Ability to run linux tests with AddressSanitizer

This makes it possible to compile and run the tests with Address
Sanitizer (ASAN) [1].

The command is:
```
make -f custom.mk clean; ASAN=1 make -f custom.mk && ./build/win_main -runUnitTests 2
```

Building without ASAN works without change.

Address Sanitizer saves a lot of time debugging memory issues, for
example for a bug where we index in an array with negative index it
gives this nice error message:
```
=================================================================
==2532658==ERROR: AddressSanitizer: global-buffer-overflow on address 0x5642389c5e37 at pc 0x564237e67492 bp 0x7fff17726e50 sp 0x7fff17726e40
READ of size 1 at 0x5642389c5e37 thread T0
    #0 0x564237e67491 in CHANNEL_GetType src/new_cfg.c:427
    #1 0x564237dfc933 in TuyaMCU_ApplyMapping src/driver/drv_tuyaMCU.c:1126
    #2 0x564237dff92f in TuyaMCU_ParseStateMessage src/driver/drv_tuyaMCU.c:1632
    #3 0x564237e019fa in TuyaMCU_ProcessIncoming src/driver/drv_tuyaMCU.c:1977
    #4 0x564237e027ee in TuyaMCU_RunReceive src/driver/drv_tuyaMCU.c:2178
    #5 0x564237e02dc2 in TuyaMCU_RunFrame src/driver/drv_tuyaMCU.c:2335
    #6 0x564237dd2ce6 in DRV_RunQuickTick src/driver/drv_main.c:536
    #7 0x564237ec4037 in QuickTick src/user_main.c:946
    #8 0x564237eca8a5 in Sim_RunFrame src/win_main.c:106
    #9 0x564237eca993 in Sim_RunFrames src/win_main.c:134
    #10 0x564237ebce4a in Test_TuyaMCU_Basic src/selftest/selftest_tuyaMCU.c:369
    #11 0x564237ecab1f in Win_DoUnitTests src/win_main.c:194
    #12 0x564237ecba57 in main src/win_main.c:535
    #13 0x7fb55312ed8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #14 0x7fb55312ee3f in __libc_start_main_impl ../csu/libc-start.c:392
    #15 0x564237cb16b4 in _start (/home/niteria/tmp/broken-realloc/OpenBK7231T_App/build/win_main+0xcf6b4)

0x5642389c5e37 is located 51 bytes to the right of global variable 'stat_deduper_culled_tooFast' defined in 'src/mqtt/new_mqtt_deduper.c:40:12' (0x5642389c5e00) of size 4
0x5642389c5e37 is located 9 bytes to the left of global variable 'g_mutex' defined in 'src/mqtt/new_mqtt_deduper.c:42:26' (0x5642389c5e40) of size 4
SUMMARY: AddressSanitizer: global-buffer-overflow src/new_cfg.c:427 in CHANNEL_GetType
Shadow bytes around the buggy address:
  0x0ac8c7130b70: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
  0x0ac8c7130b80: 00 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
  0x0ac8c7130b90: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
  0x0ac8c7130ba0: 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9
  0x0ac8c7130bb0: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
=>0x0ac8c7130bc0: 04 f9 f9 f9 f9 f9[f9]f9 04 f9 f9 f9 f9 f9 f9 f9
  0x0ac8c7130bd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac8c7130be0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac8c7130bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac8c7130c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac8c7130c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==2532658==ABORTING
```

[1] https://github.com/google/sanitizers/wiki/addresssanitizer

* disable tests broken on linux

* add a suppression file for known leaks

* attempt at adding an ASAN workflow

* fix autogen

* Update workflow.yaml

---------

Co-authored-by: openshwprojects <85486843+openshwprojects@users.noreply.github.com>
2025-05-31 14:27:02 +02:00

320 lines
14 KiB
YAML

name: Build App
on:
push:
branches:
- '**'
pull_request:
branches:
- '**'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APP_NAME: ${{ github.event.repository.name }}
jobs:
refs:
name: Prepare CI Environment
runs-on: ubuntu-22.04
outputs:
sha_short: ${{ steps.refs.outputs.sha_short }}
short_ref: ${{ steps.refs.outputs.short_ref }}
version: ${{ steps.refs.outputs.version }}
new_release: ${{ steps.refs.outputs.new_release }}
steps:
- name: Source checkout
uses: actions/checkout@v4
- name: Update SDKs if required
run: make update-submodules
- name: Semantic Release
id: semantic
uses: cycjimmy/semantic-release-action@v4
with:
dry_run: true
semantic_version: 21
extra_plugins: |
@semantic-release/changelog
@semantic-release/git
conventional-changelog-conventionalcommits@7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set outputs
id: refs
run: |
export BRANCH=${GITHUB_REF#refs/*/}
echo "branch: ${BRANCH}"
export BRANCHTRANSLATED=$(echo ${BRANCH} | tr '/' '_')
echo "short_ref: ${BRANCHTRANSLATED}"
export VERSION=""
if ${{ steps.semantic.outputs.new_release_published == 'true' }}; then
export VERSION=${{ steps.semantic.outputs.new_release_version }}
else
export VERSION=${BRANCHTRANSLATED}_$(git rev-parse --short=12 HEAD)
fi
echo "new_release=${{ steps.semantic.outputs.new_release_published }}" >> $GITHUB_OUTPUT
echo "short_ref=${BRANCHTRANSLATED}" >> $GITHUB_OUTPUT
echo "sha_short=SHA-$(git rev-parse --short=12 HEAD)" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_OUTPUT
build2:
name: Build Simulator
needs: refs
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout berry submodule
run: |
git submodule update --init --recursive libraries/berry
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Checkout simulator repository
run: |
git clone https://github.com/openshwprojects/obkSimulator
mkdir -p ./libs_for_simulator
cp -r ./obkSimulator/simulator/libs_for_simulator/* ./libs_for_simulator
- name: Build project
run: msbuild openBeken_win32_mvsc2017.vcxproj /p:Configuration=Release /p:PlatformToolset=v143
- name: Flatten build assets
run: |
mkdir -p flat
cp ./Release/openBeken_win32.exe flat/
cp ./obkSimulator/simulator/*.dll flat/
cp ./run_*.bat flat/
mkdir -p flat/examples
cp -r ./obkSimulator/examples/* flat/examples/
- name: Run unit tests
run: |
./flat/openBeken_win32.exe -runUnitTests 2
- name: Compress build assets
run: |
Compress-Archive -Path flat/* -DestinationPath obkSimulator_win32_${{ needs.refs.outputs.version }}.zip
- name: Copy build assets
run: |
mkdir -Force output/${{ needs.refs.outputs.version }}
cp obkSimulator_win32_${{ needs.refs.outputs.version }}.zip output/${{ needs.refs.outputs.version }}/obkSimulator_${{ needs.refs.outputs.version }}.zip
- name: Upload build assets
uses: actions/upload-artifact@v4
with:
name: ${{ env.APP_NAME }}_${{ needs.refs.outputs.version }}_sim
path: output/${{ needs.refs.outputs.version }}/obkSimulator_${{ needs.refs.outputs.version }}.zip
build_asan:
name: Build Linux Simulator and Run Tests With Address Sanitizer
needs: refs
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout berry submodule
run: |
git submodule update --init --recursive libraries/berry
- name: Build project
run: ASAN=1 make -f custom.mk
- name: Run unit tests
run: |
export LSAN_OPTIONS=suppressions=platforms/linux/asan.suppressions
./build/win_main -runUnitTests 2
build:
name: Build
needs: refs
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
# default for all platforms
- platform: OpenBK7231T
variant: default
- platform: OpenBK7231N
variant: default
- platform: OpenBK7238
variant: default
- platform: OpenXR809
variant: default
- platform: OpenXR806
variant: default
- platform: OpenXR872
variant: default
- platform: OpenBL602
variant: default
- platform: OpenW800
variant: default
- platform: OpenW600
variant: default
- platform: OpenLN882H
variant: default
- platform: OpenTR6260
variant: default
- platform: OpenRTL8710A
variant: default
- platform: OpenRTL8710B
variant: default
- platform: OpenRTL87X0C
variant: default
- platform: OpenRTL8720D
variant: default
- platform: OpenECR6600
variant: default
# extras for BK7231T
- platform: OpenBK7231T
variant: berry
- platform: OpenBK7231T
variant: tuyaMCU
- platform: OpenBK7231T
variant: powerMetering
- platform: OpenBK7231T
variant: irRemoteESP
# extras for BK7231N
- platform: OpenBK7231N
variant: berry
- platform: OpenBK7231N
variant: tuyaMCU
- platform: OpenBK7231N
variant: powerMetering
- platform: OpenBK7231N
variant: irRemoteESP
steps:
- name: Source checkout
uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.8'
architecture: 'x64'
- name: Install dependencies
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get -y install libc6-i386 make cmake gcc-arm-none-eabi
pip3 install pycryptodomex
pip3 install configobj
pip3 install toml
pip3 install fdt
- name: Copy config header
if: matrix.variant != 'default'
run: cp src/configs/obk_config_${{ matrix.variant }}.h src/obk_config.h
- run: ls -la
- name: Run make
run: make APP_VERSION=${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }} APP_NAME=${{ matrix.platform }} VARIANT=${{ matrix.variant }} ${{ matrix.platform }}
- name: Save build assets
uses: actions/upload-artifact@v4
with:
name: ${{ env.APP_NAME }}_${{ needs.refs.outputs.version }}_${{ matrix.platform }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}
path: |
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_UA_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}.bin
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_UG_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}.bin
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_QIO_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}.bin
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/OpenBK7231M_QIO_${{ needs.refs.outputs.version }}.bin
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}.rbl
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}.img
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}.bin
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}.fls
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}_ota.img
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}_gz.img
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}_OTA.bin
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}_OTA.bin.xz
output/${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}${{ matrix.variant != 'default' && '_' || '' }}${{ matrix.variant != 'default' && matrix.variant || '' }}_OTA.bin.xz.ota
if-no-files-found: warn
build_idf:
name: Build IDF
needs: refs
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
platform: [OpenESP32, OpenESP32C3, OpenESP32C2, OpenESP32C6, OpenESP32S3, OpenESP32S2]
steps:
- name: Source checkout
uses: actions/checkout@v4
- name: SDK checkout
uses: actions/checkout@v4
with:
repository: espressif/esp-idf
path: sdk/esp-idf
ref: v5.3.2
submodules: recursive
- uses: actions/setup-python@v5
with:
python-version: '3.8'
architecture: 'x64'
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install make cmake python3-venv
pip3 install pycryptodomex
pip3 install configobj
pip3 install toml
pip3 install fdt
- name: Run make
run: |
cd sdk/esp-idf
./install.sh > /dev/null
. ./export.sh
. ./add_path.sh
cd ../..
make APP_VERSION=${{ needs.refs.outputs.version }} APP_NAME=${{ matrix.platform }} ${{ matrix.platform }}
- name: Save build assets
uses: actions/upload-artifact@v4
with:
name: ${{ env.APP_NAME }}_${{ needs.refs.outputs.version }}_${{ matrix.platform }}
path: |
output/${{ needs.refs.outputs.version }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}.img
output/${{ needs.refs.outputs.version }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}.factory.bin
if-no-files-found: warn
merge:
name: Merge Artifacts
runs-on: ubuntu-22.04
needs: [refs, build, build2, build_idf]
#if: always() && needs.refs.outputs.new_release == 'true' && (github.ref == 'refs/heads/main' || github.ref_name == 'alpha')
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: ${{ env.APP_NAME }}_${{ needs.refs.outputs.version }}
#delete-merged: true
release:
name: Semantic Release Images and Artifacts
runs-on: ubuntu-22.04
needs: [merge, refs]
if: always() && needs.refs.outputs.new_release == 'true' && (github.ref == 'refs/heads/main' || github.ref_name == 'alpha')
steps:
- name: Source checkout
uses: actions/checkout@v4
- name: Fetch build assets
uses: actions/download-artifact@v4
with:
name: ${{ env.APP_NAME }}_${{ needs.refs.outputs.version }}
path: output/${{ needs.refs.outputs.version }}
- name: Run Semantic Release
id: semantic
uses: cycjimmy/semantic-release-action@v4
with:
dry_run: false
semantic_version: 21
extra_plugins: |
@semantic-release/changelog
@semantic-release/git
conventional-changelog-conventionalcommits@7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Echo Semantic Release Versions
if: steps.semantic.outputs.new_release_published == 'true'
run: |
echo ${{ steps.semantic.outputs.new_release_version }}
echo ${{ steps.semantic.outputs.new_release_major_version }}
echo ${{ steps.semantic.outputs.new_release_minor_version }}
echo ${{ steps.semantic.outputs.new_release_patch_version }}