Add automated E2E testing documentation and test prompts
- docs/automated-e2e-testing.md: Guide for running headless Claude CLI tests with both mcbluetooth and mcbluetooth-esp32 MCP servers - tests/prompts/test-prompt-v4.md: 71-test suite covering Classic BT, BLE GATT, HCI capture, device management - tests/prompts/test-prompt-v5.md: 76-test suite adding Battery Service (0x180F) and bt_ble_battery verification Test results from v4: 71/71 PASS with 143 HCI packets captured
This commit is contained in:
parent
5a853c15fc
commit
88d006e9c4
287
docs/automated-e2e-testing.md
Normal file
287
docs/automated-e2e-testing.md
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
# Automated E2E Testing with Claude CLI
|
||||||
|
|
||||||
|
This document describes how to run fully automated end-to-end Bluetooth tests using the Claude CLI in headless mode. The tests exercise the complete Bluetooth stack across two devices: a Linux host running `mcbluetooth` (BlueZ) and an ESP32 running the `mcbluetooth-esp32` firmware.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌───────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Claude CLI (headless mode) │
|
||||||
|
│ Orchestrates both MCP servers │
|
||||||
|
└───────────────────────────┬───────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
┌───────────────┴───────────────┐
|
||||||
|
│ │
|
||||||
|
┌───────┴───────┐ ┌───────┴───────┐
|
||||||
|
│ mcbluetooth │ │mcbluetooth-esp32│
|
||||||
|
│ MCP Server │ │ MCP Server │
|
||||||
|
│ (bt_* tools)│ │ (esp32_* tools)│
|
||||||
|
└───────┬───────┘ └───────┬────────┘
|
||||||
|
│ │
|
||||||
|
D-Bus/BlueZ Serial/UART
|
||||||
|
│ │
|
||||||
|
┌───────┴───────┐ ┌───────┴────────┐
|
||||||
|
│ Linux Host │◄── Bluetooth ──►│ ESP32 │
|
||||||
|
│ (hci1) │ (over air) │ (peripheral) │
|
||||||
|
└───────────────┘ └────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### Hardware
|
||||||
|
- ESP32 dev board connected via USB (typically `/dev/ttyUSB0` or `/dev/ttyUSB4`)
|
||||||
|
- Linux host with Bluetooth adapter (typically `hci0` or `hci1`)
|
||||||
|
|
||||||
|
### Software
|
||||||
|
- ESP32 flashed with mcbluetooth-esp32 firmware
|
||||||
|
- Both MCP servers installed and accessible via `uvx`
|
||||||
|
- Claude CLI installed
|
||||||
|
|
||||||
|
### Permissions
|
||||||
|
For HCI packet capture tests, grant btmon the required capability:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo setcap cap_net_raw+ep /usr/bin/btmon
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Environment Setup
|
||||||
|
|
||||||
|
### 1. Create a test directory
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /tmp/bt-e2e-test
|
||||||
|
cd /tmp/bt-e2e-test
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Create MCP configuration
|
||||||
|
|
||||||
|
Create `.mcp.json` with both MCP servers:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"esp32": {
|
||||||
|
"type": "stdio",
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["mcbluetooth-esp32"],
|
||||||
|
"env": {
|
||||||
|
"ESP32_SERIAL_PORT": "/dev/ttyUSB4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bluez": {
|
||||||
|
"type": "stdio",
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["mcbluetooth"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Initialize git (required for Claude CLI)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git init
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
|
||||||
|
### Basic Command Structure
|
||||||
|
|
||||||
|
```bash
|
||||||
|
claude -p "$(cat test-prompt.md)" \
|
||||||
|
--mcp-config .mcp.json \
|
||||||
|
--allowedTools "mcp__esp32__*,mcp__bluez__*" \
|
||||||
|
--output-format json \
|
||||||
|
2>/dev/null | tee results.json | jq -r '.result'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key flags:**
|
||||||
|
- `-p`: Print/headless mode (non-interactive)
|
||||||
|
- `--mcp-config`: Path to MCP server configuration
|
||||||
|
- `--allowedTools`: Glob patterns for permitted tools (required in headless mode)
|
||||||
|
- `--output-format json`: Machine-parseable output
|
||||||
|
|
||||||
|
### Full Test Suite (76 tests)
|
||||||
|
|
||||||
|
The comprehensive test suite covers:
|
||||||
|
- ESP32 connection and system commands
|
||||||
|
- BlueZ adapter management
|
||||||
|
- Classic Bluetooth SSP pairing with auto-accept
|
||||||
|
- BLE GATT service creation (Environmental Sensing + Battery Service)
|
||||||
|
- HCI packet capture and analysis
|
||||||
|
- GATT read/write/notify operations
|
||||||
|
- Device management (trust, block, alias)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
claude -p "$(cat test-prompt-v5.md)" \
|
||||||
|
--mcp-config .mcp.json \
|
||||||
|
--allowedTools "mcp__esp32__*,mcp__bluez__*" \
|
||||||
|
--output-format json 2>/dev/null | tee results-v5.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Analyzing Results
|
||||||
|
|
||||||
|
Extract the summary:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
jq -r '.result' results-v5.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Check pass/fail statistics:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
jq -r '.result' results-v5.json | grep -E "(PASS|FAIL|Total)"
|
||||||
|
```
|
||||||
|
|
||||||
|
View full metrics:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
jq '{
|
||||||
|
duration_ms: .duration_ms,
|
||||||
|
num_turns: .num_turns,
|
||||||
|
total_cost_usd: .total_cost_usd,
|
||||||
|
success: .is_error == false
|
||||||
|
}' results-v5.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Phases
|
||||||
|
|
||||||
|
The test suite is organized into phases that must run sequentially:
|
||||||
|
|
||||||
|
| Phase | Tests | Coverage |
|
||||||
|
|-------|-------|----------|
|
||||||
|
| 1. ESP32 Connection | 1-4 | connect, ping, get_info, status |
|
||||||
|
| 2. BlueZ Adapter | 5-8 | list_adapters, adapter_info, pairable, discoverable |
|
||||||
|
| 3. Classic BT + SSP | 9-24 | enable, configure, SSP mode, scan, pair, device management |
|
||||||
|
| 4. Classic Cleanup | 25-29 | disable, events, clear_events |
|
||||||
|
| 5. BLE GATT Setup | 30-42 | Battery Service, Environmental Sensing, advertising |
|
||||||
|
| 6. HCI Capture + Discovery | 43-51 | capture_start, BLE scan, connect, services, characteristics |
|
||||||
|
| 7. Analyze Capture | 52-55 | capture_stop, parse, analyze, read_raw |
|
||||||
|
| 8. GATT Write + Notify | 56-63 | write, subscribe, notify, unsubscribe |
|
||||||
|
| 9. BLE Cleanup | 64-68 | stop advertising, clear GATT, disable BLE |
|
||||||
|
| 10. Adapter Management | 69-73 | set_alias, restore, disable discoverable |
|
||||||
|
| 11. Final Cleanup | 74-76 | ESP32 reset, disconnect, final check |
|
||||||
|
|
||||||
|
## SSP Pairing: The auto_accept Flag
|
||||||
|
|
||||||
|
Numeric Comparison SSP requires **both sides** to confirm the passkey. In headless mode, this creates a deadlock:
|
||||||
|
|
||||||
|
1. Linux calls `bt_pair()` which blocks waiting for ESP32 confirmation
|
||||||
|
2. ESP32 can't receive the confirmation command because the LLM is blocked
|
||||||
|
|
||||||
|
**Solution:** The ESP32 firmware supports `auto_accept` mode:
|
||||||
|
|
||||||
|
```
|
||||||
|
esp32_set_ssp_mode(mode="numeric_comparison", auto_accept=true)
|
||||||
|
```
|
||||||
|
|
||||||
|
This makes the ESP32 automatically confirm SSP pairings, breaking the deadlock.
|
||||||
|
|
||||||
|
## Battery Service Test
|
||||||
|
|
||||||
|
The test suite creates a standard Battery Service (UUID 0x180F) on the ESP32:
|
||||||
|
|
||||||
|
1. Add Battery Service as primary GATT service
|
||||||
|
2. Add Battery Level characteristic (UUID 0x2A19) with read property
|
||||||
|
3. Set value to "4b" (75% in hex)
|
||||||
|
4. After BLE connection, call `bt_ble_battery` on Linux
|
||||||
|
5. Verify it returns 75
|
||||||
|
|
||||||
|
This tests the dedicated `bt_ble_battery` tool in mcbluetooth which reads from the standard Battery Level characteristic.
|
||||||
|
|
||||||
|
## HCI Packet Capture
|
||||||
|
|
||||||
|
Tests 43-55 exercise the btsnoop capture functionality:
|
||||||
|
|
||||||
|
```
|
||||||
|
bt_capture_start(adapter="hci1", output_file="/tmp/ble-gatt-capture.btsnoop")
|
||||||
|
# ... BLE operations ...
|
||||||
|
bt_capture_stop(capture_id="...")
|
||||||
|
bt_capture_parse(filepath="...", max_packets=50)
|
||||||
|
bt_capture_analyze(filepath="...")
|
||||||
|
bt_capture_read_raw(filepath="...", count=20)
|
||||||
|
```
|
||||||
|
|
||||||
|
Typical captures include 100-150 packets covering:
|
||||||
|
- HCI commands (LE scanning, connection)
|
||||||
|
- ACL data (GATT operations)
|
||||||
|
- HCI events (connection complete, encryption)
|
||||||
|
|
||||||
|
## Test Prompt Format
|
||||||
|
|
||||||
|
Test prompts follow a structured format:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Test Suite Title
|
||||||
|
|
||||||
|
## Phase N: Phase Name (Tests X-Y)
|
||||||
|
|
||||||
|
N. **Test Name**: Call `tool_name` with params — expected result
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
After all tests, print a DETAILED summary table:
|
||||||
|
|
||||||
|
| # | Test | Result | Notes |
|
||||||
|
|---|------|--------|-------|
|
||||||
|
| 1 | Connect | PASS/FAIL | ... |
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Serial port busy
|
||||||
|
|
||||||
|
```
|
||||||
|
Error: could not open port /dev/ttyUSB4
|
||||||
|
```
|
||||||
|
|
||||||
|
Check for other processes using the port:
|
||||||
|
```bash
|
||||||
|
lsof /dev/ttyUSB4
|
||||||
|
```
|
||||||
|
|
||||||
|
### btmon permission denied
|
||||||
|
|
||||||
|
```
|
||||||
|
Error: Failed to open HCI raw socket
|
||||||
|
```
|
||||||
|
|
||||||
|
Grant capability:
|
||||||
|
```bash
|
||||||
|
sudo setcap cap_net_raw+ep /usr/bin/btmon
|
||||||
|
```
|
||||||
|
|
||||||
|
### ESP32 not responding
|
||||||
|
|
||||||
|
Power cycle the ESP32 and check the firmware is flashed:
|
||||||
|
```bash
|
||||||
|
# Monitor serial output
|
||||||
|
screen /dev/ttyUSB4 115200
|
||||||
|
```
|
||||||
|
|
||||||
|
Press reset button — should see boot event JSON.
|
||||||
|
|
||||||
|
### Pairing timeout
|
||||||
|
|
||||||
|
Ensure `auto_accept=true` is set for SSP numeric comparison mode before initiating pairing from Linux.
|
||||||
|
|
||||||
|
## Example Results
|
||||||
|
|
||||||
|
A successful v5 run produces:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "result",
|
||||||
|
"subtype": "success",
|
||||||
|
"is_error": false,
|
||||||
|
"duration_ms": 320000,
|
||||||
|
"num_turns": 88,
|
||||||
|
"result": "All 76 tests passed..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Key metrics from successful runs:
|
||||||
|
- Duration: ~5-6 minutes
|
||||||
|
- API turns: 80-90
|
||||||
|
- HCI packets captured: 100-150
|
||||||
|
- Cost: ~$1.50-1.70 USD
|
||||||
29
tests/prompts/README.md
Normal file
29
tests/prompts/README.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# E2E Test Prompts
|
||||||
|
|
||||||
|
These markdown files are test prompts for running automated E2E Bluetooth tests using Claude CLI in headless mode.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /tmp/bt-e2e-test
|
||||||
|
claude -p "$(cat test-prompt-v5.md)" \
|
||||||
|
--mcp-config .mcp.json \
|
||||||
|
--allowedTools "mcp__esp32__*,mcp__bluez__*" \
|
||||||
|
--output-format json
|
||||||
|
```
|
||||||
|
|
||||||
|
See [automated-e2e-testing.md](../../docs/automated-e2e-testing.md) for full setup instructions.
|
||||||
|
|
||||||
|
## Test Prompts
|
||||||
|
|
||||||
|
| File | Tests | Coverage |
|
||||||
|
|------|-------|----------|
|
||||||
|
| `test-prompt-v4.md` | 71 | Classic BT, BLE GATT, HCI capture |
|
||||||
|
| `test-prompt-v5.md` | 76 | v4 + Battery Service, bt_ble_battery |
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- ESP32 with mcbluetooth-esp32 firmware
|
||||||
|
- Linux host with Bluetooth adapter
|
||||||
|
- Both MCP servers configured in `.mcp.json`
|
||||||
|
- btmon with CAP_NET_RAW for HCI capture tests
|
||||||
153
tests/prompts/test-prompt-v4.md
Normal file
153
tests/prompts/test-prompt-v4.md
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
# ESP32 + BlueZ Full E2E Bluetooth Test Suite (v4 - Extended Coverage)
|
||||||
|
|
||||||
|
You have two MCP servers available:
|
||||||
|
- **esp32** (prefix: `mcp__esp32__`) — controls an ESP32 dev board via serial/UART
|
||||||
|
- **bluez** (prefix: `mcp__bluez__`) — controls the Linux BlueZ Bluetooth stack
|
||||||
|
|
||||||
|
Run ALL tests IN ORDER. For each test, report PASS or FAIL with actual response data.
|
||||||
|
If a test fails, note the error and continue with remaining tests.
|
||||||
|
|
||||||
|
**Important**: The Linux adapter is `hci1` (not hci0). Use `hci1` for all BlueZ calls.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: ESP32 Connection & System (Tests 1-4)
|
||||||
|
|
||||||
|
1. **Connect**: Call `esp32_connect` — should return connected=true AND ready=true
|
||||||
|
2. **Ping**: Call `esp32_ping` — expect `{"pong": true}`
|
||||||
|
3. **Get Info**: Call `esp32_get_info` — note the chip model, FW version, and BT MAC address (you'll need the MAC later)
|
||||||
|
4. **Get Status**: Call `esp32_status` — confirm bt_enabled=false, ble_enabled=false
|
||||||
|
|
||||||
|
## Phase 2: BlueZ Adapter Deep Dive (Tests 5-8)
|
||||||
|
|
||||||
|
5. **List Adapters**: Call `bt_list_adapters` — find the powered adapter, note its name (probably hci1)
|
||||||
|
6. **Adapter Info**: Call `bt_adapter_info` with the adapter name — report full details including the adapter's MAC address
|
||||||
|
7. **Set Pairable**: Call `bt_adapter_pairable` with adapter, on=true — enable pairing acceptance
|
||||||
|
8. **Set Discoverable**: Call `bt_adapter_discoverable` with adapter, on=true, timeout=300 — make Linux visible
|
||||||
|
|
||||||
|
## Phase 3: Classic BT + SSP Pairing (Tests 9-24)
|
||||||
|
|
||||||
|
IMPORTANT: Enable Classic BT FIRST, then configure IO capabilities.
|
||||||
|
|
||||||
|
9. **Enable Classic**: Call `esp32_classic_enable`
|
||||||
|
10. **Configure ESP32**: Call `esp32_configure` with name="SSP-Test-Device", io_cap="display_yesno"
|
||||||
|
11. **Set SSP Mode**: Call `esp32_set_ssp_mode` with mode="numeric_comparison", auto_accept=true
|
||||||
|
12. **Check Status**: Call `esp32_status` — confirm bt_enabled=true
|
||||||
|
13. **Set ESP32 Discoverable**: Call `esp32_classic_set_discoverable` with discoverable=true, timeout=120
|
||||||
|
14. **Scan from Linux**: Call `bt_scan` with adapter="hci1", mode="classic", timeout=10 — find the ESP32 by its MAC
|
||||||
|
|
||||||
|
Now initiate pairing:
|
||||||
|
|
||||||
|
15. **Check Pairing Status Before**: Call `bt_pairing_status` — should show no pending requests
|
||||||
|
16. **Start Pairing**: Call `bt_pair` with adapter="hci1", address=<ESP32 MAC>, pairing_mode="auto"
|
||||||
|
17. **Check ESP32 Pair Events**: Call `esp32_get_events` — look for pair_request and pair_complete events
|
||||||
|
18. **Verify Paired on Linux**: Call `bt_device_info` with adapter="hci1", address=<ESP32 MAC> — check paired=true
|
||||||
|
|
||||||
|
Post-pairing device management:
|
||||||
|
|
||||||
|
19. **List Known Devices**: Call `bt_list_devices` with adapter="hci1", filter="paired" — ESP32 should be in the list
|
||||||
|
20. **Trust Device**: Call `bt_trust` with adapter="hci1", address=<ESP32 MAC>, trusted=true
|
||||||
|
21. **Set Alias**: Call `bt_device_set_alias` with adapter="hci1", address=<ESP32 MAC>, alias="My ESP32 Test Device"
|
||||||
|
22. **Block Device**: Call `bt_block` with adapter="hci1", address=<ESP32 MAC>, blocked=true — block the device
|
||||||
|
23. **Unblock Device**: Call `bt_block` with adapter="hci1", address=<ESP32 MAC>, blocked=false — unblock it
|
||||||
|
24. **Unpair**: Call `bt_unpair` with adapter="hci1", address=<ESP32 MAC> — clean up pairing
|
||||||
|
|
||||||
|
## Phase 4: Classic Cleanup + Event System (Tests 25-29)
|
||||||
|
|
||||||
|
25. **Disable Classic**: Call `esp32_classic_disable`
|
||||||
|
26. **Get All Events**: Call `esp32_get_events` — report ALL events captured so far
|
||||||
|
27. **Clear Events**: Call `esp32_clear_events`
|
||||||
|
28. **Verify Cleared**: Call `esp32_get_events` — should return empty list
|
||||||
|
29. **Check Status**: Call `esp32_status` — confirm bt_enabled=false
|
||||||
|
|
||||||
|
## Phase 5: BLE GATT Setup (Tests 30-38)
|
||||||
|
|
||||||
|
Set up ESP32 as a BLE peripheral with multiple characteristics:
|
||||||
|
|
||||||
|
30. **Enable BLE**: Call `esp32_ble_enable`
|
||||||
|
31. **Add Service**: Call `esp32_gatt_add_service` with uuid="0000181a-0000-1000-8000-00805f9b34fb" (Environmental Sensing), primary=true — save the service_handle
|
||||||
|
32. **Add Read+Notify Char**: Call `esp32_gatt_add_characteristic` with the service_handle, uuid="00002a6e-0000-1000-8000-00805f9b34fb" (Temperature), properties=["read","notify"] — save as temp_handle
|
||||||
|
33. **Add Read+Write Char**: Call `esp32_gatt_add_characteristic` with the service_handle, uuid="00002a6f-0000-1000-8000-00805f9b34fb" (Humidity), properties=["read","write"] — save as humidity_handle
|
||||||
|
34. **Set Temperature**: Call `esp32_gatt_set_value` with char_handle=temp_handle, value="e803" (25.0°C)
|
||||||
|
35. **Set Humidity**: Call `esp32_gatt_set_value` with char_handle=humidity_handle, value="3200" (50%)
|
||||||
|
36. **Set Adv Data**: Call `esp32_ble_set_adv_data` with name="BLE-Sensor-Test", service_uuids=["0000181a-0000-1000-8000-00805f9b34fb"]
|
||||||
|
37. **Start Advertising**: Call `esp32_ble_advertise` with enable=true
|
||||||
|
38. **Clear Events**: Call `esp32_clear_events` — clear event history before BLE tests
|
||||||
|
|
||||||
|
## Phase 6: HCI Capture + BLE Discovery (Tests 39-47)
|
||||||
|
|
||||||
|
Start HCI packet capture BEFORE connecting, then analyze it afterwards:
|
||||||
|
|
||||||
|
39. **Start HCI Capture**: Call `bt_capture_start` with adapter="hci1", output_file="/tmp/ble-gatt-capture.btsnoop"
|
||||||
|
40. **List Active Captures**: Call `bt_capture_list_active` — verify capture is running
|
||||||
|
41. **BLE Scan**: Call `bt_ble_scan` with adapter="hci1", timeout=10 — find the ESP32, verify name="BLE-Sensor-Test"
|
||||||
|
42. **Connect BLE**: Call `bt_connect` with adapter="hci1", address=<ESP32 MAC>
|
||||||
|
|
||||||
|
Wait 3 seconds for service discovery to complete, then:
|
||||||
|
|
||||||
|
43. **List Services**: Call `bt_ble_services` with adapter="hci1", address=<ESP32 MAC> — should see Environmental Sensing (181a)
|
||||||
|
44. **List Characteristics**: Call `bt_ble_characteristics` with adapter="hci1", address=<ESP32 MAC> — should see Temperature (2a6e) and Humidity (2a6f)
|
||||||
|
45. **Read Temperature**: Call `bt_ble_read` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb" — should return hex "e803"
|
||||||
|
46. **Check Read Event on ESP32**: Call `esp32_get_events` — look for a gatt_read event
|
||||||
|
47. **Stop HCI Capture**: Call `bt_capture_stop` with capture_id from test 39
|
||||||
|
|
||||||
|
## Phase 7: Analyze HCI Capture (Tests 48-50)
|
||||||
|
|
||||||
|
48. **Parse Capture**: Call `bt_capture_parse` with filepath="/tmp/ble-gatt-capture.btsnoop", max_packets=50 — report packet count and types
|
||||||
|
49. **Analyze Capture**: Call `bt_capture_analyze` with filepath="/tmp/ble-gatt-capture.btsnoop" — report statistics
|
||||||
|
50. **Read Raw Packets**: Call `bt_capture_read_raw` with filepath="/tmp/ble-gatt-capture.btsnoop", count=20 — show decoded packets
|
||||||
|
|
||||||
|
## Phase 8: BLE GATT Write + Notifications (Tests 51-58)
|
||||||
|
|
||||||
|
51. **Write Humidity**: Call `bt_ble_write` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6f-0000-1000-8000-00805f9b34fb", value="4b00", value_type="hex"
|
||||||
|
52. **Check Write Event**: Call `esp32_get_events` — look for a gatt_write event with the written value
|
||||||
|
53. **Subscribe Notifications**: Call `bt_ble_notify` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb", enable=true
|
||||||
|
54. **Check Subscribe Event**: Call `esp32_get_events` — look for a gatt_subscribe event
|
||||||
|
55. **Push Notification**: First call `esp32_gatt_set_value` with char_handle=temp_handle, value="f401" (50.0°C), then call `esp32_gatt_notify` with char_handle=temp_handle
|
||||||
|
56. **Read Updated Value**: Call `bt_ble_read` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb" — should now return "f401"
|
||||||
|
57. **Unsubscribe**: Call `bt_ble_notify` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb", enable=false
|
||||||
|
58. **Disconnect BLE**: Call `bt_disconnect` with adapter="hci1", address=<ESP32 MAC>
|
||||||
|
|
||||||
|
## Phase 9: BLE Cleanup (Tests 59-63)
|
||||||
|
|
||||||
|
59. **Stop Advertising**: Call `esp32_ble_advertise` with enable=false
|
||||||
|
60. **Clear GATT**: Call `esp32_gatt_clear`
|
||||||
|
61. **Disable BLE**: Call `esp32_ble_disable`
|
||||||
|
62. **Final Status**: Call `esp32_status` — bt_enabled=false, ble_enabled=false
|
||||||
|
63. **Clear ESP32 Events**: Call `esp32_clear_events`
|
||||||
|
|
||||||
|
## Phase 10: Adapter Self-Management (Tests 64-68)
|
||||||
|
|
||||||
|
These tests verify adapter configuration tools. Done at the end to not interfere with earlier tests.
|
||||||
|
|
||||||
|
64. **Get Original Alias**: Call `bt_adapter_info` with adapter="hci1" — note the current alias
|
||||||
|
65. **Set New Alias**: Call `bt_adapter_set_alias` with adapter="hci1", alias="E2E-Test-Adapter" — change the name
|
||||||
|
66. **Verify Alias Changed**: Call `bt_adapter_info` with adapter="hci1" — confirm alias is "E2E-Test-Adapter"
|
||||||
|
67. **Restore Original Alias**: Call `bt_adapter_set_alias` with adapter="hci1", alias=<original alias from test 64>
|
||||||
|
68. **Disable Discoverable**: Call `bt_adapter_discoverable` with adapter="hci1", on=false — clean up
|
||||||
|
|
||||||
|
## Phase 11: Final Cleanup (Tests 69-71)
|
||||||
|
|
||||||
|
69. **Reset ESP32**: Call `esp32_reset`
|
||||||
|
70. **Disconnect Serial**: Call `esp32_disconnect`
|
||||||
|
71. **Final Adapter Check**: Call `bt_adapter_info` with adapter="hci1" — verify adapter is still powered and healthy
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
After all tests, print a DETAILED summary table:
|
||||||
|
|
||||||
|
| # | Test | Result | Notes |
|
||||||
|
|---|------|--------|-------|
|
||||||
|
| 1 | Connect | PASS/FAIL | ... |
|
||||||
|
| ... | ... | ... | ... |
|
||||||
|
|
||||||
|
Report:
|
||||||
|
- Total PASS/FAIL counts
|
||||||
|
- Whether pairing succeeded (phase 3)
|
||||||
|
- What ESP32 events were captured (phases 4, 6, 8)
|
||||||
|
- Whether GATT read returned expected value (test 45)
|
||||||
|
- Whether GATT write succeeded (test 51)
|
||||||
|
- Whether the updated value was readable after notification (test 56)
|
||||||
|
- HCI capture statistics (tests 48-50): packet count, types captured, any errors
|
||||||
170
tests/prompts/test-prompt-v5.md
Normal file
170
tests/prompts/test-prompt-v5.md
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
# ESP32 + BlueZ Full E2E Bluetooth Test Suite (v5 - Complete Coverage)
|
||||||
|
|
||||||
|
You have two MCP servers available:
|
||||||
|
- **esp32** (prefix: `mcp__esp32__`) — controls an ESP32 dev board via serial/UART
|
||||||
|
- **bluez** (prefix: `mcp__bluez__`) — controls the Linux BlueZ Bluetooth stack
|
||||||
|
|
||||||
|
Run ALL tests IN ORDER. For each test, report PASS or FAIL with actual response data.
|
||||||
|
If a test fails, note the error and continue with remaining tests.
|
||||||
|
|
||||||
|
**Important**: The Linux adapter is `hci1` (not hci0). Use `hci1` for all BlueZ calls.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: ESP32 Connection & System (Tests 1-4)
|
||||||
|
|
||||||
|
1. **Connect**: Call `esp32_connect` — should return connected=true AND ready=true
|
||||||
|
2. **Ping**: Call `esp32_ping` — expect `{"pong": true}`
|
||||||
|
3. **Get Info**: Call `esp32_get_info` — note the chip model, FW version, and BT MAC address (you'll need the MAC later)
|
||||||
|
4. **Get Status**: Call `esp32_status` — confirm bt_enabled=false, ble_enabled=false
|
||||||
|
|
||||||
|
## Phase 2: BlueZ Adapter Deep Dive (Tests 5-8)
|
||||||
|
|
||||||
|
5. **List Adapters**: Call `bt_list_adapters` — find the powered adapter, note its name (probably hci1)
|
||||||
|
6. **Adapter Info**: Call `bt_adapter_info` with the adapter name — report full details including the adapter's MAC address
|
||||||
|
7. **Set Pairable**: Call `bt_adapter_pairable` with adapter, on=true — enable pairing acceptance
|
||||||
|
8. **Set Discoverable**: Call `bt_adapter_discoverable` with adapter, on=true, timeout=300 — make Linux visible
|
||||||
|
|
||||||
|
## Phase 3: Classic BT + SSP Pairing (Tests 9-24)
|
||||||
|
|
||||||
|
IMPORTANT: Enable Classic BT FIRST, then configure IO capabilities.
|
||||||
|
|
||||||
|
9. **Enable Classic**: Call `esp32_classic_enable`
|
||||||
|
10. **Configure ESP32**: Call `esp32_configure` with name="SSP-Test-Device", io_cap="display_yesno"
|
||||||
|
11. **Set SSP Mode**: Call `esp32_set_ssp_mode` with mode="numeric_comparison", auto_accept=true
|
||||||
|
12. **Check Status**: Call `esp32_status` — confirm bt_enabled=true
|
||||||
|
13. **Set ESP32 Discoverable**: Call `esp32_classic_set_discoverable` with discoverable=true, timeout=120
|
||||||
|
14. **Scan from Linux**: Call `bt_scan` with adapter="hci1", mode="classic", timeout=10 — find the ESP32 by its MAC
|
||||||
|
|
||||||
|
Now initiate pairing:
|
||||||
|
|
||||||
|
15. **Check Pairing Status Before**: Call `bt_pairing_status` — should show no pending requests
|
||||||
|
16. **Start Pairing**: Call `bt_pair` with adapter="hci1", address=<ESP32 MAC>, pairing_mode="auto"
|
||||||
|
17. **Check ESP32 Pair Events**: Call `esp32_get_events` — look for pair_request and pair_complete events
|
||||||
|
18. **Verify Paired on Linux**: Call `bt_device_info` with adapter="hci1", address=<ESP32 MAC> — check paired=true
|
||||||
|
|
||||||
|
Post-pairing device management:
|
||||||
|
|
||||||
|
19. **List Known Devices**: Call `bt_list_devices` with adapter="hci1", filter="paired" — ESP32 should be in the list
|
||||||
|
20. **Trust Device**: Call `bt_trust` with adapter="hci1", address=<ESP32 MAC>, trusted=true
|
||||||
|
21. **Set Alias**: Call `bt_device_set_alias` with adapter="hci1", address=<ESP32 MAC>, alias="My ESP32 Test Device"
|
||||||
|
22. **Block Device**: Call `bt_block` with adapter="hci1", address=<ESP32 MAC>, blocked=true — block the device
|
||||||
|
23. **Unblock Device**: Call `bt_block` with adapter="hci1", address=<ESP32 MAC>, blocked=false — unblock it
|
||||||
|
24. **Unpair**: Call `bt_unpair` with adapter="hci1", address=<ESP32 MAC> — clean up pairing
|
||||||
|
|
||||||
|
## Phase 4: Classic Cleanup + Event System (Tests 25-29)
|
||||||
|
|
||||||
|
25. **Disable Classic**: Call `esp32_classic_disable`
|
||||||
|
26. **Get All Events**: Call `esp32_get_events` — report ALL events captured so far
|
||||||
|
27. **Clear Events**: Call `esp32_clear_events`
|
||||||
|
28. **Verify Cleared**: Call `esp32_get_events` — should return empty list
|
||||||
|
29. **Check Status**: Call `esp32_status` — confirm bt_enabled=false
|
||||||
|
|
||||||
|
## Phase 5: BLE GATT Setup with Battery Service (Tests 30-42)
|
||||||
|
|
||||||
|
Set up ESP32 as a BLE peripheral with Environmental Sensing AND Battery Service:
|
||||||
|
|
||||||
|
30. **Enable BLE**: Call `esp32_ble_enable`
|
||||||
|
|
||||||
|
First, add Battery Service (0x180F) for bt_ble_battery test:
|
||||||
|
|
||||||
|
31. **Add Battery Service**: Call `esp32_gatt_add_service` with uuid="0000180f-0000-1000-8000-00805f9b34fb" (Battery Service), primary=true — save as battery_svc_handle
|
||||||
|
32. **Add Battery Level Char**: Call `esp32_gatt_add_characteristic` with service_handle=battery_svc_handle, uuid="00002a19-0000-1000-8000-00805f9b34fb" (Battery Level), properties=["read"] — save as battery_char_handle
|
||||||
|
33. **Set Battery Level**: Call `esp32_gatt_set_value` with char_handle=battery_char_handle, value="4b" (75%)
|
||||||
|
|
||||||
|
Now add Environmental Sensing Service:
|
||||||
|
|
||||||
|
34. **Add Env Service**: Call `esp32_gatt_add_service` with uuid="0000181a-0000-1000-8000-00805f9b34fb" (Environmental Sensing), primary=true — save as env_svc_handle
|
||||||
|
35. **Add Temperature Char**: Call `esp32_gatt_add_characteristic` with service_handle=env_svc_handle, uuid="00002a6e-0000-1000-8000-00805f9b34fb" (Temperature), properties=["read","notify"] — save as temp_handle
|
||||||
|
36. **Add Humidity Char**: Call `esp32_gatt_add_characteristic` with service_handle=env_svc_handle, uuid="00002a6f-0000-1000-8000-00805f9b34fb" (Humidity), properties=["read","write"] — save as humidity_handle
|
||||||
|
37. **Set Temperature**: Call `esp32_gatt_set_value` with char_handle=temp_handle, value="e803" (25.0°C)
|
||||||
|
38. **Set Humidity**: Call `esp32_gatt_set_value` with char_handle=humidity_handle, value="3200" (50%)
|
||||||
|
|
||||||
|
Configure advertising:
|
||||||
|
|
||||||
|
39. **Set Adv Data**: Call `esp32_ble_set_adv_data` with name="BLE-Sensor-Test", service_uuids=["0000180f-0000-1000-8000-00805f9b34fb", "0000181a-0000-1000-8000-00805f9b34fb"]
|
||||||
|
40. **Start Advertising**: Call `esp32_ble_advertise` with enable=true
|
||||||
|
41. **Clear Events**: Call `esp32_clear_events` — clear event history before BLE tests
|
||||||
|
42. **Check BLE Status**: Call `esp32_status` — confirm ble_enabled=true
|
||||||
|
|
||||||
|
## Phase 6: HCI Capture + BLE Discovery (Tests 43-51)
|
||||||
|
|
||||||
|
Start HCI packet capture BEFORE connecting:
|
||||||
|
|
||||||
|
43. **Start HCI Capture**: Call `bt_capture_start` with adapter="hci1", output_file="/tmp/ble-gatt-capture.btsnoop"
|
||||||
|
44. **List Active Captures**: Call `bt_capture_list_active` — verify capture is running
|
||||||
|
45. **BLE Scan**: Call `bt_ble_scan` with adapter="hci1", timeout=10 — find the ESP32, verify name="BLE-Sensor-Test"
|
||||||
|
46. **Connect BLE**: Call `bt_connect` with adapter="hci1", address=<ESP32 MAC>
|
||||||
|
|
||||||
|
Wait 3 seconds for service discovery to complete, then:
|
||||||
|
|
||||||
|
47. **List Services**: Call `bt_ble_services` with adapter="hci1", address=<ESP32 MAC> — should see Battery (180f) and Environmental Sensing (181a)
|
||||||
|
48. **List Characteristics**: Call `bt_ble_characteristics` with adapter="hci1", address=<ESP32 MAC> — should see Battery Level (2a19), Temperature (2a6e), Humidity (2a6f)
|
||||||
|
49. **Read Battery Level**: Call `bt_ble_battery` with adapter="hci1", address=<ESP32 MAC> — should return 75 (the value we set as "4b")
|
||||||
|
50. **Read Temperature**: Call `bt_ble_read` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb" — should return hex "e803"
|
||||||
|
51. **Check Read Events**: Call `esp32_get_events` — look for gatt_read events
|
||||||
|
|
||||||
|
Stop capture for analysis:
|
||||||
|
|
||||||
|
## Phase 7: Analyze HCI Capture (Tests 52-55)
|
||||||
|
|
||||||
|
52. **Stop HCI Capture**: Call `bt_capture_stop` with capture_id from test 43
|
||||||
|
53. **Parse Capture**: Call `bt_capture_parse` with filepath="/tmp/ble-gatt-capture.btsnoop", max_packets=50 — report packet count and types
|
||||||
|
54. **Analyze Capture**: Call `bt_capture_analyze` with filepath="/tmp/ble-gatt-capture.btsnoop" — report statistics
|
||||||
|
55. **Read Raw Packets**: Call `bt_capture_read_raw` with filepath="/tmp/ble-gatt-capture.btsnoop", count=20 — show decoded packets
|
||||||
|
|
||||||
|
## Phase 8: BLE GATT Write + Notifications (Tests 56-63)
|
||||||
|
|
||||||
|
56. **Write Humidity**: Call `bt_ble_write` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6f-0000-1000-8000-00805f9b34fb", value="4b00", value_type="hex"
|
||||||
|
57. **Check Write Event**: Call `esp32_get_events` — look for a gatt_write event with the written value
|
||||||
|
58. **Subscribe Notifications**: Call `bt_ble_notify` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb", enable=true
|
||||||
|
59. **Check Subscribe Event**: Call `esp32_get_events` — look for a gatt_subscribe event
|
||||||
|
60. **Push Notification**: First call `esp32_gatt_set_value` with char_handle=temp_handle, value="f401" (50.0°C), then call `esp32_gatt_notify` with char_handle=temp_handle
|
||||||
|
61. **Read Updated Value**: Call `bt_ble_read` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb" — should now return "f401"
|
||||||
|
62. **Unsubscribe**: Call `bt_ble_notify` with adapter="hci1", address=<ESP32 MAC>, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb", enable=false
|
||||||
|
63. **Disconnect BLE**: Call `bt_disconnect` with adapter="hci1", address=<ESP32 MAC>
|
||||||
|
|
||||||
|
## Phase 9: BLE Cleanup (Tests 64-68)
|
||||||
|
|
||||||
|
64. **Stop Advertising**: Call `esp32_ble_advertise` with enable=false
|
||||||
|
65. **Clear GATT**: Call `esp32_gatt_clear`
|
||||||
|
66. **Disable BLE**: Call `esp32_ble_disable`
|
||||||
|
67. **Final Status**: Call `esp32_status` — bt_enabled=false, ble_enabled=false
|
||||||
|
68. **Clear ESP32 Events**: Call `esp32_clear_events`
|
||||||
|
|
||||||
|
## Phase 10: Adapter Self-Management (Tests 69-73)
|
||||||
|
|
||||||
|
These tests verify adapter configuration tools. Done at the end to not interfere with earlier tests.
|
||||||
|
|
||||||
|
69. **Get Original Alias**: Call `bt_adapter_info` with adapter="hci1" — note the current alias
|
||||||
|
70. **Set New Alias**: Call `bt_adapter_set_alias` with adapter="hci1", alias="E2E-Test-Adapter" — change the name
|
||||||
|
71. **Verify Alias Changed**: Call `bt_adapter_info` with adapter="hci1" — confirm alias is "E2E-Test-Adapter"
|
||||||
|
72. **Restore Original Alias**: Call `bt_adapter_set_alias` with adapter="hci1", alias=<original alias from test 69>
|
||||||
|
73. **Disable Discoverable**: Call `bt_adapter_discoverable` with adapter="hci1", on=false — clean up
|
||||||
|
|
||||||
|
## Phase 11: Final Cleanup (Tests 74-76)
|
||||||
|
|
||||||
|
74. **Reset ESP32**: Call `esp32_reset`
|
||||||
|
75. **Disconnect Serial**: Call `esp32_disconnect`
|
||||||
|
76. **Final Adapter Check**: Call `bt_adapter_info` with adapter="hci1" — verify adapter is still powered and healthy
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
After all tests, print a DETAILED summary table:
|
||||||
|
|
||||||
|
| # | Test | Result | Notes |
|
||||||
|
|---|------|--------|-------|
|
||||||
|
| 1 | Connect | PASS/FAIL | ... |
|
||||||
|
| ... | ... | ... | ... |
|
||||||
|
|
||||||
|
Report:
|
||||||
|
- Total PASS/FAIL counts
|
||||||
|
- Whether pairing succeeded (phase 3)
|
||||||
|
- What ESP32 events were captured (phases 4, 6, 8)
|
||||||
|
- Whether bt_ble_battery returned the expected value 75 (test 49)
|
||||||
|
- Whether GATT read returned expected value (test 50)
|
||||||
|
- Whether GATT write succeeded (test 56)
|
||||||
|
- Whether the updated value was readable after notification (test 61)
|
||||||
|
- HCI capture statistics (tests 53-55): packet count, types captured, any errors
|
||||||
Loading…
x
Reference in New Issue
Block a user