Support volume group when creating a volume
Co-Authored-By: Ivan Kolodyazhny <e0ne@e0ne.info> blueprint cinder-generic-volume-groups Change-Id: I53eb10c5d7efabcab82aae83e0c71a190a0784e2
This commit is contained in:
parent
ef4d8d69c9
commit
b6d52b0db9
|
@ -370,7 +370,9 @@ def volume_get(request, volume_id):
|
|||
@profiler.trace
|
||||
def volume_create(request, size, name, description, volume_type,
|
||||
snapshot_id=None, metadata=None, image_id=None,
|
||||
availability_zone=None, source_volid=None):
|
||||
availability_zone=None, source_volid=None,
|
||||
group_id=None):
|
||||
client = _cinderclient_with_generic_groups(request)
|
||||
data = {'name': name,
|
||||
'description': description,
|
||||
'volume_type': volume_type,
|
||||
|
@ -378,9 +380,10 @@ def volume_create(request, size, name, description, volume_type,
|
|||
'metadata': metadata,
|
||||
'imageRef': image_id,
|
||||
'availability_zone': availability_zone,
|
||||
'source_volid': source_volid}
|
||||
'source_volid': source_volid,
|
||||
'group_id': group_id}
|
||||
|
||||
volume = cinderclient(request).volumes.create(size, **data)
|
||||
volume = client.volumes.create(size, **data)
|
||||
return Volume(volume)
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
Views for managing volumes.
|
||||
"""
|
||||
|
||||
from cinderclient import exceptions as cinder_exc
|
||||
|
||||
from django.conf import settings
|
||||
from django.forms import ValidationError
|
||||
from django.template.defaultfilters import filesizeformat
|
||||
|
@ -123,6 +125,10 @@ class CreateForm(forms.SelfHandlingForm):
|
|||
'data-switch-on': 'source',
|
||||
'data-source-no_source_type': _('Availability Zone'),
|
||||
'data-source-image_source': _('Availability Zone')}))
|
||||
group = forms.ThemableChoiceField(
|
||||
label=_("Group"), required=False,
|
||||
help_text=_("Group which the new volume belongs to. Choose "
|
||||
"'No group' if the new volume belongs to no group."))
|
||||
|
||||
def prepare_source_fields_if_snapshot_specified(self, request):
|
||||
try:
|
||||
|
@ -261,6 +267,21 @@ class CreateForm(forms.SelfHandlingForm):
|
|||
else:
|
||||
del self.fields['volume_source_type']
|
||||
|
||||
def _populate_group_choices(self, request):
|
||||
try:
|
||||
groups = cinder.group_list(request)
|
||||
except cinder_exc.VersionNotFoundForAPIMethod:
|
||||
del self.fields['group']
|
||||
return
|
||||
except Exception:
|
||||
redirect = reverse("horizon:project:volumes:index")
|
||||
exceptions.handle(request,
|
||||
_('Unable to retrieve the volume group list.'),
|
||||
redirect=redirect)
|
||||
group_choices = [(g.id, g.name or g.id) for g in groups]
|
||||
group_choices.insert(0, ("", _("No group")))
|
||||
self.fields['group'].choices = group_choices
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(CreateForm, self).__init__(request, *args, **kwargs)
|
||||
volume_types = []
|
||||
|
@ -287,6 +308,8 @@ class CreateForm(forms.SelfHandlingForm):
|
|||
else:
|
||||
self.prepare_source_fields_default(request)
|
||||
|
||||
self._populate_group_choices(request)
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(CreateForm, self).clean()
|
||||
source_type = self.cleaned_data.get('volume_source_type')
|
||||
|
@ -400,7 +423,8 @@ class CreateForm(forms.SelfHandlingForm):
|
|||
image_id=image_id,
|
||||
metadata=metadata,
|
||||
availability_zone=az,
|
||||
source_volid=volume_id)
|
||||
source_volid=volume_id,
|
||||
group_id=data.get('group') or None)
|
||||
message = _('Creating volume "%s"') % data['name']
|
||||
messages.info(request, message)
|
||||
return volume
|
||||
|
|
|
@ -220,7 +220,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
cinder: ['volume_create', 'volume_snapshot_list',
|
||||
'volume_type_list', 'volume_type_default',
|
||||
'volume_list', 'availability_zone_list',
|
||||
'extension_supported'],
|
||||
'extension_supported', 'group_list'],
|
||||
quotas: ['tenant_quota_usages'],
|
||||
api.glance: ['image_list_detailed'],
|
||||
})
|
||||
|
@ -250,6 +250,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_extension_supported.return_value = True
|
||||
self.mock_volume_list.return_value = self.cinder_volumes.list()
|
||||
self.mock_volume_create.return_value = volume
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
res = self.client.post(url, formData)
|
||||
|
@ -270,7 +271,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_volume_create.assert_called_once_with(
|
||||
test.IsHttpRequest(), formData['size'], formData['name'],
|
||||
formData['description'], formData['type'], metadata={},
|
||||
snapshot_id=None, image_id=None,
|
||||
snapshot_id=None, group_id=None, image_id=None,
|
||||
availability_zone=formData['availability_zone'], source_volid=None)
|
||||
self.mock_image_list_detailed.assert_called_with(
|
||||
test.IsHttpRequest(),
|
||||
|
@ -278,6 +279,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_tenant_quota_usages.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
targets=('volumes', 'gigabytes'))
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -288,7 +290,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
'volume_type_default',
|
||||
'volume_type_list',
|
||||
'volume_snapshot_list',
|
||||
'volume_create'],
|
||||
'volume_create',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_without_name(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
|
@ -318,6 +321,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.cinder_volume_types.first()
|
||||
self.mock_volume_list.return_value = self.cinder_volumes.list()
|
||||
self.mock_volume_create.return_value = volume
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
res = self.client.post(url, formData)
|
||||
|
@ -326,7 +330,6 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.assertRedirectsNoFollow(res, redirect_url)
|
||||
|
||||
self.mock_volume_type_list.assert_called_once()
|
||||
self.mock_tenant_quota_usages.assert_called_once()
|
||||
self.mock_volume_snapshot_list.assert_called_once_with(
|
||||
test.IsHttpRequest(), search_opts=SEARCH_OPTS)
|
||||
self.mock_image_list_detailed.assert_called_with(
|
||||
|
@ -340,8 +343,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_volume_create.assert_called_once_with(
|
||||
test.IsHttpRequest(), formData['size'], formData['name'],
|
||||
formData['description'], formData['type'], metadata={},
|
||||
snapshot_id=None, image_id=None,
|
||||
snapshot_id=None, group_id=None, image_id=None,
|
||||
availability_zone=formData['availability_zone'], source_volid=None)
|
||||
self.mock_group_list.assert_called_once_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -352,7 +356,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
'volume_type_default',
|
||||
'volume_type_list',
|
||||
'volume_snapshot_list',
|
||||
'volume_create'],
|
||||
'volume_create',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_dropdown(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
|
@ -380,6 +385,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_extension_supported.return_value = True
|
||||
self.mock_availability_zone_list.return_value = \
|
||||
self.cinder_availability_zones.list()
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
self.mock_volume_create.return_value = volume
|
||||
|
||||
|
@ -405,7 +411,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_volume_create.assert_called_once_with(
|
||||
test.IsHttpRequest(), formData['size'], formData['name'],
|
||||
formData['description'], '', metadata={}, snapshot_id=None,
|
||||
image_id=None, availability_zone=None, source_volid=None)
|
||||
group_id=None, image_id=None, availability_zone=None,
|
||||
source_volid=None)
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -413,7 +421,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
'volume_type_default',
|
||||
'volume_get',
|
||||
'volume_snapshot_get',
|
||||
'volume_create'],
|
||||
'volume_create',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_from_snapshot(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
|
@ -434,6 +443,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_volume_snapshot_get.return_value = snapshot
|
||||
self.mock_volume_get.return_value = self.cinder_volumes.first()
|
||||
self.mock_volume_create.return_value = volume
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
# get snapshot from url
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
|
@ -454,7 +464,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_volume_create.assert_called_once_with(
|
||||
test.IsHttpRequest(), formData['size'], formData['name'],
|
||||
formData['description'], '', metadata={}, snapshot_id=snapshot.id,
|
||||
image_id=None, availability_zone=None, source_volid=None)
|
||||
group_id=None, image_id=None, availability_zone=None,
|
||||
source_volid=None)
|
||||
self.mock_group_list.assert_called_once_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -467,7 +479,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
'volume_list',
|
||||
'volume_type_default',
|
||||
'volume_get',
|
||||
'volume_create'],
|
||||
'volume_create',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_from_volume(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
|
@ -497,6 +510,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_image_list_detailed.return_value = \
|
||||
[self.images.list(), False, False]
|
||||
self.mock_volume_create.return_value = volume
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
redirect_url = INDEX_URL
|
||||
|
@ -523,7 +537,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_volume_create.assert_called_once_with(
|
||||
test.IsHttpRequest(), formData['size'], formData['name'],
|
||||
formData['description'], '', metadata={}, snapshot_id=None,
|
||||
image_id=None, availability_zone=None, source_volid=volume.id)
|
||||
group_id=None, image_id=None, availability_zone=None,
|
||||
source_volid=volume.id)
|
||||
self.mock_group_list.assert_called_once_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -536,7 +552,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
'volume_get',
|
||||
'volume_snapshot_get',
|
||||
'volume_snapshot_list',
|
||||
'volume_create'],
|
||||
'volume_create',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_from_snapshot_dropdown(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
|
@ -565,6 +582,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_availability_zone_list.return_value = \
|
||||
self.cinder_availability_zones.list()
|
||||
self.mock_volume_create.return_value = volume
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
# get snapshot from dropdown list
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
|
@ -591,7 +609,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_volume_create.assert_called_once_with(
|
||||
test.IsHttpRequest(), formData['size'], formData['name'],
|
||||
formData['description'], '', metadata={}, snapshot_id=snapshot.id,
|
||||
image_id=None, availability_zone=None, source_volid=None)
|
||||
group_id=None, image_id=None, availability_zone=None,
|
||||
source_volid=None)
|
||||
self.mock_group_list.assert_called_once_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -599,7 +619,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
cinder: ['volume_snapshot_get',
|
||||
'volume_type_list',
|
||||
'volume_type_default',
|
||||
'volume_get'],
|
||||
'volume_get',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_from_snapshot_invalid_size(self):
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
|
@ -616,6 +637,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.cinder_quota_usages.first()
|
||||
self.mock_volume_snapshot_get.return_value = snapshot
|
||||
self.mock_volume_get.return_value = self.cinder_volumes.first()
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
res = self.client.post("?".join([url,
|
||||
|
@ -632,6 +654,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
str(snapshot.id))
|
||||
self.mock_volume_get.assert_called_with(test.IsHttpRequest(),
|
||||
snapshot.volume_id)
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -640,7 +663,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
'availability_zone_list',
|
||||
'volume_type_default',
|
||||
'volume_type_list',
|
||||
'volume_create'],
|
||||
'volume_create',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_from_image(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
|
@ -661,6 +685,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_extension_supported.return_value = True
|
||||
self.mock_availability_zone_list.return_value = \
|
||||
self.cinder_availability_zones.list()
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
self.mock_volume_create.return_value = volume
|
||||
|
||||
|
@ -684,7 +709,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_volume_create.assert_called_once_with(
|
||||
test.IsHttpRequest(), formData['size'], formData['name'],
|
||||
formData['description'], '', metadata={}, snapshot_id=None,
|
||||
image_id=image.id, availability_zone=None, source_volid=None)
|
||||
group_id=None, image_id=image.id, availability_zone=None,
|
||||
source_volid=None)
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -696,7 +723,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
'volume_list',
|
||||
'volume_type_list',
|
||||
'volume_type_default',
|
||||
'volume_create'],
|
||||
'volume_create',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_from_image_dropdown(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
|
@ -725,6 +753,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_extension_supported.return_value = True
|
||||
self.mock_availability_zone_list.return_value = \
|
||||
self.cinder_availability_zones.list()
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
self.mock_volume_create.return_value = volume
|
||||
|
||||
|
@ -753,7 +782,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_volume_create.assert_called_once_with(
|
||||
test.IsHttpRequest(), formData['size'], formData['name'],
|
||||
formData['description'], '', metadata={}, snapshot_id=None,
|
||||
image_id=image.id, availability_zone=None, source_volid=None)
|
||||
group_id=None, image_id=image.id, availability_zone=None,
|
||||
source_volid=None)
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -761,7 +792,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
cinder: ['extension_supported',
|
||||
'availability_zone_list',
|
||||
'volume_type_list',
|
||||
'volume_type_default'],
|
||||
'volume_type_default',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_from_image_under_image_size(self):
|
||||
image = self.images.first()
|
||||
|
@ -778,6 +810,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.cinder_quota_usages.first()
|
||||
self.mock_image_get.return_value = image
|
||||
self.mock_extension_supported.return_value = True
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
res = self.client.post("?".join([url,
|
||||
|
@ -798,6 +831,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
str(image.id))
|
||||
self.mock_extension_supported.assert_called_with(test.IsHttpRequest(),
|
||||
'AvailabilityZones')
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -805,7 +839,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
cinder: ['extension_supported',
|
||||
'availability_zone_list',
|
||||
'volume_type_list',
|
||||
'volume_type_default'],
|
||||
'volume_type_default',
|
||||
'group_list'],
|
||||
})
|
||||
def _test_create_volume_from_image_under_image_min_disk_size(self, image):
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
|
@ -823,6 +858,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_extension_supported.return_value = True
|
||||
self.mock_availability_zone_list.return_value = \
|
||||
self.cinder_availability_zones.list()
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
res = self.client.post("?".join([url,
|
||||
|
@ -840,6 +876,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
str(image.id))
|
||||
self.mock_extension_supported.assert_called_with(test.IsHttpRequest(),
|
||||
'AvailabilityZones')
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
def test_create_volume_from_image_under_image_min_disk_size(self):
|
||||
image = self.images.get(name="protected_images")
|
||||
|
@ -865,7 +902,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
'volume_list',
|
||||
'volume_type_list',
|
||||
'volume_type_default',
|
||||
'volume_snapshot_list'],
|
||||
'volume_snapshot_list',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_gb_used_over_alloted_quota(self):
|
||||
formData = {'name': u'This Volume Is Huge!',
|
||||
|
@ -892,6 +930,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_extension_supported.return_value = True
|
||||
self.mock_availability_zone_list.return_value = \
|
||||
self.cinder_availability_zones.list()
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
res = self.client.post(url, formData)
|
||||
|
@ -913,6 +952,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
filters={'visibility': 'shared', 'status': 'active'})
|
||||
self.mock_extension_supported.assert_called_with(test.IsHttpRequest(),
|
||||
'AvailabilityZones')
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
quotas: ['tenant_quota_usages'],
|
||||
|
@ -922,7 +962,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
'volume_list',
|
||||
'volume_type_list',
|
||||
'volume_type_default',
|
||||
'volume_snapshot_list'],
|
||||
'volume_snapshot_list',
|
||||
'group_list'],
|
||||
})
|
||||
def test_create_volume_number_over_alloted_quota(self):
|
||||
formData = {'name': u'Too Many...',
|
||||
|
@ -950,6 +991,7 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
self.mock_extension_supported.return_value = True
|
||||
self.mock_availability_zone_list.return_value = \
|
||||
self.cinder_availability_zones.list()
|
||||
self.mock_group_list.return_value = []
|
||||
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
res = self.client.post(url, formData)
|
||||
|
@ -971,6 +1013,74 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
|||
search_opts=SEARCH_OPTS)
|
||||
self.mock_extension_supported.assert_called_with(test.IsHttpRequest(),
|
||||
'AvailabilityZones')
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
cinder: ['volume_create', 'volume_snapshot_list',
|
||||
'volume_type_list', 'volume_type_default',
|
||||
'volume_list', 'availability_zone_list',
|
||||
'extension_supported', 'group_list'],
|
||||
quotas: ['tenant_quota_usages'],
|
||||
api.glance: ['image_list_detailed'],
|
||||
})
|
||||
def test_create_volume_with_group(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
volume_type = self.cinder_volume_types.first()
|
||||
az = self.cinder_availability_zones.first().zoneName
|
||||
volume_group = self.cinder_groups.list()[0]
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
'description': u'This is a volume I am making for a test.',
|
||||
'method': u'CreateForm',
|
||||
'type': volume_type.name,
|
||||
'size': 50,
|
||||
'snapshot_source': '',
|
||||
'availability_zone': az,
|
||||
'group': volume_group.id}
|
||||
|
||||
self.mock_volume_type_default.return_value = \
|
||||
self.cinder_volume_types.first()
|
||||
self.mock_volume_type_list.return_value = \
|
||||
self.cinder_volume_types.list()
|
||||
self.mock_tenant_quota_usages.return_value = \
|
||||
self.cinder_quota_usages.first()
|
||||
self.mock_volume_snapshot_list.return_value = \
|
||||
self.cinder_volume_snapshots.list()
|
||||
self.mock_image_list_detailed.return_value = [[], False, False]
|
||||
self.mock_availability_zone_list.return_value = \
|
||||
self.cinder_availability_zones.list()
|
||||
self.mock_extension_supported.return_value = True
|
||||
self.mock_volume_list.return_value = self.cinder_volumes.list()
|
||||
self.mock_volume_create.return_value = volume
|
||||
self.mock_group_list.return_value = self.cinder_groups.list()
|
||||
|
||||
url = reverse('horizon:project:volumes:create')
|
||||
res = self.client.post(url, formData)
|
||||
self.assertNoFormErrors(res)
|
||||
|
||||
redirect_url = INDEX_URL
|
||||
self.assertRedirectsNoFollow(res, redirect_url)
|
||||
|
||||
self.mock_volume_type_default.assert_called_once()
|
||||
self.mock_volume_type_list.assert_called_once()
|
||||
self.mock_volume_snapshot_list.assert_called_once_with(
|
||||
test.IsHttpRequest(), search_opts=SEARCH_OPTS)
|
||||
self.mock_availability_zone_list.assert_called_once()
|
||||
self.mock_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'AvailabilityZones')
|
||||
self.mock_volume_list.assert_called_once_with(test.IsHttpRequest(),
|
||||
search_opts=SEARCH_OPTS)
|
||||
self.mock_volume_create.assert_called_once_with(
|
||||
test.IsHttpRequest(), formData['size'], formData['name'],
|
||||
formData['description'], formData['type'], metadata={},
|
||||
snapshot_id=None, group_id=volume_group.id, image_id=None,
|
||||
availability_zone=formData['availability_zone'], source_volid=None)
|
||||
self.mock_image_list_detailed.assert_called_with(
|
||||
test.IsHttpRequest(),
|
||||
filters={'visibility': 'shared', 'status': 'active'})
|
||||
self.mock_tenant_quota_usages.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
targets=('volumes', 'gigabytes'))
|
||||
self.mock_group_list.assert_called_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({
|
||||
api.nova: ['server_list'],
|
||||
|
|
Loading…
Reference in New Issue