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