Skip to content

Commit b3e5aba

Browse files
alxelaxkartben
authored andcommitted
tests: bluetooth: mesh: bsim test to check memory leak after suspending
Commit adds mesh bsim test to check adv pool memory leakage after mesh has been suspended. Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
1 parent 9e0c6d5 commit b3e5aba

File tree

4 files changed

+94
-20
lines changed

4 files changed

+94
-20
lines changed

tests/bsim/bluetooth/mesh/src/test_advertiser.c

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF);
1919

2020
#define WAIT_TIME 60 /*seconds*/
2121

22+
enum suspending_ctx {
23+
NOT_SUSPENDED,
24+
SUSPENDED_IN_CTX,
25+
SUSPENDED_IN_CB
26+
};
27+
2228
extern const struct bt_mesh_comp comp;
2329

2430
static uint8_t test_prov_uuid[16] = { 0x6c, 0x69, 0x6e, 0x67, 0x61, 0xaa };
@@ -796,7 +802,7 @@ static void adv_resume(void)
796802
}
797803

798804
struct adv_suspend_ctx {
799-
bool suspend;
805+
enum suspending_ctx suspend;
800806
int instance_idx;
801807
};
802808

@@ -812,7 +818,7 @@ static void adv_send_end(int err, void *cb_data)
812818

813819
ASSERT_EQUAL(err, 0);
814820

815-
if (adv_data->suspend) {
821+
if (adv_data->suspend != NOT_SUSPENDED) {
816822
/* When suspending, the end callback will be called only for the first adv, because
817823
* it was already scheduled.
818824
*/
@@ -831,8 +837,8 @@ static void adv_send_start(uint16_t duration, int err, void *cb_data)
831837
LOG_DBG("start(): err (%d), suspend (%d), i (%d)", err, adv_data->suspend,
832838
adv_data->instance_idx);
833839

834-
if (adv_data->suspend) {
835-
if (adv_data->instance_idx == 0) {
840+
if (adv_data->suspend != NOT_SUSPENDED) {
841+
if (adv_data->instance_idx == 0 && adv_data->suspend == SUSPENDED_IN_CB) {
836842
ASSERT_EQUAL(err, 0);
837843
adv_suspend();
838844
} else {
@@ -851,7 +857,8 @@ static void adv_send_start(uint16_t duration, int err, void *cb_data)
851857
}
852858
}
853859

854-
static void adv_create_and_send(bool suspend, uint8_t first_byte, struct adv_suspend_ctx *adv_data)
860+
static void adv_create_and_send(enum suspending_ctx suspend, uint8_t first_byte,
861+
struct adv_suspend_ctx *adv_data)
855862
{
856863
struct bt_mesh_adv *advs[CONFIG_BT_MESH_ADV_BUF_COUNT];
857864
static const struct bt_mesh_send_cb send_cb = {
@@ -864,7 +871,7 @@ static void adv_create_and_send(bool suspend, uint8_t first_byte, struct adv_sus
864871
adv_data[i].instance_idx = i;
865872

866873
advs[i] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
867-
BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
874+
BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
868875
ASSERT_FALSE_MSG(!advs[i], "Out of advs\n");
869876

870877
net_buf_simple_add_u8(&advs[i]->b, first_byte);
@@ -877,29 +884,41 @@ static void adv_create_and_send(bool suspend, uint8_t first_byte, struct adv_sus
877884
}
878885
}
879886

880-
static void test_tx_disable(void)
887+
static void check_suspending(void)
881888
{
882-
struct adv_suspend_ctx adv_data[CONFIG_BT_MESH_ADV_BUF_COUNT];
883889
struct bt_mesh_adv *extra_adv;
884890
int err;
885891

886-
bt_init();
887-
adv_init();
888-
889-
/* Fill up the adv pool and suspend the advertiser in the first start callback call. */
890-
adv_create_and_send(true, 0xAA, adv_data);
891-
892892
err = k_sem_take(&adv_suspended_sem, K_SECONDS(10));
893893
ASSERT_OK_MSG(err, "Not all advs were sent");
894894

895895
extra_adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
896896
BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
897897
ASSERT_TRUE_MSG(!extra_adv, "Created adv while suspended");
898+
}
899+
900+
static void test_tx_disable(void)
901+
{
902+
struct adv_suspend_ctx adv_data[CONFIG_BT_MESH_ADV_BUF_COUNT];
903+
int err;
904+
905+
bt_init();
906+
adv_init();
907+
908+
LOG_INF("Fill up the adv pool and suspend the advertiser right after in the same context.");
909+
adv_create_and_send(SUSPENDED_IN_CTX, 0xAA, adv_data);
910+
adv_suspend();
911+
check_suspending();
912+
adv_resume();
898913

914+
LOG_INF("Fill up the adv pool and suspend the advertiser in the first start callback "
915+
"call.");
916+
adv_create_and_send(SUSPENDED_IN_CB, 0xAA, adv_data);
917+
check_suspending();
899918
adv_resume();
900919

901-
/* Fill up the adv pool and suspend the advertiser and let it send all advs. */
902-
adv_create_and_send(false, 0xBB, adv_data);
920+
LOG_INF("Fill up the adv pool and suspend the advertiser and let it send all advs");
921+
adv_create_and_send(NOT_SUSPENDED, 0xBB, adv_data);
903922

904923
err = k_sem_take(&adv_sent_sem, K_SECONDS(10));
905924
ASSERT_OK_MSG(err, "Not all advs were sent");

tests/bsim/bluetooth/mesh/src/test_suspend.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,34 @@ static void test_tester_gatt(void)
464464
PASS();
465465
}
466466

467+
static void test_dut_suspend_resume_unref(void)
468+
{
469+
const struct bt_mesh_test_cfg tx_cfg = {
470+
.addr = 0x0001,
471+
.dev_key = {0x01},
472+
};
473+
474+
bt_mesh_test_cfg_set(&tx_cfg, 2 * WAIT_TIME);
475+
bt_mesh_test_setup();
476+
477+
for (uint16_t count = 0; count < 2 * CONFIG_BT_MESH_ADV_BUF_COUNT; count++) {
478+
LOG_DBG("Step %d", count);
479+
480+
ASSERT_OK_MSG(bt_mesh_test_send_data(BT_MESH_ADDR_ALL_NODES, NULL,
481+
(uint8_t *)&count, sizeof(count), NULL, NULL),
482+
"Cannot send data");
483+
ASSERT_OK_MSG(bt_mesh_test_send_data(BT_MESH_ADDR_ALL_NODES, NULL,
484+
(uint8_t *)&count, sizeof(count), NULL, NULL),
485+
"Cannot send data");
486+
487+
ASSERT_OK_MSG(bt_mesh_suspend(), "Failed to suspend Mesh.");
488+
k_sleep(K_MSEC(500));
489+
ASSERT_OK_MSG(bt_mesh_resume(), "Failed to resume Mesh.");
490+
}
491+
492+
PASS();
493+
}
494+
467495
#define TEST_CASE(role, name, description) \
468496
{ \
469497
.test_id = "suspend_" #role "_" #name, .test_descr = description, \
@@ -479,6 +507,8 @@ static const struct bst_test_instance test_suspend[] = {
479507
"Suspend and resume Mesh with GATT proxy advs"),
480508
TEST_CASE(dut, gatt_suspend_disable_resume,
481509
"Suspend and resume Mesh (and disable/enable BT) with GATT proxy advs"),
510+
TEST_CASE(dut, suspend_resume_unref,
511+
"Suspend and resume Mesh twice adv more than advertiser pool size times"),
482512

483513
TEST_CASE(tester, pub, "Scan and verify behavior of periodic publishing adv"),
484514
TEST_CASE(tester, gatt, "Scan and verify behavior of GATT proxy adv"),

tests/bsim/bluetooth/mesh/tests_scripts/advertiser/disable.sh

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
1717
# 1. Tx device creates `CONFIG_BT_MESH_ADV_BUF_COUNT` advertisements, setting the first byte of the
1818
# PDU to 0xAA and the second byte of the PDU to the advertisement order number
1919
# 2. Tx devices pushes all created advs to the pool by calling `bt_mesh_adv_send` function
20-
# 3. When the `bt_mesh_send_cb.start` callback is called for the first adv, the tx device submits
21-
# a work item which suspends the advertiser by calling `bt_mesh_adv_disable`.
20+
# 3. After calling sending function Tx device immediately suspends the advertiser.
2221
# 4. Tx device checks that for the first adv the `bt_mesh_send_cb.end` callback is called with the
2322
# error code `0`.
2423
# 5. Tx device checks that for the consecutive advs the `bt_mesh_send_cb.start` is called with error
2524
# `-ENODEV`.
2625
# 6. Tx device checks that no more advs can be created using `bt_mesh_adv_create` function.
2726
# 7. Tx device resumes the advertiser and repeats steps 1 and 2.
28-
# 8. Tx device expects that all advs are sent.
27+
# 8. When the `bt_mesh_send_cb.start` callback is called for the first adv, the tx device submits
28+
# a work item which suspends the advertiser by calling `bt_mesh_adv_disable`.
29+
# 9. Tx device repeats steps 4-6.
30+
# 10. Tx device resumes the advertiser and repeats steps 1 and 2.
31+
# 11. Tx device expects that all advs are sent.
2932
#
3033
# Rx device procedure:
3134
# 1. Rx devices listens all the time while tx device sends advs and ensure that no new advs were
@@ -35,7 +38,7 @@ RunTest mesh_adv_disable adv_tx_disable adv_rx_disable
3538

3639
# Low latency overlay uses legacy advertiser
3740
overlay=overlay_low_lat_conf
38-
RunTest mesh_adv_disable adv_tx_disable adv_rx_disable
41+
RunTest mesh_adv_disable_low_lat adv_tx_disable adv_rx_disable
3942

4043
overlay=overlay_workq_sys_conf
4144
RunTest mesh_adv_disable_workq adv_tx_disable adv_rx_disable
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2025 Nordic Semiconductor
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
6+
7+
# Test that initiates a broadcasting of the test model command and immediately suspends device.
8+
# After a short pause, the device is resumed and attempt of broadcasting is repeated.
9+
# This is repeated twice more time than allocated advertiser pool size to be sure in that
10+
# device unreferences allocated advertiser from the pool back if it is suspended.
11+
#
12+
# Test procedure:
13+
# 0. Provisioning and setup.
14+
# 1. Send test model command twice to check that all allocated advertisers are freed.
15+
# 2. Suspend Mesh.
16+
# 3. Resume Mesh.
17+
# 4. Repeat steps 1-3 twice more than allocated advertiser pool size.
18+
overlay="overlay_psa_conf"
19+
RunTest mesh_suspend_resume_unref suspend_dut_suspend_resume_unref
20+
21+
overlay="overlay_low_lat_conf_overlay_psa_conf"
22+
RunTest mesh_suspend_resume_unref_low_lat suspend_dut_suspend_resume_unref

0 commit comments

Comments
 (0)