update tests for use_neutron=True; fix exposed bugs

Update all the tests to use_neutron=True, in doing so this exposed an
issue with the existing nova.utils.is_neutron function, as it only
worked off of the network_api_class option.

This was adjusted to provide a new nova.network.is_neutron function
which returns True / False / None (None when we have no idea because
it's not a class we know). nova.utils.is_neutron now uses this.

Remove tests that specifically were using Neutron API subclasses. In
digging through git history this comes from
I6b7b7389e127ff8b084ac379cb9aebccc102620c which was the transition
patches to get us from Quantum -> Neutron without breaking the
world. They need not be supported anymore.

Return the support for network_api_class actually working, as the
previous patch did a little more than deprecate it, as the option
provided was never respected.

Change-Id: I5ddf56bac99b16a8c6752303a532f132c3e5f14d
This commit is contained in:
Sean Dague 2016-03-04 10:48:04 -05:00
parent 6e8e322718
commit 600e86c456
11 changed files with 66 additions and 73 deletions

View File

@ -53,7 +53,6 @@ server_opts = [
]
CONF = cfg.CONF
CONF.register_opts(server_opts)
CONF.import_opt('network_api_class', 'nova.network')
CONF.import_opt('reclaim_instance_interval', 'nova.compute.manager')
LOG = logging.getLogger(__name__)

View File

@ -49,7 +49,6 @@ ALIAS = 'servers'
CONF = cfg.CONF
CONF.import_opt('enable_instance_password',
'nova.api.openstack.compute.legacy_v2.servers')
CONF.import_opt('network_api_class', 'nova.network')
CONF.import_opt('reclaim_instance_interval', 'nova.compute.manager')
CONF.import_opt('extensions_blacklist', 'nova.api.openstack',
group='osapi_v21')

View File

@ -44,19 +44,36 @@ Defaults to False (indicating Nova network). Set to True to use neutron.
oslo_config.cfg.CONF.register_opts(_network_opts)
def API(skip_policy_check=False):
def is_neutron():
"""Does this configuration mean we're neutron.
This logic exists as a separate config option
"""
legacy_class = oslo_config.cfg.CONF.network_api_class
use_neutron = oslo_config.cfg.CONF.use_neutron
if legacy_class == NEUTRON_NET_API and not use_neutron:
if legacy_class not in (NEUTRON_NET_API, NOVA_NET_API):
# Someone actually used this option, this gets a pass for now,
# but will just go away once deleted.
return None
elif legacy_class == NEUTRON_NET_API and not use_neutron:
# If they specified neutron via class, we should respect that
network_api_class = legacy_class
LOG.warn(_LW("Config mismatch. The network_api_class specifies %s, "
"however use_neutron is not set to True. Using Neutron "
"networking for now, however please set use_neutron to "
"True in your configuration as network_api_class is "
"deprecated and will be removed."), legacy_class)
return True
elif use_neutron:
return True
else:
return False
def API(skip_policy_check=False):
if is_neutron() is None:
network_api_class = oslo_config.cfg.CONF.network_api_class
elif is_neutron():
network_api_class = NEUTRON_NET_API
else:
network_api_class = NOVA_NET_API

View File

@ -47,7 +47,6 @@ from nova.db.sqlalchemy import models
from nova import exception
from nova.image import glance
from nova.network import manager
from nova.network.neutronv2 import api as neutron_api
from nova import objects
from nova.objects import instance as instance_obj
from nova import policy
@ -151,11 +150,6 @@ class Base64ValidationTest(test.TestCase):
self.assertIsNone(result)
class NeutronV2Subclass(neutron_api.API):
"""Used to ensure that API handles subclasses properly."""
pass
class ControllerTest(test.TestCase):
def setUp(self):
@ -200,21 +194,21 @@ class ServersControllerTest(ControllerTest):
self.assertIn((uuid, None), res.as_tuples())
def test_requested_networks_neutronv2_enabled_with_port(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'port': port}]
res = self.controller._get_requested_networks(requested_networks)
self.assertEqual([(None, None, port, None)], res.as_tuples())
def test_requested_networks_neutronv2_enabled_with_network(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
requested_networks = [{'uuid': network}]
res = self.controller._get_requested_networks(requested_networks)
self.assertEqual([(network, None, None, None)], res.as_tuples())
def test_requested_networks_neutronv2_enabled_with_network_and_port(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'uuid': network, 'port': port}]
@ -232,7 +226,7 @@ class ServersControllerTest(ControllerTest):
def test_requested_networks_with_neutronv2_and_duplicate_networks(self):
# duplicate networks are allowed only for nova neutron v2.0
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
requested_networks = [{'uuid': network}, {'uuid': network}]
res = self.controller._get_requested_networks(requested_networks)
@ -248,22 +242,13 @@ class ServersControllerTest(ControllerTest):
requested_networks)
def test_requested_networks_api_enabled_with_v2_subclass(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'uuid': network, 'port': port}]
res = self.controller._get_requested_networks(requested_networks)
self.assertEqual([(None, None, port, None)], res.as_tuples())
def test_requested_networks_neutronv2_subclass_with_port(self):
cls = ('nova.tests.unit.api.openstack.compute.legacy_v2'
'.test_servers.NeutronV2Subclass')
self.flags(network_api_class=cls)
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'port': port}]
res = self.controller._get_requested_networks(requested_networks)
self.assertEqual([(None, None, port, None)], res.as_tuples())
def test_get_server_by_uuid(self):
req = fakes.HTTPRequest.blank('/fake/servers/%s' % FAKE_UUID)
res_dict = self.controller.show(req, FAKE_UUID)
@ -2183,7 +2168,7 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_extra({'security_groups': [{'name': group}]})
def test_create_instance_with_non_unique_secgroup_name(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'uuid': network}]
params = {'networks': requested_networks,
@ -2197,7 +2182,7 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_extra, params)
def test_create_instance_sg_with_leading_trailing_spaces(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'uuid': network}]
params = {'networks': requested_networks,
@ -2213,7 +2198,7 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_extra(params)
def test_create_instance_with_port_with_no_fixed_ips(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
port_id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'port': port_id}]
params = {'networks': requested_networks}
@ -2252,7 +2237,7 @@ class ServersControllerCreateTest(test.TestCase):
self.req, self.body)
def test_create_instance_with_network_with_no_subnet(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'uuid': network}]
params = {'networks': requested_networks}
@ -2726,7 +2711,7 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_extra(params)
def test_create_instance_with_neutronv2_port_in_use(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'uuid': network, 'port': port}]
@ -2740,7 +2725,7 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_extra, params)
def test_create_instance_with_neutronv2_not_found_network(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
requested_networks = [{'uuid': network}]
params = {'networks': requested_networks}
@ -2753,7 +2738,7 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_extra, params)
def test_create_instance_with_neutronv2_port_not_found(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'uuid': network, 'port': port}]
@ -2782,7 +2767,7 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_extra, params)
def test_create_multiple_instance_with_neutronv2_port(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
self.body['server']['max_count'] = 2
@ -2800,7 +2785,7 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_extra, params)
def test_create_instance_with_networks_disabled_neutronv2(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
net_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
requested_networks = [{'uuid': net_uuid}]
params = {'networks': requested_networks}
@ -3016,7 +3001,7 @@ class ServersControllerCreateTestWithMock(test.TestCase):
@mock.patch.object(compute_api.API, 'create')
def test_create_instance_with_neutronv2_fixed_ip_already_in_use(self,
create_mock):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
address = '10.0.2.3'
requested_networks = [{'uuid': network, 'fixed_ip': address}]
@ -3031,7 +3016,7 @@ class ServersControllerCreateTestWithMock(test.TestCase):
@mock.patch.object(compute_api.API, 'create')
def test_create_instance_with_neutronv2_invalid_fixed_ip(self,
create_mock):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
address = '999.0.2.3'
requested_networks = [{'uuid': network, 'fixed_ip': address}]

View File

@ -115,7 +115,7 @@ class FloatingIpTestNeutronV21(test.NoDBTestCase):
def setUp(self):
super(FloatingIpTestNeutronV21, self).setUp()
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
self.controller = self.floating_ips.FloatingIPController()
def test_floatingip_delete(self):

View File

@ -56,7 +56,6 @@ from nova.db.sqlalchemy import models
from nova import exception
from nova.image import glance
from nova.network import manager
from nova.network.neutronv2 import api as neutron_api
from nova import objects
from nova.objects import instance as instance_obj
from nova import policy
@ -190,11 +189,6 @@ class Base64ValidationTest(test.TestCase):
self.assertIsNone(result)
class NeutronV2Subclass(neutron_api.API):
"""Used to ensure that API handles subclasses properly."""
pass
class ControllerTest(test.TestCase):
def setUp(self):
@ -241,21 +235,21 @@ class ServersControllerTest(ControllerTest):
self.assertIn((uuid, None), res.as_tuples())
def test_requested_networks_neutronv2_enabled_with_port(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'port': port}]
res = self.controller._get_requested_networks(requested_networks)
self.assertEqual([(None, None, port, None)], res.as_tuples())
def test_requested_networks_neutronv2_enabled_with_network(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
requested_networks = [{'uuid': network}]
res = self.controller._get_requested_networks(requested_networks)
self.assertEqual([(network, None, None, None)], res.as_tuples())
def test_requested_networks_neutronv2_enabled_with_network_and_port(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'uuid': network, 'port': port}]
@ -273,7 +267,7 @@ class ServersControllerTest(ControllerTest):
def test_requested_networks_with_neutronv2_and_duplicate_networks(self):
# duplicate networks are allowed only for nova neutron v2.0
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
requested_networks = [{'uuid': network}, {'uuid': network}]
res = self.controller._get_requested_networks(requested_networks)
@ -281,7 +275,7 @@ class ServersControllerTest(ControllerTest):
(network, None, None, None)], res.as_tuples())
def test_requested_networks_neutronv2_enabled_conflict_on_fixed_ip(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
addr = '10.0.0.1'
@ -302,22 +296,13 @@ class ServersControllerTest(ControllerTest):
requested_networks)
def test_requested_networks_api_enabled_with_v2_subclass(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'uuid': network, 'port': port}]
res = self.controller._get_requested_networks(requested_networks)
self.assertEqual([(None, None, port, None)], res.as_tuples())
def test_requested_networks_neutronv2_subclass_with_port(self):
cls = ('nova.tests.unit.api.openstack.compute.test_serversV21.'
'NeutronV2Subclass')
self.flags(network_api_class=cls)
port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
requested_networks = [{'port': port}]
res = self.controller._get_requested_networks(requested_networks)
self.assertEqual([(None, None, port, None)], res.as_tuples())
def test_get_server_by_uuid(self):
req = self.req('/fake/servers/%s' % FAKE_UUID)
res_dict = self.controller.show(req, FAKE_UUID)
@ -2665,7 +2650,7 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_extra(params)
def test_create_instance_with_networks_disabled_neutronv2(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
net_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
requested_networks = [{'uuid': net_uuid}]
params = {'networks': requested_networks}
@ -3419,7 +3404,7 @@ class ServersControllerCreateTestWithMock(test.TestCase):
@mock.patch.object(compute_api.API, 'create')
def test_create_instance_with_neutronv2_invalid_fixed_ip(self,
create_mock):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
address = '999.0.2.3'
requested_networks = [{'uuid': network, 'fixed_ip': address}]

View File

@ -208,7 +208,7 @@ class _ComputeAPIUnitTestMixIn(object):
# Tests that if port is specified there is only one instance booting
# (i.e max_count == 1) as we can't share the same port across multiple
# instances.
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
port = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
address = '10.0.0.1'
min_count = 1
@ -243,7 +243,7 @@ class _ComputeAPIUnitTestMixIn(object):
requested_networks)
def test_specified_ip_and_multiple_instances_neutronv2(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
address = '10.0.0.1'
requested_networks = objects.NetworkRequestList(

View File

@ -16,6 +16,11 @@ import nova.network
import nova.test
class FileATicket(object):
def __init__(self, **kwargs):
pass
class NetworkAPIConfigTest(nova.test.NoDBTestCase):
"""Test the transition from legacy to use_neutron config options."""
@ -39,3 +44,10 @@ class NetworkAPIConfigTest(nova.test.NoDBTestCase):
self.flags(network_api_class='nova.network.neutronv2.api.API')
netapi = nova.network.API()
self.assertIsInstance(netapi, nova.network.neutronv2.api.API)
def test_legacy_custom_class(self):
"""use neutron even if config is false because of legacy option."""
self.flags(network_api_class=
'nova.tests.unit.network.test_config.FileATicket')
netapi = nova.network.API()
self.assertIsInstance(netapi, FileATicket)

View File

@ -294,7 +294,7 @@ class NetworkCommandsTestCase(test.NoDBTestCase):
class NeutronV2NetworkCommandsTestCase(test.NoDBTestCase):
def setUp(self):
super(NeutronV2NetworkCommandsTestCase, self).setUp()
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
self.commands = manage.NetworkCommands()
def test_create(self):

View File

@ -982,7 +982,7 @@ class ValidateNeutronConfiguration(test.NoDBTestCase):
self.assertFalse(utils.is_neutron())
def test_neutron(self):
self.flags(network_api_class='nova.network.neutronv2.api.API')
self.flags(use_neutron=True)
self.assertTrue(utils.is_neutron())

View File

@ -56,6 +56,7 @@ from six.moves import range
from nova import exception
from nova.i18n import _, _LE, _LI, _LW
import nova.network
from nova import safe_utils
notify_decorator = 'nova.notifications.notify_decorator'
@ -153,7 +154,6 @@ Then this is a good place for your workaround.
CONF = cfg.CONF
CONF.register_opts(monkey_patch_opts)
CONF.register_opts(utils_opts)
CONF.import_opt('network_api_class', 'nova.network')
CONF.register_opts(workarounds_opts, group='workarounds')
LOG = logging.getLogger(__name__)
@ -1199,14 +1199,10 @@ def is_neutron():
if _IS_NEUTRON is not None:
return _IS_NEUTRON
try:
cls_name = CONF.network_api_class
from nova.network.neutronv2 import api as neutron_api
_IS_NEUTRON = issubclass(importutils.import_class(cls_name),
neutron_api.API)
except ImportError:
_IS_NEUTRON = False
# TODO(sdague): As long as network_api_class is importable
# is_neutron can return None to mean we have no idea what their
# class is.
_IS_NEUTRON = (nova.network.is_neutron() is True)
return _IS_NEUTRON