Files
MeshCore/.github/workflows/run-unit-tests.yml
T
mikecarper b2f2b5bf02 Add persistent LoRa OTA speed control and harden timing
Add get/set ota.speed and OTA CLI aliases for factors from 0.05 to 3,
defaulting to the existing pace. Persist the setting independently of the
OTA workspace and apply it to OTA packet pacing, relays, discovery and
adverts while retaining the configured airtime budget.

Preserve physical proof/retry allowances, account for both participating
radio profiles, keep optional deadlines armed across millis rollover, and
exclude intentional pacing from observer stale-packet age. Keep local
verification at its normal rate and retain a valid saved speed if backup
recovery cannot finish. Add documentation and CI regression coverage.

Validation: 1,491 native tests and 26 CLI/integration tests passed. Built
ESP32 full repeater, ESP32 full Companion, nRF52 full Companion and STM32
USB Companion successfully, including their memory/size checks.
2026-09-15 06:16:29 -07:00

211 lines
8.1 KiB
YAML

name: Run Unit Tests
on:
push:
branches:
- main
- master
- keymindCascade
pull_request:
workflow_dispatch:
jobs:
stm32-companion-smoke:
runs-on: ubuntu-latest
steps:
- name: Clone Repo
uses: actions/checkout@v4
- name: Setup Build Environment
uses: ./.github/actions/setup-build-environment
- name: Compile ordinary STM32 USB Companion with pinned core and RadioLib
run: pio run -e RAK_3x72_companion_radio_usb
bootloader-version:
runs-on: ubuntu-latest
steps:
- name: Clone Repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Verify bootloader version regressions without hardware or downloads
run: python3 -B test/test_nrf52_bootloader_version.py -v
- name: Install signed-package verification dependency
run: python3 -m pip install cryptography
- name: Verify old-firmware compatibility in both OTA launchers
run: python3 -B -m unittest discover -s tools/lora_ota -p test_lora_ota_bootloader_version.py -v
- name: Verify all signed OTAFIX 2.4.6 release images
env:
MESHCORE_BOOTLOADER_MOTA_ZIP: ${{ runner.temp }}/OTAFIX-2.4.6-bootloader-mota.zip
# The test pins the archive SHA-256, verifies every .mota signature,
# and checks the exact MeshTower V2 SD CRC from the bug report.
run: |
curl --fail --location --retry 3 --max-time 120 --output "$MESHCORE_BOOTLOADER_MOTA_ZIP" \
https://github.com/mikecarper/Adafruit_nRF52_Bootloader_OTAFIX/releases/download/0.11.0-OTAFIX2.4.6/OTAFIX-2.4.6-bootloader-mota.zip
python3 -B test/test_nrf52_bootloader_version.py -v
test:
runs-on: ubuntu-latest
steps:
- name: Clone Repo
uses: actions/checkout@v4
- name: Setup Build Environment
uses: ./.github/actions/setup-build-environment
- name: Verify ArduinoJson pin
run: |
python3 -B scripts/check_arduinojson_pin.py --self-test
python3 -B scripts/check_arduinojson_pin.py
- name: Run Unit Tests
run: pio test -e native -e native_kiss_modem -vv
- name: Verify filter playground modes and built-in defaults
run: node scripts/test_filter_tool.js
- name: Verify bridge filter wiring and shorthand permissions
run: python3 -B test/test_transport_filter_wiring.py -v
- name: Verify Companion contact and channel TX routing
run: |
sudo apt-get update
sudo apt-get install -y libssl-dev
python3 -B test/test_companion_tx_routing.py -v
python3 -B test/test_contact_cache.py -v
- name: Verify receive recovery and pinned radio status transport
run: |
python3 -B test/test_radio_receive_contract.py
python3 - <<'PY'
from pathlib import Path
import re
import subprocess
dependency = re.search(r'https://github.com/jgromes/RadioLib.git#[0-9a-f]{40}',
Path('platformio.ini').read_text()).group(0)
Path('.pio/libdeps/radio-status-test').mkdir(parents=True, exist_ok=True)
subprocess.run(['pio', 'pkg', 'install', '--global', '--library', dependency,
'--storage-dir', '.pio/libdeps/radio-status-test'], check=True)
PY
python3 -B test/test_sx126x_receive_mode.py
- name: Verify temporary-radio timing and exact reply delivery
run: |
python3 -B test/test_carrier_wave.py
python3 -B test/test_radio_profile_cli.py
python3 -B test/test_radio_profile_scan.py
python3 -B test/test_repeater_radio_timing_integration.py
python3 -B test/test_temp_radio_reply_delivery_contract.py
python3 -B test/test_reply_tx_integration.py
python3 -B test/test_ota_speed.py -v
- name: Verify dual-profile switching and chirp timing
working-directory: test
run: >-
python3 -B -m unittest -v
test_sx1262_profile_switch test_sx1262_batched_modulation
test_radio_chirp_math
- name: Verify radio lab collectors and compiled experiment contracts
run: |
python3 -B -m unittest discover -s test -p 'test_profile_*.py' -v
python3 -B -m unittest discover -s tools/hil -p 'test_*.py' -v
- name: Verify ESP32 static DRAM budget
run: |
python3 -B test/test_esp32_dram.py
python3 -B test/test_elrs_power.py
python3 -B test/test_ota_heap_context.py
python3 -B test/test_client_acl_spiffs.py
- name: Verify ESP32 USB sleep and G3 button wake
run: python3 -B test/test_esp32_usb_sleep.py
- name: Verify Companion ASCII defaults and USB session cleanup
run: |
python3 -B test/test_companion_usb_default.py
python3 -B test/test_nrf52_usb_client.py
python3 -B test/test_esp32_usb_serial_hygiene.py
python3 -B test/test_stm32_float_conversion.py
- name: Verify Companion contact persistence and OTA sleep guards
run: python3 -B test/test_companion_contact_sleep_contract.py -v
- name: Verify Companion Bluetooth CLI connection protection
run: python3 -B test/test_companion_bluetooth_control.py -v
- name: Verify WiFi, ESP-NOW and combined wireless controls
run: |
python3 -B test/test_wireless_control.py -v
python3 -B test/test_espnow_radio_lifecycle.py -v
- name: Verify message reader buttons, touch targets, and footer layouts
working-directory: test
run: >-
python3 -B -m unittest
test_message_navigation test_companion_john test_reader_touch_coordinates
test_touch_debug_overlay test_touch_debug_cli test_color_theme
test_indicator_messages_profile test_t096_message_footer_profile
test_indicator_display_profile test_indicator_render_profile
test_indicator_exclusive_transport test_companion_transport_selector
- name: Verify logging sleep guards and instructions
run: |
python3 -B test/test_logging_sleep_contract.py
python3 -B test/test_picker_controls_generator.py
node test/test_firmware_picker.js
- name: Verify Full logging compiler flags and packaged capabilities
run: |
python3 -B test/test_full_build_flag_dedup.py
python3 -B test/test_full_logging_compile.py
python3 -B test/test_full_logging_resume.py
python3 -B test/test_firmware_capabilities.py
bash test/test_build_profiles.sh
- name: Verify nRF52 UF2-reset CLI coverage
run: python3 -B test/test_nrf52_uf2reset_cli.py
- name: Verify CLI setting dispatch and get-set coverage
run: |
python3 -B test/test_path_hash_cli.py
python3 -B test/test_cli_settings_contract.py
python3 -B test/test_local_cli_access.py
- name: Verify firmware memory budgets and nRF52 Bluetooth startup
run: |
bash test/test_build_size_detection.sh
python3 -B test/test_firmware_ram.py
python3 -B test/test_cascade_release_package.py
python3 -B test/test_t096_full_memory.py
python3 -B test/test_nrf52_ble_startup.py
python3 -B test/test_nrf52_usb_power.py
python3 -B test/test_shared_mota_queue.py
- name: Verify Companion Bluetooth settings and WebConfig
run: |
python3 -B test/test_display_power.py
python3 -B test/test_companion_inbox.py
python3 -B test/test_heltec_r8_external_power.py
python3 -B test/test_bluetooth_mac_contract.py
python3 -B test/test_companion_settings_persistence_contract.py
python3 -B test/test_webconfig_ui.py
python3 -B test/test_webconfig_ui_runtime.py
- name: Upload Test Results
# Upload test results even if the test step failed.
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: .pio/build/native/