]> git.proxmox.com Git - mirror_qemu.git/blobdiff - tests/check-qdict.c
qobject: Use simpler QDict/QList scalar insertion macros
[mirror_qemu.git] / tests / check-qdict.c
index a136f2addf2917a20d78d5eff0293bbfbaabeee1..be8d81f07b7d391c8fc3683f580e00183f63ae2d 100644 (file)
@@ -9,11 +9,12 @@
  * 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 <glib.h>
+#include "qemu/osdep.h"
 
 #include "qapi/qmp/qint.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
+#include "qapi/error.h"
 #include "qemu-common.h"
 
 /*
@@ -46,7 +47,7 @@ static void qdict_put_obj_test(void)
     qdict = qdict_new();
 
     // key "" will have tdb hash 12345
-    qdict_put_obj(qdict, "", QOBJECT(qint_from_int(num)));
+    qdict_put_int(qdict, "", num);
 
     g_assert(qdict_size(qdict) == 1);
     ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
@@ -65,8 +66,8 @@ static void qdict_destroy_simple_test(void)
     QDict *qdict;
 
     qdict = qdict_new();
-    qdict_put_obj(qdict, "num", QOBJECT(qint_from_int(0)));
-    qdict_put_obj(qdict, "str", QOBJECT(qstring_from_str("foo")));
+    qdict_put_int(qdict, "num", 0);
+    qdict_put_str(qdict, "str", "foo");
 
     QDECREF(qdict);
 }
@@ -79,7 +80,7 @@ static void qdict_get_test(void)
     const char *key = "test";
     QDict *tests_dict = qdict_new();
 
-    qdict_put(tests_dict, key, qint_from_int(value));
+    qdict_put_int(tests_dict, key, value);
 
     obj = qdict_get(tests_dict, key);
     g_assert(obj != NULL);
@@ -97,7 +98,7 @@ static void qdict_get_int_test(void)
     const char *key = "int";
     QDict *tests_dict = qdict_new();
 
-    qdict_put(tests_dict, key, qint_from_int(value));
+    qdict_put_int(tests_dict, key, value);
 
     ret = qdict_get_int(tests_dict, key);
     g_assert(ret == value);
@@ -112,7 +113,7 @@ static void qdict_get_try_int_test(void)
     const char *key = "int";
     QDict *tests_dict = qdict_new();
 
-    qdict_put(tests_dict, key, qint_from_int(value));
+    qdict_put_int(tests_dict, key, value);
 
     ret = qdict_get_try_int(tests_dict, key, 0);
     g_assert(ret == value);
@@ -127,7 +128,7 @@ static void qdict_get_str_test(void)
     const char *str = "string";
     QDict *tests_dict = qdict_new();
 
-    qdict_put(tests_dict, key, qstring_from_str(str));
+    qdict_put_str(tests_dict, key, str);
 
     p = qdict_get_str(tests_dict, key);
     g_assert(p != NULL);
@@ -143,7 +144,7 @@ static void qdict_get_try_str_test(void)
     const char *str = "string";
     QDict *tests_dict = qdict_new();
 
-    qdict_put(tests_dict, key, qstring_from_str(str));
+    qdict_put_str(tests_dict, key, str);
 
     p = qdict_get_try_str(tests_dict, key);
     g_assert(p != NULL);
@@ -187,7 +188,7 @@ static void qdict_haskey_test(void)
     const char *key = "test";
     QDict *tests_dict = qdict_new();
 
-    qdict_put(tests_dict, key, qint_from_int(0));
+    qdict_put_int(tests_dict, key, 0);
     g_assert(qdict_haskey(tests_dict, key) == 1);
 
     QDECREF(tests_dict);
@@ -198,7 +199,7 @@ static void qdict_del_test(void)
     const char *key = "key test";
     QDict *tests_dict = qdict_new();
 
-    qdict_put(tests_dict, key, qstring_from_str("foo"));
+    qdict_put_str(tests_dict, key, "foo");
     g_assert(qdict_size(tests_dict) == 1);
 
     qdict_del(tests_dict, key);
@@ -225,9 +226,9 @@ static void qdict_iterapi_test(void)
 
     g_assert(qdict_first(tests_dict) == NULL);
 
-    qdict_put(tests_dict, "key1", qint_from_int(1));
-    qdict_put(tests_dict, "key2", qint_from_int(2));
-    qdict_put(tests_dict, "key3", qint_from_int(3));
+    qdict_put_int(tests_dict, "key1", 1);
+    qdict_put_int(tests_dict, "key2", 2);
+    qdict_put_int(tests_dict, "key3", 3);
 
     count = 0;
     for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){
@@ -293,20 +294,20 @@ static void qdict_flatten_test(void)
      * }
      */
 
-    qdict_put(dict1, "a", qint_from_int(0));
-    qdict_put(dict1, "b", qint_from_int(1));
+    qdict_put_int(dict1, "a", 0);
+    qdict_put_int(dict1, "b", 1);
 
-    qlist_append_obj(list1, QOBJECT(qint_from_int(23)));
-    qlist_append_obj(list1, QOBJECT(qint_from_int(66)));
-    qlist_append_obj(list1, QOBJECT(dict1));
-    qlist_append_obj(list2, QOBJECT(qint_from_int(42)));
-    qlist_append_obj(list2, QOBJECT(list1));
+    qlist_append_int(list1, 23);
+    qlist_append_int(list1, 66);
+    qlist_append(list1, dict1);
+    qlist_append_int(list2, 42);
+    qlist_append(list2, list1);
 
-    qdict_put(dict2, "c", qint_from_int(2));
-    qdict_put(dict2, "d", qint_from_int(3));
-    qdict_put_obj(dict3, "e", QOBJECT(list2));
-    qdict_put_obj(dict3, "f", QOBJECT(dict2));
-    qdict_put(dict3, "g", qint_from_int(4));
+    qdict_put_int(dict2, "c", 2);
+    qdict_put_int(dict2, "d", 3);
+    qdict_put(dict3, "e", list2);
+    qdict_put(dict3, "f", dict2);
+    qdict_put_int(dict3, "g", 4);
 
     qdict_flatten(dict3);
 
@@ -368,12 +369,12 @@ static void qdict_array_split_test(void)
      * This example is given in the comment of qdict_array_split().
      */
 
-    qdict_put(test_dict, "1.x", qint_from_int(0));
-    qdict_put(test_dict, "4.y", qint_from_int(1));
-    qdict_put(test_dict, "0.a", qint_from_int(42));
-    qdict_put(test_dict, "o.o", qint_from_int(7));
-    qdict_put(test_dict, "0.b", qint_from_int(23));
-    qdict_put(test_dict, "2", qint_from_int(66));
+    qdict_put_int(test_dict, "1.x", 0);
+    qdict_put_int(test_dict, "4.y", 1);
+    qdict_put_int(test_dict, "0.a", 42);
+    qdict_put_int(test_dict, "o.o", 7);
+    qdict_put_int(test_dict, "0.b", 23);
+    qdict_put_int(test_dict, "2", 66);
 
     qdict_array_split(test_dict, &test_list);
 
@@ -412,7 +413,6 @@ static void qdict_array_split_test(void)
 
     QDECREF(test_dict);
 
-
     /*
      * Test the split of
      *
@@ -441,9 +441,9 @@ static void qdict_array_split_test(void)
 
     test_dict = qdict_new();
 
-    qdict_put(test_dict, "0", qint_from_int(42));
-    qdict_put(test_dict, "1", qint_from_int(23));
-    qdict_put(test_dict, "1.x", qint_from_int(84));
+    qdict_put_int(test_dict, "0", 42);
+    qdict_put_int(test_dict, "1", 23);
+    qdict_put_int(test_dict, "1.x", 84);
 
     qdict_array_split(test_dict, &test_list);
 
@@ -472,38 +472,38 @@ static void qdict_array_entries_test(void)
 
     g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
 
-    qdict_put(dict, "bar", qint_from_int(0));
-    qdict_put(dict, "baz.0", qint_from_int(0));
+    qdict_put_int(dict, "bar", 0);
+    qdict_put_int(dict, "baz.0", 0);
     g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
 
-    qdict_put(dict, "foo.1", qint_from_int(0));
+    qdict_put_int(dict, "foo.1", 0);
     g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
-    qdict_put(dict, "foo.0", qint_from_int(0));
+    qdict_put_int(dict, "foo.0", 0);
     g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 2);
-    qdict_put(dict, "foo.bar", qint_from_int(0));
+    qdict_put_int(dict, "foo.bar", 0);
     g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
     qdict_del(dict, "foo.bar");
 
-    qdict_put(dict, "foo.2.a", qint_from_int(0));
-    qdict_put(dict, "foo.2.b", qint_from_int(0));
-    qdict_put(dict, "foo.2.c", qint_from_int(0));
+    qdict_put_int(dict, "foo.2.a", 0);
+    qdict_put_int(dict, "foo.2.b", 0);
+    qdict_put_int(dict, "foo.2.c", 0);
     g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 3);
     g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
 
     QDECREF(dict);
 
     dict = qdict_new();
-    qdict_put(dict, "1", qint_from_int(0));
+    qdict_put_int(dict, "1", 0);
     g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
-    qdict_put(dict, "0", qint_from_int(0));
+    qdict_put_int(dict, "0", 0);
     g_assert_cmpint(qdict_array_entries(dict, ""), ==, 2);
-    qdict_put(dict, "bar", qint_from_int(0));
+    qdict_put_int(dict, "bar", 0);
     g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
     qdict_del(dict, "bar");
 
-    qdict_put(dict, "2.a", qint_from_int(0));
-    qdict_put(dict, "2.b", qint_from_int(0));
-    qdict_put(dict, "2.c", qint_from_int(0));
+    qdict_put_int(dict, "2.a", 0);
+    qdict_put_int(dict, "2.b", 0);
+    qdict_put_int(dict, "2.c", 0);
     g_assert_cmpint(qdict_array_entries(dict, ""), ==, 3);
 
     QDECREF(dict);
@@ -518,7 +518,6 @@ static void qdict_join_test(void)
     dict1 = qdict_new();
     dict2 = qdict_new();
 
-
     /* Test everything once without overwrite and once with */
     do
     {
@@ -528,10 +527,9 @@ static void qdict_join_test(void)
         g_assert(qdict_size(dict1) == 0);
         g_assert(qdict_size(dict2) == 0);
 
-
         /* First iteration: Test movement */
         /* Second iteration: Test empty source and non-empty destination */
-        qdict_put(dict2, "foo", qint_from_int(42));
+        qdict_put_int(dict2, "foo", 42);
 
         for (i = 0; i < 2; i++) {
             qdict_join(dict1, dict2, overwrite);
@@ -542,9 +540,8 @@ static void qdict_join_test(void)
             g_assert(qdict_get_int(dict1, "foo") == 42);
         }
 
-
         /* Test non-empty source and destination without conflict */
-        qdict_put(dict2, "bar", qint_from_int(23));
+        qdict_put_int(dict2, "bar", 23);
 
         qdict_join(dict1, dict2, overwrite);
 
@@ -554,23 +551,21 @@ static void qdict_join_test(void)
         g_assert(qdict_get_int(dict1, "foo") == 42);
         g_assert(qdict_get_int(dict1, "bar") == 23);
 
-
         /* Test conflict */
-        qdict_put(dict2, "foo", qint_from_int(84));
+        qdict_put_int(dict2, "foo", 84);
 
         qdict_join(dict1, dict2, overwrite);
 
         g_assert(qdict_size(dict1) == 2);
         g_assert(qdict_size(dict2) == !overwrite);
 
-        g_assert(qdict_get_int(dict1, "foo") == overwrite ? 84 : 42);
+        g_assert(qdict_get_int(dict1, "foo") == (overwrite ? 84 : 42));
         g_assert(qdict_get_int(dict1, "bar") == 23);
 
         if (!overwrite) {
             g_assert(qdict_get_int(dict2, "foo") == 84);
         }
 
-
         /* Check the references */
         g_assert(qdict_get(dict1, "foo")->refcnt == 1);
         g_assert(qdict_get(dict1, "bar")->refcnt == 1);
@@ -579,7 +574,6 @@ static void qdict_join_test(void)
             g_assert(qdict_get(dict2, "foo")->refcnt == 1);
         }
 
-
         /* Clean up */
         qdict_del(dict1, "foo");
         qdict_del(dict1, "bar");
@@ -590,11 +584,145 @@ static void qdict_join_test(void)
     }
     while (overwrite ^= true);
 
-
     QDECREF(dict1);
     QDECREF(dict2);
 }
 
+static void qdict_crumple_test_recursive(void)
+{
+    QDict *src, *dst, *rule, *vnc, *acl, *listen;
+    QList *rules;
+
+    src = qdict_new();
+    qdict_put_str(src, "vnc.listen.addr", "127.0.0.1");
+    qdict_put_str(src, "vnc.listen.port", "5901");
+    qdict_put_str(src, "vnc.acl.rules.0.match", "fred");
+    qdict_put_str(src, "vnc.acl.rules.0.policy", "allow");
+    qdict_put_str(src, "vnc.acl.rules.1.match", "bob");
+    qdict_put_str(src, "vnc.acl.rules.1.policy", "deny");
+    qdict_put_str(src, "vnc.acl.default", "deny");
+    qdict_put_str(src, "vnc.acl..name", "acl0");
+    qdict_put_str(src, "vnc.acl.rule..name", "acl0");
+
+    dst = qobject_to_qdict(qdict_crumple(src, &error_abort));
+    g_assert(dst);
+    g_assert_cmpint(qdict_size(dst), ==, 1);
+
+    vnc = qdict_get_qdict(dst, "vnc");
+    g_assert(vnc);
+    g_assert_cmpint(qdict_size(vnc), ==, 3);
+
+    listen = qdict_get_qdict(vnc, "listen");
+    g_assert(listen);
+    g_assert_cmpint(qdict_size(listen), ==, 2);
+    g_assert_cmpstr("127.0.0.1", ==, qdict_get_str(listen, "addr"));
+    g_assert_cmpstr("5901", ==, qdict_get_str(listen, "port"));
+
+    acl = qdict_get_qdict(vnc, "acl");
+    g_assert(acl);
+    g_assert_cmpint(qdict_size(acl), ==, 3);
+
+    rules = qdict_get_qlist(acl, "rules");
+    g_assert(rules);
+    g_assert_cmpint(qlist_size(rules), ==, 2);
+
+    rule = qobject_to_qdict(qlist_pop(rules));
+    g_assert(rule);
+    g_assert_cmpint(qdict_size(rule), ==, 2);
+    g_assert_cmpstr("fred", ==, qdict_get_str(rule, "match"));
+    g_assert_cmpstr("allow", ==, qdict_get_str(rule, "policy"));
+    QDECREF(rule);
+
+    rule = qobject_to_qdict(qlist_pop(rules));
+    g_assert(rule);
+    g_assert_cmpint(qdict_size(rule), ==, 2);
+    g_assert_cmpstr("bob", ==, qdict_get_str(rule, "match"));
+    g_assert_cmpstr("deny", ==, qdict_get_str(rule, "policy"));
+    QDECREF(rule);
+
+    /* With recursive crumpling, we should see all names unescaped */
+    g_assert_cmpstr("acl0", ==, qdict_get_str(vnc, "acl.name"));
+    g_assert_cmpstr("acl0", ==, qdict_get_str(acl, "rule.name"));
+
+    QDECREF(src);
+    QDECREF(dst);
+}
+
+static void qdict_crumple_test_empty(void)
+{
+    QDict *src, *dst;
+
+    src = qdict_new();
+
+    dst = (QDict *)qdict_crumple(src, &error_abort);
+
+    g_assert_cmpint(qdict_size(dst), ==, 0);
+
+    QDECREF(src);
+    QDECREF(dst);
+}
+
+static void qdict_crumple_test_bad_inputs(void)
+{
+    QDict *src;
+    Error *error = NULL;
+
+    src = qdict_new();
+    /* rule.0 can't be both a string and a dict */
+    qdict_put_str(src, "rule.0", "fred");
+    qdict_put_str(src, "rule.0.policy", "allow");
+
+    g_assert(qdict_crumple(src, &error) == NULL);
+    g_assert(error != NULL);
+    error_free(error);
+    error = NULL;
+    QDECREF(src);
+
+    src = qdict_new();
+    /* rule can't be both a list and a dict */
+    qdict_put_str(src, "rule.0", "fred");
+    qdict_put_str(src, "rule.a", "allow");
+
+    g_assert(qdict_crumple(src, &error) == NULL);
+    g_assert(error != NULL);
+    error_free(error);
+    error = NULL;
+    QDECREF(src);
+
+    src = qdict_new();
+    /* The input should be flat, ie no dicts or lists */
+    qdict_put(src, "rule.a", qdict_new());
+    qdict_put_str(src, "rule.b", "allow");
+
+    g_assert(qdict_crumple(src, &error) == NULL);
+    g_assert(error != NULL);
+    error_free(error);
+    error = NULL;
+    QDECREF(src);
+
+    src = qdict_new();
+    /* List indexes must not have gaps */
+    qdict_put_str(src, "rule.0", "deny");
+    qdict_put_str(src, "rule.3", "allow");
+
+    g_assert(qdict_crumple(src, &error) == NULL);
+    g_assert(error != NULL);
+    error_free(error);
+    error = NULL;
+    QDECREF(src);
+
+    src = qdict_new();
+    /* List indexes must be in %zu format */
+    qdict_put_str(src, "rule.0", "deny");
+    qdict_put_str(src, "rule.+1", "allow");
+
+    g_assert(qdict_crumple(src, &error) == NULL);
+    g_assert(error != NULL);
+    error_free(error);
+    error = NULL;
+    QDECREF(src);
+}
+
 /*
  * Errors test-cases
  */
@@ -605,8 +733,8 @@ static void qdict_put_exists_test(void)
     const char *key = "exists";
     QDict *tests_dict = qdict_new();
 
-    qdict_put(tests_dict, key, qint_from_int(1));
-    qdict_put(tests_dict, key, qint_from_int(2));
+    qdict_put_int(tests_dict, key, 1);
+    qdict_put_int(tests_dict, key, 2);
 
     value = qdict_get_int(tests_dict, key);
     g_assert(value == 2);
@@ -742,6 +870,13 @@ int main(int argc, char **argv)
     g_test_add_func("/errors/put_exists", qdict_put_exists_test);
     g_test_add_func("/errors/get_not_exists", qdict_get_not_exists_test);
 
+    g_test_add_func("/public/crumple/recursive",
+                    qdict_crumple_test_recursive);
+    g_test_add_func("/public/crumple/empty",
+                    qdict_crumple_test_empty);
+    g_test_add_func("/public/crumple/bad_inputs",
+                    qdict_crumple_test_bad_inputs);
+
     /* The Big one */
     if (g_test_slow()) {
         g_test_add_func("/stress/test", qdict_stress_test);