1 /* 2 * String Output Visitor unit-tests. 3 * 4 * Copyright (C) 2012 Red Hat Inc. 5 * 6 * Authors: 7 * Paolo Bonzini <pbonzini@redhat.com> (based on test-qmp-output-visitor) 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 #include "qemu/osdep.h" 14 15 #include "qemu-common.h" 16 #include "qapi/error.h" 17 #include "qapi/string-output-visitor.h" 18 #include "test-qapi-types.h" 19 #include "test-qapi-visit.h" 20 #include "qapi/qmp/types.h" 21 22 typedef struct TestOutputVisitorData { 23 StringOutputVisitor *sov; 24 Visitor *ov; 25 bool human; 26 } TestOutputVisitorData; 27 28 static void visitor_output_setup(TestOutputVisitorData *data, 29 const void *unused) 30 { 31 data->human = false; 32 data->sov = string_output_visitor_new(data->human); 33 g_assert(data->sov != NULL); 34 35 data->ov = string_output_get_visitor(data->sov); 36 g_assert(data->ov != NULL); 37 } 38 39 static void visitor_output_setup_human(TestOutputVisitorData *data, 40 const void *unused) 41 { 42 data->human = true; 43 data->sov = string_output_visitor_new(data->human); 44 g_assert(data->sov != NULL); 45 46 data->ov = string_output_get_visitor(data->sov); 47 g_assert(data->ov != NULL); 48 } 49 50 static void visitor_output_teardown(TestOutputVisitorData *data, 51 const void *unused) 52 { 53 visit_free(data->ov); 54 data->sov = NULL; 55 data->ov = NULL; 56 } 57 58 static void test_visitor_out_int(TestOutputVisitorData *data, 59 const void *unused) 60 { 61 int64_t value = 42; 62 Error *err = NULL; 63 char *str; 64 65 visit_type_int(data->ov, NULL, &value, &err); 66 g_assert(!err); 67 68 str = string_output_get_string(data->sov); 69 g_assert(str != NULL); 70 if (data->human) { 71 g_assert_cmpstr(str, ==, "42 (0x2a)"); 72 } else { 73 g_assert_cmpstr(str, ==, "42"); 74 } 75 g_free(str); 76 } 77 78 static void test_visitor_out_intList(TestOutputVisitorData *data, 79 const void *unused) 80 { 81 int64_t value[] = {0, 1, 9, 10, 16, 15, 14, 82 3, 4, 5, 6, 11, 12, 13, 21, 22, INT64_MAX - 1, INT64_MAX}; 83 intList *list = NULL, **tmp = &list; 84 int i; 85 Error *err = NULL; 86 char *str; 87 88 for (i = 0; i < sizeof(value) / sizeof(value[0]); i++) { 89 *tmp = g_malloc0(sizeof(**tmp)); 90 (*tmp)->value = value[i]; 91 tmp = &(*tmp)->next; 92 } 93 94 visit_type_intList(data->ov, NULL, &list, &err); 95 g_assert(err == NULL); 96 97 str = string_output_get_string(data->sov); 98 g_assert(str != NULL); 99 if (data->human) { 100 g_assert_cmpstr(str, ==, 101 "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807 " 102 "(0x0-0x1,0x3-0x6,0x9-0x10,0x15-0x16," 103 "0x7ffffffffffffffe-0x7fffffffffffffff)"); 104 } else { 105 g_assert_cmpstr(str, ==, 106 "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807"); 107 } 108 g_free(str); 109 while (list) { 110 intList *tmp2; 111 tmp2 = list->next; 112 g_free(list); 113 list = tmp2; 114 } 115 } 116 117 static void test_visitor_out_bool(TestOutputVisitorData *data, 118 const void *unused) 119 { 120 Error *err = NULL; 121 bool value = true; 122 char *str; 123 124 visit_type_bool(data->ov, NULL, &value, &err); 125 g_assert(!err); 126 127 str = string_output_get_string(data->sov); 128 g_assert(str != NULL); 129 g_assert_cmpstr(str, ==, "true"); 130 g_free(str); 131 } 132 133 static void test_visitor_out_number(TestOutputVisitorData *data, 134 const void *unused) 135 { 136 double value = 3.14; 137 Error *err = NULL; 138 char *str; 139 140 visit_type_number(data->ov, NULL, &value, &err); 141 g_assert(!err); 142 143 str = string_output_get_string(data->sov); 144 g_assert(str != NULL); 145 g_assert_cmpstr(str, ==, "3.140000"); 146 g_free(str); 147 } 148 149 static void test_visitor_out_string(TestOutputVisitorData *data, 150 const void *unused) 151 { 152 char *string = (char *) "Q E M U"; 153 const char *string_human = "\"Q E M U\""; 154 Error *err = NULL; 155 char *str; 156 157 visit_type_str(data->ov, NULL, &string, &err); 158 g_assert(!err); 159 160 str = string_output_get_string(data->sov); 161 g_assert(str != NULL); 162 if (data->human) { 163 g_assert_cmpstr(str, ==, string_human); 164 } else { 165 g_assert_cmpstr(str, ==, string); 166 } 167 g_free(str); 168 } 169 170 static void test_visitor_out_no_string(TestOutputVisitorData *data, 171 const void *unused) 172 { 173 char *string = NULL; 174 Error *err = NULL; 175 char *str; 176 177 /* A null string should return "" */ 178 visit_type_str(data->ov, NULL, &string, &err); 179 g_assert(!err); 180 181 str = string_output_get_string(data->sov); 182 g_assert(str != NULL); 183 if (data->human) { 184 g_assert_cmpstr(str, ==, "<null>"); 185 } else { 186 g_assert_cmpstr(str, ==, ""); 187 } 188 g_free(str); 189 } 190 191 static void test_visitor_out_enum(TestOutputVisitorData *data, 192 const void *unused) 193 { 194 Error *err = NULL; 195 char *str; 196 EnumOne i; 197 198 for (i = 0; i < ENUM_ONE__MAX; i++) { 199 char *str_human; 200 201 visit_type_EnumOne(data->ov, "unused", &i, &err); 202 g_assert(!err); 203 204 str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]); 205 206 str = string_output_get_string(data->sov); 207 g_assert(str != NULL); 208 if (data->human) { 209 g_assert_cmpstr(str, ==, str_human); 210 } else { 211 g_assert_cmpstr(str, ==, EnumOne_lookup[i]); 212 } 213 g_free(str_human); 214 g_free(str); 215 } 216 } 217 218 static void test_visitor_out_enum_errors(TestOutputVisitorData *data, 219 const void *unused) 220 { 221 EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 }; 222 Error *err; 223 224 for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) { 225 err = NULL; 226 visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err); 227 g_assert(err); 228 error_free(err); 229 } 230 } 231 232 static void 233 output_visitor_test_add(const char *testpath, 234 TestOutputVisitorData *data, 235 void (*test_func)(TestOutputVisitorData *data, 236 const void *user_data), 237 bool human) 238 { 239 g_test_add(testpath, TestOutputVisitorData, data, 240 human ? visitor_output_setup_human : visitor_output_setup, 241 test_func, visitor_output_teardown); 242 } 243 244 int main(int argc, char **argv) 245 { 246 TestOutputVisitorData out_visitor_data; 247 248 g_test_init(&argc, &argv, NULL); 249 250 output_visitor_test_add("/string-visitor/output/int", 251 &out_visitor_data, test_visitor_out_int, false); 252 output_visitor_test_add("/string-visitor/output/int-human", 253 &out_visitor_data, test_visitor_out_int, true); 254 output_visitor_test_add("/string-visitor/output/bool", 255 &out_visitor_data, test_visitor_out_bool, false); 256 output_visitor_test_add("/string-visitor/output/bool-human", 257 &out_visitor_data, test_visitor_out_bool, true); 258 output_visitor_test_add("/string-visitor/output/number", 259 &out_visitor_data, test_visitor_out_number, false); 260 output_visitor_test_add("/string-visitor/output/number-human", 261 &out_visitor_data, test_visitor_out_number, true); 262 output_visitor_test_add("/string-visitor/output/string", 263 &out_visitor_data, test_visitor_out_string, false); 264 output_visitor_test_add("/string-visitor/output/string-human", 265 &out_visitor_data, test_visitor_out_string, true); 266 output_visitor_test_add("/string-visitor/output/no-string", 267 &out_visitor_data, test_visitor_out_no_string, 268 false); 269 output_visitor_test_add("/string-visitor/output/no-string-human", 270 &out_visitor_data, test_visitor_out_no_string, 271 true); 272 output_visitor_test_add("/string-visitor/output/enum", 273 &out_visitor_data, test_visitor_out_enum, false); 274 output_visitor_test_add("/string-visitor/output/enum-human", 275 &out_visitor_data, test_visitor_out_enum, true); 276 output_visitor_test_add("/string-visitor/output/enum-errors", 277 &out_visitor_data, test_visitor_out_enum_errors, 278 false); 279 output_visitor_test_add("/string-visitor/output/enum-errors-human", 280 &out_visitor_data, test_visitor_out_enum_errors, 281 true); 282 output_visitor_test_add("/string-visitor/output/intList", 283 &out_visitor_data, test_visitor_out_intList, false); 284 output_visitor_test_add("/string-visitor/output/intList-human", 285 &out_visitor_data, test_visitor_out_intList, true); 286 287 g_test_run(); 288 289 return 0; 290 } 291