qemu/tests/unit/check-qdict.c
<<
>>
Prefs
   1/*
   2 * QDict unit-tests.
   3 *
   4 * Copyright (C) 2009 Red Hat Inc.
   5 *
   6 * Authors:
   7 *  Luiz Capitulino <lcapitulino@redhat.com>
   8 *
   9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
  10 * See the COPYING.LIB file in the top-level directory.
  11 */
  12
  13#include "qemu/osdep.h"
  14#include "qapi/qmp/qdict.h"
  15#include "qapi/qmp/qnum.h"
  16#include "qapi/qmp/qstring.h"
  17
  18/*
  19 * Public Interface test-cases
  20 *
  21 * (with some violations to access 'private' data)
  22 */
  23
  24static void qdict_new_test(void)
  25{
  26    QDict *qdict;
  27
  28    qdict = qdict_new();
  29    g_assert(qdict != NULL);
  30    g_assert(qdict_size(qdict) == 0);
  31    g_assert(qdict->base.refcnt == 1);
  32    g_assert(qobject_type(QOBJECT(qdict)) == QTYPE_QDICT);
  33
  34    qobject_unref(qdict);
  35}
  36
  37static void qdict_put_obj_test(void)
  38{
  39    QNum *qn;
  40    QDict *qdict;
  41    QDictEntry *ent;
  42    const int num = 42;
  43
  44    qdict = qdict_new();
  45
  46    // key "" will have tdb hash 12345
  47    qdict_put_int(qdict, "", num);
  48
  49    g_assert(qdict_size(qdict) == 1);
  50    ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
  51    qn = qobject_to(QNum, ent->value);
  52    g_assert_cmpint(qnum_get_int(qn), ==, num);
  53
  54    qobject_unref(qdict);
  55}
  56
  57static void qdict_destroy_simple_test(void)
  58{
  59    QDict *qdict;
  60
  61    qdict = qdict_new();
  62    qdict_put_int(qdict, "num", 0);
  63    qdict_put_str(qdict, "str", "foo");
  64
  65    qobject_unref(qdict);
  66}
  67
  68static void qdict_get_test(void)
  69{
  70    QNum *qn;
  71    QObject *obj;
  72    const int value = -42;
  73    const char *key = "test";
  74    QDict *tests_dict = qdict_new();
  75
  76    qdict_put_int(tests_dict, key, value);
  77
  78    obj = qdict_get(tests_dict, key);
  79    g_assert(obj != NULL);
  80
  81    qn = qobject_to(QNum, obj);
  82    g_assert_cmpint(qnum_get_int(qn), ==, value);
  83
  84    qobject_unref(tests_dict);
  85}
  86
  87static void qdict_get_int_test(void)
  88{
  89    int ret;
  90    const int value = 100;
  91    const char *key = "int";
  92    QDict *tests_dict = qdict_new();
  93
  94    qdict_put_int(tests_dict, key, value);
  95
  96    ret = qdict_get_int(tests_dict, key);
  97    g_assert(ret == value);
  98
  99    qobject_unref(tests_dict);
 100}
 101
 102static void qdict_get_try_int_test(void)
 103{
 104    int ret;
 105    const int value = 100;
 106    const char *key = "int";
 107    QDict *tests_dict = qdict_new();
 108
 109    qdict_put_int(tests_dict, key, value);
 110    qdict_put_str(tests_dict, "string", "test");
 111
 112    ret = qdict_get_try_int(tests_dict, key, 0);
 113    g_assert(ret == value);
 114
 115    ret = qdict_get_try_int(tests_dict, "missing", -42);
 116    g_assert_cmpuint(ret, ==, -42);
 117
 118    ret = qdict_get_try_int(tests_dict, "string", -42);
 119    g_assert_cmpuint(ret, ==, -42);
 120
 121    qobject_unref(tests_dict);
 122}
 123
 124static void qdict_get_str_test(void)
 125{
 126    const char *p;
 127    const char *key = "key";
 128    const char *str = "string";
 129    QDict *tests_dict = qdict_new();
 130
 131    qdict_put_str(tests_dict, key, str);
 132
 133    p = qdict_get_str(tests_dict, key);
 134    g_assert(p != NULL);
 135    g_assert(strcmp(p, str) == 0);
 136
 137    qobject_unref(tests_dict);
 138}
 139
 140static void qdict_get_try_str_test(void)
 141{
 142    const char *p;
 143    const char *key = "key";
 144    const char *str = "string";
 145    QDict *tests_dict = qdict_new();
 146
 147    qdict_put_str(tests_dict, key, str);
 148
 149    p = qdict_get_try_str(tests_dict, key);
 150    g_assert(p != NULL);
 151    g_assert(strcmp(p, str) == 0);
 152
 153    qobject_unref(tests_dict);
 154}
 155
 156static void qdict_haskey_not_test(void)
 157{
 158    QDict *tests_dict = qdict_new();
 159    g_assert(qdict_haskey(tests_dict, "test") == 0);
 160
 161    qobject_unref(tests_dict);
 162}
 163
 164static void qdict_haskey_test(void)
 165{
 166    const char *key = "test";
 167    QDict *tests_dict = qdict_new();
 168
 169    qdict_put_int(tests_dict, key, 0);
 170    g_assert(qdict_haskey(tests_dict, key) == 1);
 171
 172    qobject_unref(tests_dict);
 173}
 174
 175static void qdict_del_test(void)
 176{
 177    const char *key = "key test";
 178    QDict *tests_dict = qdict_new();
 179
 180    qdict_put_str(tests_dict, key, "foo");
 181    g_assert(qdict_size(tests_dict) == 1);
 182
 183    qdict_del(tests_dict, key);
 184
 185    g_assert(qdict_size(tests_dict) == 0);
 186    g_assert(qdict_haskey(tests_dict, key) == 0);
 187
 188    qobject_unref(tests_dict);
 189}
 190
 191static void qobject_to_qdict_test(void)
 192{
 193    QDict *tests_dict = qdict_new();
 194    g_assert(qobject_to(QDict, QOBJECT(tests_dict)) == tests_dict);
 195
 196    qobject_unref(tests_dict);
 197}
 198
 199static void qdict_iterapi_test(void)
 200{
 201    int count;
 202    const QDictEntry *ent;
 203    QDict *tests_dict = qdict_new();
 204
 205    g_assert(qdict_first(tests_dict) == NULL);
 206
 207    qdict_put_int(tests_dict, "key1", 1);
 208    qdict_put_int(tests_dict, "key2", 2);
 209    qdict_put_int(tests_dict, "key3", 3);
 210
 211    count = 0;
 212    for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){
 213        g_assert(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1);
 214        count++;
 215    }
 216
 217    g_assert(count == qdict_size(tests_dict));
 218
 219    /* Do it again to test restarting */
 220    count = 0;
 221    for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){
 222        g_assert(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1);
 223        count++;
 224    }
 225
 226    g_assert(count == qdict_size(tests_dict));
 227
 228    qobject_unref(tests_dict);
 229}
 230
 231/*
 232 * Errors test-cases
 233 */
 234
 235static void qdict_put_exists_test(void)
 236{
 237    int value;
 238    const char *key = "exists";
 239    QDict *tests_dict = qdict_new();
 240
 241    qdict_put_int(tests_dict, key, 1);
 242    qdict_put_int(tests_dict, key, 2);
 243
 244    value = qdict_get_int(tests_dict, key);
 245    g_assert(value == 2);
 246
 247    g_assert(qdict_size(tests_dict) == 1);
 248
 249    qobject_unref(tests_dict);
 250}
 251
 252static void qdict_get_not_exists_test(void)
 253{
 254    QDict *tests_dict = qdict_new();
 255    g_assert(qdict_get(tests_dict, "foo") == NULL);
 256
 257    qobject_unref(tests_dict);
 258}
 259
 260/*
 261 * Stress test-case
 262 *
 263 * This is a lot big for a unit-test, but there is no other place
 264 * to have it.
 265 */
 266
 267static void remove_dots(char *string)
 268{
 269    char *p = strchr(string, ':');
 270    if (p)
 271        *p = '\0';
 272}
 273
 274static QString *read_line(FILE *file, char *key)
 275{
 276    char value[128];
 277
 278    if (fscanf(file, "%127s%127s", key, value) == EOF) {
 279        return NULL;
 280    }
 281    remove_dots(key);
 282    return qstring_from_str(value);
 283}
 284
 285#define reset_file(file)    fseek(file, 0L, SEEK_SET)
 286
 287static void qdict_stress_test(void)
 288{
 289    size_t lines;
 290    char key[128];
 291    FILE *test_file;
 292    QDict *qdict;
 293    QString *value;
 294    const char *test_file_path = "tests/data/qobject/qdict.txt";
 295
 296    test_file = fopen(test_file_path, "r");
 297    g_assert(test_file != NULL);
 298
 299    // Create the dict
 300    qdict = qdict_new();
 301    g_assert(qdict != NULL);
 302
 303    // Add everything from the test file
 304    for (lines = 0;; lines++) {
 305        value = read_line(test_file, key);
 306        if (!value)
 307            break;
 308
 309        qdict_put(qdict, key, value);
 310    }
 311    g_assert(qdict_size(qdict) == lines);
 312
 313    // Check if everything is really in there
 314    reset_file(test_file);
 315    for (;;) {
 316        const char *str1, *str2;
 317
 318        value = read_line(test_file, key);
 319        if (!value)
 320            break;
 321
 322        str1 = qstring_get_str(value);
 323
 324        str2 = qdict_get_str(qdict, key);
 325        g_assert(str2 != NULL);
 326
 327        g_assert(strcmp(str1, str2) == 0);
 328
 329        qobject_unref(value);
 330    }
 331
 332    // Delete everything
 333    reset_file(test_file);
 334    for (;;) {
 335        value = read_line(test_file, key);
 336        if (!value)
 337            break;
 338
 339        qdict_del(qdict, key);
 340        qobject_unref(value);
 341
 342        g_assert(qdict_haskey(qdict, key) == 0);
 343    }
 344    fclose(test_file);
 345
 346    g_assert(qdict_size(qdict) == 0);
 347    qobject_unref(qdict);
 348}
 349
 350int main(int argc, char **argv)
 351{
 352    g_test_init(&argc, &argv, NULL);
 353
 354    g_test_add_func("/public/new", qdict_new_test);
 355    g_test_add_func("/public/put_obj", qdict_put_obj_test);
 356    g_test_add_func("/public/destroy_simple", qdict_destroy_simple_test);
 357
 358    /* Continue, but now with fixtures */
 359    g_test_add_func("/public/get", qdict_get_test);
 360    g_test_add_func("/public/get_int", qdict_get_int_test);
 361    g_test_add_func("/public/get_try_int", qdict_get_try_int_test);
 362    g_test_add_func("/public/get_str", qdict_get_str_test);
 363    g_test_add_func("/public/get_try_str", qdict_get_try_str_test);
 364    g_test_add_func("/public/haskey_not", qdict_haskey_not_test);
 365    g_test_add_func("/public/haskey", qdict_haskey_test);
 366    g_test_add_func("/public/del", qdict_del_test);
 367    g_test_add_func("/public/to_qdict", qobject_to_qdict_test);
 368    g_test_add_func("/public/iterapi", qdict_iterapi_test);
 369
 370    g_test_add_func("/errors/put_exists", qdict_put_exists_test);
 371    g_test_add_func("/errors/get_not_exists", qdict_get_not_exists_test);
 372
 373    /* The Big one */
 374    if (g_test_slow()) {
 375        g_test_add_func("/stress/test", qdict_stress_test);
 376    }
 377
 378    return g_test_run();
 379}
 380