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