iotests: Add filter commit test cases

This patch adds some tests on how commit copes with filter nodes.

Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
Max Reitz 2018-08-01 20:43:46 +02:00 committed by Kevin Wolf
parent c682bf18c9
commit ffbba7fd11
2 changed files with 179 additions and 2 deletions

View File

@ -734,6 +734,183 @@ class TestErrorHandling(iotests.QMPTestCase):
self.assertTrue(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
'target image does not match source after commit')
class TestCommitWithFilters(iotests.QMPTestCase):
img0 = os.path.join(iotests.test_dir, '0.img')
img1 = os.path.join(iotests.test_dir, '1.img')
img2 = os.path.join(iotests.test_dir, '2.img')
img3 = os.path.join(iotests.test_dir, '3.img')
def do_test_io(self, read_or_write):
for index, pattern_file in enumerate(self.pattern_files):
result = qemu_io('-f', iotests.imgfmt,
'-c',
f'{read_or_write} -P {index + 1} {index}M 1M',
pattern_file)
self.assertFalse('Pattern verification failed' in result)
def setUp(self):
qemu_img('create', '-f', iotests.imgfmt, self.img0, '64M')
qemu_img('create', '-f', iotests.imgfmt, self.img1, '64M')
qemu_img('create', '-f', iotests.imgfmt, self.img2, '64M')
qemu_img('create', '-f', iotests.imgfmt, self.img3, '64M')
# Distributions of the patterns in the files; this is checked
# by tearDown() and should be changed by the test cases as is
# necessary
self.pattern_files = [self.img0, self.img1, self.img2, self.img3]
self.do_test_io('write')
self.vm = iotests.VM().add_device('virtio-scsi,id=vio-scsi')
self.vm.launch()
result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-add', **{
'node-name': 'top-filter',
'driver': 'throttle',
'throttle-group': 'tg',
'file': {
'node-name': 'cow-3',
'driver': iotests.imgfmt,
'file': {
'driver': 'file',
'filename': self.img3
},
'backing': {
'node-name': 'cow-2',
'driver': iotests.imgfmt,
'file': {
'driver': 'file',
'filename': self.img2
},
'backing': {
'node-name': 'cow-1',
'driver': iotests.imgfmt,
'file': {
'driver': 'file',
'filename': self.img1
},
'backing': {
'node-name': 'bottom-filter',
'driver': 'throttle',
'throttle-group': 'tg',
'file': {
'node-name': 'cow-0',
'driver': iotests.imgfmt,
'file': {
'driver': 'file',
'filename': self.img0
}
}
}
}
}
}
})
self.assert_qmp(result, 'return', {})
def tearDown(self):
self.vm.shutdown()
self.do_test_io('read')
os.remove(self.img3)
os.remove(self.img2)
os.remove(self.img1)
os.remove(self.img0)
# Filters make for funny filenames, so we cannot just use
# self.imgX to get them
def get_filename(self, node):
return self.vm.node_info(node)['image']['filename']
def test_filterless_commit(self):
result = self.vm.qmp('block-commit',
job_id='commit',
device='top-filter',
top_node='cow-2',
base_node='cow-1')
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='commit')
self.assertIsNotNone(self.vm.node_info('cow-3'))
self.assertIsNone(self.vm.node_info('cow-2'))
self.assertIsNotNone(self.vm.node_info('cow-1'))
# 2 has been comitted into 1
self.pattern_files[2] = self.img1
def test_commit_through_filter(self):
result = self.vm.qmp('block-commit',
job_id='commit',
device='top-filter',
top_node='cow-1',
base_node='cow-0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='commit')
self.assertIsNotNone(self.vm.node_info('cow-2'))
self.assertIsNone(self.vm.node_info('cow-1'))
self.assertIsNone(self.vm.node_info('bottom-filter'))
self.assertIsNotNone(self.vm.node_info('cow-0'))
# 1 has been comitted into 0
self.pattern_files[1] = self.img0
def test_filtered_active_commit_with_filter(self):
# Add a device, so the commit job finds a parent it can change
# to point to the base node (so we can test that top-filter is
# dropped from the graph)
result = self.vm.qmp('device_add', id='drv0', driver='scsi-hd',
bus='vio-scsi.0', drive='top-filter')
self.assert_qmp(result, 'return', {})
# Try to release our reference to top-filter; that should not
# work because drv0 uses it
result = self.vm.qmp('blockdev-del', node_name='top-filter')
self.assert_qmp(result, 'error/class', 'GenericError')
self.assert_qmp(result, 'error/desc', 'Node top-filter is in use')
result = self.vm.qmp('block-commit',
job_id='commit',
device='top-filter',
base_node='cow-2')
self.assert_qmp(result, 'return', {})
self.complete_and_wait(drive='commit')
# Try to release our reference to top-filter again
result = self.vm.qmp('blockdev-del', node_name='top-filter')
self.assert_qmp(result, 'return', {})
self.assertIsNone(self.vm.node_info('top-filter'))
self.assertIsNone(self.vm.node_info('cow-3'))
self.assertIsNotNone(self.vm.node_info('cow-2'))
# Check that drv0 is now connected to cow-2
blockdevs = self.vm.qmp('query-block')['return']
drv0 = next(dev for dev in blockdevs if dev['qdev'] == 'drv0')
self.assertEqual(drv0['inserted']['node-name'], 'cow-2')
# 3 has been comitted into 2
self.pattern_files[3] = self.img2
def test_filtered_active_commit_without_filter(self):
result = self.vm.qmp('block-commit',
job_id='commit',
device='top-filter',
top_node='cow-3',
base_node='cow-2')
self.assert_qmp(result, 'return', {})
self.complete_and_wait(drive='commit')
self.assertIsNotNone(self.vm.node_info('top-filter'))
self.assertIsNone(self.vm.node_info('cow-3'))
self.assertIsNotNone(self.vm.node_info('cow-2'))
# 3 has been comitted into 2
self.pattern_files[3] = self.img2
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'qed'],
supported_protocols=['file'])

View File

@ -1,5 +1,5 @@
...........................................................
...............................................................
----------------------------------------------------------------------
Ran 59 tests
Ran 63 tests
OK