xref: /dpdk/app/test/test_telemetry_data.c (revision d83fb967212efa19d272e7fa65d17c9ad94b17c1)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 Intel Corporation
3  */
4 
5 #ifdef RTE_EXEC_ENV_WINDOWS
6 #include "test.h"
7 
8 static int
telemetry_data_autotest(void)9 telemetry_data_autotest(void)
10 {
11 	return TEST_SKIPPED;
12 }
13 
14 #else
15 
16 #include <string.h>
17 #include <sys/socket.h>
18 #include <sys/un.h>
19 #include <unistd.h>
20 #include <limits.h>
21 
22 #include <rte_eal.h>
23 #include <rte_common.h>
24 #include <rte_telemetry.h>
25 #include <rte_string_fns.h>
26 
27 #include "test.h"
28 #include "telemetry_data.h"
29 
30 #define TELEMETRY_VERSION "v2"
31 #define REQUEST_CMD "/test"
32 #define BUF_SIZE 1024
33 #define CHECK_OUTPUT(exp) check_output(__func__, "{\"" REQUEST_CMD "\":" exp "}")
34 
35 /*
36  * Runs a series of test cases, checking the output of telemetry for various different types of
37  * responses. On init, a single connection to DPDK telemetry is made, and a single telemetry
38  * callback "/test" is registered. That callback always returns the value of the static global
39  * variable "response_data", so each test case builds up that structure, and then calls the
40  * "check_output" function to ensure the response received over the socket for "/test" matches
41  * that expected for the response_data value populated.
42  *
43  * NOTE:
44  * - each test case function in this file should be added to the "test_cases" array in
45  *   test_telemetry_data function at the bottom of the file.
46  * - each test case function should populate the "response_data" global variable (below)
47  *   with the appropriate values which would be returned from a simulated telemetry function.
48  *   Then the test case function should have "return CHECK_OUTPUT(<expected_data>);" as it's
49  *   last line. The test infrastructure will then validate that the output when returning
50  *   "response_data" structure matches that in "<expected_data>".
51  * - the response_data structure will be zeroed on entry to each test function, so each function
52  *   can begin with a call to "rte_tel_data_string/start_array/start_dict" as so desired.
53  * - the expected_output for each function can be just the actual json data from the
54  *   "response_data" value. The CHECK_OUTPUT macro will include the appropriate "{\"/test\": ... }"
55  *   structure around the json output.
56  *
57  *  See test_simple_string(), or test_case_array_int() for a basic examples of test cases.
58  */
59 
60 
61 static struct rte_tel_data response_data;
62 static int sock;
63 
64 
65 /*
66  * This function is the callback registered with Telemetry to be used when
67  * the /test command is requested. This callback returns the global data built
68  * up by the individual test cases.
69  */
70 static int
telemetry_test_cb(const char * cmd __rte_unused,const char * params __rte_unused,struct rte_tel_data * d)71 telemetry_test_cb(const char *cmd __rte_unused, const char *params __rte_unused,
72 		struct rte_tel_data *d)
73 {
74 	*d = response_data;
75 	return 0;
76 }
77 
78 /*
79  * This function is called by each test case function. It communicates with
80  * the telemetry socket by requesting the /test command, and reading the
81  * response. The expected response is passed in by the test case function,
82  * and is compared to the actual response received from Telemetry.
83  */
84 static int
check_output(const char * func_name,const char * expected)85 check_output(const char *func_name, const char *expected)
86 {
87 	int bytes;
88 	char buf[BUF_SIZE * 16];
89 	if (write(sock, REQUEST_CMD, strlen(REQUEST_CMD)) < 0) {
90 		printf("%s: Error with socket write - %s\n", __func__,
91 				strerror(errno));
92 		return -1;
93 	}
94 	bytes = read(sock, buf, sizeof(buf) - 1);
95 	if (bytes < 0) {
96 		printf("%s: Error with socket read - %s\n", __func__,
97 				strerror(errno));
98 		return -1;
99 	}
100 	buf[bytes] = '\0';
101 	printf("%s: buf = '%s', expected = '%s'\n", func_name, buf, expected);
102 	return strncmp(expected, buf, sizeof(buf));
103 }
104 
105 static int
test_null_return(void)106 test_null_return(void)
107 {
108 	return CHECK_OUTPUT("null");
109 }
110 
111 static int
test_simple_string(void)112 test_simple_string(void)
113 {
114 	rte_tel_data_string(&response_data, "Simple string");
115 
116 	return CHECK_OUTPUT("\"Simple string\"");
117 }
118 
119 static int
test_dict_with_array_int_values(void)120 test_dict_with_array_int_values(void)
121 {
122 	int i;
123 
124 	struct rte_tel_data *child_data = rte_tel_data_alloc();
125 	rte_tel_data_start_array(child_data, RTE_TEL_INT_VAL);
126 
127 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
128 	rte_tel_data_start_array(child_data2, RTE_TEL_INT_VAL);
129 
130 	rte_tel_data_start_dict(&response_data);
131 
132 	for (i = 0; i < 5; i++) {
133 		rte_tel_data_add_array_int(child_data, i);
134 		rte_tel_data_add_array_int(child_data2, i);
135 	}
136 
137 	rte_tel_data_add_dict_container(&response_data, "dict_0",
138 	 child_data, 0);
139 	rte_tel_data_add_dict_container(&response_data, "dict_1",
140 	 child_data2, 0);
141 
142 	return CHECK_OUTPUT("{\"dict_0\":[0,1,2,3,4],\"dict_1\":[0,1,2,3,4]}");
143 }
144 
145 static int
test_array_with_array_int_values(void)146 test_array_with_array_int_values(void)
147 {
148 	int i;
149 
150 	struct rte_tel_data *child_data = rte_tel_data_alloc();
151 	rte_tel_data_start_array(child_data, RTE_TEL_INT_VAL);
152 
153 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
154 	rte_tel_data_start_array(child_data2, RTE_TEL_INT_VAL);
155 
156 	rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
157 
158 	for (i = 0; i < 5; i++) {
159 		rte_tel_data_add_array_int(child_data, i);
160 		rte_tel_data_add_array_int(child_data2, i);
161 	}
162 	rte_tel_data_add_array_container(&response_data, child_data, 0);
163 	rte_tel_data_add_array_container(&response_data, child_data2, 0);
164 
165 	return CHECK_OUTPUT("[[0,1,2,3,4],[0,1,2,3,4]]");
166 }
167 
168 static int
test_case_array_int(void)169 test_case_array_int(void)
170 {
171 	int i;
172 
173 	rte_tel_data_start_array(&response_data, RTE_TEL_INT_VAL);
174 	for (i = 0; i < 5; i++)
175 		rte_tel_data_add_array_int(&response_data, i);
176 	return CHECK_OUTPUT("[0,1,2,3,4]");
177 }
178 
179 static int
test_case_add_dict_int(void)180 test_case_add_dict_int(void)
181 {
182 	int i = 0;
183 	char name_of_value[8];
184 
185 	rte_tel_data_start_dict(&response_data);
186 
187 	for (i = 0; i < 5; i++) {
188 		sprintf(name_of_value, "dict_%d", i);
189 		rte_tel_data_add_dict_int(&response_data, name_of_value, i);
190 	}
191 
192 	return CHECK_OUTPUT("{\"dict_0\":0,\"dict_1\":1,\"dict_2\":2,\"dict_3\":3,\"dict_4\":4}");
193 }
194 
195 static int
test_case_array_string(void)196 test_case_array_string(void)
197 {
198 	rte_tel_data_start_array(&response_data, RTE_TEL_STRING_VAL);
199 	rte_tel_data_add_array_string(&response_data, "aaaa");
200 	rte_tel_data_add_array_string(&response_data, "bbbb");
201 	rte_tel_data_add_array_string(&response_data, "cccc");
202 	rte_tel_data_add_array_string(&response_data, "dddd");
203 	rte_tel_data_add_array_string(&response_data, "eeee");
204 
205 	return CHECK_OUTPUT("[\"aaaa\",\"bbbb\",\"cccc\",\"dddd\",\"eeee\"]");
206 }
207 
208 static int
test_case_add_dict_string(void)209 test_case_add_dict_string(void)
210 {
211 	rte_tel_data_start_dict(&response_data);
212 
213 	rte_tel_data_add_dict_string(&response_data, "dict_0", "aaaa");
214 	rte_tel_data_add_dict_string(&response_data, "dict_1", "bbbb");
215 	rte_tel_data_add_dict_string(&response_data, "dict_2", "cccc");
216 	rte_tel_data_add_dict_string(&response_data, "dict_3", "dddd");
217 
218 	return CHECK_OUTPUT("{\"dict_0\":\"aaaa\",\"dict_1\":\"bbbb\",\"dict_2\":\"cccc\",\"dict_3\":\"dddd\"}");
219 }
220 
221 static int
test_case_add_dict_uint_hex_padding(void)222 test_case_add_dict_uint_hex_padding(void)
223 {
224 	rte_tel_data_start_dict(&response_data);
225 
226 	rte_tel_data_add_dict_uint_hex(&response_data, "dict_0",
227 				(uint8_t)0x8, 8);
228 	rte_tel_data_add_dict_uint_hex(&response_data, "dict_1",
229 				(uint16_t)0x88, 16);
230 	rte_tel_data_add_dict_uint_hex(&response_data, "dict_2",
231 				(uint32_t)0x888, 32);
232 	rte_tel_data_add_dict_uint_hex(&response_data, "dict_3",
233 				(uint64_t)0x8888, 64);
234 
235 	return CHECK_OUTPUT("{\"dict_0\":\"0x08\",\"dict_1\":\"0x0088\",\"dict_2\":\"0x00000888\",\"dict_3\":\"0x0000000000008888\"}");
236 }
237 
238 static int
test_case_add_dict_uint_hex_nopadding(void)239 test_case_add_dict_uint_hex_nopadding(void)
240 {
241 	rte_tel_data_start_dict(&response_data);
242 
243 	rte_tel_data_add_dict_uint_hex(&response_data, "dict_0",
244 				(uint8_t)0x8, 0);
245 	rte_tel_data_add_dict_uint_hex(&response_data, "dict_1",
246 				(uint16_t)0x88, 0);
247 	rte_tel_data_add_dict_uint_hex(&response_data, "dict_2",
248 				(uint32_t)0x888, 0);
249 	rte_tel_data_add_dict_uint_hex(&response_data, "dict_3",
250 				(uint64_t)0x8888, 0);
251 
252 	return CHECK_OUTPUT("{\"dict_0\":\"0x8\",\"dict_1\":\"0x88\",\"dict_2\":\"0x888\",\"dict_3\":\"0x8888\"}");
253 }
254 
255 static int
test_dict_with_array_string_values(void)256 test_dict_with_array_string_values(void)
257 {
258 	struct rte_tel_data *child_data = rte_tel_data_alloc();
259 	rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
260 
261 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
262 	rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
263 
264 	rte_tel_data_start_dict(&response_data);
265 
266 	rte_tel_data_add_array_string(child_data, "aaaa");
267 	rte_tel_data_add_array_string(child_data2, "bbbb");
268 
269 	rte_tel_data_add_dict_container(&response_data, "dict_0",
270 	 child_data, 0);
271 	rte_tel_data_add_dict_container(&response_data, "dict_1",
272 	 child_data2, 0);
273 
274 	return CHECK_OUTPUT("{\"dict_0\":[\"aaaa\"],\"dict_1\":[\"bbbb\"]}");
275 }
276 
277 static int
test_dict_with_array_uint_hex_values_padding(void)278 test_dict_with_array_uint_hex_values_padding(void)
279 {
280 	struct rte_tel_data *child_data = rte_tel_data_alloc();
281 	rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
282 
283 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
284 	rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
285 
286 	rte_tel_data_start_dict(&response_data);
287 
288 	rte_tel_data_add_array_uint_hex(child_data, (uint32_t)0x888, 32);
289 	rte_tel_data_add_array_uint_hex(child_data2, (uint64_t)0x8888, 64);
290 
291 	rte_tel_data_add_dict_container(&response_data, "dict_0",
292 					child_data, 0);
293 	rte_tel_data_add_dict_container(&response_data, "dict_1",
294 					child_data2, 0);
295 
296 	return CHECK_OUTPUT("{\"dict_0\":[\"0x00000888\"],\"dict_1\":[\"0x0000000000008888\"]}");
297 }
298 
299 static int
test_dict_with_array_uint_hex_values_nopadding(void)300 test_dict_with_array_uint_hex_values_nopadding(void)
301 {
302 	struct rte_tel_data *child_data = rte_tel_data_alloc();
303 	rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
304 
305 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
306 	rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
307 
308 	rte_tel_data_start_dict(&response_data);
309 
310 	rte_tel_data_add_array_uint_hex(child_data, (uint32_t)0x888, 0);
311 	rte_tel_data_add_array_uint_hex(child_data2, (uint64_t)0x8888, 0);
312 
313 	rte_tel_data_add_dict_container(&response_data, "dict_0",
314 					child_data, 0);
315 	rte_tel_data_add_dict_container(&response_data, "dict_1",
316 					child_data2, 0);
317 
318 	return CHECK_OUTPUT("{\"dict_0\":[\"0x888\"],\"dict_1\":[\"0x8888\"]}");
319 }
320 
321 static int
test_dict_with_dict_values(void)322 test_dict_with_dict_values(void)
323 {
324 	struct rte_tel_data *dict_of_dicts = rte_tel_data_alloc();
325 	rte_tel_data_start_dict(dict_of_dicts);
326 
327 	struct rte_tel_data *child_data = rte_tel_data_alloc();
328 	rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
329 
330 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
331 	rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
332 
333 	rte_tel_data_start_dict(&response_data);
334 
335 	rte_tel_data_add_array_string(child_data, "aaaa");
336 	rte_tel_data_add_array_string(child_data2, "bbbb");
337 	rte_tel_data_add_dict_container(dict_of_dicts, "dict_0",
338 			child_data, 0);
339 	rte_tel_data_add_dict_container(dict_of_dicts, "dict_1",
340 			child_data2, 0);
341 	rte_tel_data_add_dict_container(&response_data, "dict_of_dicts",
342 			dict_of_dicts, 0);
343 
344 	return CHECK_OUTPUT("{\"dict_of_dicts\":{\"dict_0\":[\"aaaa\"],\"dict_1\":[\"bbbb\"]}}");
345 }
346 
347 static int
test_array_with_array_string_values(void)348 test_array_with_array_string_values(void)
349 {
350 	struct rte_tel_data *child_data = rte_tel_data_alloc();
351 	rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
352 
353 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
354 	rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
355 
356 	rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
357 
358 	rte_tel_data_add_array_string(child_data, "aaaa");
359 	rte_tel_data_add_array_string(child_data2, "bbbb");
360 
361 	rte_tel_data_add_array_container(&response_data, child_data, 0);
362 	rte_tel_data_add_array_container(&response_data, child_data2, 0);
363 
364 	return CHECK_OUTPUT("[[\"aaaa\"],[\"bbbb\"]]");
365 }
366 
367 static int
test_array_with_array_uint_hex_values_padding(void)368 test_array_with_array_uint_hex_values_padding(void)
369 {
370 	struct rte_tel_data *child_data = rte_tel_data_alloc();
371 	rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
372 
373 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
374 	rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
375 
376 	rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
377 
378 	rte_tel_data_add_array_uint_hex(child_data, (uint32_t)0x888, 32);
379 	rte_tel_data_add_array_uint_hex(child_data2, (uint64_t)0x8888, 64);
380 
381 	rte_tel_data_add_array_container(&response_data, child_data, 0);
382 	rte_tel_data_add_array_container(&response_data, child_data2, 0);
383 
384 	return CHECK_OUTPUT("[[\"0x00000888\"],[\"0x0000000000008888\"]]");
385 }
386 
387 
388 static int
test_array_with_array_uint_hex_values_nopadding(void)389 test_array_with_array_uint_hex_values_nopadding(void)
390 {
391 	struct rte_tel_data *child_data = rte_tel_data_alloc();
392 	rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
393 
394 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
395 	rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
396 
397 	rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
398 
399 	rte_tel_data_add_array_uint_hex(child_data, (uint32_t)0x888, 0);
400 	rte_tel_data_add_array_uint_hex(child_data2, (uint64_t)0x8888, 0);
401 
402 	rte_tel_data_add_array_container(&response_data, child_data, 0);
403 	rte_tel_data_add_array_container(&response_data, child_data2, 0);
404 
405 	return CHECK_OUTPUT("[[\"0x888\"],[\"0x8888\"]]");
406 }
407 
408 static int
test_case_array_u64(void)409 test_case_array_u64(void)
410 {
411 	int i;
412 
413 	rte_tel_data_start_array(&response_data, RTE_TEL_UINT_VAL);
414 	for (i = 0; i < 5; i++)
415 		rte_tel_data_add_array_uint(&response_data, i);
416 	return CHECK_OUTPUT("[0,1,2,3,4]");
417 }
418 
419 static int
test_case_array_uint_hex_padding(void)420 test_case_array_uint_hex_padding(void)
421 {
422 	rte_tel_data_start_array(&response_data, RTE_TEL_STRING_VAL);
423 	rte_tel_data_add_array_uint_hex(&response_data, (uint8_t)0x8, 8);
424 	rte_tel_data_add_array_uint_hex(&response_data, (uint16_t)0x88, 16);
425 	rte_tel_data_add_array_uint_hex(&response_data, (uint32_t)0x888, 32);
426 	rte_tel_data_add_array_uint_hex(&response_data, (uint64_t)0x8888, 64);
427 
428 	return CHECK_OUTPUT("[\"0x08\",\"0x0088\",\"0x00000888\",\"0x0000000000008888\"]");
429 }
430 
431 static int
test_case_array_uint_hex_nopadding(void)432 test_case_array_uint_hex_nopadding(void)
433 {
434 	rte_tel_data_start_array(&response_data, RTE_TEL_STRING_VAL);
435 	rte_tel_data_add_array_uint_hex(&response_data, (uint8_t)0x8, 0);
436 	rte_tel_data_add_array_uint_hex(&response_data, (uint16_t)0x88, 0);
437 	rte_tel_data_add_array_uint_hex(&response_data, (uint32_t)0x888, 0);
438 	rte_tel_data_add_array_uint_hex(&response_data, (uint64_t)0x8888, 0);
439 
440 	return CHECK_OUTPUT("[\"0x8\",\"0x88\",\"0x888\",\"0x8888\"]");
441 }
442 
443 static int
test_case_add_dict_u64(void)444 test_case_add_dict_u64(void)
445 {
446 	int i = 0;
447 	char name_of_value[8];
448 
449 	rte_tel_data_start_dict(&response_data);
450 
451 	for (i = 0; i < 5; i++) {
452 		sprintf(name_of_value, "dict_%d", i);
453 		rte_tel_data_add_dict_uint(&response_data, name_of_value, i);
454 	}
455 	return CHECK_OUTPUT("{\"dict_0\":0,\"dict_1\":1,\"dict_2\":2,\"dict_3\":3,\"dict_4\":4}");
456 }
457 
458 static int
test_dict_with_array_u64_values(void)459 test_dict_with_array_u64_values(void)
460 {
461 	int i;
462 
463 	struct rte_tel_data *child_data = rte_tel_data_alloc();
464 	rte_tel_data_start_array(child_data, RTE_TEL_UINT_VAL);
465 
466 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
467 	rte_tel_data_start_array(child_data2, RTE_TEL_UINT_VAL);
468 
469 	rte_tel_data_start_dict(&response_data);
470 
471 	for (i = 0; i < 10; i++) {
472 		rte_tel_data_add_array_uint(child_data, i);
473 		rte_tel_data_add_array_uint(child_data2, i);
474 	}
475 
476 	rte_tel_data_add_dict_container(&response_data, "dict_0",
477 	 child_data, 0);
478 	rte_tel_data_add_dict_container(&response_data, "dict_1",
479 	 child_data2, 0);
480 
481 	return CHECK_OUTPUT("{\"dict_0\":[0,1,2,3,4,5,6,7,8,9],\"dict_1\":[0,1,2,3,4,5,6,7,8,9]}");
482 }
483 
484 static int
test_array_with_array_u64_values(void)485 test_array_with_array_u64_values(void)
486 {
487 	int i;
488 
489 	struct rte_tel_data *child_data = rte_tel_data_alloc();
490 	rte_tel_data_start_array(child_data, RTE_TEL_UINT_VAL);
491 
492 	struct rte_tel_data *child_data2 = rte_tel_data_alloc();
493 	rte_tel_data_start_array(child_data2, RTE_TEL_UINT_VAL);
494 
495 	rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
496 
497 	for (i = 0; i < 5; i++) {
498 		rte_tel_data_add_array_uint(child_data, i);
499 		rte_tel_data_add_array_uint(child_data2, i);
500 	}
501 	rte_tel_data_add_array_container(&response_data, child_data, 0);
502 	rte_tel_data_add_array_container(&response_data, child_data2, 0);
503 
504 	return CHECK_OUTPUT("[[0,1,2,3,4],[0,1,2,3,4]]");
505 }
506 
507 static int
test_string_char_escaping(void)508 test_string_char_escaping(void)
509 {
510 	rte_tel_data_string(&response_data, "hello,\nworld\n");
511 	return CHECK_OUTPUT("\"hello,\\nworld\\n\"");
512 }
513 
514 static int
test_array_char_escaping(void)515 test_array_char_escaping(void)
516 {
517 	rte_tel_data_start_array(&response_data, RTE_TEL_STRING_VAL);
518 	rte_tel_data_add_array_string(&response_data, "\\escape\r");
519 	rte_tel_data_add_array_string(&response_data, "characters\n");
520 	return CHECK_OUTPUT("[\"\\\\escape\\r\",\"characters\\n\"]");
521 }
522 
523 static int
test_dict_char_escaping(void)524 test_dict_char_escaping(void)
525 {
526 	rte_tel_data_start_dict(&response_data);
527 	rte_tel_data_add_dict_string(&response_data, "name", "escaped\n\tvalue");
528 	return CHECK_OUTPUT("{\"name\":\"escaped\\n\\tvalue\"}");
529 }
530 
531 static int
connect_to_socket(void)532 connect_to_socket(void)
533 {
534 	char buf[BUF_SIZE];
535 	int sock, bytes;
536 	struct sockaddr_un telem_addr;
537 
538 	sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
539 	if (sock < 0) {
540 		printf("\n%s: Error creating socket: %s\n", __func__,
541 				strerror(errno));
542 		return -1;
543 	}
544 	telem_addr.sun_family = AF_UNIX;
545 	snprintf(telem_addr.sun_path, sizeof(telem_addr.sun_path),
546 			"%s/dpdk_telemetry.%s",	rte_eal_get_runtime_dir(),
547 			TELEMETRY_VERSION);
548 	if (connect(sock, (struct sockaddr *) &telem_addr,
549 			sizeof(telem_addr)) < 0) {
550 		printf("\n%s: Error connecting to socket: %s\n", __func__,
551 				strerror(errno));
552 		close(sock);
553 		return -1;
554 	}
555 
556 	bytes = read(sock, buf, sizeof(buf) - 1);
557 	if (bytes < 0) {
558 		printf("%s: Error with socket read - %s\n", __func__,
559 				strerror(errno));
560 		close(sock);
561 		return -1;
562 	}
563 	buf[bytes] = '\0';
564 	printf("\n%s: %s\n", __func__, buf);
565 	return sock;
566 }
567 
568 static int
telemetry_data_autotest(void)569 telemetry_data_autotest(void)
570 {
571 	typedef int (*test_case)(void);
572 	unsigned int i = 0;
573 
574 	sock = connect_to_socket();
575 	if (sock <= 0)
576 		return -1;
577 
578 	test_case test_cases[] = {
579 			test_null_return,
580 			test_simple_string,
581 			test_case_array_string,
582 			test_case_array_int, test_case_array_u64,
583 			test_case_array_uint_hex_padding,
584 			test_case_array_uint_hex_nopadding,
585 			test_case_add_dict_int, test_case_add_dict_u64,
586 			test_case_add_dict_string,
587 			test_case_add_dict_uint_hex_padding,
588 			test_case_add_dict_uint_hex_nopadding,
589 			test_dict_with_array_int_values,
590 			test_dict_with_array_u64_values,
591 			test_dict_with_array_string_values,
592 			test_dict_with_array_uint_hex_values_padding,
593 			test_dict_with_array_uint_hex_values_nopadding,
594 			test_dict_with_dict_values,
595 			test_array_with_array_int_values,
596 			test_array_with_array_u64_values,
597 			test_array_with_array_string_values,
598 			test_array_with_array_uint_hex_values_padding,
599 			test_array_with_array_uint_hex_values_nopadding,
600 			test_string_char_escaping,
601 			test_array_char_escaping,
602 			test_dict_char_escaping,
603 	};
604 
605 	rte_telemetry_register_cmd(REQUEST_CMD, telemetry_test_cb, "Test");
606 	for (i = 0; i < RTE_DIM(test_cases); i++) {
607 		memset(&response_data, 0, sizeof(response_data));
608 		if (test_cases[i]() != 0) {
609 			close(sock);
610 			return -1;
611 		}
612 	}
613 	close(sock);
614 	return 0;
615 }
616 #endif /* !RTE_EXEC_ENV_WINDOWS */
617 
618 REGISTER_FAST_TEST(telemetry_data_autotest, true, true, telemetry_data_autotest);
619