From patchwork Tue Feb 10 01:35:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 438140 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E9CE6140077 for ; Tue, 10 Feb 2015 12:43:55 +1100 (AEDT) Received: from localhost ([::1]:36165 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKzrm-0000CX-6U for incoming@patchwork.ozlabs.org; Mon, 09 Feb 2015 20:43:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41500) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKzlO-0005Vp-3r for qemu-devel@nongnu.org; Mon, 09 Feb 2015 20:37:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YKzlK-0003R0-S0 for qemu-devel@nongnu.org; Mon, 09 Feb 2015 20:37:18 -0500 Received: from mx1.redhat.com ([209.132.183.28]:45723) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKzlK-0003Qq-L1 for qemu-devel@nongnu.org; Mon, 09 Feb 2015 20:37:14 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t1A1bDVU014198 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 9 Feb 2015 20:37:14 -0500 Received: from scv.usersys.redhat.com (vpn-57-228.rdu2.redhat.com [10.10.57.228]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t1A1ZcgR026319; Mon, 9 Feb 2015 20:37:10 -0500 From: John Snow To: qemu-devel@nongnu.org Date: Mon, 9 Feb 2015 20:35:17 -0500 Message-Id: <1423532117-14490-18-git-send-email-jsnow@redhat.com> In-Reply-To: <1423532117-14490-1-git-send-email-jsnow@redhat.com> References: <1423532117-14490-1-git-send-email-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, famz@redhat.com, John Snow , armbru@redhat.com, mreitz@redhat.com, vsementsov@parallels.com, stefanha@redhat.com Subject: [Qemu-devel] [PATCH v12 17/17] iotests: add incremental backup failure recovery test X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org To test the failure case, we modify iotests.py to allow us to specify that we'd like to allow failures when we wait for block job events. Signed-off-by: John Snow --- tests/qemu-iotests/112 | 55 ++++++++++++++++++++++++++++++++++++++++++- tests/qemu-iotests/112.out | 4 ++-- tests/qemu-iotests/iotests.py | 6 +++-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/tests/qemu-iotests/112 b/tests/qemu-iotests/112 index 7d1a6ec..0c1d35a 100644 --- a/tests/qemu-iotests/112 +++ b/tests/qemu-iotests/112 @@ -24,6 +24,11 @@ import os import iotests from iotests import qemu_img, qemu_io, create_image +def blkdebug_rule(file, type, **kwargs): + file.write('[%s]\n' % type) + for key, value in kwargs.iteritems(): + file.write('%s = "%s"\n' % (key, value)) + file.write('\n') def io_write_patterns(img, patterns): for pattern in patterns: @@ -136,7 +141,11 @@ class TestIncrementalBackup(iotests.QMPTestCase): mode='existing') self.assert_qmp(result, 'return', {}) - event = self.wait_until_completed(bitmap.node, check_offset=validate) + event = self.wait_until_completed(bitmap.node, check_offset=validate, + allow_failures=(not validate)) + if 'error' in event['data']: + bitmap.del_target() + return False if validate: return self.check_incremental(target) @@ -221,6 +230,50 @@ class TestIncrementalBackup(iotests.QMPTestCase): self.assertTrue(res1 and res2) + def test_incremental_failure(self): + blkdebug = os.path.join(iotests.test_dir, 'blkdebug.conf') + self.files.append(blkdebug) + + with open(blkdebug, 'w+') as file: + blkdebug_rule(file, 'set-state', + event="flush_to_disk", + state="1", + new_state="2") + blkdebug_rule(file, 'inject-error', + event="read_aio", errno="5", + state="2", immediately="off", + once="on") + + # Create a blkdebug interface to this img as 'drive1' + result = self.vm.qmp('blockdev-add', options={ + 'id': 'drive1', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'blkdebug', + 'config': blkdebug, + 'image': { + 'driver': 'file', + 'filename': self.test_img + } + } + }) + self.assert_qmp(result, 'return', {}) + + self.create_full_backup() + self.add_bitmap('bitmap0', 'drive1') + self.vm.hmp("c") + self.hmp_io_writes('drive1', (('0xab', 0, 512), + ('0xfe', '16M', '256k'), + ('0x64', '32736k', '64k'))) + + result = self.create_incremental(validate=False) + self.assertFalse(result) + self.hmp_io_writes('drive1', (('0x9a', 0, 512), + ('0x55', '8M', '352k'), + ('0x78', '15872k', '1M'))) + self.create_incremental() + + def test_sync_dirty_bitmap_missing(self): self.assert_no_active_block_jobs() self.files.append(self.foo_img) diff --git a/tests/qemu-iotests/112.out b/tests/qemu-iotests/112.out index 89968f3..914e373 100644 --- a/tests/qemu-iotests/112.out +++ b/tests/qemu-iotests/112.out @@ -1,5 +1,5 @@ -.... +..... ---------------------------------------------------------------------- -Ran 4 tests +Ran 5 tests OK diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 6bff935..e452c40 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -264,14 +264,16 @@ class QMPTestCase(unittest.TestCase): self.assert_no_active_block_jobs() return result - def wait_until_completed(self, drive='drive0', check_offset=True): + def wait_until_completed(self, drive='drive0', check_offset=True, + allow_failures=False): '''Wait for a block job to finish, returning the event''' 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/device', drive) - self.assert_qmp_absent(event, 'data/error') + if not allow_failures: + self.assert_qmp_absent(event, 'data/error') if check_offset: self.assert_qmp(event, 'data/offset', event['data']['len']) completed = True