tests/mgmt/mcumgr/smp_reassembly: Unit tests for re-assembly
The commit adds unit tests for SMP packet re-assembly. Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
This commit is contained in:
parent
d0499d112a
commit
a99118d140
6 changed files with 275 additions and 1 deletions
15
tests/subsys/mgmt/smp_reassembly/CMakeLists.txt
Normal file
15
tests/subsys/mgmt/smp_reassembly/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(smp_reassembly)
|
||||
|
||||
FILE(GLOB app_sources
|
||||
src/*.c
|
||||
)
|
||||
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/mgmt/mcumgr/)
|
||||
target_sources(app PRIVATE ${app_sources})
|
14
tests/subsys/mgmt/smp_reassembly/Kconfig
Normal file
14
tests/subsys/mgmt/smp_reassembly/Kconfig
Normal file
|
@ -0,0 +1,14 @@
|
|||
#
|
||||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
mainmenu "SMP Reassembly unit test"
|
||||
|
||||
config MCUMGR_SMP_REASSEMBLY_UNIT_TESTS
|
||||
def_bool y
|
||||
select MCUMGR_SMP_REASSEMBLY
|
||||
help
|
||||
Enable SMP Reassembly unit tests.
|
||||
|
||||
source "Kconfig.zephyr"
|
10
tests/subsys/mgmt/smp_reassembly/prj.conf
Normal file
10
tests/subsys/mgmt/smp_reassembly/prj.conf
Normal file
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
CONFIG_ZTEST=y
|
||||
# THis is annoying
|
||||
CONFIG_TINYCBOR=y
|
||||
CONFIG_MCUMGR=y
|
||||
CONFIG_MCUMGR_BUF_COUNT=1
|
217
tests/subsys/mgmt/smp_reassembly/src/main.c
Normal file
217
tests/subsys/mgmt/smp_reassembly/src/main.c
Normal file
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <ztest.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <net/buf.h>
|
||||
#include <mgmt/mcumgr/smp.h>
|
||||
#include <mgmt/mcumgr/buf.h>
|
||||
#include <mgmt/mgmt.h>
|
||||
#include "../../../../../subsys/mgmt/mcumgr/smp_reassembly.h"
|
||||
|
||||
static struct zephyr_smp_transport zst;
|
||||
static uint8_t buff[CONFIG_MCUMGR_BUF_SIZE];
|
||||
#define TEST_FRAME_SIZE 256
|
||||
|
||||
static struct net_buf *backup;
|
||||
|
||||
/* The function is called by zephyr_smp_reassembly_complete to pass a completed packet
|
||||
* for further processing; since there is nothing to process, this stub will only backup
|
||||
* buffer the pointer to allow a test case to free it with use of the mcumgr net_buf
|
||||
* management.
|
||||
*/
|
||||
void zephyr_smp_rx_req(struct zephyr_smp_transport *zst, struct net_buf *nb)
|
||||
{
|
||||
backup = nb;
|
||||
}
|
||||
|
||||
void test_first(void)
|
||||
{
|
||||
zephyr_smp_reassembly_init(&zst);
|
||||
struct mgmt_hdr *mh = (struct mgmt_hdr *)buff;
|
||||
int frag_used;
|
||||
int ret;
|
||||
int expected;
|
||||
|
||||
/** First fragment errors **/
|
||||
/* Len longer than netbuf error */
|
||||
zassert_equal(-ENOSR, zephyr_smp_reassembly_collect(&zst, buff, CONFIG_MCUMGR_BUF_SIZE + 1),
|
||||
"Expected -ENOSR error");
|
||||
/* Len not enough to read expected size from header */
|
||||
zassert_equal(-ENODATA,
|
||||
zephyr_smp_reassembly_collect(&zst, buff, sizeof(struct mgmt_hdr) - 1),
|
||||
"Expected -ENODATA error");
|
||||
/* Length extracted from header, plus size of header, is bigger than buffer */
|
||||
mh->nh_len = sys_cpu_to_be16(CONFIG_MCUMGR_BUF_SIZE - sizeof(struct mgmt_hdr) + 1);
|
||||
zassert_equal(-ENOSR,
|
||||
zephyr_smp_reassembly_collect(&zst, buff, sizeof(struct mgmt_hdr) + 1),
|
||||
"Expected -ENOSR error");
|
||||
|
||||
/* Successfully alloc buffer */
|
||||
mh->nh_len = sys_cpu_to_be16(TEST_FRAME_SIZE - sizeof(struct mgmt_hdr));
|
||||
frag_used = 40;
|
||||
expected = TEST_FRAME_SIZE - frag_used;
|
||||
ret = zephyr_smp_reassembly_collect(&zst, buff, frag_used);
|
||||
zassert_equal(expected, ret,
|
||||
"Expected is %d should be %d\n", ret, expected);
|
||||
|
||||
/* Force complete it, expected returned number of bytes missing */
|
||||
ret = zephyr_smp_reassembly_complete(&zst, true);
|
||||
zassert_equal(expected, ret,
|
||||
"Forced completion ret %d, but expected was %d\n", ret, expected);
|
||||
|
||||
/* Check fail due to lack of buffers: there is only one buffer and it already got passed
|
||||
* for processing by complete
|
||||
*/
|
||||
ret = zephyr_smp_reassembly_collect(&zst, buff, frag_used);
|
||||
zassert_equal(-ENOMEM, ret,
|
||||
"Expected is %d should be %d\n", ret, expected);
|
||||
|
||||
/* This will normally be done by packet processing and should not be done by hand:
|
||||
* release the buffer to the pool
|
||||
*/
|
||||
mcumgr_buf_free(backup);
|
||||
|
||||
}
|
||||
|
||||
void test_drops(void)
|
||||
{
|
||||
struct mgmt_hdr *mh = (struct mgmt_hdr *)buff;
|
||||
int frag_used;
|
||||
int ret;
|
||||
int expected;
|
||||
|
||||
/* Collect one buffer and drop it */
|
||||
mh->nh_len = sys_cpu_to_be16(TEST_FRAME_SIZE - sizeof(struct mgmt_hdr));
|
||||
frag_used = 40;
|
||||
expected = TEST_FRAME_SIZE - frag_used;
|
||||
ret = zephyr_smp_reassembly_collect(&zst, buff, frag_used);
|
||||
zassert_equal(expected, ret,
|
||||
"Expected is %d should be %d\n", ret, expected);
|
||||
|
||||
ret = zephyr_smp_reassembly_drop(&zst);
|
||||
zassert_equal(0, ret,
|
||||
"Expected %d from drop, got %d", ret, expected);
|
||||
}
|
||||
|
||||
void test_collection(void)
|
||||
{
|
||||
struct mgmt_hdr *mh = (struct mgmt_hdr *)buff;
|
||||
int pkt_used;
|
||||
int ret;
|
||||
int expected;
|
||||
int frag;
|
||||
void *p;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(buff); i++) {
|
||||
buff[i] = (i % 255) + 1;
|
||||
}
|
||||
|
||||
/** Collect fragments **/
|
||||
/* First fragment with header */
|
||||
mh->nh_len = sys_cpu_to_be16(TEST_FRAME_SIZE - sizeof(struct mgmt_hdr));
|
||||
frag = 40;
|
||||
ret = zephyr_smp_reassembly_collect(&zst, buff, frag);
|
||||
expected = TEST_FRAME_SIZE - frag;
|
||||
zassert_equal(expected, ret,
|
||||
"Expected is %d should be %d\n", ret, expected);
|
||||
pkt_used = frag;
|
||||
|
||||
/* Next fragment */
|
||||
frag = 40;
|
||||
ret = zephyr_smp_reassembly_collect(&zst, &buff[pkt_used], frag);
|
||||
pkt_used += frag;
|
||||
expected = TEST_FRAME_SIZE - pkt_used;
|
||||
zassert_equal(expected, ret,
|
||||
"Expected is %d should be %d\n", ret, expected);
|
||||
|
||||
/* Try to complete incomplete, no force */
|
||||
ret = zephyr_smp_reassembly_complete(&zst, false);
|
||||
zassert_equal(-ENODATA, ret,
|
||||
"Expected -ENODATA when completing incomplete buffer");
|
||||
|
||||
/* Last fragment */
|
||||
ret = zephyr_smp_reassembly_collect(&zst, &buff[pkt_used], expected);
|
||||
zassert_equal(0, ret,
|
||||
"Expected is %d should be %d\n", ret, 0);
|
||||
|
||||
/* And overflow */
|
||||
ret = zephyr_smp_reassembly_collect(&zst, buff, 1);
|
||||
zassert_equal(-EOVERFLOW, ret,
|
||||
"Expected -EOVERFLOW, got %d\n", ret);
|
||||
|
||||
/* Complete successfully complete buffer */
|
||||
ret = zephyr_smp_reassembly_complete(&zst, false);
|
||||
zassert_equal(0, ret,
|
||||
"Expected 0 from complete, got %d\n", ret);
|
||||
|
||||
p = net_buf_pull_mem(backup, TEST_FRAME_SIZE);
|
||||
|
||||
ret = memcmp(p, buff, TEST_FRAME_SIZE);
|
||||
zassert_equal(ret, 0, "Failed to assemble packet");
|
||||
|
||||
/* This will normally be done by packet processing and should not be done by hand:
|
||||
* release the buffer to the pool
|
||||
*/
|
||||
mcumgr_buf_free(backup);
|
||||
}
|
||||
|
||||
void test_no_packet_started(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/** Complete on non-started packet **/
|
||||
ret = zephyr_smp_reassembly_complete(&zst, false);
|
||||
zassert_equal(-EINVAL, ret,
|
||||
"Expected -EINVAL from complete, got %d", ret);
|
||||
ret = zephyr_smp_reassembly_complete(&zst, true);
|
||||
zassert_equal(-EINVAL, ret,
|
||||
"Expected -EINVAL from complete, got %d", ret);
|
||||
|
||||
/* Try to drop packet when there is none yet */
|
||||
ret = zephyr_smp_reassembly_drop(&zst);
|
||||
zassert_equal(-EINVAL, ret,
|
||||
"Expected -EINVAL, there is no packet started yet");
|
||||
}
|
||||
|
||||
void test_ud(void)
|
||||
{
|
||||
struct mgmt_hdr *mh = (struct mgmt_hdr *)buff;
|
||||
int frag_used;
|
||||
int ret;
|
||||
int expected;
|
||||
void *p;
|
||||
|
||||
/* No packet started yet */
|
||||
p = zephyr_smp_reassembly_get_ud(&zst);
|
||||
zassert_equal(p, NULL, "Expect NULL ud poiner");
|
||||
|
||||
/* After collecting first fragment */
|
||||
mh->nh_len = sys_cpu_to_be16(TEST_FRAME_SIZE);
|
||||
frag_used = 40;
|
||||
expected = TEST_FRAME_SIZE - frag_used + sizeof(struct mgmt_hdr);
|
||||
ret = zephyr_smp_reassembly_collect(&zst, buff, frag_used);
|
||||
zassert_equal(expected, ret,
|
||||
"Expected is %d should be %d\n", ret, expected);
|
||||
|
||||
p = zephyr_smp_reassembly_get_ud(&zst);
|
||||
zassert_not_equal(p, NULL, "Expect non-NULL ud poiner");
|
||||
zephyr_smp_reassembly_drop(&zst);
|
||||
}
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(
|
||||
smp_reassembly_tests,
|
||||
ztest_unit_test(test_first),
|
||||
ztest_unit_test(test_collection),
|
||||
ztest_unit_test(test_no_packet_started),
|
||||
ztest_unit_test(test_drops),
|
||||
ztest_unit_test(test_ud)
|
||||
);
|
||||
|
||||
ztest_run_test_suite(smp_reassembly_tests);
|
||||
}
|
9
tests/subsys/mgmt/smp_reassembly/testcase.yaml
Normal file
9
tests/subsys/mgmt/smp_reassembly/testcase.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
tests:
|
||||
smp.reassembly:
|
||||
platform_allow: native_posix
|
||||
tags: smp_reassembly
|
Loading…
Add table
Add a link
Reference in a new issue