def test_snapshot(self): expected_calls = [{ 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_PENDING_UPLOAD } }, { 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_UPLOADING, 'expected_state': task_states.IMAGE_PENDING_UPLOAD } }] func_call_matcher = matchers.FunctionCallMatcher(expected_calls) self._spawn_instance(True) snapshot_name = 'test_snapshot_' + str(uuid.uuid4()) self._conn.snapshot(self._context, self._instance_data, snapshot_name, func_call_matcher.call) self.assertTrue(self._image_metadata and "disk_format" in self._image_metadata and self._image_metadata["disk_format"] == "vhd") # assert states changed in correct order self.assertIsNone(func_call_matcher.match()) # assert VM snapshots have been removed self.assertEquals( self._hypervutils.get_vm_snapshots_count( self._instance_data["name"]), 0)
def test_snapshot_with_update_failure(self): expected_calls = [{ 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_PENDING_UPLOAD } }, { 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_UPLOADING, 'expected_state': task_states.IMAGE_PENDING_UPLOAD } }] func_call_matcher = matchers.FunctionCallMatcher(expected_calls) self._spawn_instance(True) self._update_image_raise_exception = True snapshot_name = 'test_snapshot_' + str(uuid.uuid4()) self.assertRaises(vmutils.HyperVException, self._conn.snapshot, self._context, self._instance_data, snapshot_name, func_call_matcher.call) # assert states changed in correct order self.assertIsNone(func_call_matcher.match()) # assert VM snapshots have been removed self.assertEquals( self._hypervutils.get_vm_snapshots_count( self._instance_data["name"]), 0)
def test_snapshot(self, byname_mock, repopush_mock): # Use mix-case to test that mixed-case image names succeed. snapshot_name = 'tEsT-SnAp' expected_calls = [{ 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_PENDING_UPLOAD } }, { 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_UPLOADING, 'expected_state': task_states.IMAGE_PENDING_UPLOAD } }] func_call_matcher = matchers.FunctionCallMatcher(expected_calls) instance_ref = utils.get_test_instance() properties = { 'instance_id': instance_ref['id'], 'user_id': str(self.context.user_id) } sent_meta = { 'name': snapshot_name, 'is_public': False, 'status': 'creating', 'properties': properties } # Because the docker driver doesn't push directly into Glance, we # cannot check that the images are correctly configured in the # fake image service, but we can ensuring naming and other # conventions are accurate. image_service = nova.tests.image.fake.FakeImageService() recv_meta = image_service.create(context, sent_meta) self.connection.snapshot(self.context, instance_ref, recv_meta['id'], func_call_matcher.call) (repopush_calls, repopush_kwargs) = repopush_mock.call_args repo = repopush_calls[0] # Assure the image_href is correctly placed into the headers. headers_image_href = repopush_kwargs.get( 'headers', {}).get('X-Meta-Glance-Image-Id') self.assertEqual(recv_meta['id'], headers_image_href) # Assure the repository name pushed into the docker registry is valid. self.assertIn(":" + str(self.connection._get_registry_port()) + "/", repo) self.assertEqual(repo.count(":"), 1) self.assertEqual(repo.count("/"), 1) # That the lower-case snapshot name matches the name pushed image_name = repo.split("/")[1] self.assertEqual(snapshot_name.lower(), image_name)
def test_snapshot(self, byname_mock, getimage_mock, loadrepo_mock): # Use mix-case to test that mixed-case image names succeed. snapshot_name = 'tEsT-SnAp' expected_calls = [{ 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_PENDING_UPLOAD } }, { 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_UPLOADING, 'expected_state': task_states.IMAGE_PENDING_UPLOAD } }] func_call_matcher = matchers.FunctionCallMatcher(expected_calls) instance_ref = utils.get_test_instance() properties = { 'instance_id': instance_ref['id'], 'user_id': str(self.context.user_id) } sent_meta = { 'name': snapshot_name, 'is_public': False, 'status': 'creating', 'properties': properties } # Because the docker driver doesn't push directly into Glance, we # cannot check that the images are correctly configured in the # fake image service, but we can ensuring naming and other # conventions are accurate. image_service = nova.tests.image.fake.FakeImageService() recv_meta = image_service.create(context, sent_meta) self.connection.snapshot(self.context, instance_ref, recv_meta['id'], func_call_matcher.call) snapshot = image_service.show(context, recv_meta['id']) # self.assertIsNone(func_call_matcher.match()) self.assertEqual(snapshot['properties']['image_state'], 'available') self.assertEqual(snapshot['status'], 'active') self.assertEqual(snapshot['disk_format'], 'raw') self.assertEqual(snapshot['container_format'], 'docker') self.assertEqual(snapshot['name'], snapshot_name)
def test_snapshot(self): expected_calls = [ {'args': (), 'kwargs': {'task_state': task_states.IMAGE_PENDING_UPLOAD}}, {'args': (), 'kwargs': {'task_state': task_states.IMAGE_UPLOADING, 'expected_state': task_states.IMAGE_PENDING_UPLOAD}}] func_call_matcher = matchers.FunctionCallMatcher(expected_calls) self._create_vm() info = self.conn.get_info({'uuid': 'fake-uuid'}) self._check_vm_info(info, power_state.RUNNING) self.conn.snapshot(self.context, self.instance, "Test-Snapshot", func_call_matcher.call) info = self.conn.get_info({'uuid': 'fake-uuid'}) self._check_vm_info(info, power_state.RUNNING) self.assertIsNone(func_call_matcher.match())
def _setup_snapshot_mocks(self): expected_calls = [{ 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_PENDING_UPLOAD } }, { 'args': (), 'kwargs': { 'task_state': task_states.IMAGE_UPLOADING, 'expected_state': task_states.IMAGE_PENDING_UPLOAD } }] func_call_matcher = matchers.FunctionCallMatcher(expected_calls) snapshot_name = 'test_snapshot_' + str(uuid.uuid4()) fake_hv_snapshot_path = 'fake_snapshot_path' fake_parent_vhd_path = 'C:\\fake_vhd_path\\parent.vhd' self._instance_data = self._get_instance_data() func = mox.Func(self._check_instance_name) m = vmutils.VMUtils.take_vm_snapshot(func) m.AndReturn(fake_hv_snapshot_path) m = fake.PathUtils.get_instance_dir(mox.IsA(str)) m.AndReturn(self._test_instance_dir) m = vhdutils.VHDUtils.get_vhd_parent_path(mox.IsA(str)) m.AndReturn(fake_parent_vhd_path) self._fake_dest_disk_path = None def copy_dest_disk_path(src, dest): self._fake_dest_disk_path = dest m = fake.PathUtils.copyfile(mox.IsA(str), mox.IsA(str)) m.WithSideEffects(copy_dest_disk_path) self._fake_dest_base_disk_path = None def copy_dest_base_disk_path(src, dest): self._fake_dest_base_disk_path = dest m = fake.PathUtils.copyfile(fake_parent_vhd_path, mox.IsA(str)) m.WithSideEffects(copy_dest_base_disk_path) def check_dest_disk_path(path): return path == self._fake_dest_disk_path def check_dest_base_disk_path(path): return path == self._fake_dest_base_disk_path func1 = mox.Func(check_dest_disk_path) func2 = mox.Func(check_dest_base_disk_path) # Make sure that the hyper-v base and differential VHDs are merged vhdutils.VHDUtils.reconnect_parent_vhd(func1, func2) vhdutils.VHDUtils.merge_vhd(func1, func2) def check_snapshot_path(snapshot_path): return snapshot_path == fake_hv_snapshot_path # Make sure that the Hyper-V snapshot is removed func = mox.Func(check_snapshot_path) vmutils.VMUtils.remove_vm_snapshot(func) fake.PathUtils.rmtree(mox.IsA(str)) m = fake.PathUtils.open(func2, 'rb') m.AndReturn(io.BytesIO(b'fake content')) return (snapshot_name, func_call_matcher)