testing: Add split BLE tests (#2737)

* Enhance the BLE test runner to build additional peripheral builds
  when detecting peripheral*.overlay files in the test.
* Add basic and multiple-peripheral tests to exercise the testing
  support
* Add test for triggering local behaviors on split peripherals.

fix(ble): Fix building split code w/o settings

* Properly exclude storing peripheral addresses to settings when
  settings support isn't turned on.
This commit is contained in:
Pete Johanson 2025-01-01 16:13:47 -07:00 committed by GitHub
parent 3f6841c95f
commit 85aba16eec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 216 additions and 5 deletions

View File

@ -58,7 +58,25 @@ fi
testcase="$path"
echo "Running $testcase:"
west build -d build/$testcase -b nrf52_bsim -- -DZMK_CONFIG="$(pwd)/$testcase" > /dev/null 2>&1
shopt -s nullglob
for file in $(pwd)/$testcase/peripheral*.overlay ; do
pn=$(basename -s .overlay ${file})
west build -d build/${testcase%%/}_${pn}/ -b nrf52_bsim -- -DZMK_CONFIG="$(pwd)/$testcase" -DEXTRA_DTC_OVERLAY_FILE="${file}" > /dev/null 2>&1
if [ $? -gt 0 ]; then
echo "FAILED: $testcase peripheral ${pn} did not build" | tee -a ./build/tests/pass-fail.log
exit 1
fi
done
shopt -u nullglob
extra_cmake_args=""
if ls $(pwd)/$testcase/peripheral*.overlay >/dev/null 2>&1; then
echo "Found peripheral overlays, building the test as a split central"
extra_cmake_args="-DCONFIG_ZMK_SPLIT_ROLE_CENTRAL=y"
fi
west build -d build/$testcase -b nrf52_bsim -- -DZMK_CONFIG="$(pwd)/$testcase" ${extra_cmake_args} > /dev/null 2>&1
if [ $? -gt 0 ]; then
echo "FAILED: $testcase did not build" | tee -a ./build/tests/pass-fail.log
exit 1
@ -71,25 +89,35 @@ else
fi
exe_name=${testcase//\//_}
# Remove trailing underscores
exe_name=${exe_name%%_}
start_dir=$(pwd)
cp build/$testcase/zephyr/zmk.exe "${BSIM_OUT_PATH}/bin/${exe_name}"
shopt -s nullglob
for file in $(pwd)/$testcase/peripheral*.overlay ; do
pn=$(basename -s .overlay ${file})
cp ./build/${testcase%%/}_${pn}/zephyr/zmk.exe "${BSIM_OUT_PATH}/bin/${exe_name}_${pn}.exe"
done
shopt -u nullglob
pushd "${BSIM_OUT_PATH}/bin" > /dev/null 2>&1
if [ -e "${start_dir}/build/$testcase/output.log" ]; then
rm "${start_dir}/build/$testcase/output.log"
fi
central_counts=$(wc -l ${start_dir}/${testcase}/centrals.txt | cut -d' ' -f1)
sibling_counts=$(wc -l ${start_dir}/${testcase}/siblings.txt | cut -d' ' -f1)
./${exe_name} -d=0 -s=${exe_name} | tee -a "${start_dir}/build/$testcase/output.log" > "${output_dev}" &
./bs_device_handbrake -s=${exe_name} -d=1 -r=10 > "${output_dev}" &
cat "${start_dir}/${testcase}/centrals.txt" |
cat "${start_dir}/${testcase}/siblings.txt" |
while IFS= read -r line
do
${line} -s=${exe_name} | tee -a "${start_dir}/build/$testcase/output.log" > "${output_dev}" &
done
./bs_2G4_phy_v1 -s=${exe_name} -D=$(( 2 + central_counts )) -sim_length=50e6 > "${output_dev}" 2>&1
./bs_2G4_phy_v1 -s=${exe_name} -D=$(( 2 + sibling_counts )) -sim_length=50e6 > "${output_dev}" 2>&1
popd > /dev/null 2>&1

View File

@ -379,10 +379,11 @@ int zmk_ble_put_peripheral_addr(const bt_addr_le_t *addr) {
LOG_DBG("Storing peripheral %s in slot %d", addr_str, i);
bt_addr_le_copy(&peripheral_addrs[i], addr);
#if IS_ENABLED(CONFIG_SETTINGS)
char setting_name[32];
sprintf(setting_name, "ble/peripheral_addresses/%d", i);
settings_save_one(setting_name, addr, sizeof(bt_addr_le_t));
#endif // IS_ENABLED(CONFIG_SETTINGS)
return i;
}
}

View File

@ -0,0 +1 @@
s/^d_02: @[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9][0-9][0-9][0-9] .{19}/profile 0 /p

View File

@ -0,0 +1 @@
CONFIG_ZMK_SPLIT=y

View File

@ -0,0 +1,19 @@
#include <behaviors.dtsi>
#include <dt-bindings/zmk/bt.h>
#include <dt-bindings/zmk/keys.h>
&kscan {
/delete-property/ exit-after;
events = <>;
};
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&kp A &kp B
&bt BT_SEL 0 &bt BT_CLR>;
};
};
};

View File

@ -0,0 +1,12 @@
#include <dt-bindings/zmk/kscan_mock.h>
&kscan {
events =
<ZMK_MOCK_RELEASE(0,0,5000)
ZMK_MOCK_PRESS(0,0,5000)
ZMK_MOCK_RELEASE(0,0,200)
ZMK_MOCK_PRESS(0,1,10)
ZMK_MOCK_RELEASE(0,1,2000)>;
};

View File

@ -0,0 +1,2 @@
./ble_test_central.exe -d=2
./tests_ble_split_basic_peripheral.exe -d=3

View File

@ -0,0 +1,23 @@
profile 0 <wrn> bt_id: No static addresses stored in controller
profile 0 <dbg> ble_central: main: [Bluetooth initialized]
profile 0 <dbg> ble_central: start_scan: [Scanning successfully started]
profile 0 <dbg> ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -56
profile 0 <dbg> ble_central: eir_found: [AD]: 25 data_len 2
profile 0 <dbg> ble_central: eir_found: [AD]: 1 data_len 1
profile 0 <dbg> ble_central: eir_found: [AD]: 2 data_len 4
profile 0 <dbg> ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random)
profile 0 <dbg> ble_central: connected: [Setting the security for the connection]
profile 0 <dbg> ble_central: pairing_complete: Pairing complete
profile 0 <dbg> ble_central: discover_conn: [Discovery started for conn]
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 23
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
profile 0 <dbg> ble_central: discover_func: [SUBSCRIBED]
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 04 00 00 00 00 00 |........
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 00 00 00 00 00 00 |........
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 05 00 00 00 00 00 |........
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 00 00 00 00 00 00 |........

View File

@ -0,0 +1 @@
s/^d_02: @[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9][0-9][0-9][0-9] .{19}/profile 0 /p

View File

@ -0,0 +1,2 @@
CONFIG_ZMK_SPLIT=y
CONFIG_ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS=2

View File

@ -0,0 +1,19 @@
#include <behaviors.dtsi>
#include <dt-bindings/zmk/bt.h>
#include <dt-bindings/zmk/keys.h>
&kscan {
/delete-property/ exit-after;
events = <>;
};
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&kp A &kp B
&bt BT_SEL 0 &bt BT_CLR>;
};
};
};

View File

@ -0,0 +1,10 @@
#include <dt-bindings/zmk/kscan_mock.h>
&kscan {
events =
<ZMK_MOCK_RELEASE(0,0,3000)
ZMK_MOCK_PRESS(0,1,5000)
ZMK_MOCK_RELEASE(0,1,200)>;
};

View File

@ -0,0 +1,10 @@
#include <dt-bindings/zmk/kscan_mock.h>
&kscan {
events =
<ZMK_MOCK_RELEASE(0,0,5000)
ZMK_MOCK_PRESS(0,0,5000)
ZMK_MOCK_RELEASE(0,0,200)>;
};

View File

@ -0,0 +1,3 @@
./ble_test_central.exe -d=2
./tests_ble_split_multiple-peripherals_peripheral1.exe -d=3
./tests_ble_split_multiple-peripherals_peripheral2.exe -d=4

View File

@ -0,0 +1,23 @@
profile 0 <wrn> bt_id: No static addresses stored in controller
profile 0 <dbg> ble_central: main: [Bluetooth initialized]
profile 0 <dbg> ble_central: start_scan: [Scanning successfully started]
profile 0 <dbg> ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -55
profile 0 <dbg> ble_central: eir_found: [AD]: 25 data_len 2
profile 0 <dbg> ble_central: eir_found: [AD]: 1 data_len 1
profile 0 <dbg> ble_central: eir_found: [AD]: 2 data_len 4
profile 0 <dbg> ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random)
profile 0 <dbg> ble_central: connected: [Setting the security for the connection]
profile 0 <dbg> ble_central: pairing_complete: Pairing complete
profile 0 <dbg> ble_central: discover_conn: [Discovery started for conn]
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 23
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
profile 0 <dbg> ble_central: discover_func: [SUBSCRIBED]
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 05 00 00 00 00 00 |........
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 05 04 00 00 00 00 |........
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 00 04 00 00 00 00 |........
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 00 00 00 00 00 00 |........

View File

@ -0,0 +1 @@
s/^d_03: @[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9][0-9][0-9][0-9] .{19}/peripheral 0 /p

View File

@ -0,0 +1 @@
CONFIG_ZMK_SPLIT=y

View File

@ -0,0 +1,19 @@
#include <behaviors.dtsi>
#include <dt-bindings/zmk/bt.h>
#include <dt-bindings/zmk/keys.h>
&kscan {
/delete-property/ exit-after;
events = <>;
};
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&kp A &kp B
&kp C &sys_reset>;
};
};
};

View File

@ -0,0 +1,10 @@
#include <dt-bindings/zmk/kscan_mock.h>
&kscan {
events =
<ZMK_MOCK_RELEASE(0,0,5000)
ZMK_MOCK_PRESS(1,1,5000)
ZMK_MOCK_RELEASE(1,1,200)>;
};

View File

@ -0,0 +1,2 @@
./ble_test_central.exe -d=2
./tests_ble_split_run-peripheral-behavior_peripheral.exe -d=3

View File

@ -0,0 +1,23 @@
peripheral 0 OS build 702e50c58f67 ***
peripheral 0 <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
peripheral 0 <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
peripheral 0 <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 3.5 Build 0
peripheral 0 <wrn> bt_id: No static addresses stored in controller
peripheral 0 <inf> bt_hci_core: Identity: D1:0B:03:A3:ED:6F (random)
peripheral 0 <inf> bt_hci_core: HCI: version 5.4 (0x0d) revision 0x0000, manufacturer 0x05f1
peripheral 0 <inf> bt_hci_core: LMP: version 5.4 (0x0d) subver 0xffff
peripheral 0 <dbg> zmk: kscan_mock_schedule_next_event_0: delaying next keypress: 5000
peripheral 0 <inf> zmk: Welcome to ZMK!
peripheral 0 <dbg> zmk: security_changed: Security changed: FD:9E:B2:48:47:39 (random) level 2
peripheral 0 <dbg> zmk: split_svc_pos_state_ccc: value 1
peripheral 0 <dbg> zmk: split_svc_select_phys_layout_callback: Selecting physical layout after GATT write of 0
peripheral 0 <dbg> zmk: kscan_mock_work_handler_0: ev 327680000 row 0 column 0 state 0
peripheral 0 <dbg> zmk: kscan_mock_schedule_next_event_0: delaying next keypress: 5000
peripheral 0 <dbg> zmk: zmk_physical_layouts_kscan_process_msgq: Row: 0, col: 0, position: 0, pressed: false
peripheral 0 <dbg> zmk: split_listener:
peripheral 0 <dbg> zmk: kscan_mock_work_handler_0: ev 2475163905 row 1 column 1 state 1
peripheral 0 <dbg> zmk: kscan_mock_schedule_next_event_0: delaying next keypress: 5000
peripheral 0 <dbg> zmk: zmk_physical_layouts_kscan_process_msgq: Row: 1, col: 1, position: 3, pressed: true
peripheral 0 <dbg> zmk: split_listener:
peripheral 0 <dbg> zmk: split_svc_run_behavior: offset 0 len 20
peripheral 0 <dbg> zmk: split_svc_run_behavior: sysreset with params 0 0: pressed? 1