From: Alberto Garcia <be...@igalia.com> These test cases check that it's not possible to perform two block-stream or block-commit operations if there are nodes involved in both.
Signed-off-by: Alberto Garcia <be...@igalia.com> Reviewed-by: Kevin Wolf <kw...@redhat.com> Signed-off-by: Kevin Wolf <kw...@redhat.com> --- tests/qemu-iotests/030 | 89 ++++++++++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/030.out | 4 +-- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index ba9a541..3533495 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -228,6 +228,95 @@ class TestParallelOps(iotests.QMPTestCase): qemu_io('-f', iotests.imgfmt, '-c', 'map', self.imgs[i-1]), 'image file map does not match backing file after streaming') + # Test that it's not possible to perform two block-stream + # operations if there are nodes involved in both. + def test_overlapping_1(self): + self.assert_no_active_block_jobs() + + # Set a speed limit to make sure that this job blocks the rest + result = self.vm.qmp('block-stream', device='node4', job_id='stream-node4', base=self.imgs[1], speed=1024*1024) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('block-stream', device='node5', job_id='stream-node5', base=self.imgs[2]) + self.assert_qmp(result, 'error/class', 'GenericError') + + result = self.vm.qmp('block-stream', device='node3', job_id='stream-node3', base=self.imgs[2]) + self.assert_qmp(result, 'error/class', 'GenericError') + + result = self.vm.qmp('block-stream', device='node4', job_id='stream-node4-v2') + self.assert_qmp(result, 'error/class', 'GenericError') + + # block-commit should also fail if it touches nodes used by the stream job + result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[4], job_id='commit-node4') + self.assert_qmp(result, 'error/class', 'GenericError') + + result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[1], top=self.imgs[3], job_id='commit-node1') + self.assert_qmp(result, 'error/class', 'GenericError') + + # This fails because it needs to modify the backing string in node2, which is blocked + result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[0], top=self.imgs[1], job_id='commit-node0') + self.assert_qmp(result, 'error/class', 'GenericError') + + self.wait_until_completed(drive='stream-node4') + self.assert_no_active_block_jobs() + + # Similar to test_overlapping_1, but with block-commit + # blocking the other jobs + def test_overlapping_2(self): + self.assertLessEqual(9, self.num_imgs) + self.assert_no_active_block_jobs() + + # Set a speed limit to make sure that this job blocks the rest + result = self.vm.qmp('block-commit', device='drive0', top=self.imgs[5], base=self.imgs[3], job_id='commit-node3', speed=1024*1024) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('block-stream', device='node3', job_id='stream-node3') + self.assert_qmp(result, 'error/class', 'GenericError') + + result = self.vm.qmp('block-stream', device='node6', base=self.imgs[2], job_id='stream-node6') + self.assert_qmp(result, 'error/class', 'GenericError') + + result = self.vm.qmp('block-stream', device='node4', base=self.imgs[2], job_id='stream-node4') + self.assert_qmp(result, 'error/class', 'GenericError') + + result = self.vm.qmp('block-stream', device='node6', base=self.imgs[4], job_id='stream-node6-v2') + self.assert_qmp(result, 'error/class', 'GenericError') + + # This fails because block-commit needs to block node6, the overlay of the 'top' image + result = self.vm.qmp('block-stream', device='node7', base=self.imgs[5], job_id='stream-node6-v3') + self.assert_qmp(result, 'error/class', 'GenericError') + + # This fails because block-commit currently blocks the active layer even if it's not used + result = self.vm.qmp('block-stream', device='drive0', base=self.imgs[5], job_id='stream-drive0') + self.assert_qmp(result, 'error/class', 'GenericError') + + self.wait_until_completed(drive='commit-node3') + + # Similar to test_overlapping_2, but here block-commit doesn't use the 'top' parameter. + # Internally this uses a mirror block job, hence the separate test case. + def test_overlapping_3(self): + self.assertLessEqual(8, self.num_imgs) + self.assert_no_active_block_jobs() + + # Set a speed limit to make sure that this job blocks the rest + result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[3], job_id='commit-drive0', speed=1024*1024) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('block-stream', device='node5', base=self.imgs[3], job_id='stream-node6') + self.assert_qmp(result, 'error/class', 'GenericError') + + event = self.vm.get_qmp_event(wait=True) + self.assertEqual(event['event'], 'BLOCK_JOB_READY') + self.assert_qmp(event, 'data/device', 'commit-drive0') + self.assert_qmp(event, 'data/type', 'commit') + self.assert_qmp_absent(event, 'data/error') + + result = self.vm.qmp('block-job-complete', device='commit-drive0') + self.assert_qmp(result, 'return', {}) + + self.wait_until_completed(drive='commit-drive0') + self.assert_no_active_block_jobs() + class TestSmallerBackingFile(iotests.QMPTestCase): backing_len = 1 * 1024 * 1024 # MB image_len = 2 * backing_len diff --git a/tests/qemu-iotests/030.out b/tests/qemu-iotests/030.out index b6f2576..4176bb9 100644 --- a/tests/qemu-iotests/030.out +++ b/tests/qemu-iotests/030.out @@ -1,5 +1,5 @@ -................ +................... ---------------------------------------------------------------------- -Ran 16 tests +Ran 19 tests OK -- 1.8.3.1