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