mirror of
https://github.com/alexhopeoconnor/WiFiManager.git
synced 2026-10-04 02:48:13 +10:00
test: add portal OTA A/B contract coverage
This commit is contained in:
@@ -30,3 +30,9 @@ build_flags =
|
||||
-DWM_LOG_LEVEL=3
|
||||
lib_deps =
|
||||
${common.lib_deps}
|
||||
|
||||
; Clean-consumer validation against the maintained ESP32 platform lane. This
|
||||
; is intentionally separate from the temporary 3.0.5 compatibility target.
|
||||
[env:esp32_core_3_3_11]
|
||||
extends = env:esp32
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
|
||||
@@ -14,3 +14,25 @@ Use it through the repository runner so a secondary Wi-Fi adapter is explicitly
|
||||
The ESP8266 portal SSID is `WM Contract ESP8266`; the ESP32 SSID is `WM Contract ESP32`. Both use `default1` exclusively for local development tests.
|
||||
|
||||
The runner cleans up only the temporary connection it creates on the named secondary interface. It refuses to run if that interface is the system default route.
|
||||
|
||||
## A/B portal OTA fixture
|
||||
|
||||
The same fixture has dedicated `*_ota_a` and `*_ota_b` PlatformIO environments
|
||||
for the physical portal HTTP OTA contract. A and B differ only by a compiled
|
||||
marker served from the fixture-only `/api/test/firmware-marker` endpoint. That
|
||||
proves a B boot without trusting saved portal values, EEPROM, or a filename.
|
||||
|
||||
```bash
|
||||
./tools/portal-hardware ota \
|
||||
--platform esp32 \
|
||||
--port /dev/serial/by-id/... \
|
||||
--client-interface wlx...
|
||||
```
|
||||
|
||||
ESP8266 explicitly uses `eagle.flash.4m1m.ld`. ESP32 uses the tracked two-slot
|
||||
`partitions/esp32_ota_4m_no_fs.csv` layout on the maintained Arduino-ESP32
|
||||
3.3.11 fixture lane. Both are 4 MB layouts. The runner builds and preserves A
|
||||
and B before it touches the board, validates the matching ESP32 slots (or the
|
||||
live ESP8266 updater capacity), then erases the explicitly selected test board
|
||||
before serial-flashing A. A successful run leaves B installed in the
|
||||
portal-only fixture.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# 4 MB ESP32 portal-harness OTA test layout.
|
||||
#
|
||||
# The fixture compiles portal assets into the application image, so it uses no
|
||||
# filesystem. app0 and app1 are equal 0x1F0000-byte slots. The portal OTA
|
||||
# runner validates B against that inactive-slot size before it flashes A or
|
||||
# submits the browser upload.
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x1F0000,
|
||||
app1, app, ota_1, 0x200000, 0x1F0000,
|
||||
coredump, data, coredump,0x3F0000, 0x10000,
|
||||
|
@@ -26,3 +26,42 @@ build_flags =
|
||||
-DSOC_WIFI_SUPPORTED=1
|
||||
-I${platformio.packages_dir}/framework-arduinoespressif32/libraries/Network/src
|
||||
-DWM_LOG_LEVEL=4
|
||||
|
||||
; The maintained ESP32 validation lane. Keep this named rather than relying on
|
||||
; whatever framework/toolchain pair happens to be installed in PlatformIO's
|
||||
; global package cache.
|
||||
[env:esp32_core_3_3_11]
|
||||
extends = env:esp32
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
|
||||
; OTA contract images deliberately differ only by their compile-time marker.
|
||||
; ESP8266 needs an OTA-capable linker layout; ESP32 needs a tracked two-slot
|
||||
; partition table. The hardware runner always flashes A over serial then
|
||||
; uploads B through the real portal form.
|
||||
[env:esp8266_ota_a]
|
||||
extends = env:esp8266
|
||||
board_build.ldscript = eagle.flash.4m1m.ld
|
||||
build_flags =
|
||||
${env:esp8266.build_flags}
|
||||
-DWM_OTA_TEST_IMAGE=\"A\"
|
||||
|
||||
[env:esp8266_ota_b]
|
||||
extends = env:esp8266
|
||||
board_build.ldscript = eagle.flash.4m1m.ld
|
||||
build_flags =
|
||||
${env:esp8266.build_flags}
|
||||
-DWM_OTA_TEST_IMAGE=\"B\"
|
||||
|
||||
[env:esp32_ota_a]
|
||||
extends = env:esp32_core_3_3_11
|
||||
board_build.partitions = partitions/esp32_ota_4m_no_fs.csv
|
||||
build_flags =
|
||||
${env:esp32_core_3_3_11.build_flags}
|
||||
-DWM_OTA_TEST_IMAGE=\"A\"
|
||||
|
||||
[env:esp32_ota_b]
|
||||
extends = env:esp32_core_3_3_11
|
||||
board_build.partitions = partitions/esp32_ota_4m_no_fs.csv
|
||||
build_flags =
|
||||
${env:esp32_core_3_3_11.build_flags}
|
||||
-DWM_OTA_TEST_IMAGE=\"B\"
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
|
||||
namespace {
|
||||
|
||||
// These markers belong only to the portal hardware fixture. They are compiled
|
||||
// into the image rather than stored in Wi-FiManager settings, so an A -> B
|
||||
// assertion proves that the new firmware booted after the updater restarted
|
||||
// the board. Normal portal-contract builds retain a descriptive fixture value.
|
||||
#ifndef WM_OTA_TEST_IMAGE
|
||||
#define WM_OTA_TEST_IMAGE "portal-contract"
|
||||
#endif
|
||||
|
||||
#if defined(ESP8266)
|
||||
constexpr char kPortalSsid[] = "WM Contract ESP8266";
|
||||
#else
|
||||
@@ -57,6 +65,28 @@ WiFiManagerParameter* const kPortalParameters[] = {
|
||||
&kNotes,
|
||||
};
|
||||
|
||||
void registerOtaTestMarker() {
|
||||
// setWebServerCallback runs after WiFiManager creates its server and
|
||||
// before it registers built-in routes. This private fixture endpoint is
|
||||
// intentionally not a WiFiManager product API.
|
||||
wifi.setWebServerCallback([]() {
|
||||
AsyncWebServer* const server = wifi.getServer();
|
||||
if (server == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
server->on("/api/test/firmware-marker", HTTP_GET,
|
||||
[](AsyncWebServerRequest* request) {
|
||||
String response = F("{\"marker\":\"");
|
||||
response += WM_OTA_TEST_IMAGE;
|
||||
response += F("\",\"freeSketchSpace\":");
|
||||
response += String(ESP.getFreeSketchSpace());
|
||||
response += F("}");
|
||||
request->send(200, "application/json", response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void setup() {
|
||||
@@ -75,6 +105,7 @@ void setup() {
|
||||
IPAddress(192, 168, 4, 1),
|
||||
IPAddress(192, 168, 4, 1),
|
||||
IPAddress(255, 255, 255, 0));
|
||||
registerOtaTestMarker();
|
||||
// Keep custom parameters on their own native Save parameters page. This
|
||||
// lets the browser contract exercise a parameter-only submit without
|
||||
// starting a station connection as part of the regression test.
|
||||
|
||||
Reference in New Issue
Block a user