Files
esp-idf/examples/bluetooth/PYTEST_DUAL_DUT_CI_IDS.md
2026-08-12 15:46:14 +08:00

6.5 KiB

Dual-DUT Pytest CI Example IDs

Dual-DUT CI tests pair devices by advertising name. When CI config is enabled, the device name format is:

BE<EXAMPLE_ID>_<PIPELINE_ID>_<CHIP_ID>
  • Example IDCONFIG_EXAMPLE_CI_ID; distinguishes test scenarios so unrelated examples on the same pipeline do not connect by mistake.
  • Pipeline IDCONFIG_EXAMPLE_CI_PIPELINE_ID (in CI: ${CI_PIPELINE_ID}).
  • Chip IDCONFIG_IDF_FIRMWARE_CHIP_ID; the suffix keeps the same Example ID distinct across chips.

CI device naming is disabled when CONFIG_EXAMPLE_CI_PIPELINE_ID=0 (Kconfig default).


Why register IDs

pytest randomly picks two boards from the test environment to flash and run. MAC addresses are unknown beforehand, so dual-DUT tests can only find each other by device name. Names must be unique, or boards may pair with the wrong peer.

CONFIG_EXAMPLE_CI_ID and CONFIG_EXAMPLE_CI_PIPELINE_ID (plus chip ID) form BE<EXAMPLE_ID>_<PIPELINE_ID>_<CHIP_ID>, so different pipelines, chips, and examples all use distinct names during testing.

CI runners often run many dual-DUT tests in parallel. Registering allocated Example IDs in this file also avoids:

  • Reusing an existing ID for a new test and pairing with the wrong peer;
  • ID conflicts when several developers add tests at the same time.

Before adding a new dual-DUT pytest, take max allocated ID + 1 from the table below and append a row before merging.


Allocated IDs

Paths are relative to examples/bluetooth/. Bluedroid uses esp_bluedroid_get_example_name(); NimBLE uses esp_ble_cte_get_example_name() and similar helpers.

ID Example pair (server/adv → client/sync) Pytest
1 bluedroid/ble/ble_throughput/throughput_server / throughput_client (notify) ble/ble_throughput/pytest_ble_throughput_test.py
2 same pair (write) same
3 bluedroid/ble/gatt_server / gatt_client (name) bluedroid/ble/pytest_ble_test.py
4 same pair (cfg_test) same
5 bluedroid/ble/gatt_security_server / gatt_security_client (name) same
6 bluedroid/ble_50/ble50_security_server / ble50_security_client (name) bluedroid/ble_50/pytest_ble50_test.py
7 same pair (cfg_test) same
8 bluedroid/ble_50/periodic_adv / periodic_sync same
9 bluedroid/ble/gatt_server / gatt_client (smp_off) bluedroid/ble/pytest_ble_test.py
10 same pair (min_bin) same
11 same pair (log_off) same
12 bluedroid/ble/gatt_security_server / gatt_security_client (min_bin) same
13 same pair (log_off) same
14 bluedroid/ble_50/ble50_security_server / ble50_security_client (min_bin) — (sdkconfig only)
15 same pair (log_off) — (sdkconfig only)
16 bluedroid/ble/ble_spp_server / ble_spp_client bluedroid/ble/pytest_ble_test.py
17 bluedroid/ble_50/ble_power_control_peripheral / ble_power_control_central bluedroid/ble_50/pytest_ble50_test.py
18 bluedroid/ble_50/ble_conn_subrating_peripheral / ble_conn_subrating_central same
19 bluedroid/ble_50/ble_periodic_adv_with_cte / ble_periodic_sync_with_cte same
20 bluedroid/ble_50/ble_connection_peripheral_with_cte / ble_connection_central_with_cte same
21 bluedroid/ble_50/ble_pawr_advertiser / ble_pawr_synchronizer (name) same
22 bluedroid/ble_50/ble_pawr_advertiser_conn / ble_pawr_synchronizer (conn_name) same
23 bluedroid/ble_50/ble50_throughput/throughput_server / throughput_client (notify) bluedroid/ble_50/ble50_throughput/pytest_ble50_throughput_test.py
24 same pair (write) same
25 nimble/ble_cte/ble_periodic_adv_with_cte / ble_periodic_sync_with_cte nimble/pytest_nimble_test.py
26 nimble/ble_cts/cts_prph / cts_cent nimble/pytest_nimble_test.py
27 nimble/ble_htp/htp_prph / htp_cent nimble/pytest_nimble_test.py
28 nimble/ble_spp/spp_server / spp_client nimble/pytest_nimble_test.py
29 nimble/ble_multi_conn/ble_multi_conn_prph / ble_multi_conn_cent nimble/pytest_nimble_test.py
30 nimble/ble_phy/phy_prph / phy_cent nimble/pytest_nimble_test.py
31 nimble/ble_pawr_adv_conn/ble_pawr_adv_conn / ble_pawr_sync_conn nimble/pytest_nimble_test.py
32 nimble/ble_pawr_adv/ble_pawr_adv / ble_pawr_sync nimble/pytest_nimble_test.py
33 nimble/ble_proximity_sensor (name / esp32c2_xtal26m) nimble/pytest_nimble_test.py
34 nimble/ble_proximity_sensor (conn_with_scan / esp32c2_xtal26m_conn_with_scan) same
35 nimble/ble_proximity_sensor (name_v4 / esp32c2_xtal26m_name_v4) same
36 nimble/ble_proximity_sensor (conn_with_scan_v4 / esp32c2_xtal26m_conn_with_scan_v4) same
37 nimble/ble_proximity_sensor (esp32_name_v4) same
38 nimble/ble_periodic_adv / ble_periodic_sync nimble/pytest_nimble_test.py
39 nimble/bleprph / blecent nimble/pytest_nimble_test.py
40 nimble/throughput_app/gatt/bleprph_throughput / blecent_throughput nimble/pytest_nimble_test.py
41 nimble/ble_l2cap_coc/coc_bleprph / coc_blecent nimble/pytest_nimble_test.py
42 nimble/throughput_app/l2cap_coc/l2cap_coc_prph / l2cap_coc_cent nimble/pytest_nimble_test.py

Next available Example ID: 43


Notes

  • Both boards in a dual-DUT test must use the same CONFIG_EXAMPLE_CI_ID and the same sdkconfig.ci.<config> basename.
  • Set CONFIG_EXAMPLE_CI_PIPELINE_ID=${CI_PIPELINE_ID} in every CI sdkconfig; run export CI_PIPELINE_ID=... locally before idf-ci build and pytest, using the same value for both commands.
  • Different sdkconfig.ci.* files for the same example must use different Example IDs, e.g. gatt_server / gatt_client: name (ID 3), min_bin (ID 10), log_off (ID 11), smp_off (ID 9)—do not reuse the default name ID.
  • Some examples may pair with more than one peer example; use separate sdkconfig.ci.* configs and a distinct Example ID for each pairing so device names stay unique. For example, ble_pawr_synchronizer uses name (ID 21) with ble_pawr_advertiser and conn_name (ID 22) with ble_pawr_advertiser_conn.
  • Single-board tests do not need CI device names: no CONFIG_EXAMPLE_CI_ID / CONFIG_EXAMPLE_CI_PIPELINE_ID and no row in this table. For example, bluedroid/ble_50/multi-adv is a single-board smoke test with no dual-DUT pairing.