From 33ec6ed4c389649669635c2cb2600fc2422a3490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Mon, 26 Jun 2023 07:51:09 +0200 Subject: [PATCH] Bluetooth: Tests: Add test for new `bt_settings_cleanup` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a test for the new `bt_settings_cleanup` function. The test artificially write settings then call `bt_settings_cleanup` and check that the settings that should not have been deleted have not been. Signed-off-by: Théo Battrel --- tests/bsim/bluetooth/host/compile.sh | 2 + .../host/settings/cleanup/CMakeLists.txt | 18 ++ .../bluetooth/host/settings/cleanup/prj.conf | 19 ++ .../host/settings/cleanup/src/common.h | 20 ++ .../host/settings/cleanup/src/main.c | 63 +++++ .../host/settings/cleanup/src/test.c | 221 ++++++++++++++++++ .../settings/cleanup/test_scripts/_compile.sh | 13 ++ .../settings/cleanup/test_scripts/cleanup.sh | 36 +++ 8 files changed, 392 insertions(+) create mode 100644 tests/bsim/bluetooth/host/settings/cleanup/CMakeLists.txt create mode 100644 tests/bsim/bluetooth/host/settings/cleanup/prj.conf create mode 100644 tests/bsim/bluetooth/host/settings/cleanup/src/common.h create mode 100644 tests/bsim/bluetooth/host/settings/cleanup/src/main.c create mode 100644 tests/bsim/bluetooth/host/settings/cleanup/src/test.c create mode 100755 tests/bsim/bluetooth/host/settings/cleanup/test_scripts/_compile.sh create mode 100755 tests/bsim/bluetooth/host/settings/cleanup/test_scripts/cleanup.sh diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index aa12780f2d8307..bbe857071f76d3 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -70,4 +70,6 @@ app=tests/bsim/bluetooth/host/security/ccc_update conf_file=prj_2.conf compile app=tests/bsim/bluetooth/host/id/settings compile +app=tests/bsim/bluetooth/host/settings/cleanup compile + wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/settings/cleanup/CMakeLists.txt b/tests/bsim/bluetooth/host/settings/cleanup/CMakeLists.txt new file mode 100644 index 00000000000000..24abc88fbc7976 --- /dev/null +++ b/tests/bsim/bluetooth/host/settings/cleanup/CMakeLists.txt @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_bt_host_settings_cleanup) + +target_sources(app PRIVATE + src/main.c + src/test.c +) + +zephyr_include_directories( + $ENV{BSIM_COMPONENTS_PATH}/libUtilv1/src/ + $ENV{BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + + $ENV{ZEPHYR_BASE}/subsys/bluetooth/host/ +) diff --git a/tests/bsim/bluetooth/host/settings/cleanup/prj.conf b/tests/bsim/bluetooth/host/settings/cleanup/prj.conf new file mode 100644 index 00000000000000..f7e05df8cb2b04 --- /dev/null +++ b/tests/bsim/bluetooth/host/settings/cleanup/prj.conf @@ -0,0 +1,19 @@ +CONFIG_BT=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_DEVICE_NAME="Settings Cleanup Test" + +CONFIG_LOG=y +CONFIG_BT_SETTINGS_LOG_LEVEL_DBG=y + +CONFIG_BT_ID_MAX=3 + +CONFIG_BT_EXT_ADV=y +CONFIG_BT_SMP=y + +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH_MAP=y +CONFIG_NVS=y +CONFIG_SETTINGS=y +CONFIG_BT_SETTINGS=y diff --git a/tests/bsim/bluetooth/host/settings/cleanup/src/common.h b/tests/bsim/bluetooth/host/settings/cleanup/src/common.h new file mode 100644 index 00000000000000..41d8ba0346e869 --- /dev/null +++ b/tests/bsim/bluetooth/host/settings/cleanup/src/common.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bs_tracing.h" +#include "bstests.h" + +#define FAIL(...) \ + do { \ + bst_result = Failed; \ + bs_trace_error_time_line(__VA_ARGS__); \ + } while (0) + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +extern enum bst_result_t bst_result; diff --git a/tests/bsim/bluetooth/host/settings/cleanup/src/main.c b/tests/bsim/bluetooth/host/settings/cleanup/src/main.c new file mode 100644 index 00000000000000..df72bacd5fb596 --- /dev/null +++ b/tests/bsim/bluetooth/host/settings/cleanup/src/main.c @@ -0,0 +1,63 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "bs_types.h" +#include "bs_tracing.h" +#include "bstests.h" +#include + +#include + +#include "common.h" + +#define WAIT_TIME_S 60 +#define WAIT_TIME (WAIT_TIME_S * 1e6) + +LOG_MODULE_REGISTER(bsim_bt_settings_cleanup, LOG_LEVEL_DBG); + +extern void run_tester(void); +extern void run_dut(void); + +void test_tick(bs_time_t HW_device_time) +{ + if (bst_result != Passed) { + FAIL("Test failed (not passed after %d seconds)\n", WAIT_TIME_S); + } +} + +static void test_settings_cleanup_init(void) +{ + bst_ticker_set_next_tick_absolute(WAIT_TIME); +} + +static const struct bst_test_instance test_def[] = { + { + .test_id = "tester", + .test_descr = "Tester", + .test_post_init_f = test_settings_cleanup_init, + .test_tick_f = test_tick, + .test_main_f = run_tester, + }, + { + .test_id = "dut", + .test_descr = "DUT", + .test_post_init_f = test_settings_cleanup_init, + .test_tick_f = test_tick, + .test_main_f = run_dut, + }, + BSTEST_END_MARKER}; + +struct bst_test_list *test_settings_cleanup_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_def); +} + +bst_test_install_t test_installers[] = {test_settings_cleanup_install, NULL}; + +void main(void) +{ + bst_main(); +} diff --git a/tests/bsim/bluetooth/host/settings/cleanup/src/test.c b/tests/bsim/bluetooth/host/settings/cleanup/src/test.c new file mode 100644 index 00000000000000..4d574cdc112784 --- /dev/null +++ b/tests/bsim/bluetooth/host/settings/cleanup/src/test.c @@ -0,0 +1,221 @@ +/* Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "settings.h" + +#include "common.h" +#include "zephyr/sys/util.h" +#include +#include + +LOG_MODULE_DECLARE(bsim_bt_settings_cleanup, LOG_LEVEL_DBG); + +const char *expected_settings_key[] = { + "hash", + "id", + "keys/0000000000000", + "sc/0000000000000", + "cf/0000000000000", + "ccc/0000000000000", + "mesh/dummy/key", +}; + +static int print_all_settings_cb(const char *key, size_t len, settings_read_cb read_cb, + void *cb_arg, void *param) +{ + ssize_t err; + uint8_t data[100] = {0}; + + err = read_cb(cb_arg, data, len); + if (err != len) { + FAIL("Failed to read data (err %d)\n", err); + } + + LOG_INF("key: 'bt/%s'", key); + LOG_HEXDUMP_INF(data, len, "value:"); + + return 0; +} + +static void print_all_settings(void) +{ + int err; + + err = settings_load_subtree_direct("bt", print_all_settings_cb, NULL); + if (err) { + FAIL("Failed to load 'bt' subtree (err %s)\n", err); + } +} + +static int check_settings_cb(const char *key, size_t len, settings_read_cb read_cb, void *cb_arg, + void *param) +{ + bool key_is_expected = false; + uint8_t *key_not_deleted = (uint8_t *)param; + + for (size_t i = 0; i < ARRAY_SIZE(expected_settings_key); i++) { + if (strcmp(expected_settings_key[i], key) == 0 && key_not_deleted[i] == 0) { + key_not_deleted[i] = 1; + key_is_expected = true; + } + } + + if (!key_is_expected) { + FAIL("Key 'bt/%s' should have been deleted\n", key); + } + + return 0; +} + +static void check_settings(void) +{ + int err; + uint8_t key_not_deleted[ARRAY_SIZE(expected_settings_key)] = {0}; + + err = settings_load_subtree_direct("bt", check_settings_cb, key_not_deleted); + if (err) { + FAIL("Failed to load 'bt' subtree (err %d)\n", err); + } + + for (size_t i = 0; i < ARRAY_SIZE(expected_settings_key); i++) { + if (key_not_deleted[i] == 0) { + FAIL("Key '%s' should not have been deleted\n", expected_settings_key[i]); + } + } +} + +static void populate_settings(void) +{ + int err; + uint8_t dummy_value = 0; + bt_addr_le_t dummy_addr; + bt_addr_le_t ids_addr[CONFIG_BT_ID_MAX] = {0}; + + BUILD_ASSERT(CONFIG_BT_ID_MAX >= 3); + + bt_addr_le_copy(&dummy_addr, BT_ADDR_LE_ANY); + + err = bt_addr_le_create_static(&ids_addr[0]); + if (err) { + FAIL("Failed to create static address (err %d)\n", err); + } + + err = bt_addr_le_create_static(&ids_addr[2]); + if (err) { + FAIL("Failed to create static address (err %d)\n", err); + } + + err = settings_save_one("bt/id", ids_addr, sizeof(ids_addr)); + if (err) { + FAIL("Failed to save ID (err %d)\n", err); + } + + bt_settings_store_keys(0, &dummy_addr, &dummy_value, sizeof(dummy_value)); + bt_settings_store_sc(0, &dummy_addr, &dummy_value, sizeof(dummy_value)); + bt_settings_store_cf(0, &dummy_addr, &dummy_value, sizeof(dummy_value)); + bt_settings_store_ccc(0, &dummy_addr, &dummy_value, sizeof(dummy_value)); + + bt_settings_store_keys(1, &dummy_addr, &dummy_value, sizeof(dummy_value)); + bt_settings_store_sc(1, &dummy_addr, &dummy_value, sizeof(dummy_value)); + bt_settings_store_cf(1, &dummy_addr, &dummy_value, sizeof(dummy_value)); + bt_settings_store_ccc(1, &dummy_addr, &dummy_value, sizeof(dummy_value)); + + settings_save_one("bt/dummy/key", &dummy_value, sizeof(dummy_value)); + + settings_save_one("bt/i", &dummy_value, sizeof(dummy_value)); + settings_save_one("bt/idd", &dummy_value, sizeof(dummy_value)); + + /* without keys for id 2, this settings should be deleted */ + bt_settings_store_sc(2, &dummy_addr, &dummy_value, sizeof(dummy_value)); + bt_settings_store_cf(2, &dummy_addr, &dummy_value, sizeof(dummy_value)); + bt_settings_store_ccc(2, &dummy_addr, &dummy_value, sizeof(dummy_value)); + + settings_save_one("bt/mesh/dummy/key", &dummy_value, sizeof(dummy_value)); +} + +void run_tester(void) +{ + int id; + int err; + char addr_str[BT_ADDR_STR_LEN]; + size_t id_count = CONFIG_BT_ID_MAX; + bt_addr_le_t addrs[CONFIG_BT_ID_MAX] = {0}; + + LOG_DBG("Starting test... (tester)"); + + err = bt_enable(NULL); + if (err) { + FAIL("Bluetooth init failed (err %d)\n", err); + } + + LOG_DBG("Bluetooth initialised"); + + err = settings_load(); + if (err) { + FAIL("Failed to load settings (err %d)\n", err); + } + + err = bt_id_create(NULL, NULL); + if (err < 0) { + FAIL("Failed to create new identity (err %d)\n", err); + } + id = err; + + err = bt_id_create(NULL, NULL); + if (err < 0) { + FAIL("Failed to create new identity (err %d)\n", err); + } + + err = bt_id_delete(id); + if (err) { + FAIL("Failed to delete identity %d (err %d)\n", id, err); + } + + bt_id_get(addrs, &id_count); + + for (size_t i = 0; i < CONFIG_BT_ID_MAX; i++) { + bt_addr_le_to_str(&addrs[i], addr_str, BT_ADDR_STR_LEN); + LOG_DBG("ID[%d]: %s", i, addr_str); + } + + populate_settings(); + + print_all_settings(); + + PASS("Test passed (tester)\n"); +} + +void run_dut(void) +{ + int err; + bool settings_cleanup_dry_run = false; + + LOG_DBG("Starting test... (dut)"); + + err = settings_subsys_init(); + if (err) { + FAIL("settings_subsys_init failed (err %d)\n", err); + } + + err = bt_settings_cleanup(settings_cleanup_dry_run); + if (err) { + FAIL("Failed to clean settings (err %d)\n", err); + } + + print_all_settings(); + + check_settings(); + + PASS("Test passed (dut)\n"); +} diff --git a/tests/bsim/bluetooth/host/settings/cleanup/test_scripts/_compile.sh b/tests/bsim/bluetooth/host/settings/cleanup/test_scripts/_compile.sh new file mode 100755 index 00000000000000..305f1d845cee57 --- /dev/null +++ b/tests/bsim/bluetooth/host/settings/cleanup/test_scripts/_compile.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +set -eu +bash_source_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +bsim_bin="${BSIM_OUT_PATH}/bin" +BOARD="${BOARD:-nrf52_bsim}" +test_exe="${bsim_bin}/bs_${BOARD}_tests_bsim_bluetooth_host_settings_cleanup_prj_conf" + +west build -b nrf52_bsim -d build && \ + cp -v build/zephyr/zephyr.exe "${test_exe}" diff --git a/tests/bsim/bluetooth/host/settings/cleanup/test_scripts/cleanup.sh b/tests/bsim/bluetooth/host/settings/cleanup/test_scripts/cleanup.sh new file mode 100755 index 00000000000000..7b1dbcba695475 --- /dev/null +++ b/tests/bsim/bluetooth/host/settings/cleanup/test_scripts/cleanup.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +test_exe="bs_${BOARD}_tests_bsim_bluetooth_host_settings_cleanup_prj_conf" +simulation_id="settings_cleanup" +verbosity_level=2 +EXECUTE_TIMEOUT=30 + +settings_file="${simulation_id}.log.bin" + +cd ${BSIM_OUT_PATH}/bin + +if [ -e "${settings_file}" ]; then + rm "${settings_file}" +fi + +Execute "./${test_exe}" \ + -v=${verbosity_level} -s="${simulation_id}_1" -d=0 -testid=tester \ + -flash="${settings_file}" + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s="${simulation_id}_1" \ + -D=1 -sim_length=60e6 + +wait_for_background_jobs + +Execute "./${test_exe}" \ + -v=${verbosity_level} -s="${simulation_id}_2" -d=0 -testid=dut \ + -flash="${settings_file}" -flash_rm + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s="${simulation_id}_2" \ + -D=1 -sim_length=60e6 + +wait_for_background_jobs