def test_finalize(self, sd_type, chain_len, base_index, top_index): with self.make_env(sd_type=sd_type, chain_len=chain_len) as env: base_vol = env.chain[base_index] top_vol = env.chain[top_index] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) merge.finalize(subchain) # If top has a child, the child must now be rebased on base. if top_vol is not env.chain[-1]: child_vol = env.chain[top_index + 1] info = qemuimg.info(child_vol.volumePath) self.assertEqual( info['backingfile'], volume.getBackingVolumePath(subchain.img_id, subchain.base_id)) # verify syncVolumeChain arguments self.check_sync_volume_chain(subchain, env.chain[-1].volUUID) new_chain = [vol.volUUID for vol in env.chain] new_chain.remove(top_vol.volUUID) self.assertEqual(image.Image.syncVolumeChain.actual_chain, new_chain) self.assertEqual(base_vol.getLegality(), sc.LEGAL_VOL)
def test_chain_after_finalize(self, base_fmt): with self.make_env(format=base_fmt, chain_len=3) as env: base_vol = env.chain[0] # We write data to the base and will read it from the child volume # to verify that the chain is valid after qemu-rebase. offset = 0 pattern = 0xf0 length = 1024 qemu_pattern_write(base_vol.volumePath, sc.fmt2str(base_vol.getFormat()), offset=offset, len=length, pattern=pattern) top_vol = env.chain[1] child_vol = env.chain[2] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) merge.finalize(subchain) qemu_pattern_verify(child_vol.volumePath, sc.fmt2str(child_vol.getFormat()), offset=offset, len=length, pattern=pattern)
def test_finalize(self, sd_type, chain_len, base_index, top_index): with self.make_env(sd_type=sd_type, chain_len=chain_len) as env: base_vol = env.chain[base_index] # This volume *was* prepared base_vol.setLegality(sc.ILLEGAL_VOL) top_vol = env.chain[top_index] subchain_info = dict( sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0, ) subchain = merge.SubchainInfo(subchain_info, 0) merge.finalize(subchain) # If top has a child, the child must now be rebased on base. if top_vol is not env.chain[-1]: child_vol = env.chain[top_index + 1] info = qemuimg.info(child_vol.volumePath) self.assertEqual(info["backingfile"], base_vol.volumePath) # verify syncVolumeChain arguments self.assertEquals(image.Image.syncVolumeChain.sd_id, subchain.sd_id) self.assertEquals(image.Image.syncVolumeChain.img_id, subchain.img_id) self.assertEquals(image.Image.syncVolumeChain.vol_id, env.chain[-1].volUUID) new_chain = [vol.volUUID for vol in env.chain] new_chain.remove(top_vol.volUUID) self.assertEquals(image.Image.syncVolumeChain.actual_chain, new_chain) self.assertEqual(base_vol.getLegality(), sc.LEGAL_VOL)
def test_finalize_illegal_volume(self, volume): with self.make_env(sd_type='block', format='cow', chain_len=4) as env: base_vol = env.chain[1] top_vol = env.chain[2] if volume == 'base': base_vol.setLegality(sc.ILLEGAL_VOL) else: top_vol.setLegality(sc.ILLEGAL_VOL) subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) with self.assertRaises(se.prepareIllegalVolumeError): merge.finalize(subchain)
def test_validate_illegal_base(self): with self.make_env(sd_type="file", chain_len=3) as env: base_vol = env.chain[0] # This volume was *not* prepared base_vol.setLegality(sc.LEGAL_VOL) top_vol = env.chain[1] subchain_info = dict( sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0, ) subchain = merge.SubchainInfo(subchain_info, 0) with self.assertRaises(se.UnexpectedVolumeState): merge.finalize(subchain)
def test_qemuimg_rebase_failed(self): with self.make_env(sd_type='file', chain_len=4) as env: base_vol = env.chain[1] top_vol = env.chain[2] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) with MonkeyPatchScope([(qemuimg._qemuimg, '_cmd', '/usr/bin/false') ]): with self.assertRaises(cmdutils.Error): merge.finalize(subchain) self.assertEqual(subchain.top_vol.getLegality(), sc.LEGAL_VOL) self.assertEqual(subchain.top_vol.getParent(), base_vol.volUUID)
def test_qemuimg_rebase_failed(self): with self.make_env(sd_type='file', chain_len=4) as env: base_vol = env.chain[1] top_vol = env.chain[2] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) with MonkeyPatchScope([ (qemuimg._qemuimg, '_cmd', '/usr/bin/false') ]): with self.assertRaises(cmdutils.Error): merge.finalize(subchain) self.assertEqual(subchain.top_vol.getLegality(), sc.LEGAL_VOL) self.assertEqual(subchain.top_vol.getParent(), base_vol.volUUID)
def test_reduce_not_chunked(self): with self.make_env(sd_type='file', format='cow', chain_len=4) as env: base_vol = env.chain[1] top_vol = env.chain[2] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) merge.finalize(subchain) fake_sd = env.sdcache.domains[env.sd_manifest.sdUUID] fake_base_vol = fake_sd.produceVolume(subchain.img_id, subchain.base_id) calls = getattr(fake_base_vol, "__calls__", {}) # Verify that 'calls' is empty which means that 'reduce' wasn't # called self.assertEqual(len(calls), 0)
def test_reduce_chunked(self): with self.make_env(sd_type='block', format='cow', chain_len=4) as env: base_vol = env.chain[1] top_vol = env.chain[2] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) merge.finalize(subchain) fake_sd = env.sdcache.domains[env.sd_manifest.sdUUID] fake_base_vol = fake_sd.produceVolume(subchain.img_id, subchain.base_id) self.assertEqual(len(fake_base_vol.__calls__), 1) optimal_size = base_vol.optimal_size() // sc.BLOCK_SIZE self.assertEqual(fake_base_vol.__calls__[0], ('reduce', (optimal_size, ), {}))
def test_reduce_chunked(self): with self.make_env(sd_type='block', format='cow', chain_len=4) as env: base_vol = env.chain[1] top_vol = env.chain[2] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) merge.finalize(subchain) fake_sd = env.sdcache.domains[env.sd_manifest.sdUUID] fake_base_vol = fake_sd.produceVolume(subchain.img_id, subchain.base_id) self.assertEqual(len(fake_base_vol.__calls__), 1) optimal_size = base_vol.optimal_size() // sc.BLOCK_SIZE self.assertEqual(fake_base_vol.__calls__[0], ('reduce', (optimal_size,), {}))
def test_reduce_failure(self): with self.make_env(sd_type='block', format='cow', chain_len=4) as env: base_vol = env.chain[0] top_vol = env.chain[1] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) fake_sd = env.sdcache.domains[env.sd_manifest.sdUUID] fake_base_vol = fake_sd.produceVolume(subchain.img_id, subchain.base_id) fake_base_vol.errors["reduce"] = se.LogicalVolumeExtendError( "vgname", "lvname", base_vol.optimal_size()) with self.assertRaises(se.LogicalVolumeExtendError): merge.finalize(subchain) # verify syncVolumeChain arguments self.check_sync_volume_chain(subchain, env.chain[-1].volUUID)
def test_rollback_volume_legallity_failed(self): with self.make_env(sd_type='block', chain_len=4) as env: base_vol = env.chain[1] top_vol = env.chain[2] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) def setLegality(self, legality): if legality == sc.LEGAL_VOL: raise RuntimeError("Rollback volume legality failed") self.setMetaParam(sc.LEGALITY, legality) with MonkeyPatchScope([ (qemuimg._qemuimg, '_cmd', '/usr/bin/false'), (volume.VolumeManifest, 'setLegality', setLegality), ]): with self.assertRaises(cmdutils.Error): merge.finalize(subchain) self.assertEqual(subchain.top_vol.getLegality(), sc.ILLEGAL_VOL)