check-qdict.c (8656B)
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}