aboutsummaryrefslogtreecommitdiff
path: root/tests/test-qemu-opts.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-qemu-opts.c')
-rw-r--r--tests/test-qemu-opts.c253
1 files changed, 253 insertions, 0 deletions
diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c
index 5d5a3da..2c422ab 100644
--- a/tests/test-qemu-opts.c
+++ b/tests/test-qemu-opts.c
@@ -10,6 +10,7 @@
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qemu/option.h"
+#include "qemu/option_int.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
@@ -23,6 +24,8 @@ static QemuOptsList opts_list_01 = {
{
.name = "str1",
.type = QEMU_OPT_STRING,
+ .help = "Help texts are preserved in qemu_opts_append",
+ .def_value_str = "default",
},{
.name = "str2",
.type = QEMU_OPT_STRING,
@@ -32,6 +35,7 @@ static QemuOptsList opts_list_01 = {
},{
.name = "number1",
.type = QEMU_OPT_NUMBER,
+ .help = "Having help texts only for some options is okay",
},{
.name = "number2",
.type = QEMU_OPT_NUMBER,
@@ -743,6 +747,250 @@ static void test_opts_parse_size(void)
qemu_opts_reset(&opts_list_02);
}
+static void append_verify_list_01(QemuOptDesc *desc, bool with_overlapping)
+{
+ int i = 0;
+
+ if (with_overlapping) {
+ g_assert_cmpstr(desc[i].name, ==, "str1");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
+ g_assert_cmpstr(desc[i].help, ==,
+ "Help texts are preserved in qemu_opts_append");
+ g_assert_cmpstr(desc[i].def_value_str, ==, "default");
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, "str2");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+ }
+
+ g_assert_cmpstr(desc[i].name, ==, "str3");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, "number1");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER);
+ g_assert_cmpstr(desc[i].help, ==,
+ "Having help texts only for some options is okay");
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, "number2");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, NULL);
+}
+
+static void append_verify_list_02(QemuOptDesc *desc)
+{
+ int i = 0;
+
+ g_assert_cmpstr(desc[i].name, ==, "str1");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, "str2");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, "bool1");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, "bool2");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, "size1");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, "size2");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+ i++;
+
+ g_assert_cmpstr(desc[i].name, ==, "size3");
+ g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
+ g_assert_cmpstr(desc[i].help, ==, NULL);
+ g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
+}
+
+static void test_opts_append_to_null(void)
+{
+ QemuOptsList *merged;
+
+ merged = qemu_opts_append(NULL, &opts_list_01);
+ g_assert(merged != &opts_list_01);
+
+ g_assert_cmpstr(merged->name, ==, NULL);
+ g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
+ g_assert_false(merged->merge_lists);
+
+ append_verify_list_01(merged->desc, true);
+
+ qemu_opts_free(merged);
+}
+
+static void test_opts_append(void)
+{
+ QemuOptsList *first, *merged;
+
+ first = qemu_opts_append(NULL, &opts_list_02);
+ merged = qemu_opts_append(first, &opts_list_01);
+ g_assert(first != &opts_list_02);
+ g_assert(merged != &opts_list_01);
+
+ g_assert_cmpstr(merged->name, ==, NULL);
+ g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
+ g_assert_false(merged->merge_lists);
+
+ append_verify_list_02(&merged->desc[0]);
+ append_verify_list_01(&merged->desc[7], false);
+
+ qemu_opts_free(merged);
+}
+
+static void test_opts_to_qdict_basic(void)
+{
+ QemuOpts *opts;
+ QDict *dict;
+
+ opts = qemu_opts_parse(&opts_list_01, "str1=foo,str2=,str3=bar,number1=42",
+ false, &error_abort);
+ g_assert(opts != NULL);
+
+ dict = qemu_opts_to_qdict(opts, NULL);
+ g_assert(dict != NULL);
+
+ g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
+ g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
+ g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
+ g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
+ g_assert_false(qdict_haskey(dict, "number2"));
+
+ QDECREF(dict);
+ qemu_opts_del(opts);
+}
+
+static void test_opts_to_qdict_filtered(void)
+{
+ QemuOptsList *first, *merged;
+ QemuOpts *opts;
+ QDict *dict;
+
+ first = qemu_opts_append(NULL, &opts_list_02);
+ merged = qemu_opts_append(first, &opts_list_01);
+
+ opts = qemu_opts_parse(merged,
+ "str1=foo,str2=,str3=bar,bool1=off,number1=42",
+ false, &error_abort);
+ g_assert(opts != NULL);
+
+ /* Convert to QDict without deleting from opts */
+ dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, false);
+ g_assert(dict != NULL);
+ g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
+ g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
+ g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
+ g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
+ g_assert_false(qdict_haskey(dict, "number2"));
+ g_assert_false(qdict_haskey(dict, "bool1"));
+ QDECREF(dict);
+
+ dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, false);
+ g_assert(dict != NULL);
+ g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
+ g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
+ g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off");
+ g_assert_false(qdict_haskey(dict, "str3"));
+ g_assert_false(qdict_haskey(dict, "number1"));
+ g_assert_false(qdict_haskey(dict, "number2"));
+ QDECREF(dict);
+
+ /* Now delete converted options from opts */
+ dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, true);
+ g_assert(dict != NULL);
+ g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
+ g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
+ g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
+ g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
+ g_assert_false(qdict_haskey(dict, "number2"));
+ g_assert_false(qdict_haskey(dict, "bool1"));
+ QDECREF(dict);
+
+ dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, true);
+ g_assert(dict != NULL);
+ g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off");
+ g_assert_false(qdict_haskey(dict, "str1"));
+ g_assert_false(qdict_haskey(dict, "str2"));
+ g_assert_false(qdict_haskey(dict, "str3"));
+ g_assert_false(qdict_haskey(dict, "number1"));
+ g_assert_false(qdict_haskey(dict, "number2"));
+ QDECREF(dict);
+
+ g_assert_true(QTAILQ_EMPTY(&opts->head));
+
+ qemu_opts_del(opts);
+ qemu_opts_free(merged);
+}
+
+static void test_opts_to_qdict_duplicates(void)
+{
+ QemuOpts *opts;
+ QemuOpt *opt;
+ QDict *dict;
+
+ opts = qemu_opts_parse(&opts_list_03, "foo=a,foo=b", false, &error_abort);
+ g_assert(opts != NULL);
+
+ /* Verify that opts has two options with the same name */
+ opt = QTAILQ_FIRST(&opts->head);
+ g_assert_cmpstr(opt->name, ==, "foo");
+ g_assert_cmpstr(opt->str , ==, "a");
+
+ opt = QTAILQ_NEXT(opt, next);
+ g_assert_cmpstr(opt->name, ==, "foo");
+ g_assert_cmpstr(opt->str , ==, "b");
+
+ opt = QTAILQ_NEXT(opt, next);
+ g_assert(opt == NULL);
+
+ /* In the conversion to QDict, the last one wins */
+ dict = qemu_opts_to_qdict(opts, NULL);
+ g_assert(dict != NULL);
+ g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b");
+ QDECREF(dict);
+
+ /* The last one still wins if entries are deleted, and both are deleted */
+ dict = qemu_opts_to_qdict_filtered(opts, NULL, NULL, true);
+ g_assert(dict != NULL);
+ g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b");
+ QDECREF(dict);
+
+ g_assert_true(QTAILQ_EMPTY(&opts->head));
+
+ qemu_opts_del(opts);
+}
+
int main(int argc, char *argv[])
{
register_opts();
@@ -761,6 +1009,11 @@ int main(int argc, char *argv[])
g_test_add_func("/qemu-opts/opts_parse/bool", test_opts_parse_bool);
g_test_add_func("/qemu-opts/opts_parse/number", test_opts_parse_number);
g_test_add_func("/qemu-opts/opts_parse/size", test_opts_parse_size);
+ g_test_add_func("/qemu-opts/append_to_null", test_opts_append_to_null);
+ g_test_add_func("/qemu-opts/append", test_opts_append);
+ g_test_add_func("/qemu-opts/to_qdict/basic", test_opts_to_qdict_basic);
+ g_test_add_func("/qemu-opts/to_qdict/filtered", test_opts_to_qdict_filtered);
+ g_test_add_func("/qemu-opts/to_qdict/duplicates", test_opts_to_qdict_duplicates);
g_test_run();
return 0;
}