net: lwm2m: fix observation path list ordering
under certain conditions the current implementation did not maintain the desired sort order. Signed-off-by: Pascal Brogle <pascal.brogle@husqvarnagroup.com>
This commit is contained in:
parent
35bd427927
commit
6ac281887c
6 changed files with 639 additions and 36 deletions
|
@ -1499,7 +1499,9 @@ int lwm2m_engine_add_path_to_list(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm
|
|||
new_entry->path = *path;
|
||||
if (!sys_slist_is_empty(lwm2m_path_list)) {
|
||||
|
||||
/* Keep list Ordered by Object ID/ Object instance/ resource ID */
|
||||
/* Keep list Ordered by Object ID / Object instance / resource ID /
|
||||
* Resource Instance ID
|
||||
*/
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(lwm2m_path_list, entry, node) {
|
||||
if (entry->path.level == LWM2M_PATH_LEVEL_NONE ||
|
||||
lwm2m_obj_path_equal(&entry->path, &new_entry->path)) {
|
||||
|
@ -1508,39 +1510,63 @@ int lwm2m_engine_add_path_to_list(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (entry->path.obj_id > path->obj_id) {
|
||||
/* New entry have smaller Object ID */
|
||||
add_before_current = true;
|
||||
} else if (entry->path.obj_id == path->obj_id &&
|
||||
entry->path.level > path->level) {
|
||||
add_before_current = true;
|
||||
} else if (entry->path.obj_id == path->obj_id &&
|
||||
entry->path.level == path->level) {
|
||||
if (path->level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
|
||||
entry->path.obj_inst_id > path->obj_inst_id) {
|
||||
/*
|
||||
* New have same Object ID
|
||||
* but smaller Object Instance ID
|
||||
* algorithm assumes that list is already properly sorted and that
|
||||
* there are no duplicates. general idea:
|
||||
* - if at any level up to new entry's path level, IDs below the level
|
||||
* match and the ID of the new entry at that level is smaller,
|
||||
* insert before.
|
||||
* - if all IDs of the new entry match the existing entry, insert before.
|
||||
* Because of sorting and no duplicates, the existing entry must have
|
||||
* higher path level and come after the new entry.
|
||||
*/
|
||||
add_before_current = true;
|
||||
} else if (path->level >= LWM2M_PATH_LEVEL_RESOURCE &&
|
||||
entry->path.obj_inst_id == path->obj_inst_id &&
|
||||
entry->path.res_id > path->res_id) {
|
||||
/*
|
||||
* Object ID and Object Instance id same
|
||||
* but Resource ID is smaller
|
||||
*/
|
||||
add_before_current = true;
|
||||
} else if (path->level >= LWM2M_PATH_LEVEL_RESOURCE_INST &&
|
||||
entry->path.obj_inst_id == path->obj_inst_id &&
|
||||
entry->path.res_id == path->res_id &&
|
||||
entry->path.res_inst_id > path->res_inst_id) {
|
||||
/*
|
||||
* Object ID, Object Instance id & Resource ID same
|
||||
* but Resource instance ID is smaller
|
||||
*/
|
||||
add_before_current = true;
|
||||
}
|
||||
switch (new_entry->path.level) {
|
||||
case LWM2M_PATH_LEVEL_OBJECT:
|
||||
add_before_current = new_entry->path.obj_id <= entry->path.obj_id;
|
||||
break;
|
||||
|
||||
case LWM2M_PATH_LEVEL_OBJECT_INST:
|
||||
add_before_current =
|
||||
(new_entry->path.obj_id < entry->path.obj_id) ||
|
||||
|
||||
(entry->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
|
||||
entry->path.obj_id == new_entry->path.obj_id &&
|
||||
new_entry->path.obj_inst_id <= entry->path.obj_inst_id);
|
||||
break;
|
||||
|
||||
case LWM2M_PATH_LEVEL_RESOURCE:
|
||||
add_before_current =
|
||||
(new_entry->path.obj_id < entry->path.obj_id) ||
|
||||
|
||||
(entry->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
|
||||
entry->path.obj_id == new_entry->path.obj_id &&
|
||||
new_entry->path.obj_inst_id < entry->path.obj_inst_id) ||
|
||||
|
||||
(entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE &&
|
||||
entry->path.obj_id == new_entry->path.obj_id &&
|
||||
entry->path.obj_inst_id == new_entry->path.obj_inst_id &&
|
||||
new_entry->path.res_id <= entry->path.res_id);
|
||||
break;
|
||||
|
||||
case LWM2M_PATH_LEVEL_RESOURCE_INST:
|
||||
add_before_current =
|
||||
(new_entry->path.obj_id < entry->path.obj_id) ||
|
||||
|
||||
(entry->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
|
||||
entry->path.obj_id == new_entry->path.obj_id &&
|
||||
new_entry->path.obj_inst_id < entry->path.obj_inst_id) ||
|
||||
|
||||
(entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE &&
|
||||
entry->path.obj_id == new_entry->path.obj_id &&
|
||||
entry->path.obj_inst_id == new_entry->path.obj_inst_id &&
|
||||
new_entry->path.res_id < entry->path.res_id) ||
|
||||
|
||||
(entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE_INST &&
|
||||
entry->path.obj_id == new_entry->path.obj_id &&
|
||||
entry->path.obj_inst_id == new_entry->path.obj_inst_id &&
|
||||
entry->path.res_id == new_entry->path.res_id &&
|
||||
new_entry->path.res_inst_id <= entry->path.res_inst_id);
|
||||
break;
|
||||
}
|
||||
|
||||
if (add_before_current) {
|
||||
|
|
|
@ -61,13 +61,29 @@ struct lwm2m_obj_path_list {
|
|||
void lwm2m_engine_path_list_init(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm2m_free_list,
|
||||
struct lwm2m_obj_path_list path_object_buf[],
|
||||
uint8_t path_object_size);
|
||||
/* Add new Path to the list */
|
||||
/**
|
||||
* Add new path to the list while maintaining hierarchical sort order
|
||||
*
|
||||
* @param lwm2m_path_list sorted path list
|
||||
* @param lwm2m_free_list free list
|
||||
* @param path path to be added
|
||||
* @return 0 on success or a negative error code
|
||||
*/
|
||||
int lwm2m_engine_add_path_to_list(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm2m_free_list,
|
||||
struct lwm2m_obj_path *path);
|
||||
|
||||
int lwm2m_get_path_reference_ptr(struct lwm2m_engine_obj *obj, struct lwm2m_obj_path *path,
|
||||
void **ref);
|
||||
/* Remove paths when parent already exist in the list. */
|
||||
|
||||
/**
|
||||
* Remove paths when parent already exists in the list
|
||||
*
|
||||
* @note Path list must be sorted
|
||||
* @see lwm2m_engine_add_path_to_list()
|
||||
*
|
||||
* @param lwm2m_path_list sorted path list
|
||||
* @param lwm2m_free_list free list
|
||||
*/
|
||||
void lwm2m_engine_clear_duplicate_path(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm2m_free_list);
|
||||
|
||||
/* Resources */
|
||||
|
|
12
tests/net/lib/lwm2m/engine/CMakeLists.txt
Normal file
12
tests/net/lib/lwm2m/engine/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(lwm2m_engine)
|
||||
|
||||
target_include_directories(app PRIVATE
|
||||
${ZEPHYR_BASE}/subsys/net/lib/lwm2m
|
||||
)
|
||||
FILE(GLOB app_sources src/*.c)
|
||||
target_sources(app PRIVATE ${app_sources})
|
11
tests/net/lib/lwm2m/engine/prj.conf
Normal file
11
tests/net/lib/lwm2m/engine/prj.conf
Normal file
|
@ -0,0 +1,11 @@
|
|||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_TEST=y
|
||||
CONFIG_ZTEST=y
|
||||
CONFIG_ZTEST_NEW_API=y
|
||||
|
||||
CONFIG_ENTROPY_GENERATOR=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NEWLIB_LIBC=y
|
||||
|
||||
CONFIG_LWM2M=y
|
||||
CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512
|
532
tests/net/lib/lwm2m/engine/src/lwm2m_observation.c
Normal file
532
tests/net/lib/lwm2m/engine/src/lwm2m_observation.c
Normal file
|
@ -0,0 +1,532 @@
|
|||
/*
|
||||
* Copyright (c) 2022 GARDENA GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "lwm2m_engine.h"
|
||||
#include "lwm2m_util.h"
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
#define TEST_VERBOSE 0
|
||||
|
||||
#if TEST_VERBOSE
|
||||
#define TEST_VERBOSE_PRINT(fmt, ...) TC_PRINT(fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define TEST_VERBOSE_PRINT(fmt, ...)
|
||||
#endif
|
||||
|
||||
static bool lwm2m_path_object_equal_upto(struct lwm2m_obj_path *path,
|
||||
struct lwm2m_obj_path *compare_path, uint8_t level)
|
||||
{
|
||||
|
||||
if (level >= LWM2M_PATH_LEVEL_OBJECT && path->obj_id != compare_path->obj_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
|
||||
path->obj_inst_id != compare_path->obj_inst_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (level >= LWM2M_PATH_LEVEL_RESOURCE && path->res_id != compare_path->res_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (level >= LWM2M_PATH_LEVEL_RESOURCE_INST &&
|
||||
path->res_inst_id != compare_path->res_inst_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void assert_path_list_order(sys_slist_t *lwm2m_path_list)
|
||||
{
|
||||
|
||||
struct lwm2m_obj_path_list *prev = NULL;
|
||||
struct lwm2m_obj_path_list *entry, *tmp;
|
||||
|
||||
uint16_t obj_id_max;
|
||||
uint16_t obj_inst_id_max;
|
||||
uint16_t res_id_max;
|
||||
uint16_t res_inst_id_max;
|
||||
|
||||
char next_path_str[LWM2M_MAX_PATH_STR_LEN];
|
||||
char prev_path_str[LWM2M_MAX_PATH_STR_LEN];
|
||||
|
||||
if (sys_slist_is_empty(lwm2m_path_list)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(lwm2m_path_list, entry, tmp, node) {
|
||||
if (prev) {
|
||||
if (entry->path.level > prev->path.level) {
|
||||
|
||||
lwm2m_path_to_string(next_path_str, sizeof(next_path_str),
|
||||
&entry->path, entry->path.level);
|
||||
lwm2m_path_to_string(prev_path_str, sizeof(prev_path_str),
|
||||
&prev->path, prev->path.level);
|
||||
|
||||
bool is_after = false;
|
||||
|
||||
if (prev->path.level >= LWM2M_PATH_LEVEL_OBJECT) {
|
||||
is_after = entry->path.obj_id >= prev->path.obj_id;
|
||||
}
|
||||
if (is_after && prev->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
|
||||
entry->path.obj_id == prev->path.obj_id) {
|
||||
is_after =
|
||||
entry->path.obj_inst_id >= prev->path.obj_inst_id;
|
||||
}
|
||||
|
||||
if (is_after && prev->path.level >= LWM2M_PATH_LEVEL_RESOURCE &&
|
||||
entry->path.obj_inst_id == prev->path.obj_inst_id) {
|
||||
is_after = entry->path.res_id >= prev->path.res_id;
|
||||
}
|
||||
|
||||
if (is_after &&
|
||||
prev->path.level >= LWM2M_PATH_LEVEL_RESOURCE_INST &&
|
||||
entry->path.res_id == prev->path.res_id) {
|
||||
is_after =
|
||||
entry->path.res_inst_id >= prev->path.res_inst_id;
|
||||
}
|
||||
|
||||
zassert_true(is_after, "Next element %s must be before previous %s",
|
||||
next_path_str, prev_path_str);
|
||||
} else if (entry->path.level == prev->path.level) {
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT) {
|
||||
zassert_true(entry->path.obj_id >= obj_id_max,
|
||||
"Next element has object %d which is smaller "
|
||||
"than previous max object %d",
|
||||
entry->path.obj_id, obj_id_max);
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST) {
|
||||
if (!lwm2m_path_object_equal_upto(
|
||||
&entry->path, &prev->path,
|
||||
LWM2M_PATH_LEVEL_OBJECT)) {
|
||||
/* reset max id when path changed */
|
||||
obj_inst_id_max = 0;
|
||||
}
|
||||
|
||||
zassert_true(entry->path.obj_inst_id >= obj_inst_id_max,
|
||||
"Next element has object instance %d which is "
|
||||
"smaller "
|
||||
"than previous max object instance %d",
|
||||
entry->path.obj_inst_id, obj_inst_id_max);
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE) {
|
||||
if (!lwm2m_path_object_equal_upto(
|
||||
&entry->path, &prev->path,
|
||||
LWM2M_PATH_LEVEL_OBJECT_INST)) {
|
||||
/* reset max id when path changed */
|
||||
res_id_max = 0;
|
||||
}
|
||||
|
||||
zassert_true(
|
||||
entry->path.res_id >= res_id_max,
|
||||
"Next element has resource %d which is smaller "
|
||||
"than previous max resource %d",
|
||||
entry->path.res_id, res_id_max);
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE_INST) {
|
||||
if (!lwm2m_path_object_equal_upto(
|
||||
&entry->path, &prev->path,
|
||||
LWM2M_PATH_LEVEL_RESOURCE)) {
|
||||
/* reset max id when path changed */
|
||||
res_inst_id_max = 0;
|
||||
}
|
||||
zassert_true(entry->path.res_inst_id >= res_inst_id_max,
|
||||
"Next element has resource instance %d which "
|
||||
"is smaller "
|
||||
"than previous max resource instance %d",
|
||||
entry->path.res_inst_id, res_inst_id_max);
|
||||
}
|
||||
|
||||
} else { /* entry->path.level < prev->path.level */
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT) {
|
||||
zassert_true(entry->path.obj_id >= obj_id_max,
|
||||
"Next element has object %d which is smaller "
|
||||
"than previous max object %d",
|
||||
entry->path.obj_id, obj_id_max);
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST) {
|
||||
zassert_true(entry->path.obj_inst_id >= obj_inst_id_max,
|
||||
"Next element has object instance %d which is "
|
||||
"smaller "
|
||||
"than previous max object instance %d",
|
||||
entry->path.obj_inst_id, obj_inst_id_max);
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE) {
|
||||
zassert_true(
|
||||
entry->path.res_id >= res_id_max,
|
||||
"Next element has resource %d which is smaller "
|
||||
"than previous max resource %d",
|
||||
entry->path.res_id, res_id_max);
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE_INST) {
|
||||
zassert_true(entry->path.res_inst_id >= res_inst_id_max,
|
||||
"Next element has resource instance %d which "
|
||||
"is bigger "
|
||||
"than previous max resource instance %d",
|
||||
entry->path.res_inst_id, res_inst_id_max);
|
||||
}
|
||||
|
||||
zassert_true(!lwm2m_path_object_equal_upto(
|
||||
&entry->path, &prev->path, entry->path.level),
|
||||
"Next element equals previous up to level %d "
|
||||
"and thus must be before previous",
|
||||
entry->path.level);
|
||||
}
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT) {
|
||||
obj_id_max = entry->path.obj_id;
|
||||
} else {
|
||||
obj_id_max = 0;
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
|
||||
(prev == NULL || entry->path.obj_id == prev->path.obj_id)) {
|
||||
obj_inst_id_max = entry->path.obj_inst_id;
|
||||
} else {
|
||||
obj_inst_id_max = 0;
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE &&
|
||||
(prev == NULL || entry->path.obj_id == prev->path.obj_id) &&
|
||||
(prev == NULL || entry->path.obj_inst_id == prev->path.obj_inst_id)) {
|
||||
res_id_max = entry->path.res_id;
|
||||
} else {
|
||||
res_id_max = 0;
|
||||
}
|
||||
|
||||
if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE_INST &&
|
||||
(prev == NULL || entry->path.obj_id == prev->path.obj_id) &&
|
||||
(prev == NULL || entry->path.obj_inst_id == prev->path.obj_inst_id) &&
|
||||
(prev == NULL || entry->path.res_id == prev->path.res_id)) {
|
||||
res_inst_id_max = entry->path.res_inst_id;
|
||||
} else {
|
||||
res_inst_id_max = 0;
|
||||
}
|
||||
|
||||
prev = entry;
|
||||
}
|
||||
}
|
||||
static void print_path_list(sys_slist_t *lwm2m_path_list, const char *name)
|
||||
{
|
||||
struct lwm2m_obj_path_list *entry, *tmp;
|
||||
|
||||
if (name != NULL) {
|
||||
TEST_VERBOSE_PRINT("Path List %s:\n", name);
|
||||
}
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(lwm2m_path_list, entry, tmp, node) {
|
||||
char buf[LWM2M_MAX_PATH_STR_LEN];
|
||||
|
||||
lwm2m_path_to_string(buf, LWM2M_MAX_PATH_STR_LEN, &entry->path, entry->path.level);
|
||||
TEST_VERBOSE_PRINT("- %s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void run_insertion_test(char const *insert_path_str[], int insertions_count,
|
||||
char const *expected_path_str[])
|
||||
{
|
||||
/* GIVEN: different paths */
|
||||
struct lwm2m_obj_path_list lwm2m_path_list_buf[insertions_count];
|
||||
sys_slist_t lwm2m_path_list;
|
||||
sys_slist_t lwm2m_path_free_list;
|
||||
int ret;
|
||||
|
||||
lwm2m_engine_path_list_init(&lwm2m_path_list, &lwm2m_path_free_list, lwm2m_path_list_buf,
|
||||
insertions_count);
|
||||
|
||||
/* WHEN: inserting each path */
|
||||
struct lwm2m_obj_path insert_path;
|
||||
char name[20];
|
||||
|
||||
for (int i = 0; i < insertions_count; ++i) {
|
||||
ret = lwm2m_string_to_path(insert_path_str[i], &insert_path, '/');
|
||||
zassert_true(ret >= 0, "Conversion to path #%d failed", i);
|
||||
|
||||
ret = lwm2m_engine_add_path_to_list(&lwm2m_path_list, &lwm2m_path_free_list,
|
||||
&insert_path);
|
||||
|
||||
sprintf(name, "Insertion: %d", i);
|
||||
print_path_list(&lwm2m_path_list, name);
|
||||
zassert_true(ret >= 0, "Insertion #%d failed", i);
|
||||
/* THEN: path order is maintained */
|
||||
assert_path_list_order(&lwm2m_path_list);
|
||||
}
|
||||
|
||||
print_path_list(&lwm2m_path_list, "Final");
|
||||
|
||||
/* AND: final list matches expectation */
|
||||
struct lwm2m_obj_path_list *entry, *tmp;
|
||||
int path_num = 0;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&lwm2m_path_list, entry, tmp, node) {
|
||||
struct lwm2m_obj_path expected_path;
|
||||
|
||||
lwm2m_string_to_path(expected_path_str[path_num++], &expected_path, '/');
|
||||
zassert_mem_equal(&entry->path, &expected_path, sizeof(struct lwm2m_obj_path),
|
||||
"Path #%d did not match expectation", path_num);
|
||||
}
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(2),
|
||||
LWM2M_PATH(1),
|
||||
LWM2M_PATH(1, 2),
|
||||
LWM2M_PATH(1, 1),
|
||||
LWM2M_PATH(1, 1, 10),
|
||||
LWM2M_PATH(1, 1, 10, 10),
|
||||
LWM2M_PATH(1, 1, 10, 9),
|
||||
LWM2M_PATH(1, 2, 10, 11),
|
||||
|
||||
LWM2M_PATH(100),
|
||||
|
||||
LWM2M_PATH(41),
|
||||
LWM2M_PATH(43, 3),
|
||||
LWM2M_PATH(45, 2, 2),
|
||||
LWM2M_PATH(47, 1, 1, 1),
|
||||
|
||||
LWM2M_PATH(57, 1, 1, 1),
|
||||
LWM2M_PATH(55, 2, 2),
|
||||
LWM2M_PATH(53, 3),
|
||||
LWM2M_PATH(51),
|
||||
};
|
||||
|
||||
char const *expected_path_str[] = {
|
||||
LWM2M_PATH(1),
|
||||
LWM2M_PATH(1, 1),
|
||||
LWM2M_PATH(1, 1, 10),
|
||||
LWM2M_PATH(1, 1, 10, 9),
|
||||
LWM2M_PATH(1, 1, 10, 10),
|
||||
LWM2M_PATH(1, 2),
|
||||
LWM2M_PATH(1, 2, 10, 11),
|
||||
LWM2M_PATH(2),
|
||||
LWM2M_PATH(41),
|
||||
LWM2M_PATH(43, 3),
|
||||
LWM2M_PATH(45, 2, 2),
|
||||
LWM2M_PATH(47, 1, 1, 1),
|
||||
LWM2M_PATH(51),
|
||||
LWM2M_PATH(53, 3),
|
||||
LWM2M_PATH(55, 2, 2),
|
||||
LWM2M_PATH(57, 1, 1, 1),
|
||||
LWM2M_PATH(100),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_inverse_non_overlapping)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(41),
|
||||
LWM2M_PATH(43, 3),
|
||||
LWM2M_PATH(45, 2, 2),
|
||||
LWM2M_PATH(47, 1, 1, 1),
|
||||
};
|
||||
|
||||
char const *expected_path_str[] = {
|
||||
LWM2M_PATH(41),
|
||||
LWM2M_PATH(43, 3),
|
||||
LWM2M_PATH(45, 2, 2),
|
||||
LWM2M_PATH(47, 1, 1, 1),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_inverse_non_overlapping_2)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(57, 1, 1, 1),
|
||||
LWM2M_PATH(55, 2, 2),
|
||||
LWM2M_PATH(53, 3),
|
||||
LWM2M_PATH(51),
|
||||
};
|
||||
|
||||
char const *expected_path_str[] = {
|
||||
LWM2M_PATH(51),
|
||||
LWM2M_PATH(53, 3),
|
||||
LWM2M_PATH(55, 2, 2),
|
||||
LWM2M_PATH(57, 1, 1, 1),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_object_before_resource_inst)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(1, 1, 1, 1),
|
||||
LWM2M_PATH(1),
|
||||
};
|
||||
|
||||
char const *expected_path_str[6] = {
|
||||
LWM2M_PATH(1),
|
||||
LWM2M_PATH(1, 1, 1, 1),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_object_inst_before_resource_inst)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(1, 1, 1, 1),
|
||||
LWM2M_PATH(1, 1),
|
||||
};
|
||||
|
||||
char const *expected_path_str[6] = {
|
||||
LWM2M_PATH(1, 1),
|
||||
LWM2M_PATH(1, 1, 1, 1),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_resource_before_resource_inst)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(1, 1, 1, 1),
|
||||
LWM2M_PATH(1, 1, 1),
|
||||
};
|
||||
|
||||
char const *expected_path_str[] = {
|
||||
LWM2M_PATH(1, 1, 1),
|
||||
LWM2M_PATH(1, 1, 1, 1),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_resource_order)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(32765, 1, 6, 0),
|
||||
LWM2M_PATH(32765, 1, 6, 1),
|
||||
LWM2M_PATH(32765, 1, 6),
|
||||
LWM2M_PATH(32765, 1, 5),
|
||||
LWM2M_PATH(32765, 1, 5, 2),
|
||||
LWM2M_PATH(32765, 1, 5, 1),
|
||||
};
|
||||
|
||||
char const *expected_path_str[] = {
|
||||
LWM2M_PATH(32765, 1, 5),
|
||||
LWM2M_PATH(32765, 1, 5, 1),
|
||||
LWM2M_PATH(32765, 1, 5, 2),
|
||||
LWM2M_PATH(32765, 1, 6),
|
||||
LWM2M_PATH(32765, 1, 6, 0),
|
||||
LWM2M_PATH(32765, 1, 6, 1),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_resource_before_instance)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(32765, 1, 6, 0),
|
||||
LWM2M_PATH(32765, 1, 6, 1),
|
||||
LWM2M_PATH(32765, 1, 6),
|
||||
};
|
||||
|
||||
char const *expected_path_str[6] = {
|
||||
LWM2M_PATH(32765, 1, 6),
|
||||
LWM2M_PATH(32765, 1, 6, 0),
|
||||
LWM2M_PATH(32765, 1, 6, 1),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_resource_inverse)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(1, 1, 1, 1),
|
||||
LWM2M_PATH(1, 1, 1),
|
||||
LWM2M_PATH(1, 1),
|
||||
LWM2M_PATH(1),
|
||||
};
|
||||
|
||||
char const *expected_path_str[] = {
|
||||
LWM2M_PATH(1),
|
||||
LWM2M_PATH(1, 1),
|
||||
LWM2M_PATH(1, 1, 1),
|
||||
LWM2M_PATH(1, 1, 1, 1),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_obj_after_resource)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(1),
|
||||
LWM2M_PATH(1, 1),
|
||||
LWM2M_PATH(1, 1, 1),
|
||||
LWM2M_PATH(1, 2),
|
||||
};
|
||||
|
||||
char const *expected_path_str[] = {
|
||||
LWM2M_PATH(1),
|
||||
LWM2M_PATH(1, 1),
|
||||
LWM2M_PATH(1, 1, 1),
|
||||
LWM2M_PATH(1, 2),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST(lwm2m_observation, test_add_path_to_list_duplicate)
|
||||
{
|
||||
/* clang-format off */
|
||||
char const *insert_path_str[] = {
|
||||
LWM2M_PATH(1),
|
||||
LWM2M_PATH(1, 1),
|
||||
LWM2M_PATH(1),
|
||||
};
|
||||
|
||||
char const *expected_path_str[] = {
|
||||
LWM2M_PATH(1),
|
||||
LWM2M_PATH(1, 1),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
|
||||
}
|
||||
|
||||
ZTEST_SUITE(lwm2m_observation, NULL, NULL, NULL, NULL, NULL);
|
6
tests/net/lib/lwm2m/engine/testcase.yaml
Normal file
6
tests/net/lib/lwm2m/engine/testcase.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
common:
|
||||
depends_on: netif
|
||||
tests:
|
||||
net.lwm2m.engine:
|
||||
platform_allow: native_posix
|
||||
tags: lwm2m net
|
Loading…
Add table
Add a link
Reference in a new issue