Test - start two vms (vm_a, vm_b) - in a - do writes from set A - do writes from set B - fix bitmap md5 - clear bitmap - do writes from set A - start migration - than, in b - wait vm start (postcopy should start) - do writes from set B - check btimap md5
The test should verify postcopy migration and than merging with delta (changes in target, during postcopy process). Reduce supported cache modes to only 'none', because with cache on time from source.STOP to target.RESUME is unpredictable and we can fail with timout while waiting for target.RESUME. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- tests/qemu-iotests/169 | 70 ++++++++++++++++++++++++++++++++++++------- tests/qemu-iotests/169.out | 4 +-- tests/qemu-iotests/group | 1 + tests/qemu-iotests/iotests.py | 7 ++++- 4 files changed, 69 insertions(+), 13 deletions(-) diff --git a/tests/qemu-iotests/169 b/tests/qemu-iotests/169 index d40be1d..31fe4b2 100755 --- a/tests/qemu-iotests/169 +++ b/tests/qemu-iotests/169 @@ -29,8 +29,14 @@ fifo = os.path.join(iotests.test_dir, 'mig_fifo') class TestDirtyBitmapMigration(iotests.QMPTestCase): - def setUp(self): - size = 0x400000000 # 1G + def tearDown(self): + self.vm_a.shutdown() + self.vm_b.shutdown() + os.remove(disk_a) + os.remove(disk_b) + os.remove(fifo) + + def init(self, size): os.mkfifo(fifo) qemu_img('create', '-f', iotests.imgfmt, disk_a, str(size)) qemu_img('create', '-f', iotests.imgfmt, disk_b, str(size)) @@ -40,14 +46,8 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase): self.vm_a.launch() self.vm_b.launch() - def tearDown(self): - self.vm_a.shutdown() - self.vm_b.shutdown() - os.remove(disk_a) - os.remove(disk_b) - os.remove(fifo) - def test_migration(self): + self.init(0x400000000) # 1G granularity = 512 regions = [ { 'start': 0, 'count': 0x100000 }, @@ -79,6 +79,56 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase): result = self.vm_b.qmp('query-block'); self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/md5', md5); + def test_postcopy(self): + self.init(0x4000000000) # 128G + write_size = 0x40000000 + granularity = 512 + chunk = 4096 + + result = self.vm_a.qmp('block-dirty-bitmap-add', node='drive0', + name='bitmap', granularity=granularity) + self.assert_qmp(result, 'return', {}); + + s = 0 + while s < write_size: + self.vm_a.hmp_qemu_io('drive0', 'write %d %d' % (s, chunk)) + s += 0x10000 + s = 0x8000 + while s < write_size: + self.vm_a.hmp_qemu_io('drive0', 'write %d %d' % (s, chunk)) + s += 0x10000 + + result = self.vm_a.qmp('query-block'); + md5 = result['return'][0]['dirty-bitmaps'][0]['md5'] + + result = self.vm_a.qmp('block-dirty-bitmap-clear', node='drive0', + name='bitmap') + self.assert_qmp(result, 'return', {}); + s = 0 + while s < write_size: + self.vm_a.hmp_qemu_io('drive0', 'write %d %d' % (s, chunk)) + s += 0x10000 + + result = self.vm_a.qmp('migrate-set-capabilities', + capabilities=[{'capability': 'dirty-bitmaps', + 'state': True}]) + self.assert_qmp(result, 'return', {}) + + result = self.vm_a.qmp('migrate', uri='exec:cat>' + fifo) + self.assertNotEqual(self.vm_a.event_wait("STOP"), None) + self.assertNotEqual(self.vm_b.event_wait("RESUME"), None) + + s = 0x8000 + while s < write_size: + self.vm_b.hmp_qemu_io('drive0', 'write %d %d' % (s, chunk)) + s += 0x10000 + + result = self.vm_b.qmp('query-block'); + while len(result['return'][0]['dirty-bitmaps']) > 1: + time.sleep(2) + result = self.vm_b.qmp('query-block'); + + self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/md5', md5); if __name__ == '__main__': - iotests.main() + iotests.main(supported_fmts=['qcow2'], supported_cache_modes=['none']) diff --git a/tests/qemu-iotests/169.out b/tests/qemu-iotests/169.out index ae1213e..fbc63e6 100644 --- a/tests/qemu-iotests/169.out +++ b/tests/qemu-iotests/169.out @@ -1,5 +1,5 @@ -. +.. ---------------------------------------------------------------------- -Ran 1 tests +Ran 2 tests OK diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index a939718..3355ce4 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -158,3 +158,4 @@ 156 rw auto quick 157 auto 169 rw auto quick +170 rw auto diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 0332589..5fa0603 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -320,12 +320,16 @@ def verify_platform(supported_oses=['linux']): if True not in [sys.platform.startswith(x) for x in supported_oses]: notrun('not suitable for this OS: %s' % sys.platform) +def verify_cache_mode(supported_cache_modes=[]): + if supported_cache_modes and (cachemode not in supported_cache_modes): + notrun('not suitable for this cache mode: %s' % cachemode) + def verify_quorum(): '''Skip test suite if quorum support is not available''' if 'quorum' not in qemu_img_pipe('--help'): notrun('quorum support missing') -def main(supported_fmts=[], supported_oses=['linux']): +def main(supported_fmts=[], supported_oses=['linux'], supported_cache_modes=[]): '''Run tests''' # We are using TEST_DIR and QEMU_DEFAULT_MACHINE as proxies to @@ -340,6 +344,7 @@ def main(supported_fmts=[], supported_oses=['linux']): verbosity = 1 verify_image_format(supported_fmts) verify_platform(supported_oses) + verify_cache_mode(supported_cache_modes) # We need to filter out the time taken from the output so that qemu-iotest # can reliably diff the results against master output. -- 1.8.3.1