From a50c1d062028197cb5f1c75f1306ace46bf7cd78 Mon Sep 17 00:00:00 2001 From: Leandro Pereira Date: Thu, 23 Mar 2017 16:37:22 -0700 Subject: [PATCH] test: Add test for JSON library This adds a test suite for the JSON library, testing both encoding and decoding of all supported data types, including arrays, nested objects, and basic types such as booleans, numbers, and strings. Jira: ZEP-1607 Change-Id: I4f6ad7e2859a142e06d405e0760e91751e01a31f Signed-off-by: Leandro Pereira --- tests/lib/json/Makefile | 4 + tests/lib/json/prj.conf | 3 + tests/lib/json/src/Makefile | 4 + tests/lib/json/src/main.c | 193 ++++++++++++++++++++++++++++++++++++ tests/lib/json/testcase.ini | 4 + 5 files changed, 208 insertions(+) create mode 100644 tests/lib/json/Makefile create mode 100644 tests/lib/json/prj.conf create mode 100644 tests/lib/json/src/Makefile create mode 100644 tests/lib/json/src/main.c create mode 100644 tests/lib/json/testcase.ini diff --git a/tests/lib/json/Makefile b/tests/lib/json/Makefile new file mode 100644 index 0000000000..4b05dca8ed --- /dev/null +++ b/tests/lib/json/Makefile @@ -0,0 +1,4 @@ +BOARD ?= qemu_x86 +CONF_FILE = prj.conf + +include $(ZEPHYR_BASE)/Makefile.test diff --git a/tests/lib/json/prj.conf b/tests/lib/json/prj.conf new file mode 100644 index 0000000000..c3d72622ba --- /dev/null +++ b/tests/lib/json/prj.conf @@ -0,0 +1,3 @@ +CONFIG_JSON_LIBRARY=y +CONFIG_ZTEST=y +CONFIG_ZTEST_STACKSIZE=32768 diff --git a/tests/lib/json/src/Makefile b/tests/lib/json/src/Makefile new file mode 100644 index 0000000000..afdcaab7fb --- /dev/null +++ b/tests/lib/json/src/Makefile @@ -0,0 +1,4 @@ +obj-y = main.o +ccflags-y += -I${ZEPHYR_BASE}/lib/json/ + +include $(ZEPHYR_BASE)/tests/Makefile.test diff --git a/tests/lib/json/src/main.c b/tests/lib/json/src/main.c new file mode 100644 index 0000000000..ff0361e81e --- /dev/null +++ b/tests/lib/json/src/main.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include + +struct test_nested { + int nested_int; + bool nested_bool; + const char *nested_string; +}; + +struct test_struct { + const char *some_string; + int some_int; + bool some_bool; + struct test_nested some_nested_struct; + int some_array[16]; + size_t some_array_len; +}; + +#define FIELD(struct_, member_, type_) { \ + .field_name = #member_, \ + .field_name_len = sizeof(#member_) - 1, \ + .offset = offsetof(struct_, member_), \ + .type = type_ \ +} +static const struct json_obj_descr nested_descr[] = { + FIELD(struct test_nested, nested_int, JSON_TOK_NUMBER), + FIELD(struct test_nested, nested_bool, JSON_TOK_TRUE), + FIELD(struct test_nested, nested_string, JSON_TOK_STRING), +}; + +static const struct json_obj_descr test_descr[] = { + FIELD(struct test_struct, some_string, JSON_TOK_STRING), + FIELD(struct test_struct, some_int, JSON_TOK_NUMBER), + FIELD(struct test_struct, some_bool, JSON_TOK_TRUE), + JSON_OBJ_DESCR_OBJECT(struct test_struct, some_nested_struct, + nested_descr), + JSON_OBJ_DESCR_ARRAY(struct test_struct, some_array, + 16, some_array_len, JSON_TOK_NUMBER), +}; +#undef FIELD + +static void test_json_encoding(void) +{ + struct test_struct ts = { + .some_string = "zephyr 123", + .some_int = 42, + .some_bool = true, + .some_nested_struct = { + .nested_int = -1234, + .nested_bool = false, + .nested_string = "this should be escaped: \t" + }, + .some_array[0] = 1, + .some_array[1] = 4, + .some_array[2] = 8, + .some_array[3] = 16, + .some_array[4] = 32, + .some_array_len = 5 + }; + char encoded[] = "{\"some_string\":\"zephyr 123\"," + "\"some_int\":42,\"some_bool\":true," + "\"some_nested_struct\":{\"nested_int\":-1234," + "\"nested_bool\":false,\"nested_string\":" + "\"this should be escaped: \\t\"}," + "\"some_array\":[1,4,8,16,32]}"; + char buffer[sizeof(encoded)]; + int ret; + + ret = json_obj_encode_buf(test_descr, ARRAY_SIZE(test_descr), + &ts, buffer, sizeof(buffer)); + assert_equal(ret, 0, "Encoding function returned no errors"); + + ret = strncmp(buffer, encoded, sizeof(encoded) - 1); + assert_equal(ret, 0, "Encoded contents consistent"); +} + +static void test_json_decoding(void) +{ + struct test_struct ts; + char encoded[] = "{\"some_string\":\"zephyr 123\"," + "\"some_int\":\t42\n," + "\"some_bool\":true \t " + "\n" + "\r ," + "\"some_nested_struct\":{ " + "\"nested_int\":-1234,\n\n" + "\"nested_bool\":false,\t" + "\"nested_string\":\"this should be escaped: \\t\"}," + "\"some_array\":[11,22, 33,\t45,\n299]" + "}"; + const int expected_array[] = { 11, 22, 33, 45, 299 }; + int ret; + + ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr, + ARRAY_SIZE(test_descr), &ts); + + assert_equal(ret, (1 << ARRAY_SIZE(test_descr)) - 1, + "All fields decoded correctly"); + + assert_true(!strcmp(ts.some_string, "zephyr 123"), + "String decoded correctly"); + assert_equal(ts.some_int, 42, "Positive integer decoded correctly"); + assert_equal(ts.some_bool, true, "Boolean decoded correctly"); + assert_equal(ts.some_nested_struct.nested_int, -1234, + "Nested negative integer decoded correctly"); + assert_equal(ts.some_nested_struct.nested_bool, false, + "Nested boolean value decoded correctly"); + assert_true(!strcmp(ts.some_nested_struct.nested_string, + "this should be escaped: \\t"), + "Nested string decoded correctly"); + assert_equal(ts.some_array_len, 5, "Array has correct number of items"); + assert_true(!memcmp(ts.some_array, expected_array, + sizeof(expected_array)), + "Array decoded with unexpected values"); +} + +static void test_json_invalid_unicode(void) +{ + struct test_struct ts; + char encoded[] = "{\"some_string\":\"\\uABC@\"}"; + int ret; + + ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr, + ARRAY_SIZE(test_descr), &ts); + assert_equal(ret, -EINVAL, "Decoding has to fail"); +} + +static void test_json_missing_quote(void) +{ + struct test_struct ts; + char encoded[] = "{\"some_string"; + int ret; + + ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr, + ARRAY_SIZE(test_descr), &ts); + assert_equal(ret, -EINVAL, "Decoding has to fail"); +} + +static void test_json_wrong_token(void) +{ + struct test_struct ts; + char encoded[] = "{\"some_string\",}"; + int ret; + + ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr, + ARRAY_SIZE(test_descr), &ts); + assert_equal(ret, -EINVAL, "Decoding has to fail"); +} + +static void test_json_item_wrong_type(void) +{ + struct test_struct ts; + char encoded[] = "{\"some_string\":false}"; + int ret; + + ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr, + ARRAY_SIZE(test_descr), &ts); + assert_equal(ret, -EINVAL, "Decoding has to fail"); +} + +static void test_json_key_not_in_descr(void) +{ + struct test_struct ts; + char encoded[] = "{\"key_not_in_descr\":123456}"; + int ret; + + ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr, + ARRAY_SIZE(test_descr), &ts); + assert_equal(ret, 0, "No items should be decoded"); +} + +void test_main(void) +{ + ztest_test_suite(lib_json_test, + ztest_unit_test(test_json_encoding), + ztest_unit_test(test_json_decoding), + ztest_unit_test(test_json_invalid_unicode), + ztest_unit_test(test_json_missing_quote), + ztest_unit_test(test_json_wrong_token), + ztest_unit_test(test_json_item_wrong_type), + ztest_unit_test(test_json_key_not_in_descr) + ); + + ztest_run_test_suite(lib_json_test); +} diff --git a/tests/lib/json/testcase.ini b/tests/lib/json/testcase.ini new file mode 100644 index 0000000000..0a360c810c --- /dev/null +++ b/tests/lib/json/testcase.ini @@ -0,0 +1,4 @@ +[test] +tags = json +build_only = true +filter = ( CONFIG_SRAM_SIZE > 32 or CONFIG_DCCM_SIZE > 32 or CONFIG_RAM_SIZE > 32 )