ironic/ironic/tests/unit/common/test_neutron.py
Vasyl Saienko 228a2a7885 Change pxe dhcp options name to codes.
There is difference between dhcp option names in different backends.
This patch changes options name to code according to [0].

[0] https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml

Closes-Bug: 1717236

This is an updated version of c377f5cbbd034e16b68a3fc30e138b03badc9c94
which problems with PXE and dnsmasq due to buggy dnsmasq code which uses
siaddr field to specify tftp server. They are addressed now by always
sending server-ip-address to make sure that dnsmasq works.

More information about siaddr and option 150,66 can be found in
informational RFC https://tools.ietf.org/html/rfc5859

Change-Id: I55487d867979bf6bb4cf228fcf6408beae955d2b
2017-10-13 12:50:58 +03:00

905 lines
37 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from neutronclient.common import exceptions as neutron_client_exc
from neutronclient.v2_0 import client
from oslo_config import cfg
from oslo_utils import uuidutils
from ironic.common import exception
from ironic.common import neutron
from ironic.conductor import task_manager
from ironic.tests import base
from ironic.tests.unit.conductor import mgr_utils
from ironic.tests.unit.db import base as db_base
from ironic.tests.unit.objects import utils as object_utils
@mock.patch.object(neutron, '_get_neutron_session')
@mock.patch.object(client.Client, "__init__")
class TestNeutronClient(base.TestCase):
def setUp(self):
super(TestNeutronClient, self).setUp()
self.config(url_timeout=30,
retries=2,
group='neutron')
self.config(admin_user='test-admin-user',
admin_tenant_name='test-admin-tenant',
admin_password='test-admin-password',
auth_uri='test-auth-uri',
group='keystone_authtoken')
# TODO(pas-ha) register session options to test legacy path
self.config(insecure=False,
cafile='test-file',
group='neutron')
def test_get_neutron_client_with_token(self, mock_client_init,
mock_session):
token = 'test-token-123'
sess = mock.Mock()
sess.get_endpoint.return_value = 'fake-url'
mock_session.return_value = sess
expected = {'timeout': 30,
'retries': 2,
'insecure': False,
'ca_cert': 'test-file',
'token': token,
'endpoint_url': 'fake-url'}
mock_client_init.return_value = None
neutron.get_client(token=token)
mock_client_init.assert_called_once_with(**expected)
def test_get_neutron_client_without_token(self, mock_client_init,
mock_session):
self.config(url='test-url',
group='neutron')
sess = mock.Mock()
mock_session.return_value = sess
expected = {'retries': 2,
'endpoint_override': 'test-url',
'session': sess}
mock_client_init.return_value = None
neutron.get_client(token=None)
mock_client_init.assert_called_once_with(**expected)
def test_get_neutron_client_with_region(self, mock_client_init,
mock_session):
self.config(region_name='fake_region',
group='keystone')
sess = mock.Mock()
mock_session.return_value = sess
expected = {'retries': 2,
'region_name': 'fake_region',
'session': sess}
mock_client_init.return_value = None
neutron.get_client(token=None)
mock_client_init.assert_called_once_with(**expected)
def test_get_neutron_client_noauth(self, mock_client_init, mock_session):
self.config(auth_strategy='noauth',
url='test-url',
group='neutron')
expected = {'ca_cert': 'test-file',
'insecure': False,
'endpoint_url': 'test-url',
'timeout': 30,
'retries': 2,
'auth_strategy': 'noauth'}
mock_client_init.return_value = None
neutron.get_client(token=None)
mock_client_init.assert_called_once_with(**expected)
def test_out_range_auth_strategy(self, mock_client_init, mock_session):
self.assertRaises(ValueError, cfg.CONF.set_override,
'auth_strategy', 'fake', 'neutron')
class TestNeutronNetworkActions(db_base.DbTestCase):
_CLIENT_ID = (
'20:00:55:04:01:fe:80:00:00:00:00:00:00:00:02:c9:02:00:23:13:92')
def setUp(self):
super(TestNeutronNetworkActions, self).setUp()
mgr_utils.mock_the_extension_manager(driver='fake')
self.config(enabled_drivers=['fake'])
self.node = object_utils.create_test_node(self.context)
self.ports = [object_utils.create_test_port(
self.context, node_id=self.node.id,
uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c782',
address='52:54:00:cf:2d:32',
extra={'vif_port_id': uuidutils.generate_uuid()}
)]
# Very simple neutron port representation
self.neutron_port = {'id': '132f871f-eaec-4fed-9475-0d54465e0f00',
'mac_address': '52:54:00:cf:2d:32'}
self.network_uuid = uuidutils.generate_uuid()
self.client_mock = mock.Mock()
patcher = mock.patch('ironic.common.neutron.get_client',
return_value=self.client_mock)
patcher.start()
self.addCleanup(patcher.stop)
def _test_add_ports_to_network(self, is_client_id,
security_groups=None):
# Ports will be created only if pxe_enabled is True
self.node.network_interface = 'neutron'
self.node.save()
object_utils.create_test_port(
self.context, node_id=self.node.id,
uuid=uuidutils.generate_uuid(),
address='52:54:00:cf:2d:22',
pxe_enabled=False
)
port = self.ports[0]
if is_client_id:
extra = port.extra
extra['client-id'] = self._CLIENT_ID
port.extra = extra
port.save()
expected_body = {
'port': {
'network_id': self.network_uuid,
'admin_state_up': True,
'binding:vnic_type': 'baremetal',
'device_owner': 'baremetal:none',
'binding:host_id': self.node.uuid,
'device_id': self.node.uuid,
'mac_address': port.address,
'binding:profile': {
'local_link_information': [port.local_link_connection]
}
}
}
if security_groups:
expected_body['port']['security_groups'] = security_groups
if is_client_id:
expected_body['port']['extra_dhcp_opts'] = (
[{'opt_name': '61', 'opt_value': self._CLIENT_ID}])
# Ensure we can create ports
self.client_mock.create_port.return_value = {
'port': self.neutron_port}
expected = {port.uuid: self.neutron_port['id']}
with task_manager.acquire(self.context, self.node.uuid) as task:
ports = neutron.add_ports_to_network(
task, self.network_uuid, security_groups=security_groups)
self.assertEqual(expected, ports)
self.client_mock.create_port.assert_called_once_with(
expected_body)
def test_add_ports_to_network(self):
self._test_add_ports_to_network(is_client_id=False,
security_groups=None)
@mock.patch.object(neutron, '_verify_security_groups')
def test_add_ports_to_network_with_sg(self, verify_mock):
sg_ids = []
for i in range(2):
sg_ids.append(uuidutils.generate_uuid())
self._test_add_ports_to_network(is_client_id=False,
security_groups=sg_ids)
def test_verify_sec_groups(self):
sg_ids = []
for i in range(2):
sg_ids.append(uuidutils.generate_uuid())
expected_vals = {'security_groups': []}
for sg in sg_ids:
expected_vals['security_groups'].append({'id': sg})
client = mock.MagicMock()
client.list_security_groups.return_value = expected_vals
self.assertIsNone(
neutron._verify_security_groups(sg_ids, client))
client.list_security_groups.assert_called_once_with()
def test_verify_sec_groups_less_than_configured(self):
sg_ids = []
for i in range(2):
sg_ids.append(uuidutils.generate_uuid())
expected_vals = {'security_groups': []}
for sg in sg_ids:
expected_vals['security_groups'].append({'id': sg})
client = mock.MagicMock()
client.list_security_groups.return_value = expected_vals
self.assertIsNone(
neutron._verify_security_groups(sg_ids[:1], client))
client.list_security_groups.assert_called_once_with()
def test_verify_sec_groups_more_than_configured(self):
sg_ids = []
for i in range(1):
sg_ids.append(uuidutils.generate_uuid())
client = mock.MagicMock()
expected_vals = {'security_groups': []}
client.list_security_groups.return_value = expected_vals
self.assertRaises(
exception.NetworkError,
neutron._verify_security_groups, sg_ids, client)
client.list_security_groups.assert_called_once_with()
def test_verify_sec_groups_no_sg_from_neutron(self):
sg_ids = []
for i in range(1):
sg_ids.append(uuidutils.generate_uuid())
client = mock.MagicMock()
client.list_security_groups.return_value = {}
self.assertRaises(
exception.NetworkError,
neutron._verify_security_groups, sg_ids, client)
client.list_security_groups.assert_called_once_with()
def test_verify_sec_groups_exception_by_neutronclient(self):
sg_ids = []
for i in range(2):
sg_ids.append(uuidutils.generate_uuid())
client = mock.MagicMock()
client.list_security_groups.side_effect = \
neutron_client_exc.NeutronClientException
self.assertRaisesRegex(
exception.NetworkError,
"Could not retrieve security groups",
neutron._verify_security_groups, sg_ids, client)
client.list_security_groups.assert_called_once_with()
def test_add_ports_with_client_id_to_network(self):
self._test_add_ports_to_network(is_client_id=True)
@mock.patch.object(neutron, 'validate_port_info', autospec=True)
def test_add_ports_to_network_instance_uuid(self, vpi_mock):
self.node.instance_uuid = uuidutils.generate_uuid()
self.node.network_interface = 'neutron'
self.node.save()
port = self.ports[0]
expected_body = {
'port': {
'network_id': self.network_uuid,
'admin_state_up': True,
'binding:vnic_type': 'baremetal',
'device_owner': 'baremetal:none',
'binding:host_id': self.node.uuid,
'device_id': self.node.instance_uuid,
'mac_address': port.address,
'binding:profile': {
'local_link_information': [port.local_link_connection]
}
}
}
vpi_mock.return_value = True
# Ensure we can create ports
self.client_mock.create_port.return_value = {'port': self.neutron_port}
expected = {port.uuid: self.neutron_port['id']}
with task_manager.acquire(self.context, self.node.uuid) as task:
ports = neutron.add_ports_to_network(task, self.network_uuid)
self.assertEqual(expected, ports)
self.client_mock.create_port.assert_called_once_with(expected_body)
self.assertTrue(vpi_mock.called)
@mock.patch.object(neutron, 'rollback_ports')
def test_add_network_all_ports_fail(self, rollback_mock):
# Check that if creating a port fails, the ports are cleaned up
self.client_mock.create_port.side_effect = \
neutron_client_exc.ConnectionFailed
with task_manager.acquire(self.context, self.node.uuid) as task:
self.assertRaises(
exception.NetworkError, neutron.add_ports_to_network, task,
self.network_uuid)
rollback_mock.assert_called_once_with(task, self.network_uuid)
@mock.patch.object(neutron, 'LOG')
def test_add_network_create_some_ports_fail(self, log_mock):
object_utils.create_test_port(
self.context, node_id=self.node.id,
uuid=uuidutils.generate_uuid(),
address='52:54:55:cf:2d:32',
extra={'vif_port_id': uuidutils.generate_uuid()}
)
self.client_mock.create_port.side_effect = [
{'port': self.neutron_port}, neutron_client_exc.ConnectionFailed]
with task_manager.acquire(self.context, self.node.uuid) as task:
neutron.add_ports_to_network(task, self.network_uuid)
self.assertIn("Could not create neutron port for node's",
log_mock.warning.call_args_list[0][0][0])
self.assertIn("Some errors were encountered when updating",
log_mock.warning.call_args_list[1][0][0])
@mock.patch.object(neutron, 'remove_neutron_ports')
def test_remove_ports_from_network(self, remove_mock):
with task_manager.acquire(self.context, self.node.uuid) as task:
neutron.remove_ports_from_network(task, self.network_uuid)
remove_mock.assert_called_once_with(
task,
{'network_id': self.network_uuid,
'mac_address': [self.ports[0].address]}
)
@mock.patch.object(neutron, 'remove_neutron_ports')
def test_remove_ports_from_network_not_all_pxe_enabled(self, remove_mock):
object_utils.create_test_port(
self.context, node_id=self.node.id,
uuid=uuidutils.generate_uuid(),
address='52:54:55:cf:2d:32',
pxe_enabled=False
)
with task_manager.acquire(self.context, self.node.uuid) as task:
neutron.remove_ports_from_network(task, self.network_uuid)
remove_mock.assert_called_once_with(
task,
{'network_id': self.network_uuid,
'mac_address': [self.ports[0].address]}
)
def test_remove_neutron_ports(self):
with task_manager.acquire(self.context, self.node.uuid) as task:
self.client_mock.list_ports.return_value = {
'ports': [self.neutron_port]}
neutron.remove_neutron_ports(task, {'param': 'value'})
self.client_mock.list_ports.assert_called_once_with(
**{'param': 'value'})
self.client_mock.delete_port.assert_called_once_with(
self.neutron_port['id'])
def test_remove_neutron_ports_list_fail(self):
with task_manager.acquire(self.context, self.node.uuid) as task:
self.client_mock.list_ports.side_effect = \
neutron_client_exc.ConnectionFailed
self.assertRaisesRegex(
exception.NetworkError, 'Could not get given network VIF',
neutron.remove_neutron_ports, task, {'param': 'value'})
self.client_mock.list_ports.assert_called_once_with(
**{'param': 'value'})
def test_remove_neutron_ports_delete_fail(self):
with task_manager.acquire(self.context, self.node.uuid) as task:
self.client_mock.delete_port.side_effect = \
neutron_client_exc.ConnectionFailed
self.client_mock.list_ports.return_value = {
'ports': [self.neutron_port]}
self.assertRaisesRegex(
exception.NetworkError, 'Could not remove VIF',
neutron.remove_neutron_ports, task, {'param': 'value'})
self.client_mock.list_ports.assert_called_once_with(
**{'param': 'value'})
self.client_mock.delete_port.assert_called_once_with(
self.neutron_port['id'])
def test_get_node_portmap(self):
with task_manager.acquire(self.context, self.node.uuid) as task:
portmap = neutron.get_node_portmap(task)
self.assertEqual(
{self.ports[0].uuid: self.ports[0].local_link_connection},
portmap
)
def test_get_local_group_information(self):
pg = object_utils.create_test_portgroup(
self.context, node_id=self.node.id,
uuid=uuidutils.generate_uuid(),
address='52:54:55:cf:2d:32',
mode='802.3ad', properties={'bond_opt1': 'foo',
'opt2': 'bar'},
name='test-pg'
)
expected = {
'id': pg.uuid,
'name': pg.name,
'bond_mode': pg.mode,
'bond_properties': {'bond_opt1': 'foo', 'bond_opt2': 'bar'},
}
with task_manager.acquire(self.context, self.node.uuid) as task:
res = neutron.get_local_group_information(task, pg)
self.assertEqual(expected, res)
@mock.patch.object(neutron, 'remove_ports_from_network')
def test_rollback_ports(self, remove_mock):
with task_manager.acquire(self.context, self.node.uuid) as task:
neutron.rollback_ports(task, self.network_uuid)
remove_mock.assert_called_once_with(task, self.network_uuid)
@mock.patch.object(neutron, 'LOG')
@mock.patch.object(neutron, 'remove_ports_from_network')
def test_rollback_ports_exception(self, remove_mock, log_mock):
remove_mock.side_effect = exception.NetworkError('boom')
with task_manager.acquire(self.context, self.node.uuid) as task:
neutron.rollback_ports(task, self.network_uuid)
self.assertTrue(log_mock.exception.called)
@mock.patch.object(neutron, 'LOG')
def test_validate_port_info_neutron_interface(self, log_mock):
self.node.network_interface = 'neutron'
self.node.save()
port = object_utils.create_test_port(
self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(),
address='52:54:00:cf:2d:33')
res = neutron.validate_port_info(self.node, port)
self.assertTrue(res)
self.assertFalse(log_mock.warning.called)
@mock.patch.object(neutron, 'LOG')
def test_validate_port_info_neutron_interface_missed_info(self, log_mock):
self.node.network_interface = 'neutron'
self.node.save()
llc = {}
port = object_utils.create_test_port(
self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(),
address='52:54:00:cf:2d:33', local_link_connection=llc)
res = neutron.validate_port_info(self.node, port)
self.assertFalse(res)
self.assertTrue(log_mock.warning.called)
@mock.patch.object(neutron, 'LOG')
def test_validate_port_info_flat_interface(self, log_mock):
self.node.network_interface = 'flat'
self.node.save()
llc = {}
port = object_utils.create_test_port(
self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(),
address='52:54:00:cf:2d:33', local_link_connection=llc)
res = neutron.validate_port_info(self.node, port)
self.assertTrue(res)
self.assertFalse(log_mock.warning.called)
@mock.patch.object(neutron, 'get_client', autospec=True)
class TestValidateNetwork(base.TestCase):
def setUp(self):
super(TestValidateNetwork, self).setUp()
self.uuid = uuidutils.generate_uuid()
def test_by_uuid(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.return_value = {
'networks': [
{'id': self.uuid},
]
}
self.assertEqual(self.uuid, neutron.validate_network(self.uuid))
net_mock.assert_called_once_with(fields=['id'],
id=self.uuid)
def test_by_name(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.return_value = {
'networks': [
{'id': self.uuid},
]
}
self.assertEqual(self.uuid, neutron.validate_network('name'))
net_mock.assert_called_once_with(fields=['id'],
name='name')
def test_not_found(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.return_value = {
'networks': []
}
self.assertRaisesRegex(exception.InvalidParameterValue,
'was not found',
neutron.validate_network, self.uuid)
net_mock.assert_called_once_with(fields=['id'],
id=self.uuid)
def test_failure(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.side_effect = neutron_client_exc.NeutronClientException('foo')
self.assertRaisesRegex(exception.NetworkError, 'foo',
neutron.validate_network, 'name')
net_mock.assert_called_once_with(fields=['id'],
name='name')
def test_duplicate(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.return_value = {
'networks': [{'id': self.uuid},
{'id': 'uuid2'}]
}
self.assertRaisesRegex(exception.InvalidParameterValue,
'More than one network',
neutron.validate_network, 'name')
net_mock.assert_called_once_with(fields=['id'],
name='name')
@mock.patch.object(neutron, 'get_client', autospec=True)
class TestUpdatePortAddress(base.TestCase):
def test_update_port_address(self, mock_client):
address = 'fe:54:00:77:07:d9'
port_id = 'fake-port-id'
expected = {'port': {'mac_address': address}}
mock_client.return_value.show_port.return_value = {}
neutron.update_port_address(port_id, address)
mock_client.return_value.update_port.assert_called_once_with(port_id,
expected)
@mock.patch.object(neutron, 'unbind_neutron_port', autospec=True)
def test_update_port_address_with_binding(self, mock_unp, mock_client):
address = 'fe:54:00:77:07:d9'
port_id = 'fake-port-id'
mock_client.return_value.show_port.return_value = {
'port': {'binding:host_id': 'host',
'binding:profile': 'foo'}}
calls = [mock.call(port_id, {'port': {'mac_address': address}}),
mock.call(port_id, {'port': {'binding:host_id': 'host',
'binding:profile': 'foo'}})]
neutron.update_port_address(port_id, address)
mock_unp.assert_called_once_with(port_id, client=mock_client())
mock_client.return_value.update_port.assert_has_calls(calls)
@mock.patch.object(neutron, 'unbind_neutron_port', autospec=True)
def test_update_port_address_without_binding(self, mock_unp, mock_client):
address = 'fe:54:00:77:07:d9'
port_id = 'fake-port-id'
expected = {'port': {'mac_address': address}}
mock_client.return_value.show_port.return_value = {
'port': {'binding:profile': 'foo'}}
neutron.update_port_address(port_id, address)
self.assertFalse(mock_unp.called)
mock_client.return_value.update_port.assert_any_call(port_id, expected)
def test_update_port_address_show_failed(self, mock_client):
address = 'fe:54:00:77:07:d9'
port_id = 'fake-port-id'
mock_client.return_value.show_port.side_effect = (
neutron_client_exc.NeutronClientException())
self.assertRaises(exception.FailedToUpdateMacOnPort,
neutron.update_port_address, port_id, address)
self.assertFalse(mock_client.return_value.update_port.called)
@mock.patch.object(neutron, 'unbind_neutron_port', autospec=True)
def test_update_port_address_unbind_port_failed(self, mock_unp,
mock_client):
address = 'fe:54:00:77:07:d9'
port_id = 'fake-port-id'
mock_client.return_value.show_port.return_value = {
'port': {'binding:profile': 'foo',
'binding:host_id': 'host'}}
mock_unp.side_effect = (exception.NetworkError('boom'))
self.assertRaises(exception.FailedToUpdateMacOnPort,
neutron.update_port_address, port_id, address)
mock_unp.assert_called_once_with(port_id, client=mock_client())
self.assertFalse(mock_client.return_value.update_port.called)
@mock.patch.object(neutron, 'unbind_neutron_port', autospec=True)
def test_update_port_address_with_exception(self, mock_unp,
mock_client):
address = 'fe:54:00:77:07:d9'
port_id = 'fake-port-id'
mock_client.return_value.show_port.return_value = {}
mock_client.return_value.update_port.side_effect = (
neutron_client_exc.NeutronClientException())
self.assertRaises(exception.FailedToUpdateMacOnPort,
neutron.update_port_address,
port_id, address)
@mock.patch.object(neutron, 'get_client', autospec=True)
class TestUnbindPort(base.TestCase):
def test_unbind_neutron_port_client_passed(self, mock_client):
port_id = 'fake-port-id'
body = {
'port': {
'binding:host_id': '',
'binding:profile': {}
}
}
neutron.unbind_neutron_port(port_id, mock_client())
self.assertEqual(1, mock_client.call_count)
mock_client.return_value.update_port.assert_called_once_with(port_id,
body)
@mock.patch.object(neutron, 'LOG')
def test_unbind_neutron_port_failure(self, mock_log, mock_client):
mock_client.return_value.update_port.side_effect = (
neutron_client_exc.NeutronClientException())
body = {
'port': {
'binding:host_id': '',
'binding:profile': {}
}
}
port_id = 'fake-port-id'
self.assertRaises(exception.NetworkError, neutron.unbind_neutron_port,
port_id)
mock_client.assert_called_once_with()
mock_client.return_value.update_port.assert_called_once_with(port_id,
body)
mock_log.exception.assert_called_once()
def test_unbind_neutron_port(self, mock_client):
port_id = 'fake-port-id'
body = {
'port': {
'binding:host_id': '',
'binding:profile': {}
}
}
neutron.unbind_neutron_port(port_id)
mock_client.assert_called_once_with()
mock_client.return_value.update_port.assert_called_once_with(port_id,
body)
@mock.patch.object(neutron, 'LOG')
def test_unbind_neutron_port_not_found(self, mock_log, mock_client):
port_id = 'fake-port-id'
mock_client.return_value.update_port.side_effect = (
neutron_client_exc.PortNotFoundClient())
body = {
'port': {
'binding:host_id': '',
'binding:profile': {}
}
}
neutron.unbind_neutron_port(port_id)
mock_client.assert_called_once_with()
mock_client.return_value.update_port.assert_called_once_with(port_id,
body)
mock_log.info.assert_called_once_with('Port %s was not found while '
'unbinding.', port_id)
class TestGetNetworkByUUIDOrName(base.TestCase):
def setUp(self):
super(TestGetNetworkByUUIDOrName, self).setUp()
self.client = mock.MagicMock()
def test__get_network_by_uuid_or_name_uuid(self):
network_uuid = '9acb0256-2c1b-420a-b9d7-62bee90b6ed7'
networks = {
'networks': [{
'field1': 'value1',
'field2': 'value2',
}],
}
fields = ['field1', 'field2']
self.client.list_networks.return_value = networks
result = neutron._get_network_by_uuid_or_name(
self.client, network_uuid, fields=fields)
self.client.list_networks.assert_called_once_with(
id=network_uuid, fields=fields)
self.assertEqual(networks['networks'][0], result)
def test__get_network_by_uuid_or_name_name(self):
network_name = 'test-net'
networks = {
'networks': [{
'field1': 'value1',
'field2': 'value2',
}],
}
fields = ['field1', 'field2']
self.client.list_networks.return_value = networks
result = neutron._get_network_by_uuid_or_name(
self.client, network_name, fields=fields)
self.client.list_networks.assert_called_once_with(
name=network_name, fields=fields)
self.assertEqual(networks['networks'][0], result)
def test__get_network_by_uuid_or_name_failure(self):
network_uuid = '9acb0256-2c1b-420a-b9d7-62bee90b6ed7'
self.client.list_networks.side_effect = (
neutron_client_exc.NeutronClientException())
self.assertRaises(exception.NetworkError,
neutron._get_network_by_uuid_or_name,
self.client, network_uuid)
self.client.list_networks.assert_called_once_with(id=network_uuid)
def test__get_network_by_uuid_or_name_missing(self):
network_uuid = '9acb0256-2c1b-420a-b9d7-62bee90b6ed7'
networks = {
'networks': [],
}
self.client.list_networks.return_value = networks
self.assertRaises(exception.InvalidParameterValue,
neutron._get_network_by_uuid_or_name,
self.client, network_uuid)
self.client.list_networks.assert_called_once_with(id=network_uuid)
def test__get_network_by_uuid_or_name_duplicate(self):
network_name = 'test-net'
networks = {
'networks': [
{'id': '9acb0256-2c1b-420a-b9d7-62bee90b6ed7'},
{'id': '9014b6a7-8291-4676-80b0-ab00988ce3c7'},
],
}
self.client.list_networks.return_value = networks
self.assertRaises(exception.InvalidParameterValue,
neutron._get_network_by_uuid_or_name,
self.client, network_name)
self.client.list_networks.assert_called_once_with(name=network_name)
@mock.patch.object(neutron, '_get_network_by_uuid_or_name', autospec=True)
@mock.patch.object(neutron, '_get_port_by_uuid', autospec=True)
class TestGetPhysnetsByPortUUID(base.TestCase):
PORT_FIELDS = ['network_id']
NETWORK_FIELDS = ['provider:physical_network', 'segments']
def setUp(self):
super(TestGetPhysnetsByPortUUID, self).setUp()
self.client = mock.MagicMock()
def test_get_physnets_by_port_uuid_single_segment(self, mock_gp, mock_gn):
port_uuid = 'fake-port-uuid'
network_uuid = 'fake-network-uuid'
physnet = 'fake-physnet'
mock_gp.return_value = {
'network_id': network_uuid,
}
mock_gn.return_value = {
'provider:physical_network': physnet,
}
result = neutron.get_physnets_by_port_uuid(self.client,
port_uuid)
mock_gp.assert_called_once_with(self.client, port_uuid,
fields=self.PORT_FIELDS)
mock_gn.assert_called_once_with(self.client, network_uuid,
fields=self.NETWORK_FIELDS)
self.assertEqual({physnet}, result)
def test_get_physnets_by_port_uuid_single_segment_no_physnet(
self, mock_gp, mock_gn):
port_uuid = 'fake-port-uuid'
network_uuid = 'fake-network-uuid'
mock_gp.return_value = {
'network_id': network_uuid,
}
mock_gn.return_value = {
'provider:physical_network': None,
}
result = neutron.get_physnets_by_port_uuid(self.client,
port_uuid)
mock_gp.assert_called_once_with(self.client, port_uuid,
fields=self.PORT_FIELDS)
mock_gn.assert_called_once_with(self.client, network_uuid,
fields=self.NETWORK_FIELDS)
self.assertEqual(set(), result)
def test_get_physnets_by_port_uuid_multiple_segments(self, mock_gp,
mock_gn):
port_uuid = 'fake-port-uuid'
network_uuid = 'fake-network-uuid'
physnet1 = 'fake-physnet-1'
physnet2 = 'fake-physnet-2'
mock_gp.return_value = {
'network_id': network_uuid,
}
mock_gn.return_value = {
'segments': [
{
'provider:physical_network': physnet1,
},
{
'provider:physical_network': physnet2,
},
],
}
result = neutron.get_physnets_by_port_uuid(self.client,
port_uuid)
mock_gp.assert_called_once_with(self.client, port_uuid,
fields=self.PORT_FIELDS)
mock_gn.assert_called_once_with(self.client, network_uuid,
fields=self.NETWORK_FIELDS)
self.assertEqual({physnet1, physnet2}, result)
def test_get_physnets_by_port_uuid_multiple_segments_no_physnet(
self, mock_gp, mock_gn):
port_uuid = 'fake-port-uuid'
network_uuid = 'fake-network-uuid'
mock_gp.return_value = {
'network_id': network_uuid,
}
mock_gn.return_value = {
'segments': [
{
'provider:physical_network': None,
},
{
'provider:physical_network': None,
},
],
}
result = neutron.get_physnets_by_port_uuid(self.client,
port_uuid)
mock_gp.assert_called_once_with(self.client, port_uuid,
fields=self.PORT_FIELDS)
mock_gn.assert_called_once_with(self.client, network_uuid,
fields=self.NETWORK_FIELDS)
self.assertEqual(set(), result)
def test_get_physnets_by_port_uuid_port_missing(self, mock_gp, mock_gn):
port_uuid = 'fake-port-uuid'
mock_gp.side_effect = exception.InvalidParameterValue('error')
self.assertRaises(exception.InvalidParameterValue,
neutron.get_physnets_by_port_uuid,
self.client, port_uuid)
mock_gp.assert_called_once_with(self.client, port_uuid,
fields=self.PORT_FIELDS)
self.assertFalse(mock_gn.called)
def test_get_physnets_by_port_uuid_port_failure(self, mock_gp, mock_gn):
port_uuid = 'fake-port-uuid'
mock_gp.side_effect = exception.NetworkError
self.assertRaises(exception.NetworkError,
neutron.get_physnets_by_port_uuid,
self.client, port_uuid)
mock_gp.assert_called_once_with(self.client, port_uuid,
fields=self.PORT_FIELDS)
self.assertFalse(mock_gn.called)
def test_get_physnets_by_port_uuid_network_missing(
self, mock_gp, mock_gn):
port_uuid = 'fake-port-uuid'
network_uuid = 'fake-network-uuid'
mock_gp.return_value = {
'network_id': network_uuid,
}
mock_gn.side_effect = exception.InvalidParameterValue('error')
self.assertRaises(exception.InvalidParameterValue,
neutron.get_physnets_by_port_uuid,
self.client, port_uuid)
mock_gp.assert_called_once_with(self.client, port_uuid,
fields=self.PORT_FIELDS)
mock_gn.assert_called_once_with(self.client, network_uuid,
fields=self.NETWORK_FIELDS)
def test_get_physnets_by_port_uuid_network_failure(
self, mock_gp, mock_gn):
port_uuid = 'fake-port-uuid'
network_uuid = 'fake-network-uuid'
mock_gp.return_value = {
'network_id': network_uuid,
}
mock_gn.side_effect = exception.NetworkError
self.assertRaises(exception.NetworkError,
neutron.get_physnets_by_port_uuid,
self.client, port_uuid)
mock_gp.assert_called_once_with(self.client, port_uuid,
fields=self.PORT_FIELDS)
mock_gn.assert_called_once_with(self.client, network_uuid,
fields=self.NETWORK_FIELDS)