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 "qapi/qmp/qstring.h" 12 #include "qemu/config-file.h" 13 14 #include <glib.h> 15 16 static QemuOptsList opts_list_01 = { 17 .name = "opts_list_01", 18 .head = QTAILQ_HEAD_INITIALIZER(opts_list_01.head), 19 .desc = { 20 { 21 .name = "str1", 22 .type = QEMU_OPT_STRING, 23 },{ 24 .name = "str2", 25 .type = QEMU_OPT_STRING, 26 },{ 27 .name = "str3", 28 .type = QEMU_OPT_STRING, 29 },{ 30 .name = "number1", 31 .type = QEMU_OPT_NUMBER, 32 }, 33 { /* end of list */ } 34 }, 35 }; 36 37 static QemuOptsList opts_list_02 = { 38 .name = "opts_list_02", 39 .head = QTAILQ_HEAD_INITIALIZER(opts_list_02.head), 40 .desc = { 41 { 42 .name = "str1", 43 .type = QEMU_OPT_STRING, 44 },{ 45 .name = "bool1", 46 .type = QEMU_OPT_BOOL, 47 },{ 48 .name = "str2", 49 .type = QEMU_OPT_STRING, 50 },{ 51 .name = "size1", 52 .type = QEMU_OPT_SIZE, 53 }, 54 { /* end of list */ } 55 }, 56 }; 57 58 static QemuOptsList opts_list_03 = { 59 .name = "opts_list_03", 60 .head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head), 61 .desc = { 62 /* no elements => accept any params */ 63 { /* end of list */ } 64 }, 65 }; 66 67 static void register_opts(void) 68 { 69 qemu_add_opts(&opts_list_01); 70 qemu_add_opts(&opts_list_02); 71 qemu_add_opts(&opts_list_03); 72 } 73 74 static void test_find_unknown_opts(void) 75 { 76 QemuOptsList *list; 77 Error *err = NULL; 78 79 /* should not return anything, we don't have an "unknown" option */ 80 list = qemu_find_opts_err("unknown", &err); 81 g_assert(list == NULL); 82 g_assert(err); 83 error_free(err); 84 } 85 86 static void test_qemu_find_opts(void) 87 { 88 QemuOptsList *list; 89 90 /* we have an "opts_list_01" option, should return it */ 91 list = qemu_find_opts("opts_list_01"); 92 g_assert(list != NULL); 93 g_assert_cmpstr(list->name, ==, "opts_list_01"); 94 } 95 96 static void test_qemu_opts_create(void) 97 { 98 QemuOptsList *list; 99 QemuOpts *opts; 100 101 list = qemu_find_opts("opts_list_01"); 102 g_assert(list != NULL); 103 g_assert(QTAILQ_EMPTY(&list->head)); 104 g_assert_cmpstr(list->name, ==, "opts_list_01"); 105 106 /* should not find anything at this point */ 107 opts = qemu_opts_find(list, NULL); 108 g_assert(opts == NULL); 109 110 /* create the opts */ 111 opts = qemu_opts_create(list, NULL, 0, &error_abort); 112 g_assert(opts != NULL); 113 g_assert(!QTAILQ_EMPTY(&list->head)); 114 115 /* now we've create the opts, must find it */ 116 opts = qemu_opts_find(list, NULL); 117 g_assert(opts != NULL); 118 119 qemu_opts_del(opts); 120 121 /* should not find anything at this point */ 122 opts = qemu_opts_find(list, NULL); 123 g_assert(opts == NULL); 124 } 125 126 static void test_qemu_opt_get(void) 127 { 128 QemuOptsList *list; 129 QemuOpts *opts; 130 const char *opt = NULL; 131 132 list = qemu_find_opts("opts_list_01"); 133 g_assert(list != NULL); 134 g_assert(QTAILQ_EMPTY(&list->head)); 135 g_assert_cmpstr(list->name, ==, "opts_list_01"); 136 137 /* should not find anything at this point */ 138 opts = qemu_opts_find(list, NULL); 139 g_assert(opts == NULL); 140 141 /* create the opts */ 142 opts = qemu_opts_create(list, NULL, 0, &error_abort); 143 g_assert(opts != NULL); 144 g_assert(!QTAILQ_EMPTY(&list->head)); 145 146 /* haven't set anything to str2 yet */ 147 opt = qemu_opt_get(opts, "str2"); 148 g_assert(opt == NULL); 149 150 qemu_opt_set(opts, "str2", "value", &error_abort); 151 152 /* now we have set str2, should know about it */ 153 opt = qemu_opt_get(opts, "str2"); 154 g_assert_cmpstr(opt, ==, "value"); 155 156 qemu_opt_set(opts, "str2", "value2", &error_abort); 157 158 /* having reset the value, the returned should be the reset one */ 159 opt = qemu_opt_get(opts, "str2"); 160 g_assert_cmpstr(opt, ==, "value2"); 161 162 qemu_opts_del(opts); 163 164 /* should not find anything at this point */ 165 opts = qemu_opts_find(list, NULL); 166 g_assert(opts == NULL); 167 } 168 169 static void test_qemu_opt_get_bool(void) 170 { 171 Error *err = NULL; 172 QemuOptsList *list; 173 QemuOpts *opts; 174 bool opt; 175 176 list = qemu_find_opts("opts_list_02"); 177 g_assert(list != NULL); 178 g_assert(QTAILQ_EMPTY(&list->head)); 179 g_assert_cmpstr(list->name, ==, "opts_list_02"); 180 181 /* should not find anything at this point */ 182 opts = qemu_opts_find(list, NULL); 183 g_assert(opts == NULL); 184 185 /* create the opts */ 186 opts = qemu_opts_create(list, NULL, 0, &error_abort); 187 g_assert(opts != NULL); 188 g_assert(!QTAILQ_EMPTY(&list->head)); 189 190 /* haven't set anything to bool1 yet, so defval should be returned */ 191 opt = qemu_opt_get_bool(opts, "bool1", false); 192 g_assert(opt == false); 193 194 qemu_opt_set_bool(opts, "bool1", true, &err); 195 g_assert(!err); 196 197 /* now we have set bool1, should know about it */ 198 opt = qemu_opt_get_bool(opts, "bool1", false); 199 g_assert(opt == true); 200 201 /* having reset the value, opt should be the reset one not defval */ 202 qemu_opt_set_bool(opts, "bool1", false, &err); 203 g_assert(!err); 204 205 opt = qemu_opt_get_bool(opts, "bool1", true); 206 g_assert(opt == false); 207 208 qemu_opts_del(opts); 209 210 /* should not find anything at this point */ 211 opts = qemu_opts_find(list, NULL); 212 g_assert(opts == NULL); 213 } 214 215 static void test_qemu_opt_get_number(void) 216 { 217 Error *err = NULL; 218 QemuOptsList *list; 219 QemuOpts *opts; 220 uint64_t opt; 221 222 list = qemu_find_opts("opts_list_01"); 223 g_assert(list != NULL); 224 g_assert(QTAILQ_EMPTY(&list->head)); 225 g_assert_cmpstr(list->name, ==, "opts_list_01"); 226 227 /* should not find anything at this point */ 228 opts = qemu_opts_find(list, NULL); 229 g_assert(opts == NULL); 230 231 /* create the opts */ 232 opts = qemu_opts_create(list, NULL, 0, &error_abort); 233 g_assert(opts != NULL); 234 g_assert(!QTAILQ_EMPTY(&list->head)); 235 236 /* haven't set anything to number1 yet, so defval should be returned */ 237 opt = qemu_opt_get_number(opts, "number1", 5); 238 g_assert(opt == 5); 239 240 qemu_opt_set_number(opts, "number1", 10, &err); 241 g_assert(!err); 242 243 /* now we have set number1, should know about it */ 244 opt = qemu_opt_get_number(opts, "number1", 5); 245 g_assert(opt == 10); 246 247 /* having reset it, the returned should be the reset one not defval */ 248 qemu_opt_set_number(opts, "number1", 15, &err); 249 g_assert(!err); 250 251 opt = qemu_opt_get_number(opts, "number1", 5); 252 g_assert(opt == 15); 253 254 qemu_opts_del(opts); 255 256 /* should not find anything at this point */ 257 opts = qemu_opts_find(list, NULL); 258 g_assert(opts == NULL); 259 } 260 261 static void test_qemu_opt_get_size(void) 262 { 263 QemuOptsList *list; 264 QemuOpts *opts; 265 uint64_t opt; 266 QDict *dict; 267 268 list = qemu_find_opts("opts_list_02"); 269 g_assert(list != NULL); 270 g_assert(QTAILQ_EMPTY(&list->head)); 271 g_assert_cmpstr(list->name, ==, "opts_list_02"); 272 273 /* should not find anything at this point */ 274 opts = qemu_opts_find(list, NULL); 275 g_assert(opts == NULL); 276 277 /* create the opts */ 278 opts = qemu_opts_create(list, NULL, 0, &error_abort); 279 g_assert(opts != NULL); 280 g_assert(!QTAILQ_EMPTY(&list->head)); 281 282 /* haven't set anything to size1 yet, so defval should be returned */ 283 opt = qemu_opt_get_size(opts, "size1", 5); 284 g_assert(opt == 5); 285 286 dict = qdict_new(); 287 g_assert(dict != NULL); 288 289 qdict_put(dict, "size1", qstring_from_str("10")); 290 291 qemu_opts_absorb_qdict(opts, dict, &error_abort); 292 g_assert(error_abort == NULL); 293 294 /* now we have set size1, should know about it */ 295 opt = qemu_opt_get_size(opts, "size1", 5); 296 g_assert(opt == 10); 297 298 /* reset value */ 299 qdict_put(dict, "size1", qstring_from_str("15")); 300 301 qemu_opts_absorb_qdict(opts, dict, &error_abort); 302 g_assert(error_abort == NULL); 303 304 /* test the reset value */ 305 opt = qemu_opt_get_size(opts, "size1", 5); 306 g_assert(opt == 15); 307 308 qdict_del(dict, "size1"); 309 g_free(dict); 310 311 qemu_opts_del(opts); 312 313 /* should not find anything at this point */ 314 opts = qemu_opts_find(list, NULL); 315 g_assert(opts == NULL); 316 } 317 318 static void test_qemu_opt_unset(void) 319 { 320 QemuOpts *opts; 321 const char *value; 322 int ret; 323 324 /* dynamically initialized (parsed) opts */ 325 opts = qemu_opts_parse(&opts_list_03, "key=value", false, NULL); 326 g_assert(opts != NULL); 327 328 /* check default/parsed value */ 329 value = qemu_opt_get(opts, "key"); 330 g_assert_cmpstr(value, ==, "value"); 331 332 /* reset it to value2 */ 333 qemu_opt_set(opts, "key", "value2", &error_abort); 334 335 value = qemu_opt_get(opts, "key"); 336 g_assert_cmpstr(value, ==, "value2"); 337 338 /* unset, valid only for "accept any" */ 339 ret = qemu_opt_unset(opts, "key"); 340 g_assert(ret == 0); 341 342 /* after reset the value should be the parsed/default one */ 343 value = qemu_opt_get(opts, "key"); 344 g_assert_cmpstr(value, ==, "value"); 345 346 qemu_opts_del(opts); 347 } 348 349 static void test_qemu_opts_reset(void) 350 { 351 Error *err = NULL; 352 QemuOptsList *list; 353 QemuOpts *opts; 354 uint64_t opt; 355 356 list = qemu_find_opts("opts_list_01"); 357 g_assert(list != NULL); 358 g_assert(QTAILQ_EMPTY(&list->head)); 359 g_assert_cmpstr(list->name, ==, "opts_list_01"); 360 361 /* should not find anything at this point */ 362 opts = qemu_opts_find(list, NULL); 363 g_assert(opts == NULL); 364 365 /* create the opts */ 366 opts = qemu_opts_create(list, NULL, 0, &error_abort); 367 g_assert(opts != NULL); 368 g_assert(!QTAILQ_EMPTY(&list->head)); 369 370 /* haven't set anything to number1 yet, so defval should be returned */ 371 opt = qemu_opt_get_number(opts, "number1", 5); 372 g_assert(opt == 5); 373 374 qemu_opt_set_number(opts, "number1", 10, &err); 375 g_assert(!err); 376 377 /* now we have set number1, should know about it */ 378 opt = qemu_opt_get_number(opts, "number1", 5); 379 g_assert(opt == 10); 380 381 qemu_opts_reset(list); 382 383 /* should not find anything at this point */ 384 opts = qemu_opts_find(list, NULL); 385 g_assert(opts == NULL); 386 } 387 388 static void test_qemu_opts_set(void) 389 { 390 Error *err = NULL; 391 QemuOptsList *list; 392 QemuOpts *opts; 393 const char *opt; 394 395 list = qemu_find_opts("opts_list_01"); 396 g_assert(list != NULL); 397 g_assert(QTAILQ_EMPTY(&list->head)); 398 g_assert_cmpstr(list->name, ==, "opts_list_01"); 399 400 /* should not find anything at this point */ 401 opts = qemu_opts_find(list, NULL); 402 g_assert(opts == NULL); 403 404 /* implicitly create opts and set str3 value */ 405 qemu_opts_set(list, NULL, "str3", "value", &err); 406 g_assert(!err); 407 g_assert(!QTAILQ_EMPTY(&list->head)); 408 409 /* get the just created opts */ 410 opts = qemu_opts_find(list, NULL); 411 g_assert(opts != NULL); 412 413 /* check the str3 value */ 414 opt = qemu_opt_get(opts, "str3"); 415 g_assert_cmpstr(opt, ==, "value"); 416 417 qemu_opts_del(opts); 418 419 /* should not find anything at this point */ 420 opts = qemu_opts_find(list, NULL); 421 g_assert(opts == NULL); 422 } 423 424 int main(int argc, char *argv[]) 425 { 426 register_opts(); 427 g_test_init(&argc, &argv, NULL); 428 g_test_add_func("/qemu-opts/find_unknown_opts", test_find_unknown_opts); 429 g_test_add_func("/qemu-opts/find_opts", test_qemu_find_opts); 430 g_test_add_func("/qemu-opts/opts_create", test_qemu_opts_create); 431 g_test_add_func("/qemu-opts/opt_get", test_qemu_opt_get); 432 g_test_add_func("/qemu-opts/opt_get_bool", test_qemu_opt_get_bool); 433 g_test_add_func("/qemu-opts/opt_get_number", test_qemu_opt_get_number); 434 g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size); 435 g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset); 436 g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset); 437 g_test_add_func("/qemu-opts/opts_set", test_qemu_opts_set); 438 g_test_run(); 439 return 0; 440 } 441