Browse Source

tests: upgrade: Upgrade with mcumgr using BLE transport

Extend tests/boot/with_mcumgr with BLE configuration.
Updated sample to use the source code from smp_svr.

Signed-off-by: Grzegorz Chwierut <grzegorz.chwierut@nordicsemi.no>
pull/92307/head
Grzegorz Chwierut 4 weeks ago committed by Benjamin Cabé
parent
commit
1f92890283
  1. 5
      tests/boot/with_mcumgr/CMakeLists.txt
  2. 14
      tests/boot/with_mcumgr/README.rst
  3. 47
      tests/boot/with_mcumgr/overlay-bt.conf
  4. 48
      tests/boot/with_mcumgr/prj.conf
  5. 19
      tests/boot/with_mcumgr/pytest/conftest.py
  6. 4
      tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py
  7. 26
      tests/boot/with_mcumgr/pytest/test_upgrade.py
  8. 16
      tests/boot/with_mcumgr/pytest/test_upgrade_ble.py
  9. 14
      tests/boot/with_mcumgr/src/main.c
  10. 1
      tests/boot/with_mcumgr/sysbuild/mcuboot.conf
  11. 12
      tests/boot/with_mcumgr/testcase.yaml

5
tests/boot/with_mcumgr/CMakeLists.txt

@ -5,5 +5,6 @@ cmake_minimum_required(VERSION 3.20.0) @@ -5,5 +5,6 @@ cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(with_mcumgr)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
# This project uses orginal C source code from smp_svr sample
target_sources(app PRIVATE ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/main.c)
target_sources_ifdef(CONFIG_MCUMGR_TRANSPORT_BT app PRIVATE ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c)

14
tests/boot/with_mcumgr/README.rst

@ -19,8 +19,18 @@ use following command: @@ -19,8 +19,18 @@ use following command:
-p nrf52840dk/nrf52840 --device-testing --device-serial /dev/ttyACM0
.. note::
Twister requires ``--west-flash`` flag enabled (without additional parameters
like ``erase``) to use sysbuild.
Twister requires ``--west-flash`` flag enabled to use sysbuild.
To test with ``mcumgr`` with Bluetooth, one must add ``usb_hci:hciX`` fixture
where ``hciX`` is the Bluetooth HCI device (e.g. ``hci1``).
Fixture can be added to Twister command: ``-X usb_hci:hci1``,
or added to the hardware map
.. code-block:: yaml
- connected: true
fixtures:
- usb_hci:hci1
Test scripts can be found in ``pytest`` directory. To list available
scenarios with described procedures, one can use a pytest command:

47
tests/boot/with_mcumgr/overlay-bt.conf

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
# Allow for large Bluetooth data packets.
CONFIG_BT_L2CAP_TX_MTU=498
CONFIG_BT_BUF_ACL_RX_SIZE=502
CONFIG_BT_BUF_ACL_TX_SIZE=502
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
# Enable the Bluetooth mcumgr transport (unauthenticated).
CONFIG_MCUMGR_TRANSPORT_BT=y
CONFIG_MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL=y
# Enable the Shell mcumgr transport.
CONFIG_BASE64=y
CONFIG_CRC=y
CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_SERIAL=y
CONFIG_MCUMGR_TRANSPORT_SHELL=y
# Enable the mcumgr Packet Reassembly feature over Bluetooth and its configuration dependencies.
# MCUmgr buffer size is optimized to fit one SMP packet divided into five Bluetooth Write Commands,
# transmitted with the maximum possible MTU value: 498 bytes.
CONFIG_MCUMGR_TRANSPORT_BT_REASSEMBLY=y
CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE=2475
CONFIG_MCUMGR_GRP_OS_MCUMGR_PARAMS=y
CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=4608
# Enable the LittleFS file system.
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
# Enable file system commands
CONFIG_MCUMGR_GRP_FS=y
# Enable the storage erase command.
CONFIG_MCUMGR_GRP_ZBASIC=y
CONFIG_MCUMGR_GRP_ZBASIC_STORAGE_ERASE=y
# Disable Bluetooth ping support
CONFIG_BT_CTLR_LE_PING=n
# Disable shell commands that are not needed
CONFIG_CLOCK_CONTROL_NRF_SHELL=n
CONFIG_DEVICE_SHELL=n
CONFIG_DEVMEM_SHELL=n
CONFIG_FLASH_SHELL=n

48
tests/boot/with_mcumgr/prj.conf

@ -6,18 +6,50 @@ CONFIG_MCUMGR=y @@ -6,18 +6,50 @@ CONFIG_MCUMGR=y
CONFIG_STREAM_FLASH=y
CONFIG_FLASH_MAP=y
# Enable the shell MCUmgr transport.
CONFIG_BASE64=y
CONFIG_SHELL=y
CONFIG_MCUBOOT_SHELL=y
CONFIG_SHELL_BACKEND_SERIAL=y
CONFIG_MCUMGR_TRANSPORT_SHELL=y
# Some command handlers require a large stack.
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304
CONFIG_MAIN_STACK_SIZE=2048
# Ensure an MCUboot-compatible binary is generated.
CONFIG_BOOTLOADER_MCUBOOT=y
# Enable flash operations.
CONFIG_FLASH=y
# Required by the `taskstat` command.
CONFIG_THREAD_MONITOR=y
# Support for taskstat command
CONFIG_MCUMGR_GRP_OS_TASKSTAT=y
# Enable statistics and statistic names.
CONFIG_STATS=y
CONFIG_STATS_NAMES=y
# Enable most core commands.
CONFIG_FLASH=y
CONFIG_IMG_MANAGER=y
CONFIG_MCUMGR_GRP_IMG=y
CONFIG_MCUMGR_GRP_OS=y
CONFIG_MCUMGR_GRP_STAT=y
# Enable logging
CONFIG_LOG=y
CONFIG_MCUBOOT_UTIL_LOG_LEVEL_WRN=y
# Disable debug logging
CONFIG_LOG_MAX_LEVEL=3
# Enable the Shell mcumgr transport.
CONFIG_BASE64=y
CONFIG_CRC=y
CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_SERIAL=y
CONFIG_MCUMGR_TRANSPORT_SHELL=y
CONFIG_MCUBOOT_SHELL=y
# mcumgr-cli application doesn't accepts log in the channel it uses
CONFIG_SHELL_LOG_BACKEND=n
# Disable shell commands that are not needed
CONFIG_CLOCK_CONTROL_NRF_SHELL=n
CONFIG_DEVICE_SHELL=n
CONFIG_DEVMEM_SHELL=n
CONFIG_FLASH_SHELL=n

19
tests/boot/with_mcumgr/pytest/conftest.py

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
import os
import sys
# Add the directory to PYTHONPATH
zephyr_base = os.getenv("ZEPHYR_BASE")
if zephyr_base:
sys.path.insert(
0, os.path.join(zephyr_base, "scripts", "pylib", "pytest-twister-harness", "src")
)
else:
raise OSError("ZEPHYR_BASE environment variable is not set")
pytest_plugins = [
"twister_harness.plugin",
]

4
tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py

@ -6,7 +6,7 @@ from __future__ import annotations @@ -6,7 +6,7 @@ from __future__ import annotations
import logging
from pathlib import Path
from test_upgrade import create_signed_image
from test_upgrade import WELCOME_STRING, create_signed_image
from twister_harness import DeviceAdapter, MCUmgr, Shell
from twister_harness.helpers.utils import find_in_config, match_lines, match_no_lines
from utils import check_with_mcumgr_command, check_with_shell_command
@ -48,7 +48,7 @@ def test_downgrade_prevention(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): @@ -48,7 +48,7 @@ def test_downgrade_prevention(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
mcumgr.reset_device()
dut.connect()
output = dut.readlines_until('Launching primary slot application')
output = dut.readlines_until(WELCOME_STRING)
match_no_lines(output, ['Starting swap using move algorithm'])
match_lines(output, ['erased due to downgrade prevention'])
logger.info('Verify that the original APP is booted')

26
tests/boot/with_mcumgr/pytest/test_upgrade.py

@ -14,6 +14,9 @@ from west_sign_wrapper import west_sign_with_imgtool @@ -14,6 +14,9 @@ from west_sign_wrapper import west_sign_with_imgtool
logger = logging.getLogger(__name__)
# This string is used to verify that the device is running the application
WELCOME_STRING = "smp_sample: build time:"
def create_signed_image(build_dir: Path, app_build_dir: Path, version: str) -> Path:
image_to_test = Path(build_dir) / 'test_{}.signed.bin'.format(
@ -49,7 +52,7 @@ def clear_buffer(dut: DeviceAdapter) -> None: @@ -49,7 +52,7 @@ def clear_buffer(dut: DeviceAdapter) -> None:
dut.disconnect()
def test_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
def run_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
"""
Verify that the application can be updated
1) Device flashed with MCUboot and an application that contains SMP server
@ -77,7 +80,7 @@ def test_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): @@ -77,7 +80,7 @@ def test_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
mcumgr.reset_device()
dut.connect()
output = dut.readlines_until('Launching primary slot application')
output = dut.readlines_until(WELCOME_STRING)
upgrade_string_to_verify = get_upgrade_string_to_verify(dut.device_config.build_dir)
match_lines(output, [
'Swap type: test',
@ -93,7 +96,7 @@ def test_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): @@ -93,7 +96,7 @@ def test_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
mcumgr.reset_device()
dut.connect()
output = dut.readlines_until('Launching primary slot application')
output = dut.readlines_until(WELCOME_STRING)
match_no_lines(output, [
upgrade_string_to_verify
])
@ -101,6 +104,11 @@ def test_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): @@ -101,6 +104,11 @@ def test_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
check_with_shell_command(shell, new_version)
def test_upgrade_with_confirm(mcumgr: MCUmgr, dut: DeviceAdapter, shell: Shell):
"""Verify that the application can be updated over serial"""
run_upgrade_with_confirm(dut, shell, mcumgr)
def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
"""
Verify that MCUboot will roll back an image that is not confirmed
@ -133,7 +141,7 @@ def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): @@ -133,7 +141,7 @@ def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
mcumgr.reset_device()
dut.connect()
output = dut.readlines_until('Launching primary slot application')
output = dut.readlines_until(WELCOME_STRING)
upgrade_string_to_verify = get_upgrade_string_to_verify(dut.device_config.build_dir)
match_lines(output, [
'Swap type: test',
@ -148,7 +156,7 @@ def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): @@ -148,7 +156,7 @@ def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
mcumgr.reset_device()
dut.connect()
output = dut.readlines_until('Launching primary slot application')
output = dut.readlines_until(WELCOME_STRING)
match_lines(output, [
'Swap type: revert',
upgrade_string_to_verify
@ -159,10 +167,8 @@ def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): @@ -159,10 +167,8 @@ def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
@pytest.mark.parametrize(
'key_file', [None, 'root-ec-p256.pem'],
ids=[
'no_key',
'invalid_key'
])
ids=['no_key', 'invalid_key']
)
def test_upgrade_signature(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr, key_file):
"""
Verify that the application is not updated when app is not signed or signed with invalid key
@ -210,7 +216,7 @@ def test_upgrade_signature(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr, key @@ -210,7 +216,7 @@ def test_upgrade_signature(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr, key
mcumgr.reset_device()
dut.connect()
output = dut.readlines_until('Launching primary slot application')
output = dut.readlines_until(WELCOME_STRING)
upgrade_string_to_verify = get_upgrade_string_to_verify(dut.device_config.build_dir)
match_no_lines(output, [upgrade_string_to_verify])
match_lines(output, ['Image in the secondary slot is not valid'])

16
tests/boot/with_mcumgr/pytest/test_upgrade_ble.py

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import logging
from test_upgrade import run_upgrade_with_confirm
from twister_harness import DeviceAdapter, MCUmgrBle, Shell
logger = logging.getLogger(__name__)
def test_upgrade_with_confirm_ble(mcumgr_ble: MCUmgrBle, dut: DeviceAdapter, shell: Shell):
"""Verify that the application can be updated over BLE"""
run_upgrade_with_confirm(dut, shell, mcumgr_ble)

14
tests/boot/with_mcumgr/src/main.c

@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
/* Main entry point */
int main(void)
{
printk("Launching primary slot application on %s\n", CONFIG_BOARD);
return 0;
}

1
tests/boot/with_mcumgr/sysbuild/mcuboot.conf

@ -1 +0,0 @@ @@ -1 +0,0 @@
CONFIG_MCUBOOT_LOG_LEVEL_INF=y

12
tests/boot/with_mcumgr/testcase.yaml

@ -22,6 +22,18 @@ tests: @@ -22,6 +22,18 @@ tests:
pytest_root:
- "pytest/test_upgrade.py"
boot.with_mcumgr.test_upgrade_ble:
platform_allow:
- nrf52840dk/nrf52840
integration_platforms:
- nrf52840dk/nrf52840
extra_args: EXTRA_CONF_FILE="overlay-bt.conf"
harness: pytest
harness_config:
fixture: usb_hci
pytest_root:
- "pytest/test_upgrade_ble.py"
boot.with_mcumgr.test_downgrade_prevention:
platform_allow:
- nrf52840dk/nrf52840

Loading…
Cancel
Save