xref: /dpdk/app/test/test_telemetry_json.c (revision d83fb967212efa19d272e7fa65d17c9ad94b17c1)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 Intel Corporation
3  */
4 
5 #include <string.h>
6 
7 #include "telemetry_json.h"
8 
9 #include "test.h"
10 
11 static int
test_basic_array(void)12 test_basic_array(void)
13 {
14 	const char *expected = "[\"meaning of life\",42]";
15 	char buf[1024];
16 	int used = 0;
17 
18 	printf("%s: ", __func__);
19 	used = rte_tel_json_empty_array(buf, sizeof(buf), used);
20 	if (used != 2 || strcmp(buf, "[]"))
21 		return -1;
22 
23 	used = rte_tel_json_add_array_string(buf, sizeof(buf), used,
24 		"meaning of life");
25 	used = rte_tel_json_add_array_int(buf, sizeof(buf), used, 42);
26 
27 	printf("buf = '%s', expected = '%s'\n", buf, expected);
28 	if (used != (int)strlen(expected))
29 		return -1;
30 	return strncmp(expected, buf, sizeof(buf));
31 }
32 
33 static int
test_basic_obj(void)34 test_basic_obj(void)
35 {
36 	const char *expected = "{\"weddings\":4,\"funerals\":1}";
37 	char buf[1024];
38 	int used = 0;
39 
40 	used = rte_tel_json_add_obj_uint(buf, sizeof(buf), used,
41 		"weddings", 4);
42 	used = rte_tel_json_add_obj_uint(buf, sizeof(buf), used,
43 		"funerals", 1);
44 
45 	printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
46 	if (used != (int)strlen(expected))
47 		return -1;
48 	return strncmp(expected, buf, sizeof(buf));
49 }
50 
51 static int
test_overflow_array(void)52 test_overflow_array(void)
53 {
54 	static const char * const strs[] = {"Arsenal", "Chelsea", "Liverpool",
55 			"Spurs"};
56 	const char *expected = "[\"Arsenal\",\"Chelsea\"]";
57 	char buf[25];
58 	int i, used = 0;
59 
60 	for (i = 0; i < (int)RTE_DIM(strs); i++)
61 		used = rte_tel_json_add_array_string(buf, sizeof(buf), used,
62 				strs[i]);
63 
64 	printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
65 	if (buf[used - 1] != ']')
66 		return -1;
67 	if (used != (int)strlen(expected))
68 		return -1;
69 	return strncmp(expected, buf, sizeof(buf));
70 }
71 
72 static int
test_overflow_obj(void)73 test_overflow_obj(void)
74 {
75 	static const char * const names[] = {"Italy", "Wales", "Scotland",
76 			"Ireland", "England", "France"};
77 	const int vals[RTE_DIM(names)] = {20, 61, 10, 40, 55, 35};
78 	const char *expected = "{\"Italy\":20,\"Wales\":61}";
79 	char buf[25];
80 	int i, used = 0;
81 
82 	for (i = 0; i < (int)RTE_DIM(names); i++)
83 		used = rte_tel_json_add_obj_uint(buf, sizeof(buf), used, names[i], vals[i]);
84 
85 	printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
86 	if (buf[used - 1] != '}')
87 		return -1;
88 	if (used != (int)strlen(expected))
89 		return -1;
90 	return strncmp(expected, buf, sizeof(buf));
91 }
92 
93 static int
test_large_array_element(void)94 test_large_array_element(void)
95 {
96 	static const char str[] = "A really long string to overflow buffer";
97 	/* buffer should be unmodified so initial value and expected are same */
98 	const char *expected = "ABC";
99 	char buf[sizeof(str) - 5] = "ABC";
100 	int used = 0;
101 
102 	used = rte_tel_json_add_array_string(buf, sizeof(buf), used, str);
103 	printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
104 	if (used != 0)
105 		return -1;
106 
107 	return strncmp(expected, buf, sizeof(buf));
108 }
109 
110 static int
test_large_obj_element(void)111 test_large_obj_element(void)
112 {
113 	static const char str[] = "A really long string to overflow buffer";
114 	/* buffer should be unmodified so initial value and expected are same */
115 	const char *expected = "XYZ";
116 	char buf[sizeof(str) - 5] = "XYZ";
117 	int used = 0;
118 
119 	used = rte_tel_json_add_obj_uint(buf, sizeof(buf), used, str, 0);
120 	printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
121 	if (used != 0)
122 		return -1;
123 
124 	return strncmp(expected, buf, sizeof(buf));
125 }
126 
127 static int
test_string_char_escaping(void)128 test_string_char_escaping(void)
129 {
130 	static const char str[] = "A string across\ntwo lines and \"with quotes\"!";
131 	const char *expected = "\"A string across\\ntwo lines and \\\"with quotes\\\"!\"";
132 	char buf[sizeof(str) + 10] = "";
133 	int used = 0;
134 
135 	used = rte_tel_json_str(buf, sizeof(buf), used, str);
136 	printf("%s: buf = '%s', expected = '%s'\n", __func__, buf, expected);
137 	if (used != (int)strlen(expected))
138 		return -1;
139 
140 	return strncmp(expected, buf, sizeof(buf));
141 }
142 
143 static int
test_array_char_escaping(void)144 test_array_char_escaping(void)
145 {
146 	/* "meaning of life", with tab between first two words, '\n' at end,
147 	 * and "life" in quotes, followed by "all the fish" in quotes
148 	 */
149 	const char *expected = "[\"meaning\\tof \\\"life\\\"\\n\",\"\\\"all the fish\\\"\"]";
150 	char buf[1024];
151 	int used = 0;
152 
153 	used = rte_tel_json_empty_array(buf, sizeof(buf), used);
154 	if (used != 2 || strcmp(buf, "[]"))
155 		return -1;
156 
157 	used = rte_tel_json_add_array_string(buf, sizeof(buf), used, "meaning\tof \"life\"\n");
158 	used = rte_tel_json_add_array_string(buf, sizeof(buf), used, "\"all the fish\"");
159 
160 	printf("buf = '%s', expected = '%s'\n", buf, expected);
161 	if (used != (int)strlen(expected))
162 		return -1;
163 	return strncmp(expected, buf, sizeof(buf));
164 }
165 
166 static int
test_obj_char_escaping(void)167 test_obj_char_escaping(void)
168 {
169 	const char *expected = "{\"good\":\"Clint Eastwood\\n\","
170 			"\"bad\":\"Lee\\tVan\\tCleef\","
171 			"\"ugly\":\"\\rEli Wallach\"}";
172 	char buf[1024];
173 	int used = 0;
174 
175 	used = rte_tel_json_empty_obj(buf, sizeof(buf), used);
176 	if (used != 2 || strcmp(buf, "{}"))
177 		return -1;
178 
179 	used = rte_tel_json_add_obj_str(buf, sizeof(buf), used, "good", "Clint Eastwood\n");
180 	used = rte_tel_json_add_obj_str(buf, sizeof(buf), used, "bad", "Lee\tVan\tCleef");
181 	used = rte_tel_json_add_obj_str(buf, sizeof(buf), used, "ugly", "\rEli Wallach");
182 
183 	printf("buf = '%s', expected = '%s'\n", buf, expected);
184 	if (used != (int)strlen(expected))
185 		return -1;
186 	return strncmp(expected, buf, sizeof(buf));
187 }
188 
189 typedef int (*test_fn)(void);
190 
191 static int
test_telemetry_json(void)192 test_telemetry_json(void)
193 {
194 	unsigned int i;
195 	test_fn fns[] = {
196 			test_basic_array,
197 			test_basic_obj,
198 			test_overflow_array,
199 			test_overflow_obj,
200 			test_large_array_element,
201 			test_large_obj_element,
202 			test_string_char_escaping,
203 			test_array_char_escaping,
204 			test_obj_char_escaping
205 	};
206 	for (i = 0; i < RTE_DIM(fns); i++)
207 		if (fns[i]() == 0)
208 			printf("OK\n");
209 		else {
210 			printf("ERROR\n");
211 			return -1;
212 		}
213 	return 0;
214 }
215 
216 REGISTER_FAST_TEST(telemetry_json_autotest, true, true, test_telemetry_json);
217