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