mirror of
https://github.com/alexhopeoconnor/arduino-home-assistant.git
synced 2026-10-04 02:48:13 +10:00
build: standardize ESP32 3.3.11 test baseline
This commit is contained in:
@@ -35,7 +35,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [esp8266, esp32, esp32_3_3_11]
|
||||
platform: [esp8266, esp32]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
@@ -43,6 +43,4 @@ jobs:
|
||||
python-version: '3.11'
|
||||
- run: python -m pip install --upgrade platformio==6.1.19
|
||||
- run: ./scripts/test.sh compile --platform ${{ matrix.platform }}
|
||||
- if: matrix.platform == 'esp32_3_3_11'
|
||||
run: ./scripts/test.sh packages --platform esp32_3_3_11
|
||||
- run: ./scripts/test.sh examples --platform ${{ matrix.platform }}
|
||||
|
||||
@@ -51,9 +51,6 @@ jobs:
|
||||
- run: pio test -e native --filter test_native_core
|
||||
- run: ./scripts/test.sh compile --platform esp32
|
||||
- run: ./scripts/test.sh examples --platform esp32
|
||||
- run: ./scripts/test.sh compile --platform esp32_3_3_11
|
||||
- run: ./scripts/test.sh packages --platform esp32_3_3_11
|
||||
- run: ./scripts/test.sh examples --platform esp32_3_3_11
|
||||
- run: ./scripts/check-docs.sh
|
||||
- run: ./scripts/prepare-release.sh "$GITHUB_REF_NAME"
|
||||
- run: ./scripts/release-notes.sh "$GITHUB_REF_NAME" > "$RUNNER_TEMP/release-notes.md"
|
||||
|
||||
@@ -16,17 +16,17 @@ or application-source error.
|
||||
|
||||
ArduinoHA's root `pio test -e esp8266` environment and every guided ESP8266
|
||||
PlatformIO example now use this same snapshot. There is no root-test exception
|
||||
that can hide a linker regression from the example contract.
|
||||
that can hide a linker regression from the example test harness.
|
||||
|
||||
Keep this exact framework snapshot in ESP8266 environments that need the
|
||||
maintained test contract. It is unrelated to ESP32, whose pioarduino platform
|
||||
maintained test harness. It is unrelated to ESP32, whose pioarduino platform
|
||||
selects its framework and compiler as a unit. Do not replace the SHA with a
|
||||
version range: remove or advance the pin only after an upstream release includes
|
||||
the fix and the affected large firmware has compiled successfully. In
|
||||
particular, changing the ESP32 validation lane does not justify changing this
|
||||
ESP8266 pin.
|
||||
|
||||
The corresponding ESP32 Core 3 pin and shared PlatformIO-cache recovery steps
|
||||
are documented in [DeviceFramework's toolchain guide](https://github.com/alexhopeoconnor/DeviceFramework/blob/main/docs/TOOLCHAINS.md).
|
||||
The corresponding ESP32 Core 3.3.11 pin is documented in
|
||||
[DeviceFramework's toolchain guide](https://github.com/alexhopeoconnor/DeviceFramework/blob/main/docs/TOOLCHAINS.md).
|
||||
|
||||
Back to the [documentation map](README.md).
|
||||
|
||||
+15
-19
@@ -19,36 +19,33 @@ lifecycle handling, and tests are fork-native changes.
|
||||
## Arduino framework validation lanes
|
||||
|
||||
ArduinoHA compiles its embedded test suites and guided PlatformIO examples in
|
||||
three deliberately named lanes:
|
||||
two maintained lanes:
|
||||
|
||||
| Selector | Target | Pinned stack | Role |
|
||||
| --- | --- | --- | --- |
|
||||
| `esp8266` | ESP8266 D1 mini | Arduino-ESP8266 commit `521ae60` | Maintained Postmortem linker-fix contract |
|
||||
| `esp32` | ESP32 Dev Module | pioarduino `51.03.05` / Arduino-ESP32 3.0.5 | Legacy compatibility coverage |
|
||||
| `esp32_3_3_11` | ESP32 Dev Module | pioarduino `55.03.311` / Arduino-ESP32 3.3.11 / ESP-IDF 5.5.5 | Current validation baseline |
|
||||
| `esp8266` | ESP8266 D1 mini | Arduino-ESP8266 commit `521ae60` | Maintained Postmortem linker-fix test-harness lane |
|
||||
| `esp32` | ESP32 Dev Module | pioarduino `55.03.311` / Arduino-ESP32 3.3.11 / ESP-IDF 5.5.5 | Maintained baseline |
|
||||
|
||||
The ESP32 3.0.5 lane remains intentional compatibility coverage until the
|
||||
supported floor is changed in a reviewed release decision. It is not allowed to
|
||||
select a framework or compiler from a global PlatformIO cache by accident;
|
||||
every lane pins its complete pioarduino platform. The ESP8266 framework pin is
|
||||
independent of both ESP32 lanes; see the [linker workaround](ESP8266-LINKER-WORKAROUND.md).
|
||||
Every lane pins its complete framework stack. The ESP32 runner keeps its
|
||||
maintained pioarduino graph in a persistent repository cache so stale global
|
||||
metadata cannot select an uploader or compiler by accident. The ESP8266
|
||||
framework pin is independent of the ESP32 baseline; see the [linker
|
||||
workaround](ESP8266-LINKER-WORKAROUND.md).
|
||||
|
||||
Run the current ESP32 lane locally with:
|
||||
|
||||
```bash
|
||||
./scripts/test.sh compile --platform esp32_3_3_11
|
||||
./scripts/test.sh packages --platform esp32_3_3_11
|
||||
./scripts/test.sh examples --platform esp32_3_3_11
|
||||
./scripts/test.sh compile --platform esp32
|
||||
./scripts/test.sh examples --platform esp32
|
||||
```
|
||||
|
||||
The script keeps that current lane in a dedicated PlatformIO Core/cache
|
||||
The script keeps that lane in a dedicated persistent PlatformIO Core/cache
|
||||
directory by default (`${XDG_CACHE_HOME:-$HOME/.cache}/arduinoha-platformio/core-3.3.11`).
|
||||
This prevents a legacy 3.0.5 `tool-esptoolpy` cache from shadowing the current
|
||||
This prevents stale global `tool-esptoolpy` metadata from shadowing the current
|
||||
pioarduino package-form uploader. Set `ARDUINOHA_PLATFORMIO_CORE_DIR`,
|
||||
`ARDUINOHA_PLATFORMIO_PACKAGES_DIR`, and
|
||||
`ARDUINOHA_PLATFORMIO_CACHE_DIR` for a dedicated disk or a disposable
|
||||
clean-room check; do not repair this condition by overriding a single compiler
|
||||
or deleting an unrelated global toolchain.
|
||||
`ARDUINOHA_PLATFORMIO_CACHE_DIR` for a dedicated disk. The script never clears
|
||||
that cache or repairs it by overriding one compiler package.
|
||||
|
||||
The embedded multi-suite compile path also defaults
|
||||
`PLATFORMIO_RUN_JOBS=1`. A caller may explicitly set another value, but the
|
||||
@@ -76,5 +73,4 @@ git diff --stat main...upstream/develop
|
||||
|
||||
Port only independently reviewed changes with regression tests; treat open
|
||||
upstream pull requests as proposals, not release inputs. Run the native,
|
||||
board-compile (including both ESP32 lanes), and HA test harness gates before
|
||||
publishing a new release.
|
||||
board-compile, and HA test harness gates before publishing a new release.
|
||||
|
||||
@@ -16,13 +16,9 @@ platform_packages =
|
||||
|
||||
[env:esp32]
|
||||
extends = common
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
board = esp32dev
|
||||
build_unflags = -std=gnu++11
|
||||
build_flags =
|
||||
-std=gnu++14
|
||||
-I${platformio.packages_dir}/framework-arduinoespressif32/libraries/Network/src
|
||||
|
||||
[env:esp32_3_3_11]
|
||||
extends = env:esp32
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
|
||||
@@ -16,13 +16,9 @@ platform_packages =
|
||||
|
||||
[env:esp32]
|
||||
extends = common
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
board = esp32dev
|
||||
build_unflags = -std=gnu++11
|
||||
build_flags =
|
||||
-std=gnu++14
|
||||
-I${platformio.packages_dir}/framework-arduinoespressif32/libraries/Network/src
|
||||
|
||||
[env:esp32_3_3_11]
|
||||
extends = env:esp32
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
|
||||
@@ -16,13 +16,9 @@ platform_packages =
|
||||
|
||||
[env:esp32]
|
||||
extends = common
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
board = esp32dev
|
||||
build_unflags = -std=gnu++11
|
||||
build_flags =
|
||||
-std=gnu++14
|
||||
-I${platformio.packages_dir}/framework-arduinoespressif32/libraries/Network/src
|
||||
|
||||
[env:esp32_3_3_11]
|
||||
extends = env:esp32
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
|
||||
@@ -16,13 +16,9 @@ platform_packages =
|
||||
|
||||
[env:esp32]
|
||||
extends = common
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
board = esp32dev
|
||||
build_unflags = -std=gnu++11
|
||||
build_flags =
|
||||
-std=gnu++14
|
||||
-I${platformio.packages_dir}/framework-arduinoespressif32/libraries/Network/src
|
||||
|
||||
[env:esp32_3_3_11]
|
||||
extends = env:esp32
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
|
||||
+1
-3
@@ -7,9 +7,7 @@ pio run -d examples/01-esp-sensor -e esp8266
|
||||
pio run -d examples/01-esp-sensor -e esp8266 -t upload
|
||||
```
|
||||
|
||||
The checked-in `esp32` environment preserves Arduino-ESP32 3.0.5 compatibility
|
||||
coverage. Source-checkout maintenance also builds every guided project with
|
||||
`esp32_3_3_11`, the Arduino-ESP32 3.3.11 validation lane. A consuming
|
||||
The checked-in `esp32` environment uses Arduino-ESP32 3.3.11. A consuming
|
||||
application should choose and pin its complete PlatformIO platform stack.
|
||||
|
||||
| Guided example | What it demonstrates |
|
||||
|
||||
+2
-9
@@ -3,8 +3,7 @@
|
||||
; Full suite:
|
||||
; pio test -e esp8266
|
||||
; pio test -e esp32
|
||||
; ./scripts/test.sh compile --platform esp32_3_3_11
|
||||
; (uses the isolated current Arduino-ESP32 validation lane)
|
||||
; ./scripts/test.sh compile --platform esp32
|
||||
;
|
||||
; Single suite (examples):
|
||||
; pio test -e esp8266 --filter test_utils_serializers
|
||||
@@ -40,17 +39,11 @@ platform_packages =
|
||||
[env:esp32]
|
||||
extends = common
|
||||
test_ignore = test_native_core
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
board = esp32dev
|
||||
build_unflags = -std=gnu++11
|
||||
build_flags = ${common.build_flags} -std=gnu++14
|
||||
|
||||
; Current Arduino-ESP32 validation lane. Keep the legacy env above until the
|
||||
; supported floor changes through an explicit compatibility decision.
|
||||
[env:esp32_3_3_11]
|
||||
extends = env:esp32
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
|
||||
|
||||
; Host-only regression checks for serialization, topic validation, and the
|
||||
; PubSubClient mock path. The Arduino compatibility files live exclusively
|
||||
; under test/native and are never included in firmware environments.
|
||||
|
||||
+6
-9
@@ -2,27 +2,27 @@
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 compile|examples|packages --platform esp8266|esp32|esp32_3_3_11" >&2
|
||||
echo "Usage: $0 compile|examples --platform esp8266|esp32" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
[[ $# -eq 3 && ( "${1:-}" == "compile" || "${1:-}" == "examples" || "${1:-}" == "packages" ) && "${2:-}" == "--platform" ]] || usage
|
||||
[[ $# -eq 3 && ( "${1:-}" == "compile" || "${1:-}" == "examples" ) && "${2:-}" == "--platform" ]] || usage
|
||||
case "${3:-}" in
|
||||
esp8266|esp32|esp32_3_3_11) environment="${3}" ;;
|
||||
esp8266|esp32) environment="${3}" ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
|
||||
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
pio_for_platform() {
|
||||
if [[ "$environment" != "esp32_3_3_11" ]]; then
|
||||
if [[ "$environment" != "esp32" ]]; then
|
||||
pio "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
# Keep Core 3.3.11's package-form esptool and generated pioarduino
|
||||
# environment separate from the legacy Core 3.0.5 validation lane.
|
||||
# A caller can point this at a disposable directory for cache diagnosis.
|
||||
# environment in a persistent repository cache. It is never cleared by
|
||||
# this script, and isolates this tested graph from stale global metadata.
|
||||
local core_dir packages_dir cache_dir
|
||||
core_dir="${ARDUINOHA_PLATFORMIO_CORE_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/arduinoha-platformio/core-3.3.11}"
|
||||
packages_dir="${ARDUINOHA_PLATFORMIO_PACKAGES_DIR:-$core_dir/packages}"
|
||||
@@ -42,9 +42,6 @@ case "$1" in
|
||||
pio_for_platform test -d "$root" -e "$environment" --without-uploading --without-testing
|
||||
echo "ArduinoHA compile check passed for $environment"
|
||||
;;
|
||||
packages)
|
||||
pio_for_platform pkg list -d "$root" -e "$environment"
|
||||
;;
|
||||
examples)
|
||||
mapfile -t examples < <(find "$root/examples" -mindepth 1 -maxdepth 1 -type d -name '[0-9][0-9]-*' -print | sort)
|
||||
if (( ${#examples[@]} == 0 )); then
|
||||
|
||||
@@ -42,34 +42,34 @@ class HomeAssistantClient:
|
||||
token_file = state / "ha-token"
|
||||
cls.wait_until_ready(base_url)
|
||||
if token_file.exists():
|
||||
return cls(base_url, token_file.read_text(encoding="utf-8").strip())
|
||||
|
||||
client_id = "http://ha-mqtt-test-harness.local/"
|
||||
user = {
|
||||
"client_id": client_id,
|
||||
"name": owner_name,
|
||||
"username": username,
|
||||
"password": password,
|
||||
"language": "en",
|
||||
}
|
||||
created = cls._response_json(
|
||||
requests.post(f"{base_url}/api/onboarding/users", json=user, timeout=10),
|
||||
"Home Assistant onboarding user creation",
|
||||
)
|
||||
auth_code = created.get("auth_code")
|
||||
if not auth_code:
|
||||
raise TestHarnessError("Home Assistant onboarding did not return an auth_code")
|
||||
token_response = cls._response_json(
|
||||
requests.post(
|
||||
f"{base_url}/auth/token",
|
||||
data={"client_id": client_id, "grant_type": "authorization_code", "code": auth_code},
|
||||
timeout=10,
|
||||
),
|
||||
"Home Assistant token exchange",
|
||||
)
|
||||
token = token_response.get("access_token")
|
||||
if not token:
|
||||
raise TestHarnessError("Home Assistant token exchange did not return an access_token")
|
||||
token = token_file.read_text(encoding="utf-8").strip()
|
||||
else:
|
||||
client_id = "http://ha-mqtt-test-harness.local/"
|
||||
user = {
|
||||
"client_id": client_id,
|
||||
"name": owner_name,
|
||||
"username": username,
|
||||
"password": password,
|
||||
"language": "en",
|
||||
}
|
||||
created = cls._response_json(
|
||||
requests.post(f"{base_url}/api/onboarding/users", json=user, timeout=10),
|
||||
"Home Assistant onboarding user creation",
|
||||
)
|
||||
auth_code = created.get("auth_code")
|
||||
if not auth_code:
|
||||
raise TestHarnessError("Home Assistant onboarding did not return an auth_code")
|
||||
token_response = cls._response_json(
|
||||
requests.post(
|
||||
f"{base_url}/auth/token",
|
||||
data={"client_id": client_id, "grant_type": "authorization_code", "code": auth_code},
|
||||
timeout=10,
|
||||
),
|
||||
"Home Assistant token exchange",
|
||||
)
|
||||
token = token_response.get("access_token")
|
||||
if not token:
|
||||
raise TestHarnessError("Home Assistant token exchange did not return an access_token")
|
||||
|
||||
client = cls(base_url, token)
|
||||
for path, payload in (
|
||||
@@ -81,6 +81,51 @@ class HomeAssistantClient:
|
||||
raise TestHarnessError(
|
||||
f"Home Assistant onboarding step {path} failed: {response.status_code} {response.text}"
|
||||
)
|
||||
|
||||
# Complete the final server-side step before any browser test starts.
|
||||
# Leaving it to first-login UI redirects makes a shared disposable
|
||||
# instance timing-dependent and can leave it stuck on the onboarding
|
||||
# route. Matching Home Assistant's own origin keeps the IndieAuth
|
||||
# client and redirect URI locally verifiable.
|
||||
integration_response = requests.post(
|
||||
f"{base_url}/api/onboarding/integration",
|
||||
headers=client._headers,
|
||||
json={
|
||||
"client_id": f"{base_url}/",
|
||||
"redirect_uri": f"{base_url}/onboarding.html?auth_callback=1",
|
||||
},
|
||||
timeout=10,
|
||||
)
|
||||
if integration_response.status_code not in (200, 201, 400, 403, 404):
|
||||
raise TestHarnessError(
|
||||
"Home Assistant onboarding integration step failed: "
|
||||
f"{integration_response.status_code} {integration_response.text}"
|
||||
)
|
||||
|
||||
onboarding_response = requests.get(f"{base_url}/api/onboarding", timeout=10)
|
||||
if not onboarding_response.ok:
|
||||
raise TestHarnessError(
|
||||
"Home Assistant onboarding status check failed: "
|
||||
f"{onboarding_response.status_code} {onboarding_response.text}"
|
||||
)
|
||||
try:
|
||||
onboarding_steps = onboarding_response.json()
|
||||
except ValueError as error:
|
||||
raise TestHarnessError("Home Assistant onboarding status returned invalid JSON") from error
|
||||
if not isinstance(onboarding_steps, list):
|
||||
raise TestHarnessError(
|
||||
"Home Assistant onboarding status returned unexpected JSON: "
|
||||
f"{onboarding_steps}"
|
||||
)
|
||||
pending_steps = [
|
||||
str(step.get("step", "unknown"))
|
||||
for step in onboarding_steps
|
||||
if isinstance(step, dict) and step.get("done") is not True
|
||||
]
|
||||
if pending_steps:
|
||||
raise TestHarnessError(
|
||||
"Home Assistant onboarding remains incomplete after bootstrap: " + ", ".join(pending_steps)
|
||||
)
|
||||
state.mkdir(parents=True, exist_ok=True)
|
||||
token_file.write_text(token, encoding="utf-8")
|
||||
return client
|
||||
|
||||
@@ -81,7 +81,7 @@ void onNativeStateChanged(HAMqtt::ConnectionState)
|
||||
}
|
||||
|
||||
|
||||
void test_json_helpers_escape_control_bytes_and_preserve_cursor_contract()
|
||||
void test_json_helpers_escape_control_bytes_and_preserve_cursor_position()
|
||||
{
|
||||
const char value[] = "quote\" slash\\ newline\n tab\t control\x01";
|
||||
char output[96] = {};
|
||||
@@ -341,7 +341,7 @@ void tearDown(void) { }
|
||||
int main(int, char**)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_json_helpers_escape_control_bytes_and_preserve_cursor_contract);
|
||||
RUN_TEST(test_json_helpers_escape_control_bytes_and_preserve_cursor_position);
|
||||
RUN_TEST(test_availability_and_serializer_array_escape_json_values);
|
||||
RUN_TEST(test_discovery_topic_tokens_are_rejected_before_topic_generation);
|
||||
RUN_TEST(test_streaming_serializer_writes_exact_escaped_payload_to_mqtt_mock);
|
||||
|
||||
Reference in New Issue
Block a user