summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-04-03 16:42:18 +0700
committerhathach <[email protected]>2026-04-03 16:42:18 +0700
commit3ed9d6517485611b040ecdc4e5d327b6e86f3dee (patch)
tree585e87c436377cb5503b1f17e70271118544c243
parente82df22375ac22ffddf86234a818bb7f4d66af7c (diff)
add script and instruction to run remote hil on local ci server
-rw-r--r--.claude/commands/hil.md46
-rw-r--r--test/hil/hil_ci.sh69
2 files changed, 109 insertions, 6 deletions
diff --git a/.claude/commands/hil.md b/.claude/commands/hil.md
index 2ba35ec22..266321bb9 100644
--- a/.claude/commands/hil.md
+++ b/.claude/commands/hil.md
@@ -16,15 +16,49 @@ Run Hardware-in-the-Loop (HIL) tests on physical boards.
2. Parse $ARGUMENTS:
- If $ARGUMENTS contains `-b BOARD_NAME`, run for that specific board only.
- If $ARGUMENTS is empty or has no `-b`, run for all boards in the config.
- - Pass through any other flags (e.g. `-v` for verbose) directly to the command.
+ - Pass through any other flags (e.g. `-v` for verbose, `-r N` for retry count) directly to the command.
-3. Run the HIL test from the repo root directory:
- - Specific board: `python test/hil/hil_test.py -b BOARD_NAME -B examples $HIL_CONFIG $EXTRA_ARGS`
- - All boards: `python test/hil/hil_test.py -B examples $HIL_CONFIG $EXTRA_ARGS`
+3. Determine whether to run **locally** or **remotely via SSH**:
+ - **Local**: boards are attached to this machine (default when `local.json` is used)
+ - **Remote (`ssh ci.lan`)**: boards are attached to the CI machine (when `tinyusb.json` is used)
-4. Use a timeout of at least 20 minutes (600000ms). HIL tests take 2-5 minutes. NEVER cancel early.
+4. **Local execution** (boards attached to this machine):
+ ```bash
+ python test/hil/hil_test.py -b BOARD_NAME -B examples $HIL_CONFIG $EXTRA_ARGS
+ ```
+
+5. **Remote execution** (boards attached to `ci.lan`):
+ Only copy the minimal files needed (firmware binaries + test script + config), then run remotely.
+
+ ```bash
+ REMOTE=ci.lan
+ REMOTE_DIR=/tmp/tinyusb-hil
+
+ # Create remote working directory
+ ssh $REMOTE "rm -rf $REMOTE_DIR && mkdir -p $REMOTE_DIR/test/hil"
+
+ # Copy HIL test script and its dependency
+ scp test/hil/hil_test.py test/hil/pymtp.py test/hil/tinyusb.json $REMOTE:$REMOTE_DIR/test/hil/
+
+ # Copy only the firmware binaries for the target board(s)
+ # For a specific board:
+ scp -r examples/cmake-build-$BOARD_NAME $REMOTE:$REMOTE_DIR/examples/
+
+ # Or for all boards that have been built:
+ # for dir in examples/cmake-build-*/; do scp -r "$dir" $REMOTE:$REMOTE_DIR/examples/; done
+
+ # Run the test remotely
+ ssh $REMOTE "cd $REMOTE_DIR && python3 test/hil/hil_test.py -b $BOARD_NAME -B examples tinyusb.json $EXTRA_ARGS"
+ ```
+
+ Note: The remote machine (`ci.lan`) must have:
+ - Python 3 with `pyserial` installed (`pip install pyserial`)
+ - Flasher tools: `JLinkExe`, `openocd`, etc. as needed by the board
+ - USB access to the boards (udev rules configured)
+
+6. Use a timeout of at least 20 minutes (600000ms). HIL tests take 2-5 minutes. NEVER cancel early.
-5. After the test completes:
+7. After the test completes:
- Show the test output to the user.
- Summarize pass/fail results per board.
- If there are failures, suggest re-running with `-v` flag for verbose output to help debug.
diff --git a/test/hil/hil_ci.sh b/test/hil/hil_ci.sh
new file mode 100644
index 000000000..fa8bb0245
--- /dev/null
+++ b/test/hil/hil_ci.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+# Run HIL test remotely on ci.lan
+# Usage: test/hil/hil_ci.sh [-b BOARD] [-t TEST] [extra hil_test.py args...]
+# Example:
+# test/hil/hil_ci.sh -b stm32f723disco
+# test/hil/hil_ci.sh -b stm32f723disco -t host/cdc_msc_hid -r 1
+
+set -e
+
+REMOTE=ci.lan
+REMOTE_DIR=/tmp/tinyusb-hil
+SCRIPT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
+
+# Parse -b BOARD from arguments to know which build to copy
+BOARD=""
+ARGS=()
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -b)
+ BOARD="$2"
+ ARGS+=("$1" "$2")
+ shift 2
+ ;;
+ *)
+ ARGS+=("$1")
+ shift
+ ;;
+ esac
+done
+
+# Setup remote directory
+echo "==> Setting up remote $REMOTE:$REMOTE_DIR"
+ssh "$REMOTE" "rm -rf $REMOTE_DIR && mkdir -p $REMOTE_DIR/test/hil $REMOTE_DIR/examples"
+
+# Copy HIL test script and config
+echo "==> Copying test scripts"
+scp -q "$SCRIPT_DIR/test/hil/hil_test.py" \
+ "$SCRIPT_DIR/test/hil/pymtp.py" \
+ "$SCRIPT_DIR/test/hil/tinyusb.json" \
+ "$REMOTE:$REMOTE_DIR/test/hil/"
+
+# Copy only firmware binaries (elf/bin/hex), preserving directory structure
+copy_board_binaries() {
+ local src="$1"
+ local board_name
+ board_name=$(basename "$src")
+ rsync -a --include='*/' --include='*.elf' --include='*.bin' --include='*.hex' --exclude='*' \
+ "$src" "$REMOTE:$REMOTE_DIR/examples/"
+}
+
+if [ -n "$BOARD" ]; then
+ BUILD_DIR="$SCRIPT_DIR/examples/cmake-build-$BOARD"
+ if [ ! -d "$BUILD_DIR" ]; then
+ echo "Error: build directory not found: $BUILD_DIR"
+ echo "Build first with: cd examples && cmake -DBOARD=$BOARD -G Ninja -B cmake-build-$BOARD .. && cmake --build cmake-build-$BOARD"
+ exit 1
+ fi
+ echo "==> Copying binaries for $BOARD"
+ copy_board_binaries "$BUILD_DIR"
+else
+ echo "==> Copying all built binaries"
+ for dir in "$SCRIPT_DIR"/examples/cmake-build-*/; do
+ [ -d "$dir" ] && copy_board_binaries "$dir"
+ done
+fi
+
+# Run test
+echo "==> Running HIL test on $REMOTE"
+ssh -t "$REMOTE" "cd $REMOTE_DIR && python3 -u test/hil/hil_test.py -B examples ${ARGS[*]} tinyusb.json"