Am 18.10.2012 16:49, schrieb Paolo Bonzini: > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> > --- > v2->v3: new testcases test_cancel_after_ready and > test_medium_not_found, removed obsolete workaround > for os.remove failure. Fixed copyright header. > > tests/qemu-iotests/041 | 364 > +++++++++++++++++++++++++++++++++++++++++++++ > tests/qemu-iotests/041.out | 5 + > tests/qemu-iotests/group | 1 + > 3 file modificati, 370 inserzioni(+) > create mode 100755 tests/qemu-iotests/041 > create mode 100644 tests/qemu-iotests/041.out > > diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 > new file mode 100755 > index 0000000..ce99b00 > --- /dev/null > +++ b/tests/qemu-iotests/041 > @@ -0,0 +1,364 @@ > +#!/usr/bin/env python > +# > +# Tests for image mirroring. > +# > +# Copyright (C) 2012 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 time > +import os > +import iotests > +from iotests import qemu_img, qemu_io > +import struct > + > +backing_img = os.path.join(iotests.test_dir, 'backing.img') > +target_backing_img = os.path.join(iotests.test_dir, 'target-backing.img') > +test_img = os.path.join(iotests.test_dir, 'test.img') > +target_img = os.path.join(iotests.test_dir, 'target.img') > + > +class ImageMirroringTestCase(iotests.QMPTestCase): > + '''Abstract base class for image mirroring test cases''' > + > + def assert_no_active_mirrors(self): > + result = self.vm.qmp('query-block-jobs') > + self.assert_qmp(result, 'return', []) > + > + def cancel_and_wait(self, drive='drive0', wait_ready=True): > + '''Cancel a block job and wait for it to finish''' > + if wait_ready: > + ready = False > + while not ready: > + for event in self.vm.get_qmp_events(wait=True): > + if event['event'] == 'BLOCK_JOB_READY': > + self.assert_qmp(event, 'data/type', 'mirror') > + self.assert_qmp(event, 'data/device', drive) > + ready = True > + > + result = self.vm.qmp('block-job-cancel', device=drive, > + force=not wait_ready) > + self.assert_qmp(result, 'return', {}) > + > + cancelled = False > + while not cancelled: > + for event in self.vm.get_qmp_events(wait=True): > + if event['event'] == 'BLOCK_JOB_COMPLETED' or \ > + event['event'] == 'BLOCK_JOB_CANCELLED': > + self.assert_qmp(event, 'data/type', 'mirror') > + self.assert_qmp(event, 'data/device', drive) > + if wait_ready: > + self.assertEquals(event['event'], > 'BLOCK_JOB_COMPLETED') > + self.assert_qmp(event, 'data/offset', self.image_len) > + self.assert_qmp(event, 'data/len', self.image_len) > + cancelled = True > + > + self.assert_no_active_mirrors() > + > + def complete_and_wait(self, drive='drive0', wait_ready=True): > + '''Complete a block job and wait for it to finish''' > + if wait_ready: > + ready = False > + while not ready: > + for event in self.vm.get_qmp_events(wait=True): > + if event['event'] == 'BLOCK_JOB_READY': > + self.assert_qmp(event, 'data/type', 'mirror') > + self.assert_qmp(event, 'data/device', drive) > + ready = True > + > + result = self.vm.qmp('block-job-complete', device=drive) > + self.assert_qmp(result, 'return', {}) > + > + completed = False > + while not completed: > + for event in self.vm.get_qmp_events(wait=True): > + if event['event'] == 'BLOCK_JOB_COMPLETED': > + self.assert_qmp(event, 'data/type', 'mirror') > + self.assert_qmp(event, 'data/device', drive) > + self.assert_qmp_absent(event, 'data/error') > + self.assert_qmp(event, 'data/offset', self.image_len) > + self.assert_qmp(event, 'data/len', self.image_len) > + completed = True > + > + self.assert_no_active_mirrors() > + > + def create_image(self, name, size): > + file = open(name, 'w') > + i = 0 > + while i < size: > + sector = struct.pack('>l504xl', i / 512, i / 512) > + file.write(sector) > + i = i + 512 > + file.close() > + > + def compare_images(self, img1, img2): > + try: > + qemu_img('convert', '-f', iotests.imgfmt, '-O', 'raw', img1, > img1 + '.raw') > + qemu_img('convert', '-f', iotests.imgfmt, '-O', 'raw', img2, > img2 + '.raw') > + file1 = open(img1 + '.raw', 'r') > + file2 = open(img2 + '.raw', 'r') > + return file1.read() == file2.read() > + finally: > + if file1 is not None: > + file1.close() > + if file2 is not None: > + file2.close() > + try: > + os.remove(img1 + '.raw') > + except OSError: > + pass > + try: > + os.remove(img2 + '.raw') > + except OSError: > + pass > + > +class TestSingleDrive(ImageMirroringTestCase): > + image_len = 1 * 1024 * 1024 # MB > + > + def setUp(self): > + self.create_image(backing_img, TestSingleDrive.image_len) > + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % > backing_img, test_img) > + self.vm = iotests.VM().add_drive(test_img) > + self.vm.launch() > + > + def tearDown(self): > + self.vm.shutdown() > + os.remove(test_img) > + os.remove(backing_img) > + try: > + os.remove(target_img) > + except OSError: > + pass > + > + def test_complete(self): > + self.assert_no_active_mirrors() > + > + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', > + target=target_img) > + self.assert_qmp(result, 'return', {}) > + > + self.complete_and_wait() > + result = self.vm.qmp('query-block') > + self.assert_qmp(result, 'return[0]/inserted/file', target_img) > + self.vm.shutdown() > + self.assertTrue(self.compare_images(test_img, target_img), > + 'target image does not match source after mirroring') > + > + def test_cancel(self): > + self.assert_no_active_mirrors() > + > + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', > + target=target_img) > + self.assert_qmp(result, 'return', {}) > + > + self.cancel_and_wait(wait_ready=False) > + result = self.vm.qmp('query-block') > + self.assert_qmp(result, 'return[0]/inserted/file', test_img) > + self.vm.shutdown() > + self.assertTrue(self.compare_images(test_img, target_img), > + 'target image does not match source after mirroring')
Hm, shouldn't the image comparison actually fail when cancelling before the job was ready? Kevin