def test_snapshot_tab(self): cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volumes.list()) api.nova.server_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn([self.servers.list(), False]) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) keystone.tenant_list(IsA(http.HttpRequest)). \ AndReturn([self.tenants.list(), False]) cinder.volume_snapshot_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}). \ AndReturn(self.cinder_volume_snapshots.list()) cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volumes.list()) keystone.tenant_list(IsA(http.HttpRequest)). \ AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.get(reverse('horizon:admin:volumes:snapshots_tab')) self.assertEqual(res.status_code, 200) self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
def test_create_cgroup_exception(self): volume_types = self.cinder_volume_types.list() az = self.cinder_availability_zones.first().zoneName formData = {'volume_types': '1', 'name': 'test CG', 'description': 'test desc', 'availability_zone': az} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(volume_types) cinder.volume_type_list_with_qos_associations(IsA(http.HttpRequest)).\ AndReturn(volume_types) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.volume_cgroup_list(IsA( http.HttpRequest)).\ AndReturn(self.cinder_consistencygroups.list()) cinder.volume_cgroup_create( IsA(http.HttpRequest), formData['volume_types'], formData['name'], formData['description'], availability_zone=formData['availability_zone'])\ .AndRaise(self.exceptions.cinder) self.mox.ReplayAll() url = reverse('horizon:project:volumes:cgroups:create') res = self.client.post(url, formData) self.assertRedirectsNoFollow(res, VOLUME_INDEX_URL)
def test_create_volume_from_snapshot_invalid_size(self): usage_limit = {'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.cinder_volumes.list()), 'maxTotalVolumes': 6} snapshot = self.cinder_volume_snapshots.first() formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 20, 'snapshot_source': snapshot.id} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\ AndReturn(self.cinder_volumes.first()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') res = self.client.post("?".join([url, "snapshot_id=" + str(snapshot.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError(res, 'form', None, "The volume size cannot be less than the " "snapshot size (40GB)")
def test_create_volume(self): volume = self.volumes.first() volume_type = self.volume_types.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} 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': ''} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], formData['type'], metadata={}, snapshot_id=None).AndReturn(volume) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def test_create_volume_number_over_alloted_quota(self): usage_limit = { "maxTotalVolumeGigabytes": 100, "gigabytesUsed": 20, "volumesUsed": len(self.cinder_volumes.list()), "maxTotalVolumes": len(self.cinder_volumes.list()), } formData = { "name": u"Too Many...", "description": u"We have no volumes left!", "method": u"CreateForm", "size": 10, } cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volume_snapshots.list()) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"is_public": True, "status": "active"} ).AndReturn([self.images.list(), False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"} ).AndReturn([[], False, False]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volumes.list()) cinder.extension_supported(IsA(http.HttpRequest), "AvailabilityZones").AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) self.mox.ReplayAll() url = reverse("horizon:project:volumes:volumes:create") res = self.client.post(url, formData) expected_error = [u"You are already using all of your available" " volumes."] self.assertEqual(res.context["form"].errors["__all__"], expected_error)
def test_create_volume_from_image_under_image_min_disk_size(self): usage_limit = {'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.cinder_volumes.list()), 'maxTotalVolumes': 6} image = self.images.get(name="protected_images") image.min_disk = 30 formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 5, 'image_source': image.id} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') res = self.client.post("?".join([url, "image_id=" + str(image.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError(res, 'form', None, "The volume size cannot be less than the " "image minimum disk size (30GB)")
def test_create_volume_gb_used_over_alloted_quota(self): usage_limit = { "maxTotalVolumeGigabytes": 100, "gigabytesUsed": 80, "volumesUsed": len(self.cinder_volumes.list()), "maxTotalVolumes": 6, } formData = { "name": u"This Volume Is Huge!", "description": u"This is a volume that is just too big!", "method": u"CreateForm", "size": 5000, } cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volume_snapshots.list()) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"is_public": True, "status": "active"} ).AndReturn([self.images.list(), False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"} ).AndReturn([[], False, False]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volumes.list()) cinder.extension_supported(IsA(http.HttpRequest), "AvailabilityZones").AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) self.mox.ReplayAll() url = reverse("horizon:project:volumes:volumes:create") res = self.client.post(url, formData) expected_error = [u"A volume of 5000GB cannot be created as you only" " have 20GB of your quota available."] self.assertEqual(res.context["form"].errors["__all__"], expected_error)
def test_create_volume_from_image_invalid_size(self): usage_limit = {'maxTotalVolumeGigabytes': 100, 'maxTotalVolumes': 6} image = self.images.first() formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 1, 'image_source': image.id} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.volumes.list()) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.volumes.list()) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post("?".join([url, "image_id=" + str(image.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError(res, 'form', None, "The volume size cannot be less than the " "image size (20.0 GB)")
def test_index(self): cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).AndReturn(self.cinder_volumes.list()) api.nova.server_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}) \ .AndReturn([self.servers.list(), False]) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) keystone.tenant_list(IsA(http.HttpRequest)) \ .AndReturn([self.tenants.list(), False]) cinder.volume_snapshot_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volume_snapshots.list()) cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volumes.list()) keystone.tenant_list(IsA(http.HttpRequest)). \ AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.get(reverse('horizon:admin:volumes:index')) self.assertTemplateUsed(res, 'admin/volumes/index.html') volumes = res.context['volumes_table'].data self.assertItemsEqual(volumes, self.cinder_volumes.list())
def test_manage_volume(self): metadata = {"key": u"k1", "value": u"v1"} formData = { "host": "host-1", "identifier": "vol-1", "id_type": u"source-name", "name": "name-1", "description": "manage a volume", "volume_type": "vol_type_1", "availability_zone": "nova", "metadata": metadata["key"] + "=" + metadata["value"], "bootable": False, } cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volume_types.list()) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(self.availability_zones.list()) cinder.extension_supported(IsA(http.HttpRequest), "AvailabilityZones").AndReturn(True) cinder.volume_manage( IsA(http.HttpRequest), host=formData["host"], identifier=formData["identifier"], id_type=formData["id_type"], name=formData["name"], description=formData["description"], volume_type=formData["volume_type"], availability_zone=formData["availability_zone"], metadata={metadata["key"]: metadata["value"]}, bootable=formData["bootable"], ) self.mox.ReplayAll() res = self.client.post(reverse("horizon:admin:volumes:volumes:manage"), formData) self.assertNoFormErrors(res)
def test_type_encryption_detail_view_unencrypted(self): volume_type1 = self.volume_types.list()[0] volume_type1.id = u'1' volume_type_list = [volume_type1] vol_unenc_type = self.cinder_volume_encryption_types.list()[2] cinder.volume_encryption_type_get(IsA(http.HttpRequest), volume_type1.id)\ .AndReturn(vol_unenc_type) cinder.volume_type_list(IsA(http.HttpRequest))\ .AndReturn(volume_type_list) self.mox.ReplayAll() url = reverse('horizon:admin:volumes:' 'volume_types:type_encryption_detail', args=[volume_type1.id]) res = self.client.get(url) self.assertTemplateUsed( res, 'admin/volumes/volume_types/volume_encryption_type_detail.html') self.assertContains(res, "<h3>Volume Type is Unencrypted.</h3>", 1, 200) self.assertNoMessages()
def test_create_volume_from_snapshot_invalid_size(self): usage_limit = { "maxTotalVolumeGigabytes": 100, "gigabytesUsed": 20, "volumesUsed": len(self.cinder_volumes.list()), "maxTotalVolumes": 6, } snapshot = self.cinder_volume_snapshots.first() formData = { "name": u"A Volume I Am Making", "description": u"This is a volume I am making for a test.", "method": u"CreateForm", "size": 20, "snapshot_source": snapshot.id, } cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).AndReturn(self.cinder_volumes.first()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) self.mox.ReplayAll() url = reverse("horizon:project:volumes:volumes:create") res = self.client.post("?".join([url, "snapshot_id=" + str(snapshot.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError(res, "form", None, "The volume size cannot be less than the " "snapshot size (40GB)")
def test_create_volume_gb_used_over_alloted_quota(self): usage_limit = {'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 80, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6} formData = {'name': u'This Volume Is Huge!', 'description': u'This is a volume that is just too big!', 'method': u'CreateForm', 'size': 5000} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) expected_error = [u'A volume of 5000GB cannot be created as you only' ' have 20GB of your quota available.'] self.assertEqual(res.context['form'].errors['__all__'], expected_error)
def test_create_volume_number_over_alloted_quota(self): usage_limit = {'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': len(self.volumes.list())} formData = {'name': u'Too Many...', 'description': u'We have no volumes left!', 'method': u'CreateForm', 'size': 10} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) expected_error = [u'You are already using all of your available' ' volumes.'] self.assertEqual(res.context['form'].errors['__all__'], expected_error)
def test_create_volume_type_encryption(self): volume_type1 = self.volume_types.list()[0] volume_type2 = self.volume_types.list()[1] volume_type1.id = u'1' volume_type2.id = u'2' volume_type_list = [volume_type1, volume_type2] formData = {'name': u'An Encrypted Volume Type', 'provider': u'a-provider', 'control_location': u'front-end', 'cipher': u'a-cipher', 'key_size': 512, 'volume_type_id': volume_type1.id} cinder.volume_type_list(IsA(http.HttpRequest))\ .AndReturn(volume_type_list) cinder.volume_encryption_type_create(IsA(http.HttpRequest), formData['volume_type_id'], formData) self.mox.ReplayAll() url = reverse('horizon:admin:volumes:' 'volume_types:create_type_encryption', args=[volume_type1.id]) res = self.client.post(url, formData) self.assertNoFormErrors(res) self.assertTemplateUsed( res, 'admin/volumes/volume_types/create_volume_type_encryption.html')
def test_type_encryption_detail_view_encrypted(self): volume_type = self.volume_types.first() volume_type.id = u'1' volume_type.name = "An Encrypted Volume Name" volume_type_list = [volume_type] vol_enc_type = self.cinder_volume_encryption_types.list()[0] cinder.volume_encryption_type_get(IsA(http.HttpRequest), volume_type.id)\ .AndReturn(vol_enc_type) cinder.volume_type_list(IsA(http.HttpRequest))\ .AndReturn(volume_type_list) self.mox.ReplayAll() url = reverse('horizon:admin:volumes' ':volume_types:type_encryption_detail', args=[volume_type.id]) res = self.client.get(url) self.assertTemplateUsed( res, 'admin/volumes/volume_types/volume_encryption_type_detail.html') self.assertContains(res, "<h3>Volume Type Encryption Overview</h3>", 1, 200) self.assertContains(res, "<dd>%s</dd>" % volume_type.name, 1, 200) self.assertContains(res, "<dd>%s</dd>" % vol_enc_type.control_location, 1, 200) self.assertContains(res, "<dd>%s</dd>" % vol_enc_type.key_size, 1, 200) self.assertContains(res, "<dd>%s</dd>" % vol_enc_type.provider, 1, 200) self.assertContains(res, "<dd>%s</dd>" % vol_enc_type.cipher, 1, 200) self.assertNoMessages()
def test_create_volume_from_image_under_image_min_disk_size(self): usage_limit = { "maxTotalVolumeGigabytes": 100, "gigabytesUsed": 20, "volumesUsed": len(self.cinder_volumes.list()), "maxTotalVolumes": 6, } image = self.images.get(name="protected_images") image.min_disk = 30 formData = { "name": u"A Volume I Am Making", "description": u"This is a volume I am making for a test.", "method": u"CreateForm", "size": 5, "image_source": image.id, } cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.extension_supported(IsA(http.HttpRequest), "AvailabilityZones").AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) self.mox.ReplayAll() url = reverse("horizon:project:volumes:volumes:create") res = self.client.post("?".join([url, "image_id=" + str(image.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError( res, "form", None, "The volume size cannot be less than the " "image minimum disk size (30GB)" )
def test_create_cgroup_exception(self): volume_types = self.cinder_volume_types.list() volume_type_id = self.cinder_volume_types.first().id az = self.cinder_availability_zones.first().zoneName formData = {'volume_types': '1', 'name': 'test CG', 'description': 'test desc', 'availability_zone': az, 'add_vtypes_to_cgroup_role_member': [volume_type_id]} cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(volume_types) cinder.volume_type_list_with_qos_associations(IsA(http.HttpRequest)).\ AndReturn(volume_types) cinder.volume_cgroup_list(IsA(http.HttpRequest)).\ AndReturn(self.cinder_consistencygroups.list()) cinder.volume_cgroup_create( IsA(http.HttpRequest), formData['volume_types'], formData['name'], formData['description'], availability_zone=formData['availability_zone'])\ .AndRaise(self.exceptions.cinder) self.mox.ReplayAll() url = reverse('horizon:project:cgroups:create') res = self.client.post(url, formData) self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertIn("Unable to create consistency group.", res.cookies.output())
def test_create_cgroup(self): cgroup = self.cinder_consistencygroups.first() volume_types = self.cinder_volume_types.list() az = self.cinder_availability_zones.first().zoneName formData = {'volume_types': '1', 'name': 'test CG', 'description': 'test desc', 'availability_zone': az} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(volume_types) cinder.volume_type_list_with_qos_associations(IsA(http.HttpRequest)).\ AndReturn(volume_types) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.volume_cgroup_list(IsA( http.HttpRequest)).\ AndReturn(self.cinder_consistencygroups.list()) cinder.volume_cgroup_create( IsA(http.HttpRequest), formData['volume_types'], formData['name'], formData['description'], availability_zone=formData['availability_zone'])\ .AndReturn(cgroup) self.mox.ReplayAll() url = reverse('horizon:virtual:volumes:cgroups:create') res = self.client.post(url, formData) self.assertNoFormErrors(res)
def test_update_volume_type_encryption(self): volume_type = self.cinder_volume_types.first() volume_type.id = u'1' volume_type_list = [volume_type] formData = {'name': u'An Encrypted Volume Type', 'provider': u'a-provider', 'control_location': u'front-end', 'cipher': u'a-cipher', 'key_size': 256, 'volume_type_id': volume_type.id} vol_enc_type = self.cinder_volume_encryption_types.list()[0] cinder.volume_encryption_type_get(IsA(http.HttpRequest), volume_type.id)\ .AndReturn(vol_enc_type) cinder.volume_type_list(IsA(http.HttpRequest))\ .AndReturn(volume_type_list) cinder.volume_encryption_type_update(IsA(http.HttpRequest), formData['volume_type_id'], formData) self.mox.ReplayAll() url = reverse('horizon:admin:volume_types:update_type_encryption', args=[volume_type.id]) res = self.client.post(url, formData) self.assertNoFormErrors(res) self.assertTemplateUsed( res, 'admin/volume_types/update_volume_type_encryption.html')
def test_create_volume_from_snapshot(self): volume = self.volumes.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} snapshot = self.volume_snapshots.first() formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 50, 'type': '', 'snapshot_source': snapshot.id} # first call- with url param cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\ AndReturn(self.volumes.first()) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', snapshot_id=snapshot.id).\ AndReturn(volume) # second call- with dropdown cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', snapshot_id=snapshot.id).\ AndReturn(volume) self.mox.ReplayAll() # get snapshot from url url = reverse('horizon:project:volumes:create') res = self.client.post("?".join([url, "snapshot_id=" + str(snapshot.id)]), formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url) # get snapshot from dropdown list url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def test_create_volume_from_image_dropdown(self): volume = self.cinder_volumes.first() usage_limit = {'maxTotalVolumeGigabytes': 200, 'gigabytesUsed': 20, 'volumesUsed': len(self.cinder_volumes.list()), 'maxTotalVolumes': 6} image = self.images.first() formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 30, 'type': '', 'volume_source_type': 'image_source', 'snapshot_source': self.cinder_volume_snapshots.first().id, 'image_source': image.id} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.cinder_volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) cinder.volume_list(IsA( http.HttpRequest)).AndReturn(self.cinder_volumes.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)) \ .AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=None, image_id=image.id, availability_zone=None, source_volid=None).AndReturn(volume) self.mox.ReplayAll() # get image from dropdown list url = reverse('horizon:project:volumes:volumes:create') res = self.client.post(url, formData) redirect_url = VOLUME_VOLUMES_TAB_URL self.assertRedirectsNoFollow(res, redirect_url)
def test_create_volume_from_volume(self): volume = self.volumes.first() usage_limit = {'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6} formData = {'name': u'A copy of a volume', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 50, 'type': '', 'volume_source_type': 'volume_source', 'volume_source': volume.id} cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.volumes.list()) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(self.volumes.first()) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones').AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=None, image_id=None, availability_zone=None, source_volid=volume.id).AndReturn(volume) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') redirect_url = reverse('horizon:project:volumes:index') res = self.client.post(url, formData) self.assertNoFormErrors(res) self.assertMessageCount(info=1) self.assertRedirectsNoFollow(res, redirect_url)
def test_create_volume_from_image_dropdown(self): volume = self.cinder_volumes.first() usage_limit = { "maxTotalVolumeGigabytes": 200, "gigabytesUsed": 20, "volumesUsed": len(self.cinder_volumes.list()), "maxTotalVolumes": 6, } image = self.images.first() formData = { "name": u"A Volume I Am Making", "description": u"This is a volume I am making for a test.", "method": u"CreateForm", "size": 30, "type": "", "volume_source_type": "image_source", "snapshot_source": self.cinder_volume_snapshots.first().id, "image_source": image.id, } cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(self.volume_types.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volume_snapshots.list()) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"is_public": True, "status": "active"} ).AndReturn([self.images.list(), False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"} ).AndReturn([[], False, False]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volumes.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.extension_supported(IsA(http.HttpRequest), "AvailabilityZones").AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(self.cinder_availability_zones.list()) cinder.volume_create( IsA(http.HttpRequest), formData["size"], formData["name"], formData["description"], "", metadata={}, snapshot_id=None, image_id=image.id, availability_zone=None, source_volid=None, ).AndReturn(volume) self.mox.ReplayAll() # get image from dropdown list url = reverse("horizon:project:volumes:volumes:create") res = self.client.post(url, formData) redirect_url = VOLUME_VOLUMES_TAB_URL self.assertRedirectsNoFollow(res, redirect_url)
def test_create_volume_cannot_encrypt(self): volume = self.volumes.first() volume_type = self.volume_types.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} formData = { 'name': u'An Encrypted Volume', 'description': u'This volume has metadata for encryption.', 'method': u'CreateForm', 'type': volume_type.name, 'size': 50, 'snapshot_source': '', 'encryption': u'LUKS' } # check that widget is hidden if can_encrypt_volumes = false PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = False volume = self.volumes.first() volume_type = self.volume_types.first() usage_limit = { 'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'maxTotalVolumes': 6 } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.get(url) # Assert the encryption field is hidden. form = res.context['form'] self.assertTrue( isinstance(form.fields['encryption'].widget, widgets.HiddenInput)) settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
def test_create_volume_from_image_dropdown(self): volume = self.volumes.first() usage_limit = { 'maxTotalVolumeGigabytes': 200, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6 } image = self.images.first() formData = { 'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 30, 'type': '', 'volume_source_type': 'image_source', 'snapshot_source': self.volume_snapshots.first().id, 'image_source': image.id } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) quotas.tenant_limit_usages(IsA(http.HttpRequest)) \ .AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=None, image_id=image.id).\ AndReturn(volume) self.mox.ReplayAll() # get image from dropdown list url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def test_create_volume_encrypted(self): volume = self.volumes.first() volume_type = self.volume_types.first() usage_limit = {'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'maxTotalVolumes': 6} formData = {'name': u'An Encrypted Volume', 'description': u'This volume has metadata for encryption.', 'method': u'CreateForm', 'type': volume_type.name, 'size': 50, 'snapshot_source': '', 'encryption': u'LUKS'} # check normal operation with can_encrypt_volumes = true PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = True cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], formData['type'], metadata={'encryption': formData['encryption']}, snapshot_id=None, image_id=None).AndReturn(volume) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url) settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
def test_create_volume_cannot_encrypt(self): volume = self.volumes.first() volume_type = self.volume_types.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} formData = {'name': u'An Encrypted Volume', 'description': u'This volume has metadata for encryption.', 'method': u'CreateForm', 'type': volume_type.name, 'size': 50, 'snapshot_source': '', 'encryption': u'LUKS'} # check that widget is hidden if can_encrypt_volumes = false PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = False volume = self.volumes.first() volume_type = self.volume_types.first() usage_limit = {'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'maxTotalVolumes': 6} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.get(url) # Assert the encryption field is hidden. form = res.context['form'] self.assertTrue(isinstance(form.fields['encryption'].widget, widgets.HiddenInput)) settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
def test_create_volume_from_image(self): volume = self.volumes.first() usage_limit = { 'maxTotalVolumeGigabytes': 200, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6 } image = self.images.first() formData = { 'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 40, 'type': '', 'image_source': image.id } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=None, image_id=image.id, availability_zone=None, source_volid=None).AndReturn(volume) self.mox.ReplayAll() # get image from url url = reverse('horizon:project:volumes:volumes:create') res = self.client.post("?".join([url, "image_id=" + str(image.id)]), formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def test_create_volume_from_snapshot_dropdown(self): volume = self.volumes.first() usage_limit = {'maxTotalVolumeGigabytes': 250, 'maxTotalVolumes': 6} snapshot = self.volume_snapshots.first() formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 50, 'type': '', 'volume_source_type': 'snapshot_source', 'snapshot_source': snapshot.id} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.volumes.list()) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=snapshot.id, image_id=None).\ AndReturn(volume) self.mox.ReplayAll() # get snapshot from dropdown list url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = [] try: volume_types = cinder.volume_type_list(request) except Exception: redirect_url = reverse("horizon:project:volumes:index") error_message = _('Unable to retrieve the volume type list.') exceptions.handle(request, error_message, redirect=redirect_url) self.fields['type'].choices = [("", _("No volume type"))] + \ [(type.name, type.name) for type in volume_types] if 'initial' in kwargs and 'type' in kwargs['initial']: # if there is a default volume type to select, then remove # the first ""No volume type" entry self.fields['type'].choices.pop(0) if "snapshot_id" in request.GET: self.prepare_source_fields_if_snapshot_specified(request) elif 'image_id' in request.GET: self.prepare_source_fields_if_image_specified(request) elif 'volume_id' in request.GET: self.prepare_source_fields_if_volume_specified(request) else: self.prepare_source_fields_default(request) self._populate_group_choices(request)
def _get_volume_types(self): volume_types = [] try: volume_types = cinder.volume_type_list(self.request) except Exception: exceptions.handle(self.request, _('Unable to retrieve volume type list.')) # check if we have default volume type so we can present the # description of no volume type differently no_type_description = None if self.default_vol_type is None: message = \ _("If \"No volume type\" is selected, the volume will be " "created without a volume type.") no_type_description = encoding.force_text(message) type_descriptions = [{'name': '', 'description': no_type_description}] + \ [{'name': type.name, 'description': getattr(type, "description", "")} for type in volume_types] return json.dumps(type_descriptions)
def __init__(self, request, *args, **kwargs): super(CommonAccountQuotaAction, self).__init__(request, *args, **kwargs) # set fields min value to -1 for field in self.fields: self.fields[field].widget.attrs.update({'min': '-1'}) # populate volume type quotas for volume_type in cinder.volume_type_list(self.request): self.fields['quota_gigabytes_' + volume_type.name] = forms.IntegerField(label=_( "%s (GB)" % volume_type.name), required=False) # display default quota values for quota in nova.itenant_quota_get(self.request, None): field = 'quota_' + quota.name if self.fields.get(field): self.fields[field].widget.attrs.update( {'placeholder': str(quota.limit)}) for quota in cinder.default_quota_get(self.request, None): field = 'quota_' + quota.name if self.fields.get(field): self.fields[field].widget.attrs.update( {'placeholder': str(quota.limit)})
def __init__(self, request, *args, **kwargs): super(AddVolumeTypesToCGroupAction, self).__init__(request, *args, **kwargs) err_msg = _('Unable to get the available volume types') default_role_field_name = self.get_default_role_field_name() self.fields[default_role_field_name] = forms.CharField(required=False) self.fields[default_role_field_name].initial = 'member' field_name = self.get_member_field_name('member') self.fields[field_name] = forms.MultipleChoiceField(required=False) vtypes = [] try: vtypes = cinder.volume_type_list(request) except Exception: exceptions.handle(request, err_msg) vtype_names = [] for vtype in vtypes: if vtype.name not in vtype_names: vtype_names.append(vtype.name) vtype_names.sort() self.fields[field_name].choices = \ [(vtype_name, vtype_name) for vtype_name in vtype_names]
def test_create_volume_encrypted(self): volume = self.volumes.first() volume_type = self.volume_types.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} formData = {'name': u'An Encrypted Volume', 'description': u'This volume has metadata for encryption.', 'method': u'CreateForm', 'type': volume_type.name, 'size': 50, 'snapshot_source': '', 'encryption': u'LUKS'} # check normal operation with can_encrypt_volumes = true PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = True cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], formData['type'], metadata={'encryption': formData['encryption']}, snapshot_id=None, image_id=None).AndReturn(volume) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url) settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
def test_create_volume_number_over_alloted_quota(self): usage_limit = { 'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': len(self.volumes.list()) } formData = { 'name': u'Too Many...', 'description': u'We have no volumes left!', 'method': u'CreateForm', 'size': 10 } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn( self.volumes.list()) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') res = self.client.post(url, formData) expected_error = [ u'You are already using all of your available' ' volumes.' ] self.assertEqual(res.context['form'].errors['__all__'], expected_error)
def test_create_volume_gb_used_over_alloted_quota(self): usage_limit = { 'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 80, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6 } formData = { 'name': u'This Volume Is Huge!', 'description': u'This is a volume that is just too big!', 'method': u'CreateForm', 'size': 5000 } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn( self.volumes.list()) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') res = self.client.post(url, formData) expected_error = [ u'A volume of 5000GB cannot be created as you only' ' have 20GB of your quota available.' ] self.assertEqual(res.context['form'].errors['__all__'], expected_error)
def test_create_volume_from_image_under_image_size(self): usage_limit = { 'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6 } image = self.images.first() formData = { 'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 1, 'image_source': image.id } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') res = self.client.post("?".join([url, "image_id=" + str(image.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) # in django 1.6 filesizeformat replaces all spaces with # non-breaking space characters if django.VERSION >= (1, 6): msg = (u"The volume size cannot be less than the " u"image size (20.0\xa0GB)") else: msg = (u"The volume size cannot be less than the " u"image size (20.0 GB)") self.assertFormError(res, 'form', None, msg)
def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields['type'].choices = [("", "")] + \ [(type.name, type.name) for type in volume_types] # Hide the volume encryption field if the hypervisor doesn't support it # NOTE: as of Grizzly this is not yet supported in Nova so enabling # this setting will not do anything useful hypervisor_features = getattr(settings, "OPENSTACK_HYPERVISOR_FEATURES", {}) can_encrypt_volumes = hypervisor_features.get("can_encrypt_volumes", False) if can_encrypt_volumes: # TODO(laura-glendenning) get from api call in future encryption_options = {"LUKS": "dmcrypt LUKS"} self.fields['encryption'].choices = [("", "")] + \ [(enc, display) for enc, display in encryption_options.items()] else: self.fields['encryption'].widget = forms.widgets.HiddenInput() self.fields['encryption'].required = False if ("snapshot_id" in request.GET): try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.display_name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot), ) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except: pass self.fields['size'].help_text = _( 'Volume size must be equal ' 'to or greater than the snapshot size (%sGB)' % snapshot.size) except: exceptions.handle(request, _('Unable to load the specified snapshot.')) else: try: snapshots = cinder.volume_snapshot_list(request) if snapshots: choices = [('', _("Choose a snapshot"))] + \ [(s.id, s) for s in snapshots] self.fields['snapshot_source'].choices = choices else: del self.fields['snapshot_source'] except: exceptions.handle(request, _("Unable to retrieve " "volume snapshots."))
def test_volume_types_tab(self): cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.qos_spec_list(IsA(http.HttpRequest)).\ AndReturn(self.cinder_qos_specs.list()) self.mox.ReplayAll() res = self.client.get( reverse('horizon:admin:volumes:volume_types_tab')) self.assertEqual(res.status_code, 200) self.assertTemplateUsed( res, 'admin/volumes/volume_types/volume_types_tables.html') volume_types = res.context['volume_types_table'].data self.assertItemsEqual(volume_types, self.volume_types.list()) qos_specs = res.context['qos_specs_table'].data self.assertItemsEqual(qos_specs, self.cinder_qos_specs.list())
def test_create_volume_from_snapshot(self): volume = self.cinder_volumes.first() usage_limit = { 'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'volumesUsed': len(self.cinder_volumes.list()), 'maxTotalVolumes': 6 } snapshot = self.cinder_volume_snapshots.first() formData = { 'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 50, 'type': '', 'snapshot_source': snapshot.id } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\ AndReturn(self.cinder_volumes.first()) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=snapshot.id, image_id=None, availability_zone=None, source_volid=None).AndReturn(volume) self.mox.ReplayAll() # get snapshot from url url = reverse('horizon:project:volumes:volumes:create') res = self.client.post( "?".join([url, "snapshot_id=" + str(snapshot.id)]), formData) redirect_url = VOLUME_VOLUMES_TAB_URL self.assertRedirectsNoFollow(res, redirect_url)
def get_volume_types_data(self): try: volume_types = cinder.volume_type_list(self.request) except: volume_types = [] exceptions.handle(self.request, _("Unable to retrieve volume types")) return volume_types
def test_delete_volume_type(self): volume_type = self.volume_types.first() formData = {'action': 'volume_types__delete__%s' % volume_type.id} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.qos_spec_list(IsA(http.HttpRequest)).\ AndReturn(self.cinder_qos_specs.list()) cinder.volume_type_delete(IsA(http.HttpRequest), str(volume_type.id)) self.mox.ReplayAll() res = self.client.post(reverse('horizon:admin:volumes:volumes_tab'), formData) redirect = reverse('horizon:admin:volumes:volumes_tab') self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, redirect)
def test_create_volume_from_snapshot_invalid_size(self): usage_limit = { 'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6 } snapshot = self.volume_snapshots.first() formData = { 'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 20, 'snapshot_source': snapshot.id } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\ AndReturn(self.volumes.first()) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post("?".join( [url, "snapshot_id=" + str(snapshot.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError( res, 'form', None, "The volume size cannot be less than the " "snapshot size (40GB)")
def test_index(self): cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).AndReturn(self.volumes.list()) api.nova.server_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}) \ .AndReturn([self.servers.list(), False]) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) keystone.tenant_list(IsA(http.HttpRequest)) \ .AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.get(reverse('horizon:admin:volumes:index')) self.assertTemplateUsed(res, 'admin/volumes/index.html') volumes = res.context['volumes_table'].data self.assertItemsEqual(volumes, self.volumes.list())
def __init__(self, request, *args, **kwargs): super(ManageVolume, self).__init__(request, *args, **kwargs) self.fields['id_type'].choices = [("source-name", _("Name"))] + \ [("source-id", _("ID"))] volume_types = cinder.volume_type_list(request) self.fields['volume_type'].choices = [("", _("No volume type"))] + \ [(type.name, type.name) for type in volume_types] self.fields['availability_zone'].choices = \ project_forms.availability_zones(request)
def test_create_volume(self): volume = self.volumes.first() volume_type = self.volume_types.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} 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': ''} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], formData['type'], metadata={}, snapshot_id=None, image_id=None).AndReturn(volume) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def test_create_volume_from_image_under_image_min_disk_size(self): usage_limit = { 'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6 } image = self.images.get(name="protected_images") image.min_disk = 30 formData = { 'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 5, 'image_source': image.id } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') res = self.client.post("?".join([url, "image_id=" + str(image.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError( res, 'form', None, "The volume size cannot be less than the " "image minimum disk size (30GB)")
def test_create_volume_gb_used_over_alloted_quota(self): usage = {'gigabytes': {'available': 100, 'used': 20}} formData = {'name': u'This Volume Is Huge!', 'description': u'This is a volume that is just too big!', 'method': u'CreateForm', 'size': 5000} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) expected_error = [u'A volume of 5000GB cannot be created as you only' ' have 100GB of your quota available.'] self.assertEqual(res.context['form'].errors['__all__'], expected_error)
def test_create_volume_cannot_encrypt(self): # check that widget is hidden if can_encrypt_volumes = false PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = False usage_limit = { 'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'maxTotalVolumes': 6 } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.get(url) # Assert the encryption field is hidden. form = res.context['form'] self.assertTrue( isinstance(form.fields['encryption'].widget, widgets.HiddenInput)) settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
def test_create_volume_cannot_encrypt(self): volume = self.volumes.first() volume_type = self.volume_types.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} formData = { 'name': u'An Encrypted Volume', 'description': u'This volume has metadata for encryption.', 'method': u'CreateForm', 'type': volume_type.name, 'size': 50, 'snapshot_source': '', 'encryption': u'LUKS' } # check that widget is hidden if can_encrypt_volumes = false PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = False volume = self.volumes.first() volume_type = self.volume_types.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.get(url) # Assert the encryption field is hidden. form = res.context['form'] self.assertTrue( isinstance(form.fields['encryption'].widget, widgets.HiddenInput)) settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
def __init__(self, request, *args, **kwargs): super(RetypeForm, self).__init__(request, *args, **kwargs) try: volume_types = cinder.volume_type_list(request) self.fields['volume_type'].choices = [(t.name, t.name) for t in volume_types] self.fields['volume_type'].initial = self.initial['volume_type'] except Exception: redirect_url = reverse("horizon:project:volumes:index") error_message = _('Unable to retrieve the volume type list.') exceptions.handle(request, error_message, redirect=redirect_url)
def test_manage_volume(self): metadata = {'key': u'k1', 'value': u'v1'} formData = {'host': 'host-1', 'identifier': 'vol-1', 'id_type': u'source-name', 'name': 'name-1', 'description': 'manage a volume', 'volume_type': 'vol_type_1', 'availability_zone': 'nova', 'metadata': metadata['key'] + '=' + metadata['value'], 'bootable': False} cinder.volume_type_list( IsA(http.HttpRequest)). \ AndReturn(self.cinder_volume_types.list()) cinder.availability_zone_list( IsA(http.HttpRequest)). \ AndReturn(self.availability_zones.list()) cinder.extension_supported( IsA(http.HttpRequest), 'AvailabilityZones'). \ AndReturn(True) cinder.volume_manage( IsA(http.HttpRequest), host=formData['host'], identifier=formData['identifier'], id_type=formData['id_type'], name=formData['name'], description=formData['description'], volume_type=formData['volume_type'], availability_zone=formData['availability_zone'], metadata={metadata['key']: metadata['value']}, bootable=formData['bootable']) self.mox.ReplayAll() res = self.client.post( reverse('horizon:admin:volumes:manage'), formData) self.assertNoFormErrors(res)
def test_delete_volume_type(self): volume_type = self.volume_types.first() formData = {'action': 'volume_types__delete__%s' % volume_type.id} cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).AndReturn(self.volumes.list()) api.nova.server_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}) \ .AndReturn([self.servers.list(), False]) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.volume_type_delete(IsA(http.HttpRequest), str(volume_type.id)) keystone.tenant_list(IsA(http.HttpRequest)) \ .AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.post(reverse('horizon:admin:volumes:index'), formData) redirect = reverse('horizon:admin:volumes:index') self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, redirect)
def test_create_volume_number_over_alloted_quota(self): usage = {'gigabytes': {'available': 100, 'used': 20}, 'volumes': {'available': 0}} formData = {'name': u'Too Many...', 'description': u'We have no volumes left!', 'method': u'CreateForm', 'size': 10} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) expected_error = [u'You are already using all of your available' ' volumes.'] self.assertEqual(res.context['form'].errors['__all__'], expected_error)
def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields['type'].choices = [("no_type", _("No volume type"))] + \ [(type.name, type.name) for type in volume_types] if "snapshot_id" in request.GET: self.prepare_source_fields_if_snapshot_specified(request) elif 'image_id' in request.GET: self.prepare_source_fields_if_image_specified(request) elif 'volume_id' in request.GET: self.prepare_source_fields_if_volume_specified(request) else: self.prepare_source_fields_default(request)
def test_create_cgroup_exception(self): volume_types = self.cinder_volume_types.list() volume_type_id = self.cinder_volume_types.first().id az = self.cinder_availability_zones.first().zoneName formData = { 'volume_types': '1', 'name': 'test CG', 'description': 'test desc', 'availability_zone': az, 'add_vtypes_to_cgroup_role_member': [volume_type_id] } cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(volume_types) cinder.volume_type_list_with_qos_associations(IsA(http.HttpRequest)).\ AndReturn(volume_types) cinder.volume_cgroup_list(IsA(http.HttpRequest)).\ AndReturn(self.cinder_consistencygroups.list()) cinder.volume_cgroup_create( IsA(http.HttpRequest), formData['volume_types'], formData['name'], formData['description'], availability_zone=formData['availability_zone'])\ .AndRaise(self.exceptions.cinder) self.mox.ReplayAll() url = reverse('horizon:compute_user:volume2:cgroups:create') res = self.client.post(url, formData) self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, VOLUME_INDEX_URL) self.assertIn("Unable to create consistency group.", res.cookies.output())