cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

test-qemu-opts.c (33338B)


      1/*
      2 * QemuOpts unit-tests.
      3 *
      4 * Copyright (C) 2014 Leandro Dorileo <l@dorileo.org>
      5 *
      6 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
      7 * See the COPYING.LIB file in the top-level directory.
      8 */
      9
     10#include "qemu/osdep.h"
     11#include "qemu/units.h"
     12#include "qemu/option.h"
     13#include "qemu/option_int.h"
     14#include "qapi/error.h"
     15#include "qapi/qmp/qdict.h"
     16#include "qapi/qmp/qstring.h"
     17#include "qemu/config-file.h"
     18
     19
     20static QemuOptsList opts_list_01 = {
     21    .name = "opts_list_01",
     22    .head = QTAILQ_HEAD_INITIALIZER(opts_list_01.head),
     23    .desc = {
     24        {
     25            .name = "str1",
     26            .type = QEMU_OPT_STRING,
     27            .help = "Help texts are preserved in qemu_opts_append",
     28            .def_value_str = "default",
     29        },{
     30            .name = "str2",
     31            .type = QEMU_OPT_STRING,
     32        },{
     33            .name = "str3",
     34            .type = QEMU_OPT_STRING,
     35        },{
     36            .name = "number1",
     37            .type = QEMU_OPT_NUMBER,
     38            .help = "Having help texts only for some options is okay",
     39        },{
     40            .name = "number2",
     41            .type = QEMU_OPT_NUMBER,
     42        },
     43        { /* end of list */ }
     44    },
     45};
     46
     47static QemuOptsList opts_list_02 = {
     48    .name = "opts_list_02",
     49    .head = QTAILQ_HEAD_INITIALIZER(opts_list_02.head),
     50    .desc = {
     51        {
     52            .name = "str1",
     53            .type = QEMU_OPT_STRING,
     54        },{
     55            .name = "str2",
     56            .type = QEMU_OPT_STRING,
     57        },{
     58            .name = "bool1",
     59            .type = QEMU_OPT_BOOL,
     60        },{
     61            .name = "bool2",
     62            .type = QEMU_OPT_BOOL,
     63        },{
     64            .name = "size1",
     65            .type = QEMU_OPT_SIZE,
     66        },{
     67            .name = "size2",
     68            .type = QEMU_OPT_SIZE,
     69        },{
     70            .name = "size3",
     71            .type = QEMU_OPT_SIZE,
     72        },
     73        { /* end of list */ }
     74    },
     75};
     76
     77static QemuOptsList opts_list_03 = {
     78    .name = "opts_list_03",
     79    .implied_opt_name = "implied",
     80    .head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head),
     81    .desc = {
     82        /* no elements => accept any params */
     83        { /* end of list */ }
     84    },
     85};
     86
     87static QemuOptsList opts_list_04 = {
     88    .name = "opts_list_04",
     89    .head = QTAILQ_HEAD_INITIALIZER(opts_list_04.head),
     90    .merge_lists = true,
     91    .desc = {
     92        {
     93            .name = "str3",
     94            .type = QEMU_OPT_STRING,
     95        },
     96        { /* end of list */ }
     97    },
     98};
     99
    100static void register_opts(void)
    101{
    102    qemu_add_opts(&opts_list_01);
    103    qemu_add_opts(&opts_list_02);
    104    qemu_add_opts(&opts_list_03);
    105    qemu_add_opts(&opts_list_04);
    106}
    107
    108static void test_find_unknown_opts(void)
    109{
    110    QemuOptsList *list;
    111    Error *err = NULL;
    112
    113    /* should not return anything, we don't have an "unknown" option */
    114    list = qemu_find_opts_err("unknown", &err);
    115    g_assert(list == NULL);
    116    error_free_or_abort(&err);
    117}
    118
    119static void test_qemu_find_opts(void)
    120{
    121    QemuOptsList *list;
    122
    123    /* we have an "opts_list_01" option, should return it */
    124    list = qemu_find_opts("opts_list_01");
    125    g_assert(list != NULL);
    126    g_assert_cmpstr(list->name, ==, "opts_list_01");
    127}
    128
    129static void test_qemu_opts_create(void)
    130{
    131    QemuOptsList *list;
    132    QemuOpts *opts;
    133
    134    list = qemu_find_opts("opts_list_01");
    135    g_assert(list != NULL);
    136    g_assert(QTAILQ_EMPTY(&list->head));
    137    g_assert_cmpstr(list->name, ==, "opts_list_01");
    138
    139    /* should not find anything at this point */
    140    opts = qemu_opts_find(list, NULL);
    141    g_assert(opts == NULL);
    142
    143    /* create the opts */
    144    opts = qemu_opts_create(list, NULL, 0, &error_abort);
    145    g_assert(opts != NULL);
    146    g_assert(!QTAILQ_EMPTY(&list->head));
    147
    148    /* now we've create the opts, must find it */
    149    opts = qemu_opts_find(list, NULL);
    150    g_assert(opts != NULL);
    151
    152    qemu_opts_del(opts);
    153
    154    /* should not find anything at this point */
    155    opts = qemu_opts_find(list, NULL);
    156    g_assert(opts == NULL);
    157}
    158
    159static void test_qemu_opt_get(void)
    160{
    161    QemuOptsList *list;
    162    QemuOpts *opts;
    163    const char *opt = NULL;
    164
    165    list = qemu_find_opts("opts_list_01");
    166    g_assert(list != NULL);
    167    g_assert(QTAILQ_EMPTY(&list->head));
    168    g_assert_cmpstr(list->name, ==, "opts_list_01");
    169
    170    /* should not find anything at this point */
    171    opts = qemu_opts_find(list, NULL);
    172    g_assert(opts == NULL);
    173
    174    /* create the opts */
    175    opts = qemu_opts_create(list, NULL, 0, &error_abort);
    176    g_assert(opts != NULL);
    177    g_assert(!QTAILQ_EMPTY(&list->head));
    178
    179    /* haven't set anything to str2 yet */
    180    opt = qemu_opt_get(opts, "str2");
    181    g_assert(opt == NULL);
    182
    183    qemu_opt_set(opts, "str2", "value", &error_abort);
    184
    185    /* now we have set str2, should know about it */
    186    opt = qemu_opt_get(opts, "str2");
    187    g_assert_cmpstr(opt, ==, "value");
    188
    189    qemu_opt_set(opts, "str2", "value2", &error_abort);
    190
    191    /* having reset the value, the returned should be the reset one */
    192    opt = qemu_opt_get(opts, "str2");
    193    g_assert_cmpstr(opt, ==, "value2");
    194
    195    qemu_opts_del(opts);
    196
    197    /* should not find anything at this point */
    198    opts = qemu_opts_find(list, NULL);
    199    g_assert(opts == NULL);
    200}
    201
    202static void test_qemu_opt_get_bool(void)
    203{
    204    QemuOptsList *list;
    205    QemuOpts *opts;
    206    bool opt;
    207
    208    list = qemu_find_opts("opts_list_02");
    209    g_assert(list != NULL);
    210    g_assert(QTAILQ_EMPTY(&list->head));
    211    g_assert_cmpstr(list->name, ==, "opts_list_02");
    212
    213    /* should not find anything at this point */
    214    opts = qemu_opts_find(list, NULL);
    215    g_assert(opts == NULL);
    216
    217    /* create the opts */
    218    opts = qemu_opts_create(list, NULL, 0, &error_abort);
    219    g_assert(opts != NULL);
    220    g_assert(!QTAILQ_EMPTY(&list->head));
    221
    222    /* haven't set anything to bool1 yet, so defval should be returned */
    223    opt = qemu_opt_get_bool(opts, "bool1", false);
    224    g_assert(opt == false);
    225
    226    qemu_opt_set_bool(opts, "bool1", true, &error_abort);
    227
    228    /* now we have set bool1, should know about it */
    229    opt = qemu_opt_get_bool(opts, "bool1", false);
    230    g_assert(opt == true);
    231
    232    /* having reset the value, opt should be the reset one not defval */
    233    qemu_opt_set_bool(opts, "bool1", false, &error_abort);
    234
    235    opt = qemu_opt_get_bool(opts, "bool1", true);
    236    g_assert(opt == false);
    237
    238    qemu_opts_del(opts);
    239
    240    /* should not find anything at this point */
    241    opts = qemu_opts_find(list, NULL);
    242    g_assert(opts == NULL);
    243}
    244
    245static void test_qemu_opt_get_number(void)
    246{
    247    QemuOptsList *list;
    248    QemuOpts *opts;
    249    uint64_t opt;
    250
    251    list = qemu_find_opts("opts_list_01");
    252    g_assert(list != NULL);
    253    g_assert(QTAILQ_EMPTY(&list->head));
    254    g_assert_cmpstr(list->name, ==, "opts_list_01");
    255
    256    /* should not find anything at this point */
    257    opts = qemu_opts_find(list, NULL);
    258    g_assert(opts == NULL);
    259
    260    /* create the opts */
    261    opts = qemu_opts_create(list, NULL, 0, &error_abort);
    262    g_assert(opts != NULL);
    263    g_assert(!QTAILQ_EMPTY(&list->head));
    264
    265    /* haven't set anything to number1 yet, so defval should be returned */
    266    opt = qemu_opt_get_number(opts, "number1", 5);
    267    g_assert(opt == 5);
    268
    269    qemu_opt_set_number(opts, "number1", 10, &error_abort);
    270
    271    /* now we have set number1, should know about it */
    272    opt = qemu_opt_get_number(opts, "number1", 5);
    273    g_assert(opt == 10);
    274
    275    /* having reset it, the returned should be the reset one not defval */
    276    qemu_opt_set_number(opts, "number1", 15, &error_abort);
    277
    278    opt = qemu_opt_get_number(opts, "number1", 5);
    279    g_assert(opt == 15);
    280
    281    qemu_opts_del(opts);
    282
    283    /* should not find anything at this point */
    284    opts = qemu_opts_find(list, NULL);
    285    g_assert(opts == NULL);
    286}
    287
    288static void test_qemu_opt_get_size(void)
    289{
    290    QemuOptsList *list;
    291    QemuOpts *opts;
    292    uint64_t opt;
    293    QDict *dict;
    294
    295    list = qemu_find_opts("opts_list_02");
    296    g_assert(list != NULL);
    297    g_assert(QTAILQ_EMPTY(&list->head));
    298    g_assert_cmpstr(list->name, ==, "opts_list_02");
    299
    300    /* should not find anything at this point */
    301    opts = qemu_opts_find(list, NULL);
    302    g_assert(opts == NULL);
    303
    304    /* create the opts */
    305    opts = qemu_opts_create(list, NULL, 0, &error_abort);
    306    g_assert(opts != NULL);
    307    g_assert(!QTAILQ_EMPTY(&list->head));
    308
    309    /* haven't set anything to size1 yet, so defval should be returned */
    310    opt = qemu_opt_get_size(opts, "size1", 5);
    311    g_assert(opt == 5);
    312
    313    dict = qdict_new();
    314    g_assert(dict != NULL);
    315
    316    qdict_put_str(dict, "size1", "10");
    317
    318    qemu_opts_absorb_qdict(opts, dict, &error_abort);
    319    g_assert(error_abort == NULL);
    320
    321    /* now we have set size1, should know about it */
    322    opt = qemu_opt_get_size(opts, "size1", 5);
    323    g_assert(opt == 10);
    324
    325    /* reset value */
    326    qdict_put_str(dict, "size1", "15");
    327
    328    qemu_opts_absorb_qdict(opts, dict, &error_abort);
    329    g_assert(error_abort == NULL);
    330
    331    /* test the reset value */
    332    opt = qemu_opt_get_size(opts, "size1", 5);
    333    g_assert(opt == 15);
    334
    335    qdict_del(dict, "size1");
    336    g_free(dict);
    337
    338    qemu_opts_del(opts);
    339
    340    /* should not find anything at this point */
    341    opts = qemu_opts_find(list, NULL);
    342    g_assert(opts == NULL);
    343}
    344
    345static void test_qemu_opt_unset(void)
    346{
    347    QemuOpts *opts;
    348    const char *value;
    349    int ret;
    350
    351    /* dynamically initialized (parsed) opts */
    352    opts = qemu_opts_parse(&opts_list_03, "key=value", false, NULL);
    353    g_assert(opts != NULL);
    354
    355    /* check default/parsed value */
    356    value = qemu_opt_get(opts, "key");
    357    g_assert_cmpstr(value, ==, "value");
    358
    359    /* reset it to value2 */
    360    qemu_opt_set(opts, "key", "value2", &error_abort);
    361
    362    value = qemu_opt_get(opts, "key");
    363    g_assert_cmpstr(value, ==, "value2");
    364
    365    /* unset, valid only for "accept any" */
    366    ret = qemu_opt_unset(opts, "key");
    367    g_assert(ret == 0);
    368
    369    /* after reset the value should be the parsed/default one */
    370    value = qemu_opt_get(opts, "key");
    371    g_assert_cmpstr(value, ==, "value");
    372
    373    qemu_opts_del(opts);
    374}
    375
    376static void test_qemu_opts_reset(void)
    377{
    378    QemuOptsList *list;
    379    QemuOpts *opts;
    380    uint64_t opt;
    381
    382    list = qemu_find_opts("opts_list_01");
    383    g_assert(list != NULL);
    384    g_assert(QTAILQ_EMPTY(&list->head));
    385    g_assert_cmpstr(list->name, ==, "opts_list_01");
    386
    387    /* should not find anything at this point */
    388    opts = qemu_opts_find(list, NULL);
    389    g_assert(opts == NULL);
    390
    391    /* create the opts */
    392    opts = qemu_opts_create(list, NULL, 0, &error_abort);
    393    g_assert(opts != NULL);
    394    g_assert(!QTAILQ_EMPTY(&list->head));
    395
    396    /* haven't set anything to number1 yet, so defval should be returned */
    397    opt = qemu_opt_get_number(opts, "number1", 5);
    398    g_assert(opt == 5);
    399
    400    qemu_opt_set_number(opts, "number1", 10, &error_abort);
    401
    402    /* now we have set number1, should know about it */
    403    opt = qemu_opt_get_number(opts, "number1", 5);
    404    g_assert(opt == 10);
    405
    406    qemu_opts_reset(list);
    407
    408    /* should not find anything at this point */
    409    opts = qemu_opts_find(list, NULL);
    410    g_assert(opts == NULL);
    411}
    412
    413static int opts_count_iter(void *opaque, const char *name, const char *value,
    414                           Error **errp)
    415{
    416    (*(size_t *)opaque)++;
    417    return 0;
    418}
    419
    420static size_t opts_count(QemuOpts *opts)
    421{
    422    size_t n = 0;
    423
    424    qemu_opt_foreach(opts, opts_count_iter, &n, NULL);
    425    return n;
    426}
    427
    428static void test_opts_parse(void)
    429{
    430    Error *err = NULL;
    431    QemuOpts *opts;
    432
    433    /* Nothing */
    434    opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
    435    g_assert_cmpuint(opts_count(opts), ==, 0);
    436
    437    /* Empty key */
    438    opts = qemu_opts_parse(&opts_list_03, "=val", false, &error_abort);
    439    g_assert_cmpuint(opts_count(opts), ==, 1);
    440    g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
    441
    442    /* Multiple keys, last one wins */
    443    opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3",
    444                           false, &error_abort);
    445    g_assert_cmpuint(opts_count(opts), ==, 3);
    446    g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "3");
    447    g_assert_cmpstr(qemu_opt_get(opts, "b"), ==, "2,x");
    448
    449    /* Except when it doesn't */
    450    opts = qemu_opts_parse(&opts_list_03, "id=foo,id=bar",
    451                           false, &error_abort);
    452    g_assert_cmpuint(opts_count(opts), ==, 0);
    453    g_assert_cmpstr(qemu_opts_id(opts), ==, "foo");
    454
    455    /* TODO Cover low-level access to repeated keys */
    456
    457    /* Trailing comma is ignored */
    458    opts = qemu_opts_parse(&opts_list_03, "x=y,", false, &error_abort);
    459    g_assert_cmpuint(opts_count(opts), ==, 1);
    460    g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, "y");
    461
    462    /* Except when it isn't */
    463    opts = qemu_opts_parse(&opts_list_03, ",", false, &error_abort);
    464    g_assert_cmpuint(opts_count(opts), ==, 1);
    465    g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "on");
    466
    467    /* Duplicate ID */
    468    opts = qemu_opts_parse(&opts_list_03, "x=y,id=foo", false, &err);
    469    error_free_or_abort(&err);
    470    g_assert(!opts);
    471    /* TODO Cover .merge_lists = true */
    472
    473    /* Buggy ID recognition (fixed) */
    474    opts = qemu_opts_parse(&opts_list_03, "x=,,id=bar", false, &error_abort);
    475    g_assert_cmpuint(opts_count(opts), ==, 1);
    476    g_assert(!qemu_opts_id(opts));
    477    g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, ",id=bar");
    478
    479    /* Anti-social ID */
    480    opts = qemu_opts_parse(&opts_list_01, "id=666", false, &err);
    481    error_free_or_abort(&err);
    482    g_assert(!opts);
    483
    484    /* Implied value (qemu_opts_parse warns but accepts it) */
    485    opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=",
    486                           false, &error_abort);
    487    g_assert_cmpuint(opts_count(opts), ==, 3);
    488    g_assert_cmpstr(qemu_opt_get(opts, "an"), ==, "on");
    489    g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
    490    g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
    491
    492    /* Implied value, negated empty key */
    493    opts = qemu_opts_parse(&opts_list_03, "no", false, &error_abort);
    494    g_assert_cmpuint(opts_count(opts), ==, 1);
    495    g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "off");
    496
    497    /* Implied key */
    498    opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=", true,
    499                           &error_abort);
    500    g_assert_cmpuint(opts_count(opts), ==, 3);
    501    g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "an");
    502    g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
    503    g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
    504
    505    /* Implied key with empty value */
    506    opts = qemu_opts_parse(&opts_list_03, ",", true, &error_abort);
    507    g_assert_cmpuint(opts_count(opts), ==, 1);
    508    g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "");
    509
    510    /* Implied key with comma value */
    511    opts = qemu_opts_parse(&opts_list_03, ",,,a=1", true, &error_abort);
    512    g_assert_cmpuint(opts_count(opts), ==, 2);
    513    g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, ",");
    514    g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "1");
    515
    516    /* Empty key is not an implied key */
    517    opts = qemu_opts_parse(&opts_list_03, "=val", true, &error_abort);
    518    g_assert_cmpuint(opts_count(opts), ==, 1);
    519    g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
    520
    521    /* Unknown key */
    522    opts = qemu_opts_parse(&opts_list_01, "nonexistent=", false, &err);
    523    error_free_or_abort(&err);
    524    g_assert(!opts);
    525
    526    qemu_opts_reset(&opts_list_01);
    527    qemu_opts_reset(&opts_list_03);
    528}
    529
    530static void test_opts_parse_bool(void)
    531{
    532    Error *err = NULL;
    533    QemuOpts *opts;
    534
    535    opts = qemu_opts_parse(&opts_list_02, "bool1=on,bool2=off",
    536                           false, &error_abort);
    537    g_assert_cmpuint(opts_count(opts), ==, 2);
    538    g_assert(qemu_opt_get_bool(opts, "bool1", false));
    539    g_assert(!qemu_opt_get_bool(opts, "bool2", true));
    540
    541    opts = qemu_opts_parse(&opts_list_02, "bool1=offer", false, &err);
    542    error_free_or_abort(&err);
    543    g_assert(!opts);
    544
    545    qemu_opts_reset(&opts_list_02);
    546}
    547
    548static void test_opts_parse_number(void)
    549{
    550    Error *err = NULL;
    551    QemuOpts *opts;
    552
    553    /* Lower limit zero */
    554    opts = qemu_opts_parse(&opts_list_01, "number1=0", false, &error_abort);
    555    g_assert_cmpuint(opts_count(opts), ==, 1);
    556    g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 0);
    557
    558    /* Upper limit 2^64-1 */
    559    opts = qemu_opts_parse(&opts_list_01,
    560                           "number1=18446744073709551615,number2=-1",
    561                           false, &error_abort);
    562    g_assert_cmpuint(opts_count(opts), ==, 2);
    563    g_assert_cmphex(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
    564    g_assert_cmphex(qemu_opt_get_number(opts, "number2", 0), ==, UINT64_MAX);
    565
    566    /* Above upper limit */
    567    opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616",
    568                           false, &err);
    569    error_free_or_abort(&err);
    570    g_assert(!opts);
    571
    572    /* Below lower limit */
    573    opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616",
    574                           false, &err);
    575    error_free_or_abort(&err);
    576    g_assert(!opts);
    577
    578    /* Hex and octal */
    579    opts = qemu_opts_parse(&opts_list_01, "number1=0x2a,number2=052",
    580                           false, &error_abort);
    581    g_assert_cmpuint(opts_count(opts), ==, 2);
    582    g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
    583    g_assert_cmpuint(qemu_opt_get_number(opts, "number2", 0), ==, 42);
    584
    585    /* Invalid */
    586    opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err);
    587    error_free_or_abort(&err);
    588    g_assert(!opts);
    589    opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err);
    590    error_free_or_abort(&err);
    591    g_assert(!opts);
    592
    593    /* Leading whitespace */
    594    opts = qemu_opts_parse(&opts_list_01, "number1= \t42",
    595                           false, &error_abort);
    596    g_assert_cmpuint(opts_count(opts), ==, 1);
    597    g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
    598
    599    /* Trailing crap */
    600    opts = qemu_opts_parse(&opts_list_01, "number1=3.14", false, &err);
    601    error_free_or_abort(&err);
    602    g_assert(!opts);
    603    opts = qemu_opts_parse(&opts_list_01, "number1=08", false, &err);
    604    error_free_or_abort(&err);
    605    g_assert(!opts);
    606    opts = qemu_opts_parse(&opts_list_01, "number1=0 ", false, &err);
    607    error_free_or_abort(&err);
    608    g_assert(!opts);
    609
    610    qemu_opts_reset(&opts_list_01);
    611}
    612
    613static void test_opts_parse_size(void)
    614{
    615    Error *err = NULL;
    616    QemuOpts *opts;
    617
    618    /* Lower limit zero */
    619    opts = qemu_opts_parse(&opts_list_02, "size1=0", false, &error_abort);
    620    g_assert_cmpuint(opts_count(opts), ==, 1);
    621    g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0);
    622
    623    /* Note: full 64 bits of precision */
    624
    625    /* Around double limit of precision: 2^53-1, 2^53, 2^53+1 */
    626    opts = qemu_opts_parse(&opts_list_02,
    627                           "size1=9007199254740991,"
    628                           "size2=9007199254740992,"
    629                           "size3=9007199254740993",
    630                           false, &error_abort);
    631    g_assert_cmpuint(opts_count(opts), ==, 3);
    632    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
    633                     ==, 0x1fffffffffffff);
    634    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
    635                     ==, 0x20000000000000);
    636    g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1),
    637                     ==, 0x20000000000001);
    638
    639    /* Close to signed int limit: 2^63-1, 2^63, 2^63+1 */
    640    opts = qemu_opts_parse(&opts_list_02,
    641                           "size1=9223372036854775807," /* 7fffffffffffffff */
    642                           "size2=9223372036854775808," /* 8000000000000000 */
    643                           "size3=9223372036854775809", /* 8000000000000001 */
    644                           false, &error_abort);
    645    g_assert_cmpuint(opts_count(opts), ==, 3);
    646    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
    647                     ==, 0x7fffffffffffffff);
    648    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
    649                     ==, 0x8000000000000000);
    650    g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1),
    651                     ==, 0x8000000000000001);
    652
    653    /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */
    654    opts = qemu_opts_parse(&opts_list_02,
    655                           "size1=18446744073709549568," /* fffffffffffff800 */
    656                           "size2=18446744073709550591", /* fffffffffffffbff */
    657                           false, &error_abort);
    658    g_assert_cmpuint(opts_count(opts), ==, 2);
    659    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
    660                     ==, 0xfffffffffffff800);
    661    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
    662                     ==, 0xfffffffffffffbff);
    663
    664    /* Actual limit, 2^64-1 */
    665    opts = qemu_opts_parse(&opts_list_02,
    666                           "size1=18446744073709551615", /* ffffffffffffffff */
    667                           false, &error_abort);
    668    g_assert_cmpuint(opts_count(opts), ==, 1);
    669    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
    670                     ==, 0xffffffffffffffff);
    671
    672    /* Beyond limits */
    673    opts = qemu_opts_parse(&opts_list_02, "size1=-1", false, &err);
    674    error_free_or_abort(&err);
    675    g_assert(!opts);
    676    opts = qemu_opts_parse(&opts_list_02,
    677                           "size1=18446744073709551616", /* 2^64 */
    678                           false, &err);
    679    error_free_or_abort(&err);
    680    g_assert(!opts);
    681
    682    /* Suffixes */
    683    opts = qemu_opts_parse(&opts_list_02, "size1=8b,size2=1.5k,size3=2M",
    684                           false, &error_abort);
    685    g_assert_cmpuint(opts_count(opts), ==, 3);
    686    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, 8);
    687    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 1536);
    688    g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * MiB);
    689    opts = qemu_opts_parse(&opts_list_02, "size1=0.1G,size2=16777215T",
    690                           false, &error_abort);
    691    g_assert_cmpuint(opts_count(opts), ==, 2);
    692    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, GiB / 10);
    693    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 16777215ULL * TiB);
    694
    695    /* Beyond limit with suffix */
    696    opts = qemu_opts_parse(&opts_list_02, "size1=16777216T",
    697                           false, &err);
    698    error_free_or_abort(&err);
    699    g_assert(!opts);
    700
    701    /* Trailing crap */
    702    opts = qemu_opts_parse(&opts_list_02, "size1=16E", false, &err);
    703    error_free_or_abort(&err);
    704    g_assert(!opts);
    705    opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &err);
    706    error_free_or_abort(&err);
    707    g_assert(!opts);
    708
    709    qemu_opts_reset(&opts_list_02);
    710}
    711
    712static void test_has_help_option(void)
    713{
    714    static const struct {
    715        const char *params;
    716        /* expected value of qemu_opt_has_help_opt() with implied=false */
    717        bool expect;
    718        /* expected value of qemu_opt_has_help_opt() with implied=true */
    719        bool expect_implied;
    720    } test[] = {
    721        { "help", true, false },
    722        { "?", true, false },
    723        { "helpme", false, false },
    724        { "?me", false, false },
    725        { "a,help", true, true },
    726        { "a,?", true, true },
    727        { "a=0,help,b", true, true },
    728        { "a=0,?,b", true, true },
    729        { "help,b=1", true, false },
    730        { "?,b=1", true, false },
    731        { "a,b,,help", true, true },
    732        { "a,b,,?", true, true },
    733    };
    734    int i;
    735    QemuOpts *opts;
    736
    737    for (i = 0; i < ARRAY_SIZE(test); i++) {
    738        g_assert_cmpint(has_help_option(test[i].params),
    739                        ==, test[i].expect);
    740        opts = qemu_opts_parse(&opts_list_03, test[i].params, false,
    741                               &error_abort);
    742        g_assert_cmpint(qemu_opt_has_help_opt(opts),
    743                        ==, test[i].expect);
    744        qemu_opts_del(opts);
    745        opts = qemu_opts_parse(&opts_list_03, test[i].params, true,
    746                               &error_abort);
    747        g_assert_cmpint(qemu_opt_has_help_opt(opts),
    748                        ==, test[i].expect_implied);
    749        qemu_opts_del(opts);
    750    }
    751}
    752
    753static void append_verify_list_01(QemuOptDesc *desc, bool with_overlapping)
    754{
    755    int i = 0;
    756
    757    if (with_overlapping) {
    758        g_assert_cmpstr(desc[i].name, ==, "str1");
    759        g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
    760        g_assert_cmpstr(desc[i].help, ==,
    761                        "Help texts are preserved in qemu_opts_append");
    762        g_assert_cmpstr(desc[i].def_value_str, ==, "default");
    763        i++;
    764
    765        g_assert_cmpstr(desc[i].name, ==, "str2");
    766        g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
    767        g_assert_cmpstr(desc[i].help, ==, NULL);
    768        g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    769        i++;
    770    }
    771
    772    g_assert_cmpstr(desc[i].name, ==, "str3");
    773    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
    774    g_assert_cmpstr(desc[i].help, ==, NULL);
    775    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    776    i++;
    777
    778    g_assert_cmpstr(desc[i].name, ==, "number1");
    779    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER);
    780    g_assert_cmpstr(desc[i].help, ==,
    781                    "Having help texts only for some options is okay");
    782    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    783    i++;
    784
    785    g_assert_cmpstr(desc[i].name, ==, "number2");
    786    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER);
    787    g_assert_cmpstr(desc[i].help, ==, NULL);
    788    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    789    i++;
    790
    791    g_assert_cmpstr(desc[i].name, ==, NULL);
    792}
    793
    794static void append_verify_list_02(QemuOptDesc *desc)
    795{
    796    int i = 0;
    797
    798    g_assert_cmpstr(desc[i].name, ==, "str1");
    799    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
    800    g_assert_cmpstr(desc[i].help, ==, NULL);
    801    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    802    i++;
    803
    804    g_assert_cmpstr(desc[i].name, ==, "str2");
    805    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
    806    g_assert_cmpstr(desc[i].help, ==, NULL);
    807    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    808    i++;
    809
    810    g_assert_cmpstr(desc[i].name, ==, "bool1");
    811    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL);
    812    g_assert_cmpstr(desc[i].help, ==, NULL);
    813    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    814    i++;
    815
    816    g_assert_cmpstr(desc[i].name, ==, "bool2");
    817    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL);
    818    g_assert_cmpstr(desc[i].help, ==, NULL);
    819    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    820    i++;
    821
    822    g_assert_cmpstr(desc[i].name, ==, "size1");
    823    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
    824    g_assert_cmpstr(desc[i].help, ==, NULL);
    825    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    826    i++;
    827
    828    g_assert_cmpstr(desc[i].name, ==, "size2");
    829    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
    830    g_assert_cmpstr(desc[i].help, ==, NULL);
    831    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    832    i++;
    833
    834    g_assert_cmpstr(desc[i].name, ==, "size3");
    835    g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
    836    g_assert_cmpstr(desc[i].help, ==, NULL);
    837    g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
    838}
    839
    840static void test_opts_append_to_null(void)
    841{
    842    QemuOptsList *merged;
    843
    844    merged = qemu_opts_append(NULL, &opts_list_01);
    845    g_assert(merged != &opts_list_01);
    846
    847    g_assert_cmpstr(merged->name, ==, NULL);
    848    g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
    849    g_assert_false(merged->merge_lists);
    850
    851    append_verify_list_01(merged->desc, true);
    852
    853    qemu_opts_free(merged);
    854}
    855
    856static void test_opts_append(void)
    857{
    858    QemuOptsList *first, *merged;
    859
    860    first = qemu_opts_append(NULL, &opts_list_02);
    861    merged = qemu_opts_append(first, &opts_list_01);
    862    g_assert(first != &opts_list_02);
    863    g_assert(merged != &opts_list_01);
    864
    865    g_assert_cmpstr(merged->name, ==, NULL);
    866    g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
    867    g_assert_false(merged->merge_lists);
    868
    869    append_verify_list_02(&merged->desc[0]);
    870    append_verify_list_01(&merged->desc[7], false);
    871
    872    qemu_opts_free(merged);
    873}
    874
    875static void test_opts_to_qdict_basic(void)
    876{
    877    QemuOpts *opts;
    878    QDict *dict;
    879
    880    opts = qemu_opts_parse(&opts_list_01, "str1=foo,str2=,str3=bar,number1=42",
    881                           false, &error_abort);
    882    g_assert(opts != NULL);
    883
    884    dict = qemu_opts_to_qdict(opts, NULL);
    885    g_assert(dict != NULL);
    886
    887    g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
    888    g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
    889    g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
    890    g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
    891    g_assert_false(qdict_haskey(dict, "number2"));
    892
    893    qobject_unref(dict);
    894    qemu_opts_del(opts);
    895}
    896
    897static void test_opts_to_qdict_filtered(void)
    898{
    899    QemuOptsList *first, *merged;
    900    QemuOpts *opts;
    901    QDict *dict;
    902
    903    first = qemu_opts_append(NULL, &opts_list_02);
    904    merged = qemu_opts_append(first, &opts_list_01);
    905
    906    opts = qemu_opts_parse(merged,
    907                           "str1=foo,str2=,str3=bar,bool1=off,number1=42",
    908                           false, &error_abort);
    909    g_assert(opts != NULL);
    910
    911    /* Convert to QDict without deleting from opts */
    912    dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, false);
    913    g_assert(dict != NULL);
    914    g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
    915    g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
    916    g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
    917    g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
    918    g_assert_false(qdict_haskey(dict, "number2"));
    919    g_assert_false(qdict_haskey(dict, "bool1"));
    920    qobject_unref(dict);
    921
    922    dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, false);
    923    g_assert(dict != NULL);
    924    g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
    925    g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
    926    g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off");
    927    g_assert_false(qdict_haskey(dict, "str3"));
    928    g_assert_false(qdict_haskey(dict, "number1"));
    929    g_assert_false(qdict_haskey(dict, "number2"));
    930    qobject_unref(dict);
    931
    932    /* Now delete converted options from opts */
    933    dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, true);
    934    g_assert(dict != NULL);
    935    g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
    936    g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
    937    g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
    938    g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
    939    g_assert_false(qdict_haskey(dict, "number2"));
    940    g_assert_false(qdict_haskey(dict, "bool1"));
    941    qobject_unref(dict);
    942
    943    dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, true);
    944    g_assert(dict != NULL);
    945    g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off");
    946    g_assert_false(qdict_haskey(dict, "str1"));
    947    g_assert_false(qdict_haskey(dict, "str2"));
    948    g_assert_false(qdict_haskey(dict, "str3"));
    949    g_assert_false(qdict_haskey(dict, "number1"));
    950    g_assert_false(qdict_haskey(dict, "number2"));
    951    qobject_unref(dict);
    952
    953    g_assert_true(QTAILQ_EMPTY(&opts->head));
    954
    955    qemu_opts_del(opts);
    956    qemu_opts_free(merged);
    957}
    958
    959static void test_opts_to_qdict_duplicates(void)
    960{
    961    QemuOpts *opts;
    962    QemuOpt *opt;
    963    QDict *dict;
    964
    965    opts = qemu_opts_parse(&opts_list_03, "foo=a,foo=b", false, &error_abort);
    966    g_assert(opts != NULL);
    967
    968    /* Verify that opts has two options with the same name */
    969    opt = QTAILQ_FIRST(&opts->head);
    970    g_assert_cmpstr(opt->name, ==, "foo");
    971    g_assert_cmpstr(opt->str , ==, "a");
    972
    973    opt = QTAILQ_NEXT(opt, next);
    974    g_assert_cmpstr(opt->name, ==, "foo");
    975    g_assert_cmpstr(opt->str , ==, "b");
    976
    977    opt = QTAILQ_NEXT(opt, next);
    978    g_assert(opt == NULL);
    979
    980    /* In the conversion to QDict, the last one wins */
    981    dict = qemu_opts_to_qdict(opts, NULL);
    982    g_assert(dict != NULL);
    983    g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b");
    984    qobject_unref(dict);
    985
    986    /* The last one still wins if entries are deleted, and both are deleted */
    987    dict = qemu_opts_to_qdict_filtered(opts, NULL, NULL, true);
    988    g_assert(dict != NULL);
    989    g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b");
    990    qobject_unref(dict);
    991
    992    g_assert_true(QTAILQ_EMPTY(&opts->head));
    993
    994    qemu_opts_del(opts);
    995}
    996
    997int main(int argc, char *argv[])
    998{
    999    register_opts();
   1000    g_test_init(&argc, &argv, NULL);
   1001    g_test_add_func("/qemu-opts/find_unknown_opts", test_find_unknown_opts);
   1002    g_test_add_func("/qemu-opts/find_opts", test_qemu_find_opts);
   1003    g_test_add_func("/qemu-opts/opts_create", test_qemu_opts_create);
   1004    g_test_add_func("/qemu-opts/opt_get", test_qemu_opt_get);
   1005    g_test_add_func("/qemu-opts/opt_get_bool", test_qemu_opt_get_bool);
   1006    g_test_add_func("/qemu-opts/opt_get_number", test_qemu_opt_get_number);
   1007    g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size);
   1008    g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset);
   1009    g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset);
   1010    g_test_add_func("/qemu-opts/opts_parse/general", test_opts_parse);
   1011    g_test_add_func("/qemu-opts/opts_parse/bool", test_opts_parse_bool);
   1012    g_test_add_func("/qemu-opts/opts_parse/number", test_opts_parse_number);
   1013    g_test_add_func("/qemu-opts/opts_parse/size", test_opts_parse_size);
   1014    g_test_add_func("/qemu-opts/has_help_option", test_has_help_option);
   1015    g_test_add_func("/qemu-opts/append_to_null", test_opts_append_to_null);
   1016    g_test_add_func("/qemu-opts/append", test_opts_append);
   1017    g_test_add_func("/qemu-opts/to_qdict/basic", test_opts_to_qdict_basic);
   1018    g_test_add_func("/qemu-opts/to_qdict/filtered", test_opts_to_qdict_filtered);
   1019    g_test_add_func("/qemu-opts/to_qdict/duplicates", test_opts_to_qdict_duplicates);
   1020    g_test_run();
   1021    return 0;
   1022}