static void qerror_set_data(QError *qerr, const char *fmt, va_list *va) { QObject *obj; obj = qobject_from_jsonv(fmt, va); if (!obj) { qerror_abort(qerr, "invalid format '%s'", fmt); } if (qobject_type(obj) != QTYPE_QDICT) { qerror_abort(qerr, "error format is not a QDict '%s'", fmt); } qerr->error = qobject_to_qdict(obj); obj = qdict_get(qerr->error, "class"); if (!obj) { qerror_abort(qerr, "missing 'class' key in '%s'", fmt); } if (qobject_type(obj) != QTYPE_QSTRING) { qerror_abort(qerr, "'class' key value should be a QString"); } obj = qdict_get(qerr->error, "data"); if (!obj) { qerror_abort(qerr, "missing 'data' key in '%s'", fmt); } if (qobject_type(obj) != QTYPE_QDICT) { qerror_abort(qerr, "'data' key value should be a QDICT"); } }
/* This function is hooked as final emit function, which can verify the correctness. */ static void event_test_emit(test_QAPIEvent event, QDict *d, Error **errp) { QObject *obj; QDict *t; int64_t s, ms; /* Verify that we have timestamp, then remove it to compare other fields */ obj = qdict_get(d, "timestamp"); g_assert(obj); t = qobject_to_qdict(obj); g_assert(t); obj = qdict_get(t, "seconds"); g_assert(obj && qobject_type(obj) == QTYPE_QINT); s = qint_get_int(qobject_to_qint(obj)); obj = qdict_get(t, "microseconds"); g_assert(obj && qobject_type(obj) == QTYPE_QINT); ms = qint_get_int(qobject_to_qint(obj)); if (s == -1) { g_assert(ms == -1); } else { g_assert(ms >= 0 && ms <= 999999); } g_assert(qdict_size(t) == 2); qdict_del(d, "timestamp"); g_assert(qdict_cmp_simple(d, test_event_data->expect)); }
static void qdict_get_not_exists_test(void) { QDict *tests_dict = qdict_new(); g_assert(qdict_get(tests_dict, "foo") == NULL); QDECREF(tests_dict); }
QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request, bool allow_oob) { Error *err = NULL; QDict *dict = qobject_to(QDict, request); QObject *ret, *id = dict ? qdict_get(dict, "id") : NULL; QDict *rsp; ret = do_qmp_dispatch(cmds, request, allow_oob, &err); if (err) { rsp = qmp_error_response(err); } else if (ret) { rsp = qdict_new(); qdict_put_obj(rsp, "return", ret); } else { /* Can only happen for commands with QCO_NO_SUCCESS_RESP */ rsp = NULL; } if (rsp && id) { qdict_put_obj(rsp, "id", qobject_ref(id)); } return rsp; }
static void add_pc_test_cases(void) { QDict *response, *minfo; QList *list; const QListEntry *p; QObject *qobj; QString *qstr; const char *mname, *path; PCTestData *data; qtest_start("-machine none"); response = qmp("{ 'execute': 'query-machines' }"); g_assert(response); list = qdict_get_qlist(response, "return"); g_assert(list); for (p = qlist_first(list); p; p = qlist_next(p)) { minfo = qobject_to_qdict(qlist_entry_obj(p)); g_assert(minfo); qobj = qdict_get(minfo, "name"); g_assert(qobj); qstr = qobject_to_qstring(qobj); g_assert(qstr); mname = qstring_get_str(qstr); if (!g_str_has_prefix(mname, "pc-")) { continue; } data = g_malloc(sizeof(PCTestData)); data->machine = mname; data->cpu_model = "Haswell"; /* 1.3+ theoretically */ data->sockets = 1; data->cores = 3; data->threads = 2; data->maxcpus = data->sockets * data->cores * data->threads * 2; if (g_str_has_suffix(mname, "-1.4") || (strcmp(mname, "pc-1.3") == 0) || (strcmp(mname, "pc-1.2") == 0) || (strcmp(mname, "pc-1.1") == 0) || (strcmp(mname, "pc-1.0") == 0) || (strcmp(mname, "pc-0.15") == 0) || (strcmp(mname, "pc-0.14") == 0) || (strcmp(mname, "pc-0.13") == 0) || (strcmp(mname, "pc-0.12") == 0) || (strcmp(mname, "pc-0.11") == 0) || (strcmp(mname, "pc-0.10") == 0)) { path = g_strdup_printf("cpu/%s/init/%ux%ux%u&maxcpus=%u", mname, data->sockets, data->cores, data->threads, data->maxcpus); qtest_add_data_func(path, data, test_pc_without_cpu_add); } else { path = g_strdup_printf("cpu/%s/add/%ux%ux%u&maxcpus=%u", mname, data->sockets, data->cores, data->threads, data->maxcpus); qtest_add_data_func(path, data, test_pc_with_cpu_add); } } qtest_end(); }
static const char *append_field(QDict *error, QString *outstr, const QErrorStringTable *entry, const char *start) { QObject *obj; QDict *qdict; QString *key_qs; const char *end, *key; if (*start != '%') parse_error(entry, '%'); start++; if (*start != '(') parse_error(entry, '('); start++; end = strchr(start, ')'); if (!end) parse_error(entry, ')'); key_qs = qstring_from_substr(start, 0, end - start - 1); key = qstring_get_str(key_qs); qdict = qobject_to_qdict(qdict_get(error, "data")); obj = qdict_get(qdict, key); if (!obj) { abort(); } switch (qobject_type(obj)) { case QTYPE_QSTRING: qstring_append(outstr, qdict_get_str(qdict, key)); break; case QTYPE_QINT: qstring_append_int(outstr, qdict_get_int(qdict, key)); break; default: abort(); } QDECREF(key_qs); return ++end; }
/** * qdict_get_try_bool(): Try to get a bool mapped by 'key' * * Return bool mapped by 'key', if it is not present in the * dictionary or if the stored object is not of QBool type * 'def_value' will be returned. */ int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value) { QObject *obj; obj = qdict_get(qdict, key); if (!obj || qobject_type(obj) != QTYPE_QBOOL) return def_value; return qbool_get_int(qobject_to_qbool(obj)); }
const char *qdict_get_try_str(const QDict *qdict, const char *key) { QObject *obj; obj = qdict_get(qdict, key); if (!obj || qobject_type(obj) != QTYPE_QSTRING) return NULL; return qstring_get_str(qobject_to_qstring(obj)); }
static const char *append_field(QString *outstr, const QError *qerror, const char *start) { QObject *obj; QDict *qdict; QString *key_qs; const char *end, *key; if (*start != '%') parse_error(qerror, '%'); start++; if (*start != '(') parse_error(qerror, '('); start++; end = strchr(start, ')'); if (!end) parse_error(qerror, ')'); key_qs = qstring_from_substr(start, 0, end - start - 1); key = qstring_get_str(key_qs); qdict = qobject_to_qdict(qdict_get(qerror->error, "data")); obj = qdict_get(qdict, key); if (!obj) { qerror_abort(qerror, "key '%s' not found in QDict", key); } switch (qobject_type(obj)) { case QTYPE_QSTRING: qstring_append(outstr, qdict_get_str(qdict, key)); break; case QTYPE_QINT: qstring_append_int(outstr, qdict_get_int(qdict, key)); break; default: qerror_abort(qerror, "invalid type '%c'", qobject_type(obj)); } QDECREF(key_qs); return ++end; }
int64_t qdict_get_try_int(const QDict *qdict, const char *key, int64_t err_value) { QObject *obj; obj = qdict_get(qdict, key); if (!obj || qobject_type(obj) != QTYPE_QINT) return err_value; return qint_get_int(qobject_to_qint(obj)); }
static QObject *qom_get(const char *path, const char *prop) { QDict *resp = qmp("{ 'execute': 'qom-get'," " 'arguments': { 'path': %s," " 'property': %s } }", path, prop); QObject *ret = qdict_get(resp, "return"); qobject_ref(ret); qobject_unref(resp); return ret; }
static QObject *qdict_get_obj(const QDict *qdict, const char *key, qtype_code type) { QObject *obj; obj = qdict_get(qdict, key); assert(obj != NULL); assert(qobject_type(obj) == type); return obj; }
/** * qdict_get_try_bool_or_int(): Try to get a bool or int mapped by 'key' * * Return bool or int mapped by 'key', if it is not present in the * dictionary or if the stored object is not of QBool or QInt type * 'def_value' will be returned. */ int qdict_get_try_bool_or_int(const QDict *qdict, const char *key, int def_value) { QObject *obj; obj = qdict_get(qdict, key); if (obj && qobject_type(obj) == QTYPE_QBOOL) { return qbool_get_int(qobject_to_qbool(obj)); } else if (obj && qobject_type(obj) == QTYPE_QINT) { return qint_get_int(qobject_to_qint(obj)); } return def_value; }
static void test_visitor_in_any(TestInputVisitorData *data, const void *unused) { QObject *res = NULL; Visitor *v; QInt *qint; QBool *qbool; QString *qstring; QDict *qdict; QObject *qobj; v = visitor_input_test_init(data, "-42"); visit_type_any(v, &res, NULL, &error_abort); qint = qobject_to_qint(res); g_assert(qint); g_assert_cmpint(qint_get_int(qint), ==, -42); qobject_decref(res); v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); visit_type_any(v, &res, NULL, &error_abort); qdict = qobject_to_qdict(res); g_assert(qdict && qdict_size(qdict) == 3); qobj = qdict_get(qdict, "integer"); g_assert(qobj); qint = qobject_to_qint(qobj); g_assert(qint); g_assert_cmpint(qint_get_int(qint), ==, -42); qobj = qdict_get(qdict, "boolean"); g_assert(qobj); qbool = qobject_to_qbool(qobj); g_assert(qbool); g_assert(qbool_get_bool(qbool) == true); qobj = qdict_get(qdict, "string"); g_assert(qobj); qstring = qobject_to_qstring(qobj); g_assert(qstring); g_assert_cmpstr(qstring_get_str(qstring), ==, "foo"); qobject_decref(res); }
static QObject *test_qmp_dispatch(QDict *req) { QDict *resp; QObject *ret; resp = qmp_dispatch(&qmp_commands, QOBJECT(req), false); assert(resp && !qdict_haskey(resp, "error")); ret = qdict_get(resp, "return"); assert(ret); qobject_ref(ret); qobject_unref(resp); return ret; }
double qdict_get_double(const QDict *qdict, const char *key) { QObject *obj = qdict_get(qdict, key); assert(obj); switch (qobject_type(obj)) { case QTYPE_QFLOAT: return qfloat_get_double(qobject_to_qfloat(obj)); case QTYPE_QINT: return qint_get_int(qobject_to_qint(obj)); default: assert(0); } }
static void migrate_print_status(Monitor *mon, const char *name, const QDict *status_dict) { QDict *qdict; qdict = qobject_to_qdict(qdict_get(status_dict, name)); monitor_printf(mon, "transferred %s: %" PRIu64 " kbytes\n", name, qdict_get_int(qdict, "transferred") >> 10); monitor_printf(mon, "remaining %s: %" PRIu64 " kbytes\n", name, qdict_get_int(qdict, "remaining") >> 10); monitor_printf(mon, "total %s: %" PRIu64 " kbytes\n", name, qdict_get_int(qdict, "total") >> 10); }
static QObject *test_qmp_dispatch(QDict *req) { QObject *resp_obj; QDict *resp; QObject *ret; resp_obj = qmp_dispatch(&qmp_commands, QOBJECT(req)); assert(resp_obj); resp = qobject_to_qdict(resp_obj); assert(resp && !qdict_haskey(resp, "error")); ret = qdict_get(resp, "return"); assert(ret); qobject_incref(ret); qobject_decref(resp_obj); return ret; }
/* Only compares bool, int, string */ static void qdict_cmp_do_simple(const char *key, QObject *obj1, void *opaque) { QObject *obj2; QDictCmpData d_new, *d = opaque; if (!d->result) { return; } obj2 = qdict_get(d->expect, key); if (!obj2) { d->result = false; return; } if (qobject_type(obj1) != qobject_type(obj2)) { d->result = false; return; } switch (qobject_type(obj1)) { case QTYPE_QBOOL: d->result = (qbool_get_bool(qobject_to_qbool(obj1)) == qbool_get_bool(qobject_to_qbool(obj2))); return; case QTYPE_QINT: d->result = (qint_get_int(qobject_to_qint(obj1)) == qint_get_int(qobject_to_qint(obj2))); return; case QTYPE_QSTRING: d->result = g_strcmp0(qstring_get_str(qobject_to_qstring(obj1)), qstring_get_str(qobject_to_qstring(obj2))) == 0; return; case QTYPE_QDICT: d_new.expect = qobject_to_qdict(obj2); d_new.result = true; qdict_iter(qobject_to_qdict(obj1), qdict_cmp_do_simple, &d_new); d->result = d_new.result; return; default: abort(); } }
static void qdict_get_test(void) { QInt *qi; QObject *obj; const int value = -42; const char *key = "test"; QDict *tests_dict = qdict_new(); qdict_put(tests_dict, key, qint_from_int(value)); obj = qdict_get(tests_dict, key); g_assert(obj != NULL); qi = qobject_to_qint(obj); g_assert(qint_get_int(qi) == value); QDECREF(tests_dict); }
static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name) { const QObject *qobj; if (qiv->nb_stack == 0) { qobj = qiv->obj; } else { qobj = qiv->stack[qiv->nb_stack - 1].obj; } if (name && qobject_type(qobj) == QTYPE_QDICT) { return qdict_get(qobject_to_qdict(qobj), name); } else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) { return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); } return qobj; }
static QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name, bool consume) { QObject *qobj = qiv->stack[qiv->nb_stack - 1].obj; if (qobj) { if (name && qobject_type(qobj) == QTYPE_QDICT) { if (qiv->stack[qiv->nb_stack - 1].h && consume) { g_hash_table_remove(qiv->stack[qiv->nb_stack - 1].h, name); } return qdict_get(qobject_to_qdict(qobj), name); } else if (qiv->stack[qiv->nb_stack - 1].entry) { return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); } } return qobj; }
static void qobject_from_qlit_test(void) { QObject *obj, *qobj = qobject_from_qlit(&qlit); QDict *qdict; QList *bee; qdict = qobject_to(QDict, qobj); g_assert_cmpint(qdict_get_int(qdict, "foo"), ==, 42); g_assert_cmpstr(qdict_get_str(qdict, "bar"), ==, "hello world"); g_assert(qobject_type(qdict_get(qdict, "baz")) == QTYPE_QNULL); bee = qdict_get_qlist(qdict, "bee"); obj = qlist_pop(bee); g_assert_cmpint(qnum_get_int(qobject_to(QNum, obj)), ==, 43); qobject_unref(obj); obj = qlist_pop(bee); g_assert_cmpint(qnum_get_int(qobject_to(QNum, obj)), ==, 44); qobject_unref(obj); obj = qlist_pop(bee); g_assert(qbool_get_bool(qobject_to(QBool, obj))); qobject_unref(obj); qobject_unref(qobj); }
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); }
* Else, fail because we have conflicting needs on how to map * @key_in_cur. * In any case, take over the reference to @value, i.e. if the caller * wants to hold on to a reference, it needs to qobject_ref(). * Use @key up to @key_cursor to identify the key in error messages. * On success, return the mapped value. * On failure, store an error through @errp and return NULL. */ static QObject *keyval_parse_put(QDict *cur, const char *key_in_cur, QString *value, const char *key, const char *key_cursor, Error **errp) { QObject *old, *new; old = qdict_get(cur, key_in_cur); if (old) { if (qobject_type(old) != (value ? QTYPE_QSTRING : QTYPE_QDICT)) { error_setg(errp, "Parameters '%.*s.*' used inconsistently", (int)(key_cursor - key), key); qobject_unref(value); return NULL; } if (!value) { return old; /* already QDict, do nothing */ } new = QOBJECT(value); /* replacement */ } else { new = value ? QOBJECT(value) : QOBJECT(qdict_new()); } qdict_put_obj(cur, key_in_cur, new);
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(dict2, "foo", qint_from_int(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(dict2, "bar", qint_from_int(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(dict2, "foo", qint_from_int(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")->refcnt == 1); g_assert(qdict_get(dict1, "bar")->refcnt == 1); if (!overwrite) { g_assert(qdict_get(dict2, "foo")->refcnt == 1); } /* Clean up */ qdict_del(dict1, "foo"); qdict_del(dict1, "bar"); if (!overwrite) { qdict_del(dict2, "foo"); } } while (overwrite ^= true); QDECREF(dict1); QDECREF(dict2); }
static void qdict_crumple_test_recursive(void) { QDict *src, *dst, *rule, *vnc, *acl, *listen; QObject *child, *res; QList *rules; src = qdict_new(); qdict_put(src, "vnc.listen.addr", qstring_from_str("127.0.0.1")); qdict_put(src, "vnc.listen.port", qstring_from_str("5901")); qdict_put(src, "vnc.acl.rules.0.match", qstring_from_str("fred")); qdict_put(src, "vnc.acl.rules.0.policy", qstring_from_str("allow")); qdict_put(src, "vnc.acl.rules.1.match", qstring_from_str("bob")); qdict_put(src, "vnc.acl.rules.1.policy", qstring_from_str("deny")); qdict_put(src, "vnc.acl.default", qstring_from_str("deny")); qdict_put(src, "vnc.acl..name", qstring_from_str("acl0")); qdict_put(src, "vnc.acl.rule..name", qstring_from_str("acl0")); res = qdict_crumple(src, &error_abort); g_assert_cmpint(qobject_type(res), ==, QTYPE_QDICT); dst = qobject_to_qdict(res); g_assert_cmpint(qdict_size(dst), ==, 1); child = qdict_get(dst, "vnc"); g_assert_cmpint(qobject_type(child), ==, QTYPE_QDICT); vnc = qobject_to_qdict(child); child = qdict_get(vnc, "listen"); g_assert_cmpint(qobject_type(child), ==, QTYPE_QDICT); listen = qobject_to_qdict(child); g_assert_cmpstr("127.0.0.1", ==, qdict_get_str(listen, "addr")); g_assert_cmpstr("5901", ==, qdict_get_str(listen, "port")); child = qdict_get(vnc, "acl"); g_assert_cmpint(qobject_type(child), ==, QTYPE_QDICT); acl = qobject_to_qdict(child); child = qdict_get(acl, "rules"); g_assert_cmpint(qobject_type(child), ==, QTYPE_QLIST); rules = qobject_to_qlist(child); g_assert_cmpint(qlist_size(rules), ==, 2); rule = qobject_to_qdict(qlist_pop(rules)); 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_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")); child = qdict_get(vnc, "acl"); g_assert_cmpint(qobject_type(child), ==, QTYPE_QDICT); acl = qdict_get_qdict(vnc, "acl"); g_assert_cmpstr("acl0", ==, qdict_get_str(acl, "rule.name")); QDECREF(src); QDECREF(dst); }