def test_edit_stack_template(self): template = self.stack_templates.first() stack = self.stacks.first() # GET to template form api.heat.stack_get(IsA(http.HttpRequest), stack.id).AndReturn(stack) # POST template form, validation api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template.data)) \ .AndReturn(json.loads(template.validate)) # GET to edit form api.heat.stack_get(IsA(http.HttpRequest), stack.id).AndReturn(stack) api.heat.template_get(IsA(http.HttpRequest), stack.id) \ .AndReturn(json.loads(template.validate)) # POST to edit form api.heat.stack_get(IsA(http.HttpRequest), stack.id).AndReturn(stack) fields = { 'stack_name': stack.stack_name, 'disable_rollback': True, 'timeout_mins': 61, 'password': '******', 'template': None, 'parameters': IsA(dict), 'files': None } api.heat.stack_update(IsA(http.HttpRequest), stack_id=stack.id, **fields) api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id) \ .AndReturn(self.networks.list()) self.mox.ReplayAll() url = reverse('horizon:project:stacks:change_template', args=[stack.id]) res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/change_template.html') form_data = { 'template_source': 'raw', 'template_data': template.data, 'method': forms.ChangeTemplateForm.__name__ } res = self.client.post(url, form_data) url = reverse('horizon:project:stacks:edit_stack', args=[ stack.id, ]) form_data = { 'template_source': 'raw', 'template_data': template.data, 'password': '******', 'parameters': template.validate, 'stack_name': stack.stack_name, 'stack_id': stack.id, "timeout_mins": 61, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", "__param_Network": self.networks.list()[0]['id'], 'method': forms.EditStackForm.__name__ } res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
def _test_tenant_quota_usages(self, nova_quotas_enabled=True, with_compute=True, with_volume=True): cinder.is_volume_service_enabled(IsA( http.HttpRequest)).AndReturn(with_volume) api.base.is_service_enabled(IsA(http.HttpRequest), 'network').AndReturn(False) api.base.is_service_enabled( IsA(http.HttpRequest), 'compute').MultipleTimes().AndReturn(with_compute) if with_compute: if nova_quotas_enabled: servers = [ s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id ] api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.network.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .AndReturn(self.floating_ips.list()) search_opts = {'tenant_id': self.request.user.tenant_id} api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \ .AndReturn([servers, False]) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.quotas.first()) if with_volume: opts = { 'all_tenants': 1, 'project_id': self.request.user.tenant_id } cinder.volume_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.cinder_volume_snapshots.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.cinder_quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = self.get_usages( nova_quotas_enabled=nova_quotas_enabled, with_volume=with_volume, with_compute=with_compute) # Compare internal structure of usages to expected. self.assertItemsEqual(expected_output, quota_usages.usages) # Compare available resources self.assertAvailableQuotasEqual(expected_output, quota_usages.usages)
def _mock_external_network_get(self, router): ext_net_id = router.external_gateway_info['network_id'] ext_net = self.networks.list()[2] api.neutron.network_get(IsA(http.HttpRequest), ext_net_id, expand_subnet=False).AndReturn(ext_net)
def test_launch(self): job = self.jobs.first() job_execution = self.job_executions.first() cluster = self.clusters.first() input_ds = self.data_sources.first() output_ds = self.data_sources.first() api.sahara.job_get(IsA(http.HttpRequest), IsA(six.text_type)) \ .AndReturn(job) api.sahara.job_get_configs(IsA(http.HttpRequest), job.type) \ .AndReturn(job) api.sahara.cluster_list(IsA(http.HttpRequest)) \ .AndReturn(self.clusters.list()) api.sahara.data_source_list(IsA(http.HttpRequest)) \ .MultipleTimes().AndReturn(self.data_sources.list()) api.sahara.job_list(IsA(http.HttpRequest)) \ .AndReturn(self.jobs.list()) api.sahara.job_get(IsA(http.HttpRequest), IsA(six.text_type)) \ .AndReturn(job) api.sahara.job_execution_create( IsA(http.HttpRequest), IsA(six.text_type), IsA(six.text_type), IsA(six.text_type), IsA(six.text_type), IsA(dict), IsA(dict), is_public=False, is_protected=False).AndReturn(job_execution) self.mox.ReplayAll() url = reverse('horizon:project:data_processing.jobs:launch-job') form_data = { 'job': self.jobs.first().id, 'cluster': cluster.id, 'job_input': input_ds.id, 'job_output': output_ds.id, 'config': {}, 'argument_ids': '{}', 'adapt_oozie': 'on', 'adapt_swift_spark': 'on', 'hbase_common_lib': 'on', 'hbase_common_lib': 'on', 'datasource_substitute': 'on', 'java_opts': '', 'job_args_array': [[], []], 'job_configs': [{}, {}], 'job_params': [{}, {}], 'job_type': 'Pig', 'streaming_mapper': '', 'streaming_reducer': '' } res = self.client.post(url, form_data) self.assertNoFormErrors(res)
def test_detail_invalid_icmp_rule(self): sec_group = self.security_groups.first() sec_group_list = self.security_groups.list() icmp_rule = self.security_group_rules.list()[1] # Call POST 4 times for i in range(4): api.network.security_group_backend(IsA( http.HttpRequest)).AndReturn(self.secgroup_backend) api.network.security_group_list(IsA( http.HttpRequest)).AndReturn(sec_group_list) self.mox.ReplayAll() formData = { 'method': 'AddRule', 'id': sec_group.id, 'port_or_range': 'port', 'icmp_type': 256, 'icmp_code': icmp_rule.to_port, 'rule_menu': icmp_rule.ip_protocol, 'cidr': icmp_rule.ip_range['cidr'], 'remote': 'cidr' } res = self.client.post(self.edit_url, formData) self.assertNoMessages() self.assertContains(res, "The ICMP type not in range (-1, 255)") formData = { 'method': 'AddRule', 'id': sec_group.id, 'port_or_range': 'port', 'icmp_type': icmp_rule.from_port, 'icmp_code': 256, 'rule_menu': icmp_rule.ip_protocol, 'cidr': icmp_rule.ip_range['cidr'], 'remote': 'cidr' } res = self.client.post(self.edit_url, formData) self.assertNoMessages() self.assertContains(res, "The ICMP code not in range (-1, 255)") formData = { 'method': 'AddRule', 'id': sec_group.id, 'port_or_range': 'port', 'icmp_type': icmp_rule.from_port, 'icmp_code': None, 'rule_menu': icmp_rule.ip_protocol, 'cidr': icmp_rule.ip_range['cidr'], 'remote': 'cidr' } res = self.client.post(self.edit_url, formData) self.assertNoMessages() self.assertContains(res, "The ICMP code is invalid") formData = { 'method': 'AddRule', 'id': sec_group.id, 'port_or_range': 'port', 'icmp_type': None, 'icmp_code': icmp_rule.to_port, 'rule_menu': icmp_rule.ip_protocol, 'cidr': icmp_rule.ip_range['cidr'], 'remote': 'cidr' } res = self.client.post(self.edit_url, formData) self.assertNoMessages() self.assertContains(res, "The ICMP type is invalid")
def test_restore_backup(self): policy.check((), IsA(http.HttpRequest)).MultipleTimes().AndReturn(True) backup = self.database_backups.first() api.trove.backup_get(IsA(http.HttpRequest), IsA(six.text_type)) \ .AndReturn(self.database_backups.first()) api.trove.backup_list(IsA(http.HttpRequest)).AndReturn( self.database_backups.list()) api.trove.configuration_list(IsA(http.HttpRequest)) \ .AndReturn(self.database_configurations.list()) api.trove.datastore_flavors(IsA(http.HttpRequest), IsA(six.string_types), IsA(six.string_types)) \ .AndReturn(self.flavors.list()) api.trove.datastore_list(IsA(http.HttpRequest)) \ .AndReturn(self.datastores.list()) api.trove.datastore_version_list(IsA(http.HttpRequest), backup.datastore['type']) \ .AndReturn(self.datastore_versions.list()) api.trove.instance_list(IsA(http.HttpRequest), marker=None) \ .AndReturn(common.Paginated(self.databases.list())) dash_api.cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn([]) dash_api.neutron.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False).\ AndReturn(self.networks.list()[:1]) dash_api.nova.availability_zone_list(IsA(http.HttpRequest)) \ .AndReturn(self.availability_zones.list()) self.mox.ReplayAll() url = RESTORE_URL + '?backup=%s' % self.database_backups.first().id res = self.client.get(url) self.assertTemplateUsed(res, 'project/databases/launch.html') set_instance_detail_step = \ [step for step in res.context_data['workflow'].steps if isinstance(step, create_instance.SetInstanceDetails)][0] fields = set_instance_detail_step.action.fields self.assertTrue(len(fields['datastore'].choices), 1) text = 'mysql - 5.6' choice = fields['datastore'].choices[0] self.assertTrue(choice[0], common_utils.hexlify(text)) self.assertTrue(choice[1], text) advanced_step = [ step for step in res.context_data['workflow'].steps if isinstance(step, create_instance.Advanced) ][0] fields = advanced_step.action.fields self.assertTrue(len(fields['initial_state'].choices), 1) choice = fields['initial_state'].choices[0] self.assertTrue(choice[0], 'backup') self.assertTrue(choice[1], _('Restore from Backup'))
def _stub_cinder_api_calls(self): api.cinder.tenant_absolute_limits(IsA(http.HttpRequest)) \ .AndReturn(self.cinder_limits['absolute'])
def setUp(self): super(NetworkApiNeutronTestBase, self).setUp() self.mox.StubOutWithMock(api.base, 'is_service_enabled') api.base.is_service_enabled(IsA(http.HttpRequest), 'network') \ .AndReturn(True) self.qclient = self.stub_neutronclient()
def setUp(self): super(NetworkApiNeutronFloatingIpTests, self).setUp() self.qclient.list_extensions() \ .AndReturn({'extensions': self.api_extensions.list()}) api.base.is_service_enabled(IsA(http.HttpRequest), 'compute') \ .AndReturn(True)
def test_list_image_communication_error_public_image_list(self): public_images = [ image for image in self.images.list() if image.status == 'active' and image.is_public ] private_images = [ image for image in self.images.list() if (image.status == 'active' and not image.is_public) ] shared_images = [ image for image in self.imagesV2.list() if (image.status == 'active' and image.visibility == 'shared') ] api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndRaise(glance_exec.CommunicationError) # Make sure the exception is handled with the correct # error message. If the exception cannot be handled, # the error message will be different. messages.error(IsA(http.HttpRequest), "Unable to retrieve public images.") api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([private_images, False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'visibility': 'shared', 'status': 'active'}) \ .AndReturn([shared_images, False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([public_images, False, False]) self.mox.ReplayAll() images_cache = {} ret = utils.get_available_images(self.request, self.tenant.id, images_cache) expected_images = [ image for image in private_images if image.container_format not in ('ami', 'aki') ] self.assertEqual(len(expected_images), len(ret)) self.assertNotIn('public_images', images_cache) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id])) self.assertEqual(len(shared_images), len(images_cache['shared_images'])) ret = utils.get_available_images(self.request, self.tenant.id, images_cache) expected_images = [ image for image in self.images.list() if image.container_format not in ('ami', 'aki') ] self.assertEqual(len(expected_images), len(ret)) self.assertEqual(len(public_images), len(images_cache['public_images'])) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id])) self.assertEqual(len(shared_images), len(images_cache['shared_images']))
def test_list_image_error_private_image_list(self): public_images = [ image for image in self.images.list() if image.status == 'active' and image.is_public ] private_images = [ image for image in self.images.list() if (image.status == 'active' and not image.is_public) ] shared_images = [ image for image in self.imagesV2.list() if (image.status == 'active' and image.visibility == 'shared') ] api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([public_images, False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndRaise(self.exceptions.glance) exceptions.handle( IsA(http.HttpRequest), "Unable to retrieve images for the current project.") api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'visibility': 'shared', 'status': 'active'}) \ .AndReturn([shared_images, False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([private_images, False, False]) self.mox.ReplayAll() images_cache = {} ret = utils.get_available_images(self.request, self.tenant.id, images_cache) expected_images = [ image for image in public_images if image.container_format not in ('ami', 'aki') ] self.assertEqual(len(expected_images), len(ret)) self.assertEqual(len(public_images), len(images_cache['public_images'])) self.assertFalse(len(images_cache['images_by_project'])) self.assertEqual(len(shared_images), len(images_cache['shared_images'])) ret = utils.get_available_images(self.request, self.tenant.id, images_cache) expected_images = [ image for image in self.images.list() if image.container_format not in ('ami', 'aki') ] self.assertEqual(len(expected_images), len(ret)) self.assertEqual(len(public_images), len(images_cache['public_images'])) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id])) self.assertEqual(len(shared_images), len(images_cache['shared_images']))
def test_list_image_using_cache(self): public_images = [ image for image in self.images.list() if image.status == 'active' and image.is_public ] private_images = [ image for image in self.images.list() if (image.status == 'active' and not image.is_public) ] shared_images = [ image for image in self.imagesV2.list() if (image.status == 'active' and image.visibility == 'shared') ] api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([public_images, False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([private_images, False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'visibility': 'shared', 'status': 'active'}) \ .AndReturn([shared_images, False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={'property-owner_id': 'other-tenant', 'status': 'active'}) \ .AndReturn([private_images, False, False]) self.mox.ReplayAll() expected_images = [ image for image in self.images.list() if (image.status == 'active' and image.container_format not in ( 'ari', 'aki')) ] images_cache = {} ret = utils.get_available_images(self.request, self.tenant.id, images_cache) self.assertEqual(len(expected_images), len(ret)) self.assertEqual(len(public_images), len(images_cache['public_images'])) self.assertEqual(1, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project'][self.tenant.id])) self.assertEqual(len(shared_images), len(images_cache['shared_images'])) ret = utils.get_available_images(self.request, self.tenant.id, images_cache) self.assertEqual(len(expected_images), len(ret)) # image list for other-tenant ret = utils.get_available_images(self.request, 'other-tenant', images_cache) self.assertEqual(len(expected_images), len(ret)) self.assertEqual(len(public_images), len(images_cache['public_images'])) self.assertEqual(2, len(images_cache['images_by_project'])) self.assertEqual( len(private_images), len(images_cache['images_by_project']['other-tenant']))
def _test_port_create_post(self, mac_learning=False, binding=False, port_security=False): network = self.networks.first() port = self.ports.first() api.neutron.network_get(IsA(http.HttpRequest), network.id) \ .MultipleTimes().AndReturn(self.networks.first()) api.neutron.is_extension_supported(IsA(http.HttpRequest), 'mac-learning') \ .AndReturn(mac_learning) api.neutron.is_extension_supported(IsA(http.HttpRequest), 'port-security') \ .AndReturn(True) extension_kwargs = {} if binding: extension_kwargs['binding__vnic_type'] = \ port.binding__vnic_type if mac_learning: extension_kwargs['mac_learning_enabled'] = True if port_security: # The default value is True, so False is intentionally used. extension_kwargs['port_security_enabled'] = False api.neutron.port_create(IsA(http.HttpRequest), tenant_id=network.tenant_id, network_id=network.id, name=port.name, admin_state_up=port.admin_state_up, device_id=port.device_id, device_owner=port.device_owner, fixed_ips=port.fixed_ips, mac_address=port.mac_address, **extension_kwargs) \ .AndReturn(port) self.mox.ReplayAll() form_data = { 'network_id': port.network_id, 'network_name': network.name, 'name': port.name, 'admin_state': port.admin_state_up, 'device_id': port.device_id, 'device_owner': port.device_owner, 'specify_ip': 'fixed_ip', 'fixed_ip': port.fixed_ips[0]['ip_address'], 'subnet_id': port.fixed_ips[0]['subnet_id'], 'mac_address': port.mac_address } if binding: form_data['binding__vnic_type'] = port.binding__vnic_type if mac_learning: form_data['mac_state'] = True if port_security: form_data['port_security_enabled'] = False url = reverse('horizon:project:networks:addport', args=[port.network_id]) res = self.client.post(url, form_data) self.assertNoFormErrors(res) redir_url = reverse(NETWORKS_DETAIL_URL, args=[port.network_id]) self.assertRedirectsNoFollow(res, redir_url)
def test_correct_quotas_displayed(self): servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] api.cinder.is_volume_service_enabled(IsA(http.HttpRequest)) \ .AndReturn(False) api.base.is_service_enabled(IsA(http.HttpRequest), 'network') \ .MultipleTimes().AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'compute') \ .MultipleTimes().AndReturn(True) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.quotas.first()) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) search_opts = {'tenant_id': self.request.user.tenant_id} api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \ .AndReturn([servers, False]) api.neutron.is_extension_supported( IsA(http.HttpRequest), 'security-group').AndReturn(True) api.neutron.is_extension_supported(IsA(http.HttpRequest), 'quotas') \ .AndReturn(True) api.neutron.is_router_enabled(IsA(http.HttpRequest)) \ .AndReturn(True) api.neutron.tenant_quota_get(IsA(http.HttpRequest), self.tenant.id) \ .AndReturn(self.neutron_quotas.first()) api.neutron.router_list(IsA(http.HttpRequest), tenant_id=self.tenant.id) \ .AndReturn(self.routers.list()) api.neutron.subnet_list(IsA(http.HttpRequest), tenant_id=self.tenant.id) \ .AndReturn(self.subnets.list()) api.neutron.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id) \ .AndReturn(self.networks.list()) api.network.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .MultipleTimes().AndReturn(self.floating_ips.list()) api.network.floating_ip_pools_list(IsA(http.HttpRequest)) \ .AndReturn(self.pools.list()) api.network.security_group_list(IsA(http.HttpRequest)) \ .AndReturn(self.security_groups.list()) self.mox.ReplayAll() url = reverse('%s:allocate' % NAMESPACE) res = self.client.get(url) self.assertEqual(res.context['usages']['floating_ips']['quota'], self.neutron_quotas.first().get('floatingip').limit)
def test_update_flavor_update_projects_error(self): # The first element has no extra specs flavor = self.flavors.first() projects = self.tenants.list() flavor_projects = [self.tenants.first()] eph = getattr(flavor, 'OS-FLV-EXT-DATA:ephemeral') extra_specs = getattr(flavor, 'extra_specs') new_flavor = flavors.Flavor(flavors.FlavorManager(None), {'id': "cccccccc-cccc-cccc-cccc-cccccccccccc", 'name': flavor.name, 'vcpus': flavor.vcpus + 1, 'disk': flavor.disk, 'ram': flavor.ram, 'swap': 0, 'rxtx_factor': flavor.rxtx_factor, 'OS-FLV-EXT-DATA:ephemeral': eph, 'os-flavor-access:is_public': False, 'extra_specs': extra_specs}) # GET/init, set up expected behavior api.nova.flavor_get(IsA(http.HttpRequest), flavor.id) \ .MultipleTimes().AndReturn(flavor) api.keystone.tenant_list(IsA(http.HttpRequest)) \ .MultipleTimes().AndReturn([projects, False]) # POST/init api.nova.flavor_list(IsA(http.HttpRequest), None) \ .AndReturn(self.flavors.list()) api.nova.flavor_get_extras(IsA(http.HttpRequest), flavor.id, raw=True) \ .AndReturn(extra_specs) api.nova.flavor_delete(IsA(http.HttpRequest), flavor.id) api.nova.flavor_create(IsA(http.HttpRequest), new_flavor.name, new_flavor.ram, new_flavor.vcpus, new_flavor.disk, swap=new_flavor.swap, rxtx_factor=new_flavor.rxtx_factor, ephemeral=eph, is_public=new_flavor.is_public) \ .AndReturn(new_flavor) new_flavor_projects = flavor_projects for project in new_flavor_projects: expect = api.nova.add_tenant_to_flavor(IsA(http.HttpRequest), new_flavor.id, project.id) if project == projects[0]: expect.AndRaise(self.exceptions.nova) # Put mocks in replay mode self.mox.ReplayAll() # run get test url = reverse(constants.FLAVORS_UPDATE_URL, args=[flavor.id]) resp = self.client.get(url) self.assertEqual(resp.status_code, 200) self.assertTemplateUsed(resp, constants.FLAVORS_UPDATE_VIEW_TEMPLATE) # run post test data = self._get_workflow_data(new_flavor, access=flavor_projects) data['flavor_id'] = flavor.id resp = self.client.post(url, data) self.assertNoFormErrors(resp) self.assertMessageCount(error=1, warning=0) self.assertRedirectsNoFollow(resp, reverse(constants.FLAVORS_INDEX_URL))
def test_update(self): ct = self.cluster_templates.first() ngts = self.nodegroup_templates.list() configs = self.plugins_configs.first() new_name = "UpdatedName" new_ct = copy.copy(ct) new_ct.name = new_name api.sahara.cluster_template_get(IsA(http.HttpRequest), ct.id) \ .AndReturn(ct) api.sahara.plugin_get_version_details(IsA(http.HttpRequest), ct.plugin_name, ct.hadoop_version) \ .MultipleTimes().AndReturn(configs) api.sahara.nodegroup_template_find(IsA(http.HttpRequest), plugin_name=ct.plugin_name, hadoop_version=ct.hadoop_version) \ .MultipleTimes().AndReturn(ngts) api.sahara.cluster_template_update(request=IsA(http.HttpRequest), ct_id=ct.id, name=new_name, plugin_name=ct.plugin_name, hadoop_version=ct.hadoop_version, description=ct.description, cluster_configs=ct.cluster_configs, node_groups=ct.node_groups, anti_affinity=ct.anti_affinity, use_autoconfig=False, shares=ct.shares, is_public=False, is_protected=False, domain_name=ct.domain_name) \ .AndReturn(new_ct) self.mox.ReplayAll() url = reverse('horizon:project:data_processing.clusters:ct-edit', args=[ct.id]) def serialize(obj): return utils.serialize(jsonutils.dump_as_bytes(obj)) res = self.client.post( url, { 'ct_id': ct.id, 'cluster_template_name': new_name, 'plugin_name': ct.plugin_name, 'hadoop_version': ct.hadoop_version, 'description': ct.description, 'hidden_configure_field': "", 'template_id_0': ct.node_groups[0]['node_group_template_id'], 'group_name_0': ct.node_groups[0]['name'], 'count_0': 1, 'serialized_0': serialize(ct.node_groups[0]), 'template_id_1': ct.node_groups[1]['node_group_template_id'], 'group_name_1': ct.node_groups[1]['name'], 'count_1': 2, 'serialized_1': serialize(ct.node_groups[1]), 'forms_ids': "[0,1]", }) self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertMessageCount(success=1)
def test_create_replica_instance(self): api.trove.flavor_list(IsA(http.HttpRequest)).AndReturn( self.flavors.list()) api.trove.backup_list(IsA(http.HttpRequest)).AndReturn( self.database_backups.list()) api.trove.instance_list(IsA(http.HttpRequest)).AndReturn( self.databases.list()) api.trove.datastore_list(IsA(http.HttpRequest))\ .AndReturn(self.datastores.list()) api.trove.datastore_version_list(IsA(http.HttpRequest), IsA(str))\ .AndReturn(self.datastore_versions.list()) api.neutron.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False).\ AndReturn(self.networks.list()[:1]) api.neutron.network_list(IsA(http.HttpRequest), shared=True).\ AndReturn(self.networks.list()[1:]) nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ''}] api.trove.instance_get(IsA(http.HttpRequest), IsA(unicode))\ .AndReturn(self.databases.first()) # Actual create database call api.trove.instance_create(IsA(http.HttpRequest), IsA(unicode), IsA(int), IsA(unicode), databases=None, datastore=IsA(unicode), datastore_version=IsA(unicode), restore_point=None, replica_of=self.databases.first().id, users=None, nics=nics).AndReturn(self.databases.first()) self.mox.ReplayAll() post = { 'name': "MyDB", 'volume': '1', 'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'network': self.networks.first().id, 'datastore': 'mysql,5.5', 'initial_state': 'master', 'master': self.databases.first().id } res = self.client.post(LAUNCH_URL, post) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_read_pp_line_eof(self): sock = self.mox.CreateMock(socket.socket) sock.recv_into(IsA(memoryview), 2).AndReturn(0) self.mox.ReplayAll() with self.assertRaises(AssertionError): self.pp._ProxyProtocolV1__read_pp_line(sock, b'')
def _stub_nova_api_calls_unauthorized(self, exception): api.nova.extension_supported( 'SimpleTenantUsage', IsA(http.HttpRequest)) \ .AndReturn(True) self._nova_stu_enabled(exception)
def test_update_domain_post(self): default_role = self.roles.first() domain = self.domains.get(id="1") test_description = 'updated description' users = self._get_all_users(domain.id) groups = self._get_all_groups(domain.id) domain_groups = self._get_domain_groups(domain.id) roles = self.roles.list() role_assignments = self._get_domain_role_assignment(domain.id) api.keystone.domain_get(IsA(http.HttpRequest), '1').AndReturn(domain) api.keystone.get_default_role(IsA(http.HttpRequest)) \ .MultipleTimes().AndReturn(default_role) api.keystone.role_list(IsA(http.HttpRequest)) \ .MultipleTimes().AndReturn(roles) api.keystone.user_list(IsA(http.HttpRequest), domain=domain.id) \ .AndReturn(users) api.keystone.role_assignments_list(IsA(http.HttpRequest), domain=domain.id, include_subtree=False) \ .AndReturn(role_assignments) api.keystone.group_list(IsA(http.HttpRequest), domain=domain.id) \ .AndReturn(groups) for group in groups: api.keystone.roles_for_group(IsA(http.HttpRequest), group=group.id, domain=domain.id) \ .AndReturn(roles) workflow_data = self._get_workflow_data(domain) # update some fields workflow_data['description'] = test_description # User assignment form data workflow_data[USER_ROLE_PREFIX + "1"] = ['3'] # admin role workflow_data[USER_ROLE_PREFIX + "2"] = ['2'] # member role # Group assignment form data workflow_data[GROUP_ROLE_PREFIX + "1"] = ['3'] # admin role workflow_data[GROUP_ROLE_PREFIX + "2"] = ['2'] # member role # handle api.keystone.domain_update(IsA(http.HttpRequest), domain.id, name=domain.name, description=test_description, enabled=domain.enabled).AndReturn(None) api.keystone.role_assignments_list(IsA(http.HttpRequest), domain=domain.id, include_subtree=False) \ .AndReturn(role_assignments) api.keystone.user_list(IsA(http.HttpRequest), domain=domain.id).AndReturn(users) # Give user 3 role 1 api.keystone.add_domain_user_role(IsA(http.HttpRequest), domain=domain.id, user='******', role='1') # remove role 2 from user 3 api.keystone.remove_domain_user_role(IsA(http.HttpRequest), domain=domain.id, user='******', role='2') # Group assignments api.keystone.group_list(IsA(http.HttpRequest), domain=domain.id).AndReturn(domain_groups) # admin group - try to remove all roles on current domain api.keystone.roles_for_group(IsA(http.HttpRequest), group='1', domain=domain.id) \ .AndReturn(roles) for role in roles: api.keystone.remove_group_role(IsA(http.HttpRequest), role=role.id, group='1', domain=domain.id) # member group 1 - has role 1, will remove it api.keystone.roles_for_group(IsA(http.HttpRequest), group='2', domain=domain.id) \ .AndReturn((roles[0],)) # remove role 1 api.keystone.remove_group_role(IsA(http.HttpRequest), role='1', group='2', domain=domain.id) # add role 2 api.keystone.add_group_role(IsA(http.HttpRequest), role='2', group='2', domain=domain.id) # member group 3 - has role 2 api.keystone.roles_for_group(IsA(http.HttpRequest), group='3', domain=domain.id) \ .AndReturn((roles[1],)) # remove role 2 api.keystone.remove_group_role(IsA(http.HttpRequest), role='2', group='3', domain=domain.id) # add role 1 api.keystone.add_group_role(IsA(http.HttpRequest), role='1', group='3', domain=domain.id) self.mox.ReplayAll() res = self.client.post(DOMAIN_UPDATE_URL, workflow_data) self.assertNoFormErrors(res) self.assertMessageCount(success=1) self.assertRedirectsNoFollow(res, DOMAINS_INDEX_URL)
def _test_json_view(self, router_enable=True): api.nova.server_list(IsA(http.HttpRequest)).AndReturn( [self.servers.list(), False]) tenant_networks = [ net for net in self.networks.list() if not net['router:external'] ] external_networks = [ net for net in self.networks.list() if net['router:external'] ] api.neutron.network_list_for_tenant(IsA( http.HttpRequest), self.tenant.id).AndReturn(tenant_networks) if router_enable: api.neutron.network_list(IsA(http.HttpRequest), **{ 'router:external': True }).AndReturn(external_networks) # router1 : gateway port not in the port list # router2 : no gateway port # router3 : gateway port included in port list routers = self.routers.list() + self.routers_with_rules.list() if router_enable: api.neutron.router_list( IsA(http.HttpRequest), tenant_id=self.tenant.id).AndReturn(routers) api.neutron.port_list(IsA(http.HttpRequest)).AndReturn( self.ports.list()) self.mox.ReplayAll() res = self.client.get(JSON_URL) self.assertEqual('text/json', res['Content-Type']) data = json.loads(res.content) # servers # result_server_urls = [(server['id'], server['url']) # for server in data['servers']] expect_server_urls = [{ 'id': server.id, 'name': server.name, 'status': server.status, 'task': None, 'url': '/project/instances/%s/' % server.id } for server in self.servers.list()] self.assertEqual(expect_server_urls, data['servers']) # rotuers # result_router_urls = [(router['id'], router['url']) # for router in data['routers']] if router_enable: expect_router_urls = [{ 'id': router.id, 'external_gateway_info': router.external_gateway_info, 'name': router.name, 'status': router.status, 'url': '/project/routers/%s/' % router.id } for router in routers] self.assertEqual(expect_router_urls, data['routers']) else: self.assertFalse(data['routers']) # networks expect_net_urls = [] if router_enable: expect_net_urls += [{ 'id': net.id, 'url': '/project/networks/%s/detail' % net.id, 'name': net.name, 'router:external': net.router__external, 'status': net.status, 'subnets': [] } for net in external_networks] expect_net_urls += [{ 'id': net.id, 'url': '/project/networks/%s/detail' % net.id, 'name': net.name, 'router:external': net.router__external, 'status': net.status, 'subnets': [{ 'cidr': subnet.cidr, 'id': subnet.id, 'url': '/project/networks/subnets/%s/detail' % subnet.id } for subnet in net.subnets] } for net in tenant_networks] for exp_net in expect_net_urls: if exp_net['url'] is None: del exp_net['url'] self.assertEqual(expect_net_urls, data['networks']) # ports expect_port_urls = [{ 'id': port.id, 'device_id': port.device_id, 'device_owner': port.device_owner, 'fixed_ips': port.fixed_ips, 'network_id': port.network_id, 'status': port.status, 'url': '/project/networks/ports/%s/detail' % port.id } for port in self.ports.list()] if router_enable: # fake port for router1 gateway (router1 on ext_net) router1 = routers[0] ext_net = external_networks[0] expect_port_urls.append({ 'id': 'gateway%s' % ext_net.id, 'device_id': router1.id, 'network_id': ext_net.id, 'fixed_ips': [] }) self.assertEqual(expect_port_urls, data['ports'])
def test_detail_invalid_icmp_rule(self): sec_group = self.security_groups.first() sec_group_list = self.security_groups.list() icmp_rule = self.security_group_rules.list()[1] # Call POST 5 times (*2 if Django >= 1.9) call_post = 5 if django.VERSION >= (1, 9): call_post *= 2 for i in range(call_post): api.neutron.security_group_list(IsA( http.HttpRequest)).AndReturn(sec_group_list) self.mox.ReplayAll() formData = { 'method': 'AddRule', 'id': sec_group.id, 'port_or_range': 'port', 'icmp_type': 256, 'icmp_code': icmp_rule.to_port, 'rule_menu': icmp_rule.ip_protocol, 'cidr': icmp_rule.ip_range['cidr'], 'remote': 'cidr' } res = self.client.post(self.edit_url, formData) self.assertNoMessages() self.assertContains(res, "The ICMP type not in range (-1, 255)") formData = { 'method': 'AddRule', 'id': sec_group.id, 'port_or_range': 'port', 'icmp_type': icmp_rule.from_port, 'icmp_code': 256, 'rule_menu': icmp_rule.ip_protocol, 'cidr': icmp_rule.ip_range['cidr'], 'remote': 'cidr' } res = self.client.post(self.edit_url, formData) self.assertNoMessages() self.assertContains(res, "The ICMP code not in range (-1, 255)") formData = { 'method': 'AddRule', 'id': sec_group.id, 'port_or_range': 'port', 'icmp_type': icmp_rule.from_port, 'icmp_code': None, 'rule_menu': icmp_rule.ip_protocol, 'cidr': icmp_rule.ip_range['cidr'], 'remote': 'cidr' } res = self.client.post(self.edit_url, formData) self.assertNoMessages() self.assertContains(res, "The ICMP code not in range (-1, 255)") formData = { 'method': 'AddRule', 'id': sec_group.id, 'port_or_range': 'port', 'icmp_type': None, 'icmp_code': icmp_rule.to_port, 'rule_menu': icmp_rule.ip_protocol, 'cidr': icmp_rule.ip_range['cidr'], 'remote': 'cidr' } res = self.client.post(self.edit_url, formData) self.assertNoMessages() self.assertContains(res, "The ICMP type not in range (-1, 255)") formData = { 'method': 'AddRule', 'id': sec_group.id, 'port_or_range': 'port', 'icmp_type': -1, 'icmp_code': icmp_rule.to_port, 'rule_menu': icmp_rule.ip_protocol, 'cidr': icmp_rule.ip_range['cidr'], 'remote': 'cidr' } res = self.client.post(self.edit_url, formData) self.assertNoMessages() self.assertContains(res, "ICMP code is provided but ICMP type is missing.")
def _test_index(self, ec2_enabled): keypairs = self.keypairs.list() sec_groups = self.security_groups.list() floating_ips = self.floating_ips.list() quota_data = self.quota_usages.first() quota_data['security_groups']['available'] = 10 api.nova.server_list( IsA(http.HttpRequest)) \ .AndReturn([self.servers.list(), False]) api.nova.keypair_list( IsA(http.HttpRequest)) \ .AndReturn(keypairs) api.network.floating_ip_supported( IsA(http.HttpRequest)) \ .AndReturn(True) api.network.tenant_floating_ip_list( IsA(http.HttpRequest)) \ .AndReturn(floating_ips) api.network.security_group_list( IsA(http.HttpRequest)) \ .AndReturn(sec_groups) quotas.tenant_quota_usages( IsA(http.HttpRequest)).MultipleTimes() \ .AndReturn(quota_data) api.base.is_service_enabled( IsA(http.HttpRequest), 'network').MultipleTimes() \ .AndReturn(True) api.base.is_service_enabled( IsA(http.HttpRequest), 'ec2').MultipleTimes() \ .AndReturn(ec2_enabled) self.mox.ReplayAll() res = self.client.get(INDEX_URL) self.assertTemplateUsed(res, 'project/access_and_security/index.html') self.assertItemsEqual(res.context['keypairs_table'].data, keypairs) self.assertItemsEqual(res.context['floating_ips_table'].data, floating_ips) # Security groups sec_groups_from_ctx = res.context['security_groups_table'].data # Context data needs to contains all items from the test data. self.assertItemsEqual(sec_groups_from_ctx, sec_groups) # Sec groups in context need to be sorted by their ``name`` attribute. # This assertion is somewhat weak since it's only meaningful as long as # the sec groups in the test data are *not* sorted by name (which is # the case as of the time of this addition). self.assertTrue( all([ sec_groups_from_ctx[i].name <= sec_groups_from_ctx[i + 1].name for i in range(len(sec_groups_from_ctx) - 1) ])) if ec2_enabled: self.assertTrue( any( map(lambda x: isinstance(x, api_access.tables.DownloadEC2), res.context['endpoints_table'].get_table_actions()))) else: self.assertFalse( any( map(lambda x: isinstance(x, api_access.tables.DownloadEC2), res.context['endpoints_table'].get_table_actions())))
def test_create(self): flavor = self.flavors.first() ngt = self.nodegroup_templates.first() configs = self.plugins_configs.first() new_name = ngt.name + '-new' self.mox.StubOutWithMock(workflow_helpers, 'parse_configs_from_context') dash_api.cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones') \ .AndReturn(True) dash_api.cinder.availability_zone_list(IsA(http.HttpRequest))\ .AndReturn(self.availability_zones.list()) dash_api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn([flavor]) api.sahara.plugin_get_version_details(IsA(http.HttpRequest), ngt.plugin_name, ngt.hadoop_version) \ .MultipleTimes().AndReturn(configs) dash_api.network.floating_ip_pools_list(IsA(http.HttpRequest)) \ .AndReturn([]) dash_api.network.security_group_list(IsA(http.HttpRequest)) \ .AndReturn([]) workflow_helpers.parse_configs_from_context(IgnoreArg(), IgnoreArg()).AndReturn({}) api.sahara.nodegroup_template_create( IsA(http.HttpRequest), **{'name': new_name, 'plugin_name': ngt.plugin_name, 'hadoop_version': ngt.hadoop_version, 'description': ngt.description, 'flavor_id': flavor.id, 'volumes_per_node': None, 'volumes_size': None, 'volumes_availability_zone': None, 'node_processes': ['namenode'], 'node_configs': {}, 'floating_ip_pool': None, 'security_groups': [], 'auto_security_group': True, 'availability_zone': None, 'is_proxy_gateway': False}) \ .AndReturn(True) self.mox.ReplayAll() res = self.client.post( CREATE_URL, { 'nodegroup_name': new_name, 'plugin_name': ngt.plugin_name, ngt.plugin_name + '_version': '1.2.1', 'hadoop_version': ngt.hadoop_version, 'description': ngt.description, 'flavor': flavor.id, 'availability_zone': None, 'storage': 'ephemeral_drive', 'volumes_per_node': 0, 'volumes_size': 0, 'volumes_availability_zone': None, 'floating_ip_pool': None, 'security_autogroup': True, 'processes': 'HDFS:namenode' }) self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertMessageCount(success=1)
def _test_usage(self, nova_stu_enabled=True, tenant_deleted=False): self._stub_api_calls(nova_stu_enabled) api.nova.extension_supported( 'SimpleTenantUsage', IsA(http.HttpRequest)) \ .AndReturn(nova_stu_enabled) now = timezone.now() usage_list = [api.nova.NovaUsage(u) for u in self.usages.list()] if tenant_deleted: api.keystone.tenant_list(IsA(http.HttpRequest)) \ .AndReturn([[self.tenants.first()], False]) else: api.keystone.tenant_list(IsA(http.HttpRequest)) \ .AndReturn([self.tenants.list(), False]) if nova_stu_enabled: api.nova.usage_list(IsA(http.HttpRequest), datetime.datetime(now.year, now.month, 1, 0, 0, 0, 0), datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0)) \ .AndReturn(usage_list) api.nova.tenant_absolute_limits(IsA(http.HttpRequest)) \ .AndReturn(self.limits['absolute']) api.neutron.is_extension_supported(IsA(http.HttpRequest), 'security-group').AndReturn(True) api.network.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .AndReturn(self.floating_ips.list()) api.network.security_group_list(IsA(http.HttpRequest)) \ .AndReturn(self.q_secgroups.list()) api.cinder.tenant_absolute_limits(IsA(http.HttpRequest)) \ .AndReturn(self.cinder_limits['absolute']) self.mox.ReplayAll() res = self.client.get(reverse('horizon:admin:overview:index')) self.assertTemplateUsed(res, 'admin/overview/usage.html') self.assertTrue(isinstance(res.context['usage'], usage.GlobalUsage)) self.assertEqual(nova_stu_enabled, res.context['simple_tenant_usage_enabled']) usage_table = encoding.smart_str(u''' <tr class="" data-object-id="1" id="global_usage__row__1"> <td class="sortable normal_column">test_tenant</td> <td class="sortable normal_column">%s</td> <td class="sortable normal_column">%s</td> <td class="sortable normal_column">%s</td> <td class="sortable normal_column">%.2f</td> <td class="sortable normal_column">%.2f</td> <td class="sortable normal_column">%.2f</td> </tr> ''' % (usage_list[0].vcpus, sizeformat.diskgbformat(usage_list[0].local_gb), sizeformat.mb_float_format(usage_list[0].memory_mb), usage_list[0].vcpu_hours, usage_list[0].disk_gb_hours, usage_list[0].memory_mb_hours) ) # test for deleted project usage_table_deleted = encoding.smart_str(u''' <tr class="" data-object-id="3" id="global_usage__row__3"> <td class="sortable normal_column">3 (Deleted)</td> <td class="sortable normal_column">%s</td> <td class="sortable normal_column">%s</td> <td class="sortable normal_column">%s</td> <td class="sortable normal_column">%.2f</td> <td class="sortable normal_column">%.2f</td> <td class="sortable normal_column">%.2f</td> </tr> ''' % (usage_list[1].vcpus, sizeformat.diskgbformat(usage_list[1].local_gb), sizeformat.mb_float_format(usage_list[1].memory_mb), usage_list[1].vcpu_hours, usage_list[1].disk_gb_hours, usage_list[1].memory_mb_hours) ) if nova_stu_enabled: self.assertContains(res, usage_table, html=True) if tenant_deleted: self.assertContains(res, usage_table_deleted, html=True) else: self.assertNotContains(res, usage_table_deleted, html=True) else: self.assertNotContains(res, usage_table, html=True)
def test_update(self): flavor = self.flavors.first() ngt = self.nodegroup_templates.first() configs = self.plugins_configs.first() new_name = ngt.name + '-updated' UPDATE_URL = reverse( 'horizon:project:data_processing.nodegroup_templates:edit', kwargs={'template_id': ngt.id}) self.mox.StubOutWithMock(workflow_helpers, 'parse_configs_from_context') dash_api.cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones') \ .AndReturn(True) dash_api.cinder.availability_zone_list(IsA(http.HttpRequest)) \ .AndReturn(self.availability_zones.list()) dash_api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn([flavor]) api.sahara.plugin_get_version_details(IsA(http.HttpRequest), ngt.plugin_name, ngt.hadoop_version) \ .MultipleTimes().AndReturn(configs) dash_api.network.floating_ip_pools_list(IsA(http.HttpRequest)) \ .AndReturn([]) dash_api.network.security_group_list(IsA(http.HttpRequest)) \ .AndReturn([]) workflow_helpers.parse_configs_from_context(IgnoreArg(), IgnoreArg()).AndReturn({}) api.sahara.nodegroup_template_get(IsA(http.HttpRequest), ngt.id) \ .AndReturn(ngt) api.sahara.nodegroup_template_update( request=IsA(http.HttpRequest), ngt_id=ngt.id, name=new_name, plugin_name=ngt.plugin_name, hadoop_version=ngt.hadoop_version, flavor_id=flavor.id, description=ngt.description, volumes_per_node=None, volumes_size=None, volumes_availability_zone=None, node_processes=['namenode'], node_configs={}, floating_ip_pool=None, security_groups=[], auto_security_group=True, availability_zone=None).AndReturn(True) self.mox.ReplayAll() res = self.client.post( UPDATE_URL, { 'ng_id': ngt.id, 'nodegroup_name': new_name, 'plugin_name': ngt.plugin_name, ngt.plugin_name + '_version': '1.2.1', 'hadoop_version': ngt.hadoop_version, 'description': ngt.description, 'flavor': flavor.id, 'availability_zone': None, 'storage': 'ephemeral_drive', 'volumes_per_node': 0, 'volumes_size': 0, 'volumes_availability_zone': None, 'floating_ip_pool': None, 'security_autogroup': True, 'processes': 'HDFS:namenode' }) self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertMessageCount(success=1)
def test_tenant_quota_usages_unlimited_quota(self): inf_quota = self.quotas.first() inf_quota['ram'] = -1 servers = [ s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id ] cinder.is_volume_service_enabled(IsA(http.HttpRequest)).AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'network').AndReturn(False) api.base.is_service_enabled(IsA(http.HttpRequest), 'compute').MultipleTimes().AndReturn(True) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(inf_quota) api.network.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .AndReturn(self.floating_ips.list()) search_opts = {'tenant_id': self.request.user.tenant_id} api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \ .AndReturn([servers, False]) opts = {'all_tenants': 1, 'project_id': self.request.user.tenant_id} cinder.volume_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.cinder_volume_snapshots.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.cinder_quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = self.get_usages() expected_output.update({ 'ram': { 'available': float("inf"), 'used': 1024, 'quota': float("inf") } }) # Compare internal structure of usages to expected. self.assertItemsEqual(expected_output, quota_usages.usages)
def test_update_flavor_with_extra_specs(self): # The second element has extra specs flavor = self.flavors.list()[1] projects = self.tenants.list() eph = getattr(flavor, 'OS-FLV-EXT-DATA:ephemeral') extra_specs = getattr(flavor, 'extra_specs') new_flavor = flavors.Flavor(flavors.FlavorManager(None), {'id': "cccccccc-cccc-cccc-cccc-cccccccccccc", 'name': flavor.name, 'vcpus': flavor.vcpus + 1, 'disk': flavor.disk, 'ram': flavor.ram, 'swap': flavor.swap, 'rxtx_factor': flavor.rxtx_factor, 'OS-FLV-EXT-DATA:ephemeral': eph, 'extra_specs': extra_specs}) # GET/init, set up expected behavior api.nova.flavor_get(IsA(http.HttpRequest), flavor.id) \ .MultipleTimes().AndReturn(flavor) api.keystone.tenant_list(IsA(http.HttpRequest)) \ .MultipleTimes().AndReturn([projects, False]) # POST/init api.nova.flavor_list(IsA(http.HttpRequest), None) \ .AndReturn(self.flavors.list()) api.nova.flavor_get_extras(IsA(http.HttpRequest), flavor.id, raw=True) \ .AndReturn(extra_specs) api.nova.flavor_delete(IsA(http.HttpRequest), flavor.id) api.nova.flavor_create(IsA(http.HttpRequest), new_flavor.name, new_flavor.ram, new_flavor.vcpus, new_flavor.disk, swap=new_flavor.swap, rxtx_factor=new_flavor.rxtx_factor, ephemeral=eph, is_public=True).AndReturn(new_flavor) api.nova.flavor_extra_set(IsA(http.HttpRequest), new_flavor.id, extra_specs) self.mox.ReplayAll() # run get test url = reverse(constants.FLAVORS_UPDATE_URL, args=[flavor.id]) resp = self.client.get(url) self.assertEqual(resp.status_code, 200) self.assertTemplateUsed(resp, constants.FLAVORS_UPDATE_VIEW_TEMPLATE) # run post test workflow_data = {'flavor_id': flavor.id, 'name': new_flavor.name, 'vcpus': new_flavor.vcpus, 'memory_mb': new_flavor.ram, 'disk_gb': new_flavor.disk, 'swap_mb': new_flavor.swap, 'rxtx_factor': flavor.rxtx_factor, 'eph_gb': eph, 'is_public': True} resp = self.client.post(url, workflow_data) self.assertNoFormErrors(resp) self.assertMessageCount(success=1) self.assertRedirectsNoFollow(resp, reverse(constants.FLAVORS_INDEX_URL))
def _test_port_create_post_exception(self, mac_learning=False, binding=False, port_security=False): network = self.networks.first() port = self.ports.first() api.neutron.network_get(IsA(http.HttpRequest), network.id)\ .AndReturn(self.networks.first()) api.neutron.network_get(IsA(http.HttpRequest), network.id)\ .AndReturn(self.networks.first()) api.neutron.network_get(IsA(http.HttpRequest), network.id)\ .AndReturn(self.networks.first()) api.neutron.is_extension_supported(IsA(http.HttpRequest), 'mac-learning')\ .AndReturn(mac_learning) api.neutron.is_extension_supported(IsA(http.HttpRequest), 'binding') \ .AndReturn(binding) api.neutron.is_extension_supported(IsA(http.HttpRequest), 'port-security')\ .AndReturn(port_security) extension_kwargs = {} if binding: extension_kwargs['binding__vnic_type'] = port.binding__vnic_type if mac_learning: extension_kwargs['mac_learning_enabled'] = True if port_security: extension_kwargs['port_security_enabled'] = True api.neutron.port_create(IsA(http.HttpRequest), tenant_id=network.tenant_id, network_id=network.id, name=port.name, admin_state_up=port.admin_state_up, device_id=port.device_id, device_owner=port.device_owner, binding__host_id=port.binding__host_id, mac_address=port.mac_address, **extension_kwargs)\ .AndRaise(self.exceptions.neutron) self.mox.ReplayAll() form_data = {'network_id': port.network_id, 'network_name': network.name, 'name': port.name, 'admin_state': port.admin_state_up, 'mac_state': True, 'device_id': port.device_id, 'device_owner': port.device_owner, 'binding__host_id': port.binding__host_id, 'mac_address': port.mac_address} if binding: form_data['binding__vnic_type'] = port.binding__vnic_type if mac_learning: form_data['mac_learning_enabled'] = True if port_security: form_data['port_security_enabled'] = True url = reverse('horizon:admin:networks:addport', args=[port.network_id]) res = self.client.post(url, form_data) self.assertNoFormErrors(res) redir_url = reverse(NETWORKS_DETAIL_URL, args=[port.network_id]) self.assertRedirectsNoFollow(res, redir_url)
def test_launch_stack_parameter_types(self): template = { 'data': ('heat_template_version: 2013-05-23\n' 'parameters:\n' ' param1:\n' ' type: string\n' ' param2:\n' ' type: number\n' ' param3:\n' ' type: json\n' ' param4:\n' ' type: comma_delimited_list\n' ' param5:\n' ' type: boolean\n'), 'validate': { "Description": "No description", "Parameters": { "param1": { "Type": "String", "NoEcho": "false", "Description": "", "Label": "param1" }, "param2": { "Type": "Number", "NoEcho": "false", "Description": "", "Label": "param2" }, "param3": { "Type": "Json", "NoEcho": "false", "Description": "", "Label": "param3" }, "param4": { "Type": "CommaDelimitedList", "NoEcho": "false", "Description": "", "Label": "param4" }, "param5": { "Type": "Boolean", "NoEcho": "false", "Description": "", "Label": "param5" } } } } stack = self.stacks.first() api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template['data'])) \ .AndReturn(template['validate']) api.heat.stack_create(IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=hc_format.parse(template['data']), parameters={ 'param1': 'some string', 'param2': 42, 'param3': '{"key": "value"}', 'param4': 'a,b,c', 'param5': True }, password='******', files={}) self.mox.ReplayAll() url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = { 'template_source': 'raw', 'template_data': template['data'], 'method': forms.TemplateForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') # ensure the fields were rendered correctly if django.VERSION >= (1, 10): input_str = ('<input class="form-control" ' 'id="id___param_param{0}" ' 'name="__param_param{0}" type="{1}" required/>') else: input_str = ('<input class="form-control" ' 'id="id___param_param{0}" ' 'name="__param_param{0}" type="{1}"/>') self.assertContains(res, input_str.format(1, 'text'), html=True) self.assertContains(res, input_str.format(2, 'number'), html=True) self.assertContains(res, input_str.format(3, 'text'), html=True) self.assertContains(res, input_str.format(4, 'text'), html=True) self.assertContains( res, '<input id="id___param_param5" name="__param_param5" ' 'type="checkbox">', html=True) # post some sample data and make sure it validates url = reverse('horizon:project:stacks:launch') form_data = { 'template_source': 'raw', 'template_data': template['data'], 'password': '******', 'parameters': json.dumps(template['validate']), 'stack_name': stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_param1": "some string", "__param_param2": 42, "__param_param3": '{"key": "value"}', "__param_param4": "a,b,c", "__param_param5": True, 'method': forms.CreateStackForm.__name__ } res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)