- 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
10 KiB
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)
- Connect: Call
esp32_connect— should return connected=true AND ready=true - Ping: Call
esp32_ping— expect{"pong": true} - Get Info: Call
esp32_get_info— note the chip model, FW version, and BT MAC address (you'll need the MAC later) - Get Status: Call
esp32_status— confirm bt_enabled=false, ble_enabled=false
Phase 2: BlueZ Adapter Deep Dive (Tests 5-8)
- List Adapters: Call
bt_list_adapters— find the powered adapter, note its name (probably hci1) - Adapter Info: Call
bt_adapter_infowith the adapter name — report full details including the adapter's MAC address - Set Pairable: Call
bt_adapter_pairablewith adapter, on=true — enable pairing acceptance - Set Discoverable: Call
bt_adapter_discoverablewith 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.
- Enable Classic: Call
esp32_classic_enable - Configure ESP32: Call
esp32_configurewith name="SSP-Test-Device", io_cap="display_yesno" - Set SSP Mode: Call
esp32_set_ssp_modewith mode="numeric_comparison", auto_accept=true - Check Status: Call
esp32_status— confirm bt_enabled=true - Set ESP32 Discoverable: Call
esp32_classic_set_discoverablewith discoverable=true, timeout=120 - Scan from Linux: Call
bt_scanwith adapter="hci1", mode="classic", timeout=10 — find the ESP32 by its MAC
Now initiate pairing:
- Check Pairing Status Before: Call
bt_pairing_status— should show no pending requests - Start Pairing: Call
bt_pairwith adapter="hci1", address=, pairing_mode="auto" - Check ESP32 Pair Events: Call
esp32_get_events— look for pair_request and pair_complete events - Verify Paired on Linux: Call
bt_device_infowith adapter="hci1", address= — check paired=true
Post-pairing device management:
- List Known Devices: Call
bt_list_deviceswith adapter="hci1", filter="paired" — ESP32 should be in the list - Trust Device: Call
bt_trustwith adapter="hci1", address=, trusted=true - Set Alias: Call
bt_device_set_aliaswith adapter="hci1", address=, alias="My ESP32 Test Device" - Block Device: Call
bt_blockwith adapter="hci1", address=, blocked=true — block the device - Unblock Device: Call
bt_blockwith adapter="hci1", address=, blocked=false — unblock it - Unpair: Call
bt_unpairwith adapter="hci1", address= — clean up pairing
Phase 4: Classic Cleanup + Event System (Tests 25-29)
- Disable Classic: Call
esp32_classic_disable - Get All Events: Call
esp32_get_events— report ALL events captured so far - Clear Events: Call
esp32_clear_events - Verify Cleared: Call
esp32_get_events— should return empty list - 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:
- Enable BLE: Call
esp32_ble_enable
First, add Battery Service (0x180F) for bt_ble_battery test:
- Add Battery Service: Call
esp32_gatt_add_servicewith uuid="0000180f-0000-1000-8000-00805f9b34fb" (Battery Service), primary=true — save as battery_svc_handle - Add Battery Level Char: Call
esp32_gatt_add_characteristicwith service_handle=battery_svc_handle, uuid="00002a19-0000-1000-8000-00805f9b34fb" (Battery Level), properties=["read"] — save as battery_char_handle - Set Battery Level: Call
esp32_gatt_set_valuewith char_handle=battery_char_handle, value="4b" (75%)
Now add Environmental Sensing Service:
- Add Env Service: Call
esp32_gatt_add_servicewith uuid="0000181a-0000-1000-8000-00805f9b34fb" (Environmental Sensing), primary=true — save as env_svc_handle - Add Temperature Char: Call
esp32_gatt_add_characteristicwith service_handle=env_svc_handle, uuid="00002a6e-0000-1000-8000-00805f9b34fb" (Temperature), properties=["read","notify"] — save as temp_handle - Add Humidity Char: Call
esp32_gatt_add_characteristicwith service_handle=env_svc_handle, uuid="00002a6f-0000-1000-8000-00805f9b34fb" (Humidity), properties=["read","write"] — save as humidity_handle - Set Temperature: Call
esp32_gatt_set_valuewith char_handle=temp_handle, value="e803" (25.0°C) - Set Humidity: Call
esp32_gatt_set_valuewith char_handle=humidity_handle, value="3200" (50%)
Configure advertising:
- Set Adv Data: Call
esp32_ble_set_adv_datawith name="BLE-Sensor-Test", service_uuids=["0000180f-0000-1000-8000-00805f9b34fb", "0000181a-0000-1000-8000-00805f9b34fb"] - Start Advertising: Call
esp32_ble_advertisewith enable=true - Clear Events: Call
esp32_clear_events— clear event history before BLE tests - 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:
- Start HCI Capture: Call
bt_capture_startwith adapter="hci1", output_file="/tmp/ble-gatt-capture.btsnoop" - List Active Captures: Call
bt_capture_list_active— verify capture is running - BLE Scan: Call
bt_ble_scanwith adapter="hci1", timeout=10 — find the ESP32, verify name="BLE-Sensor-Test" - Connect BLE: Call
bt_connectwith adapter="hci1", address=
Wait 3 seconds for service discovery to complete, then:
- List Services: Call
bt_ble_serviceswith adapter="hci1", address= — should see Battery (180f) and Environmental Sensing (181a) - List Characteristics: Call
bt_ble_characteristicswith adapter="hci1", address= — should see Battery Level (2a19), Temperature (2a6e), Humidity (2a6f) - Read Battery Level: Call
bt_ble_batterywith adapter="hci1", address= — should return 75 (the value we set as "4b") - Read Temperature: Call
bt_ble_readwith adapter="hci1", address=, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb" — should return hex "e803" - Check Read Events: Call
esp32_get_events— look for gatt_read events
Stop capture for analysis:
Phase 7: Analyze HCI Capture (Tests 52-55)
- Stop HCI Capture: Call
bt_capture_stopwith capture_id from test 43 - Parse Capture: Call
bt_capture_parsewith filepath="/tmp/ble-gatt-capture.btsnoop", max_packets=50 — report packet count and types - Analyze Capture: Call
bt_capture_analyzewith filepath="/tmp/ble-gatt-capture.btsnoop" — report statistics - Read Raw Packets: Call
bt_capture_read_rawwith filepath="/tmp/ble-gatt-capture.btsnoop", count=20 — show decoded packets
Phase 8: BLE GATT Write + Notifications (Tests 56-63)
- Write Humidity: Call
bt_ble_writewith adapter="hci1", address=, char_uuid="00002a6f-0000-1000-8000-00805f9b34fb", value="4b00", value_type="hex" - Check Write Event: Call
esp32_get_events— look for a gatt_write event with the written value - Subscribe Notifications: Call
bt_ble_notifywith adapter="hci1", address=, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb", enable=true - Check Subscribe Event: Call
esp32_get_events— look for a gatt_subscribe event - Push Notification: First call
esp32_gatt_set_valuewith char_handle=temp_handle, value="f401" (50.0°C), then callesp32_gatt_notifywith char_handle=temp_handle - Read Updated Value: Call
bt_ble_readwith adapter="hci1", address=, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb" — should now return "f401" - Unsubscribe: Call
bt_ble_notifywith adapter="hci1", address=, char_uuid="00002a6e-0000-1000-8000-00805f9b34fb", enable=false - Disconnect BLE: Call
bt_disconnectwith adapter="hci1", address=
Phase 9: BLE Cleanup (Tests 64-68)
- Stop Advertising: Call
esp32_ble_advertisewith enable=false - Clear GATT: Call
esp32_gatt_clear - Disable BLE: Call
esp32_ble_disable - Final Status: Call
esp32_status— bt_enabled=false, ble_enabled=false - 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.
- Get Original Alias: Call
bt_adapter_infowith adapter="hci1" — note the current alias - Set New Alias: Call
bt_adapter_set_aliaswith adapter="hci1", alias="E2E-Test-Adapter" — change the name - Verify Alias Changed: Call
bt_adapter_infowith adapter="hci1" — confirm alias is "E2E-Test-Adapter" - Restore Original Alias: Call
bt_adapter_set_aliaswith adapter="hci1", alias=<original alias from test 69> - Disable Discoverable: Call
bt_adapter_discoverablewith adapter="hci1", on=false — clean up
Phase 11: Final Cleanup (Tests 74-76)
- Reset ESP32: Call
esp32_reset - Disconnect Serial: Call
esp32_disconnect - Final Adapter Check: Call
bt_adapter_infowith 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