iotests: add transactional failure race test

Add a regression test for the case found by Vladimir.

Reported-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 1478587839-9834-7-git-send-email-jsnow@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
This commit is contained in:
John Snow 2016-11-08 01:50:39 -05:00 committed by Jeff Cody
parent 111049a4ec
commit 0aef09b9c9
2 changed files with 37 additions and 20 deletions

View file

@ -395,19 +395,7 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
self.check_backups()
def test_transaction_failure(self):
'''Test: Verify backups made from a transaction that partially fails.
Add a second drive with its own unique pattern, and add a bitmap to each
drive. Use blkdebug to interfere with the backup on just one drive and
attempt to create a coherent incremental backup across both drives.
verify a failure in one but not both, then delete the failed stubs and
re-run the same transaction.
verify that both incrementals are created successfully.
'''
def do_transaction_failure_test(self, race=False):
# Create a second drive, with pattern:
drive1 = self.add_node('drive1')
self.img_create(drive1['file'], drive1['fmt'])
@ -451,9 +439,10 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
self.assertFalse(self.vm.get_qmp_events(wait=False))
# Emulate some writes
self.hmp_io_writes(drive0['id'], (('0xab', 0, 512),
('0xfe', '16M', '256k'),
('0x64', '32736k', '64k')))
if not race:
self.hmp_io_writes(drive0['id'], (('0xab', 0, 512),
('0xfe', '16M', '256k'),
('0x64', '32736k', '64k')))
self.hmp_io_writes(drive1['id'], (('0xba', 0, 512),
('0xef', '16M', '256k'),
('0x46', '32736k', '64k')))
@ -463,7 +452,8 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
target1 = self.prepare_backup(dr1bm0)
# Ask for a new incremental backup per-each drive,
# expecting drive1's backup to fail:
# expecting drive1's backup to fail. In the 'race' test,
# we expect drive1 to attempt to cancel the empty drive0 job.
transaction = [
transaction_drive_backup(drive0['id'], target0, sync='incremental',
format=drive0['fmt'], mode='existing',
@ -488,9 +478,15 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
self.assert_no_active_block_jobs()
# Delete drive0's successful target and eliminate our record of the
# unsuccessful drive1 target. Then re-run the same transaction.
# unsuccessful drive1 target.
dr0bm0.del_target()
dr1bm0.del_target()
if race:
# Don't re-run the transaction, we only wanted to test the race.
self.vm.shutdown()
return
# Re-run the same transaction:
target0 = self.prepare_backup(dr0bm0)
target1 = self.prepare_backup(dr1bm0)
@ -511,6 +507,27 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
self.vm.shutdown()
self.check_backups()
def test_transaction_failure(self):
'''Test: Verify backups made from a transaction that partially fails.
Add a second drive with its own unique pattern, and add a bitmap to each
drive. Use blkdebug to interfere with the backup on just one drive and
attempt to create a coherent incremental backup across both drives.
verify a failure in one but not both, then delete the failed stubs and
re-run the same transaction.
verify that both incrementals are created successfully.
'''
self.do_transaction_failure_test()
def test_transaction_failure_race(self):
'''Test: Verify that transactions with jobs that have no data to
transfer do not cause race conditions in the cancellation of the entire
transaction job group.
'''
self.do_transaction_failure_test(race=True)
def test_sync_dirty_bitmap_missing(self):
self.assert_no_active_block_jobs()

View file

@ -1,5 +1,5 @@
..........
...........
----------------------------------------------------------------------
Ran 10 tests
Ran 11 tests
OK