1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/ztest.h>
9 
10 #include "lwm2m_engine.h"
11 #include "lwm2m_rw_json.h"
12 
13 #define TEST_OBJ_ID 0xFFFF
14 #define TEST_OBJ_INST_ID 0
15 
16 #define TEST_RES_S8 0
17 #define TEST_RES_S16 1
18 #define TEST_RES_S32 2
19 #define TEST_RES_S64 3
20 #define TEST_RES_STRING 4
21 #define TEST_RES_FLOAT 5
22 #define TEST_RES_BOOL 6
23 #define TEST_RES_OBJLNK 7
24 
25 #define TEST_OBJ_RES_MAX_ID 8
26 
27 static struct lwm2m_engine_obj test_obj;
28 
29 static struct lwm2m_engine_obj_field test_fields[] = {
30 	OBJ_FIELD_DATA(TEST_RES_S8, RW, S8),
31 	OBJ_FIELD_DATA(TEST_RES_S16, RW, S16),
32 	OBJ_FIELD_DATA(TEST_RES_S32, RW, S32),
33 	OBJ_FIELD_DATA(TEST_RES_S64, RW, S64),
34 	OBJ_FIELD_DATA(TEST_RES_STRING, RW, STRING),
35 	OBJ_FIELD_DATA(TEST_RES_FLOAT, RW, FLOAT),
36 	OBJ_FIELD_DATA(TEST_RES_BOOL, RW, BOOL),
37 	OBJ_FIELD_DATA(TEST_RES_OBJLNK, RW, OBJLNK),
38 };
39 
40 static struct lwm2m_engine_obj_inst test_inst;
41 static struct lwm2m_engine_res test_res[TEST_OBJ_RES_MAX_ID];
42 static struct lwm2m_engine_res_inst test_res_inst[TEST_OBJ_RES_MAX_ID];
43 
44 #define TEST_STRING_MAX_SIZE 16
45 
46 static int8_t test_s8;
47 static int16_t test_s16;
48 static int32_t test_s32;
49 static int64_t test_s64;
50 static char test_string[TEST_STRING_MAX_SIZE];
51 static double test_float;
52 static bool test_bool;
53 static struct lwm2m_objlnk test_objlnk;
54 
test_obj_create(uint16_t obj_inst_id)55 static struct lwm2m_engine_obj_inst *test_obj_create(uint16_t obj_inst_id)
56 {
57 	int i = 0, j = 0;
58 
59 	init_res_instance(test_res_inst, ARRAY_SIZE(test_res_inst));
60 
61 	INIT_OBJ_RES_DATA(TEST_RES_S8, test_res, i, test_res_inst, j,
62 			  &test_s8, sizeof(test_s8));
63 	INIT_OBJ_RES_DATA(TEST_RES_S16, test_res, i, test_res_inst, j,
64 			  &test_s16, sizeof(test_s16));
65 	INIT_OBJ_RES_DATA(TEST_RES_S32, test_res, i, test_res_inst, j,
66 			  &test_s32, sizeof(test_s32));
67 	INIT_OBJ_RES_DATA(TEST_RES_S64, test_res, i, test_res_inst, j,
68 			  &test_s64, sizeof(test_s64));
69 	INIT_OBJ_RES_DATA(TEST_RES_STRING, test_res, i, test_res_inst, j,
70 			  &test_string, sizeof(test_string));
71 	INIT_OBJ_RES_DATA(TEST_RES_FLOAT, test_res, i, test_res_inst, j,
72 			  &test_float, sizeof(test_float));
73 	INIT_OBJ_RES_DATA(TEST_RES_BOOL, test_res, i, test_res_inst, j,
74 			  &test_bool, sizeof(test_bool));
75 	INIT_OBJ_RES_DATA(TEST_RES_OBJLNK, test_res, i, test_res_inst, j,
76 			  &test_objlnk, sizeof(test_objlnk));
77 
78 	test_inst.resources = test_res;
79 	test_inst.resource_count = i;
80 
81 	return &test_inst;
82 }
83 
test_obj_init(void)84 static void *test_obj_init(void)
85 {
86 	struct lwm2m_engine_obj_inst *obj_inst = NULL;
87 
88 	test_obj.obj_id = TEST_OBJ_ID;
89 	test_obj.version_major = 1;
90 	test_obj.version_minor = 0;
91 	test_obj.is_core = false;
92 	test_obj.fields = test_fields;
93 	test_obj.field_count = ARRAY_SIZE(test_fields);
94 	test_obj.max_instance_count = 1U;
95 	test_obj.create_cb = test_obj_create;
96 
97 	(void)lwm2m_register_obj(&test_obj);
98 	(void)lwm2m_create_obj_inst(TEST_OBJ_ID, TEST_OBJ_INST_ID, &obj_inst);
99 	return NULL;
100 }
101 
102 
103 /* 2 bytes for Content Format option + payload marker */
104 #define TEST_PAYLOAD_OFFSET 3
105 #define TEST_PAYLOAD(res_id, type, value) \
106 	"{\"bn\":\"/65535/0/\",\"e\":[{\"n\":\"" STRINGIFY(res_id) \
107 	"\",\"" type "\":" value "}]}"
108 
109 static struct lwm2m_message test_msg;
110 
context_reset(void)111 static void context_reset(void)
112 {
113 	memset(&test_msg, 0, sizeof(test_msg));
114 
115 	test_msg.out.writer = &json_writer;
116 	test_msg.out.out_cpkt = &test_msg.cpkt;
117 
118 	test_msg.in.reader = &json_reader;
119 	test_msg.in.in_cpkt = &test_msg.cpkt;
120 
121 	test_msg.path.level = LWM2M_PATH_LEVEL_RESOURCE;
122 	test_msg.path.obj_id = TEST_OBJ_ID;
123 	test_msg.path.obj_inst_id = TEST_OBJ_INST_ID;
124 
125 	test_msg.cpkt.data = test_msg.msg_data;
126 	test_msg.cpkt.max_len = sizeof(test_msg.msg_data);
127 }
128 
test_payload_set(const char * payload)129 static void test_payload_set(const char *payload)
130 {
131 	memcpy(test_msg.msg_data + 1, payload, strlen(payload));
132 	test_msg.cpkt.offset = strlen(payload) + 1;
133 	test_msg.in.offset = 1; /* Payload marker */
134 }
135 
test_prepare(void * dummy)136 static void test_prepare(void *dummy)
137 {
138 	ARG_UNUSED(dummy);
139 	context_reset();
140 }
141 
test_prepare_nomem(void * dummy)142 static void test_prepare_nomem(void *dummy)
143 {
144 	ARG_UNUSED(dummy);
145 	context_reset();
146 
147 	/* Leave some space for Content-format option */
148 	test_msg.cpkt.offset = sizeof(test_msg.msg_data) - TEST_PAYLOAD_OFFSET;
149 }
150 
test_prepare_nodata(void * dummy)151 static void test_prepare_nodata(void *dummy)
152 {
153 	ARG_UNUSED(dummy);
154 	context_reset();
155 }
156 
157 
ZTEST(net_content_json,test_put_s8)158 ZTEST(net_content_json, test_put_s8)
159 {
160 	int ret;
161 	int i;
162 	uint16_t offset = 0;
163 	int8_t value[] = { 0, INT8_MAX, INT8_MIN };
164 	char * const expected_payload[] = {
165 		TEST_PAYLOAD(TEST_RES_S8, "v", "0"),
166 		TEST_PAYLOAD(TEST_RES_S8, "v", "127"),
167 		TEST_PAYLOAD(TEST_RES_S8, "v", "-128"),
168 	};
169 
170 	test_msg.path.res_id = TEST_RES_S8;
171 
172 	for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
173 		test_s8 = value[i];
174 
175 		ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
176 		zassert_true(ret >= 0, "Error reported");
177 
178 		offset += TEST_PAYLOAD_OFFSET;
179 		zassert_mem_equal(test_msg.msg_data + offset,
180 				  expected_payload[i],
181 				  strlen(expected_payload[i]),
182 				  "Invalid payload format");
183 
184 		offset += strlen(expected_payload[i]);
185 		zassert_equal(test_msg.cpkt.offset, offset,
186 			      "Invalid packet offset");
187 	}
188 }
189 
ZTEST(net_content_json_nomem,test_put_s8_nomem)190 ZTEST(net_content_json_nomem, test_put_s8_nomem)
191 {
192 	int ret;
193 
194 	test_msg.path.res_id = TEST_RES_S8;
195 
196 	ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
197 	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
198 }
199 
ZTEST(net_content_json,test_put_s16)200 ZTEST(net_content_json, test_put_s16)
201 {
202 	int ret;
203 	int i;
204 	uint16_t offset = 0;
205 	int16_t value[] = { 0, INT16_MAX, INT16_MIN };
206 	char * const expected_payload[] = {
207 		TEST_PAYLOAD(TEST_RES_S16, "v", "0"),
208 		TEST_PAYLOAD(TEST_RES_S16, "v", "32767"),
209 		TEST_PAYLOAD(TEST_RES_S16, "v", "-32768"),
210 	};
211 
212 	test_msg.path.res_id = TEST_RES_S16;
213 
214 	for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
215 		test_s16 = value[i];
216 
217 		ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
218 		zassert_true(ret >= 0, "Error reported");
219 
220 		offset += TEST_PAYLOAD_OFFSET;
221 		zassert_mem_equal(test_msg.msg_data + offset,
222 				  expected_payload[i],
223 				  strlen(expected_payload[i]),
224 				  "Invalid payload format");
225 
226 		offset += strlen(expected_payload[i]);
227 		zassert_equal(test_msg.cpkt.offset, offset,
228 			      "Invalid packet offset");
229 	}
230 }
231 
ZTEST(net_content_json_nomem,test_put_s16_nomem)232 ZTEST(net_content_json_nomem, test_put_s16_nomem)
233 {
234 	int ret;
235 
236 	test_msg.path.res_id = TEST_RES_S16;
237 
238 	ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
239 	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
240 }
241 
ZTEST(net_content_json,test_put_s32)242 ZTEST(net_content_json, test_put_s32)
243 {
244 	int ret;
245 	int i;
246 	uint16_t offset = 0;
247 	int32_t value[] = { 0, INT32_MAX, INT32_MIN };
248 	char * const expected_payload[] = {
249 		TEST_PAYLOAD(TEST_RES_S32, "v", "0"),
250 		TEST_PAYLOAD(TEST_RES_S32, "v", "2147483647"),
251 		TEST_PAYLOAD(TEST_RES_S32, "v", "-2147483648"),
252 	};
253 
254 	test_msg.path.res_id = TEST_RES_S32;
255 
256 	for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
257 		test_s32 = value[i];
258 
259 		ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
260 		zassert_true(ret >= 0, "Error reported");
261 
262 		offset += TEST_PAYLOAD_OFFSET;
263 		zassert_mem_equal(test_msg.msg_data + offset,
264 				  expected_payload[i],
265 				  strlen(expected_payload[i]),
266 				  "Invalid payload format");
267 
268 		offset += strlen(expected_payload[i]);
269 		zassert_equal(test_msg.cpkt.offset, offset,
270 			      "Invalid packet offset");
271 	}
272 }
273 
ZTEST(net_content_json_nomem,test_put_s32_nomem)274 ZTEST(net_content_json_nomem, test_put_s32_nomem)
275 {
276 	int ret;
277 
278 	test_msg.path.res_id = TEST_RES_S32;
279 
280 	ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
281 	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
282 }
283 
ZTEST(net_content_json,test_put_s64)284 ZTEST(net_content_json, test_put_s64)
285 {
286 	int ret;
287 	int i;
288 	uint16_t offset = 0;
289 	int64_t value[] = { 0, INT64_MAX, INT64_MIN };
290 	char * const expected_payload[] = {
291 		TEST_PAYLOAD(TEST_RES_S64, "v", "0"),
292 		TEST_PAYLOAD(TEST_RES_S64, "v", "9223372036854775807"),
293 		TEST_PAYLOAD(TEST_RES_S64, "v", "-9223372036854775808"),
294 	};
295 
296 	test_msg.path.res_id = TEST_RES_S64;
297 
298 	for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
299 		test_s64 = value[i];
300 
301 		ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
302 		zassert_true(ret >= 0, "Error reported");
303 
304 		offset += TEST_PAYLOAD_OFFSET;
305 		zassert_mem_equal(test_msg.msg_data + offset,
306 				  expected_payload[i],
307 				  strlen(expected_payload[i]),
308 				  "Invalid payload format");
309 
310 		offset += strlen(expected_payload[i]);
311 		zassert_equal(test_msg.cpkt.offset, offset,
312 			      "Invalid packet offset");
313 	}
314 }
315 
ZTEST(net_content_json_nomem,test_put_s64_nomem)316 ZTEST(net_content_json_nomem, test_put_s64_nomem)
317 {
318 	int ret;
319 
320 	test_msg.path.res_id = TEST_RES_S64;
321 
322 	ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
323 	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
324 }
325 
ZTEST(net_content_json,test_put_string)326 ZTEST(net_content_json, test_put_string)
327 {
328 	int ret;
329 	const char *expected_payload =
330 		TEST_PAYLOAD(TEST_RES_STRING, "sv", "\"test_string\"");
331 
332 	strcpy(test_string, "test_string");
333 	test_msg.path.res_id = TEST_RES_STRING;
334 
335 	ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
336 	zassert_true(ret >= 0, "Error reported");
337 
338 	zassert_mem_equal(test_msg.msg_data + TEST_PAYLOAD_OFFSET,
339 			 expected_payload, strlen(expected_payload),
340 			  "Invalid payload format");
341 	zassert_equal(test_msg.cpkt.offset,
342 		      strlen(expected_payload) + TEST_PAYLOAD_OFFSET,
343 		      "Invalid packet offset");
344 }
345 
ZTEST(net_content_json_nomem,test_put_string_nomem)346 ZTEST(net_content_json_nomem, test_put_string_nomem)
347 {
348 	int ret;
349 
350 	test_msg.path.res_id = TEST_RES_STRING;
351 
352 	ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
353 	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
354 }
355 
ZTEST(net_content_json,test_put_float)356 ZTEST(net_content_json, test_put_float)
357 {
358 	int ret;
359 	int i;
360 	uint16_t offset = 0;
361 	double value[] = { 0., 0.123, -0.987, 3., -10., 2.333, -123.125 };
362 	char * const expected_payload[] = {
363 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "0.0"),
364 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "0.123"),
365 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "-0.987"),
366 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "3.0"),
367 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "-10.0"),
368 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "2.333"),
369 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "-123.125"),
370 	};
371 
372 	test_msg.path.res_id = TEST_RES_FLOAT;
373 
374 	for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
375 		test_float = value[i];
376 
377 		ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
378 		zassert_true(ret >= 0, "Error reported");
379 
380 		offset += TEST_PAYLOAD_OFFSET;
381 		zassert_mem_equal(test_msg.msg_data + offset,
382 				  expected_payload[i],
383 				  strlen(expected_payload[i]),
384 				  "Invalid payload format");
385 
386 		offset += strlen(expected_payload[i]);
387 		zassert_equal(test_msg.cpkt.offset, offset,
388 			      "Invalid packet offset");
389 	}
390 }
391 
ZTEST(net_content_json_nomem,test_put_float_nomem)392 ZTEST(net_content_json_nomem, test_put_float_nomem)
393 {
394 	int ret;
395 
396 	test_msg.path.res_id = TEST_RES_FLOAT;
397 
398 	ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
399 	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
400 }
401 
ZTEST(net_content_json,test_put_bool)402 ZTEST(net_content_json, test_put_bool)
403 {
404 	int ret;
405 	int i;
406 	uint16_t offset = 0;
407 	bool value[] = { true, false };
408 	char * const expected_payload[] = {
409 		TEST_PAYLOAD(TEST_RES_BOOL, "bv", "true"),
410 		TEST_PAYLOAD(TEST_RES_BOOL, "bv", "false"),
411 	};
412 
413 	test_msg.path.res_id = TEST_RES_BOOL;
414 
415 	for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
416 		test_bool = value[i];
417 
418 		ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
419 		zassert_true(ret >= 0, "Error reported");
420 
421 		offset += TEST_PAYLOAD_OFFSET;
422 		zassert_mem_equal(test_msg.msg_data + offset,
423 				  expected_payload[i],
424 				  strlen(expected_payload[i]),
425 				  "Invalid payload format");
426 
427 		offset += strlen(expected_payload[i]);
428 		zassert_equal(test_msg.cpkt.offset, offset,
429 			      "Invalid packet offset");
430 	}
431 }
432 
ZTEST(net_content_json_nomem,test_put_bool_nomem)433 ZTEST(net_content_json_nomem, test_put_bool_nomem)
434 {
435 	int ret;
436 
437 	test_msg.path.res_id = TEST_RES_BOOL;
438 
439 	ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
440 	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
441 }
442 
ZTEST(net_content_json,test_put_objlnk)443 ZTEST(net_content_json, test_put_objlnk)
444 {
445 	int ret;
446 	int i;
447 	uint16_t offset = 0;
448 	struct lwm2m_objlnk value[] = {
449 		{ 0, 0 }, { 1, 1 }, { LWM2M_OBJLNK_MAX_ID, LWM2M_OBJLNK_MAX_ID }
450 	};
451 	char * const expected_payload[] = {
452 		TEST_PAYLOAD(TEST_RES_OBJLNK, "ov", "\"0:0\""),
453 		TEST_PAYLOAD(TEST_RES_OBJLNK, "ov", "\"1:1\""),
454 		TEST_PAYLOAD(TEST_RES_OBJLNK, "ov", "\"65535:65535\""),
455 	};
456 
457 	test_msg.path.res_id = TEST_RES_OBJLNK;
458 
459 	for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
460 		test_objlnk = value[i];
461 
462 		ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
463 		zassert_true(ret >= 0, "Error reported");
464 
465 		offset += TEST_PAYLOAD_OFFSET;
466 		zassert_mem_equal(test_msg.msg_data + offset,
467 				  expected_payload[i],
468 				  strlen(expected_payload[i]),
469 				  "Invalid payload format");
470 
471 		offset += strlen(expected_payload[i]);
472 		zassert_equal(test_msg.cpkt.offset, offset,
473 			      "Invalid packet offset");
474 	}
475 }
476 
ZTEST(net_content_json_nomem,test_put_objlnk_nomem)477 ZTEST(net_content_json_nomem, test_put_objlnk_nomem)
478 {
479 	int ret;
480 
481 	test_msg.path.res_id = TEST_RES_OBJLNK;
482 
483 	ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
484 	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
485 }
486 
ZTEST(net_content_json,test_get_s32)487 ZTEST(net_content_json, test_get_s32)
488 {
489 	int ret;
490 	int i;
491 	char * const payload[] = {
492 		TEST_PAYLOAD(TEST_RES_S32, "v", "0"),
493 		TEST_PAYLOAD(TEST_RES_S32, "v", "2147483647"),
494 		TEST_PAYLOAD(TEST_RES_S32, "v", "-2147483648"),
495 	};
496 	int32_t expected_value[] = { 0, INT32_MAX, INT32_MIN };
497 
498 	test_msg.path.res_id = TEST_RES_S32;
499 
500 	for (i = 0; i < ARRAY_SIZE(expected_value); i++) {
501 		test_payload_set(payload[i]);
502 
503 		ret = do_write_op_json(&test_msg);
504 		zassert_true(ret >= 0, "Error reported");
505 		zassert_equal(test_s32, expected_value[i], "Invalid value parsed");
506 	}
507 }
508 
ZTEST(net_content_json_nomem,test_get_s32_nodata)509 ZTEST(net_content_json_nomem, test_get_s32_nodata)
510 {
511 	int ret;
512 
513 	test_msg.path.res_id = TEST_RES_S32;
514 
515 	ret = do_write_op_json(&test_msg);
516 	zassert_equal(ret, -EINVAL, "Invalid error code returned");
517 }
518 
ZTEST(net_content_json,test_get_s64)519 ZTEST(net_content_json, test_get_s64)
520 {
521 	int ret;
522 	int i;
523 	char * const payload[] = {
524 		TEST_PAYLOAD(TEST_RES_S64, "v", "0"),
525 		TEST_PAYLOAD(TEST_RES_S64, "v", "9223372036854775807"),
526 		TEST_PAYLOAD(TEST_RES_S64, "v", "-9223372036854775808"),
527 	};
528 	char * const payload_overflow[] = {
529 		TEST_PAYLOAD(TEST_RES_S64, "v", "9223372036854775808"),
530 		TEST_PAYLOAD(TEST_RES_S64, "v", "-9223372036854775809"),
531 	};
532 	int64_t expected_value[] = { 0, INT64_MAX, INT64_MIN };
533 
534 	test_msg.path.res_id = TEST_RES_S64;
535 
536 	for (i = 0; i < ARRAY_SIZE(expected_value); i++) {
537 		test_payload_set(payload[i]);
538 
539 		ret = do_write_op_json(&test_msg);
540 		zassert_true(ret >= 0, "Error reported");
541 		zassert_equal(test_s64, expected_value[i], "Invalid value parsed");
542 	}
543 
544 	for (i = 0; i < ARRAY_SIZE(payload_overflow); i++) {
545 		test_payload_set(payload_overflow[i]);
546 
547 		ret = do_write_op_json(&test_msg);
548 		zassert_equal(ret, -EINVAL, "Error expected on too large value");
549 	}
550 }
551 
ZTEST(net_content_json_nodata,test_get_s64_nodata)552 ZTEST(net_content_json_nodata, test_get_s64_nodata)
553 {
554 	int ret;
555 
556 	test_msg.path.res_id = TEST_RES_S64;
557 
558 	ret = do_write_op_json(&test_msg);
559 	zassert_equal(ret, -EINVAL, "Invalid error code returned");
560 }
561 
ZTEST(net_content_json,test_get_string)562 ZTEST(net_content_json, test_get_string)
563 {
564 	int ret;
565 	const char *payload =
566 		TEST_PAYLOAD(TEST_RES_STRING, "sv", "\"test_string\"");
567 	const char *expected_value = "test_string";
568 
569 	test_msg.path.res_id = TEST_RES_STRING;
570 
571 	test_payload_set(payload);
572 
573 	ret = do_write_op_json(&test_msg);
574 	zassert_true(ret >= 0, "Error reported");
575 	zassert_mem_equal(test_string, expected_value, strlen(expected_value),
576 			  "Invalid value parsed");
577 
578 	/* Should not truncate but return an error */
579 	const char *long_payload =
580 		TEST_PAYLOAD(TEST_RES_STRING, "sv", "\"test_stringtest_string\"");
581 	test_payload_set(long_payload);
582 	ret = do_write_op_json(&test_msg);
583 	zassert_equal(ret, -ENOMEM);
584 }
585 
ZTEST(net_content_json,test_get_string_utf8)586 ZTEST(net_content_json, test_get_string_utf8)
587 {
588 	int ret;
589 	const char *payload =
590 		TEST_PAYLOAD(TEST_RES_STRING, "sv", "\"��‍����\"");
591 	static const char expected_value[] = "��‍����";
592 
593 	test_msg.path.res_id = TEST_RES_STRING;
594 
595 	test_payload_set(payload);
596 
597 	ret = do_write_op_json(&test_msg);
598 	zassert_true(ret >= 0, "Error reported");
599 	zassert_mem_equal(test_string, expected_value, strlen(expected_value),
600 			  "Invalid value parsed");
601 
602 	/* Should not truncate but return an error */
603 	const char *long_payload =
604 		TEST_PAYLOAD(TEST_RES_STRING, "sv", "\"��‍������\"");
605 	test_payload_set(long_payload);
606 	ret = do_write_op_json(&test_msg);
607 	zassert_equal(ret, -ENOMEM);
608 }
609 
ZTEST(net_content_json_nodata,test_get_string_nodata)610 ZTEST(net_content_json_nodata, test_get_string_nodata)
611 {
612 	int ret;
613 
614 	test_msg.path.res_id = TEST_RES_STRING;
615 
616 	ret = do_write_op_json(&test_msg);
617 	zassert_equal(ret, -EINVAL, "Invalid error code returned");
618 }
619 
620 #define DOUBLE_CMP_EPSILON 0.000000001
621 
ZTEST(net_content_json,test_get_float)622 ZTEST(net_content_json, test_get_float)
623 {
624 	int ret;
625 	int i;
626 	char * const payload[] = {
627 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "0.0"),
628 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "0.123"),
629 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "-0.987"),
630 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "3.0"),
631 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "-10.0"),
632 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "2.333"),
633 		TEST_PAYLOAD(TEST_RES_FLOAT, "v", "-123.125"),
634 	};
635 	double expected_value[] = {
636 		0., 0.123, -0.987, 3., -10., 2.333, -123.125
637 	};
638 
639 	test_msg.path.res_id = TEST_RES_FLOAT;
640 
641 	for (i = 0; i < ARRAY_SIZE(expected_value); i++) {
642 		test_payload_set(payload[i]);
643 
644 		ret = do_write_op_json(&test_msg);
645 		zassert_true(ret >= 0, "Error reported");
646 		zassert_true((test_float > expected_value[i] - DOUBLE_CMP_EPSILON) &&
647 			     (test_float < expected_value[i] + DOUBLE_CMP_EPSILON),
648 			     "Invalid value parsed");
649 	}
650 }
651 
ZTEST(net_content_json_nodata,test_get_float_nodata)652 ZTEST(net_content_json_nodata, test_get_float_nodata)
653 {
654 	int ret;
655 
656 	test_msg.path.res_id = TEST_RES_FLOAT;
657 
658 	ret = do_write_op_json(&test_msg);
659 	zassert_equal(ret, -EINVAL, "Invalid error code returned");
660 }
661 
ZTEST(net_content_json,test_get_bool)662 ZTEST(net_content_json, test_get_bool)
663 {
664 	int ret;
665 	int i;
666 	char * const payload[] = {
667 		TEST_PAYLOAD(TEST_RES_BOOL, "bv", "true"),
668 		TEST_PAYLOAD(TEST_RES_BOOL, "bv", "false"),
669 	};
670 	bool expected_value[] = { true, false };
671 
672 	test_msg.path.res_id = TEST_RES_BOOL;
673 
674 	for (i = 0; i < ARRAY_SIZE(expected_value); i++) {
675 		test_payload_set(payload[i]);
676 
677 		ret = do_write_op_json(&test_msg);
678 		zassert_true(ret >= 0, "Error reported");
679 		zassert_equal(test_bool, expected_value[i], "Invalid value parsed");
680 	}
681 }
682 
ZTEST(net_content_json_nodata,test_get_bool_nodata)683 ZTEST(net_content_json_nodata, test_get_bool_nodata)
684 {
685 	int ret;
686 
687 	test_msg.path.res_id = TEST_RES_BOOL;
688 
689 	ret = do_write_op_json(&test_msg);
690 	zassert_equal(ret, -EINVAL, "Invalid error code returned");
691 }
692 
ZTEST(net_content_json,test_get_objlnk)693 ZTEST(net_content_json, test_get_objlnk)
694 {
695 	int ret;
696 	int i;
697 	char * const payload[] = {
698 		TEST_PAYLOAD(TEST_RES_OBJLNK, "ov", "\"0:0\""),
699 		TEST_PAYLOAD(TEST_RES_OBJLNK, "ov", "\"1:1\""),
700 		TEST_PAYLOAD(TEST_RES_OBJLNK, "ov", "\"65535:65535\""),
701 	};
702 	struct lwm2m_objlnk expected_value[] = {
703 		{ 0, 0 }, { 1, 1 }, { LWM2M_OBJLNK_MAX_ID, LWM2M_OBJLNK_MAX_ID }
704 	};
705 
706 	test_msg.path.res_id = TEST_RES_OBJLNK;
707 
708 	for (i = 0; i < ARRAY_SIZE(expected_value); i++) {
709 		test_payload_set(payload[i]);
710 
711 		ret = do_write_op_json(&test_msg);
712 		zassert_true(ret >= 0, "Error reported");
713 		zassert_mem_equal(&test_objlnk, &expected_value[i],
714 				  sizeof(test_objlnk), "Invalid value parsed");
715 	}
716 }
717 
ZTEST(net_content_json_nodata,test_get_objlnk_nodata)718 ZTEST(net_content_json_nodata, test_get_objlnk_nodata)
719 {
720 	int ret;
721 
722 	test_msg.path.res_id = TEST_RES_OBJLNK;
723 
724 	ret = do_write_op_json(&test_msg);
725 	zassert_equal(ret, -EINVAL, "Invalid error code returned");
726 }
727 
728 ZTEST_SUITE(net_content_json, NULL, test_obj_init, test_prepare, NULL, NULL);
729 ZTEST_SUITE(net_content_json_nomem, NULL, test_obj_init, test_prepare_nomem, NULL, NULL);
730 ZTEST_SUITE(net_content_json_nodata, NULL, test_obj_init, test_prepare_nodata, NULL, NULL);
731