diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile | 16 | ||||
-rw-r--r-- | tests/qemu-iotests/051.out | 7 | ||||
-rwxr-xr-x | tests/qemu-iotests/059 | 12 | ||||
-rw-r--r-- | tests/qemu-iotests/059.out | 18 | ||||
-rwxr-xr-x | tests/qemu-iotests/060 | 47 | ||||
-rw-r--r-- | tests/qemu-iotests/060.out | 40 | ||||
-rwxr-xr-x | tests/qemu-iotests/064 | 62 | ||||
-rw-r--r-- | tests/qemu-iotests/064.out | 14 | ||||
-rwxr-xr-x | tests/qemu-iotests/065 | 125 | ||||
-rw-r--r-- | tests/qemu-iotests/065.out | 5 | ||||
-rwxr-xr-x | tests/qemu-iotests/066 | 63 | ||||
-rw-r--r-- | tests/qemu-iotests/066.out | 13 | ||||
-rwxr-xr-x | tests/qemu-iotests/067 | 133 | ||||
-rw-r--r-- | tests/qemu-iotests/067.out | 80 | ||||
-rw-r--r-- | tests/qemu-iotests/common | 8 | ||||
-rw-r--r-- | tests/qemu-iotests/common.filter | 8 | ||||
-rw-r--r-- | tests/qemu-iotests/common.rc | 22 | ||||
-rw-r--r-- | tests/qemu-iotests/group | 4 | ||||
-rw-r--r-- | tests/qemu-iotests/iotests.py | 4 | ||||
-rw-r--r-- | tests/qemu-iotests/sample_images/iotest-dynamic-1G.vhdx.bz2 | bin | 0 -> 874 bytes |
20 files changed, 655 insertions, 26 deletions
diff --git a/tests/Makefile b/tests/Makefile index 915ae5e2d1..fa4c9f0cbb 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -196,6 +196,7 @@ check-help: @echo " make check-qapi-schema Run QAPI schema tests" @echo " make check-block Run block tests" @echo " make check-report.html Generates an HTML test report" + @echo " make check-clean Clean the tests" @echo @echo "Please note that HTML reports do not regenerate if the unit tests" @echo "has not changed." @@ -252,8 +253,10 @@ check-report.html: check-report.xml # Other tests +QEMU_IOTESTS_HELPERS-$(CONFIG_LINUX) = tests/qemu-iotests/socket_scm_helper$(EXESUF) + .PHONY: check-tests/qemu-iotests-quick.sh -check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF) tests/qemu-iotests/socket_scm_helper$(EXESUF) +check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF) $(QEMU_IOTESTS_HELPERS-y) $< .PHONY: check-tests/test-qapi.py @@ -268,12 +271,21 @@ $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json # Consolidated targets -.PHONY: check-qapi-schema check-qtest check-unit check +.PHONY: check-qapi-schema check-qtest check-unit check check-clean check-qapi-schema: $(patsubst %,check-%, $(check-qapi-schema-y)) check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS)) check-unit: $(patsubst %,check-%, $(check-unit-y)) check-block: $(patsubst %,check-%, $(check-block-y)) check: check-qapi-schema check-unit check-qtest +check-clean: + $(MAKE) -C tests/tcg clean + rm -rf $(check-unit-y) $(check-qtest-i386-y) $(check-qtest-x86_64-y) $(check-qtest-sparc64-y) $(check-qtest-sparc-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y) + +clean: check-clean + +# Build the help program automatically + +all: $(QEMU_IOTESTS_HELPERS-y) -include $(wildcard tests/*.d) -include $(wildcard tests/libqos/*.d) diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index 04bb236655..2839e32807 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -139,7 +139,10 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on -QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on: read-only not supported by this bus type +QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) QEMU_PROG: Can't use a read-only drive +QEMU_PROG: Device initialization failed. +QEMU_PROG: Initialization of device ide-hd failed Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on QEMU X.Y.Z monitor - type 'help' for more information
@@ -223,6 +226,6 @@ Testing: -drive file=foo:bar QEMU_PROG: -drive file=foo:bar: could not open disk image foo:bar: Unknown protocol 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 disk image ide0-hd0: Could not open file: No such file or directory *** done diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059 index dd6addfaab..b81c575d94 100755 --- a/tests/qemu-iotests/059 +++ b/tests/qemu-iotests/059 @@ -47,30 +47,34 @@ capacity_offset=16 granularity_offset=20 grain_table_size_offset=44 -echo "=== Testing invalid granularity ===" echo +echo "=== Testing invalid granularity ===" _make_test_img 64M poke_file "$TEST_IMG" "$granularity_offset" "\xff\xff\xff\xff\xff\xff\xff\xff" { $QEMU_IO -c "read 0 512" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir -echo "=== Testing too big L2 table size ===" echo +echo "=== Testing too big L2 table size ===" _make_test_img 64M poke_file "$TEST_IMG" "$grain_table_size_offset" "\xff\xff\xff\xff" { $QEMU_IO -c "read 0 512" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir -echo "=== Testing too big L1 table size ===" echo +echo "=== Testing too big L1 table size ===" _make_test_img 64M poke_file "$TEST_IMG" "$capacity_offset" "\xff\xff\xff\xff" poke_file "$TEST_IMG" "$grain_table_size_offset" "\x01\x00\x00\x00" { $QEMU_IO -c "read 0 512" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir -echo "=== Testing monolithicFlat creation and opening ===" echo +echo "=== Testing monolithicFlat creation and opening ===" IMGOPTS="subformat=monolithicFlat" _make_test_img 2G $QEMU_IMG info $TEST_IMG | _filter_testdir +echo +echo "=== Testing monolithicFlat with zeroed_grain ===" +IMGOPTS="subformat=monolithicFlat,zeroed_grain=on" _make_test_img 2G + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out index 9159dbec60..9b12efb466 100644 --- a/tests/qemu-iotests/059.out +++ b/tests/qemu-iotests/059.out @@ -1,27 +1,29 @@ QA output created by 059 -=== Testing invalid granularity === +=== Testing invalid granularity === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 -invalid granularity, image may be corrupt -qemu-io: can't open device TEST_DIR/t.vmdk: Could not open 'TEST_DIR/t.vmdk': Wrong medium type +qemu-io: can't open device TEST_DIR/t.vmdk: Invalid granularity, image may be corrupt no file open, try 'help open' -=== Testing too big L2 table size === +=== Testing too big L2 table size === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 L2 table size too big qemu-io: can't open device TEST_DIR/t.vmdk: Could not open 'TEST_DIR/t.vmdk': Wrong medium type no file open, try 'help open' -=== Testing too big L1 table size === +=== Testing too big L1 table size === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 -L1 size too big -qemu-io: can't open device TEST_DIR/t.vmdk: Could not open 'TEST_DIR/t.vmdk': Wrong medium type +qemu-io: can't open device TEST_DIR/t.vmdk: L1 size too big no file open, try 'help open' -=== Testing monolithicFlat creation and opening === +=== Testing monolithicFlat creation and opening === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 image: TEST_DIR/t.vmdk file format: vmdk virtual size: 2.0G (2147483648 bytes) disk size: 4.0K + +=== Testing monolithicFlat with zeroed_grain === +qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 *** done diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index 9bbc43b706..bbb19090a1 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -21,10 +21,10 @@ # creator 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! @@ -47,9 +47,15 @@ rt_offset=65536 # 0x10000 (XXX: just an assumption) rb_offset=131072 # 0x20000 (XXX: just an assumption) l1_offset=196608 # 0x30000 (XXX: just an assumption) l2_offset=262144 # 0x40000 (XXX: just an assumption) +l2_offset_after_snapshot=524288 # 0x80000 (XXX: just an assumption) IMGOPTS="compat=1.1" +OPEN_RW="open -o overlap-check=all $TEST_IMG" +# Overlap checks are done before write operations only, therefore opening an +# image read-only makes the overlap-check option irrelevant +OPEN_RO="open -r $TEST_IMG" + echo echo "=== Testing L2 reference into L1 ===" echo @@ -65,16 +71,18 @@ _check_test_img ./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features # Try to write something, thereby forcing the corrupt bit to be set -$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io # The corrupt bit must now be set ./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features # Try to open the image R/W (which should fail) -$QEMU_IO -c "read 0 512" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir | _filter_imgfmt +$QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \ + | _filter_testdir \ + | _filter_imgfmt # Try to open it RO (which should succeed) -$QEMU_IO -c "read 0 512" -r "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "$OPEN_RO" -c "read 0 512" | _filter_qemu_io # We could now try to fix the image, but this would probably fail (how should an # L2 table linked onto the L1 table be fixed?) @@ -92,7 +100,7 @@ poke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01" poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00" _check_test_img ./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features -$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io ./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features # Try to fix it @@ -102,8 +110,33 @@ _check_test_img -r all ./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features # Look if it's really really fixed -$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io +./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features + +echo +echo "=== Testing cluster data reference into inactive L2 table ===" +echo +_make_test_img 64M +$QEMU_IO -c "$OPEN_RW" -c "write -P 1 0 512" | _filter_qemu_io +$QEMU_IMG snapshot -c foo "$TEST_IMG" +$QEMU_IO -c "$OPEN_RW" -c "write -P 2 0 512" | _filter_qemu_io +# The inactive L2 table remains at its old offset +poke_file "$TEST_IMG" "$l2_offset_after_snapshot" \ + "\x80\x00\x00\x00\x00\x04\x00\x00" +_check_test_img ./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$QEMU_IO -c "$OPEN_RW" -c "write -P 3 0 512" | _filter_qemu_io +./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +_check_test_img -r all +./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$QEMU_IO -c "$OPEN_RW" -c "write -P 4 0 512" | _filter_qemu_io +./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features + +# Check data +$QEMU_IO -c "$OPEN_RO" -c "read -P 4 0 512" | _filter_qemu_io +$QEMU_IMG snapshot -a foo "$TEST_IMG" +_check_test_img +$QEMU_IO -c "$OPEN_RO" -c "read -P 1 0 512" | _filter_qemu_io # success, all done echo "*** done" diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index 648f7437a2..6c7bdbb2f2 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -12,7 +12,6 @@ qcow2: Preventing invalid write on metadata (overlaps with active L1 table); ima write failed: Input/output error incompatible_features 0x2 qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write -no file open, try 'help open' read 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -40,4 +39,43 @@ incompatible_features 0x0 wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) incompatible_features 0x0 + +=== Testing cluster data reference into inactive L2 table === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +wrote 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +ERROR cluster 4 refcount=1 reference=2 +Leaked cluster 9 refcount=1 reference=0 + +1 errors were found on the image. +Data may be corrupted, or further writes to the image may corrupt it. + +1 leaked clusters were found on the image. +This means waste of disk space, but no harm to data. +incompatible_features 0x0 +qcow2: Preventing invalid write on metadata (overlaps with inactive L2 table); image marked as corrupt. +write failed: Input/output error +incompatible_features 0x2 +Repairing cluster 4 refcount=1 reference=2 +Repairing cluster 9 refcount=1 reference=0 +Repairing OFLAG_COPIED data cluster: l2_entry=8000000000040000 refcount=2 +The following inconsistencies were found and repaired: + + 1 leaked clusters + 2 corruptions + +Double checking the fixed image now... +No errors were found on the image. +incompatible_features 0x0 +wrote 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +incompatible_features 0x0 +read 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +No errors were found on the image. +read 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) *** done diff --git a/tests/qemu-iotests/064 b/tests/qemu-iotests/064 new file mode 100755 index 0000000000..6789aa6ee4 --- /dev/null +++ b/tests/qemu-iotests/064 @@ -0,0 +1,62 @@ +#!/bin/bash +# +# Test VHDX read/write from a sample image created with Hyper-V +# +# Copyright (C) 2013 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=jcody@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt vhdx +_supported_proto generic +_supported_os Linux + +_use_sample_img iotest-dynamic-1G.vhdx.bz2 + +echo +echo "=== Verify pattern 0xa5, 0 - 33MB ===" +$QEMU_IO -r -c "read -pP 0xa5 0 33M" "$TEST_IMG" | _filter_qemu_io + +echo +echo "=== Verify pattern 0x96, 33M - 66M ===" +$QEMU_IO -r -c "read -pP 0x96 33M 33M" "$TEST_IMG" | _filter_qemu_io + +echo +echo "=== Verify pattern 0x00, 66M - 1024M ===" +$QEMU_IO -r -c "read -pP 0x00 66M 958M" "$TEST_IMG" | _filter_qemu_io + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/064.out b/tests/qemu-iotests/064.out new file mode 100644 index 0000000000..b9e8e4a873 --- /dev/null +++ b/tests/qemu-iotests/064.out @@ -0,0 +1,14 @@ +QA output created by 064 + +=== Verify pattern 0xa5, 0 - 33MB === +read 34603008/34603008 bytes at offset 0 +33 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=== Verify pattern 0x96, 33M - 66M === +read 34603008/34603008 bytes at offset 34603008 +33 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=== Verify pattern 0x00, 66M - 1024M === +read 1004535808/1004535808 bytes at offset 69206016 +958 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +*** done diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065 new file mode 100755 index 0000000000..ab5445f62d --- /dev/null +++ b/tests/qemu-iotests/065 @@ -0,0 +1,125 @@ +#!/usr/bin/env python2 +# +# Test for additional information emitted by qemu-img info on qcow2 +# images +# +# Copyright (C) 2013 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 os +import re +import json +import iotests +from iotests import qemu_img, qemu_img_pipe +import unittest + +test_img = os.path.join(iotests.test_dir, 'test.img') + +class TestImageInfoSpecific(iotests.QMPTestCase): + '''Abstract base class for ImageInfoSpecific tests''' + + def setUp(self): + if self.img_options is None: + self.skipTest('Skipping abstract test class') + qemu_img('create', '-f', iotests.imgfmt, '-o', self.img_options, + test_img, '128K') + + def tearDown(self): + os.remove(test_img) + +class TestQemuImgInfo(TestImageInfoSpecific): + '''Abstract base class for qemu-img info tests''' + + img_options = None + json_compare = None + human_compare = None + + def test_json(self): + data = json.loads(qemu_img_pipe('info', '--output=json', test_img)) + data = data['format-specific'] + self.assertEqual(data['type'], iotests.imgfmt) + self.assertEqual(data['data'], self.json_compare) + + def test_human(self): + data = qemu_img_pipe('info', '--output=human', test_img).split('\n') + data = data[(data.index('Format specific information:') + 1) + :data.index('')] + for field in data: + self.assertTrue(re.match('^ {4}[^ ]', field) is not None) + data = map(lambda line: line.strip(), data) + self.assertEqual(data, self.human_compare) + +class TestQMP(TestImageInfoSpecific): + '''Abstract base class for qemu QMP tests''' + + img_options = None + qemu_options = '' + TestImageInfoSpecific = TestImageInfoSpecific + + def setUp(self): + self.TestImageInfoSpecific.setUp(self) + self.vm = iotests.VM().add_drive(test_img, self.qemu_options) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + self.TestImageInfoSpecific.tearDown(self) + + def test_qmp(self): + result = self.vm.qmp('query-block')['return'] + drive = filter(lambda drive: drive['device'] == 'drive0', result)[0] + data = drive['inserted']['image']['format-specific'] + self.assertEqual(data['type'], iotests.imgfmt) + self.assertEqual(data['data'], self.compare) + +class TestQCow2(TestQemuImgInfo): + '''Testing a qcow2 version 2 image''' + img_options = 'compat=0.10' + json_compare = { 'compat': '0.10' } + human_compare = [ 'compat: 0.10' ] + +class TestQCow3NotLazy(TestQemuImgInfo): + '''Testing a qcow2 version 3 image with lazy refcounts disabled''' + img_options = 'compat=1.1,lazy_refcounts=off' + json_compare = { 'compat': '1.1', 'lazy-refcounts': False } + human_compare = [ 'compat: 1.1', 'lazy refcounts: false' ] + +class TestQCow3Lazy(TestQemuImgInfo): + '''Testing a qcow2 version 3 image with lazy refcounts enabled''' + img_options = 'compat=1.1,lazy_refcounts=on' + json_compare = { 'compat': '1.1', 'lazy-refcounts': True } + human_compare = [ 'compat: 1.1', 'lazy refcounts: true' ] + +class TestQCow3NotLazyQMP(TestQMP): + '''Testing a qcow2 version 3 image with lazy refcounts disabled, opening + with lazy refcounts enabled''' + img_options = 'compat=1.1,lazy_refcounts=off' + qemu_options = 'lazy-refcounts=on' + compare = { 'compat': '1.1', 'lazy-refcounts': False } + +class TestQCow3LazyQMP(TestQMP): + '''Testing a qcow2 version 3 image with lazy refcounts enabled, opening + with lazy refcounts disabled''' + img_options = 'compat=1.1,lazy_refcounts=on' + qemu_options = 'lazy-refcounts=off' + compare = { 'compat': '1.1', 'lazy-refcounts': True } + +TestImageInfoSpecific = None +TestQemuImgInfo = None +TestQMP = None + +if __name__ == '__main__': + iotests.main(supported_fmts=['qcow2']) diff --git a/tests/qemu-iotests/065.out b/tests/qemu-iotests/065.out new file mode 100644 index 0000000000..594c16f49f --- /dev/null +++ b/tests/qemu-iotests/065.out @@ -0,0 +1,5 @@ +........ +---------------------------------------------------------------------- +Ran 8 tests + +OK diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066 new file mode 100755 index 0000000000..1c2452b0c5 --- /dev/null +++ b/tests/qemu-iotests/066 @@ -0,0 +1,63 @@ +#!/bin/bash +# +# Test case for discarding preallocated zero clusters in qcow2 +# +# Copyright (C) 2013 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! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +# This tests qocw2-specific low-level functionality +_supported_fmt qcow2 +_supported_proto generic +_supported_os Linux + +IMGOPTS="compat=1.1" +IMG_SIZE=64M + +echo +echo "=== Testing snapshotting an image with zero clusters ===" +echo +_make_test_img $IMG_SIZE +# Write some normal clusters, zero them (creating preallocated zero clusters) +# and discard those +$QEMU_IO -c "write 0 256k" -c "write -z 0 256k" -c "discard 0 256k" "$TEST_IMG" \ + | _filter_qemu_io +# Check the image (there shouldn't be any leaks) +_check_test_img + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/066.out b/tests/qemu-iotests/066.out new file mode 100644 index 0000000000..9139780f49 --- /dev/null +++ b/tests/qemu-iotests/066.out @@ -0,0 +1,13 @@ +QA output created by 066 + +=== Testing snapshotting an image with zero clusters === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +wrote 262144/262144 bytes at offset 0 +256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 262144/262144 bytes at offset 0 +256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +discard 262144/262144 bytes at offset 0 +256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +No errors were found on the image. +*** done diff --git a/tests/qemu-iotests/067 b/tests/qemu-iotests/067 new file mode 100755 index 0000000000..79dc38bc04 --- /dev/null +++ b/tests/qemu-iotests/067 @@ -0,0 +1,133 @@ +#!/bin/bash +# +# Test automatic deletion of BDSes created by -drive/drive_add +# +# Copyright (C) 2013 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=kwolf@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux + +function do_run_qemu() +{ + echo Testing: "$@" + $QEMU -nographic -qmp stdio -serial none "$@" + echo +} + +function run_qemu() +{ + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp +} + +size=128M + +_make_test_img $size + +echo +echo === -drive/-device and device_del === +echo + +run_qemu -drive file=$TEST_IMG,format=$IMGFMT,if=none,id=disk -device virtio-blk-pci,drive=disk,id=virtio0 <<EOF +{ "execute": "qmp_capabilities" } +{ "execute": "query-block" } +{ "execute": "device_del", "arguments": { "id": "virtio0" } } +{ "execute": "system_reset" } +{ "execute": "query-block" } +{ "execute": "quit" } +EOF + +echo +echo === -drive/device_add and device_del === +echo + +run_qemu -drive file=$TEST_IMG,format=$IMGFMT,if=none,id=disk <<EOF +{ "execute": "qmp_capabilities" } +{ "execute": "query-block" } +{ "execute": "device_add", + "arguments": { "driver": "virtio-blk-pci", "drive": "disk", + "id": "virtio0" } } +{ "execute": "device_del", "arguments": { "id": "virtio0" } } +{ "execute": "system_reset" } +{ "execute": "query-block" } +{ "execute": "quit" } +EOF + +echo +echo === drive_add/device_add and device_del === +echo + +run_qemu <<EOF +{ "execute": "qmp_capabilities" } +{ "execute": "human-monitor-command", + "arguments": { "command-line": "drive_add 0 file=$TEST_IMG,format=$IMGFMT,if=none,id=disk" } } +{ "execute": "query-block" } +{ "execute": "device_add", + "arguments": { "driver": "virtio-blk-pci", "drive": "disk", + "id": "virtio0" } } +{ "execute": "device_del", "arguments": { "id": "virtio0" } } +{ "execute": "system_reset" } +{ "execute": "query-block" } +{ "execute": "quit" } +EOF + +echo +echo === blockdev_add/device_add and device_del === +echo + +run_qemu <<EOF +{ "execute": "qmp_capabilities" } +{ "execute": "blockdev-add", + "arguments": { + "options": { + "driver": "$IMGFMT", + "id": "disk", + "file": { + "driver": "file", + "filename": "$TEST_IMG" + } + } + } + } +{ "execute": "query-block" } +{ "execute": "device_add", + "arguments": { "driver": "virtio-blk-pci", "drive": "disk", + "id": "virtio0" } } +{ "execute": "device_del", "arguments": { "id": "virtio0" } } +{ "execute": "system_reset" } +{ "execute": "query-block" } +{ "execute": "quit" } +EOF + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out new file mode 100644 index 0000000000..4bb9ff9652 --- /dev/null +++ b/tests/qemu-iotests/067.out @@ -0,0 +1,80 @@ +QA output created by 067 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 + +=== -drive/-device and device_del === + +Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virtio-blk-pci,drive=disk,id=virtio0 +QMP_VERSION +{"return": {}} +{"return": [{"io-status": "ok", "device": "disk", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 139264, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} +{"return": {}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"} +{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} +{"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}} + + +=== -drive/device_add and device_del === + +Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk +QMP_VERSION +{"return": {}} +{"return": [{"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 139264, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} +{"return": {}} +{"return": {}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"} +{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} +{"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}} + + +=== drive_add/device_add and device_del === + +Testing: +QMP_VERSION +{"return": {}} +{"return": "OK\r\n"} +{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 139264, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]} +{"return": {}} +{"return": {}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"} +{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} +{"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}} + + +=== blockdev_add/device_add and device_del === + +Testing: +QMP_VERSION +{"return": {}} +{"return": {}} +{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 139264, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]} +{"return": {}} +{"return": {}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"} +{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 139264, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]} +{"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/qemu-iotests/common b/tests/qemu-iotests/common index fecaf85074..2932e14e73 100644 --- a/tests/qemu-iotests/common +++ b/tests/qemu-iotests/common @@ -45,6 +45,7 @@ valgrind=false rm -f $tmp.list $tmp.tmp $tmp.sed export IMGFMT=raw +export IMGFMT_GENERIC=true export IMGPROTO=file export IMGOPTS="" export QEMU_IO_OPTIONS="" @@ -133,6 +134,7 @@ check options -qed test qed -vdi test vdi -vpc test vpc + -vhdx test vhdx -vmdk test vmdk -rbd test rbd -sheepdog test sheepdog @@ -195,6 +197,12 @@ testlist options xpand=false ;; + -vhdx) + IMGFMT=vhdx + xpand=false + IMGFMT_GENERIC=false + ;; + -rbd) IMGPROTO=rbd xpand=false diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index 5dfda63e59..8e7b1a4195 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -159,5 +159,13 @@ _filter_qemu() -e 's#^QEMU [0-9]\+\.[0-9]\+\.[0-9]\+ monitor#QEMU X.Y.Z monitor#' } +# replace problematic QMP output like timestamps +_filter_qmp() +{ + _filter_win32 | \ + sed -e 's#\("\(micro\)\?seconds": \)[0-9]\+#\1 TIMESTAMP#g' \ + -e 's#^{"QMP":.*}$#QMP_VERSION#' +} + # make sure this script returns success /bin/true diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 1b22db04f4..4e826040d4 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -197,12 +197,30 @@ _check_test_img() _img_info() { + discard=0 + regex_json_spec_start='^ *"format-specific": \{' $QEMU_IMG info "$@" "$TEST_IMG" 2>&1 | \ sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \ -e "s#$TEST_DIR#TEST_DIR#g" \ -e "s#$IMGFMT#IMGFMT#g" \ -e "/^disk size:/ D" \ - -e "/actual-size/ D" + -e "/actual-size/ D" | \ + while IFS='' read line; do + if [[ $line == "Format specific information:" ]]; then + discard=1 + elif [[ $line =~ $regex_json_spec_start ]]; then + discard=2 + regex_json_spec_end="^${line%%[^ ]*}\\},? *$" + fi + if [[ $discard == 0 ]]; then + echo "$line" + elif [[ $discard == 1 && ! $line ]]; then + echo + discard=0 + elif [[ $discard == 2 && $line =~ $regex_json_spec_end ]]; then + discard=0 + fi + done } _get_pids_by_name() @@ -321,7 +339,7 @@ _fail() _supported_fmt() { for f; do - if [ "$f" = "$IMGFMT" -o "$f" = "generic" ]; then + if [ "$f" = "$IMGFMT" -o "$f" = "generic" -a "$IMGFMT_GENERIC" = "true" ]; then return fi done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 1ad02e5a2c..13c5500f54 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -69,3 +69,7 @@ 061 rw auto 062 rw auto 063 rw auto +064 rw auto +065 rw auto +066 rw auto +067 rw auto diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 376d6e8ffe..fb10ff43a7 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -49,6 +49,10 @@ def qemu_img_verbose(*args): '''Run qemu-img without suppressing its output and return the exit code''' return subprocess.call(qemu_img_args + list(args)) +def qemu_img_pipe(*args): + '''Run qemu-img and return its output''' + return subprocess.Popen(qemu_img_args + list(args), stdout=subprocess.PIPE).communicate()[0] + def qemu_io(*args): '''Run qemu-io and return the stdout data''' args = qemu_io_args + list(args) diff --git a/tests/qemu-iotests/sample_images/iotest-dynamic-1G.vhdx.bz2 b/tests/qemu-iotests/sample_images/iotest-dynamic-1G.vhdx.bz2 Binary files differnew file mode 100644 index 0000000000..77d97a0bae --- /dev/null +++ b/tests/qemu-iotests/sample_images/iotest-dynamic-1G.vhdx.bz2 |