Skip to content

Commit 9e6ffcc

Browse files
pascal-nordicnordicjm
authored andcommitted
tests: subsys: net: lib: nrf_cloud: Unit tests for CBOR codec functions
This covers the functions that uses CBOR in the codec lib Jira: CLOUDMCU-109 Signed-off-by: Pascal Hernandez <pascal.hernandez@nordicsemi.no>
1 parent 416ff14 commit 9e6ffcc

7 files changed

Lines changed: 1052 additions & 0 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#
2+
# Copyright (c) 2026 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
project(nrf_cloud_codec_cbor_test)
11+
12+
set(nrfxlib_modem_dir ${ZEPHYR_NRFXLIB_MODULE_DIR}/nrf_modem)
13+
zephyr_include_directories(${nrfxlib_modem_dir}/include)
14+
15+
# Test sources: the CoAP CBOR codec under test, its generated zcbor
16+
# encoder/decoder files, and stubs for the internal helpers it calls.
17+
target_sources(app PRIVATE
18+
src/main.c
19+
src/fakes.c
20+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/coap/src/nrf_cloud_coap_codec.c
21+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/coap/generated/src/msg_encode.c
22+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/coap/generated/src/agnss_encode.c
23+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/coap/generated/src/pgps_encode.c
24+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/coap/generated/src/pgps_decode.c
25+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/coap/generated/src/ground_fix_encode.c
26+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/coap/generated/src/ground_fix_decode.c
27+
)
28+
29+
target_include_directories(app PRIVATE
30+
src
31+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/include
32+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src
33+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/coap/include
34+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/coap/generated/include
35+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/mqtt/include
36+
${ZEPHYR_BASE}/subsys/testsuite/include
37+
${ZEPHYR_CJSON_MODULE_DIR}
38+
)
39+
40+
# Enabling NRF_CLOUD_AGNSS / NRF_CLOUD_PGPS in Kconfig causes the nRF
41+
# Cloud library CMakeLists to be added and a number of helper sources
42+
# to be compiled. Those sources reference Kconfig symbols that are
43+
# only generated when the full NRF_CLOUD subsystem is enabled, which
44+
# is incompatible with native_sim / qemu_cortex_m3 builds.
45+
#
46+
# Exclude them via HEADER_FILE_ONLY. The CBOR codec functions under
47+
# test are supplied directly via target_sources above, and fakes.c
48+
# provides the few internal helpers they reach into.
49+
set_source_files_properties(
50+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_codec_internal.c
51+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_log.c
52+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_codec.c
53+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_mem.c
54+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_client_id.c
55+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_sec_tag.c
56+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_info.c
57+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_agnss.c
58+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_agnss_utils.c
59+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_pgps.c
60+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/common/src/nrf_cloud_pgps_utils.c
61+
DIRECTORY ${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/nrf_cloud/
62+
PROPERTIES HEADER_FILE_ONLY ON
63+
)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#
2+
# Copyright (c) 2026 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# NRF_CLOUD_LOG_LEVEL and NRF_CLOUD_COAP_LOG_LEVEL are generated by
8+
# Kconfig.template.log_config inside "if NRF_CLOUD" / "if NRF_CLOUD_COAP"
9+
# blocks, so they do not exist in the Kconfig tree on native_sim.
10+
# Defining them here makes them available without conflict.
11+
12+
config NRF_CLOUD_LOG_LEVEL
13+
default 0
14+
15+
config NRF_CLOUD_COAP_LOG_LEVEL
16+
default 0
17+
18+
# Enable AGNSS and PGPS so the corresponding code paths in
19+
# nrf_cloud_coap_codec.c (guarded by these CONFIG_* symbols) are
20+
# compiled into the test binary. The actual library .c files that
21+
# would be pulled in by these symbols are excluded from the build via
22+
# HEADER_FILE_ONLY in CMakeLists.txt; the codec sources are added
23+
# explicitly there.
24+
config NRF_CLOUD_AGNSS
25+
default y
26+
27+
config NRF_CLOUD_PGPS
28+
default y
29+
30+
source "Kconfig.zephyr"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# Copyright (c) 2026 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# qemu_cortex_m3 does not support the networking stack
8+
CONFIG_NETWORKING=n
9+
10+
# coap_codec_ground_fix_req_encode() allocates a ~2.4 kB struct ground_fix_req
11+
# on the stack. The default ZTEST_STACK_SIZE on ARM (1024 B) is too small and
12+
# causes a stack overflow leading to a kernel panic.
13+
CONFIG_ZTEST_STACK_SIZE=4096
14+
15+
# Required for the test to run in qemu_cortex_m3
16+
# See https://github.com/zephyrproject-rtos/zephyr/issues/15565
17+
CONFIG_ENTROPY_GENERATOR=y
18+
CONFIG_TEST_RANDOM_GENERATOR=y
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#
2+
# Copyright (c) 2026 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# ZTEST with new API
8+
CONFIG_ZTEST=y
9+
10+
# Network (required by nrf_cloud headers)
11+
CONFIG_NETWORKING=y
12+
13+
# Disable sockets (not needed for codec unit tests)
14+
CONFIG_NET_SOCKETS=n
15+
16+
# cJSON library (required for linking; JSON encode path not tested here)
17+
CONFIG_CJSON_LIB=y
18+
19+
# zcbor CBOR library (required by generated encoder/decoder sources)
20+
CONFIG_ZCBOR=y
21+
22+
# C library with float printf support
23+
CONFIG_NEWLIB_LIBC=y
24+
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright (c) 2026 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/*
8+
* Minimal fakes required to link nrf_cloud_coap_codec.c in the test
9+
* environment.
10+
*
11+
* nrf_cloud_coap_codec.c references several symbols from
12+
* nrf_cloud_codec_internal.c and nrf_cloud_mem.c. Including those full
13+
* implementations would drag in the modem, FOTA, and REST
14+
* subsystems that are irrelevant for pure CBOR codec unit tests.
15+
*
16+
* Only three of those symbols are reachable in the CBOR path that is
17+
* exercised by these tests:
18+
* - nrf_cloud_agnss_type_array_get (called in coap_codec_agnss_encode)
19+
* - nrf_cloud_calloc / nrf_cloud_free / nrf_cloud_malloc (link-time deps)
20+
*
21+
* The remaining symbols (nrf_cloud_encode_message, nrf_cloud_error_msg_decode,
22+
* nrf_cloud_rest_fota_execution_decode) are only reachable via JSON paths that
23+
* the CBOR tests do not exercise; they are stubbed out with safe no-op or
24+
* error-returning implementations so that the linker is satisfied.
25+
*
26+
* NOTE: This file is intentionally a copy of (and closely mirrors) the fakes
27+
* in codec/json/src/fakes.c. A future refactor can hoist the shared fakes
28+
* into a common location; that is deferred until the full codec test suite
29+
* shape is known.
30+
*/
31+
32+
#include <stdbool.h>
33+
#include <stdlib.h>
34+
#include <errno.h>
35+
#include <net/nrf_cloud.h>
36+
#include <nrf_modem_gnss.h>
37+
#include <nrf_cloud_codec_internal.h>
38+
#include <nrf_cloud_mem.h>
39+
40+
/* -------------------------------------------------------------------------
41+
* Memory wrappers (mirrors of nrf_cloud_mem.c)
42+
* -------------------------------------------------------------------------
43+
*/
44+
45+
void *nrf_cloud_calloc(size_t count, size_t size)
46+
{
47+
return calloc(count, size);
48+
}
49+
50+
void *nrf_cloud_malloc(size_t size)
51+
{
52+
return malloc(size);
53+
}
54+
55+
void nrf_cloud_free(void *ptr)
56+
{
57+
free(ptr);
58+
}
59+
60+
/* -------------------------------------------------------------------------
61+
* JSON-path stubs — never called from the CBOR test path.
62+
* Returning an error code prevents silent mis-routing if they are ever
63+
* reached unexpectedly.
64+
* -------------------------------------------------------------------------
65+
*/
66+
67+
int nrf_cloud_encode_message(const char *app_id, double value, const char *str_val,
68+
const char *topic, int64_t ts, struct nrf_cloud_data *output)
69+
{
70+
ARG_UNUSED(app_id);
71+
ARG_UNUSED(value);
72+
ARG_UNUSED(str_val);
73+
ARG_UNUSED(topic);
74+
ARG_UNUSED(ts);
75+
ARG_UNUSED(output);
76+
return -ENOTSUP;
77+
}
78+
79+
int nrf_cloud_error_msg_decode(const char *const buf, const char *const app_id,
80+
const char *const msg_type, enum nrf_cloud_error *const err)
81+
{
82+
ARG_UNUSED(buf);
83+
ARG_UNUSED(app_id);
84+
ARG_UNUSED(msg_type);
85+
ARG_UNUSED(err);
86+
/* Return non-zero: signals "no JSON error message found", which causes
87+
* the callers (ground_fix / agnss / pgps decode) to return -EPROTO.
88+
*/
89+
return -ENOENT;
90+
}
91+
92+
int nrf_cloud_rest_fota_execution_decode(const char *const response,
93+
struct nrf_cloud_fota_job_info *const job)
94+
{
95+
ARG_UNUSED(response);
96+
ARG_UNUSED(job);
97+
return -ENOTSUP;
98+
}
99+
100+
/* -------------------------------------------------------------------------
101+
* nrf_cloud_agnss_type_array_get — called in the CBOR path of
102+
* coap_codec_agnss_encode when type == NRF_CLOUD_REST_AGNSS_REQ_CUSTOM.
103+
*
104+
* The real implementation parses an nrf_modem_gnss_agnss_data_frame bitmask
105+
* and fills in an array of nrf_cloud_agnss_type values. For unit testing
106+
* purposes a fixed two-element response is sufficient; it keeps the test
107+
* hermetic and produces a deterministic, non-empty CBOR output.
108+
* -------------------------------------------------------------------------
109+
*/
110+
111+
int nrf_cloud_agnss_type_array_get(const struct nrf_modem_gnss_agnss_data_frame *const request,
112+
enum nrf_cloud_agnss_type *array, const size_t array_size)
113+
{
114+
ARG_UNUSED(request);
115+
116+
if (!array || array_size < 2) {
117+
return -EINVAL;
118+
}
119+
120+
array[0] = NRF_CLOUD_AGNSS_GPS_UTC_PARAMETERS;
121+
array[1] = NRF_CLOUD_AGNSS_GPS_EPHEMERIDES;
122+
123+
return 2;
124+
}

0 commit comments

Comments
 (0)