mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2026-03-29 00:58:30 +03:00
chore: checkpoint before lint autofix
This commit is contained in:
44
documentation/CONTRACT_TEST_TEMPLATE.md
Normal file
44
documentation/CONTRACT_TEST_TEMPLATE.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Contract Test Template
|
||||
|
||||
Use this template when adding/refactoring tests to ensure they are refactor-resilient.
|
||||
|
||||
## Metadata
|
||||
|
||||
- Test ID:
|
||||
- Module/Boundary:
|
||||
- Priority (`P0`/`P1`/`P2`):
|
||||
- Platform scope (`host`, `all`, `i2s`, `muse`, `squeezeamp`, etc.):
|
||||
|
||||
## Contract
|
||||
|
||||
Describe what externally visible behavior must remain true.
|
||||
|
||||
## Invariant(s)
|
||||
|
||||
List invariant properties this test protects.
|
||||
|
||||
## Inputs/Preconditions
|
||||
|
||||
- Required setup:
|
||||
- Input variants:
|
||||
- Fault conditions (if any):
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
- Success conditions:
|
||||
- Error conditions:
|
||||
- Bounds/time/resource expectations:
|
||||
|
||||
## Non-goals
|
||||
|
||||
State what this test intentionally does not verify (to avoid implementation coupling).
|
||||
|
||||
## Refactor Resilience Check
|
||||
|
||||
- Would this still pass if internals were reorganized but behavior unchanged? (`yes`/`no`)
|
||||
- If `no`, explain why coupling is unavoidable.
|
||||
|
||||
## Regression Linkage
|
||||
|
||||
- Related issue/bug (if regression test):
|
||||
- Why this boundary was chosen:
|
||||
130
documentation/HARDWARE_TEST_MATRIX.md
Normal file
130
documentation/HARDWARE_TEST_MATRIX.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Hardware Test Matrix
|
||||
|
||||
Date: 2026-02-12
|
||||
Scope: Platform-specific stability and release validation for `squeezelite-esp32`.
|
||||
|
||||
## Purpose
|
||||
|
||||
Define a practical hardware-focused test strategy that complements host/unit tests and acknowledges embedded uncertainty under real-world load.
|
||||
|
||||
This matrix is designed to:
|
||||
- maximize platform stability
|
||||
- prioritize high-impact failures first
|
||||
- provide clear release gates per hardware profile
|
||||
|
||||
Use together with:
|
||||
- `documentation/TESTING_CHARTER.md`
|
||||
- `documentation/CONTRACT_TEST_TEMPLATE.md`
|
||||
|
||||
## Platforms
|
||||
|
||||
Mapped to build profiles used in this repo:
|
||||
- `i2s` -> `build-scripts/I2S-4MFlash-sdkconfig.defaults`
|
||||
- `muse` -> `build-scripts/Muse-sdkconfig.defaults`
|
||||
- `squeezeamp` -> `build-scripts/SqueezeAmp-sdkconfig.defaults`
|
||||
|
||||
## Priority Levels
|
||||
|
||||
- `P0`: release blocking, must pass
|
||||
- `P1`: strong confidence tests, expected to pass before release
|
||||
- `P2`: extended coverage/soak, required for nightly and milestone validation
|
||||
|
||||
## Execution Tiers
|
||||
|
||||
- PR smoke: fast subset (`P0` only, selected `P1`)
|
||||
- Nightly: full `P0 + P1` and selected `P2`
|
||||
- Pre-release: full matrix, all `P0/P1`, mandatory `P2` soak and fault-injection
|
||||
|
||||
## Core Hardware Matrix
|
||||
|
||||
| ID | Area | Test Path | Priority | Platforms | Pass Criteria |
|
||||
|---|---|---|---|---|---|
|
||||
| HW-BOOT-001 | Boot | Cold boot to operational state | P0 | all | boots successfully within target time budget; no panic/reset loop |
|
||||
| HW-BOOT-002 | Boot | Warm reboot (`esp_restart`) loop x50 | P0 | all | no stuck boot, no boot partition confusion, stable counters |
|
||||
| HW-BOOT-003 | Boot identity | Platform profile and key GPIO map sanity | P0 | all | expected `FW_PLATFORM_NAME`, expected peripheral init paths |
|
||||
| HW-STOR-001 | Storage/NVS | NVS read/write/reset cycle | P0 | all | persisted values survive reboot, reset restores defaults |
|
||||
| HW-STOR-002 | Storage/NVS | Corrupt/partial NVS handling | P1 | all | graceful recovery path, no crash, defaults restored or fallback used |
|
||||
| HW-STOR-003 | SPIFFS | SPIFFS mount + defaults file read | P0 | all | mount succeeds, required files loaded, clear error if missing |
|
||||
| HW-NET-001 | Wi-Fi | AP connect + DHCP + DNS | P0 | all | connected state reached, IP assigned, DNS query success |
|
||||
| HW-NET-002 | Wi-Fi resilience | AP loss/recovery reconnect | P0 | all | reconnect within SLA, no task deadlock or watchdog |
|
||||
| HW-NET-003 | Service discovery | mDNS announce/discover | P1 | all | service visible on LAN; no crash if mDNS unavailable |
|
||||
| HW-NET-004 | Ethernet | Link up/down + DHCP + traffic | P1 | ethernet-capable | state transitions handled cleanly; no memory growth trend |
|
||||
| HW-AUD-001 | Audio output | Start/stop playback, no signal path errors | P0 | all | successful init and playback lifecycle, no panic |
|
||||
| HW-AUD-002 | Audio behavior | Format/rate transitions during playback | P1 | all | transitions without hard fault; bounded glitch behavior |
|
||||
| HW-AUD-003 | Audio resilience | Underrun/rebuffer recovery | P1 | all | playback recovers, no runaway CPU or deadlock |
|
||||
| HW-AUD-004 | Controls | Volume/mute/jack/speaker path checks | P1 | platform-specific | control actions reflected correctly in output state |
|
||||
| HW-UI-001 | Inputs | Button/rotary/IR event mapping | P1 | platform-specific | expected commands dispatched; no ghost/repeat storm |
|
||||
| HW-UI-002 | Display | Display init + update loop | P1 | display-capable | stable render/update path, no crash under repeated updates |
|
||||
| HW-PWR-001 | Battery/charger | Battery telemetry and status logic | P1 | battery-capable | values in expected range; no invalid-state loop |
|
||||
| HW-BT-001 | Bluetooth | Pair/connect/disconnect cycles | P1 | bt-enabled | stable lifecycle across repeated cycles |
|
||||
| HW-BT-002 | Bluetooth resilience | BT stack restart/recovery | P2 | bt-enabled | stack recovers without reboot or hard fault |
|
||||
| HW-OTA-001 | OTA | Happy-path OTA update | P0 | all | new image boots and reports expected version |
|
||||
| HW-OTA-002 | OTA failure | Interrupted OTA (network/power cut) | P0 | all | safe fallback/rollback path works; device recoverable |
|
||||
| HW-OTA-003 | Recovery partition | Recovery boot and exit path | P0 | all | recovery mode entry/exit consistent and deterministic |
|
||||
| HW-PWRF-001 | Power fault | Brownout/power-cut during write/OTA | P0 | all | no bricking; deterministic recovery behavior |
|
||||
| HW-SOAK-001 | Soak | 12h playback + periodic reconnect | P2 | all | no crash/reset; memory trend within threshold |
|
||||
| HW-SOAK-002 | Soak | 24h mixed load (stream/control/network churn) | P2 | all | no regressions in responsiveness and stability |
|
||||
|
||||
## Platform-Specific Focus
|
||||
|
||||
## `i2s` (generic baseline)
|
||||
|
||||
- Emphasize:
|
||||
- audio path stability under varied sample rates
|
||||
- generic GPIO/peripheral defaults
|
||||
- OTA + recovery baseline behavior
|
||||
- Required:
|
||||
- all `P0`
|
||||
- `HW-AUD-002`, `HW-AUD-003`, `HW-SOAK-001`
|
||||
|
||||
## `muse` (portable/battery-centric)
|
||||
|
||||
- Emphasize:
|
||||
- battery telemetry, charger events, low-power edge conditions
|
||||
- UI/display responsiveness under battery/network churn
|
||||
- Wi-Fi reconnect after sleep-like or low-power transitions
|
||||
- Required:
|
||||
- all `P0`
|
||||
- `HW-PWR-001`, `HW-UI-001`, `HW-UI-002`, `HW-SOAK-001`
|
||||
|
||||
## `squeezeamp` (amp/control-centric)
|
||||
|
||||
- Emphasize:
|
||||
- amplifier-related controls, output routing, jack/speaker transitions
|
||||
- thermal/long-play stability proxies (extended playback)
|
||||
- network resilience during active playback
|
||||
- Required:
|
||||
- all `P0`
|
||||
- `HW-AUD-004`, `HW-NET-002`, `HW-SOAK-001`, `HW-SOAK-002`
|
||||
|
||||
## Release Gates
|
||||
|
||||
A release is eligible only if:
|
||||
- every target platform passes all `P0` tests
|
||||
- no unresolved regression in previously passing `P1` tests
|
||||
- at least one `P2` soak run per platform completed within release window
|
||||
- OTA/recovery tests (`HW-OTA-001/002/003`) pass on all platforms
|
||||
|
||||
## Observability Requirements During Tests
|
||||
|
||||
Collect at minimum:
|
||||
- reset reason, panic reason, boot count, recovery boot count
|
||||
- heap free/minimum and largest block trend
|
||||
- task stack high-water marks for critical tasks
|
||||
- network reconnect counters and durations
|
||||
- OTA stage/result events
|
||||
|
||||
A test can be marked "pass with warning" only for non-`P0` tests and only with a filed follow-up issue and owner.
|
||||
|
||||
## Failure Triage Rules
|
||||
|
||||
- `P0` fail: immediate release block
|
||||
- repeated `P1` fail on same platform: treat as release risk, escalate to block unless waived
|
||||
- any soak fail with crash/reset: open defect with logs and reproduction steps before next release candidate
|
||||
|
||||
## Suggested First Implementation Wave
|
||||
|
||||
1. Automate all `P0` checks for each platform profile.
|
||||
2. Add nightly `P1` network/audio/UI subset.
|
||||
3. Add 12h soak (`HW-SOAK-001`) with telemetry capture and trend thresholds.
|
||||
4. Expand to full pre-release matrix once stable signal quality is established.
|
||||
64
documentation/TESTING_CHARTER.md
Normal file
64
documentation/TESTING_CHARTER.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Testing Charter
|
||||
|
||||
Date: 2026-02-12
|
||||
Scope: `squeezelite-esp32` test design and review policy.
|
||||
|
||||
## Objective
|
||||
|
||||
Keep tests stable across refactors by validating behavior contracts and invariants, not implementation details.
|
||||
|
||||
## Grounding Rule
|
||||
|
||||
Tests must verify behavior that is expected to remain true after refactoring.
|
||||
|
||||
Tests should be rejected in review if they mainly assert internals that can change without changing user-visible or system-visible behavior.
|
||||
|
||||
## Contract-First Principles
|
||||
|
||||
1. Test module boundaries
|
||||
- public function behavior
|
||||
- state machine transitions
|
||||
- error semantics
|
||||
- resource/timing bounds where relevant
|
||||
|
||||
2. Prefer invariants over internals
|
||||
- "must never crash on malformed input"
|
||||
- "illegal state transition is rejected"
|
||||
- "retry is bounded"
|
||||
- "idempotent operation remains safe when repeated"
|
||||
|
||||
3. Avoid implementation coupling
|
||||
- do not assert private helper call order unless behavior-critical
|
||||
- do not assert exact logs/strings unless contractually required
|
||||
- do not assert private data layout
|
||||
|
||||
4. Fixes require regression tests
|
||||
- every production bug fix should add a regression test at the highest stable boundary that catches it
|
||||
|
||||
5. Embedded + host split
|
||||
- host-native tests for deterministic logic
|
||||
- hardware/HIL tests for timing, drivers, memory layout, OTA/recovery, power fault behavior
|
||||
|
||||
## Review Gate
|
||||
|
||||
Reviewers should ask:
|
||||
|
||||
1. What contract does this test protect?
|
||||
2. Would this test still pass after a clean internal refactor with identical behavior?
|
||||
3. Does this test provide failure signal that matters to users/platform stability?
|
||||
|
||||
If answers are weak, request a contract-level test instead.
|
||||
|
||||
## Minimum PR Expectations
|
||||
|
||||
- New behavior: at least one contract-level test
|
||||
- Bug fix: at least one regression test
|
||||
- Refactor-only PR: existing contract tests still pass, no new implementation-coupled tests added
|
||||
|
||||
## Mapping to Hardware Matrix
|
||||
|
||||
Use this charter with:
|
||||
- `documentation/HARDWARE_TEST_MATRIX.md`
|
||||
|
||||
The charter governs *how* tests are written.
|
||||
The matrix governs *where/what* is validated per hardware platform.
|
||||
20
documentation/agents/README.md
Normal file
20
documentation/agents/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Agent Documentation
|
||||
|
||||
Store long-form guidance for coding agents here.
|
||||
|
||||
## Suggested Files
|
||||
|
||||
- `documentation/agents/architecture.md`: subsystem boundaries, data flow, invariants.
|
||||
- `documentation/agents/build-and-test.md`: canonical commands, fast checks, CI mapping.
|
||||
- `documentation/agents/style-and-lint.md`: formatting policy, lint severity, suppression rules.
|
||||
- `documentation/agents/refactor-playbook.md`: safe refactor steps, rollout strategy, risk controls.
|
||||
- `documentation/agents/frontend_requirements_context.md`: requirements-first UI context, size budgets, and migration constraints.
|
||||
- `documentation/agents/module-notes/<module>.md`: module-level constraints and edge cases.
|
||||
|
||||
## Writing Rules
|
||||
|
||||
- Keep files operational and concrete.
|
||||
- Prefer checklists and explicit commands.
|
||||
- Record known pitfalls and non-obvious invariants.
|
||||
- Link back from `AGENTS.md` only to docs that are actively maintained.
|
||||
- When frontend payload/routes/contracts change, refresh the snapshot with `build-scripts/ui_footprint_snapshot.sh` and update `frontend_requirements_context.md`.
|
||||
201
documentation/agents/frontend_requirements_context.md
Normal file
201
documentation/agents/frontend_requirements_context.md
Normal file
@@ -0,0 +1,201 @@
|
||||
# Frontend Requirements Context (Living)
|
||||
|
||||
Status: Active
|
||||
Last reviewed: 2026-02-12
|
||||
Review scope: `components/wifi-manager/webapp`, `components/wifi-manager/http_server_handlers.c`, `components/wifi-manager/wifi_manager_http_server.c`, `spiffs_src/CMakeLists.txt`
|
||||
|
||||
## Purpose
|
||||
|
||||
This document captures reverse-engineered **product requirements** for the embedded web UI, with measurable constraints.
|
||||
It is intentionally not an implementation walkthrough.
|
||||
|
||||
Use this as session handoff context for UI refactoring and footprint control.
|
||||
|
||||
## Snapshot Findings (Current State)
|
||||
|
||||
### 1. What actually ships to firmware
|
||||
|
||||
SPIFFS packaging currently copies only:
|
||||
|
||||
- `components/wifi-manager/webapp/dist/*.gz`
|
||||
- `components/wifi-manager/webapp/dist/*.png`
|
||||
|
||||
Evidence: `spiffs_src/CMakeLists.txt`.
|
||||
|
||||
Current shipped web payload:
|
||||
|
||||
- Total shipped bytes: `219741` (`~214.6 KiB`, `~0.21 MiB`)
|
||||
- Largest asset: `dist/js/node_vendors.bundle.js.gz` (`166729` bytes)
|
||||
|
||||
### 2. What looks large but is not currently shipped
|
||||
|
||||
- `dist/` total is about `4.5M`, dominated by source maps (`*.map`).
|
||||
- Source maps are large in repo artifacts, but not copied to SPIFFS by current packaging.
|
||||
|
||||
### 3. Major technical debt signal
|
||||
|
||||
- UI source references many legacy endpoints (`/status.zzz`, `/messages.zzz`, `/commands.zzz`, etc.).
|
||||
- Active server registration in `wifi_manager_http_server.c` is centered on `/data.bin` + static handlers; many legacy handlers are commented out.
|
||||
|
||||
This indicates API/contract drift and unclear migration state.
|
||||
|
||||
### 4. Modularity and proto usage signal
|
||||
|
||||
- Main UI logic is largely monolithic in `src/js/custom.ts` (~2.5k LOC).
|
||||
- `index.ts` imports generated protobuf bundle (`configuration_pb.js`) up front.
|
||||
- `dist/js/index.bundle.js` includes many generated proto message definitions, not only request/response minimum set.
|
||||
|
||||
Implication: upfront JS parse/execute and bundle weight are likely higher than needed.
|
||||
|
||||
## Reverse-Engineered Product Requirements
|
||||
|
||||
These are the requirements we should preserve while refactoring.
|
||||
|
||||
### RQ-UI-001 Captive Portal Bootstrap
|
||||
|
||||
The UI must reliably open and render from AP/captive-portal entry points with no manual URL knowledge.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Landing page reachable from captive portal probes.
|
||||
- First meaningful controls visible without requiring cloud services.
|
||||
|
||||
### RQ-UI-002 Network Onboarding and Recovery
|
||||
|
||||
Users must be able to scan APs, join/disconnect Wi-Fi, and understand current link mode (Wi-Fi vs Ethernet) with clear status.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Scan, connect, disconnect workflows remain available and understandable.
|
||||
- Connection state transitions are visible and unambiguous.
|
||||
|
||||
### RQ-UI-003 Runtime Observability
|
||||
|
||||
Users must see operational status and logs needed for diagnosis (network, playback, OTA progress, errors).
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Status view remains available in normal and recovery mode.
|
||||
- Error and warning paths are visible in UI without dev tools.
|
||||
|
||||
### RQ-UI-004 Safe Configuration Editing
|
||||
|
||||
Users must be able to view/edit/apply configuration with guardrails (validation feedback, clear commit/apply behavior).
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Config edit path supports both selective and global update actions.
|
||||
- Validation errors are explicit before/after submit.
|
||||
|
||||
### RQ-UI-005 OTA Operations
|
||||
|
||||
Users must be able to trigger firmware update by URL or upload, with progress and failure feedback.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- OTA action always yields deterministic status progression or explicit terminal error.
|
||||
- Recovery path remains accessible if normal OTA path fails.
|
||||
|
||||
### RQ-UI-006 Advanced Control Access
|
||||
|
||||
Power-user controls (commands/NVS/diagnostics) must exist but should not degrade common-task UX.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Advanced functions remain accessible.
|
||||
- Main tasks are not blocked by advanced UI complexity.
|
||||
|
||||
### RQ-UI-007 Backward Compatibility Envelope
|
||||
|
||||
The UI must support currently deployed firmware API variants during migration (legacy and protobuf-era endpoints), with explicit deprecation strategy.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Contract compatibility matrix is documented and tested.
|
||||
- Legacy paths have clear sunset criteria.
|
||||
|
||||
### RQ-UI-008 Embedded Footprint Discipline
|
||||
|
||||
Web assets must stay within explicit firmware budget and be measurable in CI.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- Shipping budget exists and is enforced.
|
||||
- Size regressions fail checks unless explicitly approved.
|
||||
|
||||
## Non-Functional Budgets (Proposed)
|
||||
|
||||
These are targets, not yet enforced:
|
||||
|
||||
- `NB-001` Shipped web payload (`*.gz` + `*.png` in `dist/`) <= `180 KiB` target, `220 KiB` hard cap.
|
||||
- `NB-002` Main JS gzip <= `120 KiB` target.
|
||||
- `NB-003` Vendor JS gzip <= `120 KiB` target.
|
||||
- `NB-004` No runtime dependency on external CDNs for critical UI function.
|
||||
- `NB-005` One canonical API transport for new features (`/data.bin` protobuf), with compatibility shim for legacy endpoints during migration only.
|
||||
|
||||
## UX + Footprint Improvement Directions
|
||||
|
||||
Prioritized by impact/risk.
|
||||
|
||||
### P1 Contract Unification (High impact, medium risk)
|
||||
|
||||
- Define one frontend API client contract around protobuf request/response.
|
||||
- Treat legacy `.zzz` paths as compatibility layer, not primary path.
|
||||
- Add explicit compatibility table (firmware version -> supported endpoints).
|
||||
|
||||
### P2 Modularization by Capability (High impact, medium risk)
|
||||
|
||||
- Split monolithic UI logic into capability modules:
|
||||
- onboarding
|
||||
- status/logs
|
||||
- config editor
|
||||
- OTA
|
||||
- advanced
|
||||
- Lazy-load non-critical modules (advanced, release browser, heavy editors).
|
||||
|
||||
Expected result: lower startup JS cost and clearer ownership boundaries.
|
||||
|
||||
### P3 Proto Surface Minimization (High impact, medium risk)
|
||||
|
||||
- Stop importing broad generated config surface on initial load.
|
||||
- Create thin protobuf DTO layer for startup-critical flows.
|
||||
- Load heavy schema modules only when entering related screens.
|
||||
|
||||
### P4 UI Responsiveness and Clarity (Medium impact, low risk)
|
||||
|
||||
- Replace mixed polling patterns with a single scheduler and explicit backoff policy.
|
||||
- Standardize in-progress/error/success state rendering across all actions.
|
||||
- Reduce ambiguous icon-only cues with text fallback in constrained/offline contexts.
|
||||
|
||||
### P5 Build Output Hygiene (Medium impact, low risk)
|
||||
|
||||
- Keep generating sourcemaps for dev/debug if needed, but separate from shipping artifact workflow.
|
||||
- Enforce shipped-size budget on what SPIFFS actually receives, not raw `dist/`.
|
||||
|
||||
## Living Maintenance Protocol
|
||||
|
||||
This file must be updated when any of the following changes:
|
||||
|
||||
- web routes/endpoints
|
||||
- protobuf request/response schema used by UI
|
||||
- shipped asset packaging rules
|
||||
- significant UI feature flow
|
||||
|
||||
Required update steps:
|
||||
|
||||
1. Run `build-scripts/ui_footprint_snapshot.sh`.
|
||||
2. Update Snapshot Findings and budget deltas in this file.
|
||||
3. Update compatibility notes if API contract changed.
|
||||
4. Add an entry to Decision Log.
|
||||
|
||||
## Decision Log
|
||||
|
||||
| Date | Decision | Why | Follow-up |
|
||||
|------|----------|-----|-----------|
|
||||
| 2026-02-12 | Treat this file as requirements-first context, not implementation notes | Reduce drift and speed up session handoffs | Add CI size gate and API contract checks |
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Are legacy `.zzz` endpoints still required for deployed firmware versions, and for which versions exactly?
|
||||
- Is the intended long-term model pure protobuf over `/data.bin` for all dynamic data?
|
||||
- What startup latency target is acceptable on AP-mode captive portal connections?
|
||||
Reference in New Issue
Block a user