/* * Copyright (c) 2023 Codecoup * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include DEFINE_FFF_GLOBALS; FAKE_VALUE_FUNC(bool, bt_data_parse_func, struct bt_data *, void *); static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture) { RESET_FAKE(bt_data_parse_func); } ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL); ZTEST_SUITE(bt_data_parse, NULL, NULL, NULL, NULL, NULL); /* * Test empty data buffer * * Constraints: * - data.len set to 0 * * Expected behaviour: * - Callback function is not called */ ZTEST(bt_data_parse, test_parsing_empty_buf) { struct net_buf_simple *buf = NET_BUF_SIMPLE(0); bt_data_parse(buf, bt_data_parse_func, NULL); zassert_equal(bt_data_parse_func_fake.call_count, 0); } /* * Test AD Structure invalid length * * Constraints: * - AD Structure N length > number of bytes after * * Expected behaviour: * - Callback function is called N - 1 times */ ZTEST(bt_data_parse, test_parsing_invalid_length) { struct net_buf_simple buf; uint8_t data[] = { /* Significant part */ 0x02, 0x01, 0x00, /* AD Structure 1 */ 0x03, 0x02, 0x01, 0x00, /* AD Structure 2 */ /* Invalid length 0xff */ 0xff, 0x03, 0x02, 0x01, /* AD Structure N */ 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, /* AD Structure N + 1 */ }; bt_data_parse_func_fake.return_val = true; net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data)); bt_data_parse(&buf, bt_data_parse_func, NULL); zassert_equal(2, bt_data_parse_func_fake.call_count, "called %d", bt_data_parse_func_fake.call_count); } /* * Test early termination of the significant part * * Constraints: * - The significant part contains a sequence of N AD structures * - The non-significant part extends the data with all-zero octets * * Expected behaviour: * - Callback function is called N times */ ZTEST(bt_data_parse, test_parsing_early_termination) { struct net_buf_simple buf; uint8_t data[] = { /* Significant part */ 0x02, 0x01, 0x00, /* AD Structure 1 */ 0x03, 0x02, 0x01, 0x00, /* AD Structure 2 */ 0x04, 0x03, 0x02, 0x01, 0x00, /* AD Structure 3 */ /* Non-significant part */ 0x00, 0x00, 0x00, 0x00, 0x00 }; bt_data_parse_func_fake.return_val = true; net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data)); bt_data_parse(&buf, bt_data_parse_func, NULL); zassert_equal(3, bt_data_parse_func_fake.call_count, "called %d", bt_data_parse_func_fake.call_count); } /* * Test parsing stopped * * Constraints: * - Data contains valid AD Structures * - Callback function returns false to stop parsing * * Expected behaviour: * - Once parsing is stopped, the callback is not called anymore */ ZTEST(bt_data_parse, test_parsing_stopped) { struct net_buf_simple buf; uint8_t data[] = { /* Significant part */ 0x02, 0x01, 0x00, /* AD Structure 1 */ 0x03, 0x02, 0x01, 0x00, /* AD Structure 2 */ }; bt_data_parse_func_fake.return_val = false; net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data)); bt_data_parse(&buf, bt_data_parse_func, NULL); zassert_equal(1, bt_data_parse_func_fake.call_count, "called %d", bt_data_parse_func_fake.call_count); } struct custom_fake_user_data { const uint8_t *data; size_t len; }; static bool bt_data_parse_func_custom_fake(struct bt_data *data, void *user_data) { struct custom_fake_user_data *ud = user_data; /* length check */ zassert_true(ud->len-- > 0); zassert_equal(data->data_len, *ud->data - 1); ud->data++; /* type check */ zassert_true(ud->len-- > 0); zassert_equal(data->type, *ud->data); ud->data++; /* value check */ zassert_true(ud->len >= data->data_len); zassert_mem_equal(data->data, ud->data, data->data_len); ud->data += data->data_len; ud->len -= data->data_len; return true; } /* * Test parsing AD Data * * Constraints: * - Data contains valid AD Structures * - Callback function returns false to stop parsing * * Expected behaviour: * - Data passed to the callback match the expected data */ ZTEST(bt_data_parse, test_parsing_success) { struct net_buf_simple buf; uint8_t data[] = { /* Significant part */ 0x02, 0x01, 0x00, /* AD Structure 1 */ 0x03, 0x02, 0x01, 0x00, /* AD Structure 2 */ }; struct custom_fake_user_data user_data = { .data = data, .len = ARRAY_SIZE(data), }; bt_data_parse_func_fake.custom_fake = bt_data_parse_func_custom_fake; net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data)); bt_data_parse(&buf, bt_data_parse_func, &user_data); zassert_equal(2, bt_data_parse_func_fake.call_count, "called %d", bt_data_parse_func_fake.call_count); }