diff options
author | Peter Maydell | 2020-10-12 23:48:45 +0200 |
---|---|---|
committer | Peter Maydell | 2020-10-12 23:48:45 +0200 |
commit | 724c1c8bb350d84c097ab2005aad15e125d06b6c (patch) | |
tree | b55ff4dc3e8012e2624d2aa2d1211684bd425656 /tests/qtest/libqtest.c | |
parent | Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20201012a'... (diff) | |
parent | meson: identify more sections of meson.build (diff) | |
download | qemu-724c1c8bb350d84c097ab2005aad15e125d06b6c.tar.gz qemu-724c1c8bb350d84c097ab2005aad15e125d06b6c.tar.xz qemu-724c1c8bb350d84c097ab2005aad15e125d06b6c.zip |
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
* qtest documentation improvements (Eduardo, myself)
* libqtest event buffering (Maxim)
* use RCU for list of children of a bus (Maxim)
* move more files to softmmu/ (myself)
* meson.build cleanups, qemu-storage-daemon fix (Philippe)
# gpg: Signature made Mon 12 Oct 2020 16:55:19 BST
# gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg: issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini-gitlab/tags/for-upstream: (38 commits)
meson: identify more sections of meson.build
scsi/scsi_bus: fix races in REPORT LUNS
virtio-scsi: use scsi_device_get
scsi/scsi_bus: Add scsi_device_get
scsi/scsi-bus: scsi_device_find: don't return unrealized devices
device-core: use atomic_set on .realized property
scsi: switch to bus->check_address
device-core: use RCU for list of children of a bus
device_core: use drain_call_rcu in in qmp_device_add
scsi/scsi_bus: switch search direction in scsi_device_find
qdev: add "check if address free" callback for buses
qemu-iotests, qtest: rewrite test 067 as a qtest
qtest: check that drives are really appearing and disappearing
qtest: switch users back to qtest_qmp_receive
device-plug-test: use qtest_qmp to send the device_del command
qtest: remove qtest_qmp_receive_success
qtest: Reintroduce qtest_qmp_receive with QMP event buffering
qtest: rename qtest_qmp_receive to qtest_qmp_receive_dict
meson.build: Re-enable KVM support for MIPS
build-sys: fix git version from -version
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests/qtest/libqtest.c')
-rw-r--r-- | tests/qtest/libqtest.c | 110 |
1 files changed, 54 insertions, 56 deletions
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index 58f58e1ece..08929f5ff6 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -63,6 +63,7 @@ struct QTestState bool irq_level[MAX_IRQ]; GString *rx; QTestTransportOps ops; + GList *pending_events; }; static GHookList abrt_hooks; @@ -279,6 +280,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) g_test_message("starting QEMU: %s", command); + s->pending_events = NULL; s->wstatus = 0; s->expected_status = 0; s->qemu_pid = fork(); @@ -386,6 +388,13 @@ void qtest_quit(QTestState *s) close(s->fd); close(s->qmp_fd); g_string_free(s->rx, true); + + for (GList *it = s->pending_events; it != NULL; it = it->next) { + qobject_unref((QDict *)it->data); + } + + g_list_free(s->pending_events); + g_free(s); } @@ -605,6 +614,19 @@ QDict *qmp_fd_receive(int fd) QDict *qtest_qmp_receive(QTestState *s) { + while (true) { + QDict *response = qtest_qmp_receive_dict(s); + + if (!qdict_get_try_str(response, "event")) { + return response; + } + /* Stash the event for a later consumption */ + s->pending_events = g_list_prepend(s->pending_events, response); + } +} + +QDict *qtest_qmp_receive_dict(QTestState *s) +{ return qmp_fd_receive(s->qmp_fd); } @@ -771,12 +793,36 @@ void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...) va_end(ap); } -QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event) +QDict *qtest_qmp_event_ref(QTestState *s, const char *event) { + GList *next = NULL; QDict *response; + for (GList *it = s->pending_events; it != NULL; it = next) { + + next = it->next; + response = (QDict *)it->data; + + s->pending_events = g_list_remove_link(s->pending_events, it); + + if (!strcmp(qdict_get_str(response, "event"), event)) { + return response; + } + qobject_unref(response); + } + return NULL; +} + +QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event) +{ + QDict *response = qtest_qmp_event_ref(s, event); + + if (response) { + return response; + } + for (;;) { - response = qtest_qmp_receive(s); + response = qtest_qmp_receive_dict(s); if ((qdict_haskey(response, "event")) && (strcmp(qdict_get_str(response, "event"), event) == 0)) { return response; @@ -804,12 +850,6 @@ char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap) " 'arguments': {'command-line': %s}}", cmd); ret = g_strdup(qdict_get_try_str(resp, "return")); - while (ret == NULL && qdict_get_try_str(resp, "event")) { - /* Ignore asynchronous QMP events */ - qobject_unref(resp); - resp = qtest_qmp_receive(s); - ret = g_strdup(qdict_get_try_str(resp, "return")); - } g_assert(ret); qobject_unref(resp); g_free(cmd); @@ -1245,35 +1285,6 @@ void qtest_cb_for_every_machine(void (*cb)(const char *machine), qobject_unref(response); } -QDict *qtest_qmp_receive_success(QTestState *s, - void (*event_cb)(void *opaque, - const char *event, - QDict *data), - void *opaque) -{ - QDict *response, *ret, *data; - const char *event; - - for (;;) { - response = qtest_qmp_receive(s); - g_assert(!qdict_haskey(response, "error")); - ret = qdict_get_qdict(response, "return"); - if (ret) { - break; - } - event = qdict_get_str(response, "event"); - data = qdict_get_qdict(response, "data"); - if (event_cb) { - event_cb(opaque, event, data); - } - qobject_unref(response); - } - - qobject_ref(ret); - qobject_unref(response); - return ret; -} - /* * Generic hot-plugging test via the device_add QMP commands. */ @@ -1309,13 +1320,6 @@ void qtest_qmp_device_add(QTestState *qts, const char *driver, const char *id, qobject_unref(args); } -static void device_deleted_cb(void *opaque, const char *name, QDict *data) -{ - bool *got_event = opaque; - - g_assert_cmpstr(name, ==, "DEVICE_DELETED"); - *got_event = true; -} /* * Generic hot-unplugging test via the device_del QMP command. @@ -1332,24 +1336,17 @@ static void device_deleted_cb(void *opaque, const char *name, QDict *data) * and this one: * * {"return": {}} - * - * But the order of arrival may vary - so we've got to detect both. */ void qtest_qmp_device_del(QTestState *qts, const char *id) { - bool got_event = false; QDict *rsp; - qtest_qmp_send(qts, "{'execute': 'device_del', 'arguments': {'id': %s}}", - id); - rsp = qtest_qmp_receive_success(qts, device_deleted_cb, &got_event); + rsp = qtest_qmp(qts, "{'execute': 'device_del', 'arguments': {'id': %s}}", + id); + + g_assert(qdict_haskey(rsp, "return")); qobject_unref(rsp); - if (!got_event) { - rsp = qtest_qmp_receive(qts); - g_assert_cmpstr(qdict_get_try_str(rsp, "event"), - ==, "DEVICE_DELETED"); - qobject_unref(rsp); - } + qtest_qmp_eventwait(qts, "DEVICE_DELETED"); } bool qmp_rsp_is_err(QDict *rsp) @@ -1403,6 +1400,7 @@ QTestState *qtest_inproc_init(QTestState **s, bool log, const char* arch, { QTestState *qts; qts = g_new0(QTestState, 1); + qts->pending_events = NULL; *s = qts; /* Expose qts early on, since the query endianness relies on it */ qts->wstatus = 0; for (int i = 0; i < MAX_IRQ; i++) { |