tests: mgmt: mcumgr: Add callback notification grouping test

Adds a test that check that grouped events work.

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
This commit is contained in:
Jamie McCrae 2023-01-06 09:48:45 +00:00 committed by Marti Bolivar
parent d6758557f5
commit de313d748a
9 changed files with 368 additions and 0 deletions

View file

@ -0,0 +1,16 @@
#
# Copyright (c) 2023 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(cb_notifications)
FILE(GLOB app_sources
src/*.c
)
target_sources(app PRIVATE ${app_sources})
target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/)

View file

@ -0,0 +1 @@
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096

View file

@ -0,0 +1 @@
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096

View file

@ -0,0 +1 @@
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096

View file

@ -0,0 +1,14 @@
#
# Copyright (c) 2023 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
#
CONFIG_ZTEST=y
CONFIG_MCUMGR=y
CONFIG_MCUMGR_TRANSPORT_DUMMY=y
CONFIG_MCUMGR_TRANSPORT_DUMMY_RX_BUF_SIZE=256
CONFIG_MCUMGR_GRP_OS=y
CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS=y
CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS=y
CONFIG_ZTEST_NEW_API=y
CONFIG_ZTEST_STACK_SIZE=2048

View file

@ -0,0 +1,262 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/net/buf.h>
#include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
#include <zephyr/mgmt/mcumgr/transport/smp_dummy.h>
#include <zephyr/mgmt/mcumgr/mgmt/callbacks.h>
#include <zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h>
#include <zcbor_common.h>
#include <zcbor_decode.h>
#include <zcbor_encode.h>
#include <mgmt/mcumgr/util/zcbor_bulk.h>
#include <version.h>
#include <string.h>
#include <smp_internal.h>
#include "smp_test_util.h"
#define SMP_RESPONSE_WAIT_TIME 3
#define ZCBOR_BUFFER_SIZE 64
#define OUTPUT_BUFFER_SIZE 64
#define ZCBOR_HISTORY_ARRAY_SIZE 4
/* Test sets */
enum {
CB_NOTIFICATION_TEST_CALLBACK_DISABLED,
CB_NOTIFICATION_TEST_CALLBACK_ENABLED,
CB_NOTIFICATION_TEST_CALLBACK_DISABLED_VERIFY,
CB_NOTIFICATION_TEST_SET_COUNT
};
static struct net_buf *nb;
struct state {
uint8_t test_set;
};
static struct state test_state = {
.test_set = 0,
};
static bool cmd_recv_got;
static bool cmd_status_got;
static bool cmd_done_got;
static bool cmd_other_got;
/* Responses to commands */
static int32_t mgmt_event_cmd_callback(uint32_t event, int32_t rc, bool *abort_more,
void *data, size_t data_size)
{
if (event == MGMT_EVT_OP_CMD_RECV) {
cmd_recv_got = true;
} else if (event == MGMT_EVT_OP_CMD_STATUS) {
cmd_status_got = true;
} else if (event == MGMT_EVT_OP_CMD_DONE) {
cmd_done_got = true;
} else {
cmd_other_got = true;
}
return MGMT_ERR_EOK;
}
static struct mgmt_callback mgmt_event_callback = {
.callback = mgmt_event_cmd_callback,
.event_id = (MGMT_EVT_OP_CMD_RECV | MGMT_EVT_OP_CMD_STATUS | MGMT_EVT_OP_CMD_DONE),
};
static void *setup_callbacks(void)
{
mgmt_callback_register(&mgmt_event_callback);
return NULL;
}
static void destroy_callbacks(void *p)
{
mgmt_callback_unregister(&mgmt_event_callback);
}
ZTEST(callback_disabled, test_notifications_disabled)
{
uint8_t buffer[ZCBOR_BUFFER_SIZE];
uint8_t buffer_out[OUTPUT_BUFFER_SIZE];
bool ok;
uint16_t buffer_size;
zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
bool received;
memset(buffer, 0, sizeof(buffer));
memset(buffer_out, 0, sizeof(buffer_out));
buffer_size = 0;
memset(zse, 0, sizeof(zse));
memset(zsd, 0, sizeof(zsd));
zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0);
ok = create_mcumgr_format_packet(zse, buffer, buffer_out, &buffer_size);
zassert_true(ok, "Expected packet creation to be successful\n");
/* Enable dummy SMP backend and ready for usage */
smp_dummy_enable();
smp_dummy_clear_state();
/* Send query command to dummy SMP backend */
(void)smp_dummy_tx_pkt(buffer_out, buffer_size);
smp_dummy_add_data();
/* For a short duration to see if response has been received */
received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME);
zassert_true(received, "Expected to receive data but timed out\n");
/* Retrieve response buffer */
nb = smp_dummy_get_outgoing();
smp_dummy_disable();
/* Check events */
zassert_false(cmd_recv_got, "Did not expect received command callback\n");
zassert_false(cmd_status_got, "Did not expect IMG status callback\n");
zassert_false(cmd_done_got, "Did not expect done command callback\n");
zassert_false(cmd_other_got, "Did not expect other callback(s)\n");
}
ZTEST(callback_enabled, test_notifications_enabled)
{
uint8_t buffer[ZCBOR_BUFFER_SIZE];
uint8_t buffer_out[OUTPUT_BUFFER_SIZE];
bool ok;
uint16_t buffer_size;
zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
bool received;
memset(buffer, 0, sizeof(buffer));
memset(buffer_out, 0, sizeof(buffer_out));
buffer_size = 0;
memset(zse, 0, sizeof(zse));
memset(zsd, 0, sizeof(zsd));
zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0);
ok = create_mcumgr_format_packet(zse, buffer, buffer_out, &buffer_size);
zassert_true(ok, "Expected packet creation to be successful\n");
/* Enable dummy SMP backend and ready for usage */
smp_dummy_enable();
smp_dummy_clear_state();
/* Send query command to dummy SMP backend */
(void)smp_dummy_tx_pkt(buffer_out, buffer_size);
smp_dummy_add_data();
/* For a short duration to see if response has been received */
received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME);
zassert_true(received, "Expected to receive data but timed out\n");
/* Retrieve response buffer */
nb = smp_dummy_get_outgoing();
smp_dummy_disable();
/* Check events */
zassert_true(cmd_recv_got, "Expected received command callback\n");
zassert_false(cmd_status_got, "Did not expect IMG status callback\n");
zassert_true(cmd_done_got, "Expected done command callback\n");
zassert_false(cmd_other_got, "Did not expect other callback(s)\n");
}
ZTEST(callback_disabled_verify, test_notifications_disabled_verify)
{
uint8_t buffer[ZCBOR_BUFFER_SIZE];
uint8_t buffer_out[OUTPUT_BUFFER_SIZE];
bool ok;
uint16_t buffer_size;
zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
bool received;
memset(buffer, 0, sizeof(buffer));
memset(buffer_out, 0, sizeof(buffer_out));
buffer_size = 0;
memset(zse, 0, sizeof(zse));
memset(zsd, 0, sizeof(zsd));
zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0);
ok = create_mcumgr_format_packet(zse, buffer, buffer_out, &buffer_size);
zassert_true(ok, "Expected packet creation to be successful\n");
/* Enable dummy SMP backend and ready for usage */
smp_dummy_enable();
smp_dummy_clear_state();
/* Send query command to dummy SMP backend */
(void)smp_dummy_tx_pkt(buffer_out, buffer_size);
smp_dummy_add_data();
/* For a short duration to see if response has been received */
received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME);
zassert_true(received, "Expected to receive data but timed out\n");
/* Retrieve response buffer */
nb = smp_dummy_get_outgoing();
smp_dummy_disable();
/* Check events */
zassert_false(cmd_recv_got, "Did not expect received command callback\n");
zassert_false(cmd_status_got, "Did not expect IMG status callback\n");
zassert_false(cmd_done_got, "Did not expect done command callback\n");
zassert_false(cmd_other_got, "Did not expect other callback(s)\n");
}
static void cleanup_test(void *p)
{
if (nb != NULL) {
net_buf_unref(nb);
nb = NULL;
}
cmd_recv_got = false;
cmd_status_got = false;
cmd_done_got = false;
cmd_other_got = false;
}
void test_main(void)
{
while (test_state.test_set < CB_NOTIFICATION_TEST_SET_COUNT) {
ztest_run_all(&test_state);
++test_state.test_set;
}
ztest_verify_all_test_suites_ran();
}
static bool callback_disabled_predicate(const void *state)
{
return ((struct state *)state)->test_set == CB_NOTIFICATION_TEST_CALLBACK_DISABLED;
}
static bool callback_enabled_predicate(const void *state)
{
return ((struct state *)state)->test_set == CB_NOTIFICATION_TEST_CALLBACK_ENABLED;
}
static bool callback_disabled_verify_predicate(const void *state)
{
return ((struct state *)state)->test_set == CB_NOTIFICATION_TEST_CALLBACK_DISABLED_VERIFY;
}
ZTEST_SUITE(callback_disabled, callback_disabled_predicate, NULL, NULL, cleanup_test, NULL);
ZTEST_SUITE(callback_enabled, callback_enabled_predicate, setup_callbacks, NULL, cleanup_test,
destroy_callbacks);
ZTEST_SUITE(callback_disabled_verify, callback_disabled_verify_predicate, NULL, NULL,
cleanup_test, NULL);

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2022-2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "smp_test_util.h"
#include <zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h>
#include <zephyr/net/buf.h>
#include <zephyr/sys/byteorder.h>
#include <zcbor_encode.h>
void smp_make_hdr(struct smp_hdr *rsp_hdr, size_t len)
{
*rsp_hdr = (struct smp_hdr) {
.nh_len = sys_cpu_to_be16(len),
.nh_flags = 0,
.nh_op = 0,
.nh_group = sys_cpu_to_be16(MGMT_GROUP_ID_OS),
.nh_seq = 1,
.nh_id = OS_MGMT_ID_ECHO,
};
}
bool create_mcumgr_format_packet(zcbor_state_t *zse, uint8_t *buffer, uint8_t *output_buffer,
uint16_t *buffer_size)
{
bool ok;
ok = zcbor_map_start_encode(zse, 2) &&
zcbor_tstr_put_lit(zse, "d") &&
zcbor_tstr_put_term(zse, "some test data") &&
zcbor_map_end_encode(zse, 2);
*buffer_size = (zse->payload_mut - buffer);
smp_make_hdr((struct smp_hdr *)output_buffer, *buffer_size);
memcpy(&output_buffer[sizeof(struct smp_hdr)], buffer, *buffer_size);
*buffer_size += sizeof(struct smp_hdr);
return ok;
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2022-2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef H_SMP_TEST_UTIL_
#define H_SMP_TEST_UTIL_
#include <zephyr/ztest.h>
#include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
#include <zcbor_common.h>
#include <smp_internal.h>
/* SMP header function for generating MCUmgr command header with sequence number set to 1 */
void smp_make_hdr(struct smp_hdr *rsp_hdr, size_t len);
/* Function for creating an os_mgmt echo command */
bool create_mcumgr_format_packet(zcbor_state_t *zse, uint8_t *buffer, uint8_t *output_buffer,
uint16_t *buffer_size);
#endif

View file

@ -0,0 +1,9 @@
#
# Copyright (c) 2023 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
#
tests:
cb.notifications:
platform_allow: qemu_cortex_m3 native_posix native_posix_64 qemu_riscv32_smp qemu_riscv64
tags: cb_notifications