qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

test-string-input-visitor.c (14134B)


      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 "qapi/error.h"
     16 #include "qapi/string-input-visitor.h"
     17 #include "test-qapi-visit.h"
     18 
     19 typedef struct TestInputVisitorData {
     20     Visitor *v;
     21 } TestInputVisitorData;
     22 
     23 static void visitor_input_teardown(TestInputVisitorData *data,
     24                                    const void *unused)
     25 {
     26     if (data->v) {
     27         visit_free(data->v);
     28         data->v = NULL;
     29     }
     30 }
     31 
     32 /* This is provided instead of a test setup function so that the JSON
     33    string used by the tests are kept in the test functions (and not
     34    int main()) */
     35 static
     36 Visitor *visitor_input_test_init(TestInputVisitorData *data,
     37                                  const char *string)
     38 {
     39     visitor_input_teardown(data, NULL);
     40 
     41     data->v = string_input_visitor_new(string);
     42     g_assert(data->v);
     43     return data->v;
     44 }
     45 
     46 static void test_visitor_in_int(TestInputVisitorData *data,
     47                                 const void *unused)
     48 {
     49     int64_t res = 0, value = -42;
     50     Error *err = NULL;
     51     Visitor *v;
     52 
     53     v = visitor_input_test_init(data, "-42");
     54 
     55     visit_type_int(v, NULL, &res, &error_abort);
     56     g_assert_cmpint(res, ==, value);
     57 
     58     v = visitor_input_test_init(data, "not an int");
     59 
     60     visit_type_int(v, NULL, &res, &err);
     61     error_free_or_abort(&err);
     62 
     63     v = visitor_input_test_init(data, "");
     64 
     65     visit_type_int(v, NULL, &res, &err);
     66     error_free_or_abort(&err);
     67 }
     68 
     69 static void check_ilist(Visitor *v, int64_t *expected, size_t n)
     70 {
     71     int64List *res = NULL;
     72     int64List *tail;
     73     int i;
     74 
     75     visit_type_int64List(v, NULL, &res, &error_abort);
     76     tail = res;
     77     for (i = 0; i < n; i++) {
     78         g_assert(tail);
     79         g_assert_cmpint(tail->value, ==, expected[i]);
     80         tail = tail->next;
     81     }
     82     g_assert(!tail);
     83 
     84     qapi_free_int64List(res);
     85 }
     86 
     87 static void check_ulist(Visitor *v, uint64_t *expected, size_t n)
     88 {
     89     uint64List *res = NULL;
     90     uint64List *tail;
     91     int i;
     92 
     93     visit_type_uint64List(v, NULL, &res, &error_abort);
     94     tail = res;
     95     for (i = 0; i < n; i++) {
     96         g_assert(tail);
     97         g_assert_cmpuint(tail->value, ==, expected[i]);
     98         tail = tail->next;
     99     }
    100     g_assert(!tail);
    101 
    102     qapi_free_uint64List(res);
    103 }
    104 
    105 static void test_visitor_in_intList(TestInputVisitorData *data,
    106                                     const void *unused)
    107 {
    108     int64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
    109                           8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
    110     int64_t expect2[] = { 32767, -32768, -32767 };
    111     int64_t expect3[] = { INT64_MIN, INT64_MAX };
    112     int64_t expect4[] = { 1 };
    113     int64_t expect5[] = { INT64_MAX - 2,  INT64_MAX - 1, INT64_MAX };
    114     Error *err = NULL;
    115     int64List *res = NULL;
    116     Visitor *v;
    117     int64_t val;
    118 
    119     /* Valid lists */
    120 
    121     v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
    122     check_ilist(v, expect1, ARRAY_SIZE(expect1));
    123 
    124     v = visitor_input_test_init(data, "32767,-32768--32767");
    125     check_ilist(v, expect2, ARRAY_SIZE(expect2));
    126 
    127     v = visitor_input_test_init(data,
    128                                 "-9223372036854775808,9223372036854775807");
    129     check_ilist(v, expect3, ARRAY_SIZE(expect3));
    130 
    131     v = visitor_input_test_init(data, "1-1");
    132     check_ilist(v, expect4, ARRAY_SIZE(expect4));
    133 
    134     v = visitor_input_test_init(data,
    135                                 "9223372036854775805-9223372036854775807");
    136     check_ilist(v, expect5, ARRAY_SIZE(expect5));
    137 
    138     /* Value too large */
    139 
    140     v = visitor_input_test_init(data, "9223372036854775808");
    141     visit_type_int64List(v, NULL, &res, &err);
    142     error_free_or_abort(&err);
    143     g_assert(!res);
    144 
    145     /* Value too small */
    146 
    147     v = visitor_input_test_init(data, "-9223372036854775809");
    148     visit_type_int64List(v, NULL, &res, &err);
    149     error_free_or_abort(&err);
    150     g_assert(!res);
    151 
    152     /* Range not ascending */
    153 
    154     v = visitor_input_test_init(data, "3-1");
    155     visit_type_int64List(v, NULL, &res, &err);
    156     error_free_or_abort(&err);
    157     g_assert(!res);
    158 
    159     v = visitor_input_test_init(data, "9223372036854775807-0");
    160     visit_type_int64List(v, NULL, &res, &err);
    161     error_free_or_abort(&err);
    162     g_assert(!res);
    163 
    164     /* Range too big (65536 is the limit against DOS attacks) */
    165 
    166     v = visitor_input_test_init(data, "0-65536");
    167     visit_type_int64List(v, NULL, &res, &err);
    168     error_free_or_abort(&err);
    169     g_assert(!res);
    170 
    171     /* Empty list */
    172 
    173     v = visitor_input_test_init(data, "");
    174     visit_type_int64List(v, NULL, &res, &error_abort);
    175     g_assert(!res);
    176 
    177     /* Not a list */
    178 
    179     v = visitor_input_test_init(data, "not an int list");
    180 
    181     visit_type_int64List(v, NULL, &res, &err);
    182     error_free_or_abort(&err);
    183     g_assert(!res);
    184 
    185     /* Unvisited list tail */
    186 
    187     v = visitor_input_test_init(data, "0,2-3");
    188 
    189     visit_start_list(v, NULL, NULL, 0, &error_abort);
    190     visit_type_int64(v, NULL, &val, &error_abort);
    191     g_assert_cmpint(val, ==, 0);
    192     visit_type_int64(v, NULL, &val, &error_abort);
    193     g_assert_cmpint(val, ==, 2);
    194 
    195     visit_check_list(v, &err);
    196     error_free_or_abort(&err);
    197     visit_end_list(v, NULL);
    198 
    199     /* Visit beyond end of list */
    200 
    201     v = visitor_input_test_init(data, "0");
    202 
    203     visit_start_list(v, NULL, NULL, 0, &error_abort);
    204     visit_type_int64(v, NULL, &val, &err);
    205     g_assert_cmpint(val, ==, 0);
    206     visit_type_int64(v, NULL, &val, &err);
    207     error_free_or_abort(&err);
    208 
    209     visit_check_list(v, &error_abort);
    210     visit_end_list(v, NULL);
    211 }
    212 
    213 static void test_visitor_in_uintList(TestInputVisitorData *data,
    214                                      const void *unused)
    215 {
    216     uint64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
    217                            8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
    218     uint64_t expect2[] = { 32767, -32768, -32767 };
    219     uint64_t expect3[] = { INT64_MIN, INT64_MAX };
    220     uint64_t expect4[] = { 1 };
    221     uint64_t expect5[] = { UINT64_MAX };
    222     uint64_t expect6[] = { UINT64_MAX - 2,  UINT64_MAX - 1, UINT64_MAX };
    223     Error *err = NULL;
    224     uint64List *res = NULL;
    225     Visitor *v;
    226     uint64_t val;
    227 
    228     /* Valid lists */
    229 
    230     v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
    231     check_ulist(v, expect1, ARRAY_SIZE(expect1));
    232 
    233     v = visitor_input_test_init(data, "32767,-32768--32767");
    234     check_ulist(v, expect2, ARRAY_SIZE(expect2));
    235 
    236     v = visitor_input_test_init(data,
    237                                 "-9223372036854775808,9223372036854775807");
    238     check_ulist(v, expect3, ARRAY_SIZE(expect3));
    239 
    240     v = visitor_input_test_init(data, "1-1");
    241     check_ulist(v, expect4, ARRAY_SIZE(expect4));
    242 
    243     v = visitor_input_test_init(data, "18446744073709551615");
    244     check_ulist(v, expect5, ARRAY_SIZE(expect5));
    245 
    246     v = visitor_input_test_init(data,
    247                                 "18446744073709551613-18446744073709551615");
    248     check_ulist(v, expect6, ARRAY_SIZE(expect6));
    249 
    250     /* Value too large */
    251 
    252     v = visitor_input_test_init(data, "18446744073709551616");
    253     visit_type_uint64List(v, NULL, &res, &err);
    254     error_free_or_abort(&err);
    255     g_assert(!res);
    256 
    257     /* Value too small */
    258 
    259     v = visitor_input_test_init(data, "-18446744073709551616");
    260     visit_type_uint64List(v, NULL, &res, &err);
    261     error_free_or_abort(&err);
    262     g_assert(!res);
    263 
    264     /* Range not ascending */
    265 
    266     v = visitor_input_test_init(data, "3-1");
    267     visit_type_uint64List(v, NULL, &res, &err);
    268     error_free_or_abort(&err);
    269     g_assert(!res);
    270 
    271     v = visitor_input_test_init(data, "18446744073709551615-0");
    272     visit_type_uint64List(v, NULL, &res, &err);
    273     error_free_or_abort(&err);
    274     g_assert(!res);
    275 
    276     /* Range too big (65536 is the limit against DOS attacks) */
    277 
    278     v = visitor_input_test_init(data, "0-65536");
    279     visit_type_uint64List(v, NULL, &res, &err);
    280     error_free_or_abort(&err);
    281     g_assert(!res);
    282 
    283     /* Empty list */
    284 
    285     v = visitor_input_test_init(data, "");
    286     visit_type_uint64List(v, NULL, &res, &error_abort);
    287     g_assert(!res);
    288 
    289     /* Not a list */
    290 
    291     v = visitor_input_test_init(data, "not an uint list");
    292 
    293     visit_type_uint64List(v, NULL, &res, &err);
    294     error_free_or_abort(&err);
    295     g_assert(!res);
    296 
    297     /* Unvisited list tail */
    298 
    299     v = visitor_input_test_init(data, "0,2-3");
    300 
    301     visit_start_list(v, NULL, NULL, 0, &error_abort);
    302     visit_type_uint64(v, NULL, &val, &error_abort);
    303     g_assert_cmpuint(val, ==, 0);
    304     visit_type_uint64(v, NULL, &val, &error_abort);
    305     g_assert_cmpuint(val, ==, 2);
    306 
    307     visit_check_list(v, &err);
    308     error_free_or_abort(&err);
    309     visit_end_list(v, NULL);
    310 
    311     /* Visit beyond end of list */
    312 
    313     v = visitor_input_test_init(data, "0");
    314 
    315     visit_start_list(v, NULL, NULL, 0, &error_abort);
    316     visit_type_uint64(v, NULL, &val, &err);
    317     g_assert_cmpuint(val, ==, 0);
    318     visit_type_uint64(v, NULL, &val, &err);
    319     error_free_or_abort(&err);
    320 
    321     visit_check_list(v, &error_abort);
    322     visit_end_list(v, NULL);
    323 }
    324 
    325 static void test_visitor_in_bool(TestInputVisitorData *data,
    326                                  const void *unused)
    327 {
    328     bool res = false;
    329     Visitor *v;
    330 
    331     v = visitor_input_test_init(data, "true");
    332 
    333     visit_type_bool(v, NULL, &res, &error_abort);
    334     g_assert_cmpint(res, ==, true);
    335 
    336     v = visitor_input_test_init(data, "yes");
    337 
    338     visit_type_bool(v, NULL, &res, &error_abort);
    339     g_assert_cmpint(res, ==, true);
    340 
    341     v = visitor_input_test_init(data, "on");
    342 
    343     visit_type_bool(v, NULL, &res, &error_abort);
    344     g_assert_cmpint(res, ==, true);
    345 
    346     v = visitor_input_test_init(data, "false");
    347 
    348     visit_type_bool(v, NULL, &res, &error_abort);
    349     g_assert_cmpint(res, ==, false);
    350 
    351     v = visitor_input_test_init(data, "no");
    352 
    353     visit_type_bool(v, NULL, &res, &error_abort);
    354     g_assert_cmpint(res, ==, false);
    355 
    356     v = visitor_input_test_init(data, "off");
    357 
    358     visit_type_bool(v, NULL, &res, &error_abort);
    359     g_assert_cmpint(res, ==, false);
    360 }
    361 
    362 static void test_visitor_in_number(TestInputVisitorData *data,
    363                                    const void *unused)
    364 {
    365     double res = 0, value = 3.14;
    366     Error *err = NULL;
    367     Visitor *v;
    368 
    369     v = visitor_input_test_init(data, "3.14");
    370 
    371     visit_type_number(v, NULL, &res, &error_abort);
    372     g_assert_cmpfloat(res, ==, value);
    373 
    374     /* NaN and infinity has to be rejected */
    375 
    376     v = visitor_input_test_init(data, "NaN");
    377 
    378     visit_type_number(v, NULL, &res, &err);
    379     error_free_or_abort(&err);
    380 
    381     v = visitor_input_test_init(data, "inf");
    382 
    383     visit_type_number(v, NULL, &res, &err);
    384     error_free_or_abort(&err);
    385 
    386 }
    387 
    388 static void test_visitor_in_string(TestInputVisitorData *data,
    389                                    const void *unused)
    390 {
    391     char *res = NULL, *value = (char *) "Q E M U";
    392     Visitor *v;
    393 
    394     v = visitor_input_test_init(data, value);
    395 
    396     visit_type_str(v, NULL, &res, &error_abort);
    397     g_assert_cmpstr(res, ==, value);
    398 
    399     g_free(res);
    400 }
    401 
    402 static void test_visitor_in_enum(TestInputVisitorData *data,
    403                                  const void *unused)
    404 {
    405     Visitor *v;
    406     EnumOne i;
    407 
    408     for (i = 0; i < ENUM_ONE__MAX; i++) {
    409         EnumOne res = -1;
    410 
    411         v = visitor_input_test_init(data, EnumOne_str(i));
    412 
    413         visit_type_EnumOne(v, NULL, &res, &error_abort);
    414         g_assert_cmpint(i, ==, res);
    415     }
    416 }
    417 
    418 /* Try to crash the visitors */
    419 static void test_visitor_in_fuzz(TestInputVisitorData *data,
    420                                  const void *unused)
    421 {
    422     int64_t ires;
    423     intList *ilres;
    424     bool bres;
    425     double nres;
    426     char *sres;
    427     EnumOne eres;
    428     Visitor *v;
    429     unsigned int i;
    430     char buf[10000];
    431 
    432     for (i = 0; i < 100; i++) {
    433         unsigned int j, k;
    434 
    435         j = g_test_rand_int_range(0, sizeof(buf) - 1);
    436 
    437         buf[j] = '\0';
    438 
    439         for (k = 0; k != j; k++) {
    440             buf[k] = (char)g_test_rand_int_range(0, 256);
    441         }
    442 
    443         v = visitor_input_test_init(data, buf);
    444         visit_type_int(v, NULL, &ires, NULL);
    445 
    446         v = visitor_input_test_init(data, buf);
    447         visit_type_intList(v, NULL, &ilres, NULL);
    448         qapi_free_intList(ilres);
    449 
    450         v = visitor_input_test_init(data, buf);
    451         visit_type_bool(v, NULL, &bres, NULL);
    452 
    453         v = visitor_input_test_init(data, buf);
    454         visit_type_number(v, NULL, &nres, NULL);
    455 
    456         v = visitor_input_test_init(data, buf);
    457         sres = NULL;
    458         visit_type_str(v, NULL, &sres, NULL);
    459         g_free(sres);
    460 
    461         v = visitor_input_test_init(data, buf);
    462         visit_type_EnumOne(v, NULL, &eres, NULL);
    463     }
    464 }
    465 
    466 static void input_visitor_test_add(const char *testpath,
    467                                    TestInputVisitorData *data,
    468                                    void (*test_func)(TestInputVisitorData *data, const void *user_data))
    469 {
    470     g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
    471                visitor_input_teardown);
    472 }
    473 
    474 int main(int argc, char **argv)
    475 {
    476     TestInputVisitorData in_visitor_data;
    477 
    478     g_test_init(&argc, &argv, NULL);
    479 
    480     input_visitor_test_add("/string-visitor/input/int",
    481                            &in_visitor_data, test_visitor_in_int);
    482     input_visitor_test_add("/string-visitor/input/intList",
    483                            &in_visitor_data, test_visitor_in_intList);
    484     input_visitor_test_add("/string-visitor/input/uintList",
    485                            &in_visitor_data, test_visitor_in_uintList);
    486     input_visitor_test_add("/string-visitor/input/bool",
    487                            &in_visitor_data, test_visitor_in_bool);
    488     input_visitor_test_add("/string-visitor/input/number",
    489                            &in_visitor_data, test_visitor_in_number);
    490     input_visitor_test_add("/string-visitor/input/string",
    491                             &in_visitor_data, test_visitor_in_string);
    492     input_visitor_test_add("/string-visitor/input/enum",
    493                             &in_visitor_data, test_visitor_in_enum);
    494     input_visitor_test_add("/string-visitor/input/fuzz",
    495                             &in_visitor_data, test_visitor_in_fuzz);
    496 
    497     g_test_run();
    498 
    499     return 0;
    500 }