1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/bluetooth/addr.h>
9 #include <host/keys.h>
10 #include <zephyr/fff.h>
11 #include "mocks/conn.h"
12 #include "mocks/hci_core.h"
13 #include "mocks/keys_help_utils.h"
14 #include "testing_common_defs.h"
15 #include "common/bt_str.h"
16 
17 DEFINE_FFF_GLOBALS;
18 
19 /* This LUT contains different combinations of ID and Address pairs */
20 const struct id_addr_pair testing_id_addr_pair_lut[] = {
21 	{ BT_ADDR_ID_1, BT_ADDR_LE_1 },
22 	{ BT_ADDR_ID_1, BT_ADDR_LE_2 },
23 	{ BT_ADDR_ID_2, BT_ADDR_LE_1 },
24 	{ BT_ADDR_ID_2, BT_ADDR_LE_2 }
25 };
26 
27 /* This list will hold returned references while filling keys pool */
28 struct bt_keys *returned_keys_refs[CONFIG_BT_MAX_PAIRED];
29 
30 static bool all_startup_checks_executed;
31 
32 BUILD_ASSERT(ARRAY_SIZE(testing_id_addr_pair_lut) == CONFIG_BT_MAX_PAIRED);
33 BUILD_ASSERT(ARRAY_SIZE(testing_id_addr_pair_lut) == ARRAY_SIZE(returned_keys_refs));
34 
startup_suite_predicate(const void * global_state)35 static bool startup_suite_predicate(const void *global_state)
36 {
37 	return (all_startup_checks_executed == false);
38 }
39 
40 ZTEST_SUITE(bt_keys_get_addr_startup, startup_suite_predicate, NULL, NULL, NULL, NULL);
41 
42 /*
43  *  Check if the keys pool list is empty after starting up
44  *
45  *  Constraints:
46  *   - Check is executed after starting up, prior to adding any keys
47  *
48  *  Expected behaviour:
49  *   - Keys pool list is empty
50  */
ZTEST(bt_keys_get_addr_startup,test_keys_pool_list_is_empty_at_startup)51 ZTEST(bt_keys_get_addr_startup, test_keys_pool_list_is_empty_at_startup)
52 {
53 	zassert_true(check_key_pool_is_empty(),
54 		     "List isn't empty, make sure to run this test just after a fresh start");
55 }
56 
57 ZTEST_SUITE(bt_keys_get_addr_populate_non_existing_keys, NULL, NULL, NULL, NULL, NULL);
58 
59 /*
60  *  Test filling the keys pool with (ID, Address) pairs
61  *
62  *  Constraints:
63  *   - Keys pool list is empty after starting up
64  *
65  *  Expected behaviour:
66  *   - A valid reference is returned by bt_keys_get_addr()
67  *   - ID value matches the one passed to bt_keys_get_addr()
68  *   - Address value matches the one passed to bt_keys_get_addr()
69  */
ZTEST(bt_keys_get_addr_populate_non_existing_keys,test_populate_key_pool)70 ZTEST(bt_keys_get_addr_populate_non_existing_keys, test_populate_key_pool)
71 {
72 	struct id_addr_pair const *current_params_vector;
73 	struct bt_keys *returned_key;
74 	uint8_t id;
75 	bt_addr_le_t *addr;
76 
77 	for (size_t i = 0; i < ARRAY_SIZE(testing_id_addr_pair_lut); i++) {
78 
79 		current_params_vector = &testing_id_addr_pair_lut[i];
80 		id = current_params_vector->id;
81 		addr = current_params_vector->addr;
82 
83 		returned_key = bt_keys_get_addr(id, addr);
84 		returned_keys_refs[i] = returned_key;
85 
86 		zassert_true(returned_key != NULL,
87 			     "bt_keys_get_addr() failed to add key %d to the keys pool", i);
88 		zassert_true(returned_key->id == id,
89 			     "bt_keys_get_addr() returned a reference with an incorrect ID");
90 		zassert_true(!bt_addr_le_cmp(&returned_key->addr, addr),
91 			     "bt_keys_get_addr() set incorrect address %s value, expected %s",
92 			     bt_addr_le_str(&returned_key->addr), bt_addr_le_str(addr));
93 	}
94 }
95 
96 /*
97  *  Test no equal references returned by bt_keys_get_addr()
98  *
99  *  Constraints:
100  *   - Keys pool has been filled
101  *
102  *  Expected behaviour:
103  *   - All returned references are different from each other
104  */
ZTEST(bt_keys_get_addr_populate_non_existing_keys,test_no_equal_references)105 ZTEST(bt_keys_get_addr_populate_non_existing_keys, test_no_equal_references)
106 {
107 	struct bt_keys *keys_pool = bt_keys_get_key_pool();
108 
109 	for (uint32_t i = 0; i < ARRAY_SIZE(returned_keys_refs); i++) {
110 		struct bt_keys *returned_ref = returned_keys_refs[i];
111 
112 		zassert_equal_ptr(keys_pool + i, returned_ref,
113 				  "bt_keys_get_addr() returned unexpected reference at slot %u", i);
114 	}
115 }
116 
117 /* Setup test variables */
test_case_setup(void * f)118 static void test_case_setup(void *f)
119 {
120 	clear_key_pool();
121 
122 	int rv = fill_key_pool_by_id_addr(testing_id_addr_pair_lut,
123 					  ARRAY_SIZE(testing_id_addr_pair_lut), returned_keys_refs);
124 
125 	zassert_true(rv == 0, "Failed to fill keys pool list, error code %d", -rv);
126 }
127 
128 ZTEST_SUITE(bt_keys_get_addr_get_existing_keys, NULL, NULL, test_case_setup, NULL, NULL);
129 
130 /*
131  *  Test getting a valid key reference by a matching ID and address pair
132  *
133  *  Constraints:
134  *   - ID and address pairs has been inserted in the list
135  *
136  *  Expected behaviour:
137  *   - A valid reference is returned by bt_keys_get_addr() that
138  *     matches the one returned after adding the ID and address pair
139  *   - ID value matches the one passed to bt_keys_get_addr()
140  *   - Address value matches the one passed to bt_keys_get_addr()
141  */
ZTEST(bt_keys_get_addr_get_existing_keys,test_get_key_by_matched_id_and_address)142 ZTEST(bt_keys_get_addr_get_existing_keys, test_get_key_by_matched_id_and_address)
143 {
144 	struct bt_keys *returned_key, *expected_key_ref;
145 	struct id_addr_pair const *current_params_vector;
146 	uint8_t id;
147 	bt_addr_le_t *addr;
148 
149 	for (size_t i = 0; i < ARRAY_SIZE(testing_id_addr_pair_lut); i++) {
150 		current_params_vector = &testing_id_addr_pair_lut[i];
151 		id = current_params_vector->id;
152 		addr = current_params_vector->addr;
153 
154 		returned_key = bt_keys_get_addr(id, addr);
155 		expected_key_ref = returned_keys_refs[i];
156 
157 		zassert_true(returned_key != NULL,
158 			     "bt_keys_get_addr() failed to add key %d to the keys pool", i);
159 		zassert_equal_ptr(returned_key, expected_key_ref,
160 				  "bt_keys_get_addr() returned unexpected reference");
161 	}
162 }
163 
fff_reset_rule_before(const struct ztest_unit_test * test,void * fixture)164 static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
165 {
166 
167 	/* Skip tests if not all startup suite hasn't been executed */
168 	if (strcmp(test->test_suite_name, "bt_keys_get_addr_startup")) {
169 		if (all_startup_checks_executed != true) {
170 			ztest_test_skip();
171 		}
172 	}
173 
174 	CONN_FFF_FAKES_LIST(RESET_FAKE);
175 	HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
176 }
177 
178 ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
179 
test_main(void)180 void test_main(void)
181 {
182 	/* Only startup suite will run. */
183 	all_startup_checks_executed = false;
184 	ztest_run_all(NULL, false, 1, 1);
185 
186 	/* All other suites, except startup suite, will run. */
187 	all_startup_checks_executed = true;
188 	ztest_run_all(NULL, false, 1, 1);
189 
190 	/* Check that all the suites in this binary ran at least once. */
191 	ztest_verify_all_test_suites_ran();
192 }
193