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