diff options
author | Paolo Bonzini | 2020-11-12 14:40:11 +0100 |
---|---|---|
committer | Paolo Bonzini | 2021-07-06 08:33:51 +0200 |
commit | 9176e800dbcb2636a2f24411eafc3c800e3455bd (patch) | |
tree | c2b8571cd17604f2811edbdb883a33c10eb9950b /tests/unit | |
parent | qom: export more functions for use with non-UserCreatable objects (diff) | |
download | qemu-9176e800dbcb2636a2f24411eafc3c800e3455bd.tar.gz qemu-9176e800dbcb2636a2f24411eafc3c800e3455bd.tar.xz qemu-9176e800dbcb2636a2f24411eafc3c800e3455bd.zip |
keyval: introduce keyval_merge
This patch introduces a function that merges two keyval-produced
(or keyval-like) QDicts. It can be used to emulate the behavior of
.merge_lists = true QemuOpts groups, merging -readconfig sections and
command-line options in a single QDict, and also to implement -set.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'tests/unit')
-rw-r--r-- | tests/unit/test-keyval.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/tests/unit/test-keyval.c b/tests/unit/test-keyval.c index e20c07cf3e..af0581ae6c 100644 --- a/tests/unit/test-keyval.c +++ b/tests/unit/test-keyval.c @@ -747,6 +747,61 @@ static void test_keyval_visit_any(void) visit_free(v); } +static void test_keyval_merge_dict(void) +{ + QDict *first = keyval_parse("opt1=abc,opt2.sub1=def,opt2.sub2=ghi,opt3=xyz", + NULL, NULL, &error_abort); + QDict *second = keyval_parse("opt1=ABC,opt2.sub2=GHI,opt2.sub3=JKL", + NULL, NULL, &error_abort); + QDict *combined = keyval_parse("opt1=ABC,opt2.sub1=def,opt2.sub2=GHI,opt2.sub3=JKL,opt3=xyz", + NULL, NULL, &error_abort); + Error *err = NULL; + + keyval_merge(first, second, &err); + g_assert(!err); + g_assert(qobject_is_equal(QOBJECT(combined), QOBJECT(first))); + qobject_unref(first); + qobject_unref(second); + qobject_unref(combined); +} + +static void test_keyval_merge_list(void) +{ + QDict *first = keyval_parse("opt1.0=abc,opt2.0=xyz", + NULL, NULL, &error_abort); + QDict *second = keyval_parse("opt1.0=def", + NULL, NULL, &error_abort); + QDict *combined = keyval_parse("opt1.0=abc,opt1.1=def,opt2.0=xyz", + NULL, NULL, &error_abort); + Error *err = NULL; + + keyval_merge(first, second, &err); + g_assert(!err); + g_assert(qobject_is_equal(QOBJECT(combined), QOBJECT(first))); + qobject_unref(first); + qobject_unref(second); + qobject_unref(combined); +} + +static void test_keyval_merge_conflict(void) +{ + QDict *first = keyval_parse("opt2=ABC", + NULL, NULL, &error_abort); + QDict *second = keyval_parse("opt2.sub1=def,opt2.sub2=ghi", + NULL, NULL, &error_abort); + QDict *third = qdict_clone_shallow(first); + Error *err = NULL; + + keyval_merge(first, second, &err); + error_free_or_abort(&err); + keyval_merge(second, third, &err); + error_free_or_abort(&err); + + qobject_unref(first); + qobject_unref(second); + qobject_unref(third); +} + int main(int argc, char *argv[]) { g_test_init(&argc, &argv, NULL); @@ -760,6 +815,9 @@ int main(int argc, char *argv[]) g_test_add_func("/keyval/visit/optional", test_keyval_visit_optional); g_test_add_func("/keyval/visit/alternate", test_keyval_visit_alternate); g_test_add_func("/keyval/visit/any", test_keyval_visit_any); + g_test_add_func("/keyval/merge/dict", test_keyval_merge_dict); + g_test_add_func("/keyval/merge/list", test_keyval_merge_list); + g_test_add_func("/keyval/merge/conflict", test_keyval_merge_conflict); g_test_run(); return 0; } |