/* test commands that involve both input parameters and return values */ static void test_dispatch_cmd_io(void) { QDict *req = qdict_new(); QDict *args = qdict_new(); QDict *args3 = qdict_new(); QDict *ud1a = qdict_new(); QDict *ud1b = qdict_new(); QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef; QDict *ret_dict_dict2, *ret_dict_dict2_userdef; QNum *ret3; int64_t val; qdict_put_int(ud1a, "integer", 42); qdict_put_str(ud1a, "string", "hello"); qdict_put_int(ud1b, "integer", 422); qdict_put_str(ud1b, "string", "hello2"); qdict_put(args, "ud1a", ud1a); qdict_put(args, "ud1b", ud1b); qdict_put(req, "arguments", args); qdict_put_str(req, "execute", "user_def_cmd2"); ret = qobject_to(QDict, test_qmp_dispatch(req)); assert(!strcmp(qdict_get_str(ret, "string0"), "blah1")); ret_dict = qdict_get_qdict(ret, "dict1"); assert(!strcmp(qdict_get_str(ret_dict, "string1"), "blah2")); ret_dict_dict = qdict_get_qdict(ret_dict, "dict2"); ret_dict_dict_userdef = qdict_get_qdict(ret_dict_dict, "userdef"); assert(qdict_get_int(ret_dict_dict_userdef, "integer") == 42); assert(!strcmp(qdict_get_str(ret_dict_dict_userdef, "string"), "hello")); assert(!strcmp(qdict_get_str(ret_dict_dict, "string"), "blah3")); ret_dict_dict2 = qdict_get_qdict(ret_dict, "dict3"); ret_dict_dict2_userdef = qdict_get_qdict(ret_dict_dict2, "userdef"); assert(qdict_get_int(ret_dict_dict2_userdef, "integer") == 422); assert(!strcmp(qdict_get_str(ret_dict_dict2_userdef, "string"), "hello2")); assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4")); qobject_unref(ret); qdict_put_int(args3, "a", 66); qdict_put(req, "arguments", args3); qdict_put_str(req, "execute", "guest-get-time"); ret3 = qobject_to(QNum, test_qmp_dispatch(req)); g_assert(qnum_get_try_int(ret3, &val)); g_assert_cmpint(val, ==, 66); qobject_unref(ret3); qobject_unref(req); }
/* test commands that return an error due to invalid parameters */ static void test_dispatch_cmd_failure(void) { QDict *req = qdict_new(); QDict *args = qdict_new(); QDict *resp; qdict_put_str(req, "execute", "user_def_cmd2"); resp = qmp_dispatch(&qmp_commands, QOBJECT(req), false); assert(resp != NULL); assert(qdict_haskey(resp, "error")); qobject_unref(resp); qobject_unref(req); /* check that with extra arguments it throws an error */ req = qdict_new(); qdict_put_int(args, "a", 66); qdict_put(req, "arguments", args); qdict_put_str(req, "execute", "user_def_cmd"); resp = qmp_dispatch(&qmp_commands, QOBJECT(req), false); assert(resp != NULL); assert(qdict_haskey(resp, "error")); qobject_unref(resp); qobject_unref(req); }
/* test commands that involve both input parameters and return values */ static void test_dispatch_cmd_io(void) { QDict *req = qdict_new(); QDict *args = qdict_new(); QDict *args3 = qdict_new(); QDict *ud1a = qdict_new(); QDict *ud1b = qdict_new(); QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef; QDict *ret_dict_dict2, *ret_dict_dict2_userdef; QInt *ret3; qdict_put_int(ud1a, "integer", 42); qdict_put_str(ud1a, "string", "hello"); qdict_put_int(ud1b, "integer", 422); qdict_put_str(ud1b, "string", "hello2"); qdict_put(args, "ud1a", ud1a); qdict_put(args, "ud1b", ud1b); qdict_put(req, "arguments", args); qdict_put_str(req, "execute", "user_def_cmd2"); ret = qobject_to_qdict(test_qmp_dispatch(req)); assert(!strcmp(qdict_get_str(ret, "string0"), "blah1")); ret_dict = qdict_get_qdict(ret, "dict1"); assert(!strcmp(qdict_get_str(ret_dict, "string1"), "blah2")); ret_dict_dict = qdict_get_qdict(ret_dict, "dict2"); ret_dict_dict_userdef = qdict_get_qdict(ret_dict_dict, "userdef"); assert(qdict_get_int(ret_dict_dict_userdef, "integer") == 42); assert(!strcmp(qdict_get_str(ret_dict_dict_userdef, "string"), "hello")); assert(!strcmp(qdict_get_str(ret_dict_dict, "string"), "blah3")); ret_dict_dict2 = qdict_get_qdict(ret_dict, "dict3"); ret_dict_dict2_userdef = qdict_get_qdict(ret_dict_dict2, "userdef"); assert(qdict_get_int(ret_dict_dict2_userdef, "integer") == 422); assert(!strcmp(qdict_get_str(ret_dict_dict2_userdef, "string"), "hello2")); assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4")); QDECREF(ret); qdict_put_int(args3, "a", 66); qdict_put(req, "arguments", args3); qdict_put_str(req, "execute", "guest-get-time"); ret3 = qobject_to_qint(test_qmp_dispatch(req)); assert(qint_get_int(ret3) == 66); QDECREF(ret3); QDECREF(req); }
static QObject *make_qobject(void) { QDict *qdict = qdict_new(); QList *list = qlist_new(); qdict_put_int(qdict, "foo", 42); qdict_put_str(qdict, "bar", "hello world"); qdict_put_null(qdict, "baz"); qlist_append_int(list, 43); qlist_append_int(list, 44); qlist_append_bool(list, true); qdict_put(qdict, "bee", list); return QOBJECT(qdict); }
static void qobject_is_equal_dict_test(void) { Error *local_err = NULL; QDict *dict_0, *dict_1, *dict_cloned; QDict *dict_different_key, *dict_different_value, *dict_different_null_key; QDict *dict_longer, *dict_shorter, *dict_nested; QDict *dict_crumpled; dict_0 = qdict_new(); dict_1 = qdict_new(); dict_different_key = qdict_new(); dict_different_value = qdict_new(); dict_different_null_key = qdict_new(); dict_longer = qdict_new(); dict_shorter = qdict_new(); dict_nested = qdict_new(); qdict_put_int(dict_0, "f.o", 1); qdict_put_int(dict_0, "bar", 2); qdict_put_int(dict_0, "baz", 3); qdict_put_null(dict_0, "null"); qdict_put_int(dict_1, "f.o", 1); qdict_put_int(dict_1, "bar", 2); qdict_put_int(dict_1, "baz", 3); qdict_put_null(dict_1, "null"); qdict_put_int(dict_different_key, "F.o", 1); qdict_put_int(dict_different_key, "bar", 2); qdict_put_int(dict_different_key, "baz", 3); qdict_put_null(dict_different_key, "null"); qdict_put_int(dict_different_value, "f.o", 42); qdict_put_int(dict_different_value, "bar", 2); qdict_put_int(dict_different_value, "baz", 3); qdict_put_null(dict_different_value, "null"); qdict_put_int(dict_different_null_key, "f.o", 1); qdict_put_int(dict_different_null_key, "bar", 2); qdict_put_int(dict_different_null_key, "baz", 3); qdict_put_null(dict_different_null_key, "none"); qdict_put_int(dict_longer, "f.o", 1); qdict_put_int(dict_longer, "bar", 2); qdict_put_int(dict_longer, "baz", 3); qdict_put_int(dict_longer, "xyz", 4); qdict_put_null(dict_longer, "null"); qdict_put_int(dict_shorter, "f.o", 1); qdict_put_int(dict_shorter, "bar", 2); qdict_put_int(dict_shorter, "baz", 3); qdict_put(dict_nested, "f", qdict_new()); qdict_put_int(qdict_get_qdict(dict_nested, "f"), "o", 1); qdict_put_int(dict_nested, "bar", 2); qdict_put_int(dict_nested, "baz", 3); qdict_put_null(dict_nested, "null"); dict_cloned = qdict_clone_shallow(dict_0); check_equal(dict_0, dict_1, dict_cloned); check_unequal(dict_0, dict_different_key, dict_different_value, dict_different_null_key, dict_longer, dict_shorter, dict_nested); dict_crumpled = qobject_to(QDict, qdict_crumple(dict_1, &local_err)); g_assert(!local_err); check_equal(dict_crumpled, dict_nested); qdict_flatten(dict_nested); check_equal(dict_0, dict_nested); /* Containing an NaN value will make this dict compare unequal to * itself */ qdict_put(dict_0, "NaN", qnum_from_double(NAN)); g_assert(qobject_is_equal(QOBJECT(dict_0), QOBJECT(dict_0)) == false); free_all(dict_0, dict_1, dict_cloned, dict_different_key, dict_different_value, dict_different_null_key, dict_longer, dict_shorter, dict_nested, dict_crumpled); }
static void qdict_rename_keys_test(void) { QDict *dict = qdict_new(); QDict *copy; QDictRenames *renames; Error *local_err = NULL; qdict_put_str(dict, "abc", "foo"); qdict_put_str(dict, "abcdef", "bar"); qdict_put_int(dict, "number", 42); qdict_put_bool(dict, "flag", true); qdict_put_null(dict, "nothing"); /* Empty rename list */ renames = (QDictRenames[]) { { NULL, "this can be anything" } }; copy = qdict_clone_shallow(dict); qdict_rename_keys(copy, renames, &error_abort); g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo"); g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar"); g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42); g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true); g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL); g_assert_cmpint(qdict_count_entries(copy), ==, 5); qobject_unref(copy); /* Simple rename of all entries */ renames = (QDictRenames[]) { { "abc", "str1" }, { "abcdef", "str2" }, { "number", "int" }, { "flag", "bool" }, { "nothing", "null" }, { NULL , NULL } }; copy = qdict_clone_shallow(dict); qdict_rename_keys(copy, renames, &error_abort); g_assert(!qdict_haskey(copy, "abc")); g_assert(!qdict_haskey(copy, "abcdef")); g_assert(!qdict_haskey(copy, "number")); g_assert(!qdict_haskey(copy, "flag")); g_assert(!qdict_haskey(copy, "nothing")); g_assert_cmpstr(qdict_get_str(copy, "str1"), ==, "foo"); g_assert_cmpstr(qdict_get_str(copy, "str2"), ==, "bar"); g_assert_cmpint(qdict_get_int(copy, "int"), ==, 42); g_assert_cmpint(qdict_get_bool(copy, "bool"), ==, true); g_assert(qobject_type(qdict_get(copy, "null")) == QTYPE_QNULL); g_assert_cmpint(qdict_count_entries(copy), ==, 5); qobject_unref(copy); /* Renames are processed top to bottom */ renames = (QDictRenames[]) { { "abc", "tmp" }, { "abcdef", "abc" }, { "number", "abcdef" }, { "flag", "number" }, { "nothing", "flag" }, { "tmp", "nothing" }, { NULL , NULL } }; copy = qdict_clone_shallow(dict); qdict_rename_keys(copy, renames, &error_abort); g_assert_cmpstr(qdict_get_str(copy, "nothing"), ==, "foo"); g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "bar"); g_assert_cmpint(qdict_get_int(copy, "abcdef"), ==, 42); g_assert_cmpint(qdict_get_bool(copy, "number"), ==, true); g_assert(qobject_type(qdict_get(copy, "flag")) == QTYPE_QNULL); g_assert(!qdict_haskey(copy, "tmp")); g_assert_cmpint(qdict_count_entries(copy), ==, 5); qobject_unref(copy); /* Conflicting rename */ renames = (QDictRenames[]) { { "abcdef", "abc" }, { NULL , NULL } }; copy = qdict_clone_shallow(dict); qdict_rename_keys(copy, renames, &local_err); g_assert(local_err != NULL); error_free(local_err); local_err = NULL; g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo"); g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar"); g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42); g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true); g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL); g_assert_cmpint(qdict_count_entries(copy), ==, 5); qobject_unref(copy); /* Renames in an empty dict */ renames = (QDictRenames[]) { { "abcdef", "abc" }, { NULL , NULL } }; qobject_unref(dict); dict = qdict_new(); qdict_rename_keys(dict, renames, &error_abort); g_assert(qdict_first(dict) == NULL); qobject_unref(dict); }
static void qdict_flatten_test(void) { QList *e_1 = qlist_new(); QList *e = qlist_new(); QDict *e_1_2 = qdict_new(); QDict *f = qdict_new(); QList *y = qlist_new(); QDict *z = qdict_new(); QDict *root = qdict_new(); /* * Test the flattening of * * { * "e": [ * 42, * [ * 23, * 66, * { * "a": 0, * "b": 1 * } * ] * ], * "f": { * "c": 2, * "d": 3, * }, * "g": 4, * "y": [{}], * "z": {"a": []} * } * * to * * { * "e.0": 42, * "e.1.0": 23, * "e.1.1": 66, * "e.1.2.a": 0, * "e.1.2.b": 1, * "f.c": 2, * "f.d": 3, * "g": 4, * "y.0": {}, * "z.a": [] * } */ qdict_put_int(e_1_2, "a", 0); qdict_put_int(e_1_2, "b", 1); qlist_append_int(e_1, 23); qlist_append_int(e_1, 66); qlist_append(e_1, e_1_2); qlist_append_int(e, 42); qlist_append(e, e_1); qdict_put_int(f, "c", 2); qdict_put_int(f, "d", 3); qlist_append(y, qdict_new()); qdict_put(z, "a", qlist_new()); qdict_put(root, "e", e); qdict_put(root, "f", f); qdict_put_int(root, "g", 4); qdict_put(root, "y", y); qdict_put(root, "z", z); qdict_flatten(root); g_assert(qdict_get_int(root, "e.0") == 42); g_assert(qdict_get_int(root, "e.1.0") == 23); g_assert(qdict_get_int(root, "e.1.1") == 66); g_assert(qdict_get_int(root, "e.1.2.a") == 0); g_assert(qdict_get_int(root, "e.1.2.b") == 1); g_assert(qdict_get_int(root, "f.c") == 2); g_assert(qdict_get_int(root, "f.d") == 3); g_assert(qdict_get_int(root, "g") == 4); g_assert(!qdict_size(qdict_get_qdict(root, "y.0"))); g_assert(qlist_empty(qdict_get_qlist(root, "z.a"))); g_assert(qdict_size(root) == 10); qobject_unref(root); }
static void qdict_join_test(void) { QDict *dict1, *dict2; bool overwrite = false; int i; dict1 = qdict_new(); dict2 = qdict_new(); /* Test everything once without overwrite and once with */ do { /* Test empty dicts */ qdict_join(dict1, dict2, overwrite); 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_int(dict2, "foo", 42); for (i = 0; i < 2; i++) { qdict_join(dict1, dict2, overwrite); g_assert(qdict_size(dict1) == 1); g_assert(qdict_size(dict2) == 0); g_assert(qdict_get_int(dict1, "foo") == 42); } /* Test non-empty source and destination without conflict */ qdict_put_int(dict2, "bar", 23); qdict_join(dict1, dict2, overwrite); g_assert(qdict_size(dict1) == 2); g_assert(qdict_size(dict2) == 0); g_assert(qdict_get_int(dict1, "foo") == 42); g_assert(qdict_get_int(dict1, "bar") == 23); /* Test conflict */ 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, "bar") == 23); if (!overwrite) { g_assert(qdict_get_int(dict2, "foo") == 84); } /* Check the references */ g_assert(qdict_get(dict1, "foo")->base.refcnt == 1); g_assert(qdict_get(dict1, "bar")->base.refcnt == 1); if (!overwrite) { g_assert(qdict_get(dict2, "foo")->base.refcnt == 1); } /* Clean up */ qdict_del(dict1, "foo"); qdict_del(dict1, "bar"); if (!overwrite) { qdict_del(dict2, "foo"); } } while (overwrite ^= true); qobject_unref(dict1); qobject_unref(dict2); }
static void qdict_array_entries_test(void) { QDict *dict = qdict_new(); g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 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_int(dict, "foo.1", 0); g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL); qdict_put_int(dict, "foo.0", 0); g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 2); qdict_put_int(dict, "foo.bar", 0); g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL); qdict_del(dict, "foo.bar"); 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); qobject_unref(dict); dict = qdict_new(); qdict_put_int(dict, "1", 0); g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL); qdict_put_int(dict, "0", 0); g_assert_cmpint(qdict_array_entries(dict, ""), ==, 2); qdict_put_int(dict, "bar", 0); g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL); qdict_del(dict, "bar"); 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); qobject_unref(dict); }
static void qdict_array_split_test(void) { QDict *test_dict = qdict_new(); QDict *dict1, *dict2; QNum *int1; QList *test_list; /* * Test the split of * * { * "1.x": 0, * "4.y": 1, * "0.a": 42, * "o.o": 7, * "0.b": 23, * "2": 66 * } * * to * * [ * { * "a": 42, * "b": 23 * }, * { * "x": 0 * }, * 66 * ] * * and * * { * "4.y": 1, * "o.o": 7 * } * * (remaining in the old QDict) * * This example is given in the comment of qdict_array_split(). */ 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); dict1 = qobject_to(QDict, qlist_pop(test_list)); dict2 = qobject_to(QDict, qlist_pop(test_list)); int1 = qobject_to(QNum, qlist_pop(test_list)); g_assert(dict1); g_assert(dict2); g_assert(int1); g_assert(qlist_empty(test_list)); qobject_unref(test_list); g_assert(qdict_get_int(dict1, "a") == 42); g_assert(qdict_get_int(dict1, "b") == 23); g_assert(qdict_size(dict1) == 2); qobject_unref(dict1); g_assert(qdict_get_int(dict2, "x") == 0); g_assert(qdict_size(dict2) == 1); qobject_unref(dict2); g_assert_cmpint(qnum_get_int(int1), ==, 66); qobject_unref(int1); g_assert(qdict_get_int(test_dict, "4.y") == 1); g_assert(qdict_get_int(test_dict, "o.o") == 7); g_assert(qdict_size(test_dict) == 2); qobject_unref(test_dict); /* * Test the split of * * { * "0": 42, * "1": 23, * "1.x": 84 * } * * to * * [ * 42 * ] * * and * * { * "1": 23, * "1.x": 84 * } * * That is, test whether splitting stops if there is both an entry with key * of "%u" and other entries with keys prefixed "%u." for the same index. */ test_dict = qdict_new(); 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); int1 = qobject_to(QNum, qlist_pop(test_list)); g_assert(int1); g_assert(qlist_empty(test_list)); qobject_unref(test_list); g_assert_cmpint(qnum_get_int(int1), ==, 42); qobject_unref(int1); g_assert(qdict_get_int(test_dict, "1") == 23); g_assert(qdict_get_int(test_dict, "1.x") == 84); g_assert(qdict_size(test_dict) == 2); qobject_unref(test_dict); }