Skip to content

Commit

Permalink
Bluetooth: host: add l2cap stress-test
Browse files Browse the repository at this point in the history
This test reproduces more-or-less #34600.

It has a central that connects to multiple peripherals, opens one l2cap CoC
channel per connection, and transmits a few SDUs largely exceeding the MPS
of the channel.

In this commit, the test doesn't pass, but when it passes (after the
subsequent commits), error and warning messages are expected from the
stack, as this is not the happy path.

We can later debate on whether these particular error messages should be
downgraded to debug.

Signed-off-by: Jonathan Rico <[email protected]>
  • Loading branch information
jori-nordic authored and carlescufi committed Sep 26, 2022
1 parent b15e645 commit 7a6872d
Show file tree
Hide file tree
Showing 7 changed files with 623 additions and 0 deletions.
21 changes: 21 additions & 0 deletions tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

if (NOT DEFINED ENV{BSIM_COMPONENTS_PATH})
message(FATAL_ERROR "This test requires the BabbleSim simulator. Please set\
the environment variable BSIM_COMPONENTS_PATH to point to its components \
folder. More information can be found in\
https://babblesim.github.io/folder_structure_and_env.html")
endif()

find_package(Zephyr HINTS $ENV{ZEPHYR_BASE})
project(bsim_test_l2cap_stress)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources} )

zephyr_include_directories(
$ENV{BSIM_COMPONENTS_PATH}/libUtilv1/src/
$ENV{BSIM_COMPONENTS_PATH}/libPhyComv1/src/
)
45 changes: 45 additions & 0 deletions tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
CONFIG_BT=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="L2CAP stress test"

CONFIG_BT_EATT=n
CONFIG_BT_L2CAP_ECRED=n

CONFIG_BT_SMP=y # Next config depends on it
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y

# Disable auto-initiated procedures so they don't
# mess with the test's execution.
CONFIG_BT_AUTO_PHY_UPDATE=n
CONFIG_BT_AUTO_DATA_LEN_UPDATE=n
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n

# L2CAP MPS
# 23+27+27=77 makes exactly three full packets
CONFIG_BT_L2CAP_TX_MTU=77
CONFIG_BT_BUF_ACL_TX_SIZE=77
CONFIG_BT_BUF_ACL_TX_COUNT=4

# The minimum value for this is
# L2AP MPS + L2CAP header (4)
CONFIG_BT_BUF_ACL_RX_SIZE=81

# TODO: find out why we can't use 16 buffers. It should fit.

CONFIG_BT_L2CAP_TX_BUF_COUNT=30
# CONFIG_BT_L2CAP_TX_BUF_COUNT=100

CONFIG_BT_BUF_ACL_TX_COUNT=4

CONFIG_BT_CTLR_RX_BUFFERS=10
# The ring buffer now has space for three times as much data
# (default 27, 3*27=81), so that it does not run out of data
# while waiting for new SDUs to be queued.
CONFIG_BT_CTLR_DATA_LENGTH_MAX=81

CONFIG_BT_MAX_CONN=10

CONFIG_LOG=y
CONFIG_ASSERT=y
CONFIG_BT_DEBUG_LOG=y
22 changes: 22 additions & 0 deletions tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/src/common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "common.h"

extern enum bst_result_t bst_result;

void test_init(void)
{
bst_ticker_set_next_tick_absolute(WAIT_TIME);
bst_result = In_progress;
}

void test_tick(bs_time_t HW_device_time)
{
if (bst_result != Passed) {
FAIL("test failed (not passed after %i seconds)\n", WAIT_SECONDS);
}
}
57 changes: 57 additions & 0 deletions tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/src/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Common functions and helpers for L2CAP tests
*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stddef.h>

#include <zephyr/types.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/byteorder.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/l2cap.h>
#include "bs_types.h"
#include "bs_tracing.h"
#include "bstests.h"
#include "bs_pc_backchannel.h"

extern enum bst_result_t bst_result;

#define CREATE_FLAG(flag) static atomic_t flag = (atomic_t)false
#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t)true)
#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t)false)
#define TEST_FLAG(flag) (atomic_get(&flag) == (atomic_t)true)
#define WAIT_FOR_FLAG_SET(flag) \
while (!(bool)atomic_get(&flag)) { \
(void)k_sleep(K_MSEC(1)); \
}
#define WAIT_FOR_FLAG_UNSET(flag) \
while ((bool)atomic_get(&flag)) { \
(void)k_sleep(K_MSEC(1)); \
}


#define WAIT_SECONDS 120 /* seconds */
#define WAIT_TIME (WAIT_SECONDS * USEC_PER_SEC) /* microseconds*/

#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)

#define ASSERT(expr, ...) if (!(expr)) {FAIL(__VA_ARGS__); }

void test_init(void);
void test_tick(bs_time_t HW_device_time);
Loading

0 comments on commit 7a6872d

Please sign in to comment.