152af6ccbSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
252af6ccbSBruce Richardson * Copyright 2020 Intel Corporation
352af6ccbSBruce Richardson */
452af6ccbSBruce Richardson
552af6ccbSBruce Richardson #include <string.h>
652af6ccbSBruce Richardson
709e640e3SDavid Marchand #include "telemetry_json.h"
809e640e3SDavid Marchand
952af6ccbSBruce Richardson #include "test.h"
1052af6ccbSBruce Richardson
1152af6ccbSBruce Richardson static int
test_basic_array(void)1252af6ccbSBruce Richardson test_basic_array(void)
1352af6ccbSBruce Richardson {
1452af6ccbSBruce Richardson const char *expected = "[\"meaning of life\",42]";
1552af6ccbSBruce Richardson char buf[1024];
1652af6ccbSBruce Richardson int used = 0;
1752af6ccbSBruce Richardson
1852af6ccbSBruce Richardson printf("%s: ", __func__);
1952af6ccbSBruce Richardson used = rte_tel_json_empty_array(buf, sizeof(buf), used);
2052af6ccbSBruce Richardson if (used != 2 || strcmp(buf, "[]"))
2152af6ccbSBruce Richardson return -1;
2252af6ccbSBruce Richardson
2352af6ccbSBruce Richardson used = rte_tel_json_add_array_string(buf, sizeof(buf), used,
2452af6ccbSBruce Richardson "meaning of life");
2552af6ccbSBruce Richardson used = rte_tel_json_add_array_int(buf, sizeof(buf), used, 42);
2652af6ccbSBruce Richardson
2752af6ccbSBruce Richardson printf("buf = '%s', expected = '%s'\n", buf, expected);
2852af6ccbSBruce Richardson if (used != (int)strlen(expected))
2952af6ccbSBruce Richardson return -1;
3052af6ccbSBruce Richardson return strncmp(expected, buf, sizeof(buf));
3152af6ccbSBruce Richardson }
3252af6ccbSBruce Richardson
3352af6ccbSBruce Richardson static int
test_basic_obj(void)3452af6ccbSBruce Richardson test_basic_obj(void)
3552af6ccbSBruce Richardson {
3652af6ccbSBruce Richardson const char *expected = "{\"weddings\":4,\"funerals\":1}";
3752af6ccbSBruce Richardson char buf[1024];
3852af6ccbSBruce Richardson int used = 0;
3952af6ccbSBruce Richardson
402f4520cdSBruce Richardson used = rte_tel_json_add_obj_uint(buf, sizeof(buf), used,
4152af6ccbSBruce Richardson "weddings", 4);
422f4520cdSBruce Richardson used = rte_tel_json_add_obj_uint(buf, sizeof(buf), used,
4352af6ccbSBruce Richardson "funerals", 1);
4452af6ccbSBruce Richardson
4552af6ccbSBruce Richardson printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
4652af6ccbSBruce Richardson if (used != (int)strlen(expected))
4752af6ccbSBruce Richardson return -1;
4852af6ccbSBruce Richardson return strncmp(expected, buf, sizeof(buf));
4952af6ccbSBruce Richardson }
5052af6ccbSBruce Richardson
5152af6ccbSBruce Richardson static int
test_overflow_array(void)5252af6ccbSBruce Richardson test_overflow_array(void)
5352af6ccbSBruce Richardson {
5452af6ccbSBruce Richardson static const char * const strs[] = {"Arsenal", "Chelsea", "Liverpool",
5552af6ccbSBruce Richardson "Spurs"};
5652af6ccbSBruce Richardson const char *expected = "[\"Arsenal\",\"Chelsea\"]";
5752af6ccbSBruce Richardson char buf[25];
5852af6ccbSBruce Richardson int i, used = 0;
5952af6ccbSBruce Richardson
6052af6ccbSBruce Richardson for (i = 0; i < (int)RTE_DIM(strs); i++)
6152af6ccbSBruce Richardson used = rte_tel_json_add_array_string(buf, sizeof(buf), used,
6252af6ccbSBruce Richardson strs[i]);
6352af6ccbSBruce Richardson
6452af6ccbSBruce Richardson printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
6552af6ccbSBruce Richardson if (buf[used - 1] != ']')
6652af6ccbSBruce Richardson return -1;
6752af6ccbSBruce Richardson if (used != (int)strlen(expected))
6852af6ccbSBruce Richardson return -1;
6952af6ccbSBruce Richardson return strncmp(expected, buf, sizeof(buf));
7052af6ccbSBruce Richardson }
7152af6ccbSBruce Richardson
7252af6ccbSBruce Richardson static int
test_overflow_obj(void)7352af6ccbSBruce Richardson test_overflow_obj(void)
7452af6ccbSBruce Richardson {
7552af6ccbSBruce Richardson static const char * const names[] = {"Italy", "Wales", "Scotland",
7652af6ccbSBruce Richardson "Ireland", "England", "France"};
7752af6ccbSBruce Richardson const int vals[RTE_DIM(names)] = {20, 61, 10, 40, 55, 35};
7852af6ccbSBruce Richardson const char *expected = "{\"Italy\":20,\"Wales\":61}";
7952af6ccbSBruce Richardson char buf[25];
8052af6ccbSBruce Richardson int i, used = 0;
8152af6ccbSBruce Richardson
8252af6ccbSBruce Richardson for (i = 0; i < (int)RTE_DIM(names); i++)
832f4520cdSBruce Richardson used = rte_tel_json_add_obj_uint(buf, sizeof(buf), used, names[i], vals[i]);
8452af6ccbSBruce Richardson
8552af6ccbSBruce Richardson printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
8652af6ccbSBruce Richardson if (buf[used - 1] != '}')
8752af6ccbSBruce Richardson return -1;
8852af6ccbSBruce Richardson if (used != (int)strlen(expected))
8952af6ccbSBruce Richardson return -1;
9052af6ccbSBruce Richardson return strncmp(expected, buf, sizeof(buf));
9152af6ccbSBruce Richardson }
9252af6ccbSBruce Richardson
9352af6ccbSBruce Richardson static int
test_large_array_element(void)9452af6ccbSBruce Richardson test_large_array_element(void)
9552af6ccbSBruce Richardson {
9652af6ccbSBruce Richardson static const char str[] = "A really long string to overflow buffer";
9752af6ccbSBruce Richardson /* buffer should be unmodified so initial value and expected are same */
9852af6ccbSBruce Richardson const char *expected = "ABC";
9952af6ccbSBruce Richardson char buf[sizeof(str) - 5] = "ABC";
10052af6ccbSBruce Richardson int used = 0;
10152af6ccbSBruce Richardson
10252af6ccbSBruce Richardson used = rte_tel_json_add_array_string(buf, sizeof(buf), used, str);
10352af6ccbSBruce Richardson printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
10444936548SBruce Richardson if (used != 0)
10544936548SBruce Richardson return -1;
10652af6ccbSBruce Richardson
10744936548SBruce Richardson return strncmp(expected, buf, sizeof(buf));
10852af6ccbSBruce Richardson }
10952af6ccbSBruce Richardson
11052af6ccbSBruce Richardson static int
test_large_obj_element(void)11152af6ccbSBruce Richardson test_large_obj_element(void)
11252af6ccbSBruce Richardson {
11352af6ccbSBruce Richardson static const char str[] = "A really long string to overflow buffer";
11452af6ccbSBruce Richardson /* buffer should be unmodified so initial value and expected are same */
11552af6ccbSBruce Richardson const char *expected = "XYZ";
11652af6ccbSBruce Richardson char buf[sizeof(str) - 5] = "XYZ";
11752af6ccbSBruce Richardson int used = 0;
11852af6ccbSBruce Richardson
1192f4520cdSBruce Richardson used = rte_tel_json_add_obj_uint(buf, sizeof(buf), used, str, 0);
12052af6ccbSBruce Richardson printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
12144936548SBruce Richardson if (used != 0)
12244936548SBruce Richardson return -1;
12352af6ccbSBruce Richardson
12444936548SBruce Richardson return strncmp(expected, buf, sizeof(buf));
12552af6ccbSBruce Richardson }
12652af6ccbSBruce Richardson
12756069f98SBruce Richardson static int
test_string_char_escaping(void)12856069f98SBruce Richardson test_string_char_escaping(void)
12956069f98SBruce Richardson {
13056069f98SBruce Richardson static const char str[] = "A string across\ntwo lines and \"with quotes\"!";
13156069f98SBruce Richardson const char *expected = "\"A string across\\ntwo lines and \\\"with quotes\\\"!\"";
132a515b720SBruce Richardson char buf[sizeof(str) + 10] = "";
13356069f98SBruce Richardson int used = 0;
13456069f98SBruce Richardson
13556069f98SBruce Richardson used = rte_tel_json_str(buf, sizeof(buf), used, str);
13656069f98SBruce Richardson printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
13756069f98SBruce Richardson if (used != (int)strlen(expected))
13856069f98SBruce Richardson return -1;
13956069f98SBruce Richardson
14056069f98SBruce Richardson return strncmp(expected, buf, sizeof(buf));
14156069f98SBruce Richardson }
14256069f98SBruce Richardson
143f46d4260SBruce Richardson static int
test_array_char_escaping(void)144f46d4260SBruce Richardson test_array_char_escaping(void)
145f46d4260SBruce Richardson {
146f46d4260SBruce Richardson /* "meaning of life", with tab between first two words, '\n' at end,
147f46d4260SBruce Richardson * and "life" in quotes, followed by "all the fish" in quotes
148f46d4260SBruce Richardson */
149f46d4260SBruce Richardson const char *expected = "[\"meaning\\tof \\\"life\\\"\\n\",\"\\\"all the fish\\\"\"]";
150f46d4260SBruce Richardson char buf[1024];
151f46d4260SBruce Richardson int used = 0;
152f46d4260SBruce Richardson
153f46d4260SBruce Richardson used = rte_tel_json_empty_array(buf, sizeof(buf), used);
154f46d4260SBruce Richardson if (used != 2 || strcmp(buf, "[]"))
155f46d4260SBruce Richardson return -1;
156f46d4260SBruce Richardson
157f46d4260SBruce Richardson used = rte_tel_json_add_array_string(buf, sizeof(buf), used, "meaning\tof \"life\"\n");
158f46d4260SBruce Richardson used = rte_tel_json_add_array_string(buf, sizeof(buf), used, "\"all the fish\"");
159f46d4260SBruce Richardson
160f46d4260SBruce Richardson printf("buf = '%s', expected = '%s'\n", buf, expected);
161f46d4260SBruce Richardson if (used != (int)strlen(expected))
162f46d4260SBruce Richardson return -1;
163f46d4260SBruce Richardson return strncmp(expected, buf, sizeof(buf));
164f46d4260SBruce Richardson }
165f46d4260SBruce Richardson
16672f3c45cSBruce Richardson static int
test_obj_char_escaping(void)16772f3c45cSBruce Richardson test_obj_char_escaping(void)
16872f3c45cSBruce Richardson {
16972f3c45cSBruce Richardson const char *expected = "{\"good\":\"Clint Eastwood\\n\","
17072f3c45cSBruce Richardson "\"bad\":\"Lee\\tVan\\tCleef\","
17172f3c45cSBruce Richardson "\"ugly\":\"\\rEli Wallach\"}";
17272f3c45cSBruce Richardson char buf[1024];
17372f3c45cSBruce Richardson int used = 0;
17472f3c45cSBruce Richardson
17572f3c45cSBruce Richardson used = rte_tel_json_empty_obj(buf, sizeof(buf), used);
17672f3c45cSBruce Richardson if (used != 2 || strcmp(buf, "{}"))
17772f3c45cSBruce Richardson return -1;
17872f3c45cSBruce Richardson
17972f3c45cSBruce Richardson used = rte_tel_json_add_obj_str(buf, sizeof(buf), used, "good", "Clint Eastwood\n");
18072f3c45cSBruce Richardson used = rte_tel_json_add_obj_str(buf, sizeof(buf), used, "bad", "Lee\tVan\tCleef");
18172f3c45cSBruce Richardson used = rte_tel_json_add_obj_str(buf, sizeof(buf), used, "ugly", "\rEli Wallach");
18272f3c45cSBruce Richardson
18372f3c45cSBruce Richardson printf("buf = '%s', expected = '%s'\n", buf, expected);
18472f3c45cSBruce Richardson if (used != (int)strlen(expected))
18572f3c45cSBruce Richardson return -1;
18672f3c45cSBruce Richardson return strncmp(expected, buf, sizeof(buf));
18772f3c45cSBruce Richardson }
18872f3c45cSBruce Richardson
18944936548SBruce Richardson typedef int (*test_fn)(void);
19044936548SBruce Richardson
19152af6ccbSBruce Richardson static int
test_telemetry_json(void)19252af6ccbSBruce Richardson test_telemetry_json(void)
19352af6ccbSBruce Richardson {
19444936548SBruce Richardson unsigned int i;
19544936548SBruce Richardson test_fn fns[] = {
19644936548SBruce Richardson test_basic_array,
19744936548SBruce Richardson test_basic_obj,
19844936548SBruce Richardson test_overflow_array,
19944936548SBruce Richardson test_overflow_obj,
20044936548SBruce Richardson test_large_array_element,
20144936548SBruce Richardson test_large_obj_element,
20256069f98SBruce Richardson test_string_char_escaping,
203f46d4260SBruce Richardson test_array_char_escaping,
20472f3c45cSBruce Richardson test_obj_char_escaping
20544936548SBruce Richardson };
20644936548SBruce Richardson for (i = 0; i < RTE_DIM(fns); i++)
20744936548SBruce Richardson if (fns[i]() == 0)
20844936548SBruce Richardson printf("OK\n");
20944936548SBruce Richardson else {
21044936548SBruce Richardson printf("ERROR\n");
21152af6ccbSBruce Richardson return -1;
21244936548SBruce Richardson }
21352af6ccbSBruce Richardson return 0;
21452af6ccbSBruce Richardson }
21552af6ccbSBruce Richardson
216*d83fb967SDavid Marchand REGISTER_FAST_TEST(telemetry_json_autotest, true, true, test_telemetry_json);
217