aboutsummaryrefslogtreecommitdiff
path: root/tests/qemu-iotests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/qemu-iotests')
-rw-r--r--tests/qemu-iotests/016.out23
-rwxr-xr-xtests/qemu-iotests/0511
-rw-r--r--tests/qemu-iotests/051.out63
-rw-r--r--tests/qemu-iotests/087.out8
-rwxr-xr-xtests/qemu-iotests/093114
-rw-r--r--tests/qemu-iotests/093.out5
-rwxr-xr-xtests/qemu-iotests/09481
-rw-r--r--tests/qemu-iotests/094.out11
-rwxr-xr-xtests/qemu-iotests/123 (renamed from tests/qemu-iotests/016)43
-rw-r--r--tests/qemu-iotests/123.out9
-rw-r--r--tests/qemu-iotests/common.qemu12
-rw-r--r--tests/qemu-iotests/group5
-rw-r--r--tests/qemu-iotests/iotests.py23
13 files changed, 308 insertions, 90 deletions
diff --git a/tests/qemu-iotests/016.out b/tests/qemu-iotests/016.out
deleted file mode 100644
index acbd60b4a3..0000000000
--- a/tests/qemu-iotests/016.out
+++ /dev/null
@@ -1,23 +0,0 @@
-QA output created by 016
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
-
-== reading at EOF ==
-read 512/512 bytes at offset 134217728
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-== reading far past EOF ==
-read 512/512 bytes at offset 268435456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-== writing at EOF ==
-wrote 512/512 bytes at offset 134217728
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 134217728
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-== writing far past EOF ==
-wrote 512/512 bytes at offset 268435456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 268435456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-*** done
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
index 11c858f27d..27138a2299 100755
--- a/tests/qemu-iotests/051
+++ b/tests/qemu-iotests/051
@@ -93,6 +93,7 @@ echo
run_qemu -drive file="$TEST_IMG",format=foo
run_qemu -drive file="$TEST_IMG",driver=foo
run_qemu -drive file="$TEST_IMG",driver=raw,format=qcow2
+run_qemu -drive file="$TEST_IMG",driver=qcow2,format=qcow2
echo
echo === Overriding backing file ===
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index f497c5717b..bf52bf02d4 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -5,43 +5,46 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR
=== Unknown option ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=: could not open disk image TEST_DIR/t.qcow2: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=on
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=on: could not open disk image TEST_DIR/t.qcow2: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=on: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=1234
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=1234: could not open disk image TEST_DIR/t.qcow2: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=1234: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: could not open disk image TEST_DIR/t.qcow2: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
=== Unknown protocol option ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=: Block protocol 'file' doesn't support the option 'unknown_opt'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=on
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=on: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=on: Block protocol 'file' doesn't support the option 'unknown_opt'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=1234
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=1234: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=1234: Block protocol 'file' doesn't support the option 'unknown_opt'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=foo
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=foo: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=foo: Block protocol 'file' doesn't support the option 'unknown_opt'
=== Invalid format ===
Testing: -drive file=TEST_DIR/t.qcow2,format=foo
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=foo: 'foo' invalid format
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=foo: Unknown driver 'foo'
Testing: -drive file=TEST_DIR/t.qcow2,driver=foo
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=foo: could not open disk image TEST_DIR/t.qcow2: Unknown driver 'foo'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=foo: Unknown driver 'foo'
Testing: -drive file=TEST_DIR/t.qcow2,driver=raw,format=qcow2
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=raw,format=qcow2: could not open disk image TEST_DIR/t.qcow2: Driver specified twice
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=raw,format=qcow2: Cannot specify both 'driver' and 'format'
+
+Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,format=qcow2
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=qcow2,format=qcow2: Cannot specify both 'driver' and 'format'
=== Overriding backing file ===
@@ -55,13 +58,13 @@ ide0-hd0: TEST_DIR/t.qcow2 (qcow2)
(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig: could not open disk image TEST_DIR/t.qcow2: Driver doesn't support backing files
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig: Driver doesn't support backing files
Testing: -drive file=TEST_DIR/t.qcow2,file.backing.driver=file,file.backing.filename=TEST_DIR/t.qcow2.orig
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=file,file.backing.filename=TEST_DIR/t.qcow2.orig: could not open disk image TEST_DIR/t.qcow2: Driver doesn't support backing files
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=file,file.backing.filename=TEST_DIR/t.qcow2.orig: Driver doesn't support backing files
Testing: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.file.filename=TEST_DIR/t.qcow2.orig
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.file.filename=TEST_DIR/t.qcow2.orig: could not open disk image TEST_DIR/t.qcow2: Driver doesn't support backing files
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.file.filename=TEST_DIR/t.qcow2.orig: Driver doesn't support backing files
=== Enable and disable lazy refcounting on the command line, plus some invalid values ===
@@ -75,20 +78,20 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=: could not open disk image TEST_DIR/t.qcow2: Parameter 'lazy-refcounts' expects 'on' or 'off'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=: Parameter 'lazy-refcounts' expects 'on' or 'off'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=42
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=42: could not open disk image TEST_DIR/t.qcow2: Parameter 'lazy-refcounts' expects 'on' or 'off'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=42: Parameter 'lazy-refcounts' expects 'on' or 'off'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=foo
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=foo: could not open disk image TEST_DIR/t.qcow2: Parameter 'lazy-refcounts' expects 'on' or 'off'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=foo: Parameter 'lazy-refcounts' expects 'on' or 'off'
=== With version 2 images enabling lazy refcounts must fail ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: could not open disk image TEST_DIR/t.qcow2: Lazy refcounts require a qcow2 image with at least qemu 1.1 compatibility level
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: Lazy refcounts require a qcow2 image with at least qemu 1.1 compatibility level
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
QEMU X.Y.Z monitor - type 'help' for more information
@@ -248,31 +251,31 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: could not open disk image TEST_DIR/t.qcow2: Block format 'qcow2' used by device '' doesn't support the option 'filename'
+QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: Block format 'qcow2' used by device '' doesn't support the option 'filename'
=== Leaving out required options ===
Testing: -drive driver=file
-QEMU_PROG: -drive driver=file: could not open disk image ide0-hd0: The 'file' block driver requires a file name
+QEMU_PROG: -drive driver=file: The 'file' block driver requires a file name
Testing: -drive driver=nbd
-QEMU_PROG: -drive driver=nbd: could not open disk image ide0-hd0: one of path and host must be specified.
+QEMU_PROG: -drive driver=nbd: one of path and host must be specified.
Testing: -drive driver=raw
-QEMU_PROG: -drive driver=raw: could not open disk image ide0-hd0: Can't use 'raw' as a block driver for the protocol level
+QEMU_PROG: -drive driver=raw: Can't use 'raw' as a block driver for the protocol level
Testing: -drive file.driver=file
-QEMU_PROG: -drive file.driver=file: could not open disk image ide0-hd0: The 'file' block driver requires a file name
+QEMU_PROG: -drive file.driver=file: The 'file' block driver requires a file name
Testing: -drive file.driver=nbd
-QEMU_PROG: -drive file.driver=nbd: could not open disk image ide0-hd0: one of path and host must be specified.
+QEMU_PROG: -drive file.driver=nbd: one of path and host must be specified.
Testing: -drive file.driver=raw
-QEMU_PROG: -drive file.driver=raw: could not open disk image ide0-hd0: Can't use 'raw' as a block driver for the protocol level
+QEMU_PROG: -drive file.driver=raw: Can't use 'raw' as a block driver for the protocol level
Testing: -drive foo=bar
-QEMU_PROG: -drive foo=bar: could not open disk image ide0-hd0: Must specify either driver or file
+QEMU_PROG: -drive foo=bar: Must specify either driver or file
=== Specifying both an option and its legacy alias ===
@@ -323,13 +326,13 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,readonly=on,read-only=off: 'read-only' a
=== Parsing protocol from file name ===
Testing: -hda foo:bar
-QEMU_PROG: -hda foo:bar: could not open disk image foo:bar: Unknown protocol
+QEMU_PROG: -hda foo:bar: Unknown protocol 'foo'
Testing: -drive file=foo:bar
-QEMU_PROG: -drive file=foo:bar: could not open disk image foo:bar: Unknown protocol
+QEMU_PROG: -drive file=foo:bar: Unknown protocol 'foo'
Testing: -drive file.filename=foo:bar
-QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: Could not open 'foo:bar': No such file or directory
+QEMU_PROG: -drive file.filename=foo:bar: Could not open 'foo:bar': No such file or directory
Testing: -hda file:TEST_DIR/t.qcow2
QEMU X.Y.Z monitor - type 'help' for more information
@@ -340,7 +343,7 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) qququiquit
Testing: -drive file.filename=file:TEST_DIR/t.qcow2
-QEMU_PROG: -drive file.filename=file:TEST_DIR/t.qcow2: could not open disk image ide0-hd0: Could not open 'file:TEST_DIR/t.qcow2': No such file or directory
+QEMU_PROG: -drive file.filename=file:TEST_DIR/t.qcow2: Could not open 'file:TEST_DIR/t.qcow2': No such file or directory
=== Snapshot mode ===
diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
index 91f4ea1a8b..0ba2e43b40 100644
--- a/tests/qemu-iotests/087.out
+++ b/tests/qemu-iotests/087.out
@@ -21,9 +21,9 @@ QMP_VERSION
{"return": {}}
{"error": {"class": "GenericError", "desc": "Device with id 'disk' already exists"}}
{"error": {"class": "GenericError", "desc": "Device name 'test-node' conflicts with an existing node name"}}
-{"error": {"class": "GenericError", "desc": "could not open disk image disk2: node-name=disk is conflicting with a device id"}}
-{"error": {"class": "GenericError", "desc": "could not open disk image disk2: Duplicate node name"}}
-{"error": {"class": "GenericError", "desc": "could not open disk image disk3: node-name=disk3 is conflicting with a device id"}}
+{"error": {"class": "GenericError", "desc": "node-name=disk is conflicting with a device id"}}
+{"error": {"class": "GenericError", "desc": "Duplicate node name"}}
+{"error": {"class": "GenericError", "desc": "node-name=disk3 is conflicting with a device id"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
@@ -57,7 +57,7 @@ QMP_VERSION
Testing:
QMP_VERSION
{"return": {}}
-{"error": {"class": "GenericError", "desc": "could not open disk image disk: Guest must be stopped for opening of encrypted image"}}
+{"error": {"class": "GenericError", "desc": "Guest must be stopped for opening of encrypted image"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093
new file mode 100755
index 0000000000..b9096a55d4
--- /dev/null
+++ b/tests/qemu-iotests/093
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+#
+# Tests for IO throttling
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import iotests
+
+class ThrottleTestCase(iotests.QMPTestCase):
+ test_img = "null-aio://"
+
+ def blockstats(self, device):
+ result = self.vm.qmp("query-blockstats")
+ for r in result['return']:
+ if r['device'] == device:
+ stat = r['stats']
+ return stat['rd_bytes'], stat['rd_operations'], stat['wr_bytes'], stat['wr_operations']
+ raise Exception("Device not found for blockstats: %s" % device)
+
+ def setUp(self):
+ self.vm = iotests.VM().add_drive(self.test_img)
+ self.vm.launch()
+
+ def tearDown(self):
+ self.vm.shutdown()
+
+ def do_test_throttle(self, seconds, params):
+ def check_limit(limit, num):
+ # IO throttling algorithm is discrete, allow 10% error so the test
+ # is more robust
+ return limit == 0 or \
+ (num < seconds * limit * 1.1
+ and num > seconds * limit * 0.9)
+
+ nsec_per_sec = 1000000000
+
+ params['device'] = 'drive0'
+
+ result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **params)
+ self.assert_qmp(result, 'return', {})
+
+ # Set vm clock to a known value
+ ns = seconds * nsec_per_sec
+ self.vm.qtest("clock_step %d" % ns)
+
+ # Submit enough requests. They will drain bps_max and iops_max, but the
+ # rest requests won't get executed until we advance the virtual clock
+ # with qtest interface
+ rq_size = 512
+ rd_nr = max(params['bps'] / rq_size / 2,
+ params['bps_rd'] / rq_size,
+ params['iops'] / 2,
+ params['iops_rd'])
+ rd_nr *= seconds * 2
+ wr_nr = max(params['bps'] / rq_size / 2,
+ params['bps_wr'] / rq_size,
+ params['iops'] / 2,
+ params['iops_wr'])
+ wr_nr *= seconds * 2
+ for i in range(rd_nr):
+ self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % (i * rq_size, rq_size))
+ for i in range(wr_nr):
+ self.vm.hmp_qemu_io("drive0", "aio_write %d %d" % (i * rq_size, rq_size))
+
+ start_rd_bytes, start_rd_iops, start_wr_bytes, start_wr_iops = self.blockstats('drive0')
+
+ self.vm.qtest("clock_step %d" % ns)
+ end_rd_bytes, end_rd_iops, end_wr_bytes, end_wr_iops = self.blockstats('drive0')
+
+ rd_bytes = end_rd_bytes - start_rd_bytes
+ rd_iops = end_rd_iops - start_rd_iops
+ wr_bytes = end_wr_bytes - start_wr_bytes
+ wr_iops = end_wr_iops - start_wr_iops
+
+ self.assertTrue(check_limit(params['bps'], rd_bytes + wr_bytes))
+ self.assertTrue(check_limit(params['bps_rd'], rd_bytes))
+ self.assertTrue(check_limit(params['bps_wr'], wr_bytes))
+ self.assertTrue(check_limit(params['iops'], rd_iops + wr_iops))
+ self.assertTrue(check_limit(params['iops_rd'], rd_iops))
+ self.assertTrue(check_limit(params['iops_wr'], wr_iops))
+
+ def test_all(self):
+ params = {"bps": 4096,
+ "bps_rd": 4096,
+ "bps_wr": 4096,
+ "iops": 10,
+ "iops_rd": 10,
+ "iops_wr": 10,
+ }
+ # Pick each out of all possible params and test
+ for tk in params:
+ limits = dict([(k, 0) for k in params])
+ limits[tk] = params[tk]
+ self.do_test_throttle(5, limits)
+
+class ThrottleTestCoroutine(ThrottleTestCase):
+ test_img = "null-co://"
+
+if __name__ == '__main__':
+ iotests.main(supported_fmts=["raw"])
diff --git a/tests/qemu-iotests/093.out b/tests/qemu-iotests/093.out
new file mode 100644
index 0000000000..fbc63e62f8
--- /dev/null
+++ b/tests/qemu-iotests/093.out
@@ -0,0 +1,5 @@
+..
+----------------------------------------------------------------------
+Ran 2 tests
+
+OK
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
new file mode 100755
index 0000000000..27a2be2569
--- /dev/null
+++ b/tests/qemu-iotests/094
@@ -0,0 +1,81 @@
+#!/bin/bash
+#
+# Test case for drive-mirror to NBD (especially bdrv_swap() on NBD BDS)
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=mreitz@redhat.com
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+
+here="$PWD"
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+trap "exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt generic
+_supported_proto nbd
+_supported_os Linux
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
+
+_make_test_img 64M
+$QEMU_IMG create -f $IMGFMT "$TEST_DIR/source.$IMGFMT" 64M | _filter_img_create
+
+_launch_qemu -drive if=none,id=src,file="$TEST_DIR/source.$IMGFMT",format=raw \
+ -nodefaults
+
+_send_qemu_cmd $QEMU_HANDLE \
+ "{'execute': 'qmp_capabilities'}" \
+ 'return'
+
+# 'format': 'nbd' is not actually "correct", but this is probably the only way
+# to test bdrv_swap() on an NBD BDS
+_send_qemu_cmd $QEMU_HANDLE \
+ "{'execute': 'drive-mirror',
+ 'arguments': {'device': 'src',
+ 'target': '$TEST_IMG',
+ 'format': 'nbd',
+ 'sync':'full',
+ 'mode':'existing'}}" \
+ 'BLOCK_JOB_READY'
+
+_send_qemu_cmd $QEMU_HANDLE \
+ "{'execute': 'block-job-complete',
+ 'arguments': {'device': 'src'}}" \
+ 'BLOCK_JOB_COMPLETE'
+
+_send_qemu_cmd $QEMU_HANDLE \
+ "{'execute': 'quit'}" \
+ 'return'
+
+wait=1 _cleanup_qemu
+
+_cleanup_test_img
+rm -f "$TEST_DIR/source.$IMGFMT"
+
+# success, all done
+echo '*** done'
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/094.out b/tests/qemu-iotests/094.out
new file mode 100644
index 0000000000..b66dc0787d
--- /dev/null
+++ b/tests/qemu-iotests/094.out
@@ -0,0 +1,11 @@
+QA output created by 094
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/source.IMGFMT', fmt=IMGFMT size=67108864
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
+*** done
diff --git a/tests/qemu-iotests/016 b/tests/qemu-iotests/123
index 52397aa80e..ad608035d1 100755
--- a/tests/qemu-iotests/016
+++ b/tests/qemu-iotests/123
@@ -1,8 +1,8 @@
#!/bin/bash
#
-# Test I/O after EOF for growable images.
+# Test case for qemu-img convert to NBD
#
-# Copyright (C) 2009 Red Hat, Inc.
+# Copyright (C) 2015 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -19,18 +19,19 @@
#
# creator
-owner=hch@lst.de
+owner=mreitz@redhat.com
-seq=`basename $0`
+seq="$(basename $0)"
echo "QA output created by $seq"
-here=`pwd`
+here="$PWD"
tmp=/tmp/$$
status=1 # failure is the default!
_cleanup()
{
- _cleanup_test_img
+ _cleanup_test_img
+ rm -f "$SRC_IMG"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -39,35 +40,23 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
. ./common.filter
_supported_fmt raw
-_supported_proto file sheepdog nfs
+_supported_proto nbd
_supported_os Linux
+SRC_IMG="$TEST_DIR/source.$IMGFMT"
-# No -f, use probing for the protocol driver
-QEMU_IO_PROTO="$QEMU_IO_PROG -g --cache $CACHEMODE"
+_make_test_img 1M
+$QEMU_IMG create -f $IMGFMT "$SRC_IMG" 1M | _filter_img_create
-size=128M
-_make_test_img $size
+$QEMU_IO -c 'write -P 42 0 1M' "$SRC_IMG" | _filter_qemu_io
-echo
-echo "== reading at EOF =="
-$QEMU_IO_PROTO -c "read -P 0 $size 512" "$TEST_IMG" | _filter_qemu_io
-
-echo
-echo "== reading far past EOF =="
-$QEMU_IO_PROTO -c "read -P 0 256M 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG convert -n -f $IMGFMT -O raw "$SRC_IMG" "$TEST_IMG"
-echo
-echo "== writing at EOF =="
-$QEMU_IO_PROTO -c "write -P 66 $size 512" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 66 $size 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'read -P 42 0 1M' "$TEST_IMG" | _filter_qemu_io
-echo
-echo "== writing far past EOF =="
-$QEMU_IO_PROTO -c "write -P 66 256M 512" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 66 256M 512" "$TEST_IMG" | _filter_qemu_io
# success, all done
-echo "*** done"
+echo
+echo '*** done'
rm -f $seq.full
status=0
diff --git a/tests/qemu-iotests/123.out b/tests/qemu-iotests/123.out
new file mode 100644
index 0000000000..0b818d34c4
--- /dev/null
+++ b/tests/qemu-iotests/123.out
@@ -0,0 +1,9 @@
+QA output created by 123
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+Formatting 'TEST_DIR/source.IMGFMT', fmt=IMGFMT size=1048576
+wrote 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+*** done
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
index 8e618b5149..4e1996c3ec 100644
--- a/tests/qemu-iotests/common.qemu
+++ b/tests/qemu-iotests/common.qemu
@@ -187,13 +187,23 @@ function _launch_qemu()
# Silenty kills the QEMU process
+#
+# If $wait is set to anything other than the empty string, the process will not
+# be killed but only waited for, and any output will be forwarded to stdout. If
+# $wait is empty, the process will be killed and all output will be suppressed.
function _cleanup_qemu()
{
# QEMU_PID[], QEMU_IN[], QEMU_OUT[] all use same indices
for i in "${!QEMU_OUT[@]}"
do
- kill -KILL ${QEMU_PID[$i]} 2>/dev/null
+ if [ -z "${wait}" ]; then
+ kill -KILL ${QEMU_PID[$i]} 2>/dev/null
+ fi
wait ${QEMU_PID[$i]} 2>/dev/null # silent kill
+ if [ -n "${wait}" ]; then
+ cat <&${QEMU_OUT[$i]} | _filter_testdir | _filter_qemu \
+ | _filter_qemu_io | _filter_qmp
+ fi
rm -f "${QEMU_FIFO_IN}_${i}" "${QEMU_FIFO_OUT}_${i}"
eval "exec ${QEMU_IN[$i]}<&-" # close file descriptors
eval "exec ${QEMU_OUT[$i]}<&-"
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 4b2b93bc19..0d3b95c258 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -22,7 +22,7 @@
013 rw auto
014 rw auto
015 rw snapshot auto
-016 rw auto quick
+# 016 was removed, do not reuse
017 rw backing auto quick
018 rw backing auto quick
019 rw backing auto quick
@@ -99,6 +99,8 @@
090 rw auto quick
091 rw auto
092 rw auto quick
+093 auto
+094 rw auto quick
095 rw auto quick
097 rw auto backing
098 rw auto backing quick
@@ -117,3 +119,4 @@
113 rw auto quick
114 rw auto quick
116 rw auto quick
+123 rw auto quick
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 241b5ee9dd..14028540b3 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -21,8 +21,11 @@ import re
import subprocess
import string
import unittest
-import sys; sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts', 'qmp'))
+import sys
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts'))
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts', 'qmp'))
import qmp
+import qtest
import struct
__all__ = ['imgfmt', 'imgproto', 'test_dir' 'qemu_img', 'qemu_io',
@@ -81,10 +84,12 @@ class VM(object):
def __init__(self):
self._monitor_path = os.path.join(test_dir, 'qemu-mon.%d' % os.getpid())
self._qemu_log_path = os.path.join(test_dir, 'qemu-log.%d' % os.getpid())
+ self._qtest_path = os.path.join(test_dir, 'qemu-qtest.%d' % os.getpid())
self._args = qemu_args + ['-chardev',
'socket,id=mon,path=' + self._monitor_path,
'-mon', 'chardev=mon,mode=control',
- '-qtest', 'stdio', '-machine', 'accel=qtest',
+ '-qtest', 'unix:path=' + self._qtest_path,
+ '-machine', 'accel=qtest',
'-display', 'none', '-vga', 'none']
self._num_drives = 0
@@ -160,9 +165,11 @@ class VM(object):
qemulog = open(self._qemu_log_path, 'wb')
try:
self._qmp = qmp.QEMUMonitorProtocol(self._monitor_path, server=True)
+ self._qtest = qtest.QEMUQtestProtocol(self._qtest_path, server=True)
self._popen = subprocess.Popen(self._args, stdin=devnull, stdout=qemulog,
stderr=subprocess.STDOUT)
self._qmp.accept()
+ self._qtest.accept()
except:
os.remove(self._monitor_path)
raise
@@ -173,18 +180,26 @@ class VM(object):
self._qmp.cmd('quit')
self._popen.wait()
os.remove(self._monitor_path)
+ os.remove(self._qtest_path)
os.remove(self._qemu_log_path)
self._popen = None
underscore_to_dash = string.maketrans('_', '-')
- def qmp(self, cmd, **args):
+ def qmp(self, cmd, conv_keys=True, **args):
'''Invoke a QMP command and return the result dict'''
qmp_args = dict()
for k in args.keys():
- qmp_args[k.translate(self.underscore_to_dash)] = args[k]
+ if conv_keys:
+ qmp_args[k.translate(self.underscore_to_dash)] = args[k]
+ else:
+ qmp_args[k] = args[k]
return self._qmp.cmd(cmd, args=qmp_args)
+ def qtest(self, cmd):
+ '''Send a qtest command to guest'''
+ return self._qtest.cmd(cmd)
+
def get_qmp_event(self, wait=False):
'''Poll for one queued QMP events and return it'''
return self._qmp.pull_event(wait=wait)