Commit 0480367d authored by Håvard Reierstad's avatar Håvard Reierstad Committed by Anas Nashif
Browse files

bsim: Bluetooth: Mesh: refactor suspend test

Renames tx to DUT and rx to Tester to clarify roles in test.

Re-uses the same body for suspend/resume and suspend/disable/resume
for DUT with a parameter to toggle disabling BT.

Re-uses the same Tester config in both existing test-cases as the
previous configs were duplicates.

Updates the dut suspension status in the message handler.

Signed-off-by: default avatarHåvard Reierstad <haavard.reierstad@nordicsemi.no>
parent ee337087
Loading
Loading
Loading
Loading
+77 −106
Changes for tests/bsim/bluetooth/mesh/src/test_suspend.c: 77 added lines, 106 removed lines.
Original line number Diff line number Diff line
@@ -16,35 +16,40 @@ LOG_MODULE_REGISTER(test_suspend, LOG_LEVEL_INF);

#define WAIT_TIME        60 /* seconds */
#define SUSPEND_DURATION 15 /* seconds */
#define NUM_PUB           4 /* Times the transmitter will publish per interval. */
#define NUM_PUB           4 /* Times the DUT will publish per interval. */

#define TEST_MODEL_ID_1 0x2a2a
#define TEST_MODEL_ID_2 0x2b2b
#define TEST_MESSAGE_OP 0x1f

enum dut_mesh_status {
	DUT_SUSPENDED,
	DUT_RUNNING,
};

static int model_1_init(const struct bt_mesh_model *model);
static int model_2_init(const struct bt_mesh_model *model);

static uint8_t app_key[16] = {0xaa};
static uint8_t net_key[16] = {0xcc};

static const struct bt_mesh_test_cfg tx_cfg = {
static const struct bt_mesh_test_cfg dut_cfg = {
	.addr = 0x00a0,
	.dev_key = {0x01},
};
static const struct bt_mesh_test_cfg rx_cfg = {
static const struct bt_mesh_test_cfg tester_cfg = {
	.addr = 0x00b0,
	.dev_key = {0x02},
};

static struct bt_mesh_prov prov;
static struct k_sem publish_sem;
static bool suspended;
static enum dut_mesh_status dut_status;

static int model_1_update(const struct bt_mesh_model *model)
{
	model->pub->msg->data[1]++;
	LOG_INF("Model 1 publishing..., n: %d", model->pub->msg->data[1]);
	LOG_DBG("Model 1 publishing..., n: %d", model->pub->msg->data[1]);
	k_sem_give(&publish_sem);
	return 0;
}
@@ -53,16 +58,32 @@ static int msg_handler(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx
			    struct net_buf_simple *buf)
{
	static uint8_t prev_num;
	static int64_t uptime;
	uint8_t num = net_buf_simple_pull_u8(buf);

	LOG_INF("Received msg, n: %d", num);
	LOG_DBG("Received msg, n: %d", num);

	/* Ensure that payload changes. */
	ASSERT_TRUE(prev_num != num);
	prev_num = num;

	/* Ensure that no message is received while Mesh is suspended or disabled. */
	ASSERT_FALSE_MSG(suspended, "Received publication while Mesh is suspended.");
	/* Ensure that no message is received while Mesh is suspended or disabled.
	 * A publication may be sent just before DUT is suspended, which is ignored.
	 */
	if ((dut_status == DUT_SUSPENDED) && !(num == (NUM_PUB + 1))) {
		if (SUSPEND_DURATION * 1000ll <= k_uptime_delta(&uptime)) {
			dut_status = DUT_RUNNING;
			LOG_DBG("Suspend duration passed. Setting status to %d.", dut_status);
		} else {
			FAIL("Received publication while Mesh is suspended.");
		}
	}

	if (num == NUM_PUB) {
		dut_status = DUT_SUSPENDED;
		LOG_DBG("Expected number of pubs received. Setting status to %d.", dut_status);
		uptime = k_uptime_get();
	}

	k_sem_give(&publish_sem);
	return 0;
@@ -83,42 +104,42 @@ static const struct bt_mesh_model_op model_op_1[] = {BT_MESH_MODEL_OP_END};
static const struct bt_mesh_model_op model_op_2[] = {{TEST_MESSAGE_OP, 0, msg_handler},
						     BT_MESH_MODEL_OP_END};

static struct bt_mesh_cfg_cli cfg_cli_tx;
static struct bt_mesh_model tx_models[] = {
static struct bt_mesh_cfg_cli cfg_cli_dut;
static struct bt_mesh_model dut_models[] = {
	BT_MESH_MODEL_CFG_SRV,
	BT_MESH_MODEL_CFG_CLI(&cfg_cli_tx),
	BT_MESH_MODEL_CFG_CLI(&cfg_cli_dut),
	BT_MESH_MODEL_CB(TEST_MODEL_ID_1, model_op_1, &model_1_pub, NULL, &model_1_cb),
};

static struct bt_mesh_elem tx_elems[] = {
	BT_MESH_ELEM(0, tx_models, BT_MESH_MODEL_NONE),
static struct bt_mesh_elem dut_elems[] = {
	BT_MESH_ELEM(0, dut_models, BT_MESH_MODEL_NONE),
};

static const struct bt_mesh_comp tx_comp = {
static const struct bt_mesh_comp dut_comp = {
	.cid = TEST_VND_COMPANY_ID,
	.vid = 0xeeee,
	.pid = 0xaaaa,
	.elem = tx_elems,
	.elem_count = ARRAY_SIZE(tx_elems),
	.elem = dut_elems,
	.elem_count = ARRAY_SIZE(dut_elems),
};

static struct bt_mesh_cfg_cli cfg_cli_rx;
static struct bt_mesh_model rx_models[] = {
static struct bt_mesh_cfg_cli cfg_cli_tester;
static struct bt_mesh_model tester_models[] = {
	BT_MESH_MODEL_CFG_SRV,
	BT_MESH_MODEL_CFG_CLI(&cfg_cli_rx),
	BT_MESH_MODEL_CFG_CLI(&cfg_cli_tester),
	BT_MESH_MODEL_CB(TEST_MODEL_ID_2, model_op_2, NULL, NULL, &model_2_cb),
};

static struct bt_mesh_elem rx_elems[] = {
	BT_MESH_ELEM(0, rx_models, BT_MESH_MODEL_NONE),
static struct bt_mesh_elem tester_elems[] = {
	BT_MESH_ELEM(0, tester_models, BT_MESH_MODEL_NONE),
};

static const struct bt_mesh_comp rx_comp = {
static const struct bt_mesh_comp tester_comp = {
	.cid = TEST_VND_COMPANY_ID,
	.vid = 0xbaaa,
	.pid = 0xb000,
	.elem = rx_elems,
	.elem_count = ARRAY_SIZE(rx_elems),
	.elem = tester_elems,
	.elem_count = ARRAY_SIZE(tester_elems),
};

static int model_1_init(const struct bt_mesh_model *model)
@@ -134,7 +155,7 @@ static int model_2_init(const struct bt_mesh_model *model)
	return 0;
}

static void provision_and_configure(struct bt_mesh_test_cfg cfg, bool rx)
static void provision_and_configure(struct bt_mesh_test_cfg cfg, bool tester)
{
	int err;
	uint8_t status;
@@ -146,8 +167,8 @@ static void provision_and_configure(struct bt_mesh_test_cfg cfg, bool rx)
		FAIL("AppKey add failed (err %d, status %u)", err, status);
	}

	const struct bt_mesh_test_cfg *pcfg = rx ? &rx_cfg : &tx_cfg;
	uint16_t model_id = rx ? TEST_MODEL_ID_2 : TEST_MODEL_ID_1;
	const struct bt_mesh_test_cfg *pcfg = tester ? &tester_cfg : &dut_cfg;
	uint16_t model_id = tester ? TEST_MODEL_ID_2 : TEST_MODEL_ID_1;

	err = bt_mesh_cfg_cli_mod_app_bind(0, pcfg->addr, pcfg->addr, 0, model_id, &status);
	if (err || status) {
@@ -156,7 +177,7 @@ static void provision_and_configure(struct bt_mesh_test_cfg cfg, bool rx)
}

struct bt_mesh_cfg_cli_mod_pub pub_params = {
	.addr = rx_cfg.addr,
	.addr = tester_cfg.addr,
	.uuid = NULL,
	.cred_flag = false,
	.app_idx = 0,
@@ -165,19 +186,18 @@ struct bt_mesh_cfg_cli_mod_pub pub_params = {
	.transmit = 0,
};

static void test_tx_suspend_resume(void)
static void dut_pub_common(bool disable_bt)
{
	bt_mesh_test_cfg_set(NULL, WAIT_TIME);
	bt_mesh_device_setup(&prov, &tx_comp);
	provision_and_configure(tx_cfg, 0);
	bt_mesh_device_setup(&prov, &dut_comp);
	provision_and_configure(dut_cfg, 0);

	k_sem_init(&publish_sem, 0, 1);
	suspended = false;
	uint8_t status;
	int err;

	err = bt_mesh_cfg_cli_mod_pub_set(0, tx_cfg.addr, tx_cfg.addr, TEST_MODEL_ID_1, &pub_params,
					  &status);
	err = bt_mesh_cfg_cli_mod_pub_set(0, dut_cfg.addr, dut_cfg.addr, TEST_MODEL_ID_1,
					&pub_params, &status);
	if (err || status) {
		FAIL("Mod pub set failed (err %d, status %u)", err, status);
	}
@@ -187,15 +207,19 @@ static void test_tx_suspend_resume(void)
		ASSERT_OK_MSG(k_sem_take(&publish_sem, K_SECONDS(30)), "Pub timed out");
	}

	ASSERT_OK(bt_mesh_suspend());
	suspended = true;
	LOG_INF("Mesh suspended.");
	ASSERT_OK_MSG(bt_mesh_suspend(), "Failed to suspend Mesh.");

	if (disable_bt) {
		ASSERT_OK_MSG(bt_disable(), "Failed to disable Bluetooth.");
	}

	k_sleep(K_SECONDS(SUSPEND_DURATION));

	ASSERT_OK(bt_mesh_resume());
	suspended = false;
	LOG_INF("Mesh resumed.");
	if (disable_bt) {
		ASSERT_OK_MSG(bt_enable(NULL), "Failed to enable Bluetooth.");
	}

	ASSERT_OK_MSG(bt_mesh_resume(), "Failed to resume Mesh.");

	for (int i = 0; i < NUM_PUB; i++) {
		ASSERT_OK_MSG(k_sem_take(&publish_sem, K_SECONDS(30)), "Pub timed out");
@@ -204,81 +228,27 @@ static void test_tx_suspend_resume(void)
	/* Allow publishing to finish before suspending. */
	k_sleep(K_MSEC(100));
	ASSERT_OK(bt_mesh_suspend());

	PASS();
}

static void test_rx_suspend_resume(void)
static void test_dut_suspend_resume(void)
{
	bt_mesh_test_cfg_set(NULL, WAIT_TIME);
	bt_mesh_device_setup(&prov, &rx_comp);
	provision_and_configure(rx_cfg, 1);
	k_sem_init(&publish_sem, 0, 1);

	/* Receive messages before and after suspending. A publication may get lost
	 * when suspending immeditiately after publication, thus the "-1".
	 */
	for (int i = 0; i < NUM_PUB * 2 - 1; i++) {
		ASSERT_OK_MSG(k_sem_take(&publish_sem, K_SECONDS(30)), "Receiver timed out");
	}

	dut_pub_common(false);
	PASS();
}

static void test_tx_suspend_disable_resume(void)
static void test_dut_suspend_disable_resume(void)
{
	bt_mesh_test_cfg_set(NULL, WAIT_TIME);
	bt_mesh_device_setup(&prov, &tx_comp);
	provision_and_configure(tx_cfg, 0);

	k_sem_init(&publish_sem, 0, 1);
	suspended = false;
	uint8_t status;
	int err;

	err = bt_mesh_cfg_cli_mod_pub_set(0, tx_cfg.addr, tx_cfg.addr, TEST_MODEL_ID_1, &pub_params,
					  &status);
	if (err || status) {
		FAIL("Mod pub set failed (err %d, status %u)", err, status);
	}

	/* Wait until node has published before suspending. */
	for (int i = 0; i < NUM_PUB; i++) {
		ASSERT_OK_MSG(k_sem_take(&publish_sem, K_SECONDS(30)), "Pub timed out");
	}

	ASSERT_OK(bt_mesh_suspend());
	suspended = true;
	LOG_INF("Mesh suspended.");

	ASSERT_OK(bt_disable());
	LOG_INF("Bluetooth disabled.");

	k_sleep(K_SECONDS(SUSPEND_DURATION));

	ASSERT_OK(bt_enable(NULL));
	LOG_INF("Bluetooth enabled.");

	ASSERT_OK(bt_mesh_resume());
	suspended = false;
	LOG_INF("Mesh resumed.");

	for (int i = 0; i < NUM_PUB; i++) {
		ASSERT_OK_MSG(k_sem_take(&publish_sem, K_SECONDS(30)), "Pub timed out");
	}

	/* Allow publishing to finish before suspending. */
	k_sleep(K_MSEC(100));
	ASSERT_OK(bt_mesh_suspend());
	dut_pub_common(true);
	PASS();
}

static void test_rx_suspend_disable_resume(void)
static void test_tester_pub(void)
{
	bt_mesh_test_cfg_set(NULL, WAIT_TIME);
	bt_mesh_device_setup(&prov, &rx_comp);
	provision_and_configure(rx_cfg, 1);
	bt_mesh_device_setup(&prov, &tester_comp);
	provision_and_configure(tester_cfg, 1);
	k_sem_init(&publish_sem, 0, 1);
	dut_status = DUT_RUNNING;

	/* Receive messages before and after suspending. A publication may get lost
	 * when suspending immeditiately after publication, thus the "-1".
@@ -297,11 +267,12 @@ static void test_rx_suspend_disable_resume(void)
	}

static const struct bst_test_instance test_suspend[] = {
	TEST_CASE(tx, suspend_resume, "tx suspend resume"),
	TEST_CASE(tx, suspend_disable_resume, "tx suspend, disable resume"),
	TEST_CASE(dut, suspend_resume,
			 "Suspend and resume Mesh while publishing periodically"),
	TEST_CASE(dut, suspend_disable_resume,
			 "Suspend and resume Mesh (and disable/enable BT) while publishing periodically"),

	TEST_CASE(rx, suspend_resume, "rx suspend resume"),
	TEST_CASE(rx, suspend_disable_resume, "rx suspend, disable resume"),
	TEST_CASE(tester, pub, "Scan and verify behavior of periodic publishing adv"),

	BSTEST_END_MARKER};

+4 −4
Changes for tests/bsim/bluetooth/mesh/tests_scripts/suspend/suspend_disable_resume.sh: 4 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -17,17 +17,17 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
#   Check that publication resumes.

RunTest mesh_suspend_disable_resume \
	suspend_tx_suspend_disable_resume suspend_rx_suspend_disable_resume
	suspend_dut_suspend_disable_resume suspend_tester_pub

conf=prj_mesh1d1_conf
RunTest mesh_suspend_disable_resume_1d1 \
	suspend_tx_suspend_disable_resume suspend_rx_suspend_disable_resume
	suspend_dut_suspend_disable_resume suspend_tester_pub

overlay=overlay_low_lat_conf
RunTest mesh_suspend_disable_resume_low_lat \
	suspend_tx_suspend_disable_resume suspend_rx_suspend_disable_resume
	suspend_dut_suspend_disable_resume suspend_tester_pub

conf=prj_mesh1d1_conf
overlay=overlay_psa_conf
RunTest mesh_suspend_disable_resume_psa \
	suspend_tx_suspend_disable_resume suspend_rx_suspend_disable_resume
	suspend_dut_suspend_disable_resume suspend_tester_pub
+4 −4
Changes for tests/bsim/bluetooth/mesh/tests_scripts/suspend/suspend_resume.sh: 4 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -16,17 +16,17 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
# 3. Resume Mesh a specified time after suspension. Check that publication resumes.

RunTest mesh_suspend_resume \
	suspend_tx_suspend_resume suspend_rx_suspend_resume
	suspend_dut_suspend_resume suspend_tester_pub

conf=prj_mesh1d1_conf
RunTest mesh_suspend_resume_1d1 \
	suspend_tx_suspend_resume suspend_rx_suspend_resume
	suspend_dut_suspend_resume suspend_tester_pub

overlay=overlay_low_lat_conf
RunTest mesh_suspend_resume_low_lat \
	suspend_tx_suspend_resume suspend_rx_suspend_resume
	suspend_dut_suspend_resume suspend_tester_pub

conf=prj_mesh1d1_conf
overlay=overlay_psa_conf
RunTest mesh_suspend_resume_psa \
	suspend_tx_suspend_resume suspend_rx_suspend_resume
	suspend_dut_suspend_resume suspend_tester_pub