feat(ble): added pytest for ble power save example

pull/13090/head
cjin 2024-01-09 21:01:59 +08:00
rodzic a4f228da46
commit 9533df5c39
10 zmienionych plików z 157 dodań i 4 usunięć

Wyświetl plik

@ -205,6 +205,22 @@ examples/bluetooth/nimble/ble_phy:
depends_filepatterns:
- examples/bluetooth/nimble/common/**/*
examples/bluetooth/nimble/blecent:
<<: *bt_default_depends
disable:
- if: SOC_BLE_SUPPORTED != 1
depends_components:
- bt
- esp_phy
- esp_event
- esp_coex
- esp_pm
depends_filepatterns:
- examples/bluetooth/nimble/common/**/*
- examples/bluetooth/nimble/blecent/**/*
- examples/bluetooth/nimble/power_save/**/*
- examples/bluetooth/nimble/pytest_nimble_test.py
examples/bluetooth/nimble/blemesh:
<<: *bt_default_depends
enable:
@ -249,6 +265,9 @@ examples/bluetooth/nimble/power_save:
- esp_pm
depends_filepatterns:
- examples/bluetooth/nimble/common/**/*
- examples/bluetooth/nimble/blecent/**/*
- examples/bluetooth/nimble/power_save/**/*
- examples/bluetooth/nimble/pytest_nimble_test.py
examples/bluetooth/nimble/throughput_app:
<<: *bt_default_depends

Wyświetl plik

@ -28,4 +28,12 @@ menu "Example Configuration"
prompt "Enable Link Encryption"
help
This enables bonding and encryption after connection has been established.
config EXAMPLE_USE_CI_ADDRESS
bool
default n
prompt "Advertise using Test address(Internal Test ONLY)"
help
Used for internal test ONLY.
Use this option to advertise in a specific random address.
endmenu

Wyświetl plik

@ -455,17 +455,26 @@ ext_blecent_should_connect(const struct ble_gap_ext_disc_desc *disc)
{
int offset = 0;
int ad_struct_len = 0;
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
uint32_t *addr_offset;
#endif // CONFIG_EXAMPLE_USE_CI_ADDRESS
if (disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
return 0;
}
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen ("ADDR_ANY")) != 0)) {
#if !CONFIG_EXAMPLE_USE_CI_ADDRESS
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
#else
addr_offset = (uint32_t *)&peer_addr[1];
*addr_offset = atoi(CONFIG_EXAMPLE_PEER_ADDR);
peer_addr[5] = 0xC3;
#endif // !CONFIG_EXAMPLE_USE_CI_ADDRESS
if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0;
}
@ -501,6 +510,9 @@ blecent_should_connect(const struct ble_gap_disc_desc *disc)
struct ble_hs_adv_fields fields;
int rc;
int i;
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
uint32_t *addr_offset;
#endif // CONFIG_EXAMPLE_USE_CI_ADDRESS
/* The device has to be advertising connectability. */
if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
@ -516,10 +528,16 @@ blecent_should_connect(const struct ble_gap_disc_desc *disc)
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) {
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
#if !CONFIG_EXAMPLE_USE_CI_ADDRESS
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
#else
addr_offset = (uint32_t *)&peer_addr[1];
*addr_offset = atoi(CONFIG_EXAMPLE_PEER_ADDR);
peer_addr[5] = 0xC3;
#endif // !CONFIG_EXAMPLE_USE_CI_ADDRESS
if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0;
}

Wyświetl plik

@ -0,0 +1,2 @@
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
CONFIG_EXAMPLE_PEER_ADDR="${CI_JOB_ID}"

Wyświetl plik

@ -0,0 +1,4 @@
CONFIG_IDF_TARGET="esp32c2"
CONFIG_XTAL_FREQ_26=y
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
CONFIG_EXAMPLE_PEER_ADDR="${CI_JOB_ID}"

Wyświetl plik

@ -156,4 +156,19 @@ menu "Example Configuration"
help
Use this option to enable resolving peer's address.
config EXAMPLE_USE_CI_ADDRESS
bool
default n
prompt "Advertise using Test address(Internal Test ONLY)"
help
Used for internal test ONLY.
Use this option to advertise in a specific random address.
config EXAMPLE_CI_ADDRESS_OFFSET
string
prompt "Advertise using Test address(Internal Test ONLY)"
depends on EXAMPLE_USE_CI_ADDRESS
help
Used for internal test ONLY.
Use this option to advertise in a specific random address.
endmenu

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -28,7 +28,7 @@ static uint8_t ext_adv_pattern_1[] = {
static const char *tag = "NimBLE_BLE_PRPH";
static int bleprph_gap_event(struct ble_gap_event *event, void *arg);
#if CONFIG_EXAMPLE_RANDOM_ADDR
#if CONFIG_EXAMPLE_RANDOM_ADDR || CONFIG_EXAMPLE_USE_CI_ADDRESS
static uint8_t own_addr_type = BLE_OWN_ADDR_RANDOM;
#else
static uint8_t own_addr_type;
@ -93,7 +93,7 @@ ext_bleprph_advertise(void)
params.connectable = 1;
/* advertise using random addr */
params.own_addr_type = BLE_OWN_ADDR_PUBLIC;
params.own_addr_type = own_addr_type;
params.primary_phy = BLE_HCI_LE_PHY_1M;
params.secondary_phy = BLE_HCI_LE_PHY_2M;
@ -462,14 +462,26 @@ bleprph_on_sync(void)
ble_app_set_addr();
#endif
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
if (strlen(CONFIG_EXAMPLE_CI_ADDRESS_OFFSET)) {
uint8_t addr[6] = {0};
uint32_t *offset = (uint32_t *)&addr[1];
*offset = atoi(CONFIG_EXAMPLE_CI_ADDRESS_OFFSET);
addr[5] = 0xC3;
rc = ble_hs_id_set_rnd(addr);
assert(rc == 0);
}
#endif // CONFIG_EXAMPLE_USE_CI_ADDRESS
/* Make sure we have proper identity address set (public preferred) */
#if CONFIG_EXAMPLE_RANDOM_ADDR
#if CONFIG_EXAMPLE_RANDOM_ADDR || CONFIG_EXAMPLE_USE_CI_ADDRESS
rc = ble_hs_util_ensure_addr(1);
#else
rc = ble_hs_util_ensure_addr(0);
#endif
assert(rc == 0);
/* Figure out address to use while advertising (no privacy for now) */
rc = ble_hs_id_infer_auto(0, &own_addr_type);
if (rc != 0) {

Wyświetl plik

@ -0,0 +1,5 @@
#
# Test Config
#
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
CONFIG_EXAMPLE_CI_ADDRESS_OFFSET="${CI_JOB_ID}"

Wyświetl plik

@ -0,0 +1,7 @@
CONFIG_IDF_TARGET="esp32c2"
CONFIG_XTAL_FREQ_26=y
#
# Test Config
#
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
CONFIG_EXAMPLE_CI_ADDRESS_OFFSET="${CI_JOB_ID}"

Wyświetl plik

@ -0,0 +1,63 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import os.path
from typing import Tuple
import pexpect
import pytest
from pytest_embedded_idf.dut import IdfDut
# Case 1: BLE power save test
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32
@pytest.mark.wifi_two_dut
@pytest.mark.parametrize(
'count, app_path', [
(2,
f'{os.path.join(os.path.dirname(__file__), "power_save")}|{os.path.join(os.path.dirname(__file__), "blecent")}'),
],
indirect=True,
)
def test_power_save_conn(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None:
peripheral = dut[0]
central = dut[1]
peripheral.expect('NimBLE_BLE_PRPH: BLE Host Task Started', timeout=30)
central.expect('NimBLE_BLE_CENT: BLE Host Task Started', timeout=30)
peripheral.expect('Returned from app_main()', timeout=30)
central.expect('Returned from app_main()', timeout=30)
central.expect('Connection established', timeout=30)
peripheral.expect('connection established; status=0', timeout=30)
output = peripheral.expect(pexpect.TIMEOUT, timeout=30)
assert 'rst:' not in str(output) and 'boot:' not in str(output)
# Case 2: BLE power save test for ESP32C2
@pytest.mark.esp32c2
@pytest.mark.wifi_two_dut
@pytest.mark.xtal_26mhz
@pytest.mark.parametrize(
'config, count, app_path, baud', [
('esp32c2_xtal26m', 2,
f'{os.path.join(os.path.dirname(__file__), "power_save")}|{os.path.join(os.path.dirname(__file__), "blecent")}',
'74880'),
],
indirect=True,
)
def test_power_save_conn_esp32c2_26mhz(dut: Tuple[IdfDut, IdfDut]) -> None:
peripheral = dut[0]
central = dut[1]
peripheral.expect('NimBLE_BLE_PRPH: BLE Host Task Started', timeout=5)
central.expect('NimBLE_BLE_CENT: BLE Host Task Started', timeout=5)
peripheral.expect('Returned from app_main()', timeout=5)
central.expect('Returned from app_main()', timeout=5)
central.expect('Connection established', timeout=30)
peripheral.expect('connection established; status=0', timeout=30)
output = peripheral.expect(pexpect.TIMEOUT, timeout=30)
assert 'rst:' not in str(output) and 'boot:' not in str(output)