420 lines
18 KiB
Bash
420 lines
18 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
|
source build.sh
|
|
|
|
fail() { echo "test_full_infrastructure_selection: $*" >&2; exit 1; }
|
|
|
|
# Resolve real board inheritance, but never compile or flash firmware.
|
|
init_project_context >/dev/null
|
|
|
|
# No fixture assertion is allowed to fall through into a firmware build. The
|
|
# sole PlatformIO operation above resolves board metadata; all later calls are
|
|
# errors, including dependency preflight before the compiler entry point.
|
|
pio() { fail "selection fixture attempted PlatformIO after metadata resolution"; }
|
|
prepare_esp32_arduino3_framework() { fail "selection fixture reached build preflight"; }
|
|
run_pio_with_size_detection() { fail "selection fixture attempted compilation"; }
|
|
collect_build_artifacts() { fail "selection fixture attempted artifact publication"; }
|
|
|
|
use_qualified_resume_fixture() {
|
|
fixture_output_dir=$(mktemp -d "${TMPDIR:-/tmp}/mesh-full-selection.XXXXXX")
|
|
OUTPUT_DIR=$fixture_output_dir
|
|
trap 'rm -rf -- "$fixture_output_dir"' EXIT
|
|
# These tests mock package qualification to inspect target selection. Supply
|
|
# a real, schema-valid receipt for the new recipe gate too; its actual
|
|
# occupied/matches helpers run normally. Recipe hashing and package sealing
|
|
# are exercised independently by test_firmware_build_recipe.py.
|
|
compute_build_recipe_digest() {
|
|
python3 - "${OUTPUT_DIR}/${firmware_filename}.capabilities.json" "$1" "$3" <<'PY'
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
digest = "a" * 64
|
|
manifest = {"target": sys.argv[2], "platformio_env": sys.argv[3],
|
|
"build_recipe": {"schema_version": 1, "sha256": digest}}
|
|
Path(sys.argv[1]).write_text(json.dumps(manifest) + "\n")
|
|
print(digest)
|
|
PY
|
|
}
|
|
}
|
|
|
|
assert_auto_unified() (
|
|
local plain=$1 expected=$2
|
|
BUILD_PROFILE_OVERRIDE=auto
|
|
BUILD_PROFILE_EXPLICIT=0
|
|
SINGLE_TARGET_FULL_BUILD=0
|
|
RESOLVED_BUILD_TARGETS=("$plain")
|
|
configure_effective_build_profile build-firmware >/dev/null
|
|
[ "${RESOLVED_BUILD_TARGETS[*]}" = "$expected" ] || fail "$plain selected the wrong target"
|
|
[ "$SINGLE_TARGET_FULL_BUILD" = 1 ] || fail "$plain bypassed the unified recipe"
|
|
[ "$AUTO_PREFER_FULL_BUILD" = 0 ] || fail "$plain still schedules a plain Full artifact"
|
|
|
|
local -a built=()
|
|
run_logged_build_targets() {
|
|
[ "$FIRMWARE_FILENAME_INFIX" = full-usb-wifi ] || fail "wrong artifact name"
|
|
[ "$ESP32_FULL_BUILD" = 1 ] || fail "lost expanded partitions"
|
|
[ "$PACKET_LOGGING_OVERRIDE" = on ] || fail "lost USB packet logging"
|
|
[ "$MQTT_BRIDGE_OVERRIDE" = on ] || fail "lost MQTT"
|
|
[ "$MESHDEBUG_OVERRIDE" = off ] || fail "enabled verbose debug"
|
|
built+=("$@")
|
|
}
|
|
run_command build-firmware >/dev/null
|
|
[ "${built[*]}" = "$expected" ] || fail "auto emitted duplicate Full artifacts"
|
|
)
|
|
|
|
assert_auto_unified heltec_v4_r8_repeater heltec_v4_r8_repeater_observer_mqtt
|
|
assert_auto_unified heltec_v4_r8_room_server heltec_v4_r8_room_server_observer_mqtt
|
|
assert_auto_unified heltec_v4_r8_tft_repeater heltec_v4_r8_tft_repeater_observer_mqtt
|
|
assert_auto_unified Heltec_T190_repeater_ Heltec_T190_repeater_observer_mqtt
|
|
assert_auto_unified LilyGo_TLora_V2_1_1_6_room_server LilyGo_TLora_V2_1_1_6_room_server_observer_mqtt_
|
|
assert_auto_unified heltec_v4_r8_repeater_observer_mqtt heltec_v4_r8_repeater_observer_mqtt
|
|
assert_auto_unified Station_G2_repeater Station_G2_repeater_observer_mqtt
|
|
assert_auto_unified Station_G2_room_server Station_G2_room_server_observer_mqtt
|
|
|
|
# A one-board migration package must retain the old repeater's mOTA identity,
|
|
# even when its Full sources come from the matching observer environment.
|
|
(
|
|
BUILD_PROFILE_OVERRIDE=full
|
|
BUILD_PROFILE_EXPLICIT=1
|
|
SINGLE_TARGET_FULL_BUILD=1
|
|
EXACT_IDENTITY_FULL_BUILD=1
|
|
RESOLVED_BUILD_TARGETS=(heltec_v4_repeater)
|
|
configure_effective_build_profile build-firmware >/dev/null
|
|
[ "${RESOLVED_BUILD_TARGETS[*]}" = heltec_v4_repeater ] \
|
|
|| fail "exact Full target changed identity"
|
|
run_logged_build_targets() {
|
|
[ "${*}" = heltec_v4_repeater ] || fail "exact Full built a different target"
|
|
[ "$ESP32_FULL_BUILD" = 1 ] || fail "exact Full lost expanded partitions"
|
|
}
|
|
run_command build-firmware >/dev/null
|
|
)
|
|
|
|
# Operators may still build an alternate Full identity that is omitted from
|
|
# the ordinary bulk release, including capacity-specific plain recipes.
|
|
for alternate in Tbeam_SX1262_repeater \
|
|
Tbeam_SX1262_repeater_bridge_espnow \
|
|
LilyGo_TLora_V2_1_1_6_repeater; do
|
|
(
|
|
BUILD_PROFILE_OVERRIDE=full
|
|
BUILD_PROFILE_EXPLICIT=1
|
|
SINGLE_TARGET_FULL_BUILD=1
|
|
EXACT_IDENTITY_FULL_BUILD=1
|
|
RESOLVED_BUILD_TARGETS=("$alternate")
|
|
configure_effective_build_profile build-firmware >/dev/null
|
|
[ "${RESOLVED_BUILD_TARGETS[*]}" = "$alternate" ] \
|
|
|| fail "alternate Full target changed identity: $alternate"
|
|
run_logged_build_targets() {
|
|
[ "$*" = "$alternate" ] || fail "alternate Full built another target"
|
|
[ "$ESP32_FULL_BUILD" = 1 ] || fail "alternate Full lost expanded partitions"
|
|
}
|
|
run_command build-firmware >/dev/null
|
|
)
|
|
done
|
|
|
|
# Only targets whose standard and FULL board recipes retain the exact same
|
|
# partition table may omit their redundant portable bulk artifact.
|
|
full_only_count=0
|
|
for target in "${!PIO_ENV_PLATFORM_BY_NAME[@]}"; do
|
|
if is_esp32_full_only_bulk_target "$target"; then
|
|
full_only_count=$((full_only_count + 1))
|
|
fi
|
|
done
|
|
[ "$full_only_count" -eq 149 ] || fail "expected 149 same-partition FULL-only targets, found $full_only_count"
|
|
|
|
for target in heltec_rc32_repeater Station_G2_repeater_observer_mqtt \
|
|
Heltec_v3_repeater heltec_v4_r8_repeater \
|
|
heltec_v4_tft_repeater RAK_3112_repeater \
|
|
Station_G3_ESP32_sensor Station_G3_ESP32_r2_sensor; do
|
|
is_esp32_full_only_bulk_target "$target" || fail "missed same-partition FULL-only target $target"
|
|
done
|
|
for target in LilyGo_TLora_V2_1_1_6_repeater_observer_mqtt_ \
|
|
LilyGo_TLora_V2_1_1_6_companion_radio_wifi \
|
|
LilyGo_TLora_V2_1_1_6_repeater_bridge_espnow WHY2025_badge_repeater_; do
|
|
if is_esp32_full_only_bulk_target "$target"; then
|
|
fail "consolidated target with a partition migration: $target"
|
|
fi
|
|
done
|
|
|
|
# Partition-changing normal roles publish a canonical Full image alongside
|
|
# their portable compatibility image. They must never be mistaken for the
|
|
# same-partition policy, which is the only policy allowed to install through
|
|
# the automatic mOTA target alias.
|
|
for target in LilyGo_T3S3_sx1262_repeater \
|
|
LilyGo_T3S3_sx1262_room_server \
|
|
LilyGo_T3S3_sx1276_repeater \
|
|
LilyGo_T3S3_sx1276_room_server \
|
|
Station_G2_repeater Station_G2_room_server \
|
|
ThinkNode_M2_Repeater ThinkNode_M2_room_server; do
|
|
is_esp32_partition_migration_full_target "$target" \
|
|
|| fail "missed partition-migration Full target $target"
|
|
if is_esp32_full_only_bulk_target "$target"; then
|
|
fail "partition-migration target was incorrectly made FULL-only: $target"
|
|
fi
|
|
done
|
|
|
|
[ "$(get_exact_identity_full_pio_env heltec_v4_r8_repeater)" \
|
|
= heltec_v4_r8_repeater_observer_mqtt ] \
|
|
|| fail "V4 R8 Full lost its observer feature base"
|
|
[ "$(get_exact_identity_full_pio_env heltec_v4_r8_sensor)" \
|
|
= heltec_v4_r8_sensor ] \
|
|
|| fail "V4 R8 sensor should retain its own feature base"
|
|
[ "$(get_exact_identity_full_pio_env Station_G2_repeater)" \
|
|
= Station_G2_repeater_observer_mqtt ] \
|
|
|| fail "Station G2 migration Full lost its observer feature base"
|
|
[ "$(get_exact_identity_full_pio_env LilyGo_T3S3_sx1262_room_server)" \
|
|
= LilyGo_T3S3_sx1262_room_server_observer_mqtt ] \
|
|
|| fail "T3S3 migration Full lost its observer feature base"
|
|
[ "$(get_exact_identity_full_migration_target heltec_v4_r8_repeater_observer_mqtt)" \
|
|
= heltec_v4_r8_repeater ] \
|
|
|| fail "legacy V4 R8 observer lacks its canonical migration target"
|
|
if get_exact_identity_full_migration_target heltec_v4_r8_repeater >/dev/null; then
|
|
fail "ordinary V4 R8 target unexpectedly has a migration alias"
|
|
fi
|
|
if get_exact_identity_full_migration_target heltec_v4_r8_repeater_observer_mqtt_sim >/dev/null; then
|
|
fail "simulated observer target unexpectedly received a migration alias"
|
|
fi
|
|
if get_exact_identity_full_migration_target Station_G2_repeater_observer_mqtt >/dev/null; then
|
|
fail "partition-changing Station G2 observer unexpectedly received an mOTA alias"
|
|
fi
|
|
|
|
# Portable images and exact reduced OTA identities must not be consolidated.
|
|
for target in heltec_v4_r8_repeater heltec_v4_r8_room_server \
|
|
heltec_v4_r8_repeater_lora_ota_no_external_sensors; do
|
|
(
|
|
BUILD_PROFILE_OVERRIDE=standard
|
|
BUILD_PROFILE_EXPLICIT=1
|
|
SINGLE_TARGET_FULL_BUILD=0
|
|
RESOLVED_BUILD_TARGETS=("$target")
|
|
configure_effective_build_profile build-firmware >/dev/null
|
|
[ "${RESOLVED_BUILD_TARGETS[*]}" = "$target" ] || fail "lost portable target $target"
|
|
[ "$BUILD_PROFILE_EFFECTIVE" = standard ] || fail "expanded portable image $target"
|
|
[ "$SINGLE_TARGET_FULL_BUILD" = 0 ] || fail "portable image entered Full pipeline"
|
|
)
|
|
done
|
|
|
|
for target in Tbeam_SX1262_repeater Tbeam_SX1276_repeater \
|
|
Tbeam_SX1262_room_server Tbeam_SX1276_room_server \
|
|
LilyGo_TLora_V2_1_1_6_repeater \
|
|
heltec_v4_r8_repeater_lora_ota_no_external_sensors \
|
|
RAK_4631_repeater_bridge_rs232_serial1_lora_ota_no_external_sensors; do
|
|
if get_unified_full_infrastructure_target "$target" >/dev/null; then
|
|
fail "consolidated a distinct capacity/OTA contract: $target"
|
|
fi
|
|
done
|
|
|
|
(
|
|
PIO_ENV_BOARD_BY_NAME[heltec_v4_r8_repeater_observer_mqtt]=different_board
|
|
if get_unified_full_infrastructure_target heltec_v4_r8_repeater >/dev/null; then
|
|
fail "accepted a different physical board"
|
|
fi
|
|
)
|
|
|
|
# Direct observer promotion must use the matrix's exact output recipe even if
|
|
# interactive flags previously requested MQTT without USB logging. Stop at the
|
|
# matching-recipe/qualified-artifact check without entering compilation.
|
|
(
|
|
use_qualified_resume_fixture
|
|
ESP32_FULL_BUILD=0
|
|
BUILD_PROFILE_EFFECTIVE=standard
|
|
BUILD_PROFILE_OVERRIDE=auto
|
|
BUILD_PROFILE_EXPLICIT=0
|
|
FIRMWARE_VERSION=vtest
|
|
RESUME_BUILD_OUTPUT=1
|
|
FIRMWARE_FILENAME_INFIX=""
|
|
MESHDEBUG_OVERRIDE=on
|
|
PACKET_LOGGING_OVERRIDE=off
|
|
MQTT_BRIDGE_OVERRIDE=off
|
|
MQTT_DEBUG_OVERRIDE=on
|
|
observed_filename=""
|
|
observed_output=""
|
|
build_artifacts_exist() {
|
|
observed_filename=$3
|
|
observed_output="$PACKET_LOGGING_OVERRIDE/$MQTT_BRIDGE_OVERRIDE/$MESHDEBUG_OVERRIDE/$MQTT_DEBUG_OVERRIDE"
|
|
return 0
|
|
}
|
|
build_firmware heltec_v4_r8_repeater_observer_mqtt >/dev/null
|
|
[[ "$observed_filename" == heltec_v4_r8_repeater_observer_mqtt-full-usb-wifi-ota-vtest-* ]] \
|
|
|| fail "direct observer kept a duplicate name"
|
|
[ "$observed_output" = on/on/off/off ] || fail "direct observer differs from unified recipe"
|
|
[ "$PACKET_LOGGING_OVERRIDE/$MQTT_BRIDGE_OVERRIDE/$MESHDEBUG_OVERRIDE/$MQTT_DEBUG_OVERRIDE" = off/off/on/on ] \
|
|
|| fail "observer output settings leaked into subsequent builds"
|
|
)
|
|
|
|
# A canonical bulk build promotes an audited target in-place, retaining its
|
|
# environment/mOTA identity. Explicit standard builds remain untouched above.
|
|
(
|
|
use_qualified_resume_fixture
|
|
ESP32_FULL_BUILD=0
|
|
BUILD_PROFILE_EFFECTIVE=standard
|
|
BUILD_PROFILE_OVERRIDE=auto
|
|
BUILD_PROFILE_EXPLICIT=0
|
|
BATCH_BUILD_MODE=1
|
|
FIRMWARE_VERSION=vtest
|
|
RESUME_BUILD_OUTPUT=1
|
|
FIRMWARE_FILENAME_INFIX=""
|
|
observed_filename=""
|
|
observed_full=0
|
|
build_artifacts_exist() {
|
|
observed_filename=$3
|
|
observed_full=$ESP32_FULL_BUILD
|
|
return 0
|
|
}
|
|
build_firmware heltec_rc32_repeater >/dev/null
|
|
[ "$observed_full" = 1 ] || fail "audited bulk target did not promote to FULL"
|
|
[[ "$observed_filename" == heltec_rc32_repeater-full-usb-wifi-ota-vtest-* ]] \
|
|
|| fail "FULL-only bulk target lost its exact identity"
|
|
)
|
|
(
|
|
use_qualified_resume_fixture
|
|
ESP32_FULL_BUILD=0
|
|
BUILD_PROFILE_EFFECTIVE=standard
|
|
BUILD_PROFILE_OVERRIDE=auto
|
|
BUILD_PROFILE_EXPLICIT=0
|
|
BATCH_BUILD_MODE=1
|
|
FIRMWARE_VERSION=vtest
|
|
RESUME_BUILD_OUTPUT=1
|
|
FIRMWARE_FILENAME_INFIX=""
|
|
observed_filename=""
|
|
build_artifacts_exist() {
|
|
observed_filename=$3
|
|
return 0
|
|
}
|
|
build_firmware heltec_v4_r8_repeater >/dev/null
|
|
[[ "$observed_filename" == heltec_v4_r8_repeater-full-usb-wifi-ota-vtest-* ]] \
|
|
|| fail "V4 Full did not keep its identity and unified feature recipe"
|
|
)
|
|
(
|
|
use_qualified_resume_fixture
|
|
ESP32_FULL_BUILD=0
|
|
BUILD_PROFILE_EFFECTIVE=standard
|
|
BUILD_PROFILE_OVERRIDE=standard
|
|
BUILD_PROFILE_EXPLICIT=1
|
|
BATCH_BUILD_MODE=1
|
|
FIRMWARE_VERSION=vtest
|
|
RESUME_BUILD_OUTPUT=1
|
|
observed_full=1
|
|
build_artifacts_exist() {
|
|
observed_full=$ESP32_FULL_BUILD
|
|
return 0
|
|
}
|
|
build_firmware heltec_rc32_repeater >/dev/null
|
|
[ "$observed_full" = 0 ] || fail "explicit standard recovery build was promoted"
|
|
)
|
|
|
|
(
|
|
standard_built=""
|
|
full_built=""
|
|
REQUIRE_OTA_UPDATES=0
|
|
run_logged_build_targets() {
|
|
if [ "$ESP32_FULL_BUILD" = 0 ]; then standard_built="$*"; else full_built="$*"; fi
|
|
}
|
|
run_logging_matrix_build_targets heltec_v4_r8_repeater \
|
|
heltec_v4_r8_repeater_lora_ota_no_external_sensors \
|
|
heltec_v4_r8_repeater_observer_mqtt >/dev/null
|
|
[ "$standard_built" = heltec_v4_r8_repeater_lora_ota_no_external_sensors ] \
|
|
|| fail "matrix changed the distinct reduced OTA build"
|
|
[ "$full_built" = heltec_v4_r8_repeater ] \
|
|
|| fail "matrix emitted duplicate V4 Full identities"
|
|
[ "$ESP32_LORA_OTA_APP_LIMIT" = 1310720 ] || fail "changed the 1.25 MiB portable limit"
|
|
)
|
|
|
|
(
|
|
calls=()
|
|
REQUIRE_OTA_UPDATES=0
|
|
run_logged_build_targets() {
|
|
calls+=("$BUILD_PROFILE_EFFECTIVE:$ESP32_FULL_BUILD:$FIRMWARE_FILENAME_INFIX:$*")
|
|
}
|
|
run_logging_matrix_build_targets heltec_rc32_repeater \
|
|
heltec_rc32_repeater_bridge_espnow >/dev/null
|
|
[ "${#calls[@]}" -eq 1 ] || fail "FULL-only targets emitted duplicate matrix artifacts"
|
|
[ "${calls[0]}" = 'full:1:full-logging:heltec_rc32_repeater' ] \
|
|
|| fail "matrix emitted duplicate RC32 Full identities"
|
|
)
|
|
|
|
# Canonical board/role identities share one exact Full pass. A group without
|
|
# an audited plain Full keeps its feature-complete observer identity; legacy
|
|
# observer/ESP-NOW aliases must not create duplicate builds or lose a role.
|
|
(
|
|
calls=()
|
|
run_logged_build_targets() {
|
|
[ "$PACKET_LOGGING_OVERRIDE" = on ] || fail "multi-role Full lost packet logging"
|
|
[ "$MQTT_BRIDGE_OVERRIDE" = off ] || fail "multi-role Full changed its exact-identity recipe"
|
|
[ "$MESHDEBUG_OVERRIDE" = off ] || fail "multi-role Full enabled verbose debug"
|
|
calls+=("$BUILD_PROFILE_EFFECTIVE:$ESP32_FULL_BUILD:$FIRMWARE_FILENAME_INFIX:$*")
|
|
}
|
|
run_logging_matrix_build_targets Heltec_v3_repeater \
|
|
Heltec_v3_repeater_observer_mqtt Heltec_v3_repeater_bridge_espnow \
|
|
Tbeam_SX1262_repeater_bridge_espnow Tbeam_SX1262_repeater_observer_mqtt \
|
|
Heltec_v3_room_server >/dev/null
|
|
[ "${#calls[@]}" -eq 1 ] || fail "multi-role matrix did not emit one exact Full pass"
|
|
[ "${calls[0]}" = 'full:1:full-logging:Heltec_v3_repeater Tbeam_SX1262_repeater_observer_mqtt Heltec_v3_room_server' ] \
|
|
|| fail "multi-role Full changed canonical identities, roles, order, or profile"
|
|
)
|
|
|
|
(
|
|
mapfile -t matrix_targets < <(resolve_logging_matrix_firmwares)
|
|
mapfile -t full_targets < <(select_ordinary_full_targets "${matrix_targets[@]}")
|
|
declare -A seen=()
|
|
for target in "${full_targets[@]}"; do
|
|
key=$(get_ordinary_full_group_key "$target") || fail "invalid Full target $target"
|
|
[ -z "${seen[$key]+x}" ] || fail "duplicate ordinary Full group $key"
|
|
seen[$key]=1
|
|
done
|
|
[ "${#full_targets[@]}" -gt 100 ] || fail "Full selection unexpectedly dropped board roles"
|
|
)
|
|
|
|
(
|
|
calls=()
|
|
run_logged_build_targets() {
|
|
[ "$PACKET_LOGGING_OVERRIDE" = on ] || fail "Full-only bulk lost packet logging"
|
|
[ "$MQTT_BRIDGE_OVERRIDE" = off ] || fail "Full-only bulk changed its exact-identity recipe"
|
|
[ "$MESHDEBUG_OVERRIDE" = off ] || fail "Full-only bulk enabled verbose debug"
|
|
calls+=("$BUILD_PROFILE_EFFECTIVE:$ESP32_FULL_BUILD:$FIRMWARE_FILENAME_INFIX:$*")
|
|
}
|
|
run_full_esp32_build_targets all heltec_v4_r8_repeater \
|
|
heltec_v4_r8_repeater_observer_mqtt \
|
|
Tbeam_SX1262_repeater_bridge_espnow \
|
|
Tbeam_SX1262_repeater_observer_mqtt >/dev/null
|
|
[ "${#calls[@]}" -eq 1 ] || fail "Full-only bulk did not emit one exact Full pass"
|
|
[ "${calls[0]}" = 'full:1:full-logging:heltec_v4_r8_repeater Tbeam_SX1262_repeater_observer_mqtt' ] \
|
|
|| fail "Full-only bulk changed canonical identities, order, or profile"
|
|
)
|
|
|
|
(
|
|
calls=()
|
|
run_logged_build_targets() {
|
|
calls+=("$BUILD_PROFILE_EFFECTIVE:$ESP32_FULL_BUILD:$FIRMWARE_FILENAME_INFIX:$*")
|
|
}
|
|
run_logging_matrix_build_targets Station_G2_repeater \
|
|
Station_G2_repeater_observer_mqtt >/dev/null
|
|
full_calls=()
|
|
for call in "${calls[@]}"; do
|
|
[[ "$call" == full:1:* ]] && full_calls+=("$call")
|
|
done
|
|
[ "${#full_calls[@]}" -eq 1 ] || fail "G2 repeater matrix emitted two Full images"
|
|
[[ "${full_calls[0]}" == *:Station_G2_repeater_observer_mqtt ]] \
|
|
|| fail "G2 repeater matrix lost the observer OTA identity"
|
|
)
|
|
|
|
(
|
|
calls=()
|
|
run_logged_build_targets() {
|
|
calls+=("$BUILD_PROFILE_EFFECTIVE:$ESP32_FULL_BUILD:$FIRMWARE_FILENAME_INFIX:$*")
|
|
}
|
|
run_partition_migration_full_esp32_profile \
|
|
Station_G2_repeater Station_G2_room_server ThinkNode_M2_Repeater >/dev/null
|
|
[ "${#calls[@]}" -eq 1 ] || fail "partition-migration pass emitted the wrong number of builds"
|
|
[ "${calls[0]}" = 'full:1:full-logging:ThinkNode_M2_Repeater' ] \
|
|
|| fail "partition-migration pass emitted duplicate G2 Full identities"
|
|
)
|
|
|
|
# The default build settings retain power saving; this does not overwrite
|
|
# preferences already stored on a device.
|
|
[ "$FIRMWARE_PROFILE_OVERRIDE" = cascade ] || fail "default profile changed"
|
|
PLATFORMIO_BUILD_FLAGS=""
|
|
apply_firmware_profile_overrides
|
|
[[ "$PLATFORMIO_BUILD_FLAGS" == *-DDEFAULT_POWERSAVING_ENABLED=1* ]] || fail "device power saving disabled"
|
|
[[ "$PLATFORMIO_BUILD_FLAGS" == *-DDEFAULT_RXPS_ENABLED=1* ]] || fail "RX power saving disabled"
|
|
|
|
echo "test_full_infrastructure_selection: OK"
|