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_usage(self, nova_stu_enabled=True, tenant_deleted=False, overview_days_range=1): self._stub_api_calls(nova_stu_enabled) api.nova.extension_supported( 'SimpleTenantUsage', IsA(http.HttpRequest)) \ .AndReturn(nova_stu_enabled) 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: start_day, now = self._get_start_end_range(overview_days_range) api.nova.usage_list(IsA(http.HttpRequest), datetime.datetime(start_day.year, start_day.month, start_day.day, 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), reserved=True) \ .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.assertIsInstance(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_images_list_get_prev_pagination(self): images = self.images.list()[:3] filters = {'is_public': None} kwargs = { 'paginate': True, 'filters': filters, 'sort_dir': 'asc', 'sort_key': 'name' } api.glance.image_list_detailed(IsA(http.HttpRequest), marker=None, reversed_order=False, **kwargs) \ .AndReturn([images, True, False]) api.glance.image_list_detailed(IsA(http.HttpRequest), marker=None, reversed_order=False, **kwargs) \ .AndReturn([images[:2], True, True]) api.glance.image_list_detailed(IsA(http.HttpRequest), marker=images[2].id, reversed_order=False, **kwargs) \ .AndReturn([images[2:], True, True]) api.glance.image_list_detailed(IsA(http.HttpRequest), marker=images[2].id, reversed_order=True, **kwargs) \ .AndReturn([images[:2], True, True]) # Test tenant list api.keystone.tenant_list(IsA(http.HttpRequest)).MultipleTimes().\ AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() url = reverse('horizon:compute:images:index') res = self.client.get(url) # get all self.assertEqual(len(res.context['images_table'].data), len(images)) self.assertTemplateUsed(res, INDEX_TEMPLATE) self.assertContains(res, 'test_tenant', 5, 200) res = self.client.get(url) # get first page with 2 items self.assertEqual(len(res.context['images_table'].data), settings.API_RESULT_PAGE_SIZE) self.assertContains(res, 'test_tenant', 4, 200) params = "=".join( [tables.AdminImagesTable._meta.pagination_param, images[2].id]) url = "?".join([reverse('horizon:compute:images:index'), params]) res = self.client.get(url) # get second page (item 3) self.assertEqual(len(res.context['images_table'].data), 1) self.assertContains(res, 'test_tenant', 3, 200) params = "=".join([ tables.AdminImagesTable._meta.prev_pagination_param, images[2].id ]) url = "?".join([reverse('horizon:compute:images:index'), params]) res = self.client.get(url) # prev back to get first page with 2 items self.assertEqual(len(res.context['images_table'].data), settings.API_RESULT_PAGE_SIZE) self.assertContains(res, 'test_tenant', 4, 200)
def _test_add_member_post(self, with_weight=True, with_server_list=True, mult_ports=False): member = self.members.first() server1 = self.AttributeDict({ 'id': '12381d38-c3eb-4fee-9763-12de3338042e', 'name': 'vm1' }) server2 = self.AttributeDict({ 'id': '12381d38-c3eb-4fee-9763-12de3338043e', 'name': 'vm2' }) api.lbaas.pool_list(IsA(http.HttpRequest), tenant_id=self.tenant.id) \ .AndReturn(self.pools.list()) api.nova.server_list(IsA(http.HttpRequest)).AndReturn( [[server1, server2], False]) if with_server_list: pool = self.pools.list()[1] port1 = self.AttributeDict({ 'fixed_ips': [{ 'ip_address': member.address, 'subnet_id': 'e8abc972-eb0c-41f1-9edd-4bc6e3bcd8c9' }], 'network_id': '82288d84-e0a5-42ac-95be-e6af08727e42' }) api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool) if mult_ports: port2 = self.AttributeDict({ 'fixed_ips': [{ 'ip_address': '172.16.88.12', 'subnet_id': '3f7c5d79-ee55-47b0-9213-8e669fb03009' }], 'network_id': '72c3ab6c-c80f-4341-9dc5-210fa31ac6c2' }) api.neutron.port_list(IsA(http.HttpRequest), device_id=server1.id).AndReturn( [port1, port2]) else: api.neutron.port_list(IsA(http.HttpRequest), device_id=server1.id).AndReturn([ port1, ]) form_data = { 'pool_id': member.pool_id, 'protocol_port': member.protocol_port, 'members': [server1.id], 'admin_state_up': member.admin_state_up } if with_weight: form_data['weight'] = member.weight if with_server_list: form_data['member_type'] = 'server_list' else: form_data['member_type'] = 'member_address' form_data['address'] = member.address api.lbaas.member_create(IsA(http.HttpRequest), **form_data).AndReturn(member) self.mox.ReplayAll() res = self.client.post(reverse(self.ADDMEMBER_PATH), form_data) self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
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))\ .MultipleTimes().AndReturn(self.datastore_versions.list()) dash_api.neutron.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False).\ AndReturn(self.networks.list()[:1]) dash_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(six.text_type))\ .AndReturn(self.databases.first()) # Actual create database call api.trove.instance_create( IsA(http.HttpRequest), IsA(six.text_type), IsA(int), IsA(six.text_type), databases=None, datastore=IsA(six.text_type), datastore_version=IsA(six.text_type), 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_launch_stack_with_parameter_group(self): template = { 'data': ('heat_template_version: 2013-05-23\n' 'parameters:\n' ' last_param:\n' ' type: string\n' ' first_param:\n' ' type: string\n' ' middle_param:\n' ' type: string\n' 'parameter_groups:\n' '- parameters:\n' ' - first_param\n' ' - middle_param\n' ' - last_param\n'), 'validate': { 'Description': 'No description', 'Parameters': { 'last_param': { 'Label': 'last_param', 'Description': '', 'Type': 'String', 'NoEcho': 'false' }, 'first_param': { 'Label': 'first_param', 'Description': '', 'Type': 'String', 'NoEcho': 'false' }, 'middle_param': { 'Label': 'middle_param', 'Description': '', 'Type': 'String', 'NoEcho': 'true' } }, 'ParameterGroups': [ { 'parameters': [ 'first_param', 'middle_param', 'last_param' ] } ] } } api.heat.template_validate(IsA(http.HttpRequest), template=template['data']) \ .AndReturn(template['validate']) 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 in the correct order regex = re.compile('^.*>first_param<.*>middle_param<.*>last_param<.*$', flags=re.DOTALL) self.assertRegexpMatches(res.content.decode('utf-8'), regex)
def _test_add_vip_common_post(self, vip_name='vip1', subnet_name='mysubnet1', pool_name='pool1', with_diff_subnet=False, with_conn_limit=True): """This method is common for both IPv4 and IPv6 tests. For IPv6 test we will pass the corresponding vip_name, subnet_name & pool_name. """ vip = self.vips.get(name=vip_name) subnet = self.subnets.get(name=subnet_name) pool = self.pools.get(name=pool_name) networks = [ { 'subnets': [ subnet, ] }, ] api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).MultipleTimes().AndReturn(pool) api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id).AndReturn(subnet) api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id).AndReturn(networks) params = { 'name': vip.name, 'description': vip.description, 'pool_id': vip.pool_id, 'address': vip.address, 'subnet_id': pool.subnet_id, 'protocol_port': vip.protocol_port, 'protocol': vip.protocol, 'session_persistence': vip.session_persistence['type'], 'cookie_name': vip.session_persistence['cookie_name'], 'admin_state_up': vip.admin_state_up, } if with_conn_limit: params['connection_limit'] = vip.connection_limit if with_diff_subnet: params['subnet_id'] = vip.subnet_id api.lbaas.vip_create(IsA(http.HttpRequest), **params).AndReturn(vip) self.mox.ReplayAll() form_data = { 'name': vip.name, 'description': vip.description, 'pool_id': vip.pool_id, 'address': vip.address, 'subnet_id': pool.subnet_id, 'protocol_port': vip.protocol_port, 'protocol': vip.protocol, 'session_persistence': vip.session_persistence['type'].lower(), 'cookie_name': vip.session_persistence['cookie_name'], 'admin_state_up': vip.admin_state_up } if with_conn_limit: form_data['connection_limit'] = vip.connection_limit if with_diff_subnet: params['subnet_id'] = vip.subnet_id res = self.client.post(reverse(self.ADDVIP_PATH, args=(pool.id, )), form_data) self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, str(self.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.neutron.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.neutron.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 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.neutron.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.neutron.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_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) for server in self.servers.list(): if server.status != u'BUILD': CONSOLE_OUTPUT = '/vncserver' CONSOLE_TITLE = '&title=%s' % server.id CONSOLE_URL = CONSOLE_OUTPUT + CONSOLE_TITLE console_mock = self.mox.CreateMock(api.nova.VNCConsole) console_mock.url = CONSOLE_OUTPUT console.get_console(IsA(http.HttpRequest), 'AUTO', server) \ .AndReturn(('VNC', CONSOLE_URL)) # 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()) if router_enable: api.neutron.network_list(IsA(http.HttpRequest), **{ 'router:external': True }).AndReturn(external_networks) self.mox.ReplayAll() res = self.client.get(JSON_URL) self.assertEqual('text/json', res['Content-Type']) data = jsonutils.loads(res.content) # servers # result_server_urls = [(server['id'], server['url']) # for server in data['servers']] expect_server_urls = [] for server in self.servers.list(): expect_server = { 'id': server.id, 'name': server.name, 'status': server.status.title(), 'original_status': server.status, 'task': None, 'url': '/project/instances/%s/' % server.id } if server.status != 'BUILD': expect_server['console'] = 'vnc' expect_server_urls.append(expect_server) self.assertEqual(expect_server_urls, data['servers']) # routers # 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.title(), 'original_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.title(), 'original_status': net.status, 'subnets': [] } for net in external_networks] expect_net_urls.extend([{ 'id': net.id, 'url': '/project/networks/%s/detail' % net.id, 'name': net.name, 'router:external': net.router__external, 'status': net.status.title(), 'original_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']) valid_network_ids = [net.id for net in tenant_networks] if router_enable: valid_network_ids = [net.id for net in self.networks.list()] # 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.title(), 'original_status': port.status, 'url': '/project/networks/ports/%s/detail' % port.id } for port in self.ports.list() if port.network_id in valid_network_ids] 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 * 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_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)
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), template=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': IsA(six.text_type), 'parameters': IsA(dict) } 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_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), template=template['data']) \ .AndReturn(template['validate']) api.heat.stack_create(IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=template['data'], parameters={'param1': 'some string', 'param2': 42, 'param3': '{"key": "value"}', 'param4': 'a,b,c', 'param5': True}, password='******') 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 self.assertContains(res, '<input class="form-control" ' 'id="id___param_param1" ' 'name="__param_param1" ' 'type="text" />', html=True) if django.VERSION >= (1, 6): self.assertContains(res, '<input class="form-control" ' 'id="id___param_param2" ' 'name="__param_param2" ' 'type="number" />', html=True) else: self.assertContains(res, '<input class="form-control" ' 'id="id___param_param2" ' 'name="__param_param2" ' 'type="text" />', html=True) self.assertContains(res, '<input class="form-control" ' 'id="id___param_param3" ' 'name="__param_param3" ' 'type="text" />', html=True) self.assertContains(res, '<input class="form-control" ' 'id="id___param_param4" ' 'name="__param_param4" ' 'type="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)
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) \ .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(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'] = 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, 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, '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_learning_enabled'] = 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_tenant_quota_usages_neutron_with_target(self, targets): cinder.is_volume_service_enabled(IsA(http.HttpRequest)).AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'network') \ .AndReturn(True) api.neutron.is_extension_supported(IsA(http.HttpRequest), 'security-group').AndReturn(True) api.neutron.is_router_enabled(IsA(http.HttpRequest)).AndReturn(True) api.neutron.is_quotas_extension_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'compute') \ .MultipleTimes().AndReturn(True) api.neutron.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.neutron_quotas.first()) if 'networks' in targets: api.neutron.network_list(IsA(http.HttpRequest), tenant_id=self.request.user.tenant_id) \ .AndReturn(self.networks.list()) if 'subnets' in targets: api.neutron.subnet_list(IsA(http.HttpRequest), tenant_id=self.request.user.tenant_id) \ .AndReturn(self.subnets.list()) if 'routers' in targets: api.neutron.router_list(IsA(http.HttpRequest), tenant_id=self.request.user.tenant_id) \ .AndReturn(self.routers.list()) if 'floating_ips' in targets: api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.neutron.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .AndReturn(self.floating_ips.list()) if 'security_groups' in targets: api.neutron.security_group_list(IsA(http.HttpRequest)) \ .AndReturn(self.security_groups.list()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request, targets=targets) network_used = len(self.networks.list()) subnet_used = len(self.subnets.list()) router_used = len(self.routers.list()) fip_used = len(self.floating_ips.list()) sg_used = len(self.security_groups.list()) expected = { 'networks': { 'used': network_used, 'quota': 10, 'available': 10 - network_used }, 'subnets': { 'used': subnet_used, 'quota': 10, 'available': 10 - subnet_used }, 'routers': { 'used': router_used, 'quota': 10, 'available': 10 - router_used }, 'security_groups': { 'used': sg_used, 'quota': 20, 'available': 20 - sg_used }, 'floating_ips': { 'used': fip_used, 'quota': 50, 'available': 50 - fip_used }, } expected = dict((k, v) for k, v in expected.items() if k in targets) # Compare internal structure of usages to expected. self.assertEqual(expected, quota_usages.usages) # Compare available resources self.assertAvailableQuotasEqual(expected, quota_usages.usages)
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.neutron.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.neutron.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .MultipleTimes().AndReturn(self.floating_ips.list()) api.neutron.floating_ip_pools_list(IsA(http.HttpRequest)) \ .AndReturn(self.pools.list()) api.neutron.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_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())))