summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/libqos/virtio.c50
-rw-r--r--tests/libqos/virtio.h13
-rw-r--r--tests/qapi-schema/qapi-schema-test.json10
-rw-r--r--tests/qapi-schema/qapi-schema-test.out3
-rwxr-xr-xtests/qemu-iotests/08717
-rw-r--r--tests/qemu-iotests/087.out13
-rw-r--r--tests/test-qmp-input-strict.c17
-rw-r--r--tests/virtio-blk-test.c55
8 files changed, 132 insertions, 46 deletions
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 9b6de2c0a7..a061289249 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -78,30 +78,54 @@ void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d)
QVIRTIO_DRIVER_OK | QVIRTIO_DRIVER | QVIRTIO_ACKNOWLEDGE);
}
-bool qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
- QVirtQueue *vq, uint64_t timeout)
+void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
+ QVirtQueue *vq, gint64 timeout_us)
{
- do {
+ gint64 start_time = g_get_monotonic_time();
+
+ for (;;) {
clock_step(100);
if (bus->get_queue_isr_status(d, vq)) {
- break; /* It has ended */
+ return;
}
- } while (--timeout);
+ g_assert(g_get_monotonic_time() - start_time <= timeout_us);
+ }
+}
+
+/* Wait for the status byte at given guest memory address to be set
+ *
+ * The virtqueue interrupt must not be raised, making this useful for testing
+ * event_index functionality.
+ */
+uint8_t qvirtio_wait_status_byte_no_isr(const QVirtioBus *bus,
+ QVirtioDevice *d,
+ QVirtQueue *vq,
+ uint64_t addr,
+ gint64 timeout_us)
+{
+ gint64 start_time = g_get_monotonic_time();
+ uint8_t val;
- return timeout != 0;
+ while ((val = readb(addr)) == 0xff) {
+ clock_step(100);
+ g_assert(!bus->get_queue_isr_status(d, vq));
+ g_assert(g_get_monotonic_time() - start_time <= timeout_us);
+ }
+ return val;
}
-bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t timeout)
+void qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
+ gint64 timeout_us)
{
- do {
+ gint64 start_time = g_get_monotonic_time();
+
+ for (;;) {
clock_step(100);
if (bus->get_config_isr_status(d)) {
- break; /* It has ended */
+ return;
}
- } while (--timeout);
-
- return timeout != 0;
+ g_assert(g_get_monotonic_time() - start_time <= timeout_us);
+ }
}
void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 70b3376360..29fbacbc99 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -160,10 +160,15 @@ void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d);
void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d);
void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d);
-bool qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
- QVirtQueue *vq, uint64_t timeout);
-bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t timeout);
+void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
+ QVirtQueue *vq, gint64 timeout_us);
+uint8_t qvirtio_wait_status_byte_no_isr(const QVirtioBus *bus,
+ QVirtioDevice *d,
+ QVirtQueue *vq,
+ uint64_t addr,
+ gint64 timeout_us);
+void qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
+ gint64 timeout_us);
QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
QGuestAllocator *alloc, uint16_t index);
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index ab4d3d96b6..d43b5fd2e9 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -33,6 +33,9 @@
{ 'type': 'UserDefB',
'data': { 'integer': 'int' } }
+{ 'type': 'UserDefC',
+ 'data': { 'string1': 'str', 'string2': 'str' } }
+
{ 'union': 'UserDefUnion',
'base': 'UserDefZero',
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
@@ -47,6 +50,13 @@
# FIXME generated struct UserDefFlatUnion has members for direct base
# UserDefOne, but lacks members for indirect base UserDefZero
+# this variant of UserDefFlatUnion defaults to a union that uses fields with
+# allocated types to test corner cases in the cleanup/dealloc visitor
+{ 'union': 'UserDefFlatUnion2',
+ 'base': 'UserDefUnionBase',
+ 'discriminator': 'enum1',
+ 'data': { 'value1' : 'UserDefC', 'value2' : 'UserDefB', 'value3' : 'UserDefA' } }
+
{ 'union': 'UserDefAnonUnion',
'discriminator': {},
'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 95e989925b..08d7304dfa 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -6,9 +6,11 @@
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
OrderedDict([('union', 'UserDefUnion'), ('base', 'UserDefZero'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), ('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
+ OrderedDict([('union', 'UserDefFlatUnion2'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefC'), ('value2', 'UserDefB'), ('value3', 'UserDefA')]))]),
OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
@@ -32,6 +34,7 @@
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
OrderedDict([('type', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))])]
diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087
index 82c56b1394..d7454d13da 100755
--- a/tests/qemu-iotests/087
+++ b/tests/qemu-iotests/087
@@ -218,6 +218,23 @@ run_qemu <<EOF
{ "execute": "quit" }
EOF
+echo
+echo === Missing driver ===
+echo
+
+_make_test_img -o encryption=on $size
+run_qemu -S <<EOF
+{ "execute": "qmp_capabilities" }
+{ "execute": "blockdev-add",
+ "arguments": {
+ "options": {
+ "id": "disk"
+ }
+ }
+ }
+{ "execute": "quit" }
+EOF
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
index 75a54e0c36..e8795b3a10 100644
--- a/tests/qemu-iotests/087.out
+++ b/tests/qemu-iotests/087.out
@@ -64,4 +64,17 @@ QMP_VERSION
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+
+=== Missing driver ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
+Testing: -S
+QMP_VERSION
+{"return": {}}
+{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'driver', expected: string"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+
*** done
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 0f770034b1..d5360c6a87 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -260,6 +260,21 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,
qapi_free_UserDefFlatUnion(tmp);
}
+static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefFlatUnion2 *tmp = NULL;
+ Error *err = NULL;
+ Visitor *v;
+
+ /* test situation where discriminator field ('enum1' here) is missing */
+ v = validate_test_init(data, "{ 'string': 'c', 'string1': 'd', 'string2': 'e' }");
+
+ visit_type_UserDefFlatUnion2(v, &tmp, NULL, &err);
+ g_assert(err);
+ qapi_free_UserDefFlatUnion2(tmp);
+}
+
static void test_validate_fail_union_anon(TestInputVisitorData *data,
const void *unused)
{
@@ -310,6 +325,8 @@ int main(int argc, char **argv)
&testdata, test_validate_fail_union);
validate_test_add("/visitor/input-strict/fail/union-flat",
&testdata, test_validate_fail_union_flat);
+ validate_test_add("/visitor/input-strict/fail/union-flat-no-discriminator",
+ &testdata, test_validate_fail_union_flat_no_discrim);
validate_test_add("/visitor/input-strict/fail/union-anon",
&testdata, test_validate_fail_union_anon);
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 588666cff1..5ce6e79757 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -41,7 +41,7 @@
#define QVIRTIO_BLK_T_GET_ID 8
#define TEST_IMAGE_SIZE (64 * 1024 * 1024)
-#define QVIRTIO_BLK_TIMEOUT 100
+#define QVIRTIO_BLK_TIMEOUT_US (30 * 1000 * 1000)
#define PCI_SLOT 0x04
#define PCI_FN 0x00
@@ -183,8 +183,8 @@ static void pci_basic(void)
qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -205,8 +205,8 @@ static void pci_basic(void)
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -233,8 +233,8 @@ static void pci_basic(void)
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -256,8 +256,8 @@ static void pci_basic(void)
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -329,8 +329,8 @@ static void pci_indirect(void)
free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -354,8 +354,8 @@ static void pci_indirect(void)
free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -396,8 +396,7 @@ static void pci_config(void)
qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
" 'size': %d } }", n_size);
- g_assert(qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
g_assert_cmpint(capacity, ==, n_size / 512);
@@ -452,8 +451,7 @@ static void pci_msix(void)
qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
" 'size': %d } }", n_size);
- g_assert(qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
g_assert_cmpint(capacity, ==, n_size / 512);
@@ -473,8 +471,8 @@ static void pci_msix(void)
qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -497,8 +495,8 @@ static void pci_msix(void)
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -574,8 +572,8 @@ static void pci_idx(void)
qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
/* Write request */
req.type = QVIRTIO_BLK_T_OUT;
@@ -595,10 +593,9 @@ static void pci_idx(void)
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
/* No notification expected */
- g_assert(!qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
-
- status = readb(req_addr + 528);
+ status = qvirtio_wait_status_byte_no_isr(&qvirtio_pci, &dev->vdev,
+ &vqpci->vq, req_addr + 528,
+ QVIRTIO_BLK_TIMEOUT_US);
g_assert_cmpint(status, ==, 0);
guest_free(alloc, req_addr);
@@ -619,8 +616,8 @@ static void pci_idx(void)
qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
- g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT));
+ qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);