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