Browse Source
Cover basic aspects and API usage for QemuOpt. The current implementation covers the API's planned to be changed by Chunyan Liu in his QEMUOptionParameter replacement/cleanup job. Other APIs should be covered in future improvements. [Squashing in a small fix "QemuOpt: use qemu_find_opts_err() to avoid output on stderr in tests". qemu_find_opts() calls error_report() instead of propagating the Error object. It is undesirable to clutter test case output with error messages from a passing test. Use qemu_find_opts_err() to avoid the output on stderr. --Stefan] Signed-off-by: Leandro Dorileo <l@dorileo.org> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>pull/10/merge
committed by
Stefan Hajnoczi
2 changed files with 444 additions and 0 deletions
@ -0,0 +1,441 @@ |
|||||
|
/*
|
||||
|
* QemuOpts unit-tests. |
||||
|
* |
||||
|
* Copyright (C) 2014 Leandro Dorileo <l@dorileo.org> |
||||
|
* |
||||
|
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later. |
||||
|
* See the COPYING.LIB file in the top-level directory. |
||||
|
*/ |
||||
|
|
||||
|
#include "qapi/error.h" |
||||
|
#include "qapi/qmp/qstring.h" |
||||
|
#include "qemu/config-file.h" |
||||
|
|
||||
|
#include <glib.h> |
||||
|
#include <string.h> |
||||
|
|
||||
|
static QemuOptsList opts_list_01 = { |
||||
|
.name = "opts_list_01", |
||||
|
.head = QTAILQ_HEAD_INITIALIZER(opts_list_01.head), |
||||
|
.desc = { |
||||
|
{ |
||||
|
.name = "str1", |
||||
|
.type = QEMU_OPT_STRING, |
||||
|
},{ |
||||
|
.name = "str2", |
||||
|
.type = QEMU_OPT_STRING, |
||||
|
},{ |
||||
|
.name = "str3", |
||||
|
.type = QEMU_OPT_STRING, |
||||
|
},{ |
||||
|
.name = "number1", |
||||
|
.type = QEMU_OPT_NUMBER, |
||||
|
}, |
||||
|
{ /* end of list */ } |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
static QemuOptsList opts_list_02 = { |
||||
|
.name = "opts_list_02", |
||||
|
.head = QTAILQ_HEAD_INITIALIZER(opts_list_02.head), |
||||
|
.desc = { |
||||
|
{ |
||||
|
.name = "str1", |
||||
|
.type = QEMU_OPT_STRING, |
||||
|
},{ |
||||
|
.name = "bool1", |
||||
|
.type = QEMU_OPT_BOOL, |
||||
|
},{ |
||||
|
.name = "str2", |
||||
|
.type = QEMU_OPT_STRING, |
||||
|
},{ |
||||
|
.name = "size1", |
||||
|
.type = QEMU_OPT_SIZE, |
||||
|
}, |
||||
|
{ /* end of list */ } |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
QemuOptsList opts_list_03 = { |
||||
|
.name = "opts_list_03", |
||||
|
.head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head), |
||||
|
.desc = { |
||||
|
/* no elements => accept any params */ |
||||
|
{ /* end of list */ } |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
static void register_opts(void) |
||||
|
{ |
||||
|
qemu_add_opts(&opts_list_01); |
||||
|
qemu_add_opts(&opts_list_02); |
||||
|
qemu_add_opts(&opts_list_03); |
||||
|
} |
||||
|
|
||||
|
static void test_find_unknown_opts(void) |
||||
|
{ |
||||
|
QemuOptsList *list; |
||||
|
Error *err = NULL; |
||||
|
|
||||
|
/* should not return anything, we don't have an "unknown" option */ |
||||
|
list = qemu_find_opts_err("unknown", &err); |
||||
|
g_assert(list == NULL); |
||||
|
g_assert(err); |
||||
|
error_free(err); |
||||
|
} |
||||
|
|
||||
|
static void test_qemu_find_opts(void) |
||||
|
{ |
||||
|
QemuOptsList *list; |
||||
|
|
||||
|
/* we have an "opts_list_01" option, should return it */ |
||||
|
list = qemu_find_opts("opts_list_01"); |
||||
|
g_assert(list != NULL); |
||||
|
g_assert_cmpstr(list->name, ==, "opts_list_01"); |
||||
|
} |
||||
|
|
||||
|
static void test_qemu_opts_create(void) |
||||
|
{ |
||||
|
QemuOptsList *list; |
||||
|
QemuOpts *opts; |
||||
|
|
||||
|
list = qemu_find_opts("opts_list_01"); |
||||
|
g_assert(list != NULL); |
||||
|
g_assert(QTAILQ_EMPTY(&list->head)); |
||||
|
g_assert_cmpstr(list->name, ==, "opts_list_01"); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
|
||||
|
/* create the opts */ |
||||
|
opts = qemu_opts_create(list, NULL, 0, &error_abort); |
||||
|
g_assert(opts != NULL); |
||||
|
g_assert(!QTAILQ_EMPTY(&list->head)); |
||||
|
|
||||
|
/* now we've create the opts, must find it */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts != NULL); |
||||
|
|
||||
|
qemu_opts_del(opts); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
} |
||||
|
|
||||
|
static void test_qemu_opt_get(void) |
||||
|
{ |
||||
|
QemuOptsList *list; |
||||
|
QemuOpts *opts; |
||||
|
const char *opt = NULL; |
||||
|
|
||||
|
list = qemu_find_opts("opts_list_01"); |
||||
|
g_assert(list != NULL); |
||||
|
g_assert(QTAILQ_EMPTY(&list->head)); |
||||
|
g_assert_cmpstr(list->name, ==, "opts_list_01"); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
|
||||
|
/* create the opts */ |
||||
|
opts = qemu_opts_create(list, NULL, 0, &error_abort); |
||||
|
g_assert(opts != NULL); |
||||
|
g_assert(!QTAILQ_EMPTY(&list->head)); |
||||
|
|
||||
|
/* haven't set anything to str2 yet */ |
||||
|
opt = qemu_opt_get(opts, "str2"); |
||||
|
g_assert(opt == NULL); |
||||
|
|
||||
|
qemu_opt_set(opts, "str2", "value"); |
||||
|
|
||||
|
/* now we have set str2, should know about it */ |
||||
|
opt = qemu_opt_get(opts, "str2"); |
||||
|
g_assert_cmpstr(opt, ==, "value"); |
||||
|
|
||||
|
qemu_opt_set(opts, "str2", "value2"); |
||||
|
|
||||
|
/* having reset the value, the returned should be the reset one */ |
||||
|
opt = qemu_opt_get(opts, "str2"); |
||||
|
g_assert_cmpstr(opt, ==, "value2"); |
||||
|
|
||||
|
qemu_opts_del(opts); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
} |
||||
|
|
||||
|
static void test_qemu_opt_get_bool(void) |
||||
|
{ |
||||
|
QemuOptsList *list; |
||||
|
QemuOpts *opts; |
||||
|
bool opt; |
||||
|
int ret; |
||||
|
|
||||
|
list = qemu_find_opts("opts_list_02"); |
||||
|
g_assert(list != NULL); |
||||
|
g_assert(QTAILQ_EMPTY(&list->head)); |
||||
|
g_assert_cmpstr(list->name, ==, "opts_list_02"); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
|
||||
|
/* create the opts */ |
||||
|
opts = qemu_opts_create(list, NULL, 0, &error_abort); |
||||
|
g_assert(opts != NULL); |
||||
|
g_assert(!QTAILQ_EMPTY(&list->head)); |
||||
|
|
||||
|
/* haven't set anything to bool1 yet, so defval should be returned */ |
||||
|
opt = qemu_opt_get_bool(opts, "bool1", false); |
||||
|
g_assert(opt == false); |
||||
|
|
||||
|
ret = qemu_opt_set_bool(opts, "bool1", true); |
||||
|
g_assert(ret == 0); |
||||
|
|
||||
|
/* now we have set bool1, should know about it */ |
||||
|
opt = qemu_opt_get_bool(opts, "bool1", false); |
||||
|
g_assert(opt == true); |
||||
|
|
||||
|
/* having reset the value, opt should be the reset one not defval */ |
||||
|
ret = qemu_opt_set_bool(opts, "bool1", false); |
||||
|
g_assert(ret == 0); |
||||
|
|
||||
|
opt = qemu_opt_get_bool(opts, "bool1", true); |
||||
|
g_assert(opt == false); |
||||
|
|
||||
|
qemu_opts_del(opts); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
} |
||||
|
|
||||
|
static void test_qemu_opt_get_number(void) |
||||
|
{ |
||||
|
QemuOptsList *list; |
||||
|
QemuOpts *opts; |
||||
|
uint64_t opt; |
||||
|
int ret; |
||||
|
|
||||
|
list = qemu_find_opts("opts_list_01"); |
||||
|
g_assert(list != NULL); |
||||
|
g_assert(QTAILQ_EMPTY(&list->head)); |
||||
|
g_assert_cmpstr(list->name, ==, "opts_list_01"); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
|
||||
|
/* create the opts */ |
||||
|
opts = qemu_opts_create(list, NULL, 0, &error_abort); |
||||
|
g_assert(opts != NULL); |
||||
|
g_assert(!QTAILQ_EMPTY(&list->head)); |
||||
|
|
||||
|
/* haven't set anything to number1 yet, so defval should be returned */ |
||||
|
opt = qemu_opt_get_number(opts, "number1", 5); |
||||
|
g_assert(opt == 5); |
||||
|
|
||||
|
ret = qemu_opt_set_number(opts, "number1", 10); |
||||
|
g_assert(ret == 0); |
||||
|
|
||||
|
/* now we have set number1, should know about it */ |
||||
|
opt = qemu_opt_get_number(opts, "number1", 5); |
||||
|
g_assert(opt == 10); |
||||
|
|
||||
|
/* having reset it, the returned should be the reset one not defval */ |
||||
|
ret = qemu_opt_set_number(opts, "number1", 15); |
||||
|
g_assert(ret == 0); |
||||
|
|
||||
|
opt = qemu_opt_get_number(opts, "number1", 5); |
||||
|
g_assert(opt == 15); |
||||
|
|
||||
|
qemu_opts_del(opts); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
} |
||||
|
|
||||
|
static void test_qemu_opt_get_size(void) |
||||
|
{ |
||||
|
QemuOptsList *list; |
||||
|
QemuOpts *opts; |
||||
|
uint64_t opt; |
||||
|
QDict *dict; |
||||
|
|
||||
|
list = qemu_find_opts("opts_list_02"); |
||||
|
g_assert(list != NULL); |
||||
|
g_assert(QTAILQ_EMPTY(&list->head)); |
||||
|
g_assert_cmpstr(list->name, ==, "opts_list_02"); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
|
||||
|
/* create the opts */ |
||||
|
opts = qemu_opts_create(list, NULL, 0, &error_abort); |
||||
|
g_assert(opts != NULL); |
||||
|
g_assert(!QTAILQ_EMPTY(&list->head)); |
||||
|
|
||||
|
/* haven't set anything to size1 yet, so defval should be returned */ |
||||
|
opt = qemu_opt_get_size(opts, "size1", 5); |
||||
|
g_assert(opt == 5); |
||||
|
|
||||
|
dict = qdict_new(); |
||||
|
g_assert(dict != NULL); |
||||
|
|
||||
|
qdict_put(dict, "size1", qstring_from_str("10")); |
||||
|
|
||||
|
qemu_opts_absorb_qdict(opts, dict, &error_abort); |
||||
|
g_assert(error_abort == NULL); |
||||
|
|
||||
|
/* now we have set size1, should know about it */ |
||||
|
opt = qemu_opt_get_size(opts, "size1", 5); |
||||
|
g_assert(opt == 10); |
||||
|
|
||||
|
/* reset value */ |
||||
|
qdict_put(dict, "size1", qstring_from_str("15")); |
||||
|
|
||||
|
qemu_opts_absorb_qdict(opts, dict, &error_abort); |
||||
|
g_assert(error_abort == NULL); |
||||
|
|
||||
|
/* test the reset value */ |
||||
|
opt = qemu_opt_get_size(opts, "size1", 5); |
||||
|
g_assert(opt == 15); |
||||
|
|
||||
|
qdict_del(dict, "size1"); |
||||
|
g_free(dict); |
||||
|
|
||||
|
qemu_opts_del(opts); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
} |
||||
|
|
||||
|
static void test_qemu_opt_unset(void) |
||||
|
{ |
||||
|
QemuOpts *opts; |
||||
|
const char *value; |
||||
|
int ret; |
||||
|
|
||||
|
/* dynamically initialized (parsed) opts */ |
||||
|
opts = qemu_opts_parse(&opts_list_03, "key=value", 0); |
||||
|
g_assert(opts != NULL); |
||||
|
|
||||
|
/* check default/parsed value */ |
||||
|
value = qemu_opt_get(opts, "key"); |
||||
|
g_assert_cmpstr(value, ==, "value"); |
||||
|
|
||||
|
/* reset it to value2 */ |
||||
|
qemu_opt_set(opts, "key", "value2"); |
||||
|
|
||||
|
value = qemu_opt_get(opts, "key"); |
||||
|
g_assert_cmpstr(value, ==, "value2"); |
||||
|
|
||||
|
/* unset, valid only for "accept any" */ |
||||
|
ret = qemu_opt_unset(opts, "key"); |
||||
|
g_assert(ret == 0); |
||||
|
|
||||
|
/* after reset the value should be the parsed/default one */ |
||||
|
value = qemu_opt_get(opts, "key"); |
||||
|
g_assert_cmpstr(value, ==, "value"); |
||||
|
|
||||
|
qemu_opts_del(opts); |
||||
|
} |
||||
|
|
||||
|
static void test_qemu_opts_reset(void) |
||||
|
{ |
||||
|
QemuOptsList *list; |
||||
|
QemuOpts *opts; |
||||
|
uint64_t opt; |
||||
|
int ret; |
||||
|
|
||||
|
list = qemu_find_opts("opts_list_01"); |
||||
|
g_assert(list != NULL); |
||||
|
g_assert(QTAILQ_EMPTY(&list->head)); |
||||
|
g_assert_cmpstr(list->name, ==, "opts_list_01"); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
|
||||
|
/* create the opts */ |
||||
|
opts = qemu_opts_create(list, NULL, 0, &error_abort); |
||||
|
g_assert(opts != NULL); |
||||
|
g_assert(!QTAILQ_EMPTY(&list->head)); |
||||
|
|
||||
|
/* haven't set anything to number1 yet, so defval should be returned */ |
||||
|
opt = qemu_opt_get_number(opts, "number1", 5); |
||||
|
g_assert(opt == 5); |
||||
|
|
||||
|
ret = qemu_opt_set_number(opts, "number1", 10); |
||||
|
g_assert(ret == 0); |
||||
|
|
||||
|
/* now we have set number1, should know about it */ |
||||
|
opt = qemu_opt_get_number(opts, "number1", 5); |
||||
|
g_assert(opt == 10); |
||||
|
|
||||
|
qemu_opts_reset(list); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
} |
||||
|
|
||||
|
static void test_qemu_opts_set(void) |
||||
|
{ |
||||
|
QemuOptsList *list; |
||||
|
QemuOpts *opts; |
||||
|
int ret; |
||||
|
const char *opt; |
||||
|
|
||||
|
list = qemu_find_opts("opts_list_01"); |
||||
|
g_assert(list != NULL); |
||||
|
g_assert(QTAILQ_EMPTY(&list->head)); |
||||
|
g_assert_cmpstr(list->name, ==, "opts_list_01"); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
|
||||
|
/* implicitly create opts and set str3 value */ |
||||
|
ret = qemu_opts_set(list, NULL, "str3", "value"); |
||||
|
g_assert(ret == 0); |
||||
|
g_assert(!QTAILQ_EMPTY(&list->head)); |
||||
|
|
||||
|
/* get the just created opts */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts != NULL); |
||||
|
|
||||
|
/* check the str3 value */ |
||||
|
opt = qemu_opt_get(opts, "str3"); |
||||
|
g_assert_cmpstr(opt, ==, "value"); |
||||
|
|
||||
|
qemu_opts_del(opts); |
||||
|
|
||||
|
/* should not find anything at this point */ |
||||
|
opts = qemu_opts_find(list, NULL); |
||||
|
g_assert(opts == NULL); |
||||
|
} |
||||
|
|
||||
|
int main(int argc, char *argv[]) |
||||
|
{ |
||||
|
register_opts(); |
||||
|
g_test_init(&argc, &argv, NULL); |
||||
|
g_test_add_func("/qemu-opts/find_unknown_opts", test_find_unknown_opts); |
||||
|
g_test_add_func("/qemu-opts/find_opts", test_qemu_find_opts); |
||||
|
g_test_add_func("/qemu-opts/opts_create", test_qemu_opts_create); |
||||
|
g_test_add_func("/qemu-opts/opt_get", test_qemu_opt_get); |
||||
|
g_test_add_func("/qemu-opts/opt_get_bool", test_qemu_opt_get_bool); |
||||
|
g_test_add_func("/qemu-opts/opt_get_number", test_qemu_opt_get_number); |
||||
|
g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size); |
||||
|
g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset); |
||||
|
g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset); |
||||
|
g_test_add_func("/qemu-opts/opts_set", test_qemu_opts_set); |
||||
|
g_test_run(); |
||||
|
return 0; |
||||
|
} |
||||
Loading…
Reference in new issue