Branch data Line data Source code
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
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
71 : 27 : telemetry_test_cb(const char *cmd __rte_unused, const char *params __rte_unused,
72 : : struct rte_tel_data *d)
73 : : {
74 : 27 : *d = response_data;
75 : 27 : 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
85 : 27 : check_output(const char *func_name, const char *expected)
86 : : {
87 : : int bytes;
88 : : char buf[BUF_SIZE * 16];
89 [ - + ]: 27 : if (write(sock, REQUEST_CMD, strlen(REQUEST_CMD)) < 0) {
90 : 0 : printf("%s: Error with socket write - %s\n", __func__,
91 : 0 : strerror(errno));
92 : 0 : return -1;
93 : : }
94 : 27 : bytes = read(sock, buf, sizeof(buf) - 1);
95 [ - + ]: 27 : if (bytes < 0) {
96 : 0 : printf("%s: Error with socket read - %s\n", __func__,
97 : 0 : strerror(errno));
98 : 0 : return -1;
99 : : }
100 : 27 : buf[bytes] = '\0';
101 : : printf("%s: buf = '%s', expected = '%s'\n", func_name, buf, expected);
102 : 27 : return strncmp(expected, buf, sizeof(buf));
103 : : }
104 : :
105 : : static int
106 : 1 : test_null_return(void)
107 : : {
108 : 1 : return CHECK_OUTPUT("null");
109 : : }
110 : :
111 : : static int
112 : 1 : test_simple_string(void)
113 : : {
114 : 1 : rte_tel_data_string(&response_data, "Simple string");
115 : :
116 : 1 : return CHECK_OUTPUT("\"Simple string\"");
117 : : }
118 : :
119 : : static int
120 : 1 : test_dict_with_array_int_values(void)
121 : : {
122 : : int i;
123 : :
124 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
125 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_INT_VAL);
126 : :
127 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
128 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_INT_VAL);
129 : :
130 : 1 : rte_tel_data_start_dict(&response_data);
131 : :
132 [ + + ]: 6 : for (i = 0; i < 5; i++) {
133 : 5 : rte_tel_data_add_array_int(child_data, i);
134 : 5 : rte_tel_data_add_array_int(child_data2, i);
135 : : }
136 : :
137 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_0",
138 : : child_data, 0);
139 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_1",
140 : : child_data2, 0);
141 : :
142 : 1 : return CHECK_OUTPUT("{\"dict_0\":[0,1,2,3,4],\"dict_1\":[0,1,2,3,4]}");
143 : : }
144 : :
145 : : static int
146 : 1 : test_array_with_array_int_values(void)
147 : : {
148 : : int i;
149 : :
150 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
151 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_INT_VAL);
152 : :
153 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
154 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_INT_VAL);
155 : :
156 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
157 : :
158 [ + + ]: 6 : for (i = 0; i < 5; i++) {
159 : 5 : rte_tel_data_add_array_int(child_data, i);
160 : 5 : rte_tel_data_add_array_int(child_data2, i);
161 : : }
162 : 1 : rte_tel_data_add_array_container(&response_data, child_data, 0);
163 : 1 : rte_tel_data_add_array_container(&response_data, child_data2, 0);
164 : :
165 : 1 : return CHECK_OUTPUT("[[0,1,2,3,4],[0,1,2,3,4]]");
166 : : }
167 : :
168 : : static int
169 : 1 : test_case_array_int(void)
170 : : {
171 : : int i;
172 : :
173 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_INT_VAL);
174 [ + + ]: 6 : for (i = 0; i < 5; i++)
175 : 5 : rte_tel_data_add_array_int(&response_data, i);
176 : 1 : return CHECK_OUTPUT("[0,1,2,3,4]");
177 : : }
178 : :
179 : : static int
180 : 1 : test_case_add_dict_int(void)
181 : : {
182 : : int i = 0;
183 : : char name_of_value[8];
184 : :
185 : 1 : rte_tel_data_start_dict(&response_data);
186 : :
187 [ + + ]: 6 : for (i = 0; i < 5; i++) {
188 : : sprintf(name_of_value, "dict_%d", i);
189 : 5 : rte_tel_data_add_dict_int(&response_data, name_of_value, i);
190 : : }
191 : :
192 : 1 : return CHECK_OUTPUT("{\"dict_0\":0,\"dict_1\":1,\"dict_2\":2,\"dict_3\":3,\"dict_4\":4}");
193 : : }
194 : :
195 : : static int
196 : 1 : test_case_array_string(void)
197 : : {
198 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_STRING_VAL);
199 : 1 : rte_tel_data_add_array_string(&response_data, "aaaa");
200 : 1 : rte_tel_data_add_array_string(&response_data, "bbbb");
201 : 1 : rte_tel_data_add_array_string(&response_data, "cccc");
202 : 1 : rte_tel_data_add_array_string(&response_data, "dddd");
203 : 1 : rte_tel_data_add_array_string(&response_data, "eeee");
204 : :
205 : 1 : return CHECK_OUTPUT("[\"aaaa\",\"bbbb\",\"cccc\",\"dddd\",\"eeee\"]");
206 : : }
207 : :
208 : : static int
209 : 1 : test_case_add_dict_string(void)
210 : : {
211 : 1 : rte_tel_data_start_dict(&response_data);
212 : :
213 : 1 : rte_tel_data_add_dict_string(&response_data, "dict_0", "aaaa");
214 : 1 : rte_tel_data_add_dict_string(&response_data, "dict_1", "bbbb");
215 : 1 : rte_tel_data_add_dict_string(&response_data, "dict_2", "cccc");
216 : 1 : rte_tel_data_add_dict_string(&response_data, "dict_3", "dddd");
217 : :
218 : 1 : return CHECK_OUTPUT("{\"dict_0\":\"aaaa\",\"dict_1\":\"bbbb\",\"dict_2\":\"cccc\",\"dict_3\":\"dddd\"}");
219 : : }
220 : :
221 : : static int
222 : 1 : test_case_add_dict_uint_hex_padding(void)
223 : : {
224 : 1 : rte_tel_data_start_dict(&response_data);
225 : :
226 : 1 : rte_tel_data_add_dict_uint_hex(&response_data, "dict_0",
227 : : (uint8_t)0x8, 8);
228 : 1 : rte_tel_data_add_dict_uint_hex(&response_data, "dict_1",
229 : : (uint16_t)0x88, 16);
230 : 1 : rte_tel_data_add_dict_uint_hex(&response_data, "dict_2",
231 : : (uint32_t)0x888, 32);
232 : 1 : rte_tel_data_add_dict_uint_hex(&response_data, "dict_3",
233 : : (uint64_t)0x8888, 64);
234 : :
235 : 1 : return CHECK_OUTPUT("{\"dict_0\":\"0x08\",\"dict_1\":\"0x0088\",\"dict_2\":\"0x00000888\",\"dict_3\":\"0x0000000000008888\"}");
236 : : }
237 : :
238 : : static int
239 : 1 : test_case_add_dict_uint_hex_nopadding(void)
240 : : {
241 : 1 : rte_tel_data_start_dict(&response_data);
242 : :
243 : 1 : rte_tel_data_add_dict_uint_hex(&response_data, "dict_0",
244 : : (uint8_t)0x8, 0);
245 : 1 : rte_tel_data_add_dict_uint_hex(&response_data, "dict_1",
246 : : (uint16_t)0x88, 0);
247 : 1 : rte_tel_data_add_dict_uint_hex(&response_data, "dict_2",
248 : : (uint32_t)0x888, 0);
249 : 1 : rte_tel_data_add_dict_uint_hex(&response_data, "dict_3",
250 : : (uint64_t)0x8888, 0);
251 : :
252 : 1 : return CHECK_OUTPUT("{\"dict_0\":\"0x8\",\"dict_1\":\"0x88\",\"dict_2\":\"0x888\",\"dict_3\":\"0x8888\"}");
253 : : }
254 : :
255 : : static int
256 : 1 : test_dict_with_array_string_values(void)
257 : : {
258 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
259 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
260 : :
261 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
262 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
263 : :
264 : 1 : rte_tel_data_start_dict(&response_data);
265 : :
266 : 1 : rte_tel_data_add_array_string(child_data, "aaaa");
267 : 1 : rte_tel_data_add_array_string(child_data2, "bbbb");
268 : :
269 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_0",
270 : : child_data, 0);
271 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_1",
272 : : child_data2, 0);
273 : :
274 : 1 : return CHECK_OUTPUT("{\"dict_0\":[\"aaaa\"],\"dict_1\":[\"bbbb\"]}");
275 : : }
276 : :
277 : : static int
278 : 1 : test_dict_with_array_uint_hex_values_padding(void)
279 : : {
280 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
281 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
282 : :
283 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
284 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
285 : :
286 : 1 : rte_tel_data_start_dict(&response_data);
287 : :
288 : 1 : rte_tel_data_add_array_uint_hex(child_data, (uint32_t)0x888, 32);
289 : 1 : rte_tel_data_add_array_uint_hex(child_data2, (uint64_t)0x8888, 64);
290 : :
291 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_0",
292 : : child_data, 0);
293 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_1",
294 : : child_data2, 0);
295 : :
296 : 1 : return CHECK_OUTPUT("{\"dict_0\":[\"0x00000888\"],\"dict_1\":[\"0x0000000000008888\"]}");
297 : : }
298 : :
299 : : static int
300 : 1 : test_dict_with_array_uint_hex_values_nopadding(void)
301 : : {
302 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
303 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
304 : :
305 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
306 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
307 : :
308 : 1 : rte_tel_data_start_dict(&response_data);
309 : :
310 : 1 : rte_tel_data_add_array_uint_hex(child_data, (uint32_t)0x888, 0);
311 : 1 : rte_tel_data_add_array_uint_hex(child_data2, (uint64_t)0x8888, 0);
312 : :
313 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_0",
314 : : child_data, 0);
315 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_1",
316 : : child_data2, 0);
317 : :
318 : 1 : return CHECK_OUTPUT("{\"dict_0\":[\"0x888\"],\"dict_1\":[\"0x8888\"]}");
319 : : }
320 : :
321 : : static int
322 : 1 : test_dict_with_dict_values(void)
323 : : {
324 : 1 : struct rte_tel_data *dict_of_dicts = rte_tel_data_alloc();
325 : 1 : rte_tel_data_start_dict(dict_of_dicts);
326 : :
327 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
328 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
329 : :
330 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
331 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
332 : :
333 : 1 : rte_tel_data_start_dict(&response_data);
334 : :
335 : 1 : rte_tel_data_add_array_string(child_data, "aaaa");
336 : 1 : rte_tel_data_add_array_string(child_data2, "bbbb");
337 : 1 : rte_tel_data_add_dict_container(dict_of_dicts, "dict_0",
338 : : child_data, 0);
339 : 1 : rte_tel_data_add_dict_container(dict_of_dicts, "dict_1",
340 : : child_data2, 0);
341 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_of_dicts",
342 : : dict_of_dicts, 0);
343 : :
344 : 1 : return CHECK_OUTPUT("{\"dict_of_dicts\":{\"dict_0\":[\"aaaa\"],\"dict_1\":[\"bbbb\"]}}");
345 : : }
346 : :
347 : : static int
348 : 1 : test_array_with_array_string_values(void)
349 : : {
350 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
351 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
352 : :
353 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
354 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
355 : :
356 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
357 : :
358 : 1 : rte_tel_data_add_array_string(child_data, "aaaa");
359 : 1 : rte_tel_data_add_array_string(child_data2, "bbbb");
360 : :
361 : 1 : rte_tel_data_add_array_container(&response_data, child_data, 0);
362 : 1 : rte_tel_data_add_array_container(&response_data, child_data2, 0);
363 : :
364 : 1 : return CHECK_OUTPUT("[[\"aaaa\"],[\"bbbb\"]]");
365 : : }
366 : :
367 : : static int
368 : 1 : test_array_with_array_uint_hex_values_padding(void)
369 : : {
370 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
371 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
372 : :
373 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
374 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
375 : :
376 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
377 : :
378 : 1 : rte_tel_data_add_array_uint_hex(child_data, (uint32_t)0x888, 32);
379 : 1 : rte_tel_data_add_array_uint_hex(child_data2, (uint64_t)0x8888, 64);
380 : :
381 : 1 : rte_tel_data_add_array_container(&response_data, child_data, 0);
382 : 1 : rte_tel_data_add_array_container(&response_data, child_data2, 0);
383 : :
384 : 1 : return CHECK_OUTPUT("[[\"0x00000888\"],[\"0x0000000000008888\"]]");
385 : : }
386 : :
387 : :
388 : : static int
389 : 1 : test_array_with_array_uint_hex_values_nopadding(void)
390 : : {
391 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
392 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_STRING_VAL);
393 : :
394 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
395 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_STRING_VAL);
396 : :
397 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
398 : :
399 : 1 : rte_tel_data_add_array_uint_hex(child_data, (uint32_t)0x888, 0);
400 : 1 : rte_tel_data_add_array_uint_hex(child_data2, (uint64_t)0x8888, 0);
401 : :
402 : 1 : rte_tel_data_add_array_container(&response_data, child_data, 0);
403 : 1 : rte_tel_data_add_array_container(&response_data, child_data2, 0);
404 : :
405 : 1 : return CHECK_OUTPUT("[[\"0x888\"],[\"0x8888\"]]");
406 : : }
407 : :
408 : : static int
409 : 1 : test_array_with_dict_values(void)
410 : : {
411 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
412 : :
413 : 1 : struct rte_tel_data *d1 = rte_tel_data_alloc();
414 : 1 : rte_tel_data_start_dict(d1);
415 : 1 : rte_tel_data_add_dict_string(d1, "name", "foo");
416 : 1 : rte_tel_data_add_dict_uint(d1, "size", 42);
417 : 1 : rte_tel_data_add_array_container(&response_data, d1, 0);
418 : :
419 : 1 : struct rte_tel_data *d2 = rte_tel_data_alloc();
420 : 1 : rte_tel_data_start_dict(d2);
421 : 1 : rte_tel_data_add_dict_string(d2, "name", "bar");
422 : 1 : rte_tel_data_add_dict_uint(d2, "size", 666);
423 : 1 : rte_tel_data_add_array_container(&response_data, d2, 0);
424 : :
425 : 1 : return CHECK_OUTPUT("[{\"name\":\"foo\",\"size\":42},{\"name\":\"bar\",\"size\":666}]");
426 : : }
427 : :
428 : : static int
429 : 1 : test_case_array_u64(void)
430 : : {
431 : : int i;
432 : :
433 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_UINT_VAL);
434 [ + + ]: 6 : for (i = 0; i < 5; i++)
435 : 5 : rte_tel_data_add_array_uint(&response_data, i);
436 : 1 : return CHECK_OUTPUT("[0,1,2,3,4]");
437 : : }
438 : :
439 : : static int
440 : 1 : test_case_array_uint_hex_padding(void)
441 : : {
442 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_STRING_VAL);
443 : 1 : rte_tel_data_add_array_uint_hex(&response_data, (uint8_t)0x8, 8);
444 : 1 : rte_tel_data_add_array_uint_hex(&response_data, (uint16_t)0x88, 16);
445 : 1 : rte_tel_data_add_array_uint_hex(&response_data, (uint32_t)0x888, 32);
446 : 1 : rte_tel_data_add_array_uint_hex(&response_data, (uint64_t)0x8888, 64);
447 : :
448 : 1 : return CHECK_OUTPUT("[\"0x08\",\"0x0088\",\"0x00000888\",\"0x0000000000008888\"]");
449 : : }
450 : :
451 : : static int
452 : 1 : test_case_array_uint_hex_nopadding(void)
453 : : {
454 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_STRING_VAL);
455 : 1 : rte_tel_data_add_array_uint_hex(&response_data, (uint8_t)0x8, 0);
456 : 1 : rte_tel_data_add_array_uint_hex(&response_data, (uint16_t)0x88, 0);
457 : 1 : rte_tel_data_add_array_uint_hex(&response_data, (uint32_t)0x888, 0);
458 : 1 : rte_tel_data_add_array_uint_hex(&response_data, (uint64_t)0x8888, 0);
459 : :
460 : 1 : return CHECK_OUTPUT("[\"0x8\",\"0x88\",\"0x888\",\"0x8888\"]");
461 : : }
462 : :
463 : : static int
464 : 1 : test_case_add_dict_u64(void)
465 : : {
466 : : int i = 0;
467 : : char name_of_value[8];
468 : :
469 : 1 : rte_tel_data_start_dict(&response_data);
470 : :
471 [ + + ]: 6 : for (i = 0; i < 5; i++) {
472 : : sprintf(name_of_value, "dict_%d", i);
473 : 5 : rte_tel_data_add_dict_uint(&response_data, name_of_value, i);
474 : : }
475 : 1 : return CHECK_OUTPUT("{\"dict_0\":0,\"dict_1\":1,\"dict_2\":2,\"dict_3\":3,\"dict_4\":4}");
476 : : }
477 : :
478 : : static int
479 : 1 : test_dict_with_array_u64_values(void)
480 : : {
481 : : int i;
482 : :
483 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
484 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_UINT_VAL);
485 : :
486 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
487 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_UINT_VAL);
488 : :
489 : 1 : rte_tel_data_start_dict(&response_data);
490 : :
491 [ + + ]: 11 : for (i = 0; i < 10; i++) {
492 : 10 : rte_tel_data_add_array_uint(child_data, i);
493 : 10 : rte_tel_data_add_array_uint(child_data2, i);
494 : : }
495 : :
496 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_0",
497 : : child_data, 0);
498 : 1 : rte_tel_data_add_dict_container(&response_data, "dict_1",
499 : : child_data2, 0);
500 : :
501 : 1 : 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]}");
502 : : }
503 : :
504 : : static int
505 : 1 : test_array_with_array_u64_values(void)
506 : : {
507 : : int i;
508 : :
509 : 1 : struct rte_tel_data *child_data = rte_tel_data_alloc();
510 : 1 : rte_tel_data_start_array(child_data, RTE_TEL_UINT_VAL);
511 : :
512 : 1 : struct rte_tel_data *child_data2 = rte_tel_data_alloc();
513 : 1 : rte_tel_data_start_array(child_data2, RTE_TEL_UINT_VAL);
514 : :
515 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_CONTAINER);
516 : :
517 [ + + ]: 6 : for (i = 0; i < 5; i++) {
518 : 5 : rte_tel_data_add_array_uint(child_data, i);
519 : 5 : rte_tel_data_add_array_uint(child_data2, i);
520 : : }
521 : 1 : rte_tel_data_add_array_container(&response_data, child_data, 0);
522 : 1 : rte_tel_data_add_array_container(&response_data, child_data2, 0);
523 : :
524 : 1 : return CHECK_OUTPUT("[[0,1,2,3,4],[0,1,2,3,4]]");
525 : : }
526 : :
527 : : static int
528 : 1 : test_string_char_escaping(void)
529 : : {
530 : 1 : rte_tel_data_string(&response_data, "hello,\nworld\n");
531 : 1 : return CHECK_OUTPUT("\"hello,\\nworld\\n\"");
532 : : }
533 : :
534 : : static int
535 : 1 : test_array_char_escaping(void)
536 : : {
537 : 1 : rte_tel_data_start_array(&response_data, RTE_TEL_STRING_VAL);
538 : 1 : rte_tel_data_add_array_string(&response_data, "\\escape\r");
539 : 1 : rte_tel_data_add_array_string(&response_data, "characters\n");
540 : 1 : return CHECK_OUTPUT("[\"\\\\escape\\r\",\"characters\\n\"]");
541 : : }
542 : :
543 : : static int
544 : 1 : test_dict_char_escaping(void)
545 : : {
546 : 1 : rte_tel_data_start_dict(&response_data);
547 : 1 : rte_tel_data_add_dict_string(&response_data, "name", "escaped\n\tvalue");
548 : 1 : return CHECK_OUTPUT("{\"name\":\"escaped\\n\\tvalue\"}");
549 : : }
550 : :
551 : : static int
552 : 1 : connect_to_socket(void)
553 : : {
554 : : char buf[BUF_SIZE];
555 : : int sock, bytes;
556 : : struct sockaddr_un telem_addr;
557 : :
558 : 1 : sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
559 [ - + ]: 1 : if (sock < 0) {
560 : 0 : printf("\n%s: Error creating socket: %s\n", __func__,
561 : 0 : strerror(errno));
562 : 0 : return -1;
563 : : }
564 : 1 : telem_addr.sun_family = AF_UNIX;
565 : 1 : snprintf(telem_addr.sun_path, sizeof(telem_addr.sun_path),
566 : : "%s/dpdk_telemetry.%s", rte_eal_get_runtime_dir(),
567 : : TELEMETRY_VERSION);
568 [ - + ]: 1 : if (connect(sock, (struct sockaddr *) &telem_addr,
569 : : sizeof(telem_addr)) < 0) {
570 : 0 : printf("\n%s: Error connecting to socket: %s\n", __func__,
571 : 0 : strerror(errno));
572 : 0 : close(sock);
573 : 0 : return -1;
574 : : }
575 : :
576 : 1 : bytes = read(sock, buf, sizeof(buf) - 1);
577 [ - + ]: 1 : if (bytes < 0) {
578 : 0 : printf("%s: Error with socket read - %s\n", __func__,
579 : 0 : strerror(errno));
580 : 0 : close(sock);
581 : 0 : return -1;
582 : : }
583 : 1 : buf[bytes] = '\0';
584 : : printf("\n%s: %s\n", __func__, buf);
585 : 1 : return sock;
586 : : }
587 : :
588 : : static int
589 : 1 : telemetry_data_autotest(void)
590 : : {
591 : : typedef int (*test_case)(void);
592 : : unsigned int i = 0;
593 : :
594 : 1 : sock = connect_to_socket();
595 [ + - ]: 1 : if (sock <= 0)
596 : : return -1;
597 : :
598 : 1 : test_case test_cases[] = {
599 : : test_null_return,
600 : : test_simple_string,
601 : : test_case_array_string,
602 : : test_case_array_int, test_case_array_u64,
603 : : test_case_array_uint_hex_padding,
604 : : test_case_array_uint_hex_nopadding,
605 : : test_case_add_dict_int, test_case_add_dict_u64,
606 : : test_case_add_dict_string,
607 : : test_case_add_dict_uint_hex_padding,
608 : : test_case_add_dict_uint_hex_nopadding,
609 : : test_dict_with_array_int_values,
610 : : test_dict_with_array_u64_values,
611 : : test_dict_with_array_string_values,
612 : : test_dict_with_array_uint_hex_values_padding,
613 : : test_dict_with_array_uint_hex_values_nopadding,
614 : : test_dict_with_dict_values,
615 : : test_array_with_array_int_values,
616 : : test_array_with_array_u64_values,
617 : : test_array_with_array_string_values,
618 : : test_array_with_array_uint_hex_values_padding,
619 : : test_array_with_array_uint_hex_values_nopadding,
620 : : test_array_with_dict_values,
621 : : test_string_char_escaping,
622 : : test_array_char_escaping,
623 : : test_dict_char_escaping,
624 : : };
625 : :
626 : 1 : rte_telemetry_register_cmd(REQUEST_CMD, telemetry_test_cb, "Test");
627 [ + + ]: 28 : for (i = 0; i < RTE_DIM(test_cases); i++) {
628 : : memset(&response_data, 0, sizeof(response_data));
629 [ - + ]: 27 : if (test_cases[i]() != 0) {
630 : 0 : close(sock);
631 : 0 : return -1;
632 : : }
633 : : }
634 : 1 : close(sock);
635 : 1 : return 0;
636 : : }
637 : : #endif /* !RTE_EXEC_ENV_WINDOWS */
638 : :
639 : 276 : REGISTER_FAST_TEST(telemetry_data_autotest, NOHUGE_OK, ASAN_OK, telemetry_data_autotest);
|