aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorLeandro Dorileo <l@dorileo.org>2014-05-19 18:53:55 -0300
committerStefan Hajnoczi <stefanha@redhat.com>2014-05-28 14:27:42 +0200
commit4ba6fabfb447661ee44ee593b2c454c7ffd1183f (patch)
treef4dc795ba2c35a3f27c354dac533017d6bd6eff0 /tests
parent7cf6376ae80e320fdaa6c9020f3e8ac1eecf1307 (diff)
QemuOpt: add unit tests
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>
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile3
-rw-r--r--tests/test-qemu-opts.c441
2 files changed, 444 insertions, 0 deletions
diff --git a/tests/Makefile b/tests/Makefile
index 9f7ca61ae3..8f71e0d664 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -60,6 +60,8 @@ check-unit-y += tests/test-qdev-global-props$(EXESUF)
check-unit-y += tests/check-qom-interface$(EXESUF)
gcov-files-check-qom-interface-y = qom/object.c
check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF)
+check-unit-y += tests/test-qemu-opts$(EXESUF)
+gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c
check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
@@ -319,6 +321,7 @@ tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o
tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o
tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o
tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
+tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o libqemuutil.a libqemustub.a
# QTest rules
diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c
new file mode 100644
index 0000000000..3653507f56
--- /dev/null
+++ b/tests/test-qemu-opts.c
@@ -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;
+}