qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio
at jcs-hda-dma 373 lines 10 kB view raw
1/* 2 * String Input Visitor unit-tests. 3 * 4 * Copyright (C) 2012 Red Hat Inc. 5 * 6 * Authors: 7 * Paolo Bonzini <pbonzini@redhat.com> (based on test-qobject-input-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-input-visitor.h" 18#include "test-qapi-visit.h" 19 20typedef struct TestInputVisitorData { 21 Visitor *v; 22} TestInputVisitorData; 23 24static void visitor_input_teardown(TestInputVisitorData *data, 25 const void *unused) 26{ 27 if (data->v) { 28 visit_free(data->v); 29 data->v = NULL; 30 } 31} 32 33/* This is provided instead of a test setup function so that the JSON 34 string used by the tests are kept in the test functions (and not 35 int main()) */ 36static 37Visitor *visitor_input_test_init(TestInputVisitorData *data, 38 const char *string) 39{ 40 visitor_input_teardown(data, NULL); 41 42 data->v = string_input_visitor_new(string); 43 g_assert(data->v); 44 return data->v; 45} 46 47static void test_visitor_in_int(TestInputVisitorData *data, 48 const void *unused) 49{ 50 int64_t res = 0, value = -42; 51 Error *err = NULL; 52 Visitor *v; 53 54 v = visitor_input_test_init(data, "-42"); 55 56 visit_type_int(v, NULL, &res, &err); 57 g_assert(!err); 58 g_assert_cmpint(res, ==, value); 59 60 v = visitor_input_test_init(data, "not an int"); 61 62 visit_type_int(v, NULL, &res, &err); 63 error_free_or_abort(&err); 64 65 v = visitor_input_test_init(data, ""); 66 67 visit_type_int(v, NULL, &res, &err); 68 error_free_or_abort(&err); 69} 70 71static void check_ilist(Visitor *v, int64_t *expected, size_t n) 72{ 73 int64List *res = NULL; 74 int64List *tail; 75 int i; 76 77 visit_type_int64List(v, NULL, &res, &error_abort); 78 tail = res; 79 for (i = 0; i < n; i++) { 80 g_assert(tail); 81 g_assert_cmpint(tail->value, ==, expected[i]); 82 tail = tail->next; 83 } 84 g_assert(!tail); 85 86 qapi_free_int64List(res); 87} 88 89static void check_ulist(Visitor *v, uint64_t *expected, size_t n) 90{ 91 uint64List *res = NULL; 92 uint64List *tail; 93 int i; 94 95 /* BUG: unsigned numbers above INT64_MAX don't work */ 96 for (i = 0; i < n; i++) { 97 if (expected[i] > INT64_MAX) { 98 Error *err = NULL; 99 visit_type_uint64List(v, NULL, &res, &err); 100 error_free_or_abort(&err); 101 return; 102 } 103 } 104 105 visit_type_uint64List(v, NULL, &res, &error_abort); 106 tail = res; 107 for (i = 0; i < n; i++) { 108 g_assert(tail); 109 g_assert_cmpuint(tail->value, ==, expected[i]); 110 tail = tail->next; 111 } 112 g_assert(!tail); 113 114 qapi_free_uint64List(res); 115} 116 117static void test_visitor_in_intList(TestInputVisitorData *data, 118 const void *unused) 119{ 120 /* Note: the visitor *sorts* ranges *unsigned* */ 121 int64_t expect1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20 }; 122 int64_t expect2[] = { 32767, -32768, -32767 }; 123 int64_t expect3[] = { INT64_MAX, INT64_MIN }; 124 uint64_t expect4[] = { UINT64_MAX }; 125 Error *err = NULL; 126 int64List *res = NULL; 127 int64List *tail; 128 Visitor *v; 129 int64_t val; 130 131 /* Valid lists */ 132 133 v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8"); 134 check_ilist(v, expect1, ARRAY_SIZE(expect1)); 135 136 v = visitor_input_test_init(data, "32767,-32768--32767"); 137 check_ilist(v, expect2, ARRAY_SIZE(expect2)); 138 139 v = visitor_input_test_init(data, 140 "-9223372036854775808,9223372036854775807"); 141 check_ilist(v, expect3, ARRAY_SIZE(expect3)); 142 143 v = visitor_input_test_init(data, "18446744073709551615"); 144 check_ulist(v, expect4, ARRAY_SIZE(expect4)); 145 146 /* Empty list */ 147 148 v = visitor_input_test_init(data, ""); 149 visit_type_int64List(v, NULL, &res, &error_abort); 150 g_assert(!res); 151 152 /* Not a list */ 153 154 v = visitor_input_test_init(data, "not an int list"); 155 156 visit_type_int64List(v, NULL, &res, &err); 157 error_free_or_abort(&err); 158 g_assert(!res); 159 160 /* Unvisited list tail */ 161 162 v = visitor_input_test_init(data, "0,2-3"); 163 164 /* Would be simpler if the visitor genuinely supported virtual walks */ 165 visit_start_list(v, NULL, (GenericList **)&res, sizeof(*res), 166 &error_abort); 167 tail = res; 168 visit_type_int64(v, NULL, &tail->value, &error_abort); 169 g_assert_cmpint(tail->value, ==, 0); 170 tail = (int64List *)visit_next_list(v, (GenericList *)tail, sizeof(*res)); 171 g_assert(tail); 172 visit_type_int64(v, NULL, &tail->value, &error_abort); 173 g_assert_cmpint(tail->value, ==, 2); 174 tail = (int64List *)visit_next_list(v, (GenericList *)tail, sizeof(*res)); 175 g_assert(tail); 176 177 visit_check_list(v, &err); 178 error_free_or_abort(&err); 179 visit_end_list(v, (void **)&res); 180 181 qapi_free_int64List(res); 182 183 /* Visit beyond end of list */ 184 v = visitor_input_test_init(data, "0"); 185 186 visit_start_list(v, NULL, (GenericList **)&res, sizeof(*res), 187 &error_abort); 188 tail = res; 189 visit_type_int64(v, NULL, &tail->value, &err); 190 g_assert_cmpint(tail->value, ==, 0); 191 visit_type_int64(v, NULL, &val, &err); 192 g_assert_cmpint(val, ==, 1); /* BUG */ 193 visit_check_list(v, &error_abort); 194 visit_end_list(v, (void **)&res); 195 196 qapi_free_int64List(res); 197} 198 199static void test_visitor_in_bool(TestInputVisitorData *data, 200 const void *unused) 201{ 202 Error *err = NULL; 203 bool res = false; 204 Visitor *v; 205 206 v = visitor_input_test_init(data, "true"); 207 208 visit_type_bool(v, NULL, &res, &err); 209 g_assert(!err); 210 g_assert_cmpint(res, ==, true); 211 212 v = visitor_input_test_init(data, "yes"); 213 214 visit_type_bool(v, NULL, &res, &err); 215 g_assert(!err); 216 g_assert_cmpint(res, ==, true); 217 218 v = visitor_input_test_init(data, "on"); 219 220 visit_type_bool(v, NULL, &res, &err); 221 g_assert(!err); 222 g_assert_cmpint(res, ==, true); 223 224 v = visitor_input_test_init(data, "false"); 225 226 visit_type_bool(v, NULL, &res, &err); 227 g_assert(!err); 228 g_assert_cmpint(res, ==, false); 229 230 v = visitor_input_test_init(data, "no"); 231 232 visit_type_bool(v, NULL, &res, &err); 233 g_assert(!err); 234 g_assert_cmpint(res, ==, false); 235 236 v = visitor_input_test_init(data, "off"); 237 238 visit_type_bool(v, NULL, &res, &err); 239 g_assert(!err); 240 g_assert_cmpint(res, ==, false); 241} 242 243static void test_visitor_in_number(TestInputVisitorData *data, 244 const void *unused) 245{ 246 double res = 0, value = 3.14; 247 Error *err = NULL; 248 Visitor *v; 249 250 v = visitor_input_test_init(data, "3.14"); 251 252 visit_type_number(v, NULL, &res, &err); 253 g_assert(!err); 254 g_assert_cmpfloat(res, ==, value); 255} 256 257static void test_visitor_in_string(TestInputVisitorData *data, 258 const void *unused) 259{ 260 char *res = NULL, *value = (char *) "Q E M U"; 261 Error *err = NULL; 262 Visitor *v; 263 264 v = visitor_input_test_init(data, value); 265 266 visit_type_str(v, NULL, &res, &err); 267 g_assert(!err); 268 g_assert_cmpstr(res, ==, value); 269 270 g_free(res); 271} 272 273static void test_visitor_in_enum(TestInputVisitorData *data, 274 const void *unused) 275{ 276 Error *err = NULL; 277 Visitor *v; 278 EnumOne i; 279 280 for (i = 0; i < ENUM_ONE__MAX; i++) { 281 EnumOne res = -1; 282 283 v = visitor_input_test_init(data, EnumOne_str(i)); 284 285 visit_type_EnumOne(v, NULL, &res, &err); 286 g_assert(!err); 287 g_assert_cmpint(i, ==, res); 288 } 289} 290 291/* Try to crash the visitors */ 292static void test_visitor_in_fuzz(TestInputVisitorData *data, 293 const void *unused) 294{ 295 int64_t ires; 296 intList *ilres; 297 bool bres; 298 double nres; 299 char *sres; 300 EnumOne eres; 301 Visitor *v; 302 unsigned int i; 303 char buf[10000]; 304 305 for (i = 0; i < 100; i++) { 306 unsigned int j; 307 308 j = g_test_rand_int_range(0, sizeof(buf) - 1); 309 310 buf[j] = '\0'; 311 312 if (j != 0) { 313 for (j--; j != 0; j--) { 314 buf[j - 1] = (char)g_test_rand_int_range(0, 256); 315 } 316 } 317 318 v = visitor_input_test_init(data, buf); 319 visit_type_int(v, NULL, &ires, NULL); 320 321 v = visitor_input_test_init(data, buf); 322 visit_type_intList(v, NULL, &ilres, NULL); 323 qapi_free_intList(ilres); 324 325 v = visitor_input_test_init(data, buf); 326 visit_type_bool(v, NULL, &bres, NULL); 327 328 v = visitor_input_test_init(data, buf); 329 visit_type_number(v, NULL, &nres, NULL); 330 331 v = visitor_input_test_init(data, buf); 332 sres = NULL; 333 visit_type_str(v, NULL, &sres, NULL); 334 g_free(sres); 335 336 v = visitor_input_test_init(data, buf); 337 visit_type_EnumOne(v, NULL, &eres, NULL); 338 } 339} 340 341static void input_visitor_test_add(const char *testpath, 342 TestInputVisitorData *data, 343 void (*test_func)(TestInputVisitorData *data, const void *user_data)) 344{ 345 g_test_add(testpath, TestInputVisitorData, data, NULL, test_func, 346 visitor_input_teardown); 347} 348 349int main(int argc, char **argv) 350{ 351 TestInputVisitorData in_visitor_data; 352 353 g_test_init(&argc, &argv, NULL); 354 355 input_visitor_test_add("/string-visitor/input/int", 356 &in_visitor_data, test_visitor_in_int); 357 input_visitor_test_add("/string-visitor/input/intList", 358 &in_visitor_data, test_visitor_in_intList); 359 input_visitor_test_add("/string-visitor/input/bool", 360 &in_visitor_data, test_visitor_in_bool); 361 input_visitor_test_add("/string-visitor/input/number", 362 &in_visitor_data, test_visitor_in_number); 363 input_visitor_test_add("/string-visitor/input/string", 364 &in_visitor_data, test_visitor_in_string); 365 input_visitor_test_add("/string-visitor/input/enum", 366 &in_visitor_data, test_visitor_in_enum); 367 input_visitor_test_add("/string-visitor/input/fuzz", 368 &in_visitor_data, test_visitor_in_fuzz); 369 370 g_test_run(); 371 372 return 0; 373}