Add UT coverage for attach_interface by port
Previously attach_interface tests in project/instances/tests.py did not cover the case of attach_interface by port. This commit adds UT for such cases. Details: - The second call of the mocked network_list_for_tenant retured an empty list. It sounds tricky to change the return value for network_list_for_tenant() in two calls, but this trick was used to skip the processing of port_field_data. This should return a same value for the two calls to test port_field_data() function. - To test the behavior of attach_interface by "port", an unbound port (whose device_owner/device_id of the port is empty) is required, so this commit adds it to neutron_data.py. - test_interface_attach_get() covers a list of choices when "By Port" is selected in the form. - test_interface_attach_post_by_port() is added. Related to the addition of an unbound port to neutron_data.py, the following other tests are adjusted. They assumed that all non-network ports are owned by servers, but it is no longer true as an unbound port is added to the test data. Note that associating an unbound port with a floating IP is a valid operation in neutron, so there is no problem to adjust UTs. - openstack_dashboard/dashboards/project/floating_ips/tests.py - openstack_dashboard/test/unit/api/test_neutron.py Related-Bug: #1943639 Change-Id: Ib0ee342463e5668858078db43c04fe0a1be6e995
This commit is contained in:
parent
a4718409f5
commit
516e57bc89
|
@ -90,7 +90,7 @@ class FloatingIpViewTests(test.TestCase):
|
|||
for p in self._get_compute_ports():
|
||||
for ip in p.fixed_ips:
|
||||
targets.append(api.neutron.FloatingIpTarget(
|
||||
p, ip['ip_address'], server_dict[p.device_id]))
|
||||
p, ip['ip_address'], server_dict.get(p.device_id)))
|
||||
return targets
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -3054,11 +3054,14 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
|||
'port_list_with_trunk_types')})
|
||||
def test_interface_attach_get(self):
|
||||
server = self.servers.first()
|
||||
self.mock_network_list_for_tenant.side_effect = [
|
||||
self.networks.list()[:1],
|
||||
[],
|
||||
]
|
||||
self.mock_port_list_with_trunk_types.return_value = self.ports.list()
|
||||
tenant_networks = [net for net in self.networks.list()
|
||||
if not net['router:external']]
|
||||
net1 = tenant_networks[0]
|
||||
self.mock_network_list_for_tenant.return_value = tenant_networks
|
||||
ports = self.ports.list()
|
||||
# Pick up the first unbound port for check
|
||||
unbound_port = [p for p in ports if not p.device_owner][0]
|
||||
self.mock_port_list_with_trunk_types.return_value = ports
|
||||
|
||||
url = reverse('horizon:project:instances:attach_interface',
|
||||
args=[server.id])
|
||||
|
@ -3066,6 +3069,13 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
|||
|
||||
self.assertTemplateUsed(res,
|
||||
'project/instances/attach_interface.html')
|
||||
expected_label = (
|
||||
'%(port_name)s (%(ip_address)s) - %(net_name)s'
|
||||
% {'port_name': unbound_port.name_or_id,
|
||||
'ip_address': unbound_port.fixed_ips[0]['ip_address'],
|
||||
'net_name': net1.name_or_id}
|
||||
)
|
||||
self.assertContains(res, expected_label)
|
||||
self.mock_network_list_for_tenant.assert_has_calls([
|
||||
mock.call(helpers.IsHttpRequest(), self.tenant.id),
|
||||
mock.call(helpers.IsHttpRequest(), self.tenant.id),
|
||||
|
@ -3077,21 +3087,31 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
|||
@helpers.create_mocks({api.neutron: ('network_list_for_tenant',
|
||||
'port_list_with_trunk_types'),
|
||||
api.nova: ('interface_attach',)})
|
||||
def test_interface_attach_post(self):
|
||||
def _test_interface_attach_post(self, by_port=False):
|
||||
fixed_ip = '10.0.0.10'
|
||||
server = self.servers.first()
|
||||
network = self.networks.first()
|
||||
self.mock_network_list_for_tenant.side_effect = [
|
||||
[network],
|
||||
[],
|
||||
]
|
||||
self.mock_port_list_with_trunk_types.return_value = self.ports.list()
|
||||
ports = self.ports.list()
|
||||
# Pick up the first unbound port for check
|
||||
unbound_port = [p for p in ports if not p.device_owner][0]
|
||||
|
||||
self.mock_network_list_for_tenant.return_value = [network]
|
||||
self.mock_port_list_with_trunk_types.return_value = ports
|
||||
self.mock_interface_attach.return_value = None
|
||||
|
||||
form_data = {'instance_id': server.id,
|
||||
'network': network.id,
|
||||
'specification_method': 'network',
|
||||
'fixed_ip': fixed_ip}
|
||||
if by_port:
|
||||
form_data = {
|
||||
'instance_id': server.id,
|
||||
'specification_method': 'port',
|
||||
'port': unbound_port.id,
|
||||
}
|
||||
else:
|
||||
form_data = {
|
||||
'instance_id': server.id,
|
||||
'specification_method': 'network',
|
||||
'network': network.id,
|
||||
'fixed_ip': fixed_ip,
|
||||
}
|
||||
|
||||
url = reverse('horizon:project:instances:attach_interface',
|
||||
args=[server.id])
|
||||
|
@ -3107,9 +3127,20 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
|||
self.assertEqual(2, self.mock_network_list_for_tenant.call_count)
|
||||
self.mock_port_list_with_trunk_types.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id=self.tenant.id)
|
||||
self.mock_interface_attach.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), server.id,
|
||||
net_id=network.id, fixed_ip=fixed_ip, port_id=None)
|
||||
if by_port:
|
||||
self.mock_interface_attach.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), server.id,
|
||||
net_id=None, fixed_ip=None, port_id=unbound_port.id)
|
||||
else:
|
||||
self.mock_interface_attach.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), server.id,
|
||||
net_id=network.id, fixed_ip=fixed_ip, port_id=None)
|
||||
|
||||
def test_interface_attach_post_by_network(self):
|
||||
self._test_interface_attach_post()
|
||||
|
||||
def test_interface_attach_post_by_port(self):
|
||||
self._test_interface_attach_post(by_port=True)
|
||||
|
||||
@helpers.create_mocks({api.cinder: ('volume_list',)})
|
||||
def test_volume_attach_get(self):
|
||||
|
|
|
@ -222,6 +222,26 @@ def data(TEST):
|
|||
TEST.api_ports.add(port_dict)
|
||||
TEST.ports.add(neutron.Port(port_dict))
|
||||
|
||||
# unbound port on 1st network
|
||||
port_dict = {
|
||||
'admin_state_up': True,
|
||||
'device_id': '',
|
||||
'device_owner': '',
|
||||
'fixed_ips': [{'ip_address': '10.0.0.5',
|
||||
'subnet_id': subnet_dict['id']}],
|
||||
'id': 'a5aa0d62-cd5f-4e7d-b022-4ff63f981bcd',
|
||||
'mac_address': 'fa:16:3e:ce:e0:f8',
|
||||
'name': '',
|
||||
'network_id': network_dict['id'],
|
||||
'status': 'DOWN',
|
||||
'tenant_id': network_dict['tenant_id'],
|
||||
'binding:vnic_type': 'normal',
|
||||
'binding:host_id': '',
|
||||
'security_groups': [],
|
||||
}
|
||||
TEST.api_ports.add(port_dict)
|
||||
TEST.ports.add(neutron.Port(port_dict))
|
||||
|
||||
# 2nd network.
|
||||
network_dict = {'admin_state_up': True,
|
||||
'id': '72c3ab6c-c80f-4341-9dc5-210fa31ac6c2',
|
||||
|
|
|
@ -2488,9 +2488,11 @@ class NeutronApiFloatingIpTests(test.APIMockTestCase):
|
|||
return '%(id)s_%(addr)s' % param
|
||||
|
||||
def _get_target_name(self, port, ip=None):
|
||||
param = {'svrid': port['device_id'],
|
||||
'addr': ip or port['fixed_ips'][0]['ip_address']}
|
||||
return 'server_%(svrid)s: %(addr)s' % param
|
||||
ip_address = ip or port['fixed_ips'][0]['ip_address']
|
||||
if port['device_id']:
|
||||
return 'server_%s: %s' % (port['device_id'], ip_address)
|
||||
else:
|
||||
return ip_address
|
||||
|
||||
@override_settings(
|
||||
OPENSTACK_NEUTRON_NETWORK={
|
||||
|
|
Loading…
Reference in New Issue