dc_ref, src_path, dc_ref, dest_path)
self.assertEqual(dest_path, ret)
- @mock.patch.object(image_transfer, 'download_stream_optimized_image')
- @mock.patch.object(VMDK_DRIVER, '_extend_backing')
@mock.patch.object(VMDK_DRIVER, '_select_ds_for_volume')
@mock.patch.object(VMDK_DRIVER, '_get_storage_profile_id')
- @mock.patch.object(VMDK_DRIVER, 'session')
+ @mock.patch('cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver.'
+ '_get_disk_type')
+ @mock.patch.object(VMDK_DRIVER, '_get_extra_config')
@mock.patch.object(VMDK_DRIVER, 'volumeops')
- def test_copy_image_to_volume_stream_optimized(self,
- volumeops,
- session,
- get_profile_id,
- _select_ds_for_volume,
- extend_backing,
- download_image):
- """Test copy_image_to_volume.
-
- Test with an acceptable vmdk disk format and streamOptimized disk type.
- """
- self._test_copy_image_to_volume_stream_optimized(volumeops,
- session,
- get_profile_id,
- _select_ds_for_volume,
- extend_backing,
- download_image)
-
- def _test_copy_image_to_volume_stream_optimized(self, volumeops,
+ @mock.patch.object(VMDK_DRIVER, 'session')
+ @mock.patch.object(image_transfer, 'download_stream_optimized_image')
+ def _test_copy_image_to_volume_stream_optimized(self,
+ download_image,
session,
+ vops,
+ get_extra_config,
+ get_disk_type,
get_profile_id,
- _select_ds_for_volume,
- extend_backing,
- download_image):
- fake_context = mock.Mock()
- fake_backing = mock.sentinel.backing
- fake_image_id = 'image-id'
- size = 5 * units.Gi
- size_gb = float(size) / units.Gi
- fake_volume_size = 1 + size_gb
- adapter_type = 'ide'
- fake_image_meta = {'disk_format': 'vmdk', 'size': size,
- 'container_format': 'bare',
- 'properties': {'vmware_disktype': 'streamOptimized',
- 'vmware_adaptertype': adapter_type}}
- image_service = mock.Mock(glance.GlanceImageService)
- fake_host = mock.sentinel.host
- fake_rp = mock.sentinel.rp
- fake_folder = mock.sentinel.folder
- fake_summary = mock.sentinel.summary
- fake_summary.name = "datastore-1"
- fake_vm_create_spec = mock.sentinel.spec
- fake_disk_type = 'thin'
- vol_name = 'fake_volume name'
- vol_id = 'd11a82de-ddaa-448d-b50a-a255a7e61a1e'
- fake_volume = {'name': vol_name,
- 'id': vol_id,
- 'size': fake_volume_size,
- 'volume_type_id': None}
- cf = session.vim.client.factory
- vm_import_spec = cf.create('ns0:VirtualMachineImportSpec')
- vm_import_spec.configSpec = fake_vm_create_spec
- timeout = self._config.vmware_image_transfer_timeout_secs
-
- image_service.show.return_value = fake_image_meta
- volumeops.get_create_spec.return_value = fake_vm_create_spec
- volumeops.get_backing.return_value = fake_backing
-
- # If _select_ds_for_volume raises an exception, get_create_spec
- # will not be called.
- _select_ds_for_volume.side_effect = exceptions.VimException('Error')
- self.assertRaises(cinder_exceptions.VolumeBackendAPIException,
- self._driver.copy_image_to_volume,
- fake_context, fake_volume,
- image_service, fake_image_id)
- self.assertFalse(volumeops.get_create_spec.called)
-
- # If the volume size is greater then than the backing's disk size,
- # _extend_backing will be called.
- _select_ds_for_volume.side_effect = None
- _select_ds_for_volume.return_value = (fake_host, fake_rp,
- fake_folder, fake_summary)
- profile_id = 'profile-1'
+ select_ds_for_volume,
+ download_error=False):
+ host = mock.sentinel.host
+ rp = mock.sentinel.rp
+ folder = mock.sentinel.folder
+ summary = mock.Mock(name=mock.sentinel.ds_name)
+ select_ds_for_volume.return_value = (host, rp, folder, summary)
+
+ profile_id = mock.sentinel.profile_id
get_profile_id.return_value = profile_id
- volumeops.get_disk_size.return_value = size
+ disk_type = mock.sentinel.disk_type
+ get_disk_type.return_value = disk_type
+
+ extra_config = mock.sentinel.extra_config
+ get_extra_config.return_value = extra_config
+
+ vm_create_spec = mock.sentinel.vm_create_spec
+ vops.get_create_spec.return_value = vm_create_spec
+
+ import_spec = mock.Mock()
+ session.vim.client.factory.create.return_value = import_spec
backing = mock.sentinel.backing
- download_image.return_value = backing
-
- self._driver.copy_image_to_volume(fake_context, fake_volume,
- image_service, fake_image_id)
-
- image_service.show.assert_called_with(fake_context, fake_image_id)
- _select_ds_for_volume.assert_called_with(fake_volume)
- get_profile_id.assert_called_once_with(fake_volume)
- extra_config = {vmdk.EXTRA_CONFIG_VOLUME_ID_KEY: vol_id}
- volumeops.get_create_spec.assert_called_with(fake_volume['name'],
- 0,
- fake_disk_type,
- fake_summary.name,
- profileId=profile_id,
- adapter_type=adapter_type,
- extra_config=extra_config)
- self.assertTrue(download_image.called)
- download_image.assert_called_with(fake_context, timeout,
- image_service,
- fake_image_id,
- session=session,
- host=self.IP,
- port=self.PORT,
- resource_pool=fake_rp,
- vm_folder=fake_folder,
- vm_import_spec=vm_import_spec,
- image_size=size)
- volumeops.update_backing_disk_uuid.assert_called_once_with(
- backing, fake_volume['id'])
- extend_backing.assert_called_once_with(backing, fake_volume_size)
-
- # If the volume size is not greater then than backing's disk size,
- # _extend_backing will not be called.
- volumeops.get_disk_size.return_value = fake_volume_size * units.Gi
- extend_backing.reset_mock()
-
- self._driver.copy_image_to_volume(fake_context, fake_volume,
- image_service, fake_image_id)
-
- self.assertFalse(extend_backing.called)
-
- # If fetch_stream_optimized_image raises an exception,
- # get_backing and delete_backing will be called.
- download_image.side_effect = exceptions.VimException('error')
-
- self.assertRaises(exceptions.VimException,
- self._driver.copy_image_to_volume,
- fake_context, fake_volume,
- image_service, fake_image_id)
- volumeops.get_backing.assert_called_with(fake_volume['name'])
- volumeops.delete_backing.assert_called_with(fake_backing)
- self.assertFalse(extend_backing.called)
+ if download_error:
+ download_image.side_effect = exceptions.VimException
+ vops.get_backing.return_value = backing
+ else:
+ download_image.return_value = backing
+
+ context = mock.sentinel.context
+ volume = self._create_volume_dict(size=3)
+ image_service = mock.sentinel.image_service
+ image_id = mock.sentinel.image_id
+ image_size = 2 * units.Gi
+ adapter_type = mock.sentinel.adapter_type
+
+ if download_error:
+ self.assertRaises(
+ exceptions.VimException,
+ self._driver._fetch_stream_optimized_image,
+ context, volume, image_service, image_id,
+ image_size, adapter_type)
+ else:
+ self._driver._fetch_stream_optimized_image(
+ context, volume, image_service, image_id, image_size,
+ adapter_type)
+
+ select_ds_for_volume.assert_called_once_with(volume)
+ vops.get_create_spec.assert_called_once_with(
+ volume['name'], 0, disk_type, summary.name, profileId=profile_id,
+ adapter_type=adapter_type, extra_config=extra_config)
+ self.assertEqual(vm_create_spec, import_spec.configSpec)
+ download_image.assert_called_with(
+ context,
+ self._config.vmware_image_transfer_timeout_secs,
+ image_service,
+ image_id,
+ session=session,
+ host=self._config.vmware_host_ip,
+ port=443,
+ resource_pool=rp,
+ vm_folder=folder,
+ vm_import_spec=import_spec,
+ image_size=image_size)
+ if download_error:
+ self.assertFalse(vops.update_backing_disk_uuid.called)
+ vops.delete_backing.assert_called_once_with(backing)
+ else:
+ vops.update_backing_disk_uuid.assert_called_once_with(
+ backing, volume['id'])
+
+ def test_copy_image_to_volume_stream_optimized(self):
+ self._test_copy_image_to_volume_stream_optimized()
+
+ def test_copy_image_to_volume_stream_optimized_with_download_error(self):
+ self._test_copy_image_to_volume_stream_optimized(download_error=True)
- def test_copy_volume_to_image_non_vmdk(self):
- """Test copy_volume_to_image for a non-vmdk disk format."""
- m = self.mox
- image_meta = FakeObject()
- image_meta['disk_format'] = 'novmdk'
- volume = FakeObject()
- volume['name'] = 'vol-name'
- volume['volume_attachment'] = None
+ def test_copy_volume_to_image_when_attached(self):
+ volume = self._create_volume_dict(
+ attachment=[mock.sentinel.attachment_1])
+ self.assertRaises(
+ cinder_exceptions.InvalidVolume,
+ self._driver.copy_volume_to_image,
+ mock.sentinel.context,
+ volume,
+ mock.sentinel.image_service,
+ mock.sentinel.image_meta)
+
+ @mock.patch.object(VMDK_DRIVER, '_validate_disk_format')
+ @mock.patch.object(VMDK_DRIVER, 'volumeops')
+ @mock.patch('oslo_vmware.image_transfer.upload_image')
+ @mock.patch.object(VMDK_DRIVER, 'session')
+ def test_copy_volume_to_image(
+ self, session, upload_image, vops, validate_disk_format):
+ backing = mock.sentinel.backing
+ vops.get_backing.return_value = backing
- m.ReplayAll()
- self.assertRaises(cinder_exceptions.ImageUnacceptable,
- self._driver.copy_volume_to_image,
- mox.IgnoreArg(), volume,
- mox.IgnoreArg(), image_meta)
- m.UnsetStubs()
- m.VerifyAll()
+ vmdk_file_path = mock.sentinel.vmdk_file_path
+ vops.get_vmdk_path.return_value = vmdk_file_path
- def test_copy_volume_to_image_when_attached(self):
- """Test copy_volume_to_image when volume is attached."""
- m = self.mox
- volume = FakeObject()
- volume['volume_attachment'] = [mock.sentinel.volume_attachment]
+ context = mock.sentinel.context
+ volume = self._create_volume_dict()
+ image_service = mock.sentinel.image_service
+ image_meta = self._create_image_meta()
+ self._driver.copy_volume_to_image(
+ context, volume, image_service, image_meta)
- m.ReplayAll()
- self.assertRaises(cinder_exceptions.InvalidVolume,
- self._driver.copy_volume_to_image,
- mox.IgnoreArg(), volume,
- mox.IgnoreArg(), mox.IgnoreArg())
- m.UnsetStubs()
- m.VerifyAll()
-
- def test_copy_volume_to_image_vmdk(self):
- """Test copy_volume_to_image for a valid vmdk disk format."""
- m = self.mox
- m.StubOutWithMock(self._driver.__class__, 'session')
- self._driver.session = self._session
- m.StubOutWithMock(api.VMwareAPISession, 'vim')
- self._session.vim = self._vim
- m.StubOutWithMock(self._driver.__class__, 'volumeops')
- self._driver.volumeops = self._volumeops
-
- image_id = 'image-id-1'
- image_meta = FakeObject()
- image_meta['disk_format'] = 'vmdk'
- image_meta['id'] = image_id
- image_meta['name'] = image_id
- image_meta['is_public'] = True
- image_service = FakeObject()
- vol_name = 'volume-123456789'
- project_id = 'project-owner-id-123'
- volume = FakeObject()
- volume['name'] = vol_name
- size_gb = 5
- size = size_gb * units.Gi
- volume['size'] = size_gb
- volume['project_id'] = project_id
- volume['volume_attachment'] = None
- # volumeops.get_backing
- backing = FakeMor("VirtualMachine", "my_vm")
- m.StubOutWithMock(self._volumeops, 'get_backing')
- self._volumeops.get_backing(vol_name).AndReturn(backing)
- # volumeops.get_vmdk_path
- datastore_name = 'datastore1'
- file_path = 'my_folder/my_nested_folder/my_vm.vmdk'
- vmdk_file_path = '[%s] %s' % (datastore_name, file_path)
- m.StubOutWithMock(self._volumeops, 'get_vmdk_path')
- self._volumeops.get_vmdk_path(backing).AndReturn(vmdk_file_path)
- # vmware_images.upload_image
- timeout = self._config.vmware_image_transfer_timeout_secs
- host_ip = self.IP
- m.StubOutWithMock(image_transfer, 'upload_image')
- image_transfer.upload_image(mox.IgnoreArg(),
- timeout,
- image_service,
- image_id,
- project_id,
- session=self._session,
- host=host_ip,
- port=self.PORT,
- vm=backing,
- vmdk_file_path=vmdk_file_path,
- vmdk_size=size,
- image_name=image_id,
- image_version=1,
- is_public=True)
-
- m.ReplayAll()
- self._driver.copy_volume_to_image(mox.IgnoreArg(), volume,
- image_service, image_meta)
- m.UnsetStubs()
- m.VerifyAll()
+ validate_disk_format.assert_called_once_with(image_meta['disk_format'])
+ vops.get_backing.assert_called_once_with(volume['name'])
+ vops.get_vmdk_path.assert_called_once_with(backing)
+ upload_image.assert_called_once_with(
+ context,
+ self._config.vmware_image_transfer_timeout_secs,
+ image_service,
+ image_meta['id'],
+ volume['project_id'],
+ session=session,
+ host=self._config.vmware_host_ip,
+ port=443,
+ vm=backing,
+ vmdk_file_path=vmdk_file_path,
+ vmdk_size=volume['size'] * units.Gi,
+ image_name=image_meta['name'],
+ image_version=1,
+ is_public=image_meta['is_public'])
@mock.patch.object(VMDK_DRIVER, '_delete_temp_backing')
@mock.patch('oslo_utils.uuidutils.generate_uuid')