mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
test(ble_log): add on-target test app for the version info frame
New ble_log_test app captures the runtime hook output through the test peripheral and validates the version info frame: source code, BLE Log version, a hex-valid idf commit that must be non-zero, per-lib commit fields non-zero exactly when the matching lib is linked, and chip model/revision matching esp_chip_info(). The README carries the generated empty Supported Targets table to match the build-test manifest. The test drives transports via sustained writes instead of ble_log_flush(): the flush window disables the module, so hook frames written during a flush would be dropped. Also move .build-test-rules.yml from ble_log_perf_test/ to the test_apps/ root (one manifest entry per app, as elsewhere in ESP-IDF). Both apps stay disabled until BLE Log test runners are available. Verified: full esp32c6 build of the app; the build-test checker's own parsing logic confirms the README table matches the manifest.
This commit is contained in:
17
components/bt/common/ble_log/test_apps/.build-test-rules.yml
Normal file
17
components/bt/common/ble_log/test_apps/.build-test-rules.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/bt/common/ble_log/test_apps/ble_log_perf_test:
|
||||
disable:
|
||||
- if: IDF_TARGET != "none"
|
||||
temporary: true
|
||||
reason: No BLE Log test runners are available yet
|
||||
depends_components:
|
||||
- bt
|
||||
|
||||
components/bt/common/ble_log/test_apps/ble_log_test:
|
||||
disable:
|
||||
- if: IDF_TARGET != "none"
|
||||
temporary: true
|
||||
reason: No BLE Log test runners are available yet
|
||||
depends_components:
|
||||
- bt
|
||||
@@ -1,9 +0,0 @@
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/bt/common/ble_log/test_apps:
|
||||
disable:
|
||||
- if: IDF_TARGET != "none"
|
||||
temporary: true
|
||||
reason: No BLE Log test runners are available yet
|
||||
depends_components:
|
||||
- bt
|
||||
@@ -0,0 +1,13 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
#
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
list(PREPEND SDKCONFIG_DEFAULTS
|
||||
"$ENV{IDF_PATH}/tools/test_apps/configs/sdkconfig.debug_helpers"
|
||||
"sdkconfig.defaults")
|
||||
set(COMPONENTS main)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(ble_log_test)
|
||||
@@ -0,0 +1,18 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# BLE Log Functional Test
|
||||
|
||||
| Supported Targets |
|
||||
| ----------------- |
|
||||
|
||||
This test app verifies the BLE Log runtime behaviour on target, using the
|
||||
in-memory test peripheral (`CONFIG_BLE_LOG_PRPH_TEST=y`) to capture the
|
||||
transport stream written by the runtime task hook.
|
||||
|
||||
Currently covered:
|
||||
|
||||
- `BLE_LOG_INT_SRC_VERSION_INFO` frame: BLE Log version, ESP-IDF build commit,
|
||||
controller lib commit, btdm_common lib commit, BLE Mesh and BLE Audio lib
|
||||
commits, chip model and chip revision
|
||||
@@ -0,0 +1,17 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
idf_component_register(
|
||||
SRCS "test_ble_log_main.c" "test_ble_log_rt.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES unity bt esp_hw_support esp_timer
|
||||
WHOLE_ARCHIVE
|
||||
)
|
||||
|
||||
idf_component_get_property(bt_dir bt COMPONENT_DIR)
|
||||
target_include_directories(${COMPONENT_LIB} PRIVATE
|
||||
"${bt_dir}/common/ble_log/include"
|
||||
"${bt_dir}/common/ble_log/src/internal_include"
|
||||
"${bt_dir}/common/ble_log/src/internal_include/prph"
|
||||
)
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_runner.h"
|
||||
|
||||
#include "ble_log.h"
|
||||
#include "ble_log_lbm.h"
|
||||
#include "test_ble_log_main.h"
|
||||
|
||||
bool test_ble_log_walk_frames(const uint8_t *data, size_t len,
|
||||
test_ble_log_frame_observer_t observer, void *ctx)
|
||||
{
|
||||
size_t offset = 0;
|
||||
while (len - offset >= BLE_LOG_FRAME_OVERHEAD) {
|
||||
ble_log_frame_head_t head;
|
||||
memcpy(&head, data + offset, sizeof(head));
|
||||
|
||||
size_t frame_len = BLE_LOG_FRAME_OVERHEAD + head.length;
|
||||
if (frame_len > len - offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t checksum;
|
||||
memcpy(&checksum, data + offset + BLE_LOG_FRAME_HEAD_LEN + head.length,
|
||||
sizeof(checksum));
|
||||
if (checksum != ble_log_fast_checksum(data + offset,
|
||||
BLE_LOG_FRAME_HEAD_LEN + head.length)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (observer) {
|
||||
test_ble_log_frame_t frame = {
|
||||
.src = head.frame_meta & 0xff,
|
||||
.sn = head.frame_meta >> 8,
|
||||
.payload = data + offset + BLE_LOG_FRAME_HEAD_LEN,
|
||||
.payload_len = head.length,
|
||||
};
|
||||
observer(&frame, ctx);
|
||||
}
|
||||
offset += frame_len;
|
||||
}
|
||||
return offset == len;
|
||||
}
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/* The BLE Log module has no automatic system init on this branch; the
|
||||
* controller normally calls ble_log_init(). Initialize it explicitly. */
|
||||
TEST_ASSERT_TRUE_MESSAGE(ble_log_init(), "BLE Log init failed");
|
||||
unity_run_menu();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ble_log.h"
|
||||
|
||||
typedef struct {
|
||||
ble_log_src_t src;
|
||||
uint32_t sn;
|
||||
const uint8_t *payload;
|
||||
size_t payload_len;
|
||||
} test_ble_log_frame_t;
|
||||
|
||||
typedef void (*test_ble_log_frame_observer_t)(const test_ble_log_frame_t *frame, void *ctx);
|
||||
|
||||
/* Walks a captured transport buffer, validating frame headers and checksums.
|
||||
* Returns true when the whole buffer consists of valid frames. */
|
||||
bool test_ble_log_walk_frames(const uint8_t *data, size_t len,
|
||||
test_ble_log_frame_observer_t observer, void *ctx);
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_chip_info.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
#include "unity.h"
|
||||
|
||||
#include "ble_log.h"
|
||||
#include "ble_log_prph_test.h"
|
||||
#include "ble_log_rt.h"
|
||||
#include "test_ble_log_main.h"
|
||||
|
||||
#if !CONFIG_BLE_LOG_PRPH_TEST
|
||||
#error "BLE Log test app requires CONFIG_BLE_LOG_PRPH_TEST"
|
||||
#endif
|
||||
|
||||
/* The runtime task hook is throttled to one pass per
|
||||
* BLE_LOG_TS_TRIGGER_TIMEOUT_MS; let the window elapse between write bursts
|
||||
* so a hook pass is guaranteed to run after the settle delay. */
|
||||
#define TEST_HOOK_SETTLE_MS (BLE_LOG_TS_TRIGGER_TIMEOUT_MS + 100)
|
||||
#define TEST_READ_TIMEOUT_MS (50)
|
||||
#define TEST_MAX_ROUNDS (3)
|
||||
#define TEST_WRITES_PER_ROUND (64)
|
||||
#define TEST_PAYLOAD_LEN (64)
|
||||
#define TEST_READ_BUF_SIZE (4096)
|
||||
#define TEST_READER_STACK_SIZE (3072)
|
||||
#define TEST_READER_PRIO (2)
|
||||
|
||||
typedef struct {
|
||||
size_t version_info_count;
|
||||
ble_log_version_info_t version_info;
|
||||
} version_capture_t;
|
||||
|
||||
typedef struct {
|
||||
version_capture_t capture;
|
||||
bool malformed;
|
||||
volatile bool stop;
|
||||
SemaphoreHandle_t done;
|
||||
} reader_ctx_t;
|
||||
|
||||
static uint8_t s_read_buf[TEST_READ_BUF_SIZE];
|
||||
|
||||
/* A commit field is hex characters, zero-padded after a shorter value;
|
||||
* anything else (garbage, non-hex, zeros after data) is invalid. */
|
||||
static bool commit_is_valid(const uint8_t *commit, size_t len)
|
||||
{
|
||||
bool padding = false;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (commit[i] == 0) {
|
||||
padding = true;
|
||||
continue;
|
||||
}
|
||||
if (padding ||
|
||||
!((commit[i] >= '0' && commit[i] <= '9') ||
|
||||
(commit[i] >= 'a' && commit[i] <= 'f') ||
|
||||
(commit[i] >= 'A' && commit[i] <= 'F'))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool commit_is_zero(const uint8_t *commit, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (commit[i] != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void capture_version_info_frame(const test_ble_log_frame_t *frame, void *ctx)
|
||||
{
|
||||
version_capture_t *capture = ctx;
|
||||
/* Every frame payload starts with a 4-byte timestamp prefix */
|
||||
const uint8_t *record = frame->payload + sizeof(uint32_t);
|
||||
size_t record_len = frame->payload_len - sizeof(uint32_t);
|
||||
|
||||
if (frame->src == BLE_LOG_SRC_INTERNAL &&
|
||||
record_len == sizeof(ble_log_version_info_t) &&
|
||||
record[0] == BLE_LOG_INT_SRC_VERSION_INFO) {
|
||||
memcpy(&capture->version_info, record, sizeof(capture->version_info));
|
||||
capture->version_info_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Consumes pending test transports concurrently with the writer: transports
|
||||
* are recycled only once read, and the LBM has a small pool of them. */
|
||||
static void test_reader_task(void *arg)
|
||||
{
|
||||
reader_ctx_t *ctx = arg;
|
||||
while (!ctx->stop) {
|
||||
size_t len = ble_log_prph_test_read(s_read_buf, sizeof(s_read_buf),
|
||||
pdMS_TO_TICKS(TEST_READ_TIMEOUT_MS), 0);
|
||||
if (len > 0 &&
|
||||
!test_ble_log_walk_frames(s_read_buf, len, capture_version_info_frame,
|
||||
&ctx->capture)) {
|
||||
ctx->malformed = true;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(ctx->done);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("BLE Log runtime hook reports build and chip versions", "[ble_log]")
|
||||
{
|
||||
static const uint8_t payload[TEST_PAYLOAD_LEN] = {0};
|
||||
|
||||
reader_ctx_t ctx = {0};
|
||||
ctx.done = xSemaphoreCreateBinary();
|
||||
TEST_ASSERT_NOT_NULL(ctx.done);
|
||||
|
||||
TaskHandle_t reader;
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xTaskCreate(test_reader_task, "ble_log_rd",
|
||||
TEST_READER_STACK_SIZE, &ctx,
|
||||
TEST_READER_PRIO, &reader));
|
||||
TEST_ASSERT_TRUE(ble_log_enable(true));
|
||||
|
||||
/* Transports are auto-submitted once full, which wakes the runtime task;
|
||||
* after the throttle window elapses, a hook pass writes the version frame
|
||||
* into the LBM and a later transport carries it out. ble_log_flush()
|
||||
* cannot be used here: it disables the module while waiting for the
|
||||
* transports to drain, so the hook frame written during the flush window
|
||||
* would be dropped. */
|
||||
for (int round = 0; round < TEST_MAX_ROUNDS && ctx.capture.version_info_count == 0; round++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(TEST_HOOK_SETTLE_MS));
|
||||
for (int i = 0; i < TEST_WRITES_PER_ROUND; i++) {
|
||||
ble_log_write_hex(BLE_LOG_SRC_CUSTOM, payload, sizeof(payload));
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
}
|
||||
|
||||
ctx.stop = true;
|
||||
TEST_ASSERT_TRUE(xSemaphoreTake(ctx.done, pdMS_TO_TICKS(1000)));
|
||||
|
||||
TEST_ASSERT_FALSE(ctx.malformed);
|
||||
TEST_ASSERT_GREATER_OR_EQUAL_size_t(1, ctx.capture.version_info_count);
|
||||
|
||||
const ble_log_version_info_t *vi = &ctx.capture.version_info;
|
||||
TEST_ASSERT_EQUAL_UINT8(BLE_LOG_INT_SRC_VERSION_INFO, vi->int_src_code);
|
||||
TEST_ASSERT_EQUAL_UINT8(BLE_LOG_VERSION, vi->version);
|
||||
TEST_ASSERT_TRUE(commit_is_valid(vi->idf_commit, BLE_LOG_IDF_COMMIT_LEN));
|
||||
/* Built from an IDF git checkout; the build commit must be injected */
|
||||
TEST_ASSERT_FALSE(commit_is_zero(vi->idf_commit, BLE_LOG_IDF_COMMIT_LEN));
|
||||
TEST_ASSERT_TRUE(commit_is_valid(vi->controller_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
TEST_ASSERT_TRUE(commit_is_valid(vi->btdm_common_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
TEST_ASSERT_TRUE(commit_is_valid(vi->mesh_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
TEST_ASSERT_TRUE(commit_is_valid(vi->audio_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
/* A commit field is non-zero only when the matching lib is linked in */
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED && (!CONFIG_BT_DUAL_MODE_ARCH || CONFIG_BT_CTRL_BLE_ENABLE)
|
||||
TEST_ASSERT_FALSE(commit_is_zero(vi->controller_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
#else
|
||||
TEST_ASSERT_TRUE(commit_is_zero(vi->controller_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
#endif
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED && CONFIG_BT_DUAL_MODE_ARCH
|
||||
TEST_ASSERT_FALSE(commit_is_zero(vi->btdm_common_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
#else
|
||||
TEST_ASSERT_TRUE(commit_is_zero(vi->btdm_common_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH && CONFIG_BLE_MESH_V11_SUPPORT
|
||||
TEST_ASSERT_FALSE(commit_is_zero(vi->mesh_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
#else
|
||||
TEST_ASSERT_TRUE(commit_is_zero(vi->mesh_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
#endif
|
||||
#if CONFIG_BT_AUDIO && CONFIG_SOC_BLE_AUDIO_SUPPORTED
|
||||
TEST_ASSERT_FALSE(commit_is_zero(vi->audio_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
#else
|
||||
TEST_ASSERT_TRUE(commit_is_zero(vi->audio_commit, BLE_LOG_LIB_COMMIT_LEN));
|
||||
#endif
|
||||
|
||||
esp_chip_info_t chip_info;
|
||||
esp_chip_info(&chip_info);
|
||||
TEST_ASSERT_EQUAL_UINT16((uint16_t)chip_info.model, vi->chip_model);
|
||||
TEST_ASSERT_EQUAL_UINT16(chip_info.revision, vi->chip_revision);
|
||||
|
||||
vSemaphoreDelete(ctx.done);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BLE_LOG_ENABLED=y
|
||||
CONFIG_BLE_LOG_PRPH_TEST=y
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
||||
CONFIG_UNITY_ENABLE_64BIT=y
|
||||
CONFIG_BLE_MESH=y
|
||||
Reference in New Issue
Block a user