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 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 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 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 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 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 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 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 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 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 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