Arm the test watchdog through initial loop service and assert both recovery boundaries. Update cooperative contact negative controls for the current background APIs and run the existing USB, contact persistence, and startup regressions in Actions. Validation: 1762 native tests, 48 added-workflow fixture tests, and 18 related persistence/logging checks passed locally.
406 lines
18 KiB
YAML
406 lines
18 KiB
YAML
name: Run Unit Tests
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- master
|
|
- keymindCascade
|
|
pull_request:
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
management-reports:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-python@v6
|
|
with:
|
|
python-version: '3.13'
|
|
- name: Install real crypto implementations for cross-language tests
|
|
run: |
|
|
python3 -m pip install platformio pycryptodome==3.23.0
|
|
mkdir -p .pio/libdeps/management-test
|
|
pio pkg install --global --library 'rweather/Crypto@0.4.0' --storage-dir .pio/libdeps/management-test
|
|
- name: Verify protocol, encryption, scheduling and MQTT decoding
|
|
run: |
|
|
python3 -B test/test_management_report.py -v
|
|
python3 -B test/test_management_cli_wrapper.py -v
|
|
node test/test_management_decoder.js
|
|
|
|
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 OTA orchestration and automatic relay policy cleanup
|
|
run: python3 -B -m unittest discover -s tools/lora_ota -p 'test_lora_ota*.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 -e native_ota_channel -vv
|
|
|
|
- name: Verify OTA channel persistence and published image tags
|
|
run: |
|
|
python3 -B test/test_ota_channel_persistence.py -v
|
|
python3 -B test/test_observer_ota_channel.py -v
|
|
python3 -B test/test_observer_build_channels.py -v
|
|
python3 -B scripts/verify_ota_channel.py --self-test
|
|
|
|
- name: Verify build output cleanup safety
|
|
run: python3 -B test/test_build_output_safety.py -v
|
|
|
|
- name: Verify serial mOTA response deadlines and RX fairness
|
|
run: python3 -B test/test_mota_serial_deadline.py -v
|
|
|
|
- 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 saved repeat-off trace exception and relay guards
|
|
run: |
|
|
python3 -B test/test_repeater_trace_repeat.py -v
|
|
python3 -B test/test_repeater_trace_forwarding.py -v
|
|
|
|
- name: Verify telemetry schedule input and persistence rollback
|
|
run: python3 -B test/test_telemetry_tx_command.py -v
|
|
|
|
- name: Verify transactional telemetry preferences and legacy route recovery
|
|
run: python3 -B test/test_telemetry_tx_persistence.py -v
|
|
|
|
- name: Verify MQTT start results and connection-attempt accounting
|
|
run: python3 -B test/test_mqtt_transport_results.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_companion_discovery.py -v
|
|
python3 -B test/test_companion_discovery_correlation.py -v
|
|
python3 -B test/test_pico_ble_queues.py -v
|
|
python3 -B test/test_companion_preferences_transaction.py -v
|
|
python3 -B test/test_companion_prefs_values.py -v
|
|
python3 -B test/test_companion_prefs_image.py -v
|
|
python3 -B test/test_companion_prefs_tail.py -v
|
|
python3 -B test/test_companion_radio_settings_transaction.py -v
|
|
python3 -B test/test_companion_prefs_transactions.py -v
|
|
python3 -B test/test_companion_primary_radio_persistence.py -v
|
|
python3 -B test/test_companion_response_bounds.py -v
|
|
python3 -B test/test_companion_ack_delivery.py -v
|
|
python3 -B test/test_companion_delayed_reply_delivery.py -v
|
|
python3 -B test/test_companion_hardware_serial.py -v
|
|
python3 -B test/test_companion_hardware_serial_gps.py -v
|
|
python3 -B test/test_companion_contact_lifetime.py -v
|
|
python3 -B test/test_companion_identity_cli.py -v
|
|
python3 -B test/test_companion_uncached_storage.py -v
|
|
python3 -B test/test_companion_ota_config.py -v
|
|
python3 -B test/test_ota_identity_policy.py -v
|
|
python3 -B test/test_companion_radio_gain_restore.py -v
|
|
python3 -B test/test_common_radio_persistence.py -v
|
|
python3 -B test/test_common_cli_save_results.py -v
|
|
python3 -B test/test_common_prefs_commit.py -v
|
|
python3 -B test/test_mqtt_prefs_commit.py -v
|
|
python3 -B test/test_identity_and_settings_recovery.py -v
|
|
python3 -B test/test_contact_cache.py -v
|
|
|
|
- name: Verify receive recovery and pinned radio status transport
|
|
run: |
|
|
python3 -B test/test_dispatcher_startup_watchdog.py -v
|
|
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_reply_mutation.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
|
|
python3 -B test/test_ota_apply_delivery.py -v
|
|
python3 -B test/test_ota_install_preflight.py -v
|
|
python3 -B test/test_ota_store_resume.py -v
|
|
python3 -B test/test_ota_catalog_lifetime.py -v
|
|
python3 -B test/test_ota_store_flash_nrf52_hybrid.py -v
|
|
python3 -B test/test_ota_dev_staging.py -v
|
|
python3 -B test/test_ota_dev_reboot_guard.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
|
|
python3 -B test/test_hil_esp32_self_serve_ota.py -v
|
|
python3 -B test/test_hil_esp32_usb_host_reboot.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_ota_self_serve_policy.py -v
|
|
python3 -B test/test_ota_self_metadata_cache.py -v
|
|
python3 -B test/test_ota_device_deflate_encoder.py -v
|
|
python3 -B test/test_ota_device_deflate_role.py -v
|
|
python3 -B test/test_client_acl_spiffs.py
|
|
python3 -B test/test_client_acl_cli.py -v
|
|
|
|
- name: Verify ESP32 USB reboot sleep grace and G3 button wake
|
|
run: |
|
|
python3 -B test/test_usb_host_sleep_policy.py
|
|
python3 -B test/test_esp32_usb_sleep.py
|
|
|
|
- name: Verify GPS status distinguishes user settings from receiver sleep
|
|
run: |
|
|
python3 -B test/test_gps_status.py
|
|
python3 -B test/test_gps_upstream_adaptations.py -v
|
|
python3 -B test/test_gps_sync_interval.py -v
|
|
python3 -B test/test_gps_sync_preferences.py -v
|
|
python3 -B test/test_t1000e_sensor_power.py -v
|
|
|
|
- name: Verify Companion ASCII defaults and USB session cleanup
|
|
run: |
|
|
python3 -B test/test_companion_usb_default.py
|
|
python3 -B test/test_companion_usb_input.py
|
|
python3 -B test/test_companion_ota_includes.py
|
|
python3 -B test/test_companion_usb_logging_handoff.py
|
|
python3 -B test/test_companion_usb_mota_exit.py
|
|
python3 -B test/test_common_cli_logging_transaction.py
|
|
python3 -B test/test_usb_diagnostic_logging.py
|
|
python3 -B test/test_nrf52_usb_client.py
|
|
python3 -B test/test_nrf52_usb_lifecycle.py
|
|
python3 -B test/test_nrf52_usb_logging_contract.py
|
|
python3 -B test/test_esp32_usb_serial_hygiene.py
|
|
python3 -B test/test_esp32_tinyusb_nonblocking.py
|
|
python3 -B test/test_esp32_usb_session_fix.py
|
|
python3 -B test/test_hwcdc_tx_backport.py -v
|
|
python3 -B test/test_esp32_file_buffer_fix.py -v
|
|
python3 -B test/test_companion_usb_logging_reply.py
|
|
python3 -B test/test_esp32_tinyusb_cooperative_output.py
|
|
python3 -B test/test_esp32_tinyusb_role_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
|
|
python3 -B test/test_esp32_cooperative_contacts.py -v
|
|
python3 -B test/test_esp32_contact_writer_batch.py -v
|
|
python3 -B test/test_esp32_contact_crc_batch.py -v
|
|
python3 -B test/test_esp32_contact_publication.py -v
|
|
python3 -B test/test_esp32_advert_cache.py -v
|
|
|
|
- name: Verify Companion Bluetooth CLI connection protection
|
|
run: python3 -B test/test_companion_bluetooth_control.py -v
|
|
|
|
- name: Verify Companion Bluetooth reboot persistence
|
|
run: python3 -B test/test_companion_bluetooth_persistence.py -v
|
|
|
|
- name: Verify nRF52 SoftDevice LTO and persistent BLE subscriptions
|
|
env:
|
|
MESHCORE_REQUIRE_ARM_COMPILER: '1'
|
|
MESHCORE_REQUIRE_DFU_EMULATOR: '1'
|
|
run: |
|
|
pio pkg install --global --tool 'platformio/toolchain-gccarmnoneeabi@1.140201.0'
|
|
python3 -B test/test_nrf52_svc_compat.py -v
|
|
python3 -B test/test_nrf52_ble_cccd_fix.py -v
|
|
pip install unicorn==2.1.4
|
|
python3 -B test/test_nrf52_ble_dfu_fix.py -v
|
|
|
|
- name: Verify WiFi, ESP-NOW and combined wireless controls
|
|
run: |
|
|
python3 -B test/test_wireless_control.py -v
|
|
python3 -B test/test_serial_wifi_sessions.py -v
|
|
python3 -B test/test_serial_ethernet_sessions.py -v
|
|
python3 -B test/test_companion_wifi_session.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_reader 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 independent USB packet/debug logging, recovery, and instructions
|
|
run: |
|
|
python3 -B test/test_common_usb_debug.py
|
|
python3 -B test/test_companion_usb_logging.py
|
|
python3 -B test/test_usb_logging_watchdog.py
|
|
python3 -B test/test_usb_watchdog_event.py
|
|
python3 -B test/test_usb_logging_client_activity.py
|
|
python3 -B test/test_usb_logging_watchdog_runtime.py
|
|
python3 -B test/test_usb_logging_watchdog_roles.py
|
|
python3 -B test/test_nrf52_usb_console.py
|
|
python3 -B test/test_esp32_tinyusb_nonblocking.py
|
|
python3 -B test/test_esp32_tinyusb_role_hygiene.py
|
|
python3 -B test/test_logging_sleep_contract.py
|
|
python3 -B test/test_picker_controls_generator.py
|
|
python3 -B test/test_firmware_picker_package.py
|
|
node test/test_firmware_picker.js
|
|
|
|
- name: Verify Full logging compiler flags and packaged capabilities
|
|
run: |
|
|
python3 -B test/test_upstream_observer_recipes.py -v
|
|
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_build_recipe.py -v
|
|
python3 -B test/test_firmware_capabilities.py
|
|
MESHCORE_TEST_REAL_PIO_PATHS=1 python3 -B test/test_esp32_partition_migration_build_dir.py -v
|
|
bash test/test_build_profiles.sh
|
|
bash test/test_full_infrastructure_selection.sh
|
|
bash test/test_nrf52_ota_profiles.sh
|
|
bash test/test_xiao_qspi_combined.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
|
|
python3 -B test/test_remote_cli_command_identity.py -v
|
|
python3 -B test/test_replay_reset_integration.py -v
|
|
|
|
- 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_neighbor_scope_storage.py
|
|
python3 -B test/test_ed25519_compact.py
|
|
python3 -B test/test_cascade_release_package.py
|
|
python3 -B test/test_local_release_full_selection.py
|
|
python3 -B test/test_t096_full_memory.py
|
|
python3 -B test/test_nrf52_ble_startup.py
|
|
python3 -B test/test_nrf52_ble_trace.py
|
|
python3 -B test/test_nrf52_ble_debug_tools.py
|
|
python3 -B test/test_nrf52_usb_power.py
|
|
python3 -B test/test_shared_mota_queue.py
|
|
|
|
- name: Verify nRF52 infrastructure trims and unchanged Companion scope
|
|
run: |
|
|
python3 -B test/test_nrf52_flash_trim.py -v
|
|
python3 -B test/test_nrf52_tft_font_trim.py -v
|
|
python3 -B test/test_ota_target_names.py -v
|
|
|
|
- name: Verify compact same-size fonts and lossless rendering
|
|
run: |
|
|
python3 -B test/test_compact_arial.py -v
|
|
python3 -B test/test_compact_noto.py -v
|
|
python3 -B test/test_nrf52_font_license.py -v
|
|
python3 -B test/test_oled_font_experiments.py -v
|
|
python3 -B test/test_font_family_trials.py -v
|
|
|
|
- name: Verify Companion Bluetooth settings and WebConfig
|
|
run: |
|
|
python3 -B test/test_gps_voice_buttons.py -v
|
|
python3 -B test/test_gps_voice_generator.py -v
|
|
python3 -B test/test_button_voice_actions.py -v
|
|
python3 -B test/test_button_voice_generator.py -v
|
|
python3 -B test/test_button_voice_preview.py -v
|
|
python3 -B test/test_g726_voice.py -v
|
|
MESH_G726_TEST_SANITIZERS=1 python3 -B test/test_g726_voice.py -v
|
|
python3 -B test/test_g726_voice_generator.py -v
|
|
python3 -B test/test_voice_prefixes.py -v
|
|
MESH_VOICE_TEST_SANITIZERS=1 python3 -B test/test_voice_prefixes.py -v
|
|
python3 -B test/test_nimble_companion.py
|
|
python3 -B test/test_bluetooth_pairing_ui.py
|
|
python3 -B test/test_companion_pairing_display.py
|
|
python3 -B test/test_companion_identity_startup.py
|
|
python3 -B test/test_startup_screen.py
|
|
node test/test_notification_builder.js
|
|
python3 -B test/test_notification_settings.py
|
|
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_gzip.py
|
|
python3 -B test/test_webconfig_secret_masking.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/
|