#!/usr/bin/env bash set -euo pipefail # Keep standalone compilation predictable on laptops and shared workstations. # A developer may explicitly raise this for an isolated local diagnosis. export PLATFORMIO_RUN_JOBS="${PLATFORMIO_RUN_JOBS:-2}" usage() { cat <<'USAGE' >&2 Usage: ./scripts/test.sh compile --platform esp8266|esp32 ./scripts/test.sh unity --platform esp8266|esp32 ./scripts/test.sh examples --platform esp8266|esp32 ./scripts/test.sh ota-fixtures --platform esp8266|esp32 ./scripts/test.sh hardware --platform esp8266|esp32 --port /dev/serial/by-id/... USAGE exit 2 } mode="${1:-}" [[ "$mode" == "compile" || "$mode" == "unity" || "$mode" == "examples" || "$mode" == "ota-fixtures" || "$mode" == "hardware" ]] || usage shift platform="" port="" while [[ $# -gt 0 ]]; do case "$1" in --platform) [[ $# -ge 2 ]] || usage; platform="${2:-}"; shift 2 ;; --port) [[ $# -ge 2 ]] || usage; port="${2:-}"; shift 2 ;; *) usage ;; esac done case "$platform" in esp8266|esp32) environment="$platform" ;; *) usage ;; esac [[ "$mode" != "hardware" || -n "$port" ]] || usage [[ "$mode" != "hardware" || -e "$port" ]] || { echo "Serial port not found: $port" >&2; exit 1; } root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" # shellcheck source=tools/lib/platformio.sh source "$root/tools/lib/platformio.sh" # shellcheck source=tools/lib/ota-fixture-identity.sh source "$root/tools/lib/ota-fixture-identity.sh" pio_for_platform() { if [[ "$platform" != "esp32" ]]; then wm_pio "$@" return fi # Keep the maintained Core 3.3.11 package form in a persistent project # cache shared by the maintained framework repositories. It is never # cleared by this script and avoids stale global package metadata selecting # an incompatible uploader without redownloading this same pinned graph. local core_dir packages_dir cache_dir core_dir="${WIFIMANAGER_PLATFORMIO_CORE_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/arduino-framework-platformio/core-3.3.11}" packages_dir="${WIFIMANAGER_PLATFORMIO_PACKAGES_DIR:-$core_dir/packages}" cache_dir="${WIFIMANAGER_PLATFORMIO_CACHE_DIR:-$core_dir/cache}" install -d -m 700 "$core_dir" "$packages_dir" "$cache_dir" PLATFORMIO_CORE_DIR="$core_dir" PLATFORMIO_PACKAGES_DIR="$packages_dir" \ PLATFORMIO_CACHE_DIR="$cache_dir" wm_pio "$@" } assert_ota_fixture_pair() { local firmware_a="$1" firmware_b="$2" firmware size capacity [[ -s "$firmware_a" && -s "$firmware_b" ]] || { echo "Portal OTA fixture build did not produce both A and B images." >&2 return 1 } if cmp -s "$firmware_a" "$firmware_b"; then echo "Portal OTA fixture A and B are identical." >&2 return 1 fi if [[ "$platform" == "esp32" ]]; then capacity=$((0x1F0000)) for firmware in "$firmware_a" "$firmware_b"; do size="$(wc -c < "$firmware" | tr -d '[:space:]')" (( size <= capacity )) || { echo "ESP32 OTA fixture $(basename "$firmware") is $size bytes; it exceeds the $capacity-byte app slot." >&2 return 1 } done fi } if [[ "$mode" == "hardware" ]]; then # Unity uses only the named serial device; it does not own a portal AP or # secondary adapter, so it may run beside an unrelated station test. # shellcheck source=tools/lib/harness-locks.sh source "$root/tools/lib/harness-locks.sh" wm_harness_lock_serial_port "$port" fi if [[ "$mode" == "examples" ]]; then mapfile -t examples < <(find "$root/examples" -mindepth 2 -maxdepth 2 -type f -name platformio.ini -printf '%h\n' | sort) if (( ${#examples[@]} == 0 )); then echo "No example projects found" >&2 exit 1 fi for example in "${examples[@]}"; do pio_for_platform run -d "$example" -e "$environment"