docs/agents/testing-commands.md
ALWAYS use bash wrapper scripts. DO NOT run low-level build tools or Python scripts directly.
# ā
CORRECT - Use bash wrapper scripts
bash test # Run all tests
bash test <test_name> # Build and run specific test
bash compile <platform> # Compile for platforms
bash lint # Run linting
bash validate --parlio # Hardware validation
# ā ļø AVOID - Only when bash scripts don't provide needed functionality
uv run test.py <test_name> # Direct Python script
# ā FORBIDDEN - Never use these
uv run python test.py # WRONG - never "uv run python"
meson setup builddir # WRONG - use bash scripts
ninja -C builddir # WRONG - use bash scripts
clang++ main.cpp -o main # WRONG - use bash scripts
Exceptions: Runtime debugging (e.g., lldb .build/runner.exe) and compiler feature testing are allowed. See docs/agents/build-system.md for details.
Tests automatically timeout after 10 seconds to detect infinite loops and deadlocks.
TEST HUNG: test_name
Exceeded timeout of 10.0s
š Attaching lldb to hung process (PID 12345)...
THREAD STACK TRACES:
* frame #0: infinite_loop() at test.cpp:67
šŖ Killed hung process
What to do:
Technical details:
tests/meson.build)docs/signal-handler-chaining.md and docs/deadlock-detection.md for detailsUse the --clean flag to rebuild from scratch. DO NOT manually delete build directories.
# ā
CORRECT - Use clean flag
bash test --clean # Clean and rebuild all tests
bash test --clean tests/fl/async # Clean and rebuild specific test
bash compile --clean esp32s3 # Clean and rebuild platform
# ā FORBIDDEN - Never manually delete build caches
rm -rf .build/meson-quick # WRONG - use --clean instead
rm -rf .build && bash test # WRONG - use bash test --clean
The build system is self-healing and revalidates automatically. Manual cache deletion is highly discouraged. See docs/agents/build-system.md for details.
DO NOT use --no-fingerprint. This flag disables critical performance optimizations and makes builds 10-100x slower.
# ā FORBIDDEN - Never disable fingerprint caching
uv run test.py --no-fingerprint # WRONG - extremely slow
bash test --no-fingerprint # WRONG - extremely slow
# ā
CORRECT - Trust the fingerprint cache
bash test # Fast, uses fingerprint cache
bash test --clean # Clean rebuild, preserves fingerprint cache
Rationale: Fingerprint caching tracks file changes and skips rebuilding unchanged files. Disabling it forces full rebuilds every time, which is unnecessary and extremely slow. If you suspect cache issues, use --clean instead.
LAST RESORT ONLY: Only use --no-fingerprint if you have concrete evidence that fingerprint caching itself is broken (not just a stale build). This should be extremely rare. See docs/agents/build-system.md for details.
Run tests inside a Docker container for consistent Linux environment with ASAN/LSAN sanitizers:
# Run all C++ tests in Docker (implies --debug with sanitizers)
bash test --docker
# Run specific unit test in Docker
bash test --docker tests/fl/async
# Run with quick mode (no sanitizers, faster)
bash test --docker --quick
# Run with release mode (optimized)
bash test --docker --build-mode release
# Run only unit tests
bash test --docker --unit
# Run only examples
bash test --docker --examples
Notes:
--docker implies --debug mode (ASAN/LSAN sanitizers enabled) unless --quick or --build-mode is specified--docker implies --debug mode (sanitizers enabled). Use --quick or --build-mode release for faster builds..venv and .build to persist between runsAI AGENTS: Avoid bash test --docker unless necessary - Docker testing is slow (3-5 minutes per test). Use uv run test.py for quick local testing. Only use Docker when:
The project uses fbuild as the default build system for ESP32-S3 and ESP32-C6 (RISC-V) boards. fbuild provides:
Default behavior:
Usage via debug_attached.py:
# ESP32-S3: fbuild is the default (no --use-fbuild needed)
uv run ci/debug_attached.py esp32s3 --example Blink
# Force PlatformIO on esp32s3/esp32c6
uv run ci/debug_attached.py esp32s3 --example Blink --no-fbuild
# Explicitly use fbuild on other ESP32 variants
uv run ci/debug_attached.py esp32dev --use-fbuild --example Blink
Build caching: fbuild stores builds in .fbuild/build/<env>/ and caches toolchains in .fbuild/cache/.
FastLED supports fast host-based compilation of .ino examples using Meson build system:
Quick Mode (Default - Fast Iteration):
uv run test.py --examples - Compile and run all examples (quick mode, 80 examples in ~0.24s)uv run test.py --examples Blink DemoReel100 - Compile specific examples (quick mode)uv run test.py --examples --no-parallel - Sequential compilation (easier debugging)uv run test.py --examples --verbose - Show detailed compilation outputuv run test.py --examples --clean - Clean build cache and recompileDebug Mode (Full Symbols + Sanitizers):
uv run test.py --examples --debug - Compile all examples with debug symbols and sanitizersuv run test.py --examples Blink --debug - Compile specific example in debug modeuv run test.py --examples Blink --debug --full - Debug mode with executionuv run python ci/util/meson_example_runner.py Blink --debug - Direct invocation (debug)Release Mode (Optimized Production Builds):
uv run test.py --examples --build-mode release - Compile all examples optimizeduv run test.py --examples Blink --build-mode release - Compile specific example (release)uv run python ci/util/meson_example_runner.py Blink --build-mode release - Direct invocation (release)Build Modes:
quick (default): Light optimization with minimal debug info (-O1 -g1)
.build/meson-quick/examples/debug: Full symbols and sanitizers (-O0 -g3 -fsanitize=address,undefined)
.build/meson-debug/examples/release: Optimized production build (-O2 -DNDEBUG)
.build/meson-release/examples/Mode-Specific Directories:
.build/meson-{quick,debug,release}/examples/Performance Notes:
Direct Invocation:
uv run python ci/util/meson_example_runner.py - Compile all examples directly (quick mode)uv run python ci/util/meson_example_runner.py Blink --full - Compile and execute specific exampleuv run python ci/util/meson_example_runner.py Blink --debug --full - Debug mode with executionbash run wasm <example> - Compile WASM example and serve with live-server:
Usage:
bash run wasm AnimartrixRing - Compile AnimartrixRing to WASM and serve with live-serverbash run wasm Blink - Compile Blink to WASM and serve with live-serverWhat it does:
bash compile wasm <example>examples/<example>/fastled_js/) with live-serverRequirements:
npm install -g live-serverRun AVR firmware in the avr8js emulator locally using Node.js ā no Docker needed.
One-time setup:
cd ci/docker_utils/avr8js && npm install && cd -
Workflow: Compile ā Run
# 1. Compile sketch for UNO (uses PlatformIO, may use Docker for compilation)
bash compile uno --examples Blink --local
# 2. Run hex in avr8js emulator (pure Node.js, no Docker)
npx --prefix ci/docker_utils/avr8js tsx ci/docker_utils/avr8js/main.ts \
.build/pio/uno/.pio/build/uno/firmware.hex --timeout 5 --verbose
Options:
--timeout <seconds> ā Simulated time limit (default: 30)--verbose ā Show execution stats (wall time, cycles, performance %)Performance: avr8js runs at ~140-180% of real 16MHz clock speed.
Output: Serial (UART) output prints to stdout. The emulator checks for "Test loop" in output by default (exit code 1 if missing ā safe to ignore for non-test sketches).
Supported boards: uno (ATmega328P), nano_every (ATmega4809). ATtiny85/88 lack hardware UART so serial output won't work.
Hex file location: .build/pio/<board>/.pio/build/<board>/firmware.hex
Files:
ci/docker_utils/avr8js/main.ts ā Entry pointci/docker_utils/avr8js/execute.ts ā AVR CPU emulator wrapperci/docker_utils/avr8js/package.json ā Node dependencies (avr8js, tsx)uv run ci/install-qemu.py - Install QEMU for ESP32 emulation (standalone)uv run test.py --qemu esp32s3 - Run QEMU tests (installs QEMU automatically)FASTLED_QEMU_SKIP_INSTALL=true uv run test.py --qemu esp32s3 - Skip QEMU installation step