diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.include | 7 | ||||
-rw-r--r-- | tests/check-qjson.c | 150 | ||||
-rw-r--r-- | tests/check-qlit.c | 74 | ||||
-rw-r--r-- | tests/check-qom-proplist.c | 14 | ||||
-rw-r--r-- | tests/io-channel-helpers.c | 102 | ||||
-rw-r--r-- | tests/qapi-schema/alternate-conflict-bool-string.err | 1 | ||||
-rw-r--r-- | tests/qapi-schema/alternate-conflict-bool-string.exit | 1 | ||||
-rw-r--r-- | tests/qapi-schema/alternate-conflict-bool-string.json | 4 | ||||
-rw-r--r-- | tests/qapi-schema/alternate-conflict-bool-string.out | 0 | ||||
-rw-r--r-- | tests/qapi-schema/alternate-conflict-num-string.err | 1 | ||||
-rw-r--r-- | tests/qapi-schema/alternate-conflict-num-string.exit | 1 | ||||
-rw-r--r-- | tests/qapi-schema/alternate-conflict-num-string.json | 4 | ||||
-rw-r--r-- | tests/qapi-schema/alternate-conflict-num-string.out | 0 | ||||
-rw-r--r-- | tests/qmp-test.c | 181 | ||||
-rw-r--r-- | tests/test-io-channel-tls.c | 6 | ||||
-rw-r--r-- | tests/test-qapi-util.c | 18 | ||||
-rw-r--r-- | tests/test-qobject-input-visitor.c | 8 | ||||
-rw-r--r-- | tests/test-qobject-output-visitor.c | 2 | ||||
-rw-r--r-- | tests/test-string-input-visitor.c | 4 | ||||
-rw-r--r-- | tests/test-string-output-visitor.c | 4 |
20 files changed, 335 insertions, 247 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include index f08b7418f0..fae5715e9c 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -43,6 +43,8 @@ check-unit-y += tests/check-qnull$(EXESUF) gcov-files-check-qnull-y = qobject/qnull.c check-unit-y += tests/check-qjson$(EXESUF) gcov-files-check-qjson-y = qobject/qjson.c +check-unit-y += tests/check-qlit$(EXESUF) +gcov-files-check-qlit-y = qobject/qlit.c check-unit-y += tests/test-qobject-output-visitor$(EXESUF) gcov-files-test-qobject-output-visitor-y = qapi/qobject-output-visitor.c check-unit-y += tests/test-clone-visitor$(EXESUF) @@ -376,6 +378,8 @@ qapi-schema += alternate-conflict-dict.json qapi-schema += alternate-conflict-enum-bool.json qapi-schema += alternate-conflict-enum-int.json qapi-schema += alternate-conflict-string.json +qapi-schema += alternate-conflict-bool-string.json +qapi-schema += alternate-conflict-num-string.json qapi-schema += alternate-empty.json qapi-schema += alternate-nested.json qapi-schema += alternate-unknown.json @@ -539,7 +543,7 @@ GENERATED_FILES += tests/test-qapi-types.h tests/test-qapi-visit.h \ test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \ tests/check-qlist.o tests/check-qnull.o \ - tests/check-qjson.o \ + tests/check-qjson.o tests/check-qlit.o \ tests/test-coroutine.o tests/test-string-output-visitor.o \ tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \ tests/test-clone-visitor.o \ @@ -573,6 +577,7 @@ tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y) tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y) tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y) tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y) +tests/check-qlit$(EXESUF): tests/check-qlit.o $(test-util-obj-y) tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y) tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y) diff --git a/tests/check-qjson.c b/tests/check-qjson.c index a3a97b0d99..59227934ce 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -16,6 +16,7 @@ #include "qapi/error.h" #include "qapi/qmp/types.h" #include "qapi/qmp/qjson.h" +#include "qapi/qmp/qlit.h" #include "qemu-common.h" static void escaped_string(void) @@ -1059,123 +1060,28 @@ static void keyword_literal(void) QDECREF(null); } -typedef struct LiteralQDictEntry LiteralQDictEntry; -typedef struct LiteralQObject LiteralQObject; - -struct LiteralQObject -{ - int type; - union { - int64_t qnum; - const char *qstr; - LiteralQDictEntry *qdict; - LiteralQObject *qlist; - } value; -}; - -struct LiteralQDictEntry -{ - const char *key; - LiteralQObject value; -}; - -#define QLIT_QNUM(val) (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)} -#define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)} -#define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)} -#define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)} - -typedef struct QListCompareHelper -{ - int index; - LiteralQObject *objs; - int result; -} QListCompareHelper; - -static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs); - -static void compare_helper(QObject *obj, void *opaque) -{ - QListCompareHelper *helper = opaque; - - if (helper->result == 0) { - return; - } - - if (helper->objs[helper->index].type == QTYPE_NONE) { - helper->result = 0; - return; - } - - helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj); -} - -static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs) -{ - int64_t val; - - if (!rhs || lhs->type != qobject_type(rhs)) { - return 0; - } - - switch (lhs->type) { - case QTYPE_QNUM: - g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val)); - return lhs->value.qnum == val; - case QTYPE_QSTRING: - return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0); - case QTYPE_QDICT: { - int i; - - for (i = 0; lhs->value.qdict[i].key; i++) { - QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key); - - if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) { - return 0; - } - } - - return 1; - } - case QTYPE_QLIST: { - QListCompareHelper helper; - - helper.index = 0; - helper.objs = lhs->value.qlist; - helper.result = 1; - - qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper); - - return helper.result; - } - default: - break; - } - - return 0; -} - static void simple_dict(void) { int i; struct { const char *encoded; - LiteralQObject decoded; + QLitObject decoded; } test_cases[] = { { .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}", - .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QDICT(((QLitDictEntry[]){ { "foo", QLIT_QNUM(42) }, { "bar", QLIT_QSTR("hello world") }, { } })), }, { .encoded = "{}", - .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QDICT(((QLitDictEntry[]){ { } })), }, { .encoded = "{\"foo\": 43}", - .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QDICT(((QLitDictEntry[]){ { "foo", QLIT_QNUM(43) }, { } })), @@ -1188,13 +1094,13 @@ static void simple_dict(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); qobject_decref(obj); QDECREF(str); } @@ -1257,11 +1163,11 @@ static void simple_list(void) int i; struct { const char *encoded; - LiteralQObject decoded; + QLitObject decoded; } test_cases[] = { { .encoded = "[43,42]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), QLIT_QNUM(42), { } @@ -1269,21 +1175,21 @@ static void simple_list(void) }, { .encoded = "[43]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), { } })), }, { .encoded = "[]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ { } })), }, { .encoded = "[{}]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ - QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ + QLIT_QDICT(((QLitDictEntry[]){ {}, })), {}, @@ -1297,13 +1203,13 @@ static void simple_list(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); qobject_decref(obj); QDECREF(str); } @@ -1314,11 +1220,11 @@ static void simple_whitespace(void) int i; struct { const char *encoded; - LiteralQObject decoded; + QLitObject decoded; } test_cases[] = { { .encoded = " [ 43 , 42 ]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), QLIT_QNUM(42), { } @@ -1326,12 +1232,12 @@ static void simple_whitespace(void) }, { .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), - QLIT_QDICT(((LiteralQDictEntry[]){ + QLIT_QDICT(((QLitDictEntry[]){ { "h", QLIT_QSTR("b") }, { }})), - QLIT_QLIST(((LiteralQObject[]){ + QLIT_QLIST(((QLitObject[]){ { }})), QLIT_QNUM(42), { } @@ -1339,13 +1245,13 @@ static void simple_whitespace(void) }, { .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), - QLIT_QDICT(((LiteralQDictEntry[]){ + QLIT_QDICT(((QLitDictEntry[]){ { "h", QLIT_QSTR("b") }, { "a", QLIT_QNUM(32) }, { }})), - QLIT_QLIST(((LiteralQObject[]){ + QLIT_QLIST(((QLitObject[]){ { }})), QLIT_QNUM(42), { } @@ -1359,13 +1265,13 @@ static void simple_whitespace(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); qobject_decref(obj); QDECREF(str); @@ -1376,10 +1282,10 @@ static void simple_varargs(void) { QObject *embedded_obj; QObject *obj; - LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){ + QLitObject decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(1), QLIT_QNUM(2), - QLIT_QLIST(((LiteralQObject[]){ + QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(32), QLIT_QNUM(42), {}})), @@ -1389,7 +1295,7 @@ static void simple_varargs(void) g_assert(embedded_obj != NULL); obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj); - g_assert(compare_litqobj_to_qobj(&decoded, obj) == 1); + g_assert(qlit_equal_qobject(&decoded, obj)); qobject_decref(obj); } diff --git a/tests/check-qlit.c b/tests/check-qlit.c new file mode 100644 index 0000000000..c59ec1ab88 --- /dev/null +++ b/tests/check-qlit.c @@ -0,0 +1,74 @@ +/* + * QLit unit-tests. + * + * Copyright (C) 2017 Red Hat Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "qapi/qmp/qbool.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qlit.h" +#include "qapi/qmp/qnum.h" +#include "qapi/qmp/qstring.h" + +static QLitObject qlit = QLIT_QDICT(((QLitDictEntry[]) { + { "foo", QLIT_QNUM(42) }, + { "bar", QLIT_QSTR("hello world") }, + { "baz", QLIT_QNULL }, + { "bee", QLIT_QLIST(((QLitObject[]) { + QLIT_QNUM(43), + QLIT_QNUM(44), + QLIT_QBOOL(true), + { }, + }))}, + { }, +})); + +static QLitObject qlit_foo = QLIT_QDICT(((QLitDictEntry[]) { + { "foo", QLIT_QNUM(42) }, + { }, +})); + +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 qlit_equal_qobject_test(void) +{ + QObject *qobj = make_qobject(); + + g_assert(qlit_equal_qobject(&qlit, qobj)); + + g_assert(!qlit_equal_qobject(&qlit_foo, qobj)); + + qdict_put(qobject_to_qdict(qobj), "bee", qlist_new()); + g_assert(!qlit_equal_qobject(&qlit, qobj)); + + qobject_decref(qobj); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/qlit/equal_qobject", qlit_equal_qobject_test); + + return g_test_run(); +} diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index c51e6e734d..92898e1520 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -46,11 +46,13 @@ enum DummyAnimal { DUMMY_LAST, }; -static const char *const dummy_animal_map[DUMMY_LAST + 1] = { - [DUMMY_FROG] = "frog", - [DUMMY_ALLIGATOR] = "alligator", - [DUMMY_PLATYPUS] = "platypus", - [DUMMY_LAST] = NULL, +const QEnumLookup dummy_animal_map = { + .array = (const char *const[]) { + [DUMMY_FROG] = "frog", + [DUMMY_ALLIGATOR] = "alligator", + [DUMMY_PLATYPUS] = "platypus", + }, + .size = DUMMY_LAST }; struct DummyObject { @@ -142,7 +144,7 @@ static void dummy_class_init(ObjectClass *cls, void *data) NULL); object_class_property_add_enum(cls, "av", "DummyAnimal", - dummy_animal_map, + &dummy_animal_map, dummy_get_av, dummy_set_av, NULL); diff --git a/tests/io-channel-helpers.c b/tests/io-channel-helpers.c index 05e5579cf8..5430e1389d 100644 --- a/tests/io-channel-helpers.c +++ b/tests/io-channel-helpers.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "io-channel-helpers.h" #include "qapi/error.h" +#include "qemu/iov.h" struct QIOChannelTest { QIOChannel *src; @@ -37,77 +38,17 @@ struct QIOChannelTest { }; -static void test_skip_iovec(struct iovec **iov, - size_t *niov, - size_t skip, - struct iovec *old) -{ - size_t offset = 0; - size_t i; - - for (i = 0; i < *niov; i++) { - if (skip < (*iov)[i].iov_len) { - old->iov_len = (*iov)[i].iov_len; - old->iov_base = (*iov)[i].iov_base; - - (*iov)[i].iov_len -= skip; - (*iov)[i].iov_base += skip; - break; - } else { - skip -= (*iov)[i].iov_len; - - if (i == 0 && old->iov_base) { - (*iov)[i].iov_len = old->iov_len; - (*iov)[i].iov_base = old->iov_base; - old->iov_len = 0; - old->iov_base = NULL; - } - - offset++; - } - } - - *iov = *iov + offset; - *niov -= offset; -} - - /* This thread sends all data using iovecs */ static gpointer test_io_thread_writer(gpointer opaque) { QIOChannelTest *data = opaque; - struct iovec *iov = data->inputv; - size_t niov = data->niov; - struct iovec old = { 0 }; qio_channel_set_blocking(data->src, data->blocking, NULL); - while (niov) { - ssize_t ret; - ret = qio_channel_writev(data->src, - iov, - niov, - &data->writeerr); - if (ret == QIO_CHANNEL_ERR_BLOCK) { - if (data->blocking) { - error_setg(&data->writeerr, - "Unexpected I/O blocking"); - break; - } else { - qio_channel_wait(data->src, - G_IO_OUT); - continue; - } - } else if (ret < 0) { - break; - } else if (ret == 0) { - error_setg(&data->writeerr, - "Unexpected zero length write"); - break; - } - - test_skip_iovec(&iov, &niov, ret, &old); - } + qio_channel_writev_all(data->src, + data->inputv, + data->niov, + &data->writeerr); return NULL; } @@ -117,38 +58,13 @@ static gpointer test_io_thread_writer(gpointer opaque) static gpointer test_io_thread_reader(gpointer opaque) { QIOChannelTest *data = opaque; - struct iovec *iov = data->outputv; - size_t niov = data->niov; - struct iovec old = { 0 }; qio_channel_set_blocking(data->dst, data->blocking, NULL); - while (niov) { - ssize_t ret; - - ret = qio_channel_readv(data->dst, - iov, - niov, - &data->readerr); - - if (ret == QIO_CHANNEL_ERR_BLOCK) { - if (data->blocking) { - error_setg(&data->readerr, - "Unexpected I/O blocking"); - break; - } else { - qio_channel_wait(data->dst, - G_IO_IN); - continue; - } - } else if (ret < 0) { - break; - } else if (ret == 0) { - break; - } - - test_skip_iovec(&iov, &niov, ret, &old); - } + qio_channel_readv_all(data->dst, + data->outputv, + data->niov, + &data->readerr); return NULL; } diff --git a/tests/qapi-schema/alternate-conflict-bool-string.err b/tests/qapi-schema/alternate-conflict-bool-string.err new file mode 100644 index 0000000000..e52fee7620 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-bool-string.err @@ -0,0 +1 @@ +tests/qapi-schema/alternate-conflict-bool-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one' diff --git a/tests/qapi-schema/alternate-conflict-bool-string.exit b/tests/qapi-schema/alternate-conflict-bool-string.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-bool-string.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/alternate-conflict-bool-string.json b/tests/qapi-schema/alternate-conflict-bool-string.json new file mode 100644 index 0000000000..0544de10f3 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-bool-string.json @@ -0,0 +1,4 @@ +# alternate branches of 'str' type conflict with all scalar types +{ 'alternate': 'Alt', + 'data': { 'one': 'bool', + 'two': 'str' } } diff --git a/tests/qapi-schema/alternate-conflict-bool-string.out b/tests/qapi-schema/alternate-conflict-bool-string.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-bool-string.out diff --git a/tests/qapi-schema/alternate-conflict-num-string.err b/tests/qapi-schema/alternate-conflict-num-string.err new file mode 100644 index 0000000000..5ba3827dd1 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-num-string.err @@ -0,0 +1 @@ +tests/qapi-schema/alternate-conflict-num-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one' diff --git a/tests/qapi-schema/alternate-conflict-num-string.exit b/tests/qapi-schema/alternate-conflict-num-string.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-num-string.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/alternate-conflict-num-string.json b/tests/qapi-schema/alternate-conflict-num-string.json new file mode 100644 index 0000000000..ae901449af --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-num-string.json @@ -0,0 +1,4 @@ +# alternate branches of 'str' type conflict with all scalar types +{ 'alternate': 'Alt', + 'data': { 'one': 'number', + 'two': 'str' } } diff --git a/tests/qapi-schema/alternate-conflict-num-string.out b/tests/qapi-schema/alternate-conflict-num-string.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-num-string.out diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 5d0260b2be..c5a5c10b41 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -15,6 +15,7 @@ #include "qapi-visit.h" #include "qapi/error.h" #include "qapi/qobject-input-visitor.h" +#include "qapi/util.h" #include "qapi/visitor.h" const char common_args[] = "-nodefaults -machine none"; @@ -129,11 +130,189 @@ static void test_qmp_protocol(void) qtest_end(); } +static int query_error_class(const char *cmd) +{ + static struct { + const char *cmd; + int err_class; + } fails[] = { + /* Success depends on build configuration: */ +#ifndef CONFIG_SPICE + { "query-spice", ERROR_CLASS_COMMAND_NOT_FOUND }, +#endif +#ifndef CONFIG_VNC + { "query-vnc", ERROR_CLASS_GENERIC_ERROR }, + { "query-vnc-servers", ERROR_CLASS_GENERIC_ERROR }, +#endif +#ifndef CONFIG_REPLICATION + { "query-xen-replication-status", ERROR_CLASS_COMMAND_NOT_FOUND }, +#endif + /* Likewise, and require special QEMU command-line arguments: */ + { "query-acpi-ospm-status", ERROR_CLASS_GENERIC_ERROR }, + { "query-balloon", ERROR_CLASS_DEVICE_NOT_ACTIVE }, + { "query-hotpluggable-cpus", ERROR_CLASS_GENERIC_ERROR }, + { "query-vm-generation-id", ERROR_CLASS_GENERIC_ERROR }, + { NULL, -1 } + }; + int i; + + for (i = 0; fails[i].cmd; i++) { + if (!strcmp(cmd, fails[i].cmd)) { + return fails[i].err_class; + } + } + return -1; +} + +static void test_query(const void *data) +{ + const char *cmd = data; + int expected_error_class = query_error_class(cmd); + QDict *resp, *error; + const char *error_class; + + qtest_start(common_args); + + resp = qmp("{ 'execute': %s }", cmd); + error = qdict_get_qdict(resp, "error"); + error_class = error ? qdict_get_str(error, "class") : NULL; + + if (expected_error_class < 0) { + g_assert(qdict_haskey(resp, "return")); + } else { + g_assert(error); + g_assert_cmpint(qapi_enum_parse(&QapiErrorClass_lookup, error_class, + -1, &error_abort), + ==, expected_error_class); + } + QDECREF(resp); + + qtest_end(); +} + +static bool query_is_blacklisted(const char *cmd) +{ + const char *blacklist[] = { + /* Not actually queries: */ + "add-fd", + /* Success depends on target arch: */ + "query-cpu-definitions", /* arm, i386, ppc, s390x */ + "query-gic-capabilities", /* arm */ + /* Success depends on target-specific build configuration: */ + "query-pci", /* CONFIG_PCI */ + NULL + }; + int i; + + for (i = 0; blacklist[i]; i++) { + if (!strcmp(cmd, blacklist[i])) { + return true; + } + } + return false; +} + +typedef struct { + SchemaInfoList *list; + GHashTable *hash; +} QmpSchema; + +static void qmp_schema_init(QmpSchema *schema) +{ + QDict *resp; + Visitor *qiv; + SchemaInfoList *tail; + + qtest_start(common_args); + resp = qmp("{ 'execute': 'query-qmp-schema' }"); + + qiv = qobject_input_visitor_new(qdict_get(resp, "return")); + visit_type_SchemaInfoList(qiv, NULL, &schema->list, &error_abort); + visit_free(qiv); + + QDECREF(resp); + qtest_end(); + + schema->hash = g_hash_table_new(g_str_hash, g_str_equal); + + /* Build @schema: hash table mapping entity name to SchemaInfo */ + for (tail = schema->list; tail; tail = tail->next) { + g_hash_table_insert(schema->hash, tail->value->name, tail->value); + } +} + +static SchemaInfo *qmp_schema_lookup(QmpSchema *schema, const char *name) +{ + return g_hash_table_lookup(schema->hash, name); +} + +static void qmp_schema_cleanup(QmpSchema *schema) +{ + qapi_free_SchemaInfoList(schema->list); + g_hash_table_destroy(schema->hash); +} + +static bool object_type_has_mandatory_members(SchemaInfo *type) +{ + SchemaInfoObjectMemberList *tail; + + g_assert(type->meta_type == SCHEMA_META_TYPE_OBJECT); + + for (tail = type->u.object.members; tail; tail = tail->next) { + if (!tail->value->has_q_default) { + return true; + } + } + + return false; +} + +static void add_query_tests(QmpSchema *schema) +{ + SchemaInfoList *tail; + SchemaInfo *si, *arg_type, *ret_type; + const char *test_name; + + /* Test the query-like commands */ + for (tail = schema->list; tail; tail = tail->next) { + si = tail->value; + if (si->meta_type != SCHEMA_META_TYPE_COMMAND) { + continue; + } + + if (query_is_blacklisted(si->name)) { + continue; + } + + arg_type = qmp_schema_lookup(schema, si->u.command.arg_type); + if (object_type_has_mandatory_members(arg_type)) { + continue; + } + + ret_type = qmp_schema_lookup(schema, si->u.command.ret_type); + if (ret_type->meta_type == SCHEMA_META_TYPE_OBJECT + && !ret_type->u.object.members) { + continue; + } + + test_name = g_strdup_printf("qmp/%s", si->name); + qtest_add_data_func(test_name, si->name, test_query); + } +} + int main(int argc, char *argv[]) { + QmpSchema schema; + int ret; + g_test_init(&argc, &argv, NULL); qtest_add_func("qmp/protocol", test_qmp_protocol); + qmp_schema_init(&schema); + add_query_tests(&schema); + + ret = g_test_run(); - return g_test_run(); + qmp_schema_cleanup(&schema); + return ret; } diff --git a/tests/test-io-channel-tls.c b/tests/test-io-channel-tls.c index 8eaa208e1b..a210d01ba5 100644 --- a/tests/test-io-channel-tls.c +++ b/tests/test-io-channel-tls.c @@ -127,8 +127,8 @@ static void test_io_channel_tls(const void *opaque) /* We'll use this for our fake client-server connection */ g_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, channel) == 0); -#define CLIENT_CERT_DIR "tests/test-crypto-tlssession-client/" -#define SERVER_CERT_DIR "tests/test-crypto-tlssession-server/" +#define CLIENT_CERT_DIR "tests/test-io-channel-tls-client/" +#define SERVER_CERT_DIR "tests/test-io-channel-tls-server/" mkdir(CLIENT_CERT_DIR, 0700); mkdir(SERVER_CERT_DIR, 0700); @@ -218,7 +218,7 @@ static void test_io_channel_tls(const void *opaque) mainloop = g_main_context_default(); do { g_main_context_iteration(mainloop, TRUE); - } while (!clientHandshake.finished && + } while (!clientHandshake.finished || !serverHandshake.finished); g_assert(clientHandshake.failed == data->expectClientFail); diff --git a/tests/test-qapi-util.c b/tests/test-qapi-util.c index e8697577a5..4b5e4f8bd3 100644 --- a/tests/test-qapi-util.c +++ b/tests/test-qapi-util.c @@ -12,7 +12,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/util.h" #include "test-qapi-types.h" static void test_qapi_enum_parse(void) @@ -20,25 +19,20 @@ static void test_qapi_enum_parse(void) Error *err = NULL; int ret; - ret = qapi_enum_parse(QType_lookup, NULL, QTYPE__MAX, QTYPE_NONE, - &error_abort); + ret = qapi_enum_parse(&QType_lookup, NULL, QTYPE_NONE, &error_abort); g_assert_cmpint(ret, ==, QTYPE_NONE); - ret = qapi_enum_parse(QType_lookup, "junk", QTYPE__MAX, -1, - NULL); + ret = qapi_enum_parse(&QType_lookup, "junk", -1, NULL); g_assert_cmpint(ret, ==, -1); - ret = qapi_enum_parse(QType_lookup, "junk", QTYPE__MAX, -1, - &err); + ret = qapi_enum_parse(&QType_lookup, "junk", -1, &err); error_free_or_abort(&err); - ret = qapi_enum_parse(QType_lookup, "none", QTYPE__MAX, -1, - &error_abort); + ret = qapi_enum_parse(&QType_lookup, "none", -1, &error_abort); g_assert_cmpint(ret, ==, QTYPE_NONE); - ret = qapi_enum_parse(QType_lookup, QType_lookup[QTYPE__MAX - 1], - QTYPE__MAX, QTYPE__MAX - 1, - &error_abort); + ret = qapi_enum_parse(&QType_lookup, QType_str(QTYPE__MAX - 1), + QTYPE__MAX - 1, &error_abort); g_assert_cmpint(ret, ==, QTYPE__MAX - 1); } diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c index bcf02617dc..fe591814e4 100644 --- a/tests/test-qobject-input-visitor.c +++ b/tests/test-qobject-input-visitor.c @@ -382,10 +382,10 @@ static void test_visitor_in_enum(TestInputVisitorData *data, Visitor *v; EnumOne i; - for (i = 0; EnumOne_lookup[i]; i++) { + for (i = 0; i < ENUM_ONE__MAX; i++) { EnumOne res = -1; - v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]); + v = visitor_input_test_init(data, "%s", EnumOne_str(i)); visit_type_EnumOne(v, NULL, &res, &error_abort); g_assert_cmpint(i, ==, res); @@ -699,7 +699,7 @@ static void test_native_list_integer_helper(TestInputVisitorData *data, } } g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }", - UserDefNativeListUnionKind_lookup[kind], + UserDefNativeListUnionKind_str(kind), gstr_list->str); v = visitor_input_test_init_raw(data, gstr_union->str); @@ -1110,7 +1110,7 @@ static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data, error_free_or_abort(&err); visit_optional(v, "optional", &present); g_assert(!present); - visit_type_enum(v, "enum", &en, EnumOne_lookup, &err); + visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err); error_free_or_abort(&err); visit_type_int(v, "i64", &i64, &err); error_free_or_abort(&err); diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c index 7eb162059c..d375100a52 100644 --- a/tests/test-qobject-output-visitor.c +++ b/tests/test-qobject-output-visitor.c @@ -133,7 +133,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data, qstr = qobject_to_qstring(visitor_get(data)); g_assert(qstr); - g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_lookup[i]); + g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_str(i)); visitor_reset(data); } } diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 79313a7f7a..4f9c36bef1 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -279,10 +279,10 @@ static void test_visitor_in_enum(TestInputVisitorData *data, Visitor *v; EnumOne i; - for (i = 0; EnumOne_lookup[i]; i++) { + for (i = 0; i < ENUM_ONE__MAX; i++) { EnumOne res = -1; - v = visitor_input_test_init(data, EnumOne_lookup[i]); + v = visitor_input_test_init(data, EnumOne_str(i)); visit_type_EnumOne(v, NULL, &res, &err); g_assert(!err); diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c index e736db3af8..385cddb5d9 100644 --- a/tests/test-string-output-visitor.c +++ b/tests/test-string-output-visitor.c @@ -194,12 +194,12 @@ static void test_visitor_out_enum(TestOutputVisitorData *data, str = visitor_get(data); if (data->human) { - char *str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]); + char *str_human = g_strdup_printf("\"%s\"", EnumOne_str(i)); g_assert_cmpstr(str, ==, str_human); g_free(str_human); } else { - g_assert_cmpstr(str, ==, EnumOne_lookup[i]); + g_assert_cmpstr(str, ==, EnumOne_str(i)); } visitor_reset(data); } |