diff --git a/neutron/tests/functional/agent/linux/base.py b/neutron/tests/functional/agent/linux/base.py deleted file mode 100644 index c5ea717f7..000000000 --- a/neutron/tests/functional/agent/linux/base.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2014 Cisco Systems, Inc. -# -# 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 os -import random - -from neutron.agent.linux import ovs_lib -from neutron.agent.linux import utils -from neutron.plugins.common import constants as q_const -from neutron.tests import base - - -BR_PREFIX = 'test-br' - - -class BaseLinuxTestCase(base.BaseTestCase): - def setUp(self, root_helper='sudo'): - super(BaseLinuxTestCase, self).setUp() - - self.root_helper = root_helper - - def check_command(self, cmd, error_text, skip_msg): - try: - utils.execute(cmd) - except RuntimeError as e: - if error_text in str(e): - self.skipTest(skip_msg) - raise - - def check_sudo_enabled(self): - if os.environ.get('OS_SUDO_TESTING') not in base.TRUE_STRING: - self.skipTest('testing with sudo is not enabled') - - def get_rand_name(self, max_length, prefix='test'): - name = prefix + str(random.randint(1, 0x7fffffff)) - return name[:max_length] - - def create_resource(self, name_prefix, creation_func, *args, **kwargs): - """Create a new resource that does not already exist. - - :param name_prefix: The prefix for a randomly generated name - :param creation_func: A function taking the name of the resource - to be created as it's first argument. An error is assumed - to indicate a name collision. - :param *args *kwargs: These will be passed to the create function. - """ - while True: - name = self.get_rand_name(q_const.MAX_DEV_NAME_LEN, name_prefix) - try: - return creation_func(name, *args, **kwargs) - except RuntimeError: - continue - - -class BaseOVSLinuxTestCase(BaseLinuxTestCase): - def setUp(self, root_helper='sudo'): - super(BaseOVSLinuxTestCase, self).setUp(root_helper) - self.ovs = ovs_lib.BaseOVS(self.root_helper) - - def create_ovs_bridge(self, br_prefix=BR_PREFIX): - br = self.create_resource(br_prefix, self.ovs.add_bridge) - self.addCleanup(br.destroy) - return br diff --git a/neutron/tests/functional/agent/linux/test_async_process.py b/neutron/tests/functional/agent/linux/test_async_process.py deleted file mode 100644 index dd2ebb889..000000000 --- a/neutron/tests/functional/agent/linux/test_async_process.py +++ /dev/null @@ -1,71 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc. -# -# 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 eventlet -import fixtures - -from six import moves - -from neutron.agent.linux import async_process -from neutron.tests import base - - -class TestAsyncProcess(base.BaseTestCase): - - def setUp(self): - super(TestAsyncProcess, self).setUp() - self.test_file_path = self.useFixture( - fixtures.TempDir()).join("test_async_process.tmp") - self.data = [str(x) for x in moves.xrange(4)] - with file(self.test_file_path, 'w') as f: - f.writelines('%s\n' % item for item in self.data) - - def _check_stdout(self, proc): - # Ensure that all the output from the file is read - output = [] - while output != self.data: - new_output = list(proc.iter_stdout()) - if new_output: - output += new_output - eventlet.sleep(0.01) - - def test_stopping_async_process_lifecycle(self): - with self.assert_max_execution_time(): - proc = async_process.AsyncProcess(['tail', '-f', - self.test_file_path]) - proc.start() - self._check_stdout(proc) - proc.stop() - - # Ensure that the process and greenthreads have stopped - proc._process.wait() - self.assertEqual(proc._process.returncode, -9) - for watcher in proc._watchers: - watcher.wait() - - def test_async_process_respawns(self): - with self.assert_max_execution_time(): - proc = async_process.AsyncProcess(['tail', '-f', - self.test_file_path], - respawn_interval=0) - proc.start() - - # Ensure that the same output is read twice - self._check_stdout(proc) - pid = proc._get_pid_to_kill() - proc._kill_process(pid) - self._check_stdout(proc) - proc.stop() diff --git a/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py b/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py deleted file mode 100644 index 3ef5f9411..000000000 --- a/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py +++ /dev/null @@ -1,108 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc. -# -# 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. - -""" -Tests in this module will be skipped unless: - - - ovsdb-client is installed - - - ovsdb-client can be invoked via password-less sudo - - - OS_SUDO_TESTING is set to '1' or 'True' in the test execution - environment - - -The jenkins gate does not allow direct sudo invocation during test -runs, but configuring OS_SUDO_TESTING ensures that developers are -still able to execute tests that require the capability. -""" - -import eventlet - -from neutron.agent.linux import ovsdb_monitor -from neutron.tests.functional.agent.linux import base as base_agent - - -class BaseMonitorTest(base_agent.BaseOVSLinuxTestCase): - - def setUp(self): - # Emulate using a rootwrap script with sudo - super(BaseMonitorTest, self).setUp(root_helper='sudo sudo') - - self._check_test_requirements() - self.bridge = self.create_ovs_bridge() - - def _check_test_requirements(self): - self.check_sudo_enabled() - self.check_command(['which', 'ovsdb-client'], - 'Exit code: 1', 'ovsdb-client is not installed') - self.check_command(['sudo', '-n', 'ovsdb-client', 'list-dbs'], - 'Exit code: 1', - 'password-less sudo not granted for ovsdb-client') - - -class TestOvsdbMonitor(BaseMonitorTest): - - def setUp(self): - super(TestOvsdbMonitor, self).setUp() - - self.monitor = ovsdb_monitor.OvsdbMonitor('Bridge', - root_helper=self.root_helper) - self.addCleanup(self.monitor.stop) - self.monitor.start() - - def collect_initial_output(self): - while True: - output = list(self.monitor.iter_stdout()) - if output: - return output[0] - eventlet.sleep(0.01) - - def test_killed_monitor_respawns(self): - with self.assert_max_execution_time(): - self.monitor.respawn_interval = 0 - old_pid = self.monitor._process.pid - output1 = self.collect_initial_output() - pid = self.monitor._get_pid_to_kill() - self.monitor._kill_process(pid) - self.monitor._reset_queues() - while (self.monitor._process.pid == old_pid): - eventlet.sleep(0.01) - output2 = self.collect_initial_output() - # Initial output should appear twice - self.assertEqual(output1, output2) - - -class TestSimpleInterfaceMonitor(BaseMonitorTest): - - def setUp(self): - super(TestSimpleInterfaceMonitor, self).setUp() - - self.monitor = ovsdb_monitor.SimpleInterfaceMonitor( - root_helper=self.root_helper) - self.addCleanup(self.monitor.stop) - self.monitor.start(block=True) - - def test_has_updates(self): - self.assertTrue(self.monitor.has_updates, - 'Initial call should always be true') - self.assertFalse(self.monitor.has_updates, - 'has_updates without port addition should be False') - self.create_resource('test-port-', self.bridge.add_port) - with self.assert_max_execution_time(): - # has_updates after port addition should become True - while not self.monitor.has_updates: - eventlet.sleep(0.01) diff --git a/neutron/tests/functional/sanity/__init__.py b/neutron/tests/functional/sanity/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/functional/sanity/test_ovs_sanity.py b/neutron/tests/functional/sanity/test_ovs_sanity.py deleted file mode 100644 index fa63300fe..000000000 --- a/neutron/tests/functional/sanity/test_ovs_sanity.py +++ /dev/null @@ -1,46 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2014 OpenStack Foundation. -# All Rights Reserved. -# -# 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 os - -from neutron.cmd.sanity import checks -from neutron.tests import base - - -class OVSSanityTestCase(base.BaseTestCase): - def setUp(self): - super(OVSSanityTestCase, self).setUp() - - self.root_helper = 'sudo' - - def check_sudo_enabled(self): - if os.environ.get('OS_SUDO_TESTING') not in base.TRUE_STRING: - self.skipTest('testing with sudo is not enabled') - - def test_ovs_vxlan_support_runs(self): - """This test just ensures that the test in neutron-sanity-check - can run through without error, without mocking anything out - """ - self.check_sudo_enabled() - checks.vxlan_supported(self.root_helper) - - def test_ovs_patch_support_runs(self): - """This test just ensures that the test in neutron-sanity-check - can run through without error, without mocking anything out - """ - self.check_sudo_enabled() - checks.patch_supported(self.root_helper) diff --git a/neutron/tests/unit/_test_extension_portbindings.py b/neutron/tests/unit/_test_extension_portbindings.py deleted file mode 100644 index 3a78b8d8f..000000000 --- a/neutron/tests/unit/_test_extension_portbindings.py +++ /dev/null @@ -1,377 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 NEC Corporation -# All rights reserved. -# -# 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. -# -# @author: Akihiro Motoki, NEC Corporation -# - -import contextlib -import httplib - -from oslo.config import cfg -from webob import exc - -from neutron import context -from neutron.extensions import portbindings -from neutron import manager -from neutron.tests.unit import test_db_plugin - - -class PortBindingsTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - - # VIF_TYPE must be overridden according to plugin vif_type - VIF_TYPE = portbindings.VIF_TYPE_OTHER - # The plugin supports the port security feature such as - # security groups and anti spoofing. - HAS_PORT_FILTER = False - - def _check_response_portbindings(self, port): - self.assertEqual(port[portbindings.VIF_TYPE], self.VIF_TYPE) - vif_details = port[portbindings.VIF_DETAILS] - # REVISIT(rkukura): Consider reworking tests to enable ML2 to bind - if self.VIF_TYPE not in [portbindings.VIF_TYPE_UNBOUND, - portbindings.VIF_TYPE_BINDING_FAILED]: - # TODO(rkukura): Replace with new VIF security details - self.assertEqual(vif_details[portbindings.CAP_PORT_FILTER], - self.HAS_PORT_FILTER) - - def _check_response_no_portbindings(self, port): - self.assertIn('status', port) - self.assertNotIn(portbindings.VIF_TYPE, port) - self.assertNotIn(portbindings.VIF_DETAILS, port) - - def _get_non_admin_context(self): - return context.Context(user_id=None, - tenant_id=self._tenant_id, - is_admin=False, - read_deleted="no") - - def test_port_vif_details(self): - with self.port(name='name') as port: - port_id = port['port']['id'] - # Check a response of create_port - self._check_response_portbindings(port['port']) - # Check a response of get_port - ctx = context.get_admin_context() - port = self._show('ports', port_id, neutron_context=ctx)['port'] - self._check_response_portbindings(port) - # By default user is admin - now test non admin user - ctx = self._get_non_admin_context() - non_admin_port = self._show( - 'ports', port_id, neutron_context=ctx)['port'] - self._check_response_no_portbindings(non_admin_port) - - def test_ports_vif_details(self): - plugin = manager.NeutronManager.get_plugin() - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(), self.port()): - ctx = context.get_admin_context() - ports = plugin.get_ports(ctx) - self.assertEqual(len(ports), 2) - for port in ports: - self._check_response_portbindings(port) - # By default user is admin - now test non admin user - ctx = self._get_non_admin_context() - ports = self._list('ports', neutron_context=ctx)['ports'] - self.assertEqual(len(ports), 2) - for non_admin_port in ports: - self._check_response_no_portbindings(non_admin_port) - - def _check_port_binding_profile(self, port, profile=None): - # For plugins which does not use binding:profile attr - # we just check an operation for the port succeed. - self.assertIn('id', port) - - def _test_create_port_binding_profile(self, profile): - profile_arg = {portbindings.PROFILE: profile} - with self.port(arg_list=(portbindings.PROFILE,), - **profile_arg) as port: - port_id = port['port']['id'] - self._check_port_binding_profile(port['port'], profile) - port = self._show('ports', port_id) - self._check_port_binding_profile(port['port'], profile) - - def test_create_port_binding_profile_none(self): - self._test_create_port_binding_profile(None) - - def test_create_port_binding_profile_with_empty_dict(self): - self._test_create_port_binding_profile({}) - - def _test_update_port_binding_profile(self, profile): - profile_arg = {portbindings.PROFILE: profile} - with self.port() as port: - # print "(1) %s" % port - self._check_port_binding_profile(port['port']) - port_id = port['port']['id'] - ctx = context.get_admin_context() - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self._check_port_binding_profile(port, profile) - port = self._show('ports', port_id)['port'] - self._check_port_binding_profile(port, profile) - - def test_update_port_binding_profile_none(self): - self._test_update_port_binding_profile(None) - - def test_update_port_binding_profile_with_empty_dict(self): - self._test_update_port_binding_profile({}) - - def test_port_create_portinfo_non_admin(self): - profile_arg = {portbindings.PROFILE: {'dummy': 'dummy'}} - with self.network(set_context=True, tenant_id='test') as net1: - with self.subnet(network=net1) as subnet1: - # succeed without binding:profile - with self.port(subnet=subnet1, - set_context=True, tenant_id='test'): - pass - # fail with binding:profile - try: - with self.port(subnet=subnet1, - expected_res_status=403, - arg_list=(portbindings.PROFILE,), - set_context=True, tenant_id='test', - **profile_arg): - pass - except exc.HTTPClientError: - pass - - def test_port_update_portinfo_non_admin(self): - profile_arg = {portbindings.PROFILE: {'dummy': 'dummy'}} - with self.network() as net1: - with self.subnet(network=net1) as subnet1: - with self.port(subnet=subnet1) as port: - # By default user is admin - now test non admin user - # Note that 404 is returned when prohibit by policy. - # See comment for PolicyNotAuthorized except clause - # in update() in neutron.api.v2.base.Controller. - port_id = port['port']['id'] - ctx = self._get_non_admin_context() - port = self._update('ports', port_id, - {'port': profile_arg}, - expected_code=404, - neutron_context=ctx) - - -class PortBindingsHostTestCaseMixin(object): - fmt = 'json' - hostname = 'testhost' - - def _check_response_portbindings_host(self, port): - self.assertEqual(port[portbindings.HOST_ID], self.hostname) - - def _check_response_no_portbindings_host(self, port): - self.assertIn('status', port) - self.assertNotIn(portbindings.HOST_ID, port) - - def test_port_vif_non_admin(self): - with self.network(set_context=True, - tenant_id='test') as net1: - with self.subnet(network=net1) as subnet1: - host_arg = {portbindings.HOST_ID: self.hostname} - try: - with self.port(subnet=subnet1, - expected_res_status=403, - arg_list=(portbindings.HOST_ID,), - set_context=True, - tenant_id='test', - **host_arg): - pass - except exc.HTTPClientError: - pass - - def test_port_vif_host(self): - host_arg = {portbindings.HOST_ID: self.hostname} - with self.port(name='name', arg_list=(portbindings.HOST_ID,), - **host_arg) as port: - port_id = port['port']['id'] - # Check a response of create_port - self._check_response_portbindings_host(port['port']) - # Check a response of get_port - ctx = context.get_admin_context() - port = self._show('ports', port_id, neutron_context=ctx)['port'] - self._check_response_portbindings_host(port) - # By default user is admin - now test non admin user - ctx = context.Context(user_id=None, - tenant_id=self._tenant_id, - is_admin=False, - read_deleted="no") - non_admin_port = self._show( - 'ports', port_id, neutron_context=ctx)['port'] - self._check_response_no_portbindings_host(non_admin_port) - - def test_ports_vif_host(self): - cfg.CONF.set_default('allow_overlapping_ips', True) - host_arg = {portbindings.HOST_ID: self.hostname} - with contextlib.nested( - self.port(name='name1', - arg_list=(portbindings.HOST_ID,), - **host_arg), - self.port(name='name2')): - ctx = context.get_admin_context() - ports = self._list('ports', neutron_context=ctx)['ports'] - self.assertEqual(2, len(ports)) - for port in ports: - if port['name'] == 'name1': - self._check_response_portbindings_host(port) - else: - self.assertFalse(port[portbindings.HOST_ID]) - # By default user is admin - now test non admin user - ctx = context.Context(user_id=None, - tenant_id=self._tenant_id, - is_admin=False, - read_deleted="no") - ports = self._list('ports', neutron_context=ctx)['ports'] - self.assertEqual(2, len(ports)) - for non_admin_port in ports: - self._check_response_no_portbindings_host(non_admin_port) - - def test_ports_vif_host_update(self): - cfg.CONF.set_default('allow_overlapping_ips', True) - host_arg = {portbindings.HOST_ID: self.hostname} - with contextlib.nested( - self.port(name='name1', - arg_list=(portbindings.HOST_ID,), - **host_arg), - self.port(name='name2')) as (port1, port2): - data = {'port': {portbindings.HOST_ID: 'testhosttemp'}} - req = self.new_update_request('ports', data, port1['port']['id']) - req.get_response(self.api) - req = self.new_update_request('ports', data, port2['port']['id']) - ctx = context.get_admin_context() - req.get_response(self.api) - ports = self._list('ports', neutron_context=ctx)['ports'] - self.assertEqual(2, len(ports)) - for port in ports: - self.assertEqual('testhosttemp', port[portbindings.HOST_ID]) - - def test_ports_vif_non_host_update(self): - host_arg = {portbindings.HOST_ID: self.hostname} - with self.port(name='name', arg_list=(portbindings.HOST_ID,), - **host_arg) as port: - data = {'port': {'admin_state_up': False}} - req = self.new_update_request('ports', data, port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(port['port'][portbindings.HOST_ID], - res['port'][portbindings.HOST_ID]) - - def test_ports_vif_non_host_update_when_host_null(self): - with self.port() as port: - data = {'port': {'admin_state_up': False}} - req = self.new_update_request('ports', data, port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(port['port'][portbindings.HOST_ID], - res['port'][portbindings.HOST_ID]) - - def test_ports_vif_host_list(self): - cfg.CONF.set_default('allow_overlapping_ips', True) - host_arg = {portbindings.HOST_ID: self.hostname} - with contextlib.nested( - self.port(name='name1', - arg_list=(portbindings.HOST_ID,), - **host_arg), - self.port(name='name2'), - self.port(name='name3', - arg_list=(portbindings.HOST_ID,), - **host_arg),) as (port1, _port2, port3): - self._test_list_resources( - 'port', (port1, port3), - query_params='%s=%s' % (portbindings.HOST_ID, self.hostname)) - - -class PortBindingsVnicTestCaseMixin(object): - fmt = 'json' - vnic_type = portbindings.VNIC_NORMAL - - def _check_response_portbindings_vnic_type(self, port): - self.assertIn('status', port) - self.assertEqual(port[portbindings.VNIC_TYPE], self.vnic_type) - - def test_port_vnic_type_non_admin(self): - with self.network(set_context=True, - tenant_id='test') as net1: - with self.subnet(network=net1) as subnet1: - vnic_arg = {portbindings.VNIC_TYPE: self.vnic_type} - with self.port(subnet=subnet1, - expected_res_status=httplib.CREATED, - arg_list=(portbindings.VNIC_TYPE,), - set_context=True, - tenant_id='test', - **vnic_arg) as port: - # Check a response of create_port - self._check_response_portbindings_vnic_type(port['port']) - - def test_port_vnic_type(self): - vnic_arg = {portbindings.VNIC_TYPE: self.vnic_type} - with self.port(name='name', arg_list=(portbindings.VNIC_TYPE,), - **vnic_arg) as port: - port_id = port['port']['id'] - # Check a response of create_port - self._check_response_portbindings_vnic_type(port['port']) - # Check a response of get_port - ctx = context.get_admin_context() - port = self._show('ports', port_id, neutron_context=ctx)['port'] - self._check_response_portbindings_vnic_type(port) - # By default user is admin - now test non admin user - ctx = context.Context(user_id=None, - tenant_id=self._tenant_id, - is_admin=False, - read_deleted="no") - non_admin_port = self._show( - 'ports', port_id, neutron_context=ctx)['port'] - self._check_response_portbindings_vnic_type(non_admin_port) - - def test_ports_vnic_type(self): - cfg.CONF.set_default('allow_overlapping_ips', True) - vnic_arg = {portbindings.VNIC_TYPE: self.vnic_type} - with contextlib.nested( - self.port(name='name1', - arg_list=(portbindings.VNIC_TYPE,), - **vnic_arg), - self.port(name='name2')): - ctx = context.get_admin_context() - ports = self._list('ports', neutron_context=ctx)['ports'] - self.assertEqual(2, len(ports)) - for port in ports: - if port['name'] == 'name1': - self._check_response_portbindings_vnic_type(port) - else: - self.assertEqual(portbindings.VNIC_NORMAL, - port[portbindings.VNIC_TYPE]) - # By default user is admin - now test non admin user - ctx = context.Context(user_id=None, - tenant_id=self._tenant_id, - is_admin=False, - read_deleted="no") - ports = self._list('ports', neutron_context=ctx)['ports'] - self.assertEqual(2, len(ports)) - for non_admin_port in ports: - self._check_response_portbindings_vnic_type(non_admin_port) - - def test_ports_vnic_type_list(self): - cfg.CONF.set_default('allow_overlapping_ips', True) - vnic_arg = {portbindings.VNIC_TYPE: self.vnic_type} - with contextlib.nested( - self.port(name='name1', - arg_list=(portbindings.VNIC_TYPE,), - **vnic_arg), - self.port(name='name2'), - self.port(name='name3', - arg_list=(portbindings.VNIC_TYPE,), - **vnic_arg),) as (port1, port2, port3): - self._test_list_resources( - 'port', (port1, port2, port3), - query_params='%s=%s' % (portbindings.VNIC_TYPE, - self.vnic_type)) diff --git a/neutron/tests/unit/agent/linux/test_ovs_lib.py b/neutron/tests/unit/agent/linux/test_ovs_lib.py deleted file mode 100644 index 8a19ed39a..000000000 --- a/neutron/tests/unit/agent/linux/test_ovs_lib.py +++ /dev/null @@ -1,967 +0,0 @@ -# Copyright 2012, VMware, Inc. -# -# 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 collections -import mock -from oslo.config import cfg -import testtools - -from neutron.agent.linux import ovs_lib -from neutron.agent.linux import utils -from neutron.common import exceptions -from neutron.openstack.common import jsonutils -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants as p_const -from neutron.plugins.openvswitch.common import constants as const -from neutron.tests import base -from neutron.tests import tools - -try: - OrderedDict = collections.OrderedDict -except AttributeError: - import ordereddict - OrderedDict = ordereddict.OrderedDict - -OVS_LINUX_KERN_VERS_WITHOUT_VXLAN = "3.12.0" - - -class TestBaseOVS(base.BaseTestCase): - - def setUp(self): - super(TestBaseOVS, self).setUp() - self.root_helper = 'sudo' - self.ovs = ovs_lib.BaseOVS(self.root_helper) - self.br_name = 'bridge1' - - def test_add_bridge(self): - with mock.patch.object(self.ovs, 'run_vsctl') as mock_vsctl: - bridge = self.ovs.add_bridge(self.br_name) - - mock_vsctl.assert_called_with(["--", "--may-exist", - "add-br", self.br_name]) - self.assertEqual(bridge.br_name, self.br_name) - self.assertEqual(bridge.root_helper, self.ovs.root_helper) - - def test_delete_bridge(self): - with mock.patch.object(self.ovs, 'run_vsctl') as mock_vsctl: - self.ovs.delete_bridge(self.br_name) - mock_vsctl.assert_called_with(["--", "--if-exists", "del-br", - self.br_name]) - - def test_bridge_exists_returns_true(self): - with mock.patch.object(self.ovs, 'run_vsctl') as mock_vsctl: - self.assertTrue(self.ovs.bridge_exists(self.br_name)) - mock_vsctl.assert_called_with(['br-exists', self.br_name], - check_error=True) - - def test_bridge_exists_returns_false_for_exit_code_2(self): - with mock.patch.object(self.ovs, 'run_vsctl', - side_effect=RuntimeError('Exit code: 2\n')): - self.assertFalse(self.ovs.bridge_exists('bridge1')) - - def test_bridge_exists_raises_unknown_exception(self): - with mock.patch.object(self.ovs, 'run_vsctl', - side_effect=RuntimeError()): - with testtools.ExpectedException(RuntimeError): - self.ovs.bridge_exists('bridge1') - - def test_get_bridge_name_for_port_name_returns_bridge_for_valid_port(self): - port_name = 'bar' - with mock.patch.object(self.ovs, 'run_vsctl', - return_value=self.br_name) as mock_vsctl: - bridge = self.ovs.get_bridge_name_for_port_name(port_name) - self.assertEqual(bridge, self.br_name) - mock_vsctl.assert_called_with(['port-to-br', port_name], - check_error=True) - - def test_get_bridge_name_for_port_name_returns_none_for_exit_code_1(self): - with mock.patch.object(self.ovs, 'run_vsctl', - side_effect=RuntimeError('Exit code: 1\n')): - self.assertFalse(self.ovs.get_bridge_name_for_port_name('bridge1')) - - def test_get_bridge_name_for_port_name_raises_unknown_exception(self): - with mock.patch.object(self.ovs, 'run_vsctl', - side_effect=RuntimeError()): - with testtools.ExpectedException(RuntimeError): - self.ovs.get_bridge_name_for_port_name('bridge1') - - def _test_port_exists(self, br_name, result): - with mock.patch.object(self.ovs, - 'get_bridge_name_for_port_name', - return_value=br_name): - self.assertEqual(self.ovs.port_exists('bar'), result) - - def test_port_exists_returns_true_for_bridge_name(self): - self._test_port_exists(self.br_name, True) - - def test_port_exists_returns_false_for_none(self): - self._test_port_exists(None, False) - - -class OVS_Lib_Test(base.BaseTestCase): - """A test suite to exercise the OVS libraries shared by Neutron agents. - - Note: these tests do not actually execute ovs-* utilities, and thus - can run on any system. That does, however, limit their scope. - """ - - def setUp(self): - super(OVS_Lib_Test, self).setUp() - self.BR_NAME = "br-int" - self.TO = "--timeout=10" - - self.root_helper = 'sudo' - self.br = ovs_lib.OVSBridge(self.BR_NAME, self.root_helper) - self.execute = mock.patch.object( - utils, "execute", spec=utils.execute).start() - - def test_vifport(self): - """Create and stringify vif port, confirm no exceptions.""" - - pname = "vif1.0" - ofport = 5 - vif_id = uuidutils.generate_uuid() - mac = "ca:fe:de:ad:be:ef" - - # test __init__ - port = ovs_lib.VifPort(pname, ofport, vif_id, mac, self.br) - self.assertEqual(port.port_name, pname) - self.assertEqual(port.ofport, ofport) - self.assertEqual(port.vif_id, vif_id) - self.assertEqual(port.vif_mac, mac) - self.assertEqual(port.switch.br_name, self.BR_NAME) - - # test __str__ - str(port) - - def test_set_controller(self): - controller_names = ['tcp:127.0.0.1:6633', 'tcp:172.17.16.10:5555'] - self.br.set_controller(controller_names) - self.execute.assert_called_once_with( - ['ovs-vsctl', self.TO, '--', 'set-controller', self.BR_NAME, - 'tcp:127.0.0.1:6633', 'tcp:172.17.16.10:5555'], - root_helper=self.root_helper) - - def test_del_controller(self): - self.br.del_controller() - self.execute.assert_called_once_with( - ['ovs-vsctl', self.TO, '--', 'del-controller', self.BR_NAME], - root_helper=self.root_helper) - - def test_get_controller(self): - self.execute.return_value = 'tcp:127.0.0.1:6633\ntcp:172.17.16.10:5555' - names = self.br.get_controller() - self.assertEqual(names, - ['tcp:127.0.0.1:6633', 'tcp:172.17.16.10:5555']) - self.execute.assert_called_once_with( - ['ovs-vsctl', self.TO, '--', 'get-controller', self.BR_NAME], - root_helper=self.root_helper) - - def test_set_secure_mode(self): - self.br.set_secure_mode() - self.execute.assert_called_once_with( - ['ovs-vsctl', self.TO, '--', 'set-fail-mode', self.BR_NAME, - 'secure'], root_helper=self.root_helper) - - def test_set_protocols(self): - protocols = 'OpenFlow13' - self.br.set_protocols(protocols) - self.execute.assert_called_once_with( - ['ovs-vsctl', self.TO, '--', 'set', 'bridge', self.BR_NAME, - "protocols=%s" % protocols], - root_helper=self.root_helper) - - def test_create(self): - self.br.add_bridge(self.BR_NAME) - - self.br.create() - - def test_destroy(self): - self.br.delete_bridge(self.BR_NAME) - - self.br.destroy() - - def test_reset_bridge(self): - self.br.destroy() - self.br.create() - - self.br.reset_bridge() - - def _build_timeout_opt(self, exp_timeout): - return "--timeout=%d" % exp_timeout if exp_timeout else self.TO - - def _test_delete_port(self, exp_timeout=None): - exp_timeout_str = self._build_timeout_opt(exp_timeout) - pname = "tap5" - self.br.delete_port(pname) - self.execute.assert_called_once_with( - ["ovs-vsctl", exp_timeout_str, "--", "--if-exists", - "del-port", self.BR_NAME, pname], - root_helper=self.root_helper) - - def test_delete_port(self): - self._test_delete_port() - - def test_call_command_non_default_timeput(self): - # This test is only for verifying a non-default timeout - # is correctly applied. Does not need to be repeated for - # every ovs_lib method - new_timeout = 5 - self.br.vsctl_timeout = new_timeout - self._test_delete_port(new_timeout) - - def test_add_flow(self): - ofport = "99" - vid = 4000 - lsw_id = 18 - cidr = '192.168.1.0/24' - - flow_dict_1 = OrderedDict([('priority', 2), - ('dl_src', 'ca:fe:de:ad:be:ef'), - ('actions', 'strip_vlan,output:0')]) - flow_dict_2 = OrderedDict([('priority', 1), - ('actions', 'normal')]) - flow_dict_3 = OrderedDict([('priority', 2), - ('actions', 'drop')]) - flow_dict_4 = OrderedDict([('priority', 2), - ('in_port', ofport), - ('actions', 'drop')]) - flow_dict_5 = OrderedDict([ - ('priority', 4), - ('in_port', ofport), - ('dl_vlan', vid), - ('actions', "strip_vlan,set_tunnel:%s,normal" % (lsw_id))]) - flow_dict_6 = OrderedDict([ - ('priority', 3), - ('tun_id', lsw_id), - ('actions', "mod_vlan_vid:%s,output:%s" % (vid, ofport))]) - flow_dict_7 = OrderedDict([ - ('priority', 4), - ('nw_src', cidr), - ('proto', 'arp'), - ('actions', 'drop')]) - - self.br.add_flow(**flow_dict_1) - self.br.add_flow(**flow_dict_2) - self.br.add_flow(**flow_dict_3) - self.br.add_flow(**flow_dict_4) - self.br.add_flow(**flow_dict_5) - self.br.add_flow(**flow_dict_6) - self.br.add_flow(**flow_dict_7) - expected_calls = [ - mock.call(["ovs-ofctl", "add-flow", self.BR_NAME, - "hard_timeout=0,idle_timeout=0," - "priority=2,dl_src=ca:fe:de:ad:be:ef" - ",actions=strip_vlan,output:0"], - process_input=None, root_helper=self.root_helper), - mock.call(["ovs-ofctl", "add-flow", self.BR_NAME, - "hard_timeout=0,idle_timeout=0," - "priority=1,actions=normal"], - process_input=None, root_helper=self.root_helper), - mock.call(["ovs-ofctl", "add-flow", self.BR_NAME, - "hard_timeout=0,idle_timeout=0," - "priority=2,actions=drop"], - process_input=None, root_helper=self.root_helper), - mock.call(["ovs-ofctl", "add-flow", self.BR_NAME, - "hard_timeout=0,idle_timeout=0," - "priority=2,in_port=%s,actions=drop" % ofport], - process_input=None, root_helper=self.root_helper), - mock.call(["ovs-ofctl", "add-flow", self.BR_NAME, - "hard_timeout=0,idle_timeout=0," - "priority=4,dl_vlan=%s,in_port=%s," - "actions=strip_vlan,set_tunnel:%s,normal" - % (vid, ofport, lsw_id)], - process_input=None, root_helper=self.root_helper), - mock.call(["ovs-ofctl", "add-flow", self.BR_NAME, - "hard_timeout=0,idle_timeout=0," - "priority=3,tun_id=%s,actions=" - "mod_vlan_vid:%s,output:%s" - % (lsw_id, vid, ofport)], - process_input=None, root_helper=self.root_helper), - mock.call(["ovs-ofctl", "add-flow", self.BR_NAME, - "hard_timeout=0,idle_timeout=0," - "priority=4,nw_src=%s,arp,actions=drop" % cidr], - process_input=None, root_helper=self.root_helper), - ] - self.execute.assert_has_calls(expected_calls) - - def test_add_flow_timeout_set(self): - flow_dict = OrderedDict([('priority', 1), - ('hard_timeout', 1000), - ('idle_timeout', 2000), - ('actions', 'normal')]) - - self.br.add_flow(**flow_dict) - self.execute.assert_called_once_with( - ["ovs-ofctl", "add-flow", self.BR_NAME, - "hard_timeout=1000,idle_timeout=2000,priority=1,actions=normal"], - process_input=None, - root_helper=self.root_helper) - - def test_add_flow_default_priority(self): - flow_dict = OrderedDict([('actions', 'normal')]) - - self.br.add_flow(**flow_dict) - self.execute.assert_called_once_with( - ["ovs-ofctl", "add-flow", self.BR_NAME, - "hard_timeout=0,idle_timeout=0,priority=1,actions=normal"], - process_input=None, - root_helper=self.root_helper) - - def test_get_port_ofport(self): - pname = "tap99" - ofport = "6" - self.execute.return_value = ofport - self.assertEqual(self.br.get_port_ofport(pname), ofport) - self.execute.assert_called_once_with( - ["ovs-vsctl", self.TO, "get", "Interface", pname, "ofport"], - root_helper=self.root_helper) - - def test_get_port_ofport_non_int(self): - pname = "tap99" - ofport = "[]" - self.execute.return_value = ofport - self.assertEqual(self.br.get_port_ofport(pname), const.INVALID_OFPORT) - self.execute.assert_called_once_with( - ["ovs-vsctl", self.TO, "get", "Interface", pname, "ofport"], - root_helper=self.root_helper) - - def test_get_datapath_id(self): - datapath_id = '"0000b67f4fbcc149"' - self.execute.return_value = datapath_id - self.assertEqual(self.br.get_datapath_id(), datapath_id.strip('"')) - self.execute.assert_called_once_with( - ["ovs-vsctl", self.TO, "get", - "Bridge", self.BR_NAME, "datapath_id"], - root_helper=self.root_helper) - - def test_count_flows(self): - self.execute.return_value = 'ignore\nflow-1\n' - # counts the number of flows as total lines of output - 2 - self.assertEqual(self.br.count_flows(), 1) - self.execute.assert_called_once_with( - ["ovs-ofctl", "dump-flows", self.BR_NAME], - root_helper=self.root_helper, - process_input=None) - - def test_delete_flow(self): - ofport = "5" - lsw_id = 40 - vid = 39 - self.br.delete_flows(in_port=ofport) - self.br.delete_flows(tun_id=lsw_id) - self.br.delete_flows(dl_vlan=vid) - expected_calls = [ - mock.call(["ovs-ofctl", "del-flows", self.BR_NAME, - "in_port=" + ofport], - process_input=None, root_helper=self.root_helper), - mock.call(["ovs-ofctl", "del-flows", self.BR_NAME, - "tun_id=%s" % lsw_id], - process_input=None, root_helper=self.root_helper), - mock.call(["ovs-ofctl", "del-flows", self.BR_NAME, - "dl_vlan=%s" % vid], - process_input=None, root_helper=self.root_helper), - ] - self.execute.assert_has_calls(expected_calls) - - def test_delete_flow_with_priority_set(self): - params = {'in_port': '1', - 'priority': '1'} - - self.assertRaises(exceptions.InvalidInput, - self.br.delete_flows, - **params) - - def test_dump_flows(self): - table = 23 - nxst_flow = "NXST_FLOW reply (xid=0x4):" - flows = "\n".join([" cookie=0x0, duration=18042.514s, table=0, " - "n_packets=6, n_bytes=468, " - "priority=2,in_port=1 actions=drop", - " cookie=0x0, duration=18027.562s, table=0, " - "n_packets=0, n_bytes=0, " - "priority=3,in_port=1,dl_vlan=100 " - "actions=mod_vlan_vid:1,NORMAL", - " cookie=0x0, duration=18044.351s, table=0, " - "n_packets=9, n_bytes=594, priority=1 " - "actions=NORMAL", " cookie=0x0, " - "duration=18044.211s, table=23, n_packets=0, " - "n_bytes=0, priority=0 actions=drop"]) - flow_args = '\n'.join([nxst_flow, flows]) - run_ofctl = mock.patch.object(self.br, 'run_ofctl').start() - run_ofctl.side_effect = [flow_args] - retflows = self.br.dump_flows_for_table(table) - self.assertEqual(flows, retflows) - - def test_dump_flows_ovs_dead(self): - table = 23 - run_ofctl = mock.patch.object(self.br, 'run_ofctl').start() - run_ofctl.side_effect = [''] - retflows = self.br.dump_flows_for_table(table) - self.assertEqual(None, retflows) - - def test_mod_flow_with_priority_set(self): - params = {'in_port': '1', - 'priority': '1'} - - self.assertRaises(exceptions.InvalidInput, - self.br.mod_flow, - **params) - - def test_mod_flow_no_actions_set(self): - params = {'in_port': '1'} - - self.assertRaises(exceptions.InvalidInput, - self.br.mod_flow, - **params) - - def test_defer_apply_flows(self): - - flow_expr = mock.patch.object(ovs_lib, '_build_flow_expr_str').start() - flow_expr.side_effect = ['added_flow_1', 'added_flow_2', - 'deleted_flow_1'] - run_ofctl = mock.patch.object(self.br, 'run_ofctl').start() - - self.br.defer_apply_on() - self.br.add_flow(flow='add_flow_1') - self.br.defer_apply_on() - self.br.add_flow(flow='add_flow_2') - self.br.delete_flows(flow='delete_flow_1') - self.br.defer_apply_off() - - flow_expr.assert_has_calls([ - mock.call({'flow': 'add_flow_1'}, 'add'), - mock.call({'flow': 'add_flow_2'}, 'add'), - mock.call({'flow': 'delete_flow_1'}, 'del') - ]) - - run_ofctl.assert_has_calls([ - mock.call('add-flows', ['-'], 'added_flow_1\nadded_flow_2\n'), - mock.call('del-flows', ['-'], 'deleted_flow_1\n') - ]) - - def test_defer_apply_flows_concurrently(self): - flow_expr = mock.patch.object(ovs_lib, '_build_flow_expr_str').start() - flow_expr.side_effect = ['added_flow_1', 'deleted_flow_1', - 'modified_flow_1', 'added_flow_2', - 'deleted_flow_2', 'modified_flow_2'] - - run_ofctl = mock.patch.object(self.br, 'run_ofctl').start() - - def run_ofctl_fake(cmd, args, process_input=None): - self.br.defer_apply_on() - if cmd == 'add-flows': - self.br.add_flow(flow='added_flow_2') - elif cmd == 'del-flows': - self.br.delete_flows(flow='deleted_flow_2') - elif cmd == 'mod-flows': - self.br.mod_flow(flow='modified_flow_2') - run_ofctl.side_effect = run_ofctl_fake - - self.br.defer_apply_on() - self.br.add_flow(flow='added_flow_1') - self.br.delete_flows(flow='deleted_flow_1') - self.br.mod_flow(flow='modified_flow_1') - self.br.defer_apply_off() - - run_ofctl.side_effect = None - self.br.defer_apply_off() - - flow_expr.assert_has_calls([ - mock.call({'flow': 'added_flow_1'}, 'add'), - mock.call({'flow': 'deleted_flow_1'}, 'del'), - mock.call({'flow': 'modified_flow_1'}, 'mod'), - mock.call({'flow': 'added_flow_2'}, 'add'), - mock.call({'flow': 'deleted_flow_2'}, 'del'), - mock.call({'flow': 'modified_flow_2'}, 'mod') - ]) - run_ofctl.assert_has_calls([ - mock.call('add-flows', ['-'], 'added_flow_1\n'), - mock.call('del-flows', ['-'], 'deleted_flow_1\n'), - mock.call('mod-flows', ['-'], 'modified_flow_1\n'), - mock.call('add-flows', ['-'], 'added_flow_2\n'), - mock.call('del-flows', ['-'], 'deleted_flow_2\n'), - mock.call('mod-flows', ['-'], 'modified_flow_2\n') - ]) - - def test_add_tunnel_port(self): - pname = "tap99" - local_ip = "1.1.1.1" - remote_ip = "9.9.9.9" - ofport = "6" - command = ["ovs-vsctl", self.TO, '--', "--may-exist", "add-port", - self.BR_NAME, pname] - command.extend(["--", "set", "Interface", pname]) - command.extend(["type=gre", "options:df_default=true", - "options:remote_ip=" + remote_ip, - "options:local_ip=" + local_ip, - "options:in_key=flow", - "options:out_key=flow"]) - # Each element is a tuple of (expected mock call, return_value) - expected_calls_and_values = [ - (mock.call(command, root_helper=self.root_helper), None), - (mock.call(["ovs-vsctl", self.TO, "get", - "Interface", pname, "ofport"], - root_helper=self.root_helper), - ofport), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - self.assertEqual( - self.br.add_tunnel_port(pname, remote_ip, local_ip), - ofport) - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_add_vxlan_fragmented_tunnel_port(self): - pname = "tap99" - local_ip = "1.1.1.1" - remote_ip = "9.9.9.9" - ofport = "6" - vxlan_udp_port = "9999" - dont_fragment = False - command = ["ovs-vsctl", self.TO, '--', "--may-exist", "add-port", - self.BR_NAME, pname] - command.extend(["--", "set", "Interface", pname]) - command.extend(["type=" + p_const.TYPE_VXLAN, - "options:dst_port=" + vxlan_udp_port, - "options:df_default=false", - "options:remote_ip=" + remote_ip, - "options:local_ip=" + local_ip, - "options:in_key=flow", - "options:out_key=flow"]) - # Each element is a tuple of (expected mock call, return_value) - expected_calls_and_values = [ - (mock.call(command, root_helper=self.root_helper), None), - (mock.call(["ovs-vsctl", self.TO, "get", - "Interface", pname, "ofport"], - root_helper=self.root_helper), - ofport), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - self.assertEqual( - self.br.add_tunnel_port(pname, remote_ip, local_ip, - p_const.TYPE_VXLAN, vxlan_udp_port, - dont_fragment), - ofport) - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_add_patch_port(self): - pname = "tap99" - peer = "bar10" - ofport = "6" - - # Each element is a tuple of (expected mock call, return_value) - command = ["ovs-vsctl", self.TO, "add-port", self.BR_NAME, pname] - command.extend(["--", "set", "Interface", pname]) - command.extend(["type=patch", "options:peer=" + peer]) - expected_calls_and_values = [ - (mock.call(command, root_helper=self.root_helper), - None), - (mock.call(["ovs-vsctl", self.TO, "get", - "Interface", pname, "ofport"], - root_helper=self.root_helper), - ofport) - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - self.assertEqual(self.br.add_patch_port(pname, peer), ofport) - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def _test_get_vif_ports(self, is_xen=False): - pname = "tap99" - ofport = "6" - vif_id = uuidutils.generate_uuid() - mac = "ca:fe:de:ad:be:ef" - - if is_xen: - external_ids = ('{xs-vif-uuid="%s", attached-mac="%s"}' - % (vif_id, mac)) - else: - external_ids = ('{iface-id="%s", attached-mac="%s"}' - % (vif_id, mac)) - - # Each element is a tuple of (expected mock call, return_value) - expected_calls_and_values = [ - (mock.call(["ovs-vsctl", self.TO, "list-ports", self.BR_NAME], - root_helper=self.root_helper), - "%s\n" % pname), - (mock.call(["ovs-vsctl", self.TO, "get", - "Interface", pname, "external_ids"], - root_helper=self.root_helper), - external_ids), - (mock.call(["ovs-vsctl", self.TO, "get", - "Interface", pname, "ofport"], - root_helper=self.root_helper), - ofport), - ] - if is_xen: - expected_calls_and_values.append( - (mock.call(["xe", "vif-param-get", "param-name=other-config", - "param-key=nicira-iface-id", "uuid=" + vif_id], - root_helper=self.root_helper), - vif_id) - ) - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - ports = self.br.get_vif_ports() - self.assertEqual(1, len(ports)) - self.assertEqual(ports[0].port_name, pname) - self.assertEqual(ports[0].ofport, ofport) - self.assertEqual(ports[0].vif_id, vif_id) - self.assertEqual(ports[0].vif_mac, mac) - self.assertEqual(ports[0].switch.br_name, self.BR_NAME) - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def _encode_ovs_json(self, headings, data): - # See man ovs-vsctl(8) for the encoding details. - r = {"data": [], - "headings": headings} - for row in data: - ovs_row = [] - r["data"].append(ovs_row) - for cell in row: - if isinstance(cell, (str, int, list)): - ovs_row.append(cell) - elif isinstance(cell, dict): - ovs_row.append(["map", cell.items()]) - elif isinstance(cell, set): - ovs_row.append(["set", cell]) - else: - raise TypeError('%r not int, str, list, set or dict' % - type(cell)) - return jsonutils.dumps(r) - - def _test_get_vif_port_set(self, is_xen): - if is_xen: - id_key = 'xs-vif-uuid' - else: - id_key = 'iface-id' - - headings = ['name', 'external_ids'] - data = [ - # A vif port on this bridge: - ['tap99', {id_key: 'tap99id', 'attached-mac': 'tap99mac'}, 1], - # A vif port on this bridge not yet configured - ['tap98', {id_key: 'tap98id', 'attached-mac': 'tap98mac'}, []], - # Another vif port on this bridge not yet configured - ['tap97', {id_key: 'tap97id', 'attached-mac': 'tap97mac'}, - ['set', []]], - - # A vif port on another bridge: - ['tap88', {id_key: 'tap88id', 'attached-mac': 'tap88id'}, 1], - # Non-vif port on this bridge: - ['tun22', {}, 2], - ] - - # Each element is a tuple of (expected mock call, return_value) - expected_calls_and_values = [ - (mock.call(["ovs-vsctl", self.TO, "list-ports", self.BR_NAME], - root_helper=self.root_helper), - 'tap99\ntun22'), - (mock.call(["ovs-vsctl", self.TO, "--format=json", - "--", "--columns=name,external_ids,ofport", - "list", "Interface"], - root_helper=self.root_helper), - self._encode_ovs_json(headings, data)), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - if is_xen: - get_xapi_iface_id = mock.patch.object(self.br, - 'get_xapi_iface_id').start() - get_xapi_iface_id.return_value = 'tap99id' - - port_set = self.br.get_vif_port_set() - self.assertEqual(set(['tap99id']), port_set) - tools.verify_mock_calls(self.execute, expected_calls_and_values) - if is_xen: - get_xapi_iface_id.assert_called_once_with('tap99id') - - def test_get_vif_ports_nonxen(self): - self._test_get_vif_ports(is_xen=False) - - def test_get_vif_ports_xen(self): - self._test_get_vif_ports(is_xen=True) - - def test_get_vif_port_set_nonxen(self): - self._test_get_vif_port_set(False) - - def test_get_vif_port_set_xen(self): - self._test_get_vif_port_set(True) - - def test_get_vif_ports_list_ports_error(self): - expected_calls_and_values = [ - (mock.call(["ovs-vsctl", self.TO, "list-ports", self.BR_NAME], - root_helper=self.root_helper), - RuntimeError()), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - self.assertRaises(RuntimeError, self.br.get_vif_ports) - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_get_vif_port_set_list_ports_error(self): - expected_calls_and_values = [ - (mock.call(["ovs-vsctl", self.TO, "list-ports", self.BR_NAME], - root_helper=self.root_helper), - RuntimeError()), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - self.assertRaises(RuntimeError, self.br.get_vif_port_set) - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_get_vif_port_set_list_interface_error(self): - expected_calls_and_values = [ - (mock.call(["ovs-vsctl", self.TO, "list-ports", self.BR_NAME], - root_helper=self.root_helper), - 'tap99\n'), - (mock.call(["ovs-vsctl", self.TO, "--format=json", - "--", "--columns=name,external_ids,ofport", - "list", "Interface"], - root_helper=self.root_helper), - RuntimeError()), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - self.assertRaises(RuntimeError, self.br.get_vif_port_set) - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_get_port_tag_dict(self): - headings = ['name', 'tag'] - data = [ - ['int-br-eth2', set()], - ['patch-tun', set()], - ['qr-76d9e6b6-21', 1], - ['tapce5318ff-78', 1], - ['tape1400310-e6', 1], - ] - - # Each element is a tuple of (expected mock call, return_value) - expected_calls_and_values = [ - (mock.call(["ovs-vsctl", self.TO, "list-ports", self.BR_NAME], - root_helper=self.root_helper), - '\n'.join((iface for iface, tag in data))), - (mock.call(["ovs-vsctl", self.TO, "--format=json", - "--", "--columns=name,tag", - "list", "Port"], - root_helper=self.root_helper), - self._encode_ovs_json(headings, data)), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - port_tags = self.br.get_port_tag_dict() - self.assertEqual( - port_tags, - {u'int-br-eth2': [], - u'patch-tun': [], - u'qr-76d9e6b6-21': 1, - u'tapce5318ff-78': 1, - u'tape1400310-e6': 1} - ) - - def test_clear_db_attribute(self): - pname = "tap77" - self.br.clear_db_attribute("Port", pname, "tag") - self.execute.assert_called_once_with( - ["ovs-vsctl", self.TO, "clear", "Port", pname, "tag"], - root_helper=self.root_helper) - - def _test_iface_to_br(self, exp_timeout=None): - iface = 'tap0' - br = 'br-int' - root_helper = 'sudo' - self.execute.return_value = 'br-int' - exp_timeout_str = self._build_timeout_opt(exp_timeout) - self.assertEqual(ovs_lib.get_bridge_for_iface(root_helper, iface), br) - self.execute.assert_called_once_with( - ["ovs-vsctl", exp_timeout_str, "iface-to-br", iface], - root_helper=root_helper) - - def test_iface_to_br(self): - self._test_iface_to_br() - - def test_iface_to_br_non_default_timeout(self): - new_timeout = 5 - cfg.CONF.set_override('ovs_vsctl_timeout', new_timeout) - self._test_iface_to_br(new_timeout) - - def test_iface_to_br_handles_ovs_vsctl_exception(self): - iface = 'tap0' - root_helper = 'sudo' - self.execute.side_effect = Exception - - self.assertIsNone(ovs_lib.get_bridge_for_iface(root_helper, iface)) - self.execute.assert_called_once_with( - ["ovs-vsctl", self.TO, "iface-to-br", iface], - root_helper=root_helper) - - def test_delete_all_ports(self): - with mock.patch.object(self.br, 'get_port_name_list', - return_value=['port1']) as get_port: - with mock.patch.object(self.br, 'delete_port') as delete_port: - self.br.delete_ports(all_ports=True) - get_port.assert_called_once_with() - delete_port.assert_called_once_with('port1') - - def test_delete_neutron_ports(self): - port1 = ovs_lib.VifPort('tap1234', 1, uuidutils.generate_uuid(), - 'ca:fe:de:ad:be:ef', 'br') - port2 = ovs_lib.VifPort('tap5678', 2, uuidutils.generate_uuid(), - 'ca:ee:de:ad:be:ef', 'br') - with mock.patch.object(self.br, 'get_vif_ports', - return_value=[port1, port2]) as get_ports: - with mock.patch.object(self.br, 'delete_port') as delete_port: - self.br.delete_ports(all_ports=False) - get_ports.assert_called_once_with() - delete_port.assert_has_calls([ - mock.call('tap1234'), - mock.call('tap5678') - ]) - - def test_delete_neutron_ports_list_error(self): - expected_calls_and_values = [ - (mock.call(["ovs-vsctl", self.TO, "list-ports", self.BR_NAME], - root_helper=self.root_helper), - RuntimeError()), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - self.assertRaises(RuntimeError, self.br.delete_ports, all_ports=False) - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def _test_get_bridges(self, exp_timeout=None): - bridges = ['br-int', 'br-ex'] - root_helper = 'sudo' - self.execute.return_value = 'br-int\nbr-ex\n' - timeout_str = self._build_timeout_opt(exp_timeout) - self.assertEqual(ovs_lib.get_bridges(root_helper), bridges) - self.execute.assert_called_once_with( - ["ovs-vsctl", timeout_str, "list-br"], - root_helper=root_helper) - - def test_get_bridges(self): - self._test_get_bridges() - - def test_get_bridges_not_default_timeout(self): - new_timeout = 5 - cfg.CONF.set_override('ovs_vsctl_timeout', new_timeout) - self._test_get_bridges(new_timeout) - - def test_get_local_port_mac_succeeds(self): - with mock.patch('neutron.agent.linux.ip_lib.IpLinkCommand', - return_value=mock.Mock(address='foo')): - self.assertEqual('foo', self.br.get_local_port_mac()) - - def test_get_local_port_mac_raises_exception_for_missing_mac(self): - with mock.patch('neutron.agent.linux.ip_lib.IpLinkCommand', - return_value=mock.Mock(address=None)): - with testtools.ExpectedException(Exception): - self.br.get_local_port_mac() - - def _test_get_vif_port_by_id(self, iface_id, data, br_name=None): - headings = ['external_ids', 'name', 'ofport'] - # Each element is a tuple of (expected mock call, return_value) - expected_calls_and_values = [ - (mock.call(["ovs-vsctl", self.TO, "--format=json", - "--", "--columns=external_ids,name,ofport", - "find", "Interface", - 'external_ids:iface-id="%s"' % iface_id], - root_helper=self.root_helper), - self._encode_ovs_json(headings, data))] - if data: - if not br_name: - br_name = self.BR_NAME - - expected_calls_and_values.append( - (mock.call(["ovs-vsctl", self.TO, - "iface-to-br", data[0][headings.index('name')]], - root_helper=self.root_helper), - br_name)) - tools.setup_mock_calls(self.execute, expected_calls_and_values) - vif_port = self.br.get_vif_port_by_id(iface_id) - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - return vif_port - - def _test_get_vif_port_by_id_with_data(self, ofport=None, mac=None): - external_ids = [["iface-id", "tap99id"], - ["iface-status", "active"]] - if mac: - external_ids.append(["attached-mac", mac]) - data = [[["map", external_ids], "tap99", - ofport if ofport else '["set",[]]']] - vif_port = self._test_get_vif_port_by_id('tap99id', data) - if not ofport or ofport == -1 or not mac: - self.assertIsNone(vif_port) - return - self.assertEqual(vif_port.vif_id, 'tap99id') - self.assertEqual(vif_port.vif_mac, 'aa:bb:cc:dd:ee:ff') - self.assertEqual(vif_port.port_name, 'tap99') - self.assertEqual(vif_port.ofport, ofport) - - def test_get_vif_by_port_id_with_ofport(self): - self._test_get_vif_port_by_id_with_data( - ofport=1, mac="aa:bb:cc:dd:ee:ff") - - def test_get_vif_by_port_id_without_ofport(self): - self._test_get_vif_port_by_id_with_data(mac="aa:bb:cc:dd:ee:ff") - - def test_get_vif_by_port_id_with_invalid_ofport(self): - self._test_get_vif_port_by_id_with_data( - ofport=-1, mac="aa:bb:cc:dd:ee:ff") - - def test_get_vif_by_port_id_without_mac(self): - self._test_get_vif_port_by_id_with_data(ofport=1) - - def test_get_vif_by_port_id_with_no_data(self): - self.assertIsNone(self._test_get_vif_port_by_id('whatever', [])) - - def test_get_vif_by_port_id_different_bridge(self): - external_ids = [["iface-id", "tap99id"], - ["iface-status", "active"]] - data = [[["map", external_ids], "tap99", 1]] - self.assertIsNone(self._test_get_vif_port_by_id('tap99id', data, - "br-ext")) - - def test_ofctl_arg_supported(self): - with mock.patch('neutron.common.utils.get_random_string') as utils: - utils.return_value = 'test' - supported = ovs_lib.ofctl_arg_supported(self.root_helper, 'cmd', - ['args']) - self.execute.assert_has_calls([ - mock.call(['ovs-vsctl', self.TO, '--', '--if-exists', 'del-br', - 'br-test-test'], root_helper=self.root_helper), - mock.call(['ovs-vsctl', self.TO, '--', '--may-exist', 'add-br', - 'br-test-test'], root_helper=self.root_helper), - mock.call(['ovs-ofctl', 'cmd', 'br-test-test', 'args'], - root_helper=self.root_helper), - mock.call(['ovs-vsctl', self.TO, '--', '--if-exists', 'del-br', - 'br-test-test'], root_helper=self.root_helper) - ]) - self.assertTrue(supported) - - self.execute.side_effect = Exception - supported = ovs_lib.ofctl_arg_supported(self.root_helper, 'cmd', - ['args']) - self.execute.assert_has_calls([ - mock.call(['ovs-vsctl', self.TO, '--', '--if-exists', 'del-br', - 'br-test-test'], root_helper=self.root_helper), - mock.call(['ovs-vsctl', self.TO, '--', '--may-exist', 'add-br', - 'br-test-test'], root_helper=self.root_helper), - mock.call(['ovs-ofctl', 'cmd', 'br-test-test', 'args'], - root_helper=self.root_helper), - mock.call(['ovs-vsctl', self.TO, '--', '--if-exists', 'del-br', - 'br-test-test'], root_helper=self.root_helper) - ]) - self.assertFalse(supported) diff --git a/neutron/tests/unit/agent/linux/test_ovsdb_monitor.py b/neutron/tests/unit/agent/linux/test_ovsdb_monitor.py deleted file mode 100644 index ec37f83aa..000000000 --- a/neutron/tests/unit/agent/linux/test_ovsdb_monitor.py +++ /dev/null @@ -1,105 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc. -# -# 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 eventlet.event -import mock - -from neutron.agent.linux import ovsdb_monitor -from neutron.tests import base - - -class TestOvsdbMonitor(base.BaseTestCase): - - def setUp(self): - super(TestOvsdbMonitor, self).setUp() - self.root_helper = 'sudo' - self.monitor = ovsdb_monitor.OvsdbMonitor('Interface', - root_helper=self.root_helper) - - def read_output_queues_and_returns_result(self, output_type, output): - with mock.patch.object(self.monitor, '_process') as mock_process: - with mock.patch.object(mock_process, output_type) as mock_file: - with mock.patch.object(mock_file, 'readline') as mock_readline: - mock_readline.return_value = output - func = getattr(self.monitor, - '_read_%s' % output_type, - None) - return func() - - def test__read_stdout_returns_none_for_empty_read(self): - result = self.read_output_queues_and_returns_result('stdout', '') - self.assertIsNone(result) - - def test__read_stdout_queues_normal_output_to_stdout_queue(self): - output = 'foo' - result = self.read_output_queues_and_returns_result('stdout', output) - self.assertEqual(result, output) - self.assertEqual(self.monitor._stdout_lines.get_nowait(), output) - - def test__read_stderr_returns_none(self): - result = self.read_output_queues_and_returns_result('stderr', '') - self.assertIsNone(result) - - -class TestSimpleInterfaceMonitor(base.BaseTestCase): - - def setUp(self): - super(TestSimpleInterfaceMonitor, self).setUp() - self.root_helper = 'sudo' - self.monitor = ovsdb_monitor.SimpleInterfaceMonitor( - root_helper=self.root_helper) - - def test_is_active_is_false_by_default(self): - self.assertFalse(self.monitor.is_active) - - def test_is_active_can_be_true(self): - self.monitor.data_received = True - self.monitor._kill_event = eventlet.event.Event() - self.assertTrue(self.monitor.is_active) - - def test_has_updates_is_true_by_default(self): - self.assertTrue(self.monitor.has_updates) - - def test_has_updates_is_false_if_active_with_no_output(self): - target = ('neutron.agent.linux.ovsdb_monitor.SimpleInterfaceMonitor' - '.is_active') - with mock.patch(target, - new_callable=mock.PropertyMock(return_value=True)): - self.assertFalse(self.monitor.has_updates) - - def test__kill_sets_data_received_to_false(self): - self.monitor.data_received = True - with mock.patch( - 'neutron.agent.linux.ovsdb_monitor.OvsdbMonitor._kill'): - self.monitor._kill() - self.assertFalse(self.monitor.data_received) - - def test__read_stdout_sets_data_received_and_returns_output(self): - output = 'foo' - with mock.patch( - 'neutron.agent.linux.ovsdb_monitor.OvsdbMonitor._read_stdout', - return_value=output): - result = self.monitor._read_stdout() - self.assertTrue(self.monitor.data_received) - self.assertEqual(result, output) - - def test__read_stdout_does_not_set_data_received_for_empty_ouput(self): - output = None - with mock.patch( - 'neutron.agent.linux.ovsdb_monitor.OvsdbMonitor._read_stdout', - return_value=output): - self.monitor._read_stdout() - self.assertFalse(self.monitor.data_received) diff --git a/neutron/tests/unit/agent/linux/test_polling.py b/neutron/tests/unit/agent/linux/test_polling.py deleted file mode 100644 index e288654c2..000000000 --- a/neutron/tests/unit/agent/linux/test_polling.py +++ /dev/null @@ -1,116 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Red Hat, Inc. -# -# 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 neutron.agent.linux import polling -from neutron.tests import base - - -class TestGetPollingManager(base.BaseTestCase): - - def test_return_always_poll_by_default(self): - with polling.get_polling_manager() as pm: - self.assertEqual(pm.__class__, polling.AlwaysPoll) - - def test_manage_polling_minimizer(self): - mock_target = 'neutron.agent.linux.polling.InterfacePollingMinimizer' - with mock.patch('%s.start' % mock_target) as mock_start: - with mock.patch('%s.stop' % mock_target) as mock_stop: - with polling.get_polling_manager(minimize_polling=True, - root_helper='test') as pm: - self.assertEqual(pm._monitor.root_helper, 'test') - self.assertEqual(pm.__class__, - polling.InterfacePollingMinimizer) - mock_stop.assert_has_calls(mock.call()) - mock_start.assert_has_calls(mock.call()) - - -class TestBasePollingManager(base.BaseTestCase): - - def setUp(self): - super(TestBasePollingManager, self).setUp() - self.pm = polling.BasePollingManager() - - def test_force_polling_sets_interval_attribute(self): - self.assertFalse(self.pm._force_polling) - self.pm.force_polling() - self.assertTrue(self.pm._force_polling) - - def test_polling_completed_sets_interval_attribute(self): - self.pm._polling_completed = False - self.pm.polling_completed() - self.assertTrue(self.pm._polling_completed) - - def mock_is_polling_required(self, return_value): - return mock.patch.object(self.pm, '_is_polling_required', - return_value=return_value) - - def test_is_polling_required_returns_true_when_forced(self): - with self.mock_is_polling_required(False): - self.pm.force_polling() - self.assertTrue(self.pm.is_polling_required) - self.assertFalse(self.pm._force_polling) - - def test_is_polling_required_returns_true_when_polling_not_completed(self): - with self.mock_is_polling_required(False): - self.pm._polling_completed = False - self.assertTrue(self.pm.is_polling_required) - - def test_is_polling_required_returns_true_when_updates_are_present(self): - with self.mock_is_polling_required(True): - self.assertTrue(self.pm.is_polling_required) - self.assertFalse(self.pm._polling_completed) - - def test_is_polling_required_returns_false_for_no_updates(self): - with self.mock_is_polling_required(False): - self.assertFalse(self.pm.is_polling_required) - - -class TestAlwaysPoll(base.BaseTestCase): - - def test_is_polling_required_always_returns_true(self): - pm = polling.AlwaysPoll() - self.assertTrue(pm.is_polling_required) - - -class TestInterfacePollingMinimizer(base.BaseTestCase): - - def setUp(self): - super(TestInterfacePollingMinimizer, self).setUp() - self.pm = polling.InterfacePollingMinimizer() - - def test_start_calls_monitor_start(self): - with mock.patch.object(self.pm._monitor, 'start') as mock_start: - self.pm.start() - mock_start.assert_called_with() - - def test_stop_calls_monitor_stop(self): - with mock.patch.object(self.pm._monitor, 'stop') as mock_stop: - self.pm.stop() - mock_stop.assert_called_with() - - def mock_has_updates(self, return_value): - target = ('neutron.agent.linux.ovsdb_monitor.SimpleInterfaceMonitor' - '.has_updates') - return mock.patch( - target, - new_callable=mock.PropertyMock(return_value=return_value), - ) - - def test__is_polling_required_returns_when_updates_are_present(self): - with self.mock_has_updates(True): - self.assertTrue(self.pm._is_polling_required()) diff --git a/neutron/tests/unit/api/__init__.py b/neutron/tests/unit/api/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/api/rpc/__init__.py b/neutron/tests/unit/api/rpc/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/api/rpc/agentnotifiers/__init__.py b/neutron/tests/unit/api/rpc/agentnotifiers/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/api/rpc/agentnotifiers/test_dhcp_rpc_agent_api.py b/neutron/tests/unit/api/rpc/agentnotifiers/test_dhcp_rpc_agent_api.py deleted file mode 100644 index 5d29f6cbd..000000000 --- a/neutron/tests/unit/api/rpc/agentnotifiers/test_dhcp_rpc_agent_api.py +++ /dev/null @@ -1,154 +0,0 @@ -# Copyright (c) 2013 Red Hat, Inc. -# -# 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 datetime -import mock - -from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api -from neutron.common import utils -from neutron.db import agents_db -from neutron.openstack.common import timeutils -from neutron.tests import base - - -class TestDhcpAgentNotifyAPI(base.BaseTestCase): - - def setUp(self): - super(TestDhcpAgentNotifyAPI, self).setUp() - self.notifier = ( - dhcp_rpc_agent_api.DhcpAgentNotifyAPI(plugin=mock.Mock())) - - mock_util_p = mock.patch.object(utils, 'is_extension_supported') - mock_log_p = mock.patch.object(dhcp_rpc_agent_api, 'LOG') - mock_fanout_p = mock.patch.object(self.notifier, '_fanout_message') - mock_cast_p = mock.patch.object(self.notifier, '_cast_message') - self.mock_util = mock_util_p.start() - self.mock_log = mock_log_p.start() - self.mock_fanout = mock_fanout_p.start() - self.mock_cast = mock_cast_p.start() - - def _test__schedule_network(self, network, - new_agents=None, existing_agents=None, - expected_casts=0, expected_warnings=0): - self.notifier.plugin.schedule_network.return_value = new_agents - agents = self.notifier._schedule_network( - mock.ANY, network, existing_agents) - if new_agents is None: - new_agents = [] - self.assertEqual(new_agents + existing_agents, agents) - self.assertEqual(expected_casts, self.mock_cast.call_count) - self.assertEqual(expected_warnings, self.mock_log.warn.call_count) - - def test__schedule_network(self): - agent = agents_db.Agent() - agent.admin_state_up = True - agent.heartbeat_timestamp = timeutils.utcnow() - network = {'id': 'foo_net_id'} - self._test__schedule_network(network, - new_agents=[agent], existing_agents=[], - expected_casts=1, expected_warnings=0) - - def test__schedule_network_no_existing_agents(self): - agent = agents_db.Agent() - agent.admin_state_up = True - agent.heartbeat_timestamp = timeutils.utcnow() - network = {'id': 'foo_net_id'} - self._test__schedule_network(network, - new_agents=None, existing_agents=[agent], - expected_casts=0, expected_warnings=0) - - def test__schedule_network_no_new_agents(self): - network = {'id': 'foo_net_id'} - self._test__schedule_network(network, - new_agents=None, existing_agents=[], - expected_casts=0, expected_warnings=1) - - def _test__get_enabled_agents(self, network, - agents=None, port_count=0, - expected_warnings=0, expected_errors=0): - self.notifier.plugin.get_ports_count.return_value = port_count - enabled_agents = self.notifier._get_enabled_agents( - mock.ANY, network, agents, mock.ANY, mock.ANY) - self.assertEqual(agents, enabled_agents) - self.assertEqual(expected_warnings, self.mock_log.warn.call_count) - self.assertEqual(expected_errors, self.mock_log.error.call_count) - - def test__get_enabled_agents(self): - agent = agents_db.Agent() - agent.admin_state_up = True - agent.heartbeat_timestamp = timeutils.utcnow() - network = {'id': 'foo_network_id'} - self._test__get_enabled_agents(network, agents=[agent]) - - def test__get_enabled_agents_with_inactive_ones(self): - agent1 = agents_db.Agent() - agent1.admin_state_up = True - agent1.heartbeat_timestamp = timeutils.utcnow() - agent2 = agents_db.Agent() - agent2.admin_state_up = True - # This is effectively an inactive agent - agent2.heartbeat_timestamp = datetime.datetime(2000, 1, 1, 0, 0) - network = {'id': 'foo_network_id'} - self._test__get_enabled_agents(network, - agents=[agent1, agent2], - expected_warnings=1, expected_errors=0) - - def test__get_enabled_agents_with_notification_required(self): - network = {'id': 'foo_network_id', 'subnets': ['foo_subnet_id']} - self._test__get_enabled_agents(network, [], port_count=20, - expected_warnings=0, expected_errors=1) - - def test__notify_agents_fanout_required(self): - self.notifier._notify_agents(mock.ANY, - 'network_delete_end', - mock.ANY, 'foo_network_id') - self.assertEqual(1, self.mock_fanout.call_count) - - def _test__notify_agents(self, method, - expected_scheduling=0, expected_casts=0): - with mock.patch.object(self.notifier, '_schedule_network') as f: - with mock.patch.object(self.notifier, '_get_enabled_agents') as g: - agent = agents_db.Agent() - agent.admin_state_up = True - agent.heartbeat_timestamp = timeutils.utcnow() - g.return_value = [agent] - self.notifier._notify_agents(mock.Mock(), method, - mock.ANY, 'foo_network_id') - self.assertEqual(expected_scheduling, f.call_count) - self.assertEqual(expected_casts, self.mock_cast.call_count) - - def test__notify_agents_cast_required_with_scheduling(self): - self._test__notify_agents('port_create_end', - expected_scheduling=1, expected_casts=1) - - def test__notify_agents_cast_required_wo_scheduling_on_port_update(self): - self._test__notify_agents('port_update_end', - expected_scheduling=0, expected_casts=1) - - def test__notify_agents_cast_required_wo_scheduling_on_subnet_create(self): - self._test__notify_agents('subnet_create_end', - expected_scheduling=0, expected_casts=1) - - def test__notify_agents_no_action(self): - self._test__notify_agents('network_create_end', - expected_scheduling=0, expected_casts=0) - - def test__fanout_message(self): - self.notifier._fanout_message(mock.ANY, mock.ANY, mock.ANY) - self.assertEqual(1, self.mock_fanout.call_count) - - def test__cast_message(self): - self.notifier._cast_message(mock.ANY, mock.ANY, mock.ANY) - self.assertEqual(1, self.mock_cast.call_count) diff --git a/neutron/tests/unit/bigswitch/__init__.py b/neutron/tests/unit/bigswitch/__init__.py deleted file mode 100644 index 7e503debd..000000000 --- a/neutron/tests/unit/bigswitch/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/bigswitch/etc/restproxy.ini.test b/neutron/tests/unit/bigswitch/etc/restproxy.ini.test deleted file mode 100644 index 8df78a6eb..000000000 --- a/neutron/tests/unit/bigswitch/etc/restproxy.ini.test +++ /dev/null @@ -1,44 +0,0 @@ -# Test config file for quantum-proxy-plugin. - -[database] -# This line MUST be changed to actually run the plugin. -# Example: -# connection = mysql://root:pass@127.0.0.1:3306/restproxy_quantum -# Replace 127.0.0.1 above with the IP address of the database used by the -# main quantum server. (Leave it as is if the database runs on this host.) -connection = sqlite:// -# Database reconnection retry times - in event connectivity is lost -# set to -1 implies an infinite retry count -# max_retries = 10 -# Database reconnection interval in seconds - in event connectivity is lost -retry_interval = 2 - -[restproxy] -# All configuration for this plugin is in section '[restproxy]' -# -# The following parameters are supported: -# servers : [,]* (Error if not set) -# serverauth : (default: no auth) -# serverssl : True | False (default: False) -# -servers=localhost:9000,localhost:8899 -serverssl=False -#serverauth=username:password - -[nova] -# Specify the VIF_TYPE that will be controlled on the Nova compute instances -# options: ivs or ovs -# default: ovs -vif_type = ovs -# Overrides for vif types based on nova compute node host IDs -# Comma separated list of host IDs to fix to a specific VIF type -node_override_vif_ivs = ivshost - -[router] -# Specify the default router rules installed in newly created tenant routers -# Specify multiple times for multiple rules -# Use an * to specify default for all tenants -# Default is any any allow for all tenants -#tenant_default_router_rule=*:any:any:permit -# Maximum number of rules that a single router may have -max_router_rules=200 diff --git a/neutron/tests/unit/bigswitch/etc/ssl/ca_certs/README b/neutron/tests/unit/bigswitch/etc/ssl/ca_certs/README deleted file mode 100644 index 91779e39d..000000000 --- a/neutron/tests/unit/bigswitch/etc/ssl/ca_certs/README +++ /dev/null @@ -1,2 +0,0 @@ -ca_certs directory for SSL unit tests -No files will be generated here, but it should exist for the tests diff --git a/neutron/tests/unit/bigswitch/etc/ssl/combined/README b/neutron/tests/unit/bigswitch/etc/ssl/combined/README deleted file mode 100644 index 9f9922fd5..000000000 --- a/neutron/tests/unit/bigswitch/etc/ssl/combined/README +++ /dev/null @@ -1,2 +0,0 @@ -combined certificates directory for SSL unit tests -No files will be created here, but it should exist for the tests diff --git a/neutron/tests/unit/bigswitch/etc/ssl/host_certs/README b/neutron/tests/unit/bigswitch/etc/ssl/host_certs/README deleted file mode 100644 index 0eaec67ce..000000000 --- a/neutron/tests/unit/bigswitch/etc/ssl/host_certs/README +++ /dev/null @@ -1,2 +0,0 @@ -host_certs directory for SSL unit tests -No files will be created here, but it should exist for the tests diff --git a/neutron/tests/unit/bigswitch/fake_server.py b/neutron/tests/unit/bigswitch/fake_server.py deleted file mode 100644 index 3db3cc3ed..000000000 --- a/neutron/tests/unit/bigswitch/fake_server.py +++ /dev/null @@ -1,185 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Big Switch Networks, Inc. All rights reserved. -# -# 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. -# -# @author: Kevin Benton, -# - -from neutron.openstack.common import jsonutils as json -from neutron.openstack.common import log as logging -from neutron.plugins.bigswitch import servermanager - -LOG = logging.getLogger(__name__) - - -class HTTPResponseMock(): - status = 200 - reason = 'OK' - - def __init__(self, sock, debuglevel=0, strict=0, method=None, - buffering=False): - pass - - def read(self): - return "{'status': '200 OK'}" - - def getheader(self, header): - return None - - -class HTTPResponseMock404(HTTPResponseMock): - status = 404 - reason = 'Not Found' - - def read(self): - return "{'status': '%s 404 Not Found'}" % servermanager.NXNETWORK - - -class HTTPResponseMock500(HTTPResponseMock): - status = 500 - reason = 'Internal Server Error' - - def __init__(self, sock, debuglevel=0, strict=0, method=None, - buffering=False, errmsg='500 Internal Server Error'): - self.errmsg = errmsg - - def read(self): - return "{'status': '%s'}" % self.errmsg - - -class HTTPConnectionMock(object): - - def __init__(self, server, port, timeout): - self.response = None - self.broken = False - # Port 9000 is the broken server - if port == 9000: - self.broken = True - errmsg = "This server is broken, please try another" - self.response = HTTPResponseMock500(None, errmsg=errmsg) - - def request(self, action, uri, body, headers): - LOG.debug(_("Request: action=%(action)s, uri=%(uri)r, " - "body=%(body)s, headers=%(headers)s"), - {'action': action, 'uri': uri, - 'body': body, 'headers': headers}) - if self.broken and "ExceptOnBadServer" in uri: - raise Exception("Broken server got an unexpected request") - if self.response: - return - - # detachment may return 404 and plugin shouldn't die - if uri.endswith('attachment') and action == 'DELETE': - self.response = HTTPResponseMock404(None) - else: - self.response = HTTPResponseMock(None) - - # Port creations/updates must contain binding information - if ('port' in uri and 'attachment' not in uri - and 'binding' not in body and action in ('POST', 'PUT')): - errmsg = "Port binding info missing in port request '%s'" % body - self.response = HTTPResponseMock500(None, errmsg=errmsg) - return - - return - - def getresponse(self): - return self.response - - def close(self): - pass - - -class HTTPConnectionMock404(HTTPConnectionMock): - - def __init__(self, server, port, timeout): - self.response = HTTPResponseMock404(None) - self.broken = True - - -class HTTPConnectionMock500(HTTPConnectionMock): - - def __init__(self, server, port, timeout): - self.response = HTTPResponseMock500(None) - self.broken = True - - -class VerifyMultiTenantFloatingIP(HTTPConnectionMock): - - def request(self, action, uri, body, headers): - # Only handle network update requests - if 'network' in uri and 'tenant' in uri and 'ports' not in uri: - req = json.loads(body) - if 'network' not in req or 'floatingips' not in req['network']: - msg = _("No floating IPs in request" - "uri=%(uri)s, body=%(body)s") % {'uri': uri, - 'body': body} - raise Exception(msg) - distinct_tenants = [] - for flip in req['network']['floatingips']: - if flip['tenant_id'] not in distinct_tenants: - distinct_tenants.append(flip['tenant_id']) - if len(distinct_tenants) < 2: - msg = _("Expected floating IPs from multiple tenants." - "uri=%(uri)s, body=%(body)s") % {'uri': uri, - 'body': body} - raise Exception(msg) - super(VerifyMultiTenantFloatingIP, - self).request(action, uri, body, headers) - - -class HTTPSMockBase(HTTPConnectionMock): - expected_cert = '' - combined_cert = None - - def __init__(self, host, port=None, key_file=None, cert_file=None, - strict=None, timeout=None, source_address=None): - self.host = host - super(HTTPSMockBase, self).__init__(host, port, timeout) - - def request(self, method, url, body=None, headers={}): - self.connect() - super(HTTPSMockBase, self).request(method, url, body, headers) - - -class HTTPSNoValidation(HTTPSMockBase): - - def connect(self): - if self.combined_cert: - raise Exception('combined_cert set on NoValidation') - - -class HTTPSCAValidation(HTTPSMockBase): - expected_cert = 'DUMMYCERTIFICATEAUTHORITY' - - def connect(self): - contents = get_cert_contents(self.combined_cert) - if self.expected_cert not in contents: - raise Exception('No dummy CA cert in cert_file') - - -class HTTPSHostValidation(HTTPSMockBase): - expected_cert = 'DUMMYCERTFORHOST%s' - - def connect(self): - contents = get_cert_contents(self.combined_cert) - expected = self.expected_cert % self.host - if expected not in contents: - raise Exception(_('No host cert for %(server)s in cert %(cert)s'), - {'server': self.host, 'cert': contents}) - - -def get_cert_contents(path): - raise Exception('METHOD MUST BE MOCKED FOR TEST') diff --git a/neutron/tests/unit/bigswitch/test_agent_scheduler.py b/neutron/tests/unit/bigswitch/test_agent_scheduler.py deleted file mode 100644 index b8d5e3aae..000000000 --- a/neutron/tests/unit/bigswitch/test_agent_scheduler.py +++ /dev/null @@ -1,33 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2013 Big Switch Networks, Inc. -# -# 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. - - -from neutron.tests.unit.bigswitch import test_base -from neutron.tests.unit.openvswitch import test_agent_scheduler - - -class BigSwitchDhcpAgentNotifierTestCase( - test_agent_scheduler.OvsDhcpAgentNotifierTestCase, - test_base.BigSwitchTestBase): - - plugin_str = ('%s.NeutronRestProxyV2' % - test_base.RESTPROXY_PKG_PATH) - - def setUp(self): - self.setup_config_files() - self.setup_patches() - super(BigSwitchDhcpAgentNotifierTestCase, self).setUp() - self.startHttpPatch() diff --git a/neutron/tests/unit/bigswitch/test_base.py b/neutron/tests/unit/bigswitch/test_base.py deleted file mode 100644 index 6fc5580eb..000000000 --- a/neutron/tests/unit/bigswitch/test_base.py +++ /dev/null @@ -1,74 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2013 Big Switch Networks, Inc. -# All Rights Reserved. -# -# 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 os - -import mock -from oslo.config import cfg - -import neutron.common.test_lib as test_lib -from neutron.db import api as db -from neutron.plugins.bigswitch import config -from neutron.tests.unit.bigswitch import fake_server - -# REVISIT(kevinbenton): This needs to be imported here to create the -# portbindings table since it's not imported until function call time -# in the porttracker_db module, which will cause unit test failures when -# the unit tests are being run by testtools -from neutron.db import portbindings_db # noqa - -RESTPROXY_PKG_PATH = 'neutron.plugins.bigswitch.plugin' -NOTIFIER = 'neutron.plugins.bigswitch.plugin.AgentNotifierApi' -CERTFETCH = 'neutron.plugins.bigswitch.servermanager.ServerPool._fetch_cert' -SERVER_MANAGER = 'neutron.plugins.bigswitch.servermanager' -HTTPCON = 'neutron.plugins.bigswitch.servermanager.httplib.HTTPConnection' -SPAWN = 'neutron.plugins.bigswitch.plugin.eventlet.GreenPool.spawn_n' -CWATCH = SERVER_MANAGER + '.ServerPool._consistency_watchdog' - - -class BigSwitchTestBase(object): - - _plugin_name = ('%s.NeutronRestProxyV2' % RESTPROXY_PKG_PATH) - - def setup_config_files(self): - etc_path = os.path.join(os.path.dirname(__file__), 'etc') - test_lib.test_config['config_files'] = [os.path.join(etc_path, - 'restproxy.ini.test')] - self.addCleanup(cfg.CONF.reset) - config.register_config() - # Only try SSL on SSL tests - cfg.CONF.set_override('server_ssl', False, 'RESTPROXY') - cfg.CONF.set_override('ssl_cert_directory', - os.path.join(etc_path, 'ssl'), 'RESTPROXY') - # The mock interferes with HTTP(S) connection caching - cfg.CONF.set_override('cache_connections', False, 'RESTPROXY') - - def setup_patches(self): - self.plugin_notifier_p = mock.patch(NOTIFIER) - # prevent any greenthreads from spawning - self.spawn_p = mock.patch(SPAWN, new=lambda *args, **kwargs: None) - # prevent the consistency watchdog from starting - self.watch_p = mock.patch(CWATCH, new=lambda *args, **kwargs: None) - self.addCleanup(db.clear_db) - self.plugin_notifier_p.start() - self.spawn_p.start() - self.watch_p.start() - - def startHttpPatch(self): - self.httpPatch = mock.patch(HTTPCON, - new=fake_server.HTTPConnectionMock) - self.httpPatch.start() diff --git a/neutron/tests/unit/bigswitch/test_capabilities.py b/neutron/tests/unit/bigswitch/test_capabilities.py deleted file mode 100644 index 89e4c5b72..000000000 --- a/neutron/tests/unit/bigswitch/test_capabilities.py +++ /dev/null @@ -1,84 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2014 Big Switch Networks, Inc. -# All Rights Reserved. -# -# 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. -# -# @author Kevin Benton - -import contextlib -import mock - -from neutron.tests.unit.bigswitch import test_router_db - -PLUGIN = 'neutron.plugins.bigswitch.plugin' -SERVERMANAGER = PLUGIN + '.servermanager' -SERVERPOOL = SERVERMANAGER + '.ServerPool' -SERVERRESTCALL = SERVERMANAGER + '.ServerProxy.rest_call' -HTTPCON = SERVERMANAGER + '.httplib.HTTPConnection' - - -class CapabilitiesTests(test_router_db.RouterDBTestBase): - - def test_floating_ip_capability(self): - with contextlib.nested( - mock.patch(SERVERRESTCALL, - return_value=(200, None, '["floatingip"]', None)), - mock.patch(SERVERPOOL + '.rest_create_floatingip', - return_value=(200, None, None, None)), - mock.patch(SERVERPOOL + '.rest_delete_floatingip', - return_value=(200, None, None, None)) - ) as (mock_rest, mock_create, mock_delete): - with self.floatingip_with_assoc() as fip: - pass - mock_create.assert_has_calls( - [mock.call(fip['floatingip']['tenant_id'], fip['floatingip'])] - ) - mock_delete.assert_has_calls( - [mock.call(fip['floatingip']['tenant_id'], - fip['floatingip']['id'])] - ) - - def test_floating_ip_capability_neg(self): - with contextlib.nested( - mock.patch(SERVERRESTCALL, - return_value=(200, None, '[""]', None)), - mock.patch(SERVERPOOL + '.rest_update_network', - return_value=(200, None, None, None)) - ) as (mock_rest, mock_netupdate): - with self.floatingip_with_assoc() as fip: - pass - updates = [call[0][2]['floatingips'] - for call in mock_netupdate.call_args_list] - all_floats = [f['floating_ip_address'] - for floats in updates for f in floats] - self.assertIn(fip['floatingip']['floating_ip_address'], all_floats) - - def test_keep_alive_capability(self): - with mock.patch( - SERVERRESTCALL, return_value=(200, None, '["keep-alive"]', None) - ): - # perform a task to cause capabilities to be retrieved - with self.floatingip_with_assoc(): - pass - # stop default HTTP patch since we need a magicmock - self.httpPatch.stop() - # now mock HTTP class instead of REST so we can see headers - conmock = mock.patch(HTTPCON).start() - instance = conmock.return_value - instance.getresponse.return_value.getheader.return_value = 'HASHHEADER' - with self.network(): - callheaders = instance.request.mock_calls[0][1][3] - self.assertIn('Connection', callheaders) - self.assertEqual(callheaders['Connection'], 'keep-alive') diff --git a/neutron/tests/unit/bigswitch/test_restproxy_agent.py b/neutron/tests/unit/bigswitch/test_restproxy_agent.py deleted file mode 100644 index 4c961df7d..000000000 --- a/neutron/tests/unit/bigswitch/test_restproxy_agent.py +++ /dev/null @@ -1,188 +0,0 @@ -# Copyright 2014 Big Switch Networks, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Kevin Benton, Big Switch Networks - -import contextlib - -import mock - -from neutron.openstack.common import importutils -from neutron.tests import base - -OVSBRIDGE = 'neutron.agent.linux.ovs_lib.OVSBridge' -PLUGINAPI = 'neutron.plugins.bigswitch.agent.restproxy_agent.PluginApi' -CONTEXT = 'neutron.context' -CONSUMERCREATE = 'neutron.agent.rpc.create_consumers' -SGRPC = 'neutron.agent.securitygroups_rpc' -SGAGENT = 'neutron.plugins.bigswitch.agent.restproxy_agent.SecurityGroupAgent' -AGENTMOD = 'neutron.plugins.bigswitch.agent.restproxy_agent' -NEUTRONCFG = 'neutron.common.config' -PLCONFIG = 'neutron.plugins.bigswitch.config' - - -class BaseAgentTestCase(base.BaseTestCase): - - def setUp(self): - super(BaseAgentTestCase, self).setUp() - self.mod_agent = importutils.import_module(AGENTMOD) - - -class TestRestProxyAgentOVS(BaseAgentTestCase): - def setUp(self): - super(TestRestProxyAgentOVS, self).setUp() - self.plapi = mock.patch(PLUGINAPI).start() - self.ovsbridge = mock.patch(OVSBRIDGE).start() - self.context = mock.patch(CONTEXT).start() - self.rpc = mock.patch(CONSUMERCREATE).start() - self.sg_rpc = mock.patch(SGRPC).start() - self.sg_agent = mock.patch(SGAGENT).start() - - def mock_agent(self): - mock_context = mock.Mock(return_value='abc') - self.context.get_admin_context_without_session = mock_context - return self.mod_agent.RestProxyAgent('int-br', 2, 'helper') - - def mock_port_update(self, **kwargs): - agent = self.mock_agent() - agent.port_update(mock.Mock(), **kwargs) - - def test_port_update(self): - port = {'id': 1, 'security_groups': 'default'} - - with mock.patch.object(self.ovsbridge.return_value, - 'get_vif_port_by_id', - return_value=1) as get_vif: - self.mock_port_update(port=port) - - get_vif.assert_called_once_with(1) - self.sg_agent.assert_has_calls([ - mock.call().refresh_firewall() - ]) - - def test_port_update_not_vifport(self): - port = {'id': 1, 'security_groups': 'default'} - - with mock.patch.object(self.ovsbridge.return_value, - 'get_vif_port_by_id', - return_value=0) as get_vif: - self.mock_port_update(port=port) - - get_vif.assert_called_once_with(1) - self.assertFalse(self.sg_agent.return_value.refresh_firewall.called) - - def test_port_update_without_secgroup(self): - port = {'id': 1} - - with mock.patch.object(self.ovsbridge.return_value, - 'get_vif_port_by_id', - return_value=1) as get_vif: - self.mock_port_update(port=port) - - get_vif.assert_called_once_with(1) - self.assertFalse(self.sg_agent.return_value.refresh_firewall.called) - - def mock_update_ports(self, vif_port_set=None, registered_ports=None): - with mock.patch.object(self.ovsbridge.return_value, - 'get_vif_port_set', - return_value=vif_port_set): - agent = self.mock_agent() - return agent._update_ports(registered_ports) - - def test_update_ports_unchanged(self): - self.assertIsNone(self.mock_update_ports()) - - def test_update_ports_changed(self): - vif_port_set = set([1, 3]) - registered_ports = set([1, 2]) - expected = dict(current=vif_port_set, - added=set([3]), - removed=set([2])) - - actual = self.mock_update_ports(vif_port_set, registered_ports) - - self.assertEqual(expected, actual) - - def mock_process_devices_filter(self, port_info): - agent = self.mock_agent() - agent._process_devices_filter(port_info) - - def test_process_devices_filter_add(self): - port_info = {'added': 1} - - self.mock_process_devices_filter(port_info) - - self.sg_agent.assert_has_calls([ - mock.call().prepare_devices_filter(1) - ]) - - def test_process_devices_filter_remove(self): - port_info = {'removed': 2} - - self.mock_process_devices_filter(port_info) - - self.sg_agent.assert_has_calls([ - mock.call().remove_devices_filter(2) - ]) - - def test_process_devices_filter_both(self): - port_info = {'added': 1, 'removed': 2} - - self.mock_process_devices_filter(port_info) - - self.sg_agent.assert_has_calls([ - mock.call().prepare_devices_filter(1), - mock.call().remove_devices_filter(2) - ]) - - def test_process_devices_filter_none(self): - port_info = {} - - self.mock_process_devices_filter(port_info) - - self.assertFalse( - self.sg_agent.return_value.prepare_devices_filter.called) - self.assertFalse( - self.sg_agent.return_value.remove_devices_filter.called) - - -class TestRestProxyAgent(BaseAgentTestCase): - def mock_main(self): - cfg_attrs = {'CONF.RESTPROXYAGENT.integration_bridge': 'integ_br', - 'CONF.RESTPROXYAGENT.polling_interval': 5, - 'CONF.RESTPROXYAGENT.virtual_switch_type': 'ovs', - 'CONF.AGENT.root_helper': 'helper'} - with contextlib.nested( - mock.patch(AGENTMOD + '.cfg', **cfg_attrs), - mock.patch(AGENTMOD + '.config.init'), - mock.patch(NEUTRONCFG), - mock.patch(PLCONFIG), - ) as (mock_conf, mock_init, mock_log_conf, mock_pluginconf): - self.mod_agent.main() - - mock_log_conf.assert_has_calls([ - mock.call(mock_conf), - ]) - - def test_main(self): - agent_attrs = {'daemon_loop.side_effect': SystemExit(0)} - with mock.patch(AGENTMOD + '.RestProxyAgent', - **agent_attrs) as mock_agent: - self.assertRaises(SystemExit, self.mock_main) - - mock_agent.assert_has_calls([ - mock.call('integ_br', 5, 'helper', 'ovs'), - mock.call().daemon_loop() - ]) diff --git a/neutron/tests/unit/bigswitch/test_restproxy_plugin.py b/neutron/tests/unit/bigswitch/test_restproxy_plugin.py deleted file mode 100644 index df3aeb030..000000000 --- a/neutron/tests/unit/bigswitch/test_restproxy_plugin.py +++ /dev/null @@ -1,316 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2012 Big Switch Networks, Inc. -# All Rights Reserved. -# -# 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 contextlib -import mock -from oslo.config import cfg -import webob.exc - -from neutron.common import constants -from neutron import context -from neutron.extensions import portbindings -from neutron import manager -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit.bigswitch import fake_server -from neutron.tests.unit.bigswitch import test_base -from neutron.tests.unit import test_api_v2 -import neutron.tests.unit.test_db_plugin as test_plugin -import neutron.tests.unit.test_extension_allowedaddresspairs as test_addr_pair - -patch = mock.patch -HTTPCON = 'neutron.plugins.bigswitch.servermanager.httplib.HTTPConnection' - - -class BigSwitchProxyPluginV2TestCase(test_base.BigSwitchTestBase, - test_plugin.NeutronDbPluginV2TestCase): - - def setUp(self, plugin_name=None): - if hasattr(self, 'HAS_PORT_FILTER'): - cfg.CONF.set_override( - 'enable_security_group', self.HAS_PORT_FILTER, 'SECURITYGROUP') - self.setup_config_files() - self.setup_patches() - if plugin_name: - self._plugin_name = plugin_name - super(BigSwitchProxyPluginV2TestCase, - self).setUp(self._plugin_name) - self.port_create_status = 'BUILD' - self.startHttpPatch() - - -class TestBigSwitchProxyBasicGet(test_plugin.TestBasicGet, - BigSwitchProxyPluginV2TestCase): - - pass - - -class TestBigSwitchProxyV2HTTPResponse(test_plugin.TestV2HTTPResponse, - BigSwitchProxyPluginV2TestCase): - - def test_failover_memory(self): - # first request causes failover so next shouldn't hit bad server - with self.network() as net: - kwargs = {'tenant_id': 'ExceptOnBadServer'} - with self.network(**kwargs) as net: - req = self.new_show_request('networks', net['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 200) - - -class TestBigSwitchProxyPortsV2(test_plugin.TestPortsV2, - BigSwitchProxyPluginV2TestCase, - test_bindings.PortBindingsTestCase): - - VIF_TYPE = portbindings.VIF_TYPE_OVS - HAS_PORT_FILTER = False - - def setUp(self, plugin_name=None): - super(TestBigSwitchProxyPortsV2, - self).setUp(self._plugin_name) - - def test_router_port_status_active(self): - # router ports screw up port auto-deletion so it has to be - # disabled for this test - with self.network(do_delete=False) as net: - with self.subnet(network=net, do_delete=False) as sub: - with self.port( - subnet=sub, - no_delete=True, - device_owner=constants.DEVICE_OWNER_ROUTER_INTF - ) as port: - # router ports should be immediately active - self.assertEqual(port['port']['status'], 'ACTIVE') - - def test_update_port_status_build(self): - # normal ports go into the pending build state for async creation - with self.port() as port: - self.assertEqual(port['port']['status'], 'BUILD') - self.assertEqual(self.port_create_status, 'BUILD') - - def _get_ports(self, netid): - return self.deserialize('json', - self._list_ports('json', netid=netid))['ports'] - - def test_rollback_for_port_create(self): - plugin = manager.NeutronManager.get_plugin() - with self.subnet() as s: - # stop normal patch - self.httpPatch.stop() - # allow thread spawns for this test - self.spawn_p.stop() - kwargs = {'device_id': 'somedevid'} - # put in a broken 'server' - httpPatch = patch(HTTPCON, new=fake_server.HTTPConnectionMock500) - httpPatch.start() - with self.port(subnet=s, **kwargs): - # wait for async port create request to finish - plugin.evpool.waitall() - # put good 'server' back in - httpPatch.stop() - self.httpPatch.start() - ports = self._get_ports(s['subnet']['network_id']) - #failure to create should result in port in error state - self.assertEqual(ports[0]['status'], 'ERROR') - - def test_rollback_for_port_update(self): - with self.network() as n: - with self.port(network_id=n['network']['id'], - device_id='66') as port: - port = self._get_ports(n['network']['id'])[0] - data = {'port': {'name': 'aNewName', 'device_id': '99'}} - # stop normal patch - self.httpPatch.stop() - with patch(HTTPCON, new=fake_server.HTTPConnectionMock500): - self.new_update_request( - 'ports', data, port['id']).get_response(self.api) - self.httpPatch.start() - uport = self._get_ports(n['network']['id'])[0] - # name should have stayed the same - self.assertEqual(port['name'], uport['name']) - - def test_rollback_for_port_delete(self): - with self.network() as n: - with self.port(network_id=n['network']['id'], - device_id='somedevid') as port: - # stop normal patch - self.httpPatch.stop() - with patch(HTTPCON, new=fake_server.HTTPConnectionMock500): - self._delete('ports', port['port']['id'], - expected_code= - webob.exc.HTTPInternalServerError.code) - self.httpPatch.start() - port = self._get_ports(n['network']['id'])[0] - self.assertEqual('BUILD', port['status']) - - def test_correct_shared_net_tenant_id(self): - # tenant_id in port requests should match network tenant_id instead - # of port tenant_id - def rest_port_op(self, ten_id, netid, port): - if ten_id != 'SHARED': - raise Exception('expecting tenant_id SHARED. got %s' % ten_id) - with self.network(tenant_id='SHARED', shared=True) as net: - with self.subnet(network=net) as sub: - pref = 'neutron.plugins.bigswitch.servermanager.ServerPool.%s' - tomock = [pref % 'rest_create_port', - pref % 'rest_update_port', - pref % 'rest_delete_port'] - patches = [patch(f, create=True, new=rest_port_op) - for f in tomock] - for restp in patches: - restp.start() - with self.port(subnet=sub, tenant_id='port-owner') as port: - data = {'port': {'binding:host_id': 'someotherhost', - 'device_id': 'override_dev'}} - req = self.new_update_request('ports', data, - port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 200) - - def test_create404_triggers_sync(self): - # allow async port thread for this patch - self.spawn_p.stop() - with contextlib.nested( - self.subnet(), - patch(HTTPCON, create=True, - new=fake_server.HTTPConnectionMock404), - patch(test_base.RESTPROXY_PKG_PATH - + '.NeutronRestProxyV2._send_all_data') - ) as (s, mock_http, mock_send_all): - with self.port(subnet=s, device_id='somedevid') as p: - # wait for the async port thread to finish - plugin = manager.NeutronManager.get_plugin() - plugin.evpool.waitall() - call = mock.call( - send_routers=True, send_ports=True, send_floating_ips=True, - triggered_by_tenant=p['port']['tenant_id'] - ) - mock_send_all.assert_has_calls([call]) - self.spawn_p.start() - - def test_port_vif_details_default(self): - kwargs = {'name': 'name', 'device_id': 'override_dev'} - with self.port(**kwargs) as port: - self.assertEqual(port['port']['binding:vif_type'], - portbindings.VIF_TYPE_OVS) - - def test_port_vif_details_override(self): - # ivshost is in the test config to override to IVS - kwargs = {'name': 'name', 'binding:host_id': 'ivshost', - 'device_id': 'override_dev'} - with self.port(**kwargs) as port: - self.assertEqual(port['port']['binding:vif_type'], - portbindings.VIF_TYPE_IVS) - kwargs = {'name': 'name2', 'binding:host_id': 'someotherhost', - 'device_id': 'other_dev'} - with self.port(**kwargs) as port: - self.assertEqual(port['port']['binding:vif_type'], self.VIF_TYPE) - - def test_port_move(self): - # ivshost is in the test config to override to IVS - kwargs = {'name': 'name', 'binding:host_id': 'ivshost', - 'device_id': 'override_dev'} - with self.port(**kwargs) as port: - data = {'port': {'binding:host_id': 'someotherhost', - 'device_id': 'override_dev'}} - req = self.new_update_request('ports', data, port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['port']['binding:vif_type'], self.VIF_TYPE) - - def _make_port(self, fmt, net_id, expected_res_status=None, arg_list=None, - **kwargs): - arg_list = arg_list or () - arg_list += ('binding:host_id', ) - res = self._create_port(fmt, net_id, expected_res_status, - arg_list, **kwargs) - # Things can go wrong - raise HTTP exc with res code only - # so it can be caught by unit tests - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - -class TestVifDifferentDefault(BigSwitchProxyPluginV2TestCase): - - def setup_config_files(self): - super(TestVifDifferentDefault, self).setup_config_files() - cfg.CONF.set_override('vif_type', 'ivs', 'NOVA') - - def test_default_viftype(self): - with self.port() as port: - self.assertEqual(port['port']['binding:vif_type'], 'ivs') - - -class TestBigSwitchProxyNetworksV2(test_plugin.TestNetworksV2, - BigSwitchProxyPluginV2TestCase): - - def _get_networks(self, tenant_id): - ctx = context.Context('', tenant_id) - return manager.NeutronManager.get_plugin().get_networks(ctx) - - def test_rollback_on_network_create(self): - tid = test_api_v2._uuid() - kwargs = {'tenant_id': tid} - self.httpPatch.stop() - with patch(HTTPCON, new=fake_server.HTTPConnectionMock500): - self._create_network('json', 'netname', True, **kwargs) - self.httpPatch.start() - self.assertFalse(self._get_networks(tid)) - - def test_rollback_on_network_update(self): - with self.network() as n: - data = {'network': {'name': 'aNewName'}} - self.httpPatch.stop() - with patch(HTTPCON, new=fake_server.HTTPConnectionMock500): - self.new_update_request( - 'networks', data, n['network']['id'] - ).get_response(self.api) - self.httpPatch.start() - updatedn = self._get_networks(n['network']['tenant_id'])[0] - # name should have stayed the same due to failure - self.assertEqual(n['network']['name'], updatedn['name']) - - def test_rollback_on_network_delete(self): - with self.network() as n: - self.httpPatch.stop() - with patch(HTTPCON, new=fake_server.HTTPConnectionMock500): - self._delete( - 'networks', n['network']['id'], - expected_code=webob.exc.HTTPInternalServerError.code) - self.httpPatch.start() - # network should still exist in db - self.assertEqual(n['network']['id'], - self._get_networks(n['network']['tenant_id'] - )[0]['id']) - - -class TestBigSwitchProxySubnetsV2(test_plugin.TestSubnetsV2, - BigSwitchProxyPluginV2TestCase): - - pass - - -class TestBigSwitchProxySync(BigSwitchProxyPluginV2TestCase): - - def test_send_data(self): - plugin_obj = manager.NeutronManager.get_plugin() - result = plugin_obj._send_all_data() - self.assertEqual(result[0], 200) - - -class TestBigSwitchAddressPairs(BigSwitchProxyPluginV2TestCase, - test_addr_pair.TestAllowedAddressPairs): - pass diff --git a/neutron/tests/unit/bigswitch/test_router_db.py b/neutron/tests/unit/bigswitch/test_router_db.py deleted file mode 100644 index fc82b727c..000000000 --- a/neutron/tests/unit/bigswitch/test_router_db.py +++ /dev/null @@ -1,554 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Big Switch Networks, Inc. All rights reserved. -# -# 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. -# -# Adapted from neutron.tests.unit.test_l3_plugin -# @author: Sumit Naiksatam, sumitnaiksatam@gmail.com -# - -import contextlib -import copy - -import mock -from oslo.config import cfg -from six import moves -from webob import exc - -from neutron.common import test_lib -from neutron import context -from neutron.extensions import l3 -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron.plugins.bigswitch.extensions import routerrule -from neutron.tests.unit.bigswitch import fake_server -from neutron.tests.unit.bigswitch import test_base -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_extension_extradhcpopts as test_extradhcp -from neutron.tests.unit import test_l3_plugin - - -HTTPCON = 'neutron.plugins.bigswitch.servermanager.httplib.HTTPConnection' -_uuid = uuidutils.generate_uuid - - -class RouterRulesTestExtensionManager(object): - - def get_resources(self): - l3.RESOURCE_ATTRIBUTE_MAP['routers'].update( - routerrule.EXTENDED_ATTRIBUTES_2_0['routers']) - return l3.L3.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class DHCPOptsTestCase(test_base.BigSwitchTestBase, - test_extradhcp.TestExtraDhcpOpt): - - def setUp(self, plugin=None): - self.setup_patches() - self.setup_config_files() - super(test_extradhcp.ExtraDhcpOptDBTestCase, - self).setUp(plugin=self._plugin_name) - self.startHttpPatch() - - -class RouterDBTestBase(test_base.BigSwitchTestBase, - test_l3_plugin.L3BaseForIntTests, - test_l3_plugin.L3NatTestCaseMixin): - - def setUp(self): - self.setup_patches() - self.setup_config_files() - ext_mgr = RouterRulesTestExtensionManager() - super(RouterDBTestBase, self).setUp(plugin=self._plugin_name, - ext_mgr=ext_mgr) - cfg.CONF.set_default('allow_overlapping_ips', False) - self.plugin_obj = manager.NeutronManager.get_plugin() - self.startHttpPatch() - - def tearDown(self): - super(RouterDBTestBase, self).tearDown() - del test_lib.test_config['config_files'] - - -class RouterDBTestCase(RouterDBTestBase, - test_l3_plugin.L3NatDBIntTestCase): - - def test_router_remove_router_interface_wrong_subnet_returns_400(self): - with self.router() as r: - with self.subnet() as s: - with self.subnet(cidr='10.0.10.0/24') as s1: - with self.port(subnet=s1, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - p['port']['id'], - exc.HTTPBadRequest.code) - #remove properly to clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_remove_router_interface_wrong_port_returns_404(self): - with self.router() as r: - with self.subnet() as s: - with self.port(subnet=s, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - # create another port for testing failure case - res = self._create_port('json', p['port']['network_id']) - p2 = self.deserialize('json', res) - self._router_interface_action('remove', - r['router']['id'], - None, - p2['port']['id'], - exc.HTTPNotFound.code) - # remove correct interface to cleanup - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - # remove extra port created - self._delete('ports', p2['port']['id']) - - def test_multi_tenant_flip_alllocation(self): - tenant1_id = _uuid() - tenant2_id = _uuid() - with contextlib.nested( - self.network(tenant_id=tenant1_id), - self.network(tenant_id=tenant2_id)) as (n1, n2): - with contextlib.nested( - self.subnet(network=n1, cidr='11.0.0.0/24'), - self.subnet(network=n2, cidr='12.0.0.0/24'), - self.subnet(cidr='13.0.0.0/24')) as (s1, s2, psub): - with contextlib.nested( - self.router(tenant_id=tenant1_id), - self.router(tenant_id=tenant2_id), - self.port(subnet=s1, tenant_id=tenant1_id), - self.port(subnet=s2, tenant_id=tenant2_id)) as (r1, r2, - p1, p2): - self._set_net_external(psub['subnet']['network_id']) - s1id = p1['port']['fixed_ips'][0]['subnet_id'] - s2id = p2['port']['fixed_ips'][0]['subnet_id'] - s1 = {'subnet': {'id': s1id}} - s2 = {'subnet': {'id': s2id}} - self._add_external_gateway_to_router( - r1['router']['id'], - psub['subnet']['network_id']) - self._add_external_gateway_to_router( - r2['router']['id'], - psub['subnet']['network_id']) - self._router_interface_action( - 'add', r1['router']['id'], - s1['subnet']['id'], None) - self._router_interface_action( - 'add', r2['router']['id'], - s2['subnet']['id'], None) - fl1 = self._make_floatingip_for_tenant_port( - net_id=psub['subnet']['network_id'], - port_id=p1['port']['id'], - tenant_id=tenant1_id) - self.httpPatch.stop() - multiFloatPatch = mock.patch( - HTTPCON, - new=fake_server.VerifyMultiTenantFloatingIP) - multiFloatPatch.start() - fl2 = self._make_floatingip_for_tenant_port( - net_id=psub['subnet']['network_id'], - port_id=p2['port']['id'], - tenant_id=tenant2_id) - multiFloatPatch.stop() - self.httpPatch.start() - self._delete('floatingips', fl1['floatingip']['id']) - self._delete('floatingips', fl2['floatingip']['id']) - self._router_interface_action( - 'remove', r1['router']['id'], - s1['subnet']['id'], None) - self._router_interface_action( - 'remove', r2['router']['id'], - s2['subnet']['id'], None) - - def _make_floatingip_for_tenant_port(self, net_id, port_id, tenant_id): - data = {'floatingip': {'floating_network_id': net_id, - 'tenant_id': tenant_id, - 'port_id': port_id}} - floatingip_req = self.new_create_request('floatingips', data, self.fmt) - res = floatingip_req.get_response(self.ext_api) - return self.deserialize(self.fmt, res) - - def test_floatingip_with_invalid_create_port(self): - self._test_floatingip_with_invalid_create_port( - 'neutron.plugins.bigswitch.plugin.NeutronRestProxyV2') - - def test_create_floatingip_no_ext_gateway_return_404(self): - with self.subnet(cidr='10.0.10.0/24') as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - with self.port() as private_port: - with self.router(): - res = self._create_floatingip( - 'json', - public_sub['subnet']['network_id'], - port_id=private_port['port']['id']) - self.assertEqual(res.status_int, exc.HTTPNotFound.code) - - def test_router_update_gateway(self): - with self.router() as r: - with self.subnet() as s1: - with self.subnet(cidr='10.0.10.0/24') as s2: - self._set_net_external(s1['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s1['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - net_id = (body['router'] - ['external_gateway_info']['network_id']) - self.assertEqual(net_id, s1['subnet']['network_id']) - self._set_net_external(s2['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s2['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - net_id = (body['router'] - ['external_gateway_info']['network_id']) - self.assertEqual(net_id, s2['subnet']['network_id']) - self._remove_external_gateway_from_router( - r['router']['id'], - s2['subnet']['network_id']) - - def test_router_add_interface_overlapped_cidr(self): - self.skipTest("Plugin does not support") - - def test_router_add_interface_overlapped_cidr_returns_400(self): - self.skipTest("Plugin does not support") - - def test_list_nets_external(self): - self.skipTest("Plugin does not support") - - def test_router_update_gateway_with_existed_floatingip(self): - with self.subnet(cidr='10.0.10.0/24') as subnet: - self._set_net_external(subnet['subnet']['network_id']) - with self.floatingip_with_assoc() as fip: - self._add_external_gateway_to_router( - fip['floatingip']['router_id'], - subnet['subnet']['network_id'], - expected_code=exc.HTTPConflict.code) - - def test_router_remove_interface_wrong_subnet_returns_400(self): - with self.router() as r: - with self.subnet(cidr='10.0.10.0/24') as s: - with self.port(no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - p['port']['id'], - exc.HTTPBadRequest.code) - #remove properly to clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_remove_interface_wrong_port_returns_404(self): - with self.router() as r: - with self.subnet(cidr='10.0.10.0/24'): - with self.port(no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - # create another port for testing failure case - res = self._create_port('json', p['port']['network_id']) - p2 = self.deserialize('json', res) - self._router_interface_action('remove', - r['router']['id'], - None, - p2['port']['id'], - exc.HTTPNotFound.code) - # remove correct interface to cleanup - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - # remove extra port created - self._delete('ports', p2['port']['id']) - - def test_send_data(self): - fmt = 'json' - plugin_obj = manager.NeutronManager.get_plugin() - - with self.router() as r: - r_id = r['router']['id'] - - with self.subnet(cidr='10.0.10.0/24') as s: - s_id = s['subnet']['id'] - - with self.router() as r1: - r1_id = r1['router']['id'] - body = self._router_interface_action('add', r_id, s_id, - None) - self.assertIn('port_id', body) - r_port_id = body['port_id'] - body = self._show('ports', r_port_id) - self.assertEqual(body['port']['device_id'], r_id) - - with self.subnet(cidr='10.0.20.0/24') as s1: - s1_id = s1['subnet']['id'] - body = self._router_interface_action('add', r1_id, - s1_id, None) - self.assertIn('port_id', body) - r1_port_id = body['port_id'] - body = self._show('ports', r1_port_id) - self.assertEqual(body['port']['device_id'], r1_id) - - with self.subnet(cidr='11.0.0.0/24') as public_sub: - public_net_id = public_sub['subnet']['network_id'] - self._set_net_external(public_net_id) - - with self.port() as prv_port: - prv_fixed_ip = prv_port['port']['fixed_ips'][0] - priv_sub_id = prv_fixed_ip['subnet_id'] - self._add_external_gateway_to_router( - r_id, public_net_id) - self._router_interface_action('add', r_id, - priv_sub_id, - None) - - priv_port_id = prv_port['port']['id'] - res = self._create_floatingip( - fmt, public_net_id, - port_id=priv_port_id) - self.assertEqual(res.status_int, - exc.HTTPCreated.code) - floatingip = self.deserialize(fmt, res) - - result = plugin_obj._send_all_data() - self.assertEqual(result[0], 200) - - self._delete('floatingips', - floatingip['floatingip']['id']) - self._remove_external_gateway_from_router( - r_id, public_net_id) - self._router_interface_action('remove', r_id, - priv_sub_id, - None) - self._router_interface_action('remove', r_id, s_id, - None) - self._show('ports', r_port_id, - expected_code=exc.HTTPNotFound.code) - self._router_interface_action('remove', r1_id, s1_id, - None) - self._show('ports', r1_port_id, - expected_code=exc.HTTPNotFound.code) - - def test_router_rules_update(self): - with self.router() as r: - r_id = r['router']['id'] - router_rules = [{'destination': '1.2.3.4/32', - 'source': '4.3.2.1/32', - 'action': 'permit', - 'nexthops': ['4.4.4.4', '4.4.4.5']}] - body = self._update('routers', r_id, - {'router': {'router_rules': router_rules}}) - - body = self._show('routers', r['router']['id']) - self.assertIn('router_rules', body['router']) - rules = body['router']['router_rules'] - self.assertEqual(_strip_rule_ids(rules), router_rules) - # Try after adding another rule - router_rules.append({'source': 'external', - 'destination': '8.8.8.8/32', - 'action': 'permit', 'nexthops': []}) - body = self._update('routers', r['router']['id'], - {'router': {'router_rules': router_rules}}) - - body = self._show('routers', r['router']['id']) - self.assertIn('router_rules', body['router']) - rules = body['router']['router_rules'] - self.assertEqual(_strip_rule_ids(rules), router_rules) - - def test_router_rules_separation(self): - with self.router() as r1: - with self.router() as r2: - r1_id = r1['router']['id'] - r2_id = r2['router']['id'] - router1_rules = [{'destination': '5.6.7.8/32', - 'source': '8.7.6.5/32', - 'action': 'permit', - 'nexthops': ['8.8.8.8', '9.9.9.9']}] - router2_rules = [{'destination': '1.2.3.4/32', - 'source': '4.3.2.1/32', - 'action': 'permit', - 'nexthops': ['4.4.4.4', '4.4.4.5']}] - body1 = self._update('routers', r1_id, - {'router': - {'router_rules': router1_rules}}) - body2 = self._update('routers', r2_id, - {'router': - {'router_rules': router2_rules}}) - - body1 = self._show('routers', r1_id) - body2 = self._show('routers', r2_id) - rules1 = body1['router']['router_rules'] - rules2 = body2['router']['router_rules'] - self.assertEqual(_strip_rule_ids(rules1), router1_rules) - self.assertEqual(_strip_rule_ids(rules2), router2_rules) - - def test_router_rules_validation(self): - with self.router() as r: - r_id = r['router']['id'] - good_rules = [{'destination': '1.2.3.4/32', - 'source': '4.3.2.1/32', - 'action': 'permit', - 'nexthops': ['4.4.4.4', '4.4.4.5']}] - - body = self._update('routers', r_id, - {'router': {'router_rules': good_rules}}) - body = self._show('routers', r_id) - self.assertIn('router_rules', body['router']) - self.assertEqual(good_rules, - _strip_rule_ids(body['router']['router_rules'])) - - # Missing nexthops should be populated with an empty list - light_rules = copy.deepcopy(good_rules) - del light_rules[0]['nexthops'] - body = self._update('routers', r_id, - {'router': {'router_rules': light_rules}}) - body = self._show('routers', r_id) - self.assertIn('router_rules', body['router']) - light_rules[0]['nexthops'] = [] - self.assertEqual(light_rules, - _strip_rule_ids(body['router']['router_rules'])) - # bad CIDR - bad_rules = copy.deepcopy(good_rules) - bad_rules[0]['destination'] = '1.1.1.1' - body = self._update('routers', r_id, - {'router': {'router_rules': bad_rules}}, - expected_code=exc.HTTPBadRequest.code) - # bad next hop - bad_rules = copy.deepcopy(good_rules) - bad_rules[0]['nexthops'] = ['1.1.1.1', 'f2'] - body = self._update('routers', r_id, - {'router': {'router_rules': bad_rules}}, - expected_code=exc.HTTPBadRequest.code) - # bad action - bad_rules = copy.deepcopy(good_rules) - bad_rules[0]['action'] = 'dance' - body = self._update('routers', r_id, - {'router': {'router_rules': bad_rules}}, - expected_code=exc.HTTPBadRequest.code) - # duplicate rule with opposite action - bad_rules = copy.deepcopy(good_rules) - bad_rules.append(copy.deepcopy(bad_rules[0])) - bad_rules.append(copy.deepcopy(bad_rules[0])) - bad_rules[1]['source'] = 'any' - bad_rules[2]['action'] = 'deny' - body = self._update('routers', r_id, - {'router': {'router_rules': bad_rules}}, - expected_code=exc.HTTPBadRequest.code) - # duplicate nexthop - bad_rules = copy.deepcopy(good_rules) - bad_rules[0]['nexthops'] = ['1.1.1.1', '1.1.1.1'] - body = self._update('routers', r_id, - {'router': {'router_rules': bad_rules}}, - expected_code=exc.HTTPBadRequest.code) - # make sure light rules persisted during bad updates - body = self._show('routers', r_id) - self.assertIn('router_rules', body['router']) - self.assertEqual(light_rules, - _strip_rule_ids(body['router']['router_rules'])) - - def test_router_rules_config_change(self): - cfg.CONF.set_override('tenant_default_router_rule', - ['*:any:any:deny', - '*:8.8.8.8/32:any:permit:1.2.3.4'], - 'ROUTER') - with self.router() as r: - body = self._show('routers', r['router']['id']) - expected_rules = [{'source': 'any', 'destination': 'any', - 'nexthops': [], 'action': 'deny'}, - {'source': '8.8.8.8/32', 'destination': 'any', - 'nexthops': ['1.2.3.4'], 'action': 'permit'}] - self.assertEqual(expected_rules, - _strip_rule_ids(body['router']['router_rules'])) - - def test_rule_exhaustion(self): - cfg.CONF.set_override('max_router_rules', 10, 'ROUTER') - with self.router() as r: - rules = [] - for i in moves.xrange(1, 12): - rule = {'source': 'any', 'nexthops': [], - 'destination': '1.1.1.' + str(i) + '/32', - 'action': 'permit'} - rules.append(rule) - self._update('routers', r['router']['id'], - {'router': {'router_rules': rules}}, - expected_code=exc.HTTPBadRequest.code) - - def test_rollback_on_router_create(self): - tid = test_api_v2._uuid() - self.httpPatch.stop() - with mock.patch(HTTPCON, new=fake_server.HTTPConnectionMock500): - self._create_router('json', tid) - self.assertTrue(len(self._get_routers(tid)) == 0) - - def test_rollback_on_router_update(self): - with self.router() as r: - data = {'router': {'name': 'aNewName'}} - self.httpPatch.stop() - with mock.patch(HTTPCON, new=fake_server.HTTPConnectionMock500): - self.new_update_request( - 'routers', data, r['router']['id']).get_response(self.api) - self.httpPatch.start() - updatedr = self._get_routers(r['router']['tenant_id'])[0] - # name should have stayed the same due to failure - self.assertEqual(r['router']['name'], updatedr['name']) - - def test_rollback_on_router_delete(self): - with self.router() as r: - self.httpPatch.stop() - with mock.patch(HTTPCON, new=fake_server.HTTPConnectionMock500): - self._delete('routers', r['router']['id'], - expected_code=exc.HTTPInternalServerError.code) - self.httpPatch.start() - self.assertEqual(r['router']['id'], - self._get_routers(r['router']['tenant_id'] - )[0]['id']) - - def _get_routers(self, tenant_id): - ctx = context.Context('', tenant_id) - return self.plugin_obj.get_routers(ctx) - - -def _strip_rule_ids(rules): - cleaned = [] - for rule in rules: - del rule['id'] - cleaned.append(rule) - return cleaned diff --git a/neutron/tests/unit/bigswitch/test_security_groups.py b/neutron/tests/unit/bigswitch/test_security_groups.py deleted file mode 100644 index 1e3a7aa56..000000000 --- a/neutron/tests/unit/bigswitch/test_security_groups.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2014, Big Switch Networks -# All Rights Reserved. -# -# 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. - -from neutron import manager -from neutron.tests.unit.bigswitch import test_base -from neutron.tests.unit import test_extension_security_group as test_sg -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - - -class RestProxySecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase, - test_base.BigSwitchTestBase): - plugin_str = ('%s.NeutronRestProxyV2' % - test_base.RESTPROXY_PKG_PATH) - - def setUp(self, plugin=None): - test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER) - self.setup_config_files() - self.setup_patches() - self._attribute_map_bk_ = {} - super(RestProxySecurityGroupsTestCase, self).setUp(self.plugin_str) - plugin = manager.NeutronManager.get_plugin() - self.notifier = plugin.notifier - self.rpc = plugin.endpoints[0] - self.startHttpPatch() - - -class TestSecServerRpcCallBack(test_sg_rpc.SGServerRpcCallBackMixinTestCase, - RestProxySecurityGroupsTestCase): - pass - - -class TestSecurityGroupsMixin(test_sg.TestSecurityGroups, - test_sg_rpc.SGNotificationTestMixin, - RestProxySecurityGroupsTestCase): - pass diff --git a/neutron/tests/unit/bigswitch/test_servermanager.py b/neutron/tests/unit/bigswitch/test_servermanager.py deleted file mode 100644 index 7523b9a4d..000000000 --- a/neutron/tests/unit/bigswitch/test_servermanager.py +++ /dev/null @@ -1,467 +0,0 @@ -# Copyright 2014 Big Switch Networks, Inc. All rights reserved. -# -# 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. -# -# @author: Kevin Benton, kevin.benton@bigswitch.com -# -import contextlib -import httplib -import socket -import ssl - -import mock -from oslo.config import cfg - -from neutron import manager -from neutron.openstack.common import importutils -from neutron.plugins.bigswitch import servermanager -from neutron.tests.unit.bigswitch import test_restproxy_plugin as test_rp - -SERVERMANAGER = 'neutron.plugins.bigswitch.servermanager' -HTTPCON = SERVERMANAGER + '.httplib.HTTPConnection' -HTTPSCON = SERVERMANAGER + '.HTTPSConnectionWithValidation' - - -class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase): - - def setUp(self): - self.socket_mock = mock.patch( - SERVERMANAGER + '.socket.create_connection').start() - self.wrap_mock = mock.patch(SERVERMANAGER + '.ssl.wrap_socket').start() - super(ServerManagerTests, self).setUp() - # http patch must not be running or it will mangle the servermanager - # import where the https connection classes are defined - self.httpPatch.stop() - self.sm = importutils.import_module(SERVERMANAGER) - - def test_no_servers(self): - cfg.CONF.set_override('servers', [], 'RESTPROXY') - self.assertRaises(cfg.Error, servermanager.ServerPool) - - def test_malformed_servers(self): - cfg.CONF.set_override('servers', ['1.2.3.4', '1.1.1.1:a'], 'RESTPROXY') - self.assertRaises(cfg.Error, servermanager.ServerPool) - - def test_ipv6_server_address(self): - cfg.CONF.set_override( - 'servers', ['[ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]:80'], - 'RESTPROXY') - s = servermanager.ServerPool() - self.assertEqual(s.servers[0].server, - '[ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]') - - def test_sticky_cert_fetch_fail(self): - pl = manager.NeutronManager.get_plugin() - pl.servers.ssl = True - with mock.patch( - 'ssl.get_server_certificate', - side_effect=Exception('There is no more entropy in the universe') - ) as sslgetmock: - self.assertRaises( - cfg.Error, - pl.servers._get_combined_cert_for_server, - *('example.org', 443) - ) - sslgetmock.assert_has_calls([mock.call(('example.org', 443))]) - - def test_consistency_watchdog_stops_with_0_polling_interval(self): - pl = manager.NeutronManager.get_plugin() - pl.servers.capabilities = ['consistency'] - self.watch_p.stop() - with mock.patch('eventlet.sleep') as smock: - # should return immediately a polling interval of 0 - pl.servers._consistency_watchdog(0) - self.assertFalse(smock.called) - - def test_consistency_watchdog(self): - pl = manager.NeutronManager.get_plugin() - pl.servers.capabilities = [] - self.watch_p.stop() - with contextlib.nested( - mock.patch('eventlet.sleep'), - mock.patch( - SERVERMANAGER + '.ServerPool.rest_call', - side_effect=servermanager.RemoteRestError( - reason='Failure to trigger except clause.' - ) - ), - mock.patch( - SERVERMANAGER + '.LOG.exception', - side_effect=KeyError('Failure to break loop') - ) - ) as (smock, rmock, lmock): - # should return immediately without consistency capability - pl.servers._consistency_watchdog() - self.assertFalse(smock.called) - pl.servers.capabilities = ['consistency'] - self.assertRaises(KeyError, - pl.servers._consistency_watchdog) - rmock.assert_called_with('GET', '/health', '', {}, [], False) - self.assertEqual(1, len(lmock.mock_calls)) - - def test_consistency_hash_header(self): - # mock HTTP class instead of rest_call so we can see headers - with mock.patch(HTTPCON) as conmock: - rv = conmock.return_value - rv.getresponse.return_value.getheader.return_value = 'HASHHEADER' - with self.network(): - callheaders = rv.request.mock_calls[0][1][3] - self.assertIn('X-BSN-BVS-HASH-MATCH', callheaders) - # first call will be empty to indicate no previous state hash - self.assertEqual(callheaders['X-BSN-BVS-HASH-MATCH'], '') - # change the header that will be received on delete call - rv.getresponse.return_value.getheader.return_value = 'HASH2' - - # net delete should have used header received on create - callheaders = rv.request.mock_calls[1][1][3] - self.assertEqual(callheaders['X-BSN-BVS-HASH-MATCH'], 'HASHHEADER') - - # create again should now use header received from prev delete - with self.network(): - callheaders = rv.request.mock_calls[2][1][3] - self.assertIn('X-BSN-BVS-HASH-MATCH', callheaders) - self.assertEqual(callheaders['X-BSN-BVS-HASH-MATCH'], - 'HASH2') - - def test_file_put_contents(self): - pl = manager.NeutronManager.get_plugin() - with mock.patch(SERVERMANAGER + '.open', create=True) as omock: - pl.servers._file_put_contents('somepath', 'contents') - omock.assert_has_calls([mock.call('somepath', 'w')]) - omock.return_value.__enter__.return_value.assert_has_calls([ - mock.call.write('contents') - ]) - - def test_combine_certs_to_file(self): - pl = manager.NeutronManager.get_plugin() - with mock.patch(SERVERMANAGER + '.open', create=True) as omock: - omock.return_value.__enter__().read.return_value = 'certdata' - pl.servers._combine_certs_to_file(['cert1.pem', 'cert2.pem'], - 'combined.pem') - # mock shared between read and write file handles so the calls - # are mixed together - omock.assert_has_calls([ - mock.call('combined.pem', 'w'), - mock.call('cert1.pem', 'r'), - mock.call('cert2.pem', 'r'), - ], any_order=True) - omock.return_value.__enter__.return_value.assert_has_calls([ - mock.call.read(), - mock.call.write('certdata'), - mock.call.read(), - mock.call.write('certdata') - ]) - - def test_auth_header(self): - cfg.CONF.set_override('server_auth', 'username:pass', 'RESTPROXY') - sp = servermanager.ServerPool() - with mock.patch(HTTPCON) as conmock: - rv = conmock.return_value - rv.getresponse.return_value.getheader.return_value = 'HASHHEADER' - sp.rest_create_network('tenant', 'network') - callheaders = rv.request.mock_calls[0][1][3] - self.assertIn('Authorization', callheaders) - self.assertEqual(callheaders['Authorization'], - 'Basic dXNlcm5hbWU6cGFzcw==') - - def test_header_add(self): - sp = servermanager.ServerPool() - with mock.patch(HTTPCON) as conmock: - rv = conmock.return_value - rv.getresponse.return_value.getheader.return_value = 'HASHHEADER' - sp.servers[0].rest_call('GET', '/', headers={'EXTRA-HEADER': 'HI'}) - callheaders = rv.request.mock_calls[0][1][3] - # verify normal headers weren't mangled - self.assertIn('Content-type', callheaders) - self.assertEqual(callheaders['Content-type'], - 'application/json') - # verify new header made it in - self.assertIn('EXTRA-HEADER', callheaders) - self.assertEqual(callheaders['EXTRA-HEADER'], 'HI') - - def test_capabilities_retrieval(self): - sp = servermanager.ServerPool() - with mock.patch(HTTPCON) as conmock: - rv = conmock.return_value.getresponse.return_value - rv.getheader.return_value = 'HASHHEADER' - - # each server will get different capabilities - rv.read.side_effect = ['["a","b","c"]', '["b","c","d"]'] - # pool capabilities is intersection between both - self.assertEqual(set(['b', 'c']), sp.get_capabilities()) - self.assertEqual(2, rv.read.call_count) - - # the pool should cache after the first call so no more - # HTTP calls should be made - rv.read.side_effect = ['["w","x","y"]', '["x","y","z"]'] - self.assertEqual(set(['b', 'c']), sp.get_capabilities()) - self.assertEqual(2, rv.read.call_count) - - def test_capabilities_retrieval_failure(self): - sp = servermanager.ServerPool() - with mock.patch(HTTPCON) as conmock: - rv = conmock.return_value.getresponse.return_value - rv.getheader.return_value = 'HASHHEADER' - # a failure to parse should result in an empty capability set - rv.read.return_value = 'XXXXX' - self.assertEqual([], sp.servers[0].get_capabilities()) - - # One broken server should affect all capabilities - rv.read.side_effect = ['{"a": "b"}', '["b","c","d"]'] - self.assertEqual(set(), sp.get_capabilities()) - - def test_reconnect_on_timeout_change(self): - sp = servermanager.ServerPool() - with mock.patch(HTTPCON) as conmock: - rv = conmock.return_value - rv.getresponse.return_value.getheader.return_value = 'HASHHEADER' - sp.servers[0].capabilities = ['keep-alive'] - sp.servers[0].rest_call('GET', '/', timeout=10) - # even with keep-alive enabled, a change in timeout will trigger - # a reconnect - sp.servers[0].rest_call('GET', '/', timeout=75) - conmock.assert_has_calls([ - mock.call('localhost', 9000, timeout=10), - mock.call('localhost', 9000, timeout=75), - ], any_order=True) - - def test_connect_failures(self): - sp = servermanager.ServerPool() - with mock.patch(HTTPCON, return_value=None): - resp = sp.servers[0].rest_call('GET', '/') - self.assertEqual(resp, (0, None, None, None)) - # verify same behavior on ssl class - sp.servers[0].currentcon = False - sp.servers[0].ssl = True - with mock.patch(HTTPSCON, return_value=None): - resp = sp.servers[0].rest_call('GET', '/') - self.assertEqual(resp, (0, None, None, None)) - - def test_reconnect_cached_connection(self): - sp = servermanager.ServerPool() - with mock.patch(HTTPCON) as conmock: - rv = conmock.return_value - rv.getresponse.return_value.getheader.return_value = 'HASH' - sp.servers[0].capabilities = ['keep-alive'] - sp.servers[0].rest_call('GET', '/first') - # raise an error on re-use to verify reconnect - # return okay the second time so the reconnect works - rv.request.side_effect = [httplib.ImproperConnectionState(), - mock.MagicMock()] - sp.servers[0].rest_call('GET', '/second') - uris = [c[1][1] for c in rv.request.mock_calls] - expected = [ - sp.base_uri + '/first', - sp.base_uri + '/second', - sp.base_uri + '/second', - ] - self.assertEqual(uris, expected) - - def test_no_reconnect_recurse_to_infinity(self): - # retry uses recursion when a reconnect is necessary - # this test makes sure it stops after 1 recursive call - sp = servermanager.ServerPool() - with mock.patch(HTTPCON) as conmock: - rv = conmock.return_value - # hash header must be string instead of mock object - rv.getresponse.return_value.getheader.return_value = 'HASH' - sp.servers[0].capabilities = ['keep-alive'] - sp.servers[0].rest_call('GET', '/first') - # after retrying once, the rest call should raise the - # exception up - rv.request.side_effect = httplib.ImproperConnectionState() - self.assertRaises(httplib.ImproperConnectionState, - sp.servers[0].rest_call, - *('GET', '/second')) - # 1 for the first call, 2 for the second with retry - self.assertEqual(rv.request.call_count, 3) - - def test_socket_error(self): - sp = servermanager.ServerPool() - with mock.patch(HTTPCON) as conmock: - conmock.return_value.request.side_effect = socket.timeout() - resp = sp.servers[0].rest_call('GET', '/') - self.assertEqual(resp, (0, None, None, None)) - - def test_cert_get_fail(self): - pl = manager.NeutronManager.get_plugin() - pl.servers.ssl = True - with mock.patch('os.path.exists', return_value=False): - self.assertRaises(cfg.Error, - pl.servers._get_combined_cert_for_server, - *('example.org', 443)) - - def test_cert_make_dirs(self): - pl = manager.NeutronManager.get_plugin() - pl.servers.ssl = True - cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY') - # pretend base dir exists, 3 children don't, and host cert does - with contextlib.nested( - mock.patch('os.path.exists', side_effect=[True, False, False, - False, True]), - mock.patch('os.makedirs'), - mock.patch(SERVERMANAGER + '.ServerPool._combine_certs_to_file') - ) as (exmock, makemock, combmock): - # will raise error because no certs found - self.assertIn( - 'example.org', - pl.servers._get_combined_cert_for_server('example.org', 443) - ) - base = cfg.CONF.RESTPROXY.ssl_cert_directory - hpath = base + '/host_certs/example.org.pem' - combpath = base + '/combined/example.org.pem' - combmock.assert_has_calls([mock.call([hpath], combpath)]) - self.assertEqual(exmock.call_count, 5) - self.assertEqual(makemock.call_count, 3) - - def test_no_cert_error(self): - pl = manager.NeutronManager.get_plugin() - pl.servers.ssl = True - cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY') - # pretend base dir exists and 3 children do, but host cert doesn't - with mock.patch( - 'os.path.exists', - side_effect=[True, True, True, True, False] - ) as exmock: - # will raise error because no certs found - self.assertRaises( - cfg.Error, - pl.servers._get_combined_cert_for_server, - *('example.org', 443) - ) - self.assertEqual(exmock.call_count, 5) - - def test_action_success(self): - pl = manager.NeutronManager.get_plugin() - self.assertTrue(pl.servers.action_success((200,))) - - def test_server_failure(self): - pl = manager.NeutronManager.get_plugin() - self.assertTrue(pl.servers.server_failure((404,))) - # server failure has an ignore codes option - self.assertFalse(pl.servers.server_failure((404,), - ignore_codes=[404])) - - def test_conflict_triggers_sync(self): - pl = manager.NeutronManager.get_plugin() - with mock.patch( - SERVERMANAGER + '.ServerProxy.rest_call', - return_value=(httplib.CONFLICT, 0, 0, 0) - ) as srestmock: - # making a call should trigger a conflict sync - pl.servers.rest_call('GET', '/', '', None, []) - srestmock.assert_has_calls([ - mock.call('GET', '/', '', None, False, reconnect=True), - mock.call('PUT', '/topology', - {'routers': [], 'networks': []}, - timeout=None) - ]) - - def test_conflict_sync_raises_error_without_topology(self): - pl = manager.NeutronManager.get_plugin() - pl.servers.get_topo_function = None - with mock.patch( - SERVERMANAGER + '.ServerProxy.rest_call', - return_value=(httplib.CONFLICT, 0, 0, 0) - ): - # making a call should trigger a conflict sync that will - # error without the topology function set - self.assertRaises( - cfg.Error, - pl.servers.rest_call, - *('GET', '/', '', None, []) - ) - - def test_floating_calls(self): - pl = manager.NeutronManager.get_plugin() - with mock.patch(SERVERMANAGER + '.ServerPool.rest_action') as ramock: - pl.servers.rest_create_floatingip('tenant', {'id': 'somefloat'}) - pl.servers.rest_update_floatingip('tenant', {'name': 'myfl'}, 'id') - pl.servers.rest_delete_floatingip('tenant', 'oldid') - ramock.assert_has_calls([ - mock.call('PUT', '/tenants/tenant/floatingips/somefloat', - errstr=u'Unable to create floating IP: %s'), - mock.call('PUT', '/tenants/tenant/floatingips/id', - errstr=u'Unable to update floating IP: %s'), - mock.call('DELETE', '/tenants/tenant/floatingips/oldid', - errstr=u'Unable to delete floating IP: %s') - ]) - - def test_HTTPSConnectionWithValidation_without_cert(self): - con = self.sm.HTTPSConnectionWithValidation( - 'www.example.org', 443, timeout=90) - con.source_address = '127.0.0.1' - con.request("GET", "/") - self.socket_mock.assert_has_calls([mock.call( - ('www.example.org', 443), 90, '127.0.0.1' - )]) - self.wrap_mock.assert_has_calls([mock.call( - self.socket_mock(), None, None, cert_reqs=ssl.CERT_NONE - )]) - self.assertEqual(con.sock, self.wrap_mock()) - - def test_HTTPSConnectionWithValidation_with_cert(self): - con = self.sm.HTTPSConnectionWithValidation( - 'www.example.org', 443, timeout=90) - con.combined_cert = 'SOMECERTS.pem' - con.source_address = '127.0.0.1' - con.request("GET", "/") - self.socket_mock.assert_has_calls([mock.call( - ('www.example.org', 443), 90, '127.0.0.1' - )]) - self.wrap_mock.assert_has_calls([mock.call( - self.socket_mock(), None, None, ca_certs='SOMECERTS.pem', - cert_reqs=ssl.CERT_REQUIRED - )]) - self.assertEqual(con.sock, self.wrap_mock()) - - def test_HTTPSConnectionWithValidation_tunnel(self): - tunnel_mock = mock.patch.object( - self.sm.HTTPSConnectionWithValidation, - '_tunnel').start() - con = self.sm.HTTPSConnectionWithValidation( - 'www.example.org', 443, timeout=90) - con.source_address = '127.0.0.1' - if not hasattr(con, 'set_tunnel'): - # no tunnel support in py26 - return - con.set_tunnel('myproxy.local', 3128) - con.request("GET", "/") - self.socket_mock.assert_has_calls([mock.call( - ('www.example.org', 443), 90, '127.0.0.1' - )]) - self.wrap_mock.assert_has_calls([mock.call( - self.socket_mock(), None, None, cert_reqs=ssl.CERT_NONE - )]) - # _tunnel() doesn't take any args - tunnel_mock.assert_has_calls([mock.call()]) - self.assertEqual(con._tunnel_host, 'myproxy.local') - self.assertEqual(con._tunnel_port, 3128) - self.assertEqual(con.sock, self.wrap_mock()) - - -class TestSockets(test_rp.BigSwitchProxyPluginV2TestCase): - - def setUp(self): - super(TestSockets, self).setUp() - # http patch must not be running or it will mangle the servermanager - # import where the https connection classes are defined - self.httpPatch.stop() - self.sm = importutils.import_module(SERVERMANAGER) - - def test_socket_create_attempt(self): - # exercise the socket creation to make sure it works on both python - # versions - con = self.sm.HTTPSConnectionWithValidation('127.0.0.1', 0, timeout=1) - # if httpcon was created, a connect attempt should raise a socket error - self.assertRaises(socket.error, con.connect) diff --git a/neutron/tests/unit/bigswitch/test_ssl.py b/neutron/tests/unit/bigswitch/test_ssl.py deleted file mode 100644 index 551f9cc53..000000000 --- a/neutron/tests/unit/bigswitch/test_ssl.py +++ /dev/null @@ -1,250 +0,0 @@ -# Copyright 2014 Big Switch Networks, Inc. All rights reserved. -# -# 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. -# -# @author: Kevin Benton, kevin.benton@bigswitch.com -# -import contextlib -import os - -import mock -from oslo.config import cfg -import webob.exc - -from neutron.openstack.common import log as logging -from neutron.tests.unit.bigswitch import fake_server -from neutron.tests.unit.bigswitch import test_base -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_db_plugin as test_plugin - -LOG = logging.getLogger(__name__) - -SERVERMANAGER = 'neutron.plugins.bigswitch.servermanager' -HTTPS = SERVERMANAGER + '.HTTPSConnectionWithValidation' -CERTCOMBINER = SERVERMANAGER + '.ServerPool._combine_certs_to_file' -FILEPUT = SERVERMANAGER + '.ServerPool._file_put_contents' -GETCACERTS = SERVERMANAGER + '.ServerPool._get_ca_cert_paths' -GETHOSTCERT = SERVERMANAGER + '.ServerPool._get_host_cert_path' -SSLGETCERT = SERVERMANAGER + '.ssl.get_server_certificate' -FAKECERTGET = 'neutron.tests.unit.bigswitch.fake_server.get_cert_contents' - - -class test_ssl_certificate_base(test_plugin.NeutronDbPluginV2TestCase, - test_base.BigSwitchTestBase): - - plugin_str = ('%s.NeutronRestProxyV2' % - test_base.RESTPROXY_PKG_PATH) - servername = None - cert_base = None - - def _setUp(self): - self.servername = test_api_v2._uuid() - self.cert_base = cfg.CONF.RESTPROXY.ssl_cert_directory - self.host_cert_val = 'DUMMYCERTFORHOST%s' % self.servername - self.host_cert_path = os.path.join( - self.cert_base, - 'host_certs', - '%s.pem' % self.servername - ) - self.comb_cert_path = os.path.join( - self.cert_base, - 'combined', - '%s.pem' % self.servername - ) - self.ca_certs_path = os.path.join( - self.cert_base, - 'ca_certs' - ) - cfg.CONF.set_override('servers', ["%s:443" % self.servername], - 'RESTPROXY') - self.setup_patches() - - # Mock method SSL lib uses to grab cert from server - self.sslgetcert_m = mock.patch(SSLGETCERT, create=True).start() - self.sslgetcert_m.return_value = self.host_cert_val - - # Mock methods that write and read certs from the file-system - self.fileput_m = mock.patch(FILEPUT, create=True).start() - self.certcomb_m = mock.patch(CERTCOMBINER, create=True).start() - self.getcacerts_m = mock.patch(GETCACERTS, create=True).start() - - # this is used to configure what certificate contents the fake HTTPS - # lib should expect to receive - self.fake_certget_m = mock.patch(FAKECERTGET, create=True).start() - - def setUp(self): - super(test_ssl_certificate_base, self).setUp(self.plugin_str) - - -class TestSslSticky(test_ssl_certificate_base): - - def setUp(self): - self.setup_config_files() - cfg.CONF.set_override('server_ssl', True, 'RESTPROXY') - cfg.CONF.set_override('ssl_sticky', True, 'RESTPROXY') - self._setUp() - # Set fake HTTPS connection's expectation - self.fake_certget_m.return_value = self.host_cert_val - # No CA certs for this test - self.getcacerts_m.return_value = [] - super(TestSslSticky, self).setUp() - - def test_sticky_cert(self): - # SSL connection should be successful and cert should be cached - with contextlib.nested( - mock.patch(HTTPS, new=fake_server.HTTPSHostValidation), - self.network() - ): - # CA certs should have been checked for - self.getcacerts_m.assert_has_calls([mock.call(self.ca_certs_path)]) - # cert should have been fetched via SSL lib - self.sslgetcert_m.assert_has_calls( - [mock.call((self.servername, 443))] - ) - - # cert should have been recorded - self.fileput_m.assert_has_calls([mock.call(self.host_cert_path, - self.host_cert_val)]) - # no ca certs, so host cert only for this combined cert - self.certcomb_m.assert_has_calls([mock.call([self.host_cert_path], - self.comb_cert_path)]) - - -class TestSslHostCert(test_ssl_certificate_base): - - def setUp(self): - self.setup_config_files() - cfg.CONF.set_override('server_ssl', True, 'RESTPROXY') - cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY') - self.httpsPatch = mock.patch(HTTPS, create=True, - new=fake_server.HTTPSHostValidation) - self.httpsPatch.start() - self._setUp() - # Set fake HTTPS connection's expectation - self.fake_certget_m.return_value = self.host_cert_val - # No CA certs for this test - self.getcacerts_m.return_value = [] - # Pretend host cert exists - self.hcertpath_p = mock.patch(GETHOSTCERT, - return_value=(self.host_cert_path, True), - create=True).start() - super(TestSslHostCert, self).setUp() - - def test_host_cert(self): - # SSL connection should be successful because of pre-configured cert - with self.network(): - self.hcertpath_p.assert_has_calls([ - mock.call(os.path.join(self.cert_base, 'host_certs'), - self.servername) - ]) - # sticky is disabled, no fetching allowed - self.assertFalse(self.sslgetcert_m.call_count) - # no ca certs, so host cert is only for this combined cert - self.certcomb_m.assert_has_calls([mock.call([self.host_cert_path], - self.comb_cert_path)]) - - -class TestSslCaCert(test_ssl_certificate_base): - - def setUp(self): - self.setup_config_files() - cfg.CONF.set_override('server_ssl', True, 'RESTPROXY') - cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY') - self.httpsPatch = mock.patch(HTTPS, create=True, - new=fake_server.HTTPSCAValidation) - self.httpsPatch.start() - self._setUp() - - # pretend to have a few ca certs - self.getcacerts_m.return_value = ['ca1.pem', 'ca2.pem'] - - # Set fake HTTPS connection's expectation - self.fake_certget_m.return_value = 'DUMMYCERTIFICATEAUTHORITY' - - super(TestSslCaCert, self).setUp() - - def test_ca_cert(self): - # SSL connection should be successful because CA cert was present - # If not, attempting to create a network would raise an exception - with self.network(): - # sticky is disabled, no fetching allowed - self.assertFalse(self.sslgetcert_m.call_count) - # 2 CAs and no host cert so combined should only contain both CAs - self.certcomb_m.assert_has_calls([mock.call(['ca1.pem', 'ca2.pem'], - self.comb_cert_path)]) - - -class TestSslWrongHostCert(test_ssl_certificate_base): - - def setUp(self): - self.setup_config_files() - cfg.CONF.set_override('server_ssl', True, 'RESTPROXY') - cfg.CONF.set_override('ssl_sticky', True, 'RESTPROXY') - self._setUp() - - # Set fake HTTPS connection's expectation to something wrong - self.fake_certget_m.return_value = 'OTHERCERT' - - # No CA certs for this test - self.getcacerts_m.return_value = [] - - # Pretend host cert exists - self.hcertpath_p = mock.patch(GETHOSTCERT, - return_value=(self.host_cert_path, True), - create=True).start() - super(TestSslWrongHostCert, self).setUp() - - def test_error_no_cert(self): - # since there will already be a host cert, sticky should not take - # effect and there will be an error because the host cert's contents - # will be incorrect - tid = test_api_v2._uuid() - data = {} - data['network'] = {'tenant_id': tid, 'name': 'name', - 'admin_state_up': True} - with mock.patch(HTTPS, new=fake_server.HTTPSHostValidation): - req = self.new_create_request('networks', data, 'json') - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPInternalServerError.code) - self.hcertpath_p.assert_has_calls([ - mock.call(os.path.join(self.cert_base, 'host_certs'), - self.servername) - ]) - # sticky is enabled, but a host cert already exists so it shant fetch - self.assertFalse(self.sslgetcert_m.call_count) - # no ca certs, so host cert only for this combined cert - self.certcomb_m.assert_has_calls([mock.call([self.host_cert_path], - self.comb_cert_path)]) - - -class TestSslNoValidation(test_ssl_certificate_base): - - def setUp(self): - self.setup_config_files() - cfg.CONF.set_override('server_ssl', True, 'RESTPROXY') - cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY') - cfg.CONF.set_override('no_ssl_validation', True, 'RESTPROXY') - self._setUp() - super(TestSslNoValidation, self).setUp() - - def test_validation_disabled(self): - # SSL connection should be successful without any certificates - # If not, attempting to create a network will raise an exception - with contextlib.nested( - mock.patch(HTTPS, new=fake_server.HTTPSNoValidation), - self.network() - ): - # no sticky grabbing and no cert combining with no enforcement - self.assertFalse(self.sslgetcert_m.call_count) - self.assertFalse(self.certcomb_m.call_count) diff --git a/neutron/tests/unit/brocade/__init__.py b/neutron/tests/unit/brocade/__init__.py deleted file mode 100644 index d1af8c59e..000000000 --- a/neutron/tests/unit/brocade/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 OpenStack Foundation. -# -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/brocade/test_brocade_db.py b/neutron/tests/unit/brocade/test_brocade_db.py deleted file mode 100644 index 127b516be..000000000 --- a/neutron/tests/unit/brocade/test_brocade_db.py +++ /dev/null @@ -1,100 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright (c) 2013 OpenStack Foundation. -# -# 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. - - -""" -Unit test brocade db. -""" -import uuid - -from neutron import context -from neutron.plugins.brocade.db import models as brocade_db -from neutron.tests.unit import test_db_plugin as test_plugin - -TEST_VLAN = 1000 - - -class TestBrocadeDb(test_plugin.NeutronDbPluginV2TestCase): - """Test brocade db functionality.""" - - def test_create_network(self): - """Test brocade specific network db.""" - - net_id = str(uuid.uuid4()) - - # Create a network - self.context = context.get_admin_context() - brocade_db.create_network(self.context, net_id, TEST_VLAN) - - # Get the network and verify - net = brocade_db.get_network(self.context, net_id) - self.assertEqual(net['id'], net_id) - self.assertEqual(int(net['vlan']), TEST_VLAN) - - # Delete the network - brocade_db.delete_network(self.context, net['id']) - self.assertFalse(brocade_db.get_networks(self.context)) - - def test_create_port(self): - """Test brocade specific port db.""" - - net_id = str(uuid.uuid4()) - port_id = str(uuid.uuid4()) - # port_id is truncated: since the linux-bridge tap device names are - # based on truncated port id, this enables port lookups using - # tap devices - port_id = port_id[0:11] - tenant_id = str(uuid.uuid4()) - admin_state_up = True - - # Create Port - - # To create a port a network must exists, Create a network - self.context = context.get_admin_context() - brocade_db.create_network(self.context, net_id, TEST_VLAN) - - physical_interface = "em1" - brocade_db.create_port(self.context, port_id, net_id, - physical_interface, - TEST_VLAN, tenant_id, admin_state_up) - - port = brocade_db.get_port(self.context, port_id) - self.assertEqual(port['port_id'], port_id) - self.assertEqual(port['network_id'], net_id) - self.assertEqual(port['physical_interface'], physical_interface) - self.assertEqual(int(port['vlan_id']), TEST_VLAN) - self.assertEqual(port['tenant_id'], tenant_id) - self.assertEqual(port['admin_state_up'], admin_state_up) - - admin_state_up = True - brocade_db.update_port_state(self.context, port_id, admin_state_up) - port = brocade_db.get_port(self.context, port_id) - self.assertEqual(port['admin_state_up'], admin_state_up) - - admin_state_up = False - brocade_db.update_port_state(self.context, port_id, admin_state_up) - port = brocade_db.get_port(self.context, port_id) - self.assertEqual(port['admin_state_up'], admin_state_up) - - admin_state_up = True - brocade_db.update_port_state(self.context, port_id, admin_state_up) - port = brocade_db.get_port(self.context, port_id) - self.assertEqual(port['admin_state_up'], admin_state_up) - - # Delete Port - brocade_db.delete_port(self.context, port_id) - self.assertFalse(brocade_db.get_ports(self.context)) diff --git a/neutron/tests/unit/brocade/test_brocade_plugin.py b/neutron/tests/unit/brocade/test_brocade_plugin.py deleted file mode 100644 index 0e3a6ef69..000000000 --- a/neutron/tests/unit/brocade/test_brocade_plugin.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 neutron.extensions import portbindings -from neutron.openstack.common import importutils -from neutron.plugins.brocade import NeutronPlugin as brocade_plugin -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit import test_db_plugin as test_plugin - - -PLUGIN_NAME = ('neutron.plugins.brocade.' - 'NeutronPlugin.BrocadePluginV2') -NOS_DRIVER = ('neutron.plugins.brocade.' - 'nos.fake_nosdriver.NOSdriver') -FAKE_IPADDRESS = '2.2.2.2' -FAKE_USERNAME = 'user' -FAKE_PASSWORD = 'password' -FAKE_PHYSICAL_INTERFACE = 'em1' - - -class BrocadePluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self): - - def mocked_brocade_init(self): - - self._switch = {'address': FAKE_IPADDRESS, - 'username': FAKE_USERNAME, - 'password': FAKE_PASSWORD - } - self._driver = importutils.import_object(NOS_DRIVER) - - with mock.patch.object(brocade_plugin.BrocadePluginV2, - 'brocade_init', new=mocked_brocade_init): - super(BrocadePluginV2TestCase, self).setUp(self._plugin_name) - - -class TestBrocadeBasicGet(test_plugin.TestBasicGet, - BrocadePluginV2TestCase): - pass - - -class TestBrocadeV2HTTPResponse(test_plugin.TestV2HTTPResponse, - BrocadePluginV2TestCase): - pass - - -class TestBrocadePortsV2(test_plugin.TestPortsV2, - BrocadePluginV2TestCase, - test_bindings.PortBindingsTestCase): - - VIF_TYPE = portbindings.VIF_TYPE_BRIDGE - HAS_PORT_FILTER = True - - -class TestBrocadeNetworksV2(test_plugin.TestNetworksV2, - BrocadePluginV2TestCase): - pass diff --git a/neutron/tests/unit/brocade/test_brocade_vlan.py b/neutron/tests/unit/brocade/test_brocade_vlan.py deleted file mode 100644 index b5a0c33f6..000000000 --- a/neutron/tests/unit/brocade/test_brocade_vlan.py +++ /dev/null @@ -1,73 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright (c) 2013 OpenStack Foundation. -# -# 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. - - -""" -Test vlans alloc/dealloc. -""" - -from neutron.db import api as db -from neutron.openstack.common import context -from neutron.plugins.brocade import vlanbm as vlan_bitmap -from neutron.tests import base - - -class TestVlanBitmap(base.BaseTestCase): - """exercise Vlan bitmap .""" - - def setUp(self): - super(TestVlanBitmap, self).setUp() - db.configure_db() - self.addCleanup(db.clear_db) - self.context = context.get_admin_context() - self.context.session = db.get_session() - - def test_vlan(self): - """test vlan allocation/de-alloc.""" - - self.vbm_ = vlan_bitmap.VlanBitmap(self.context) - vlan_id = self.vbm_.get_next_vlan(None) - - # First vlan is always 2 - self.assertEqual(vlan_id, 2) - - # next vlan is always 3 - vlan_id = self.vbm_.get_next_vlan(None) - self.assertEqual(vlan_id, 3) - - # get a specific vlan i.e. 4 - vlan_id = self.vbm_.get_next_vlan(4) - self.assertEqual(vlan_id, 4) - - # get a specific vlan i.e. 5 - vlan_id = self.vbm_.get_next_vlan(5) - self.assertEqual(vlan_id, 5) - - # Skip 6 - - # get a specific vlan i.e. 7 - vlan_id = self.vbm_.get_next_vlan(7) - self.assertEqual(vlan_id, 7) - - # get a specific vlan i.e. 1900 - vlan_id = self.vbm_.get_next_vlan(1900) - self.assertEqual(vlan_id, 1900) - - # Release 4 and get next again - self.vbm_.release_vlan(4) - vlan_id = self.vbm_.get_next_vlan(None) - self.assertEqual(vlan_id, 4) diff --git a/neutron/tests/unit/cisco/__init__.py b/neutron/tests/unit/cisco/__init__.py deleted file mode 100644 index 7e503debd..000000000 --- a/neutron/tests/unit/cisco/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/cisco/n1kv/__init__.py b/neutron/tests/unit/cisco/n1kv/__init__.py deleted file mode 100644 index 59a411933..000000000 --- a/neutron/tests/unit/cisco/n1kv/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Cisco Systems, Inc. -# -# 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. -# -# @author: Abhishek Raut, Cisco Systems, Inc. -# diff --git a/neutron/tests/unit/cisco/n1kv/fake_client.py b/neutron/tests/unit/cisco/n1kv/fake_client.py deleted file mode 100755 index 2d1f0780e..000000000 --- a/neutron/tests/unit/cisco/n1kv/fake_client.py +++ /dev/null @@ -1,119 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2014 Cisco Systems, Inc. -# -# 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. -# -# @author: Abhishek Raut, Cisco Systems Inc. -# @author: Sourabh Patwardhan, Cisco Systems Inc. - -from neutron.openstack.common import log as logging -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.n1kv import n1kv_client - -LOG = logging.getLogger(__name__) - -_resource_metadata = {'port': ['id', 'macAddress', 'ipAddress', 'subnetId'], - 'vmnetwork': ['name', 'networkSegmentId', - 'networkSegment', 'portProfile', - 'portProfileId', 'tenantId', - 'portId', 'macAddress', - 'ipAddress', 'subnetId']} - - -class TestClient(n1kv_client.Client): - - def __init__(self, **kwargs): - self.broken = False - self.inject_params = False - self.total_profiles = 2 - super(TestClient, self).__init__() - - def _get_total_profiles(self): - return self.total_profiles - - def _do_request(self, method, action, body=None, headers=None): - if self.broken: - raise c_exc.VSMError(reason='VSM:Internal Server Error') - if self.inject_params and body: - body['invalidKey'] = 'catchMeIfYouCan' - if method == 'POST': - return _validate_resource(action, body) - elif method == 'GET': - if 'virtual-port-profile' in action: - return _policy_profile_generator( - self._get_total_profiles()) - else: - raise c_exc.VSMError(reason='VSM:Internal Server Error') - - -class TestClientInvalidRequest(TestClient): - - def __init__(self, **kwargs): - super(TestClientInvalidRequest, self).__init__() - self.inject_params = True - - -def _validate_resource(action, body=None): - if body: - body_set = set(body.keys()) - else: - return - if 'vm-network' in action and 'port' not in action: - vmnetwork_set = set(_resource_metadata['vmnetwork']) - if body_set - vmnetwork_set: - raise c_exc.VSMError(reason='Invalid Request') - elif 'port' in action: - port_set = set(_resource_metadata['port']) - if body_set - port_set: - raise c_exc.VSMError(reason='Invalid Request') - else: - return - - -def _policy_profile_generator(total_profiles): - """ - Generate policy profile response and return a dictionary. - - :param total_profiles: integer representing total number of profiles to - return - """ - profiles = {} - for num in range(1, total_profiles + 1): - name = "pp-%s" % num - profile_id = "00000000-0000-0000-0000-00000000000%s" % num - profiles[name] = {"properties": {"name": name, "id": profile_id}} - return profiles - - -def _policy_profile_generator_xml(total_profiles): - """ - Generate policy profile response in XML format. - - :param total_profiles: integer representing total number of profiles to - return - """ - xml = [""" - """] - template = ( - '' - '' - '00000000-0000-0000-0000-00000000000%(num)s' - 'pp-%(num)s' - '' - '' - ) - xml.extend(template % {'num': n} for n in range(1, total_profiles + 1)) - xml.append("") - return ''.join(xml) diff --git a/neutron/tests/unit/cisco/n1kv/test_n1kv_db.py b/neutron/tests/unit/cisco/n1kv/test_n1kv_db.py deleted file mode 100644 index e806944e0..000000000 --- a/neutron/tests/unit/cisco/n1kv/test_n1kv_db.py +++ /dev/null @@ -1,870 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Cisco Systems, Inc. -# -# 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. -# -# @author: Juergen Brendel, Cisco Systems Inc. -# @author: Abhishek Raut, Cisco Systems Inc. -# @author: Rudrajit Tapadar, Cisco Systems Inc. - -from six import moves -from sqlalchemy.orm import exc as s_exc -from testtools import matchers - -from neutron.common import exceptions as n_exc -from neutron import context -from neutron.db import api as db -from neutron.db import db_base_plugin_v2 -from neutron.plugins.cisco.common import cisco_constants -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.db import n1kv_db_v2 -from neutron.plugins.cisco.db import n1kv_models_v2 -from neutron.tests import base -from neutron.tests.unit import test_db_plugin as test_plugin - - -PHYS_NET = 'physnet1' -PHYS_NET_2 = 'physnet2' -VLAN_MIN = 10 -VLAN_MAX = 19 -VXLAN_MIN = 5000 -VXLAN_MAX = 5009 -SEGMENT_RANGE = '200-220' -SEGMENT_RANGE_MIN_OVERLAP = '210-230' -SEGMENT_RANGE_MAX_OVERLAP = '190-209' -SEGMENT_RANGE_OVERLAP = '190-230' -TEST_NETWORK_ID = 'abcdefghijklmnopqrstuvwxyz' -TEST_NETWORK_ID2 = 'abcdefghijklmnopqrstuvwxy2' -TEST_NETWORK_ID3 = 'abcdefghijklmnopqrstuvwxy3' -TEST_NETWORK_PROFILE = {'name': 'test_profile', - 'segment_type': 'vlan', - 'physical_network': 'physnet1', - 'segment_range': '10-19'} -TEST_NETWORK_PROFILE_2 = {'name': 'test_profile_2', - 'segment_type': 'vlan', - 'physical_network': 'physnet1', - 'segment_range': SEGMENT_RANGE} -TEST_NETWORK_PROFILE_VXLAN = {'name': 'test_profile', - 'segment_type': 'overlay', - 'sub_type': 'native_vxlan', - 'segment_range': '5000-5009', - 'multicast_ip_range': '239.0.0.70-239.0.0.80'} -TEST_POLICY_PROFILE = {'id': '4a417990-76fb-11e2-bcfd-0800200c9a66', - 'name': 'test_policy_profile'} -TEST_NETWORK_PROFILE_MULTI_SEGMENT = {'name': 'test_profile', - 'segment_type': 'multi-segment'} -TEST_NETWORK_PROFILE_VLAN_TRUNK = {'name': 'test_profile', - 'segment_type': 'trunk', - 'sub_type': 'vlan'} -TEST_NETWORK_PROFILE_VXLAN_TRUNK = {'name': 'test_profile', - 'segment_type': 'trunk', - 'sub_type': 'overlay'} - - -def _create_test_network_profile_if_not_there(session, - profile=TEST_NETWORK_PROFILE): - try: - _profile = session.query(n1kv_models_v2.NetworkProfile).filter_by( - name=profile['name']).one() - except s_exc.NoResultFound: - _profile = n1kv_db_v2.create_network_profile(session, profile) - return _profile - - -def _create_test_policy_profile_if_not_there(session, - profile=TEST_POLICY_PROFILE): - try: - _profile = session.query(n1kv_models_v2.PolicyProfile).filter_by( - name=profile['name']).one() - except s_exc.NoResultFound: - _profile = n1kv_db_v2.create_policy_profile(profile) - return _profile - - -class VlanAllocationsTest(base.BaseTestCase): - - def setUp(self): - super(VlanAllocationsTest, self).setUp() - db.configure_db() - self.session = db.get_session() - self.net_p = _create_test_network_profile_if_not_there(self.session) - n1kv_db_v2.sync_vlan_allocations(self.session, self.net_p) - self.addCleanup(db.clear_db) - - def test_sync_vlan_allocations_outside_segment_range(self): - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET, - VLAN_MIN - 1) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET, - VLAN_MAX + 1) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET_2, - VLAN_MIN + 20) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET_2, - VLAN_MIN + 20) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET_2, - VLAN_MAX + 20) - - def test_sync_vlan_allocations_unallocated_vlans(self): - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - VLAN_MIN + 1). - allocated) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - VLAN_MAX - 1). - allocated) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - VLAN_MAX).allocated) - - def test_vlan_pool(self): - vlan_ids = set() - for x in moves.xrange(VLAN_MIN, VLAN_MAX + 1): - (physical_network, seg_type, - vlan_id, m_ip) = n1kv_db_v2.reserve_vlan(self.session, self.net_p) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - self.assertRaises(n_exc.NoNetworkAvailable, - n1kv_db_v2.reserve_vlan, - self.session, - self.net_p) - - n1kv_db_v2.release_vlan(self.session, PHYS_NET, vlan_ids.pop()) - physical_network, seg_type, vlan_id, m_ip = (n1kv_db_v2.reserve_vlan( - self.session, self.net_p)) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - for vlan_id in vlan_ids: - n1kv_db_v2.release_vlan(self.session, PHYS_NET, vlan_id) - - def test_specific_vlan_inside_pool(self): - vlan_id = VLAN_MIN + 5 - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - vlan_id).allocated) - n1kv_db_v2.reserve_specific_vlan(self.session, PHYS_NET, vlan_id) - self.assertTrue(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - vlan_id).allocated) - - self.assertRaises(n_exc.VlanIdInUse, - n1kv_db_v2.reserve_specific_vlan, - self.session, - PHYS_NET, - vlan_id) - - n1kv_db_v2.release_vlan(self.session, PHYS_NET, vlan_id) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - vlan_id).allocated) - - def test_specific_vlan_outside_pool(self): - vlan_id = VLAN_MAX + 5 - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET, - vlan_id) - self.assertRaises(c_exc.VlanIDOutsidePool, - n1kv_db_v2.reserve_specific_vlan, - self.session, - PHYS_NET, - vlan_id) - - -class VxlanAllocationsTest(base.BaseTestCase, - n1kv_db_v2.NetworkProfile_db_mixin): - - def setUp(self): - super(VxlanAllocationsTest, self).setUp() - db.configure_db() - self.session = db.get_session() - self.net_p = _create_test_network_profile_if_not_there( - self.session, TEST_NETWORK_PROFILE_VXLAN) - n1kv_db_v2.sync_vxlan_allocations(self.session, self.net_p) - self.addCleanup(db.clear_db) - - def test_sync_vxlan_allocations_outside_segment_range(self): - self.assertRaises(c_exc.VxlanIDNotFound, - n1kv_db_v2.get_vxlan_allocation, - self.session, - VXLAN_MIN - 1) - self.assertRaises(c_exc.VxlanIDNotFound, - n1kv_db_v2.get_vxlan_allocation, - self.session, - VXLAN_MAX + 1) - - def test_sync_vxlan_allocations_unallocated_vxlans(self): - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - VXLAN_MIN).allocated) - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - VXLAN_MIN + 1). - allocated) - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - VXLAN_MAX - 1). - allocated) - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - VXLAN_MAX).allocated) - - def test_vxlan_pool(self): - vxlan_ids = set() - for x in moves.xrange(VXLAN_MIN, VXLAN_MAX + 1): - vxlan = n1kv_db_v2.reserve_vxlan(self.session, self.net_p) - vxlan_id = vxlan[2] - self.assertThat(vxlan_id, matchers.GreaterThan(VXLAN_MIN - 1)) - self.assertThat(vxlan_id, matchers.LessThan(VXLAN_MAX + 1)) - vxlan_ids.add(vxlan_id) - - self.assertRaises(n_exc.NoNetworkAvailable, - n1kv_db_v2.reserve_vxlan, - self.session, - self.net_p) - n1kv_db_v2.release_vxlan(self.session, vxlan_ids.pop()) - vxlan = n1kv_db_v2.reserve_vxlan(self.session, self.net_p) - vxlan_id = vxlan[2] - self.assertThat(vxlan_id, matchers.GreaterThan(VXLAN_MIN - 1)) - self.assertThat(vxlan_id, matchers.LessThan(VXLAN_MAX + 1)) - vxlan_ids.add(vxlan_id) - - for vxlan_id in vxlan_ids: - n1kv_db_v2.release_vxlan(self.session, vxlan_id) - n1kv_db_v2.delete_network_profile(self.session, self.net_p.id) - - def test_specific_vxlan_inside_pool(self): - vxlan_id = VXLAN_MIN + 5 - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - vxlan_id).allocated) - n1kv_db_v2.reserve_specific_vxlan(self.session, vxlan_id) - self.assertTrue(n1kv_db_v2.get_vxlan_allocation(self.session, - vxlan_id).allocated) - - self.assertRaises(c_exc.VxlanIDInUse, - n1kv_db_v2.reserve_specific_vxlan, - self.session, - vxlan_id) - - n1kv_db_v2.release_vxlan(self.session, vxlan_id) - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - vxlan_id).allocated) - - def test_specific_vxlan_outside_pool(self): - vxlan_id = VXLAN_MAX + 5 - self.assertRaises(c_exc.VxlanIDNotFound, - n1kv_db_v2.get_vxlan_allocation, - self.session, - vxlan_id) - self.assertRaises(c_exc.VxlanIDOutsidePool, - n1kv_db_v2.reserve_specific_vxlan, - self.session, - vxlan_id) - - -class NetworkBindingsTest(test_plugin.NeutronDbPluginV2TestCase): - - def setUp(self): - super(NetworkBindingsTest, self).setUp() - db.configure_db() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_add_network_binding(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there(self.session) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, 'vlan', - PHYS_NET, 1234, '0.0.0.0', p.id, None) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, 'vlan') - self.assertEqual(binding.physical_network, PHYS_NET) - self.assertEqual(binding.segmentation_id, 1234) - - def test_create_multi_segment_network(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_MULTI_SEGMENT) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, 'multi-segment', - None, 0, '0.0.0.0', p.id, None) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, 'multi-segment') - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - - def test_add_multi_segment_binding(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_MULTI_SEGMENT) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, 'multi-segment', - None, 0, '0.0.0.0', p.id, - [(TEST_NETWORK_ID2, TEST_NETWORK_ID3)]) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, 'multi-segment') - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - ms_binding = (n1kv_db_v2.get_multi_segment_network_binding( - self.session, TEST_NETWORK_ID, - (TEST_NETWORK_ID2, TEST_NETWORK_ID3))) - self.assertIsNotNone(ms_binding) - self.assertEqual(ms_binding.multi_segment_id, TEST_NETWORK_ID) - self.assertEqual(ms_binding.segment1_id, TEST_NETWORK_ID2) - self.assertEqual(ms_binding.segment2_id, TEST_NETWORK_ID3) - ms_members = (n1kv_db_v2.get_multi_segment_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(ms_members, - [(TEST_NETWORK_ID2, TEST_NETWORK_ID3)]) - self.assertTrue(n1kv_db_v2.is_multi_segment_member( - self.session, TEST_NETWORK_ID2)) - self.assertTrue(n1kv_db_v2.is_multi_segment_member( - self.session, TEST_NETWORK_ID3)) - n1kv_db_v2.del_multi_segment_binding( - self.session, TEST_NETWORK_ID, - [(TEST_NETWORK_ID2, TEST_NETWORK_ID3)]) - ms_members = (n1kv_db_v2.get_multi_segment_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(ms_members, []) - - def test_create_vlan_trunk_network(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_VLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, 'trunk', - None, 0, '0.0.0.0', p.id, None) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, 'trunk') - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - - def test_create_vxlan_trunk_network(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_VXLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, 'trunk', - None, 0, '0.0.0.0', p.id, None) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, 'trunk') - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - - def test_add_vlan_trunk_binding(self): - with self.network() as network1: - with self.network() as network2: - TEST_NETWORK_ID = network1['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - TEST_NETWORK_ID2 = network2['network']['id'] - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID2) - p_v = _create_test_network_profile_if_not_there(self.session) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID2, 'vlan', - PHYS_NET, 1234, '0.0.0.0', p_v.id, None) - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_VLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, 'trunk', - None, 0, '0.0.0.0', p.id, [(TEST_NETWORK_ID2, 0)]) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, 'trunk') - self.assertEqual(binding.physical_network, PHYS_NET) - self.assertEqual(binding.segmentation_id, 0) - t_binding = (n1kv_db_v2.get_trunk_network_binding( - self.session, TEST_NETWORK_ID, - (TEST_NETWORK_ID2, 0))) - self.assertIsNotNone(t_binding) - self.assertEqual(t_binding.trunk_segment_id, TEST_NETWORK_ID) - self.assertEqual(t_binding.segment_id, TEST_NETWORK_ID2) - self.assertEqual(t_binding.dot1qtag, '0') - t_members = (n1kv_db_v2.get_trunk_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(t_members, - [(TEST_NETWORK_ID2, '0')]) - self.assertTrue(n1kv_db_v2.is_trunk_member( - self.session, TEST_NETWORK_ID2)) - n1kv_db_v2.del_trunk_segment_binding( - self.session, TEST_NETWORK_ID, - [(TEST_NETWORK_ID2, '0')]) - t_members = (n1kv_db_v2.get_multi_segment_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(t_members, []) - - def test_add_vxlan_trunk_binding(self): - with self.network() as network1: - with self.network() as network2: - TEST_NETWORK_ID = network1['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - TEST_NETWORK_ID2 = network2['network']['id'] - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID2) - p_v = _create_test_network_profile_if_not_there( - self.session, TEST_NETWORK_PROFILE_VXLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID2, 'overlay', - None, 5100, '224.10.10.10', p_v.id, None) - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_VXLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, 'trunk', - None, 0, '0.0.0.0', p.id, - [(TEST_NETWORK_ID2, 5)]) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, 'trunk') - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - t_binding = (n1kv_db_v2.get_trunk_network_binding( - self.session, TEST_NETWORK_ID, - (TEST_NETWORK_ID2, '5'))) - self.assertIsNotNone(t_binding) - self.assertEqual(t_binding.trunk_segment_id, TEST_NETWORK_ID) - self.assertEqual(t_binding.segment_id, TEST_NETWORK_ID2) - self.assertEqual(t_binding.dot1qtag, '5') - t_members = (n1kv_db_v2.get_trunk_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(t_members, - [(TEST_NETWORK_ID2, '5')]) - self.assertTrue(n1kv_db_v2.is_trunk_member( - self.session, TEST_NETWORK_ID2)) - n1kv_db_v2.del_trunk_segment_binding( - self.session, TEST_NETWORK_ID, - [(TEST_NETWORK_ID2, '5')]) - t_members = (n1kv_db_v2.get_multi_segment_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(t_members, []) - - -class NetworkProfileTests(base.BaseTestCase, - n1kv_db_v2.NetworkProfile_db_mixin): - - def setUp(self): - super(NetworkProfileTests, self).setUp() - db.configure_db() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_create_network_profile(self): - _db_profile = n1kv_db_v2.create_network_profile(self.session, - TEST_NETWORK_PROFILE) - self.assertIsNotNone(_db_profile) - db_profile = (self.session.query(n1kv_models_v2.NetworkProfile). - filter_by(name=TEST_NETWORK_PROFILE['name']).one()) - self.assertIsNotNone(db_profile) - self.assertEqual(_db_profile.id, db_profile.id) - self.assertEqual(_db_profile.name, db_profile.name) - self.assertEqual(_db_profile.segment_type, db_profile.segment_type) - self.assertEqual(_db_profile.segment_range, db_profile.segment_range) - self.assertEqual(_db_profile.multicast_ip_index, - db_profile.multicast_ip_index) - self.assertEqual(_db_profile.multicast_ip_range, - db_profile.multicast_ip_range) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_create_multi_segment_network_profile(self): - _db_profile = (n1kv_db_v2.create_network_profile( - self.session, TEST_NETWORK_PROFILE_MULTI_SEGMENT)) - self.assertIsNotNone(_db_profile) - db_profile = ( - self.session.query( - n1kv_models_v2.NetworkProfile).filter_by( - name=TEST_NETWORK_PROFILE_MULTI_SEGMENT['name']) - .one()) - self.assertIsNotNone(db_profile) - self.assertEqual(_db_profile.id, db_profile.id) - self.assertEqual(_db_profile.name, db_profile.name) - self.assertEqual(_db_profile.segment_type, db_profile.segment_type) - self.assertEqual(_db_profile.segment_range, db_profile.segment_range) - self.assertEqual(_db_profile.multicast_ip_index, - db_profile.multicast_ip_index) - self.assertEqual(_db_profile.multicast_ip_range, - db_profile.multicast_ip_range) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_create_vlan_trunk_network_profile(self): - _db_profile = (n1kv_db_v2.create_network_profile( - self.session, TEST_NETWORK_PROFILE_VLAN_TRUNK)) - self.assertIsNotNone(_db_profile) - db_profile = (self.session.query(n1kv_models_v2.NetworkProfile). - filter_by(name=TEST_NETWORK_PROFILE_VLAN_TRUNK['name']). - one()) - self.assertIsNotNone(db_profile) - self.assertEqual(_db_profile.id, db_profile.id) - self.assertEqual(_db_profile.name, db_profile.name) - self.assertEqual(_db_profile.segment_type, db_profile.segment_type) - self.assertEqual(_db_profile.segment_range, db_profile.segment_range) - self.assertEqual(_db_profile.multicast_ip_index, - db_profile.multicast_ip_index) - self.assertEqual(_db_profile.multicast_ip_range, - db_profile.multicast_ip_range) - self.assertEqual(_db_profile.sub_type, db_profile.sub_type) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_create_vxlan_trunk_network_profile(self): - _db_profile = (n1kv_db_v2.create_network_profile( - self.session, TEST_NETWORK_PROFILE_VXLAN_TRUNK)) - self.assertIsNotNone(_db_profile) - db_profile = (self.session.query(n1kv_models_v2.NetworkProfile). - filter_by(name=TEST_NETWORK_PROFILE_VXLAN_TRUNK['name']). - one()) - self.assertIsNotNone(db_profile) - self.assertEqual(_db_profile.id, db_profile.id) - self.assertEqual(_db_profile.name, db_profile.name) - self.assertEqual(_db_profile.segment_type, db_profile.segment_type) - self.assertEqual(_db_profile.segment_range, db_profile.segment_range) - self.assertEqual(_db_profile.multicast_ip_index, - db_profile.multicast_ip_index) - self.assertEqual(_db_profile.multicast_ip_range, - db_profile.multicast_ip_range) - self.assertEqual(_db_profile.sub_type, db_profile.sub_type) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_create_network_profile_overlap(self): - _db_profile = n1kv_db_v2.create_network_profile(self.session, - TEST_NETWORK_PROFILE_2) - ctx = context.get_admin_context() - TEST_NETWORK_PROFILE_2['name'] = 'net-profile-min-overlap' - TEST_NETWORK_PROFILE_2['segment_range'] = SEGMENT_RANGE_MIN_OVERLAP - test_net_profile = {'network_profile': TEST_NETWORK_PROFILE_2} - self.assertRaises(n_exc.InvalidInput, - self.create_network_profile, - ctx, - test_net_profile) - - TEST_NETWORK_PROFILE_2['name'] = 'net-profile-max-overlap' - TEST_NETWORK_PROFILE_2['segment_range'] = SEGMENT_RANGE_MAX_OVERLAP - test_net_profile = {'network_profile': TEST_NETWORK_PROFILE_2} - self.assertRaises(n_exc.InvalidInput, - self.create_network_profile, - ctx, - test_net_profile) - - TEST_NETWORK_PROFILE_2['name'] = 'net-profile-overlap' - TEST_NETWORK_PROFILE_2['segment_range'] = SEGMENT_RANGE_OVERLAP - test_net_profile = {'network_profile': TEST_NETWORK_PROFILE_2} - self.assertRaises(n_exc.InvalidInput, - self.create_network_profile, - ctx, - test_net_profile) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_delete_network_profile(self): - try: - profile = (self.session.query(n1kv_models_v2.NetworkProfile). - filter_by(name=TEST_NETWORK_PROFILE['name']).one()) - except s_exc.NoResultFound: - profile = n1kv_db_v2.create_network_profile(self.session, - TEST_NETWORK_PROFILE) - - n1kv_db_v2.delete_network_profile(self.session, profile.id) - try: - self.session.query(n1kv_models_v2.NetworkProfile).filter_by( - name=TEST_NETWORK_PROFILE['name']).one() - except s_exc.NoResultFound: - pass - else: - self.fail("Network Profile (%s) was not deleted" % - TEST_NETWORK_PROFILE['name']) - - def test_update_network_profile(self): - TEST_PROFILE_1 = {'name': 'test_profile_1'} - profile = _create_test_network_profile_if_not_there(self.session) - updated_profile = n1kv_db_v2.update_network_profile(self.session, - profile.id, - TEST_PROFILE_1) - self.assertEqual(updated_profile.name, TEST_PROFILE_1['name']) - n1kv_db_v2.delete_network_profile(self.session, profile.id) - - def test_get_network_profile(self): - profile = n1kv_db_v2.create_network_profile(self.session, - TEST_NETWORK_PROFILE) - got_profile = n1kv_db_v2.get_network_profile(self.session, profile.id) - self.assertEqual(profile.id, got_profile.id) - self.assertEqual(profile.name, got_profile.name) - n1kv_db_v2.delete_network_profile(self.session, profile.id) - - def test_get_network_profiles(self): - test_profiles = [{'name': 'test_profile1', - 'segment_type': 'vlan', - 'physical_network': 'phys1', - 'segment_range': '200-210'}, - {'name': 'test_profile2', - 'segment_type': 'vlan', - 'physical_network': 'phys1', - 'segment_range': '211-220'}, - {'name': 'test_profile3', - 'segment_type': 'vlan', - 'physical_network': 'phys1', - 'segment_range': '221-230'}, - {'name': 'test_profile4', - 'segment_type': 'vlan', - 'physical_network': 'phys1', - 'segment_range': '231-240'}, - {'name': 'test_profile5', - 'segment_type': 'vlan', - 'physical_network': 'phys1', - 'segment_range': '241-250'}, - {'name': 'test_profile6', - 'segment_type': 'vlan', - 'physical_network': 'phys1', - 'segment_range': '251-260'}, - {'name': 'test_profile7', - 'segment_type': 'vlan', - 'physical_network': 'phys1', - 'segment_range': '261-270'}] - [n1kv_db_v2.create_network_profile(self.session, p) - for p in test_profiles] - # TODO(abhraut): Fix this test to work with real tenant_td - profiles = n1kv_db_v2._get_network_profiles(db_session=self.session) - self.assertEqual(len(test_profiles), len(list(profiles))) - - -class PolicyProfileTests(base.BaseTestCase): - - def setUp(self): - super(PolicyProfileTests, self).setUp() - db.configure_db() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_create_policy_profile(self): - _db_profile = n1kv_db_v2.create_policy_profile(TEST_POLICY_PROFILE) - self.assertIsNotNone(_db_profile) - db_profile = (self.session.query(n1kv_models_v2.PolicyProfile). - filter_by(name=TEST_POLICY_PROFILE['name']).one)() - self.assertIsNotNone(db_profile) - self.assertTrue(_db_profile.id == db_profile.id) - self.assertTrue(_db_profile.name == db_profile.name) - - def test_delete_policy_profile(self): - profile = _create_test_policy_profile_if_not_there(self.session) - n1kv_db_v2.delete_policy_profile(profile.id) - try: - self.session.query(n1kv_models_v2.PolicyProfile).filter_by( - name=TEST_POLICY_PROFILE['name']).one() - except s_exc.NoResultFound: - pass - else: - self.fail("Policy Profile (%s) was not deleted" % - TEST_POLICY_PROFILE['name']) - - def test_update_policy_profile(self): - TEST_PROFILE_1 = {'name': 'test_profile_1'} - profile = _create_test_policy_profile_if_not_there(self.session) - updated_profile = n1kv_db_v2.update_policy_profile(self.session, - profile.id, - TEST_PROFILE_1) - self.assertEqual(updated_profile.name, TEST_PROFILE_1['name']) - - def test_get_policy_profile(self): - profile = _create_test_policy_profile_if_not_there(self.session) - got_profile = n1kv_db_v2.get_policy_profile(self.session, profile.id) - self.assertEqual(profile.id, got_profile.id) - self.assertEqual(profile.name, got_profile.name) - - -class ProfileBindingTests(base.BaseTestCase, - n1kv_db_v2.NetworkProfile_db_mixin, - db_base_plugin_v2.CommonDbMixin): - - def setUp(self): - super(ProfileBindingTests, self).setUp() - db.configure_db() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def _create_test_binding_if_not_there(self, tenant_id, profile_id, - profile_type): - try: - _binding = (self.session.query(n1kv_models_v2.ProfileBinding). - filter_by(profile_type=profile_type, - tenant_id=tenant_id, - profile_id=profile_id).one()) - except s_exc.NoResultFound: - _binding = n1kv_db_v2.create_profile_binding(self.session, - tenant_id, - profile_id, - profile_type) - return _binding - - def test_create_profile_binding(self): - test_tenant_id = "d434dd90-76ec-11e2-bcfd-0800200c9a66" - test_profile_id = "dd7b9741-76ec-11e2-bcfd-0800200c9a66" - test_profile_type = "network" - n1kv_db_v2.create_profile_binding(self.session, - test_tenant_id, - test_profile_id, - test_profile_type) - try: - self.session.query(n1kv_models_v2.ProfileBinding).filter_by( - profile_type=test_profile_type, - tenant_id=test_tenant_id, - profile_id=test_profile_id).one() - except s_exc.MultipleResultsFound: - self.fail("Bindings must be unique") - except s_exc.NoResultFound: - self.fail("Could not create Profile Binding") - - def test_get_profile_binding(self): - test_tenant_id = "d434dd90-76ec-11e2-bcfd-0800200c9a66" - test_profile_id = "dd7b9741-76ec-11e2-bcfd-0800200c9a66" - test_profile_type = "network" - self._create_test_binding_if_not_there(test_tenant_id, - test_profile_id, - test_profile_type) - binding = n1kv_db_v2.get_profile_binding(self.session, - test_tenant_id, - test_profile_id) - self.assertEqual(binding.tenant_id, test_tenant_id) - self.assertEqual(binding.profile_id, test_profile_id) - self.assertEqual(binding.profile_type, test_profile_type) - - def test_get_profile_binding_not_found(self): - self.assertRaises( - c_exc.ProfileTenantBindingNotFound, - n1kv_db_v2.get_profile_binding, self.session, "123", "456") - - def test_delete_profile_binding(self): - test_tenant_id = "d434dd90-76ec-11e2-bcfd-0800200c9a66" - test_profile_id = "dd7b9741-76ec-11e2-bcfd-0800200c9a66" - test_profile_type = "network" - self._create_test_binding_if_not_there(test_tenant_id, - test_profile_id, - test_profile_type) - n1kv_db_v2.delete_profile_binding(self.session, - test_tenant_id, - test_profile_id) - q = (self.session.query(n1kv_models_v2.ProfileBinding).filter_by( - profile_type=test_profile_type, - tenant_id=test_tenant_id, - profile_id=test_profile_id)) - self.assertFalse(q.count()) - - def test_default_tenant_replace(self): - ctx = context.get_admin_context() - ctx.tenant_id = "d434dd90-76ec-11e2-bcfd-0800200c9a66" - test_profile_id = "AAAAAAAA-76ec-11e2-bcfd-0800200c9a66" - test_profile_type = "policy" - n1kv_db_v2.create_profile_binding(self.session, - cisco_constants.TENANT_ID_NOT_SET, - test_profile_id, - test_profile_type) - network_profile = {"network_profile": TEST_NETWORK_PROFILE} - self.create_network_profile(ctx, network_profile) - binding = n1kv_db_v2.get_profile_binding(self.session, - ctx.tenant_id, - test_profile_id) - self.assertRaises( - c_exc.ProfileTenantBindingNotFound, - n1kv_db_v2.get_profile_binding, - self.session, - cisco_constants.TENANT_ID_NOT_SET, - test_profile_id) - self.assertNotEqual(binding.tenant_id, - cisco_constants.TENANT_ID_NOT_SET) diff --git a/neutron/tests/unit/cisco/n1kv/test_n1kv_plugin.py b/neutron/tests/unit/cisco/n1kv/test_n1kv_plugin.py deleted file mode 100644 index b2d29de61..000000000 --- a/neutron/tests/unit/cisco/n1kv/test_n1kv_plugin.py +++ /dev/null @@ -1,709 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Cisco Systems, Inc. -# -# 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. -# -# @author: Juergen Brendel, Cisco Systems Inc. -# @author: Abhishek Raut, Cisco Systems Inc. -# @author: Sourabh Patwardhan, Cisco Systems Inc. - -import mock - -from neutron.api import extensions as neutron_extensions -from neutron.api.v2 import attributes -from neutron import context -import neutron.db.api as db -from neutron.extensions import portbindings -from neutron import manager -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.db import n1kv_db_v2 -from neutron.plugins.cisco.db import network_db_v2 as cdb -from neutron.plugins.cisco import extensions -from neutron.plugins.cisco.extensions import n1kv -from neutron.plugins.cisco.extensions import network_profile -from neutron.plugins.cisco.n1kv import n1kv_client -from neutron.plugins.cisco.n1kv import n1kv_neutron_plugin -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit.cisco.n1kv import fake_client -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_l3_plugin -from neutron.tests.unit import test_l3_schedulers - - -PHYS_NET = 'some-phys-net' -VLAN_MIN = 100 -VLAN_MAX = 110 - - -class FakeResponse(object): - - """ - This object is returned by mocked requests lib instead of normal response. - - Initialize it with the status code, header and buffer contents you wish to - return. - - """ - def __init__(self, status, response_text, headers): - self.buffer = response_text - self.status_code = status - self.headers = headers - - def json(self, *args, **kwargs): - return self.buffer - - -def _fake_setup_vsm(self): - """Fake establish Communication with Cisco Nexus1000V VSM.""" - self.agent_vsm = True - self._populate_policy_profiles() - - -class NetworkProfileTestExtensionManager(object): - - def get_resources(self): - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - network_profile.RESOURCE_ATTRIBUTE_MAP) - return network_profile.Network_profile.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class N1kvPluginTestCase(test_plugin.NeutronDbPluginV2TestCase): - - _plugin_name = ('neutron.plugins.cisco.n1kv.' - 'n1kv_neutron_plugin.N1kvNeutronPluginV2') - - tenant_id = "some_tenant" - - DEFAULT_RESP_BODY = "" - DEFAULT_RESP_CODE = 200 - DEFAULT_CONTENT_TYPE = "" - fmt = "json" - - def _make_test_policy_profile(self, name='service_profile'): - """ - Create a policy profile record for testing purpose. - - :param name: string representing the name of the policy profile to - create. Default argument value chosen to correspond to the - default name specified in config.py file. - """ - uuid = test_api_v2._uuid() - profile = {'id': uuid, - 'name': name} - return n1kv_db_v2.create_policy_profile(profile) - - def _make_test_profile(self, - name='default_network_profile', - segment_range='386-400'): - """ - Create a profile record for testing purposes. - - :param name: string representing the name of the network profile to - create. Default argument value chosen to correspond to the - default name specified in config.py file. - :param segment_range: string representing the segment range for network - profile. - """ - db_session = db.get_session() - profile = {'name': name, - 'segment_type': 'vlan', - 'physical_network': PHYS_NET, - 'tenant_id': self.tenant_id, - 'segment_range': segment_range} - net_p = n1kv_db_v2.create_network_profile(db_session, profile) - n1kv_db_v2.sync_vlan_allocations(db_session, net_p) - return net_p - - def setUp(self): - """ - Setup method for n1kv plugin tests. - - First step is to define an acceptable response from the VSM to - our requests. This needs to be done BEFORE the setUp() function - of the super-class is called. - - This default here works for many cases. If you need something - extra, please define your own setUp() function in your test class, - and set your DEFAULT_RESPONSE value also BEFORE calling the - setUp() of the super-function (this one here). If you have set - a value already, it will not be overwritten by this code. - - """ - if not self.DEFAULT_RESP_BODY: - self.DEFAULT_RESP_BODY = { - "icehouse-pp": {"properties": {"name": "icehouse-pp", - "id": "some-uuid-1"}}, - "havana_pp": {"properties": {"name": "havana_pp", - "id": "some-uuid-2"}}, - "dhcp_pp": {"properties": {"name": "dhcp_pp", - "id": "some-uuid-3"}}, - } - # Creating a mock HTTP connection object for requests lib. The N1KV - # client interacts with the VSM via HTTP. Since we don't have a VSM - # running in the unit tests, we need to 'fake' it by patching the HTTP - # library itself. We install a patch for a fake HTTP connection class. - # Using __name__ to avoid having to enter the full module path. - http_patcher = mock.patch(n1kv_client.requests.__name__ + ".request") - FakeHttpConnection = http_patcher.start() - # Now define the return values for a few functions that may be called - # on any instance of the fake HTTP connection class. - self.resp_headers = {"content-type": "application/json"} - FakeHttpConnection.return_value = (FakeResponse( - self.DEFAULT_RESP_CODE, - self.DEFAULT_RESP_BODY, - self.resp_headers)) - - # Patch some internal functions in a few other parts of the system. - # These help us move along, without having to mock up even more systems - # in the background. - - # Return a dummy VSM IP address - mock.patch(n1kv_client.__name__ + ".Client._get_vsm_hosts", - new=lambda self: "127.0.0.1").start() - - # Return dummy user profiles - mock.patch(cdb.__name__ + ".get_credential_name", - new=lambda self: {"user_name": "admin", - "password": "admin_password"}).start() - - n1kv_neutron_plugin.N1kvNeutronPluginV2._setup_vsm = _fake_setup_vsm - - neutron_extensions.append_api_extensions_path(extensions.__path__) - ext_mgr = NetworkProfileTestExtensionManager() - - # Save the original RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.items(): - self.saved_attr_map[resource] = attrs.copy() - # Update the RESOURCE_ATTRIBUTE_MAP with n1kv specific extended attrs. - attributes.RESOURCE_ATTRIBUTE_MAP["networks"].update( - n1kv.EXTENDED_ATTRIBUTES_2_0["networks"]) - attributes.RESOURCE_ATTRIBUTE_MAP["ports"].update( - n1kv.EXTENDED_ATTRIBUTES_2_0["ports"]) - self.addCleanup(self.restore_resource_attribute_map) - self.addCleanup(db.clear_db) - super(N1kvPluginTestCase, self).setUp(self._plugin_name, - ext_mgr=ext_mgr) - # Create some of the database entries that we require. - self._make_test_profile() - self._make_test_policy_profile() - - def restore_resource_attribute_map(self): - # Restore the original RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - - def test_plugin(self): - self._make_network('json', - 'some_net', - True, - tenant_id=self.tenant_id, - set_context=True) - - req = self.new_list_request('networks', params="fields=tenant_id") - req.environ['neutron.context'] = context.Context('', self.tenant_id) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 200) - body = self.deserialize('json', res) - self.assertIn('tenant_id', body['networks'][0]) - - -class TestN1kvNetworkProfiles(N1kvPluginTestCase): - def _prepare_net_profile_data(self, segment_type): - netp = {'network_profile': {'name': 'netp1', - 'segment_type': segment_type, - 'tenant_id': self.tenant_id}} - if segment_type == 'vlan': - netp['network_profile']['segment_range'] = '100-110' - netp['network_profile']['physical_network'] = PHYS_NET - elif segment_type == 'overlay': - netp['network_profile']['segment_range'] = '10000-10010' - netp['network_profile']['sub_type'] = 'enhanced' or 'native_vxlan' - netp['network_profile']['multicast_ip_range'] = ("224.1.1.1-" - "224.1.1.10") - elif segment_type == 'trunk': - netp['network_profile']['sub_type'] = 'vlan' - return netp - - def test_create_network_profile_vlan(self): - data = self._prepare_net_profile_data('vlan') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - - def test_create_network_profile_overlay(self): - data = self._prepare_net_profile_data('overlay') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - - def test_create_network_profile_trunk(self): - data = self._prepare_net_profile_data('trunk') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - - def test_create_network_profile_trunk_missing_subtype(self): - data = self._prepare_net_profile_data('trunk') - data['network_profile'].pop('sub_type') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_network_profile_overlay_unreasonable_seg_range(self): - data = self._prepare_net_profile_data('overlay') - data['network_profile']['segment_range'] = '10000-100000000001' - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_network_profile_plugin(self): - net_p_dict = self._prepare_net_profile_data('overlay') - net_p_req = self.new_create_request('network_profiles', net_p_dict) - net_p = self.deserialize(self.fmt, - net_p_req.get_response(self.ext_api)) - data = {'network_profile': {'name': 'netp2'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 200) - - def test_update_network_profile_physical_network_fail(self): - net_p = self._make_test_profile(name='netp1') - data = {'network_profile': {'physical_network': PHYS_NET}} - net_p_req = self.new_update_request('network_profiles', - data, - net_p['id']) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_network_profile_segment_type_fail(self): - net_p = self._make_test_profile(name='netp1') - data = {'network_profile': {'segment_type': 'overlay'}} - net_p_req = self.new_update_request('network_profiles', - data, - net_p['id']) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_network_profile_sub_type_fail(self): - net_p_dict = self._prepare_net_profile_data('overlay') - net_p_req = self.new_create_request('network_profiles', net_p_dict) - net_p = self.deserialize(self.fmt, - net_p_req.get_response(self.ext_api)) - data = {'network_profile': {'sub_type': 'vlan'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_update_network_profiles_with_networks_fail(self): - net_p = self._make_test_profile(name='netp1') - data = {'network_profile': {'segment_range': '200-210'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 200) - net_data = {'network': {'name': 'net1', - n1kv.PROFILE_ID: net_p['id'], - 'tenant_id': 'some_tenant'}} - network_req = self.new_create_request('networks', net_data) - network_res = network_req.get_response(self.api) - self.assertEqual(network_res.status_int, 201) - data = {'network_profile': {'segment_range': '300-310'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 409) - - def test_create_overlay_network_profile_invalid_multicast_fail(self): - net_p_dict = self._prepare_net_profile_data('overlay') - data = {'network_profile': {'sub_type': 'native_vxlan', - 'multicast_ip_range': '1.1.1.1'}} - net_p_req = self.new_create_request('network_profiles', data, - net_p_dict) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_no_multicast_fail(self): - net_p_dict = self._prepare_net_profile_data('overlay') - data = {'network_profile': {'sub_type': 'native_vxlan', - 'multicast_ip_range': ''}} - net_p_req = self.new_create_request('network_profiles', data, - net_p_dict) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_wrong_split_multicast_fail(self): - net_p_dict = self._prepare_net_profile_data('overlay') - data = {'network_profile': { - 'sub_type': 'native_vxlan', - 'multicast_ip_range': '224.1.1.1.224.1.1.3'}} - net_p_req = self.new_create_request('network_profiles', data, - net_p_dict) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_invalid_minip_multicast_fail(self): - net_p_dict = self._prepare_net_profile_data('overlay') - data = {'network_profile': { - 'sub_type': 'native_vxlan', - 'multicast_ip_range': '10.0.0.1-224.1.1.3'}} - net_p_req = self.new_create_request('network_profiles', data, - net_p_dict) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_invalid_maxip_multicast_fail(self): - net_p_dict = self._prepare_net_profile_data('overlay') - data = {'network_profile': { - 'sub_type': 'native_vxlan', - 'multicast_ip_range': '224.1.1.1-20.0.0.1'}} - net_p_req = self.new_create_request('network_profiles', data, - net_p_dict) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_correct_multicast_pass(self): - data = self._prepare_net_profile_data('overlay') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - - def test_update_overlay_network_profile_correct_multicast_pass(self): - data = self._prepare_net_profile_data('overlay') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - net_p = self.deserialize(self.fmt, res) - data = {'network_profile': {'multicast_ip_range': - '224.0.1.0-224.0.1.100'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 200) - - def test_create_overlay_network_profile_reservedip_multicast_fail(self): - net_p_dict = self._prepare_net_profile_data('overlay') - data = {'network_profile': {'multicast_ip_range': - '224.0.0.100-224.0.1.100'}} - net_p_req = self.new_create_request('network_profiles', data, - net_p_dict) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_overlay_network_profile_reservedip_multicast_fail(self): - data = self._prepare_net_profile_data('overlay') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - net_p = self.deserialize(self.fmt, res) - data = {'network_profile': {'multicast_ip_range': - '224.0.0.11-224.0.0.111'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_update_vlan_network_profile_multicast_fail(self): - net_p = self._make_test_profile(name='netp1') - data = {'network_profile': {'multicast_ip_range': - '224.0.1.0-224.0.1.100'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_update_trunk_network_profile_segment_range_fail(self): - data = self._prepare_net_profile_data('trunk') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - net_p = self.deserialize(self.fmt, res) - data = {'network_profile': {'segment_range': - '100-200'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_update_trunk_network_profile_multicast_fail(self): - data = self._prepare_net_profile_data('trunk') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - net_p = self.deserialize(self.fmt, res) - data = {'network_profile': {'multicast_ip_range': - '224.0.1.0-224.0.1.100'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_create_network_profile_populate_vlan_segment_pool(self): - db_session = db.get_session() - net_p_dict = self._prepare_net_profile_data('vlan') - net_p_req = self.new_create_request('network_profiles', net_p_dict) - self.deserialize(self.fmt, - net_p_req.get_response(self.ext_api)) - for vlan in range(VLAN_MIN, VLAN_MAX + 1): - self.assertIsNotNone(n1kv_db_v2.get_vlan_allocation(db_session, - PHYS_NET, - vlan)) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(db_session, - PHYS_NET, - vlan).allocated) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - db_session, - PHYS_NET, - VLAN_MIN - 1) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - db_session, - PHYS_NET, - VLAN_MAX + 1) - - def test_delete_network_profile_with_network_fail(self): - net_p = self._make_test_profile(name='netp1') - net_data = {'network': {'name': 'net1', - n1kv.PROFILE_ID: net_p['id'], - 'tenant_id': 'some_tenant'}} - network_req = self.new_create_request('networks', net_data) - network_res = network_req.get_response(self.api) - self.assertEqual(network_res.status_int, 201) - self._delete('network_profiles', net_p['id'], - expected_code=409) - - def test_delete_network_profile_deallocate_vlan_segment_pool(self): - db_session = db.get_session() - net_p_dict = self._prepare_net_profile_data('vlan') - net_p_req = self.new_create_request('network_profiles', net_p_dict) - net_p = self.deserialize(self.fmt, - net_p_req.get_response(self.ext_api)) - self.assertIsNotNone(n1kv_db_v2.get_vlan_allocation(db_session, - PHYS_NET, - VLAN_MIN)) - self._delete('network_profiles', net_p['network_profile']['id']) - for vlan in range(VLAN_MIN, VLAN_MAX + 1): - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - db_session, - PHYS_NET, - vlan) - - -class TestN1kvBasicGet(test_plugin.TestBasicGet, - N1kvPluginTestCase): - - pass - - -class TestN1kvHTTPResponse(test_plugin.TestV2HTTPResponse, - N1kvPluginTestCase): - - pass - - -class TestN1kvPorts(test_plugin.TestPortsV2, - N1kvPluginTestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - HAS_PORT_FILTER = False - - def test_create_port_with_default_n1kv_policy_profile_id(self): - """Test port create without passing policy profile id.""" - with self.port() as port: - db_session = db.get_session() - pp = n1kv_db_v2.get_policy_profile( - db_session, port['port'][n1kv.PROFILE_ID]) - self.assertEqual(pp['name'], 'service_profile') - - def test_create_port_with_n1kv_policy_profile_id(self): - """Test port create with policy profile id.""" - profile_obj = self._make_test_policy_profile(name='test_profile') - with self.network() as network: - data = {'port': {n1kv.PROFILE_ID: profile_obj.id, - 'tenant_id': self.tenant_id, - 'network_id': network['network']['id']}} - port_req = self.new_create_request('ports', data) - port = self.deserialize(self.fmt, - port_req.get_response(self.api)) - self.assertEqual(port['port'][n1kv.PROFILE_ID], - profile_obj.id) - self._delete('ports', port['port']['id']) - - def test_update_port_with_n1kv_policy_profile_id(self): - """Test port update failure while updating policy profile id.""" - with self.port() as port: - data = {'port': {n1kv.PROFILE_ID: 'some-profile-uuid'}} - port_req = self.new_update_request('ports', - data, - port['port']['id']) - res = port_req.get_response(self.api) - # Port update should fail to update policy profile id. - self.assertEqual(res.status_int, 400) - - def test_create_first_port_invalid_parameters_fail(self): - """Test parameters for first port create sent to the VSM.""" - profile_obj = self._make_test_policy_profile(name='test_profile') - with self.network() as network: - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClientInvalidRequest) - client_patch.start() - data = {'port': {n1kv.PROFILE_ID: profile_obj.id, - 'tenant_id': self.tenant_id, - 'network_id': network['network']['id'], - }} - port_req = self.new_create_request('ports', data) - res = port_req.get_response(self.api) - self.assertEqual(res.status_int, 500) - client_patch.stop() - - def test_create_next_port_invalid_parameters_fail(self): - """Test parameters for subsequent port create sent to the VSM.""" - with self.port() as port: - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClientInvalidRequest) - client_patch.start() - data = {'port': {n1kv.PROFILE_ID: port['port']['n1kv:profile_id'], - 'tenant_id': port['port']['tenant_id'], - 'network_id': port['port']['network_id']}} - port_req = self.new_create_request('ports', data) - res = port_req.get_response(self.api) - self.assertEqual(res.status_int, 500) - client_patch.stop() - - -class TestN1kvPolicyProfiles(N1kvPluginTestCase): - def test_populate_policy_profile(self): - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClient) - client_patch.start() - instance = n1kv_neutron_plugin.N1kvNeutronPluginV2() - instance._populate_policy_profiles() - db_session = db.get_session() - profile = n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000001') - self.assertEqual('pp-1', profile['name']) - client_patch.stop() - - def test_populate_policy_profile_delete(self): - # Patch the Client class with the TestClient class - with mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClient): - # Patch the _get_total_profiles() method to return a custom value - with mock.patch(fake_client.__name__ + - '.TestClient._get_total_profiles') as obj_inst: - # Return 3 policy profiles - obj_inst.return_value = 3 - plugin = manager.NeutronManager.get_plugin() - plugin._populate_policy_profiles() - db_session = db.get_session() - profile = n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000001') - # Verify that DB contains only 3 policy profiles - self.assertEqual('pp-1', profile['name']) - profile = n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000002') - self.assertEqual('pp-2', profile['name']) - profile = n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000003') - self.assertEqual('pp-3', profile['name']) - self.assertRaises(c_exc.PolicyProfileIdNotFound, - n1kv_db_v2.get_policy_profile, - db_session, - '00000000-0000-0000-0000-000000000004') - # Return 2 policy profiles - obj_inst.return_value = 2 - plugin._populate_policy_profiles() - # Verify that the third policy profile is deleted - self.assertRaises(c_exc.PolicyProfileIdNotFound, - n1kv_db_v2.get_policy_profile, - db_session, - '00000000-0000-0000-0000-000000000003') - - -class TestN1kvNetworks(test_plugin.TestNetworksV2, - N1kvPluginTestCase): - - def _prepare_net_data(self, net_profile_id): - return {'network': {'name': 'net1', - n1kv.PROFILE_ID: net_profile_id, - 'tenant_id': self.tenant_id}} - - def test_create_network_with_default_n1kv_network_profile_id(self): - """Test network create without passing network profile id.""" - with self.network() as network: - db_session = db.get_session() - np = n1kv_db_v2.get_network_profile( - db_session, network['network'][n1kv.PROFILE_ID]) - self.assertEqual(np['name'], 'default_network_profile') - - def test_create_network_with_n1kv_network_profile_id(self): - """Test network create with network profile id.""" - profile_obj = self._make_test_profile(name='test_profile') - data = self._prepare_net_data(profile_obj.id) - network_req = self.new_create_request('networks', data) - network = self.deserialize(self.fmt, - network_req.get_response(self.api)) - self.assertEqual(network['network'][n1kv.PROFILE_ID], - profile_obj.id) - - def test_update_network_with_n1kv_network_profile_id(self): - """Test network update failure while updating network profile id.""" - with self.network() as network: - data = {'network': {n1kv.PROFILE_ID: 'some-profile-uuid'}} - network_req = self.new_update_request('networks', - data, - network['network']['id']) - res = network_req.get_response(self.api) - # Network update should fail to update network profile id. - self.assertEqual(res.status_int, 400) - - -class TestN1kvSubnets(test_plugin.TestSubnetsV2, - N1kvPluginTestCase): - - def setUp(self): - super(TestN1kvSubnets, self).setUp() - - -class TestN1kvL3Test(test_l3_plugin.L3NatExtensionTestCase): - - pass - - -class TestN1kvL3SchedulersTest(test_l3_schedulers.L3SchedulerTestCase): - - pass diff --git a/neutron/tests/unit/cisco/test_config.py b/neutron/tests/unit/cisco/test_config.py deleted file mode 100644 index 7104ed06a..000000000 --- a/neutron/tests/unit/cisco/test_config.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) 2013 Cisco Systems Inc. -# -# 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 oslo.config import cfg - -from neutron.plugins.cisco.common import config as cisco_config -from neutron.tests import base - - -class TestCiscoNexusPluginConfig(base.BaseTestCase): - - def setUp(self): - # Point neutron config file to: neutron/tests/etc/neutron.conf.test - self.config_parse() - - super(TestCiscoNexusPluginConfig, self).setUp() - - def test_config_parse_error(self): - """Check that config error is raised upon config parser failure.""" - with mock.patch.object(cfg, 'MultiConfigParser') as parser: - parser.return_value.read.return_value = [] - self.assertRaises(cfg.Error, cisco_config.CiscoConfigOptions) - - def test_create_device_dictionary(self): - """Test creation of the device dictionary based on nexus config.""" - test_config = { - 'NEXUS_SWITCH:1.1.1.1': { - 'username': ['admin'], - 'password': ['mySecretPassword'], - 'ssh_port': [22], - 'compute1': ['1/1'], - 'compute2': ['1/2'], - }, - 'NEXUS_SWITCH:2.2.2.2': { - 'username': ['admin'], - 'password': ['mySecretPassword'], - 'ssh_port': [22], - 'compute3': ['1/1'], - 'compute4': ['1/2'], - }, - } - expected_dev_dict = { - ('NEXUS_SWITCH', '1.1.1.1', 'username'): 'admin', - ('NEXUS_SWITCH', '1.1.1.1', 'password'): 'mySecretPassword', - ('NEXUS_SWITCH', '1.1.1.1', 'ssh_port'): 22, - ('NEXUS_SWITCH', '1.1.1.1', 'compute1'): '1/1', - ('NEXUS_SWITCH', '1.1.1.1', 'compute2'): '1/2', - ('NEXUS_SWITCH', '2.2.2.2', 'username'): 'admin', - ('NEXUS_SWITCH', '2.2.2.2', 'password'): 'mySecretPassword', - ('NEXUS_SWITCH', '2.2.2.2', 'ssh_port'): 22, - ('NEXUS_SWITCH', '2.2.2.2', 'compute3'): '1/1', - ('NEXUS_SWITCH', '2.2.2.2', 'compute4'): '1/2', - } - with mock.patch.object(cfg, 'MultiConfigParser') as parser: - parser.return_value.read.return_value = cfg.CONF.config_file - parser.return_value.parsed = [test_config] - cisco_config.CiscoConfigOptions() - self.assertEqual(cisco_config.device_dictionary, - expected_dev_dict) diff --git a/neutron/tests/unit/cisco/test_network_db.py b/neutron/tests/unit/cisco/test_network_db.py deleted file mode 100644 index ef09c81c2..000000000 --- a/neutron/tests/unit/cisco/test_network_db.py +++ /dev/null @@ -1,291 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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 collections -import mock -import testtools - -from neutron.db import api as db -from neutron.plugins.cisco.common import cisco_constants -from neutron.plugins.cisco.common import cisco_credentials_v2 -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.common import config as config -from neutron.plugins.cisco.db import network_db_v2 as cdb -from neutron.plugins.cisco import network_plugin -from neutron.tests import base - - -class CiscoNetworkDbTest(base.BaseTestCase): - - """Base class for Cisco network database unit tests.""" - - def setUp(self): - super(CiscoNetworkDbTest, self).setUp() - db.configure_db() - - # The Cisco network plugin includes a thin layer of QoS and - # credential API methods which indirectly call Cisco QoS and - # credential database access methods. For better code coverage, - # this test suite will make calls to the QoS and credential database - # access methods indirectly through the network plugin. The network - # plugin's init function can be mocked out for this purpose. - def new_network_plugin_init(instance): - pass - with mock.patch.object(network_plugin.PluginV2, - '__init__', new=new_network_plugin_init): - self._network_plugin = network_plugin.PluginV2() - - self.addCleanup(db.clear_db) - - -class CiscoNetworkQosDbTest(CiscoNetworkDbTest): - - """Unit tests for Cisco network QoS database model.""" - - QosObj = collections.namedtuple('QosObj', 'tenant qname desc') - - def _qos_test_obj(self, tnum, qnum, desc=None): - """Create a Qos test object from a pair of numbers.""" - if desc is None: - desc = 'test qos %s-%s' % (str(tnum), str(qnum)) - tenant = 'tenant_%s' % str(tnum) - qname = 'qos_%s' % str(qnum) - return self.QosObj(tenant, qname, desc) - - def _assert_equal(self, qos, qos_obj): - self.assertEqual(qos.tenant_id, qos_obj.tenant) - self.assertEqual(qos.qos_name, qos_obj.qname) - self.assertEqual(qos.qos_desc, qos_obj.desc) - - def test_qos_add_remove(self): - qos11 = self._qos_test_obj(1, 1) - qos = self._network_plugin.create_qos(qos11.tenant, qos11.qname, - qos11.desc) - self._assert_equal(qos, qos11) - qos_id = qos.qos_id - qos = self._network_plugin.delete_qos(qos11.tenant, qos_id) - self._assert_equal(qos, qos11) - qos = self._network_plugin.delete_qos(qos11.tenant, qos_id) - self.assertIsNone(qos) - - def test_qos_add_dup(self): - qos22 = self._qos_test_obj(2, 2) - qos = self._network_plugin.create_qos(qos22.tenant, qos22.qname, - qos22.desc) - self._assert_equal(qos, qos22) - qos_id = qos.qos_id - with testtools.ExpectedException(c_exc.QosNameAlreadyExists): - self._network_plugin.create_qos(qos22.tenant, qos22.qname, - "duplicate 22") - qos = self._network_plugin.delete_qos(qos22.tenant, qos_id) - self._assert_equal(qos, qos22) - qos = self._network_plugin.delete_qos(qos22.tenant, qos_id) - self.assertIsNone(qos) - - def test_qos_get(self): - qos11 = self._qos_test_obj(1, 1) - qos11_id = self._network_plugin.create_qos(qos11.tenant, qos11.qname, - qos11.desc).qos_id - qos21 = self._qos_test_obj(2, 1) - qos21_id = self._network_plugin.create_qos(qos21.tenant, qos21.qname, - qos21.desc).qos_id - qos22 = self._qos_test_obj(2, 2) - qos22_id = self._network_plugin.create_qos(qos22.tenant, qos22.qname, - qos22.desc).qos_id - - qos = self._network_plugin.get_qos_details(qos11.tenant, qos11_id) - self._assert_equal(qos, qos11) - qos = self._network_plugin.get_qos_details(qos21.tenant, qos21_id) - self._assert_equal(qos, qos21) - qos = self._network_plugin.get_qos_details(qos21.tenant, qos22_id) - self._assert_equal(qos, qos22) - - with testtools.ExpectedException(c_exc.QosNotFound): - self._network_plugin.get_qos_details(qos11.tenant, "dummyQosId") - with testtools.ExpectedException(c_exc.QosNotFound): - self._network_plugin.get_qos_details(qos11.tenant, qos21_id) - with testtools.ExpectedException(c_exc.QosNotFound): - self._network_plugin.get_qos_details(qos21.tenant, qos11_id) - - qos_all_t1 = self._network_plugin.get_all_qoss(qos11.tenant) - self.assertEqual(len(qos_all_t1), 1) - qos_all_t2 = self._network_plugin.get_all_qoss(qos21.tenant) - self.assertEqual(len(qos_all_t2), 2) - qos_all_t3 = self._network_plugin.get_all_qoss("tenant3") - self.assertEqual(len(qos_all_t3), 0) - - def test_qos_update(self): - qos11 = self._qos_test_obj(1, 1) - qos11_id = self._network_plugin.create_qos(qos11.tenant, qos11.qname, - qos11.desc).qos_id - self._network_plugin.rename_qos(qos11.tenant, qos11_id, - new_name=None) - new_qname = "new qos name" - new_qos = self._network_plugin.rename_qos(qos11.tenant, qos11_id, - new_qname) - expected_qobj = self.QosObj(qos11.tenant, new_qname, qos11.desc) - self._assert_equal(new_qos, expected_qobj) - new_qos = self._network_plugin.get_qos_details(qos11.tenant, qos11_id) - self._assert_equal(new_qos, expected_qobj) - with testtools.ExpectedException(c_exc.QosNotFound): - self._network_plugin.rename_qos(qos11.tenant, "dummyQosId", - new_name=None) - - -class CiscoNetworkCredentialDbTest(CiscoNetworkDbTest): - - """Unit tests for Cisco network credentials database model.""" - - CredObj = collections.namedtuple('CredObj', 'cname usr pwd ctype') - - def _cred_test_obj(self, tnum, cnum): - """Create a Credential test object from a pair of numbers.""" - cname = 'credential_%s_%s' % (str(tnum), str(cnum)) - usr = 'User_%s_%s' % (str(tnum), str(cnum)) - pwd = 'Password_%s_%s' % (str(tnum), str(cnum)) - ctype = 'ctype_%s' % str(tnum) - return self.CredObj(cname, usr, pwd, ctype) - - def _assert_equal(self, credential, cred_obj): - self.assertEqual(credential.type, cred_obj.ctype) - self.assertEqual(credential.credential_name, cred_obj.cname) - self.assertEqual(credential.user_name, cred_obj.usr) - self.assertEqual(credential.password, cred_obj.pwd) - - def test_credential_add_remove(self): - cred11 = self._cred_test_obj(1, 1) - cred = cdb.add_credential( - cred11.cname, cred11.usr, cred11.pwd, cred11.ctype) - self._assert_equal(cred, cred11) - cred_id = cred.credential_id - cred = cdb.remove_credential(cred_id) - self._assert_equal(cred, cred11) - cred = cdb.remove_credential(cred_id) - self.assertIsNone(cred) - - def test_credential_add_dup(self): - cred22 = self._cred_test_obj(2, 2) - cred = cdb.add_credential( - cred22.cname, cred22.usr, cred22.pwd, cred22.ctype) - self._assert_equal(cred, cred22) - cred_id = cred.credential_id - with testtools.ExpectedException(c_exc.CredentialAlreadyExists): - cdb.add_credential( - cred22.cname, cred22.usr, cred22.pwd, cred22.ctype) - cred = cdb.remove_credential(cred_id) - self._assert_equal(cred, cred22) - cred = cdb.remove_credential(cred_id) - self.assertIsNone(cred) - - def test_credential_get_id(self): - cred11 = self._cred_test_obj(1, 1) - cred11_id = cdb.add_credential( - cred11.cname, cred11.usr, cred11.pwd, cred11.ctype).credential_id - cred21 = self._cred_test_obj(2, 1) - cred21_id = cdb.add_credential( - cred21.cname, cred21.usr, cred21.pwd, cred21.ctype).credential_id - cred22 = self._cred_test_obj(2, 2) - cred22_id = cdb.add_credential( - cred22.cname, cred22.usr, cred22.pwd, cred22.ctype).credential_id - - cred = self._network_plugin.get_credential_details(cred11_id) - self._assert_equal(cred, cred11) - cred = self._network_plugin.get_credential_details(cred21_id) - self._assert_equal(cred, cred21) - cred = self._network_plugin.get_credential_details(cred22_id) - self._assert_equal(cred, cred22) - - with testtools.ExpectedException(c_exc.CredentialNotFound): - self._network_plugin.get_credential_details("dummyCredentialId") - - cred_all_t1 = self._network_plugin.get_all_credentials() - self.assertEqual(len(cred_all_t1), 3) - - def test_credential_get_name(self): - cred11 = self._cred_test_obj(1, 1) - cred11_id = cdb.add_credential( - cred11.cname, cred11.usr, cred11.pwd, cred11.ctype).credential_id - cred21 = self._cred_test_obj(2, 1) - cred21_id = cdb.add_credential( - cred21.cname, cred21.usr, cred21.pwd, cred21.ctype).credential_id - cred22 = self._cred_test_obj(2, 2) - cred22_id = cdb.add_credential( - cred22.cname, cred22.usr, cred22.pwd, cred22.ctype).credential_id - self.assertNotEqual(cred11_id, cred21_id) - self.assertNotEqual(cred11_id, cred22_id) - self.assertNotEqual(cred21_id, cred22_id) - - cred = cdb.get_credential_name(cred11.cname) - self._assert_equal(cred, cred11) - cred = cdb.get_credential_name(cred21.cname) - self._assert_equal(cred, cred21) - cred = cdb.get_credential_name(cred22.cname) - self._assert_equal(cred, cred22) - - with testtools.ExpectedException(c_exc.CredentialNameNotFound): - cdb.get_credential_name("dummyCredentialName") - - def test_credential_update(self): - cred11 = self._cred_test_obj(1, 1) - cred11_id = cdb.add_credential( - cred11.cname, cred11.usr, cred11.pwd, cred11.ctype).credential_id - self._network_plugin.rename_credential(cred11_id, new_name=None, - new_password=None) - new_usr = "new user name" - new_pwd = "new password" - new_credential = self._network_plugin.rename_credential( - cred11_id, new_usr, new_pwd) - expected_cred = self.CredObj( - cred11.cname, new_usr, new_pwd, cred11.ctype) - self._assert_equal(new_credential, expected_cred) - new_credential = self._network_plugin.get_credential_details( - cred11_id) - self._assert_equal(new_credential, expected_cred) - with testtools.ExpectedException(c_exc.CredentialNotFound): - self._network_plugin.rename_credential( - "dummyCredentialId", new_usr, new_pwd) - - def test_get_credential_not_found_exception(self): - self.assertRaises(c_exc.CredentialNotFound, - self._network_plugin.get_credential_details, - "dummyCredentialId") - - -class CiscoCredentialStoreTest(base.BaseTestCase): - - """Cisco Credential Store unit tests.""" - - def setUp(self): - super(CiscoCredentialStoreTest, self).setUp() - db.configure_db() - self.addCleanup(db.clear_db) - - def test_cred_store_init_duplicate_creds_ignored(self): - """Check that with multi store instances, dup creds are ignored.""" - # Create a device dictionary containing credentials for 1 switch. - dev_dict = { - ('dev_id', '1.1.1.1', cisco_constants.USERNAME): 'user_1', - ('dev_id', '1.1.1.1', cisco_constants.PASSWORD): 'password_1', - ('dev_id', '1.1.1.1', 'host_a'): '1/1', - ('dev_id', '1.1.1.1', 'host_b'): '1/2', - ('dev_id', '1.1.1.1', 'host_c'): '1/3', - } - with mock.patch.object(config, 'get_device_dictionary', - return_value=dev_dict): - # Create and initialize 2 instances of credential store. - cisco_credentials_v2.Store().initialize() - cisco_credentials_v2.Store().initialize() - # There should be only 1 switch credential in the database. - self.assertEqual(len(cdb.get_all_credentials()), 1) diff --git a/neutron/tests/unit/cisco/test_network_plugin.py b/neutron/tests/unit/cisco/test_network_plugin.py deleted file mode 100644 index 4e7be3e87..000000000 --- a/neutron/tests/unit/cisco/test_network_plugin.py +++ /dev/null @@ -1,1186 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 contextlib -import copy -import inspect -import logging -import mock - -import six -import webob.exc as wexc - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.api.v2 import base -from neutron.common import exceptions as n_exc -from neutron import context -from neutron.db import db_base_plugin_v2 as base_plugin -from neutron.db import l3_db -from neutron.extensions import portbindings -from neutron.extensions import providernet as provider -from neutron import manager -from neutron.openstack.common import gettextutils -from neutron.plugins.cisco.common import cisco_constants as const -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.common import config as cisco_config -from neutron.plugins.cisco.db import network_db_v2 -from neutron.plugins.cisco.db import nexus_db_v2 -from neutron.plugins.cisco.models import virt_phy_sw_v2 -from neutron.plugins.openvswitch.common import config as ovs_config -from neutron.plugins.openvswitch import ovs_db_v2 -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import test_extensions - -LOG = logging.getLogger(__name__) -CORE_PLUGIN = 'neutron.plugins.cisco.network_plugin.PluginV2' -NEXUS_PLUGIN = 'neutron.plugins.cisco.nexus.cisco_nexus_plugin_v2.NexusPlugin' -NEXUS_DRIVER = ('neutron.plugins.cisco.nexus.' - 'cisco_nexus_network_driver_v2.CiscoNEXUSDriver') -PHYS_NET = 'physnet1' -BRIDGE_NAME = 'br-eth1' -VLAN_START = 1000 -VLAN_END = 1100 -COMP_HOST_NAME = 'testhost' -COMP_HOST_NAME_2 = 'testhost_2' -NEXUS_IP_ADDR = '1.1.1.1' -NEXUS_DEV_ID = 'NEXUS_SWITCH' -NEXUS_USERNAME = 'admin' -NEXUS_PASSWORD = 'mySecretPassword' -NEXUS_SSH_PORT = 22 -NEXUS_INTERFACE = '1/1' -NEXUS_INTERFACE_2 = '1/2' -NEXUS_PORT_1 = 'ethernet:1/1' -NEXUS_PORT_2 = 'ethernet:1/2' -NETWORK_NAME = 'test_network' -CIDR_1 = '10.0.0.0/24' -CIDR_2 = '10.0.1.0/24' -DEVICE_ID_1 = '11111111-1111-1111-1111-111111111111' -DEVICE_ID_2 = '22222222-2222-2222-2222-222222222222' -DEVICE_OWNER = 'compute:None' - - -class CiscoNetworkPluginV2TestCase(test_db_plugin.NeutronDbPluginV2TestCase): - - def setUp(self): - """Configure for end-to-end neutron testing using a mock ncclient. - - This setup includes: - - Configure the OVS plugin to use VLANs in the range of - VLAN_START-VLAN_END. - - Configure the Cisco plugin model to use the Nexus driver. - - Configure the Nexus driver to use an imaginary switch - at NEXUS_IP_ADDR. - - """ - # Configure the OVS and Cisco plugins - phys_bridge = ':'.join([PHYS_NET, BRIDGE_NAME]) - phys_vlan_range = ':'.join([PHYS_NET, str(VLAN_START), str(VLAN_END)]) - config = { - ovs_config: { - 'OVS': {'bridge_mappings': phys_bridge, - 'network_vlan_ranges': [phys_vlan_range], - 'tenant_network_type': 'vlan'} - }, - cisco_config: { - 'CISCO': {'nexus_driver': NEXUS_DRIVER}, - 'CISCO_PLUGINS': {'nexus_plugin': NEXUS_PLUGIN}, - } - } - for module in config: - for group in config[module]: - for opt, val in config[module][group].items(): - module.cfg.CONF.set_override(opt, val, group) - - # Configure the Nexus switch dictionary - # TODO(Henry): add tests for other devices - nexus_config = { - (NEXUS_DEV_ID, NEXUS_IP_ADDR, 'username'): NEXUS_USERNAME, - (NEXUS_DEV_ID, NEXUS_IP_ADDR, 'password'): NEXUS_PASSWORD, - (NEXUS_DEV_ID, NEXUS_IP_ADDR, 'ssh_port'): NEXUS_SSH_PORT, - (NEXUS_DEV_ID, NEXUS_IP_ADDR, COMP_HOST_NAME): NEXUS_INTERFACE, - (NEXUS_DEV_ID, NEXUS_IP_ADDR, COMP_HOST_NAME_2): NEXUS_INTERFACE_2, - } - nexus_patch = mock.patch.dict(cisco_config.device_dictionary, - nexus_config) - nexus_patch.start() - self.addCleanup(nexus_patch.stop) - - # Use a mock netconf client - self.mock_ncclient = mock.Mock() - ncclient_patch = mock.patch.dict('sys.modules', - {'ncclient': self.mock_ncclient}) - ncclient_patch.start() - self.addCleanup(ncclient_patch.stop) - - # Call the parent setUp, start the core plugin - super(CiscoNetworkPluginV2TestCase, self).setUp(CORE_PLUGIN) - self.port_create_status = 'DOWN' - - # Set Cisco config module's first configured Nexus IP address. - # Used for SVI placement when round-robin placement is disabled. - mock.patch.object(cisco_config, 'first_device_ip', - new=NEXUS_IP_ADDR).start() - - def _get_plugin_ref(self): - return getattr(manager.NeutronManager.get_plugin(), - "_model")._plugins[const.VSWITCH_PLUGIN] - - @contextlib.contextmanager - def _patch_ncclient(self, attr, value): - """Configure an attribute on the mock ncclient module. - - This method can be used to inject errors by setting a side effect - or a return value for an ncclient method. - - :param attr: ncclient attribute (typically method) to be configured. - :param value: Value to be configured on the attribute. - - """ - # Configure attribute. - config = {attr: value} - self.mock_ncclient.configure_mock(**config) - # Continue testing - yield - # Unconfigure attribute - config = {attr: None} - self.mock_ncclient.configure_mock(**config) - - @staticmethod - def _config_dependent_side_effect(match_config, exc): - """Generates a config-dependent side effect for ncclient edit_config. - - This method generates a mock side-effect function which can be - configured on the mock ncclient module for the edit_config method. - This side effect will cause a given exception to be raised whenever - the XML config string that is passed to edit_config contains all - words in a given match config string. - - :param match_config: String containing keywords to be matched - :param exc: Exception to be raised when match is found - :return: Side effect function for the mock ncclient module's - edit_config method. - - """ - keywords = match_config.split() - - def _side_effect_function(target, config): - if all(word in config for word in keywords): - raise exc - return _side_effect_function - - def _is_in_nexus_cfg(self, words): - """Check if any config sent to Nexus contains all words in a list.""" - for call in (self.mock_ncclient.manager.connect.return_value. - edit_config.mock_calls): - configlet = call[2]['config'] - if all(word in configlet for word in words): - return True - return False - - def _is_in_last_nexus_cfg(self, words): - """Check if last config sent to Nexus contains all words in a list.""" - last_cfg = (self.mock_ncclient.manager.connect.return_value. - edit_config.mock_calls[-1][2]['config']) - return all(word in last_cfg for word in words) - - def _is_vlan_configured(self, vlan_creation_expected=True, - add_keyword_expected=False): - vlan_created = self._is_in_nexus_cfg(['vlan', 'vlan-name']) - add_appears = self._is_in_last_nexus_cfg(['add']) - return (self._is_in_last_nexus_cfg(['allowed', 'vlan']) and - vlan_created == vlan_creation_expected and - add_appears == add_keyword_expected) - - def _is_vlan_unconfigured(self, vlan_deletion_expected=True, - vlan_untrunk_expected=True): - vlan_deleted = self._is_in_nexus_cfg( - ['no', 'vlan', 'vlan-id-create-delete']) - vlan_untrunked = self._is_in_nexus_cfg(['allowed', 'vlan', 'remove']) - return (vlan_deleted == vlan_deletion_expected and - vlan_untrunked == vlan_untrunk_expected) - - def _assertExpectedHTTP(self, status, exc): - """Confirm that an HTTP status corresponds to an expected exception. - - Confirm that an HTTP status which has been returned for an - neutron API request matches the HTTP status corresponding - to an expected exception. - - :param status: HTTP status - :param exc: Expected exception - - """ - if exc in base.FAULT_MAP: - expected_http = base.FAULT_MAP[exc].code - else: - expected_http = wexc.HTTPInternalServerError.code - self.assertEqual(status, expected_http) - - -class TestCiscoGetAttribute(CiscoNetworkPluginV2TestCase): - - def test_get_unsupported_attr_in_lazy_gettext_mode(self): - """Test get of unsupported attribute in lazy gettext mode. - - This test also checks that this operation does not cause - excessive nesting of calls to deepcopy. - """ - plugin = manager.NeutronManager.get_plugin() - - def _lazy_gettext(msg): - return gettextutils.Message(msg, domain='neutron') - - with mock.patch.dict(six.moves.builtins.__dict__, - {'_': _lazy_gettext}): - self.nesting_count = 0 - - def _count_nesting(*args, **kwargs): - self.nesting_count += 1 - - with mock.patch.object(copy, 'deepcopy', - side_effect=_count_nesting, - wraps=copy.deepcopy): - self.assertRaises(AttributeError, getattr, plugin, - 'an_unsupported_attribute') - # If there were no nested calls to deepcopy, then the total - # number of calls to deepcopy should be 2 (1 call for - # each mod'd field in the AttributeError message raised - # by the plugin). - self.assertEqual(self.nesting_count, 2) - - -class TestCiscoBasicGet(CiscoNetworkPluginV2TestCase, - test_db_plugin.TestBasicGet): - pass - - -class TestCiscoV2HTTPResponse(CiscoNetworkPluginV2TestCase, - test_db_plugin.TestV2HTTPResponse): - pass - - -class TestCiscoPortsV2(CiscoNetworkPluginV2TestCase, - test_db_plugin.TestPortsV2, - test_bindings.PortBindingsHostTestCaseMixin): - - @contextlib.contextmanager - def _create_port_res(self, name=NETWORK_NAME, cidr=CIDR_1, - do_delete=True, host_id=COMP_HOST_NAME): - """Create a network, subnet, and port and yield the result. - - Create a network, subnet, and port, yield the result, - then delete the port, subnet, and network. - - :param name: Name of network to be created - :param cidr: cidr address of subnetwork to be created - :param do_delete: If set to True, delete the port at the - end of testing - :param host_id: Name of compute host to use for testing - - """ - ctx = context.get_admin_context() - with self.network(name=name) as network: - with self.subnet(network=network, cidr=cidr) as subnet: - net_id = subnet['subnet']['network_id'] - args = (portbindings.HOST_ID, 'device_id', 'device_owner') - port_dict = {portbindings.HOST_ID: host_id, - 'device_id': DEVICE_ID_1, - 'device_owner': DEVICE_OWNER} - res = self._create_port(self.fmt, net_id, arg_list=args, - context=ctx, **port_dict) - port = self.deserialize(self.fmt, res) - yield res - if do_delete: - self._delete('ports', port['port']['id']) - - def test_create_ports_bulk_emulated_plugin_failure(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - plugin_ref = self._get_plugin_ref() - orig = plugin_ref.create_port - with mock.patch.object(plugin_ref, - 'create_port') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - with self.network() as net: - res = self._create_port_bulk(self.fmt, 2, - net['network']['id'], - 'test', - True) - # Expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'ports', - wexc.HTTPInternalServerError.code) - - def test_create_ports_bulk_native(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk port create") - - def test_create_ports_bulk_emulated(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk port create") - - def test_create_ports_bulk_native_plugin_failure(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk port create") - ctx = context.get_admin_context() - with self.network() as net: - plugin_ref = self._get_plugin_ref() - orig = plugin_ref.create_port - with mock.patch.object(plugin_ref, - 'create_port') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - res = self._create_port_bulk(self.fmt, 2, - net['network']['id'], - 'test', True, context=ctx) - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'ports', - wexc.HTTPInternalServerError.code) - - def test_nexus_enable_vlan_cmd(self): - """Verify the syntax of the command to enable a vlan on an intf.""" - - # First vlan should be configured without 'add' keyword - with self._create_port_res(name='net1', cidr=CIDR_1): - self.assertTrue(self._is_vlan_configured( - vlan_creation_expected=True, - add_keyword_expected=False)) - self.mock_ncclient.reset_mock() - - # Second vlan should be configured with 'add' keyword - with self._create_port_res(name='net2', cidr=CIDR_2): - self.assertTrue(self._is_vlan_configured( - vlan_creation_expected=True, - add_keyword_expected=True)) - - def test_nexus_vlan_config_two_hosts(self): - """Verify config/unconfig of vlan on two compute hosts.""" - - @contextlib.contextmanager - def _create_port_check_vlan(comp_host_name, device_id, - vlan_creation_expected=True): - arg_list = (portbindings.HOST_ID,) - port_dict = {portbindings.HOST_ID: comp_host_name, - 'device_id': device_id, - 'device_owner': DEVICE_OWNER} - with self.port(subnet=subnet, fmt=self.fmt, - arg_list=arg_list, **port_dict): - self.assertTrue(self._is_vlan_configured( - vlan_creation_expected=vlan_creation_expected, - add_keyword_expected=False)) - self.mock_ncclient.reset_mock() - yield - - # Create network and subnet - with self.network(name=NETWORK_NAME) as network: - with self.subnet(network=network, cidr=CIDR_1) as subnet: - - # Create an instance on first compute host - with _create_port_check_vlan( - COMP_HOST_NAME, DEVICE_ID_1, vlan_creation_expected=True): - - # Create an instance on second compute host - with _create_port_check_vlan( - COMP_HOST_NAME_2, DEVICE_ID_2, - vlan_creation_expected=False): - pass - - # Instance on second host is now terminated. - # Vlan should be untrunked from port, but vlan should - # still exist on the switch. - self.assertTrue(self._is_vlan_unconfigured( - vlan_deletion_expected=False)) - self.mock_ncclient.reset_mock() - - # Instance on first host is now terminated. - # Vlan should be untrunked from port and vlan should have - # been deleted from the switch. - self.assertTrue(self._is_vlan_unconfigured( - vlan_deletion_expected=True)) - - def test_nexus_connect_fail(self): - """Test failure to connect to a Nexus switch. - - While creating a network, subnet, and port, simulate a connection - failure to a nexus switch. Confirm that the expected HTTP code - is returned for the create port operation. - - """ - with self._patch_ncclient('manager.connect.side_effect', - AttributeError): - with self._create_port_res(do_delete=False) as res: - self._assertExpectedHTTP(res.status_int, - c_exc.NexusConnectFailed) - - def test_nexus_config_fail(self): - """Test a Nexus switch configuration failure. - - While creating a network, subnet, and port, simulate a nexus - switch configuration error. Confirm that the expected HTTP code - is returned for the create port operation. - - """ - with self._patch_ncclient( - 'manager.connect.return_value.edit_config.side_effect', - AttributeError): - with self._create_port_res(do_delete=False) as res: - self._assertExpectedHTTP(res.status_int, - c_exc.NexusConfigFailed) - - def test_nexus_extended_vlan_range_failure(self): - """Test that extended VLAN range config errors are ignored. - - Some versions of Nexus switch do not allow state changes for - the extended VLAN range (1006-4094), but these errors can be - ignored (default values are appropriate). Test that such errors - are ignored by the Nexus plugin. - - """ - config_err_strings = { - "state active": "Can't modify state for extended", - "no shutdown": "Command is only allowed on VLAN", - } - for config, err_string in config_err_strings.items(): - with self._patch_ncclient( - 'manager.connect.return_value.edit_config.side_effect', - self._config_dependent_side_effect(config, - Exception(err_string))): - with self._create_port_res() as res: - self.assertEqual(res.status_int, wexc.HTTPCreated.code) - - def test_nexus_vlan_config_rollback(self): - """Test rollback following Nexus VLAN state config failure. - - Test that the Cisco Nexus plugin correctly deletes the VLAN - on the Nexus switch when the 'state active' command fails (for - a reason other than state configuration change is rejected - for the extended VLAN range). - - """ - vlan_state_configs = ['state active', 'no shutdown'] - for config in vlan_state_configs: - with self._patch_ncclient( - 'manager.connect.return_value.edit_config.side_effect', - self._config_dependent_side_effect(config, ValueError)): - with self._create_port_res(do_delete=False) as res: - # Confirm that the last configuration sent to the Nexus - # switch was deletion of the VLAN. - self.assertTrue( - self._is_in_last_nexus_cfg(['', '']) - ) - self._assertExpectedHTTP(res.status_int, - c_exc.NexusConfigFailed) - - def test_get_seg_id_fail(self): - """Test handling of a NetworkSegmentIDNotFound exception. - - Test the Cisco NetworkSegmentIDNotFound exception by simulating - a return of None by the OVS DB get_network_binding method - during port creation. - - """ - orig = ovs_db_v2.get_network_binding - - def _return_none_if_nexus_caller(self, *args, **kwargs): - def _calling_func_name(offset=0): - """Get name of the calling function 'offset' frames back.""" - return inspect.stack()[1 + offset][3] - if (_calling_func_name(1) == '_get_segmentation_id' and - _calling_func_name(2) == '_invoke_nexus_for_net_create'): - return None - else: - return orig(self, *args, **kwargs) - - with mock.patch.object(ovs_db_v2, 'get_network_binding', - new=_return_none_if_nexus_caller): - with self._create_port_res(do_delete=False) as res: - self._assertExpectedHTTP(res.status_int, - c_exc.NetworkSegmentIDNotFound) - - def test_nexus_host_non_configured(self): - """Test handling of a NexusComputeHostNotConfigured exception. - - Test the Cisco NexusComputeHostNotConfigured exception by using - a fictitious host name during port creation. - - """ - with self._create_port_res(do_delete=False, - host_id='fakehost') as res: - self._assertExpectedHTTP(res.status_int, - c_exc.NexusComputeHostNotConfigured) - - def _check_rollback_on_bind_failure(self, - vlan_deletion_expected, - vlan_untrunk_expected): - """Test for proper rollback following add Nexus DB binding failure. - - Test that the Cisco Nexus plugin correctly rolls back the vlan - configuration on the Nexus switch when add_nexusport_binding fails - within the plugin's create_port() method. - - """ - inserted_exc = KeyError - with mock.patch.object(nexus_db_v2, 'add_nexusport_binding', - side_effect=inserted_exc): - with self._create_port_res(do_delete=False) as res: - # Confirm that the configuration sent to the Nexus - # switch includes deletion of the vlan (if expected) - # and untrunking of the vlan from the ethernet interface - # (if expected). - self.assertTrue(self._is_vlan_unconfigured( - vlan_deletion_expected=vlan_deletion_expected, - vlan_untrunk_expected=vlan_untrunk_expected)) - self._assertExpectedHTTP(res.status_int, inserted_exc) - - def test_nexus_rollback_on_bind_failure_non_provider_vlan(self): - """Test rollback upon DB binding failure for non-provider vlan.""" - self._check_rollback_on_bind_failure(vlan_deletion_expected=True, - vlan_untrunk_expected=True) - - def test_nexus_rollback_on_bind_failure_prov_vlan_no_auto_create(self): - """Test rollback on bind fail for prov vlan w auto-create disabled.""" - with mock.patch.object(network_db_v2, 'is_provider_vlan', - return_value=True): - # Disable auto-create. This config change will be cleared based - # on cleanup scheduled in the CiscoNetworkPluginV2TestCase - # class' setUp() method. - cisco_config.CONF.set_override('provider_vlan_auto_create', - False, 'CISCO') - self._check_rollback_on_bind_failure(vlan_deletion_expected=False, - vlan_untrunk_expected=True) - - def test_nexus_rollback_on_bind_failure_prov_vlan_no_auto_trunk(self): - """Test rollback on bind fail for prov vlan w auto-trunk disabled.""" - with mock.patch.object(network_db_v2, 'is_provider_vlan', - return_value=True): - # Disable auto-trunk. This config change will be cleared - # based on post-test cleanup scheduled in the - # CiscoNetworkPluginV2TestCase class' setUp() method. - cisco_config.CONF.set_override('provider_vlan_auto_trunk', - False, 'CISCO') - self._check_rollback_on_bind_failure(vlan_deletion_expected=True, - vlan_untrunk_expected=False) - - def test_model_update_port_rollback(self): - """Test for proper rollback for Cisco model layer update port failure. - - Test that the vSwitch plugin port configuration is rolled back - (restored) by the Cisco plugin model layer when there is a - failure in the Nexus sub-plugin for an update port operation. - - The update port operation simulates a port attachment scenario: - first a port is created with no instance (null device_id), - and then a port update is requested with a non-null device_id - to simulate the port attachment. - - """ - with self.port(fmt=self.fmt, device_id='', - device_owner=DEVICE_OWNER) as orig_port: - - inserted_exc = ValueError - with mock.patch.object( - virt_phy_sw_v2.VirtualPhysicalSwitchModelV2, - '_invoke_nexus_for_net_create', - side_effect=inserted_exc): - - # Send an update port request including a non-null device ID - data = {'port': {'device_id': DEVICE_ID_2, - 'device_owner': DEVICE_OWNER, - portbindings.HOST_ID: COMP_HOST_NAME}} - port_id = orig_port['port']['id'] - req = self.new_update_request('ports', data, port_id) - res = req.get_response(self.api) - - # Sanity check failure result code - self._assertExpectedHTTP(res.status_int, inserted_exc) - - # Check that the port still has the original device ID - plugin = base_plugin.NeutronDbPluginV2() - ctx = context.get_admin_context() - db_port = plugin._get_port(ctx, port_id) - self.assertEqual(db_port['device_id'], - orig_port['port']['device_id']) - - def test_model_delete_port_rollback(self): - """Test for proper rollback for OVS plugin delete port failure. - - Test that the nexus port configuration is rolled back (restored) - by the Cisco model plugin when there is a failure in the OVS - plugin for a delete port operation. - - """ - with self._create_port_res() as res: - - # After port is created, we should have one binding for this - # vlan/nexus switch. - port = self.deserialize(self.fmt, res) - start_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START, - NEXUS_IP_ADDR) - self.assertEqual(len(start_rows), 1) - - # Inject an exception in the OVS plugin delete_port - # processing, and attempt a port deletion. - inserted_exc = n_exc.Conflict - expected_http = base.FAULT_MAP[inserted_exc].code - with mock.patch.object(l3_db.L3_NAT_db_mixin, - 'disassociate_floatingips', - side_effect=inserted_exc): - self._delete('ports', port['port']['id'], - expected_code=expected_http) - - # Confirm that the Cisco model plugin has restored - # the nexus configuration for this port after deletion failure. - end_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START, - NEXUS_IP_ADDR) - self.assertEqual(start_rows, end_rows) - - def test_nexus_delete_port_rollback(self): - """Test for proper rollback for nexus plugin delete port failure. - - Test for rollback (i.e. restoration) of a VLAN entry in the - nexus database whenever the nexus plugin fails to reconfigure the - nexus switch during a delete_port operation. - - """ - with self._create_port_res() as res: - - port = self.deserialize(self.fmt, res) - - # Check that there is only one binding in the nexus database - # for this VLAN/nexus switch. - start_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START, - NEXUS_IP_ADDR) - self.assertEqual(len(start_rows), 1) - - # Simulate a Nexus switch configuration error during - # port deletion. - with self._patch_ncclient( - 'manager.connect.return_value.edit_config.side_effect', - AttributeError): - self._delete('ports', port['port']['id'], - base.FAULT_MAP[c_exc.NexusConfigFailed].code) - - # Confirm that the binding has been restored (rolled back). - end_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START, - NEXUS_IP_ADDR) - self.assertEqual(start_rows, end_rows) - - def test_model_update_port_attach(self): - """Test the model for update_port in attaching to an instance. - - Mock the routines that call into the plugin code, and make sure they - are called with correct arguments. - - """ - with contextlib.nested( - self.port(), - mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2, - '_invoke_plugin_per_device'), - mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2, - '_invoke_nexus_for_net_create') - ) as (port, invoke_plugin_per_device, invoke_nexus_for_net_create): - data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME, - 'device_id': DEVICE_ID_1, - 'device_owner': DEVICE_OWNER}} - - req = self.new_update_request('ports', data, port['port']['id']) - # Note, due to mocking out the two model routines, response won't - # contain any useful data - req.get_response(self.api) - - # Note that call_args_list is used instead of - # assert_called_once_with which requires exact match of arguments. - # This is because the mocked routines contain variable number of - # arguments and/or dynamic objects. - self.assertEqual(invoke_plugin_per_device.call_count, 1) - self.assertEqual( - invoke_plugin_per_device.call_args_list[0][0][0:2], - (const.VSWITCH_PLUGIN, 'update_port')) - self.assertEqual(invoke_nexus_for_net_create.call_count, 1) - self.assertEqual( - invoke_nexus_for_net_create.call_args_list[0][0][1:], - (port['port']['tenant_id'], port['port']['network_id'], - data['port']['device_id'], - data['port'][portbindings.HOST_ID],)) - - def test_model_update_port_migrate(self): - """Test the model for update_port in migrating an instance. - - Mock the routines that call into the plugin code, and make sure they - are called with correct arguments. - - """ - arg_list = (portbindings.HOST_ID,) - data = {portbindings.HOST_ID: COMP_HOST_NAME, - 'device_id': DEVICE_ID_1, - 'device_owner': DEVICE_OWNER} - - with contextlib.nested( - self.port(arg_list=arg_list, **data), - mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2, - '_invoke_plugin_per_device'), - mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2, - '_invoke_nexus_for_net_create') - ) as (port, invoke_plugin_per_device, invoke_nexus_for_net_create): - data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME_2}} - req = self.new_update_request('ports', data, port['port']['id']) - # Note, due to mocking out the two model routines, response won't - # contain any useful data - req.get_response(self.api) - - # Note that call_args_list is used instead of - # assert_called_once_with which requires exact match of arguments. - # This is because the mocked routines contain variable number of - # arguments and/or dynamic objects. - self.assertEqual(invoke_plugin_per_device.call_count, 2) - self.assertEqual( - invoke_plugin_per_device.call_args_list[0][0][0:2], - (const.VSWITCH_PLUGIN, 'update_port')) - self.assertEqual( - invoke_plugin_per_device.call_args_list[1][0][0:2], - (const.NEXUS_PLUGIN, 'delete_port')) - self.assertEqual(invoke_nexus_for_net_create.call_count, 1) - self.assertEqual( - invoke_nexus_for_net_create.call_args_list[0][0][1:], - (port['port']['tenant_id'], port['port']['network_id'], - port['port']['device_id'], - data['port'][portbindings.HOST_ID],)) - - def test_model_update_port_net_create_not_needed(self): - """Test the model for update_port when no action is needed. - - Mock the routines that call into the plugin code, and make sure that - VSWITCH plugin is called with correct arguments, while NEXUS plugin is - not called at all. - - """ - arg_list = (portbindings.HOST_ID,) - data = {portbindings.HOST_ID: COMP_HOST_NAME, - 'device_id': DEVICE_ID_1, - 'device_owner': DEVICE_OWNER} - - with contextlib.nested( - self.port(arg_list=arg_list, **data), - mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2, - '_invoke_plugin_per_device'), - mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2, - '_invoke_nexus_for_net_create') - ) as (port, invoke_plugin_per_device, invoke_nexus_for_net_create): - data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME, - 'device_id': DEVICE_ID_1, - 'device_owner': DEVICE_OWNER}} - req = self.new_update_request('ports', data, port['port']['id']) - # Note, due to mocking out the two model routines, response won't - # contain any useful data - req.get_response(self.api) - - # Note that call_args_list is used instead of - # assert_called_once_with which requires exact match of arguments. - # This is because the mocked routines contain variable number of - # arguments and/or dynamic objects. - self.assertEqual(invoke_plugin_per_device.call_count, 1) - self.assertEqual( - invoke_plugin_per_device.call_args_list[0][0][0:2], - (const.VSWITCH_PLUGIN, 'update_port')) - self.assertFalse(invoke_nexus_for_net_create.called) - - def verify_portbinding(self, host_id1, host_id2, - vlan, device_id, binding_port): - """Verify a port binding entry in the DB is correct.""" - self.assertEqual(host_id1, host_id2) - pb = nexus_db_v2.get_nexusvm_bindings(vlan, device_id) - self.assertEqual(len(pb), 1) - self.assertEqual(pb[0].port_id, binding_port) - self.assertEqual(pb[0].switch_ip, NEXUS_IP_ADDR) - - def test_db_update_port_attach(self): - """Test DB for update_port in attaching to an instance. - - Query DB for the port binding entry corresponding to the search key - (vlan, device_id), and make sure that it's bound to correct switch port - - """ - with self.port() as port: - data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME, - 'device_id': DEVICE_ID_1, - 'device_owner': DEVICE_OWNER}} - - req = self.new_update_request('ports', data, port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - ctx = context.get_admin_context() - net = self._show('networks', res['port']['network_id'], - neutron_context=ctx)['network'] - self.assertTrue(attributes.is_attr_set( - net.get(provider.SEGMENTATION_ID))) - vlan = net[provider.SEGMENTATION_ID] - self.assertEqual(vlan, VLAN_START) - self.verify_portbinding(res['port'][portbindings.HOST_ID], - data['port'][portbindings.HOST_ID], - vlan, - data['port']['device_id'], - NEXUS_PORT_1) - - def test_db_update_port_migrate(self): - """Test DB for update_port in migrating an instance. - - Query DB for the port binding entry corresponding to the search key - (vlan, device_id), and make sure that it's bound to correct switch port - before and after the migration. - - """ - arg_list = (portbindings.HOST_ID,) - data = {portbindings.HOST_ID: COMP_HOST_NAME, - 'device_id': DEVICE_ID_1, - 'device_owner': DEVICE_OWNER} - - with self.port(arg_list=arg_list, **data) as port: - ctx = context.get_admin_context() - net = self._show('networks', port['port']['network_id'], - neutron_context=ctx)['network'] - self.assertTrue(attributes.is_attr_set( - net.get(provider.SEGMENTATION_ID))) - vlan = net[provider.SEGMENTATION_ID] - self.assertEqual(vlan, VLAN_START) - self.verify_portbinding(port['port'][portbindings.HOST_ID], - data[portbindings.HOST_ID], - vlan, - data['device_id'], - NEXUS_PORT_1) - - new_data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME_2}} - req = self.new_update_request('ports', - new_data, port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.verify_portbinding(res['port'][portbindings.HOST_ID], - new_data['port'][portbindings.HOST_ID], - vlan, - data['device_id'], - NEXUS_PORT_2) - - def test_delete_ports_by_device_id_second_call_failure(self): - plugin_ref = self._get_plugin_ref() - self._test_delete_ports_by_device_id_second_call_failure(plugin_ref) - - def test_delete_ports_ignores_port_not_found(self): - plugin_ref = self._get_plugin_ref() - self._test_delete_ports_ignores_port_not_found(plugin_ref) - - -class TestCiscoNetworksV2(CiscoNetworkPluginV2TestCase, - test_db_plugin.TestNetworksV2): - - def test_create_networks_bulk_emulated_plugin_failure(self): - real_has_attr = hasattr - - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - plugin_ref = self._get_plugin_ref() - orig = plugin_ref.create_network - #ensures the API choose the emulation code path - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - with mock.patch.object(plugin_ref, - 'create_network') as patched_plugin: - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - patched_plugin.side_effect = side_effect - res = self._create_network_bulk(self.fmt, 2, 'test', True) - LOG.debug("response is %s" % res) - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'networks', - wexc.HTTPInternalServerError.code) - - def test_create_networks_bulk_native_plugin_failure(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk network create") - plugin_ref = self._get_plugin_ref() - orig = plugin_ref.create_network - with mock.patch.object(plugin_ref, - 'create_network') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - res = self._create_network_bulk(self.fmt, 2, 'test', True) - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'networks', - wexc.HTTPInternalServerError.code) - - @contextlib.contextmanager - def _provider_vlan_network(self, phys_net, segment_id, net_name): - provider_attrs = {provider.NETWORK_TYPE: 'vlan', - provider.PHYSICAL_NETWORK: phys_net, - provider.SEGMENTATION_ID: segment_id} - arg_list = tuple(provider_attrs.keys()) - res = self._create_network(self.fmt, net_name, True, - arg_list=arg_list, **provider_attrs) - network = self.deserialize(self.fmt, res)['network'] - yield network - req = self.new_delete_request('networks', network['id']) - req.get_response(self.api) - - def test_create_provider_vlan_network(self): - with self._provider_vlan_network(PHYS_NET, '1234', - 'pvnet1') as network: - expected = [('name', 'pvnet1'), - ('admin_state_up', True), - ('status', 'ACTIVE'), - ('shared', False), - (provider.NETWORK_TYPE, 'vlan'), - (provider.PHYSICAL_NETWORK, PHYS_NET), - (provider.SEGMENTATION_ID, 1234)] - for k, v in expected: - self.assertEqual(network[k], v) - self.assertTrue(network_db_v2.is_provider_network(network['id'])) - - def test_delete_provider_vlan_network(self): - with self._provider_vlan_network(PHYS_NET, '1234', - 'pvnet1') as network: - network_id = network['id'] - # Provider network should now be deleted - self.assertFalse(network_db_v2.is_provider_network(network_id)) - - -class TestCiscoSubnetsV2(CiscoNetworkPluginV2TestCase, - test_db_plugin.TestSubnetsV2): - - def test_create_subnets_bulk_emulated_plugin_failure(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - plugin_ref = self._get_plugin_ref() - orig = plugin_ref.create_subnet - with mock.patch.object(plugin_ref, - 'create_subnet') as patched_plugin: - - def side_effect(*args, **kwargs): - self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - with self.network() as net: - res = self._create_subnet_bulk(self.fmt, 2, - net['network']['id'], - 'test') - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'subnets', - wexc.HTTPInternalServerError.code) - - def test_create_subnets_bulk_native_plugin_failure(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk subnet create") - plugin_ref = self._get_plugin_ref() - orig = plugin_ref.create_subnet - with mock.patch.object(plugin_ref, - 'create_subnet') as patched_plugin: - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - with self.network() as net: - res = self._create_subnet_bulk(self.fmt, 2, - net['network']['id'], - 'test') - - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'subnets', - wexc.HTTPInternalServerError.code) - - -class TestCiscoRouterInterfacesV2(CiscoNetworkPluginV2TestCase): - - def setUp(self): - """Configure a log exception counter and an API extension manager.""" - self.log_exc_count = 0 - - def _count_exception_logs(*args, **kwargs): - self.log_exc_count += 1 - - mock.patch.object(logging.LoggerAdapter, 'exception', - autospec=True, - side_effect=_count_exception_logs, - wraps=logging.LoggerAdapter.exception).start() - super(TestCiscoRouterInterfacesV2, self).setUp() - ext_mgr = extensions.PluginAwareExtensionManager.get_instance() - self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr) - - @contextlib.contextmanager - def _network_subnet_router(self): - """Context mgr for creating/deleting a net, subnet, and router.""" - with self.network() as network: - with self.subnet(network=network) as subnet: - data = {'router': {'tenant_id': 'test_tenant_id'}} - request = self.new_create_request('routers', data, self.fmt) - response = request.get_response(self.ext_api) - router = self.deserialize(self.fmt, response) - yield network, subnet, router - self._delete('routers', router['router']['id']) - - @contextlib.contextmanager - def _router_interface(self, router, subnet, **kwargs): - """Create a router interface, yield the response, then delete it.""" - interface_data = {} - if subnet: - interface_data['subnet_id'] = subnet['subnet']['id'] - interface_data.update(kwargs) - request = self.new_action_request('routers', interface_data, - router['router']['id'], - 'add_router_interface') - response = request.get_response(self.ext_api) - - yield response - - # If router interface was created successfully, delete it now. - if response.status_int == wexc.HTTPOk.code: - request = self.new_action_request('routers', interface_data, - router['router']['id'], - 'remove_router_interface') - request.get_response(self.ext_api) - - @contextlib.contextmanager - def _network_subnet_router_interface(self, **kwargs): - """Context mgr for create/deleting a net, subnet, router and intf.""" - with self._network_subnet_router() as (network, subnet, router): - with self._router_interface(router, subnet, - **kwargs) as response: - yield response - - def test_port_list_filtered_by_router_id(self): - """Test port list command filtered by router ID.""" - with self._network_subnet_router() as (network, subnet, router): - with self._router_interface(router, subnet): - query_params = "device_id=%s" % router['router']['id'] - req = self.new_list_request('ports', self.fmt, query_params) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(len(res['ports']), 1) - self.assertEqual(res['ports'][0]['device_id'], - router['router']['id']) - self.assertFalse(self.log_exc_count) - - def test_add_remove_router_intf_with_nexus_l3_enabled(self): - """Verifies proper add/remove intf operation with Nexus L3 enabled. - - With 'nexus_l3_enable' configured to True, confirm that a switched - virtual interface (SVI) is created/deleted on the Nexus switch when - a virtual router interface is created/deleted. - """ - cisco_config.CONF.set_override('nexus_l3_enable', True, 'CISCO') - with self._network_subnet_router_interface(): - self.assertTrue(self._is_in_last_nexus_cfg( - ['interface', 'vlan', 'ip', 'address'])) - # Clear list of calls made to mock ncclient - self.mock_ncclient.reset() - # Router interface is now deleted. Confirm that SVI - # has been deleted from the Nexus switch. - self.assertTrue(self._is_in_nexus_cfg(['no', 'interface', 'vlan'])) - self.assertTrue(self._is_in_last_nexus_cfg(['no', 'vlan'])) - - def test_add_remove_router_intf_with_nexus_l3_disabled(self): - """Verifies proper add/remove intf operation with Nexus L3 disabled. - - With 'nexus_l3_enable' configured to False, confirm that no changes - are made to the Nexus switch running configuration when a virtual - router interface is created and then deleted. - """ - cisco_config.CONF.set_override('nexus_l3_enable', False, 'CISCO') - with self._network_subnet_router_interface(): - self.assertFalse(self.mock_ncclient.manager.connect. - return_value.edit_config.called) - - def test_create_svi_but_subnet_not_specified_exception(self): - """Tests raising of SubnetNotSpecified exception. - - Tests that a SubnetNotSpecified exception is raised when an - add_router_interface request is made for creating a switch virtual - interface (SVI), but the request does not specify a subnet. - """ - cisco_config.CONF.set_override('nexus_l3_enable', True, 'CISCO') - with self._network_subnet_router() as (network, subnet, router): - with self._router_interface(router, subnet=None) as response: - self._assertExpectedHTTP(response.status_int, - c_exc.SubnetNotSpecified) - - def test_create_svi_but_port_id_included_exception(self): - """Tests raising of PortIdForNexusSvi exception. - - Tests that a PortIdForNexusSvi exception is raised when an - add_router_interface request is made for creating a switch virtual - interface (SVI), but the request includes a virtual port ID. - """ - cisco_config.CONF.set_override('nexus_l3_enable', True, 'CISCO') - with self._network_subnet_router_interface( - port_id='my_port_id') as response: - self._assertExpectedHTTP(response.status_int, - c_exc.PortIdForNexusSvi) - - -class TestCiscoPortsV2XML(TestCiscoPortsV2): - fmt = 'xml' - - -class TestCiscoNetworksV2XML(TestCiscoNetworksV2): - fmt = 'xml' - - -class TestCiscoSubnetsV2XML(TestCiscoSubnetsV2): - fmt = 'xml' - - -class TestCiscoRouterInterfacesV2XML(TestCiscoRouterInterfacesV2): - fmt = 'xml' diff --git a/neutron/tests/unit/cisco/test_nexus_db.py b/neutron/tests/unit/cisco/test_nexus_db.py deleted file mode 100644 index 49b3dce50..000000000 --- a/neutron/tests/unit/cisco/test_nexus_db.py +++ /dev/null @@ -1,239 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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 collections -import mock -import testtools - -from neutron.db import api as db -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.common import config -from neutron.plugins.cisco.db import nexus_db_v2 as nxdb -from neutron.plugins.cisco.nexus import cisco_nexus_plugin_v2 -from neutron.tests import base - - -class CiscoNexusDbTest(base.BaseTestCase): - - """Unit tests for cisco.db.nexus_models_v2.NexusPortBinding model.""" - - NpbObj = collections.namedtuple('NpbObj', 'port vlan switch instance') - - def setUp(self): - super(CiscoNexusDbTest, self).setUp() - db.configure_db() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def _npb_test_obj(self, pnum, vnum, switch=None, instance=None): - """Create a Nexus port binding test object from a pair of numbers.""" - if pnum is 'router': - port = pnum - else: - port = '1/%s' % str(pnum) - vlan = str(vnum) - if switch is None: - switch = '10.9.8.7' - if instance is None: - instance = 'instance_%s_%s' % (str(pnum), str(vnum)) - return self.NpbObj(port, vlan, switch, instance) - - def _assert_equal(self, npb, npb_obj): - self.assertEqual(npb.port_id, npb_obj.port) - self.assertEqual(int(npb.vlan_id), int(npb_obj.vlan)) - self.assertEqual(npb.switch_ip, npb_obj.switch) - self.assertEqual(npb.instance_id, npb_obj.instance) - - def _add_to_db(self, npbs): - for npb in npbs: - nxdb.add_nexusport_binding( - npb.port, npb.vlan, npb.switch, npb.instance) - - def test_nexusportbinding_add_remove(self): - npb11 = self._npb_test_obj(10, 100) - npb = nxdb.add_nexusport_binding( - npb11.port, npb11.vlan, npb11.switch, npb11.instance) - self._assert_equal(npb, npb11) - npb = nxdb.remove_nexusport_binding( - npb11.port, npb11.vlan, npb11.switch, npb11.instance) - self.assertEqual(len(npb), 1) - self._assert_equal(npb[0], npb11) - with testtools.ExpectedException(c_exc.NexusPortBindingNotFound): - nxdb.remove_nexusport_binding( - npb11.port, npb11.vlan, npb11.switch, npb11.instance) - - def test_nexusportbinding_get(self): - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100) - npb22 = self._npb_test_obj(20, 200) - self._add_to_db([npb11, npb21, npb22]) - - npb = nxdb.get_nexusport_binding( - npb11.port, npb11.vlan, npb11.switch, npb11.instance) - self.assertEqual(len(npb), 1) - self._assert_equal(npb[0], npb11) - npb = nxdb.get_nexusport_binding( - npb21.port, npb21.vlan, npb21.switch, npb21.instance) - self.assertEqual(len(npb), 1) - self._assert_equal(npb[0], npb21) - npb = nxdb.get_nexusport_binding( - npb22.port, npb22.vlan, npb22.switch, npb22.instance) - self.assertEqual(len(npb), 1) - self._assert_equal(npb[0], npb22) - - with testtools.ExpectedException(c_exc.NexusPortBindingNotFound): - nxdb.get_nexusport_binding( - npb21.port, npb21.vlan, npb21.switch, "dummyInstance") - - def test_nexusvlanbinding_get(self): - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100) - npb22 = self._npb_test_obj(20, 200) - self._add_to_db([npb11, npb21, npb22]) - - npb_all_v100 = nxdb.get_nexusvlan_binding(npb11.vlan, npb11.switch) - self.assertEqual(len(npb_all_v100), 2) - npb_v200 = nxdb.get_nexusvlan_binding(npb22.vlan, npb22.switch) - self.assertEqual(len(npb_v200), 1) - self._assert_equal(npb_v200[0], npb22) - - with testtools.ExpectedException(c_exc.NexusPortBindingNotFound): - nxdb.get_nexusvlan_binding(npb21.vlan, "dummySwitch") - - def test_nexusvmbinding_get(self): - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100) - npb22 = self._npb_test_obj(20, 200) - self._add_to_db([npb11, npb21, npb22]) - - npb = nxdb.get_nexusvm_bindings(npb21.vlan, npb21.instance)[0] - self._assert_equal(npb, npb21) - npb = nxdb.get_nexusvm_bindings(npb22.vlan, npb22.instance)[0] - self._assert_equal(npb, npb22) - - with testtools.ExpectedException(c_exc.NexusPortBindingNotFound): - nxdb.get_nexusvm_bindings(npb21.vlan, "dummyInstance") - - def test_nexusportvlanswitchbinding_get(self): - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100) - self._add_to_db([npb11, npb21]) - - npb = nxdb.get_port_vlan_switch_binding( - npb11.port, npb11.vlan, npb11.switch) - self.assertEqual(len(npb), 1) - self._assert_equal(npb[0], npb11) - - with testtools.ExpectedException(c_exc.NexusPortBindingNotFound): - nxdb.get_port_vlan_switch_binding( - npb21.port, npb21.vlan, "dummySwitch") - - def test_nexusportswitchbinding_get(self): - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100, switch='2.2.2.2') - npb22 = self._npb_test_obj(20, 200, switch='2.2.2.2') - self._add_to_db([npb11, npb21, npb22]) - - npb = nxdb.get_port_switch_bindings(npb11.port, npb11.switch) - self.assertEqual(len(npb), 1) - self._assert_equal(npb[0], npb11) - npb_all_p20 = nxdb.get_port_switch_bindings(npb21.port, npb21.switch) - self.assertEqual(len(npb_all_p20), 2) - - npb = nxdb.get_port_switch_bindings(npb21.port, "dummySwitch") - self.assertIsNone(npb) - - def test_nexussvibinding_get(self): - npbr1 = self._npb_test_obj('router', 100) - npb21 = self._npb_test_obj(20, 100) - self._add_to_db([npbr1, npb21]) - - npb_svi = nxdb.get_nexussvi_bindings() - self.assertEqual(len(npb_svi), 1) - self._assert_equal(npb_svi[0], npbr1) - - npbr2 = self._npb_test_obj('router', 200) - self._add_to_db([npbr2]) - npb_svi = nxdb.get_nexussvi_bindings() - self.assertEqual(len(npb_svi), 2) - - def test_nexussviswitch_find(self): - """Test Nexus switch selection for SVI placement.""" - # Configure 2 Nexus switches - nexus_switches = { - ('1.1.1.1', 'username'): 'admin', - ('1.1.1.1', 'password'): 'password1', - ('1.1.1.1', 'host1'): '1/1', - ('2.2.2.2', 'username'): 'admin', - ('2.2.2.2', 'password'): 'password2', - ('2.2.2.2', 'host2'): '1/1', - } - nexus_plugin = cisco_nexus_plugin_v2.NexusPlugin() - nexus_plugin._client = mock.Mock() - nexus_plugin._client.nexus_switches = nexus_switches - - # Set the Cisco config module's first configured device IP address - # according to the preceding switch config - with mock.patch.object(config, 'first_device_ip', new='1.1.1.1'): - - # Enable round-robin mode with no SVIs configured on any of the - # Nexus switches (i.e. no entries in the SVI database). The - # plugin should select the first switch in the configuration. - config.CONF.set_override('svi_round_robin', True, 'CISCO') - switch_ip = nexus_plugin._find_switch_for_svi() - self.assertEqual(switch_ip, '1.1.1.1') - - # Keep round-robin mode enabled, and add entries to the SVI - # database. The plugin should select the switch with the least - # number of entries in the SVI database. - vlan = 100 - npbr11 = self._npb_test_obj('router', vlan, switch='1.1.1.1', - instance='instance11') - npbr12 = self._npb_test_obj('router', vlan, switch='1.1.1.1', - instance='instance12') - npbr21 = self._npb_test_obj('router', vlan, switch='2.2.2.2', - instance='instance21') - self._add_to_db([npbr11, npbr12, npbr21]) - switch_ip = nexus_plugin._find_switch_for_svi() - self.assertEqual(switch_ip, '2.2.2.2') - - # Disable round-robin mode. The plugin should select the - # first switch in the configuration. - config.CONF.clear_override('svi_round_robin', 'CISCO') - switch_ip = nexus_plugin._find_switch_for_svi() - self.assertEqual(switch_ip, '1.1.1.1') - - def test_nexusbinding_update(self): - npb11 = self._npb_test_obj(10, 100, switch='1.1.1.1', instance='test') - npb21 = self._npb_test_obj(20, 100, switch='1.1.1.1', instance='test') - self._add_to_db([npb11, npb21]) - - npb_all_v100 = nxdb.get_nexusvlan_binding(npb11.vlan, '1.1.1.1') - self.assertEqual(len(npb_all_v100), 2) - - npb22 = self._npb_test_obj(20, 200, switch='1.1.1.1', instance='test') - npb = nxdb.update_nexusport_binding(npb21.port, 200) - self._assert_equal(npb, npb22) - - npb_all_v100 = nxdb.get_nexusvlan_binding(npb11.vlan, '1.1.1.1') - self.assertEqual(len(npb_all_v100), 1) - self._assert_equal(npb_all_v100[0], npb11) - - npb = nxdb.update_nexusport_binding(npb21.port, 0) - self.assertIsNone(npb) - - npb33 = self._npb_test_obj(30, 300, switch='1.1.1.1', instance='test') - with testtools.ExpectedException(c_exc.NexusPortBindingNotFound): - nxdb.update_nexusport_binding(npb33.port, 200) diff --git a/neutron/tests/unit/cisco/test_nexus_plugin.py b/neutron/tests/unit/cisco/test_nexus_plugin.py deleted file mode 100644 index 6cf54ab84..000000000 --- a/neutron/tests/unit/cisco/test_nexus_plugin.py +++ /dev/null @@ -1,301 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 contextlib -import mock - -from oslo.config import cfg - -from neutron.db import api as db -from neutron.extensions import providernet as provider -from neutron.openstack.common import importutils -from neutron.plugins.cisco.common import cisco_constants as const -from neutron.plugins.cisco.common import cisco_exceptions as cisco_exc -from neutron.plugins.cisco.common import config as cisco_config -from neutron.plugins.cisco.db import network_db_v2 as cdb -from neutron.plugins.cisco.nexus import cisco_nexus_plugin_v2 -from neutron.tests import base - - -NEXUS_IP_ADDRESS = '1.1.1.1' -HOSTNAME1 = 'testhost1' -HOSTNAME2 = 'testhost2' -HOSTNAME3 = 'testhost3' -INSTANCE1 = 'testvm1' -INSTANCE2 = 'testvm2' -INSTANCE3 = 'testvm3' -NEXUS_PORT1 = '1/10' -NEXUS_PORT2 = '1/20' -NEXUS_PC_IP_ADDRESS = '2.2.2.2' -NEXUS_PORTCHANNELS = 'portchannel:2' -PC_HOSTNAME = 'testpchost' -NEXUS_SSH_PORT = '22' -NEXUS_DRIVER = ('neutron.plugins.cisco.nexus.' - 'cisco_nexus_network_driver_v2.CiscoNEXUSDriver') -NET_ATTRS = [const.NET_ID, - const.NET_NAME, - const.NET_VLAN_NAME, - const.NET_VLAN_ID] - - -class TestCiscoNexusPlugin(base.BaseTestCase): - - def setUp(self): - """Set up function.""" - super(TestCiscoNexusPlugin, self).setUp() - self.tenant_id = "test_tenant_cisco1" - self.net_name = "test_network_cisco1" - self.net_id = 7 - self.vlan_name = "q-" + str(self.net_id) + "vlan" - self.vlan_id = 267 - self.second_tenant_id = "test_tenant_2" - self.second_net_name = "test_network_cisco2" - self.second_net_id = 5 - self.second_vlan_name = "q-" + str(self.second_net_id) + "vlan" - self.second_vlan_id = 265 - self._pchostname = PC_HOSTNAME - - self.attachment1 = { - const.TENANT_ID: self.tenant_id, - const.INSTANCE_ID: INSTANCE1, - const.HOST_NAME: HOSTNAME1, - } - self.attachment2 = { - const.TENANT_ID: self.second_tenant_id, - const.INSTANCE_ID: INSTANCE2, - const.HOST_NAME: HOSTNAME2, - } - self.attachment3 = { - const.TENANT_ID: self.second_tenant_id, - const.INSTANCE_ID: INSTANCE3, - const.HOST_NAME: HOSTNAME3, - } - self.network1 = { - const.NET_ID: self.net_id, - const.NET_NAME: self.net_name, - const.NET_VLAN_NAME: self.vlan_name, - const.NET_VLAN_ID: self.vlan_id, - } - self.network2 = { - const.NET_ID: self.second_net_id, - const.NET_NAME: self.second_net_name, - const.NET_VLAN_NAME: self.second_vlan_name, - const.NET_VLAN_ID: self.second_vlan_id, - } - self.network3 = { - const.NET_ID: 8, - const.NET_NAME: 'vpc_net', - const.NET_VLAN_NAME: 'q-268', - const.NET_VLAN_ID: '268', - } - self.delete_port_args_1 = [ - self.attachment1[const.INSTANCE_ID], - self.network1[const.NET_VLAN_ID], - ] - self.providernet = { - const.NET_ID: 9, - const.NET_NAME: 'pnet1', - const.NET_VLAN_NAME: 'p-300', - const.NET_VLAN_ID: 300, - provider.NETWORK_TYPE: 'vlan', - provider.PHYSICAL_NETWORK: self.net_name + '200:299', - provider.SEGMENTATION_ID: 300, - } - - def new_nexus_init(self): - self._client = importutils.import_object(NEXUS_DRIVER) - self._client.nexus_switches = { - (NEXUS_IP_ADDRESS, HOSTNAME1): NEXUS_PORT1, - (NEXUS_IP_ADDRESS, 'ssh_port'): NEXUS_SSH_PORT, - (NEXUS_IP_ADDRESS, HOSTNAME2): NEXUS_PORT2, - (NEXUS_IP_ADDRESS, 'ssh_port'): NEXUS_SSH_PORT, - (NEXUS_PC_IP_ADDRESS, 'ssh_port'): NEXUS_SSH_PORT, - } - self._nexus_switches = { - ('NEXUS_SWITCH', NEXUS_IP_ADDRESS, HOSTNAME1): NEXUS_PORT1, - ('NEXUS_SWITCH', NEXUS_IP_ADDRESS, HOSTNAME2): NEXUS_PORT2, - ('NEXUS_SWITCH', NEXUS_PC_IP_ADDRESS, HOSTNAME3): - NEXUS_PORTCHANNELS, - ('NEXUS_SWITCH', NEXUS_PC_IP_ADDRESS, 'ssh_port'): - NEXUS_SSH_PORT, - ('NEXUS_SWITCH', NEXUS_IP_ADDRESS, HOSTNAME3): - NEXUS_PORTCHANNELS, - ('NEXUS_SWITCH', NEXUS_IP_ADDRESS, 'ssh_port'): NEXUS_SSH_PORT, - } - self._client.credentials = { - NEXUS_IP_ADDRESS: { - 'username': 'admin', - 'password': 'pass1234' - }, - NEXUS_PC_IP_ADDRESS: { - 'username': 'admin', - 'password': 'password' - }, - } - db.configure_db() - - self.addCleanup(db.clear_db) - # Use a mock netconf client - self.mock_ncclient = mock.Mock() - - with contextlib.nested( - mock.patch.dict('sys.modules', {'ncclient': self.mock_ncclient}), - mock.patch.object(cisco_nexus_plugin_v2.NexusPlugin, - '__init__', new=new_nexus_init) - ): - self._cisco_nexus_plugin = cisco_nexus_plugin_v2.NexusPlugin() - - # Set the Cisco config module's first configured device IP address - # according to the preceding switch config. - mock.patch.object(cisco_config, 'first_device_ip', - new=NEXUS_IP_ADDRESS).start() - - def test_create_delete_networks(self): - """Tests creation of two new Virtual Networks.""" - new_net_dict = self._cisco_nexus_plugin.create_network( - self.network1, self.attachment1) - for attr in NET_ATTRS: - self.assertEqual(new_net_dict[attr], self.network1[attr]) - - expected_instance_id = self._cisco_nexus_plugin.delete_port( - INSTANCE1, self.vlan_id) - - self.assertEqual(expected_instance_id, INSTANCE1) - - new_net_dict = self._cisco_nexus_plugin.create_network( - self.network2, self.attachment1) - for attr in NET_ATTRS: - self.assertEqual(new_net_dict[attr], self.network2[attr]) - - expected_instance_id = self._cisco_nexus_plugin.delete_port( - INSTANCE1, self.second_vlan_id) - - self.assertEqual(expected_instance_id, INSTANCE1) - - def _create_delete_providernet(self, auto_create, auto_trunk): - cfg.CONF.set_override( - 'provider_vlan_auto_create', auto_create, 'CISCO') - cfg.CONF.set_override( - 'provider_vlan_auto_trunk', auto_trunk, 'CISCO') - with mock.patch.object(cdb, 'is_provider_vlan', - return_value=True) as mock_db: - # Create a provider network - new_net_dict = self._cisco_nexus_plugin.create_network( - self.providernet, self.attachment1) - self.assertEqual(mock_db.call_count, 1) - for attr in NET_ATTRS: - self.assertEqual(new_net_dict[attr], self.providernet[attr]) - # Delete the provider network - instance_id = self._cisco_nexus_plugin.delete_port( - self.attachment1[const.INSTANCE_ID], - self.providernet[const.NET_VLAN_ID]) - self.assertEqual(instance_id, - self.attachment1[const.INSTANCE_ID]) - - def test_create_delete_providernet(self): - self._create_delete_providernet(auto_create=True, auto_trunk=True) - - def test_create_delete_provider_vlan_network_cfg_auto_man(self): - self._create_delete_providernet(auto_create=True, auto_trunk=False) - - def test_create_delete_provider_vlan_network_cfg_man_auto(self): - self._create_delete_providernet(auto_create=False, auto_trunk=True) - - def test_create_delete_provider_vlan_network_cfg_man_man(self): - self._create_delete_providernet(auto_create=False, auto_trunk=False) - - def test_create_delete_network_portchannel(self): - """Tests creation of a network over a portchannel.""" - new_net_dict = self._cisco_nexus_plugin.create_network( - self.network3, self.attachment3) - self.assertEqual(new_net_dict[const.NET_ID], - self.network3[const.NET_ID]) - self.assertEqual(new_net_dict[const.NET_NAME], - self.network3[const.NET_NAME]) - self.assertEqual(new_net_dict[const.NET_VLAN_NAME], - self.network3[const.NET_VLAN_NAME]) - self.assertEqual(new_net_dict[const.NET_VLAN_ID], - self.network3[const.NET_VLAN_ID]) - - self._cisco_nexus_plugin.delete_port( - INSTANCE3, self.network3[const.NET_VLAN_ID] - ) - - def _add_router_interface(self): - """Add a router interface using fixed (canned) parameters.""" - vlan_name = self.vlan_name - vlan_id = self.vlan_id - gateway_ip = '10.0.0.1/24' - router_id = '00000R1' - subnet_id = '00001' - return self._cisco_nexus_plugin.add_router_interface( - vlan_name, vlan_id, subnet_id, gateway_ip, router_id) - - def _remove_router_interface(self): - """Remove a router interface created with _add_router_interface.""" - vlan_id = self.vlan_id - router_id = '00000R1' - return self._cisco_nexus_plugin.remove_router_interface(vlan_id, - router_id) - - def test_nexus_add_remove_router_interface(self): - """Tests addition of a router interface.""" - self.assertTrue(self._add_router_interface()) - self.assertEqual(self._remove_router_interface(), '00000R1') - - def test_nexus_dup_add_router_interface(self): - """Tests a duplicate add of a router interface.""" - self._add_router_interface() - try: - self.assertRaises( - cisco_exc.SubnetInterfacePresent, - self._add_router_interface) - finally: - self._remove_router_interface() - - def test_nexus_no_svi_switch_exception(self): - """Tests failure to find a Nexus switch for SVI placement.""" - # Clear the Nexus switches dictionary. - with mock.patch.dict(self._cisco_nexus_plugin._client.nexus_switches, - {}, clear=True): - # Clear the first Nexus IP address discovered in config - with mock.patch.object(cisco_config, 'first_device_ip', - new=None): - self.assertRaises(cisco_exc.NoNexusSviSwitch, - self._add_router_interface) - - def test_nexus_add_port_after_router_interface(self): - """Tests creating a port after a router interface. - - Test creating a port after an SVI router interface has - been created. Only a trunk call should be invoked and the - plugin should not attempt to recreate the vlan. - """ - self._add_router_interface() - # Create a network on the switch - self._cisco_nexus_plugin.create_network( - self.network1, self.attachment1) - - # Grab a list of all mock calls from ncclient - last_cfgs = (self.mock_ncclient.manager.connect.return_value. - edit_config.mock_calls) - - # The last ncclient call should be for trunking and the second - # to last call should be creating the SVI interface - last_cfg = last_cfgs[-1][2]['config'] - self.assertIn('allowed', last_cfg) - - slast_cfg = last_cfgs[-2][2]['config'] - self.assertIn('10.0.0.1/24', slast_cfg) diff --git a/neutron/tests/unit/cisco/test_plugin_model.py b/neutron/tests/unit/cisco/test_plugin_model.py deleted file mode 100755 index fa87a5010..000000000 --- a/neutron/tests/unit/cisco/test_plugin_model.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2014 Cisco Systems, Inc. -# -# 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 sys - -import mock - -from neutron import context -from neutron.plugins.cisco.common import cisco_constants as const -from neutron.plugins.cisco.common import config as cisco_config -from neutron.plugins.cisco.models import virt_phy_sw_v2 -from neutron.plugins.cisco.nexus import cisco_nexus_plugin_v2 -from neutron.tests import base - - -class TestCiscoPluginModel(base.BaseTestCase): - - def setUp(self): - # Point config file to: neutron/tests/etc/neutron.conf.test - self.config_parse() - - super(TestCiscoPluginModel, self).setUp() - - def test_non_nexus_device_driver(self): - """Tests handling of an non-Nexus device driver being configured.""" - with mock.patch.dict(sys.modules, {'mock_driver': mock.Mock()}): - cisco_config.CONF.set_override('nexus_driver', - 'mock_driver.Non_Nexus_Driver', - 'CISCO') - # Plugin model instance should have is_nexus_plugin set to False - model = virt_phy_sw_v2.VirtualPhysicalSwitchModelV2() - self.assertFalse(model.is_nexus_plugin) - - # Model's _invoke_nexus_for_net_create should just return False - user_id = 'user_id' - tenant_id = 'tenant_id' - ctx = context.Context(user_id, tenant_id) - self.assertFalse(model._invoke_nexus_for_net_create( - ctx, tenant_id, net_id='net_id', - instance_id='instance_id', host_id='host_id')) - - def test_nexus_plugin_calls_ignored_if_plugin_not_loaded(self): - """Verifies Nexus plugin calls are ignored if plugin is not loaded.""" - cisco_config.CONF.set_override(const.NEXUS_PLUGIN, - None, 'CISCO_PLUGINS') - with mock.patch.object(cisco_nexus_plugin_v2.NexusPlugin, - 'create_network') as mock_create_network: - model = virt_phy_sw_v2.VirtualPhysicalSwitchModelV2() - model._invoke_plugin_per_device(model, const.NEXUS_PLUGIN, - 'create_network') - self.assertFalse(mock_create_network.called) diff --git a/neutron/tests/unit/db/firewall/__init__.py b/neutron/tests/unit/db/firewall/__init__.py deleted file mode 100644 index cae279d0a..000000000 --- a/neutron/tests/unit/db/firewall/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack Foundation -# -# 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. diff --git a/neutron/tests/unit/db/firewall/test_db_firewall.py b/neutron/tests/unit/db/firewall/test_db_firewall.py deleted file mode 100644 index 69cf36483..000000000 --- a/neutron/tests/unit/db/firewall/test_db_firewall.py +++ /dev/null @@ -1,1055 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 Big Switch Networks, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Sumit Naiksatam, sumitnaiksatam@gmail.com, Big Switch Networks, Inc. - -import contextlib -import logging - -import mock -import webob.exc - -from neutron.api import extensions as api_ext -from neutron.common import config -from neutron import context -from neutron.db.firewall import firewall_db as fdb -import neutron.extensions -from neutron.extensions import firewall -from neutron import manager -from neutron.openstack.common import importutils -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.services.firewall import fwaas_plugin -from neutron.tests.unit import test_db_plugin - - -LOG = logging.getLogger(__name__) -DB_FW_PLUGIN_KLASS = ( - "neutron.db.firewall.firewall_db.Firewall_db_mixin" -) -FWAAS_PLUGIN = 'neutron.services.firewall.fwaas_plugin' -DELETEFW_PATH = FWAAS_PLUGIN + '.FirewallAgentApi.delete_firewall' -extensions_path = ':'.join(neutron.extensions.__path__) -DESCRIPTION = 'default description' -SHARED = True -PROTOCOL = 'tcp' -IP_VERSION = 4 -SOURCE_IP_ADDRESS_RAW = '1.1.1.1' -DESTINATION_IP_ADDRESS_RAW = '2.2.2.2' -SOURCE_PORT = '55000:56000' -DESTINATION_PORT = '56000:57000' -ACTION = 'allow' -AUDITED = True -ENABLED = True -ADMIN_STATE_UP = True - - -class FakeAgentApi(fwaas_plugin.FirewallCallbacks): - """ - This class used to mock the AgentAPI delete method inherits from - FirewallCallbacks because it needs access to the firewall_deleted method. - The delete_firewall method belongs to the FirewallAgentApi, which has - no access to the firewall_deleted method normally because it's not - responsible for deleting the firewall from the DB. However, it needs - to in the unit tests since there is no agent to call back. - """ - def __init__(self): - pass - - def delete_firewall(self, context, firewall, **kwargs): - self.plugin = manager.NeutronManager.get_service_plugins()['FIREWALL'] - self.firewall_deleted(context, firewall['id'], **kwargs) - - -class FirewallPluginDbTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - resource_prefix_map = dict( - (k, constants.COMMON_PREFIXES[constants.FIREWALL]) - for k in firewall.RESOURCE_ATTRIBUTE_MAP.keys() - ) - - def setUp(self, core_plugin=None, fw_plugin=None, ext_mgr=None): - self.agentapi_delf_p = mock.patch(DELETEFW_PATH, create=True, - new=FakeAgentApi().delete_firewall) - self.agentapi_delf_p.start() - if not fw_plugin: - fw_plugin = DB_FW_PLUGIN_KLASS - service_plugins = {'fw_plugin_name': fw_plugin} - - fdb.Firewall_db_mixin.supported_extension_aliases = ["fwaas"] - super(FirewallPluginDbTestCase, self).setUp( - ext_mgr=ext_mgr, - service_plugins=service_plugins - ) - - if not ext_mgr: - self.plugin = importutils.import_object(fw_plugin) - ext_mgr = api_ext.PluginAwareExtensionManager( - extensions_path, - {constants.FIREWALL: self.plugin} - ) - app = config.load_paste_app('extensions_test_app') - self.ext_api = api_ext.ExtensionMiddleware(app, ext_mgr=ext_mgr) - - def _test_list_resources(self, resource, items, - neutron_context=None, - query_params=None): - if resource.endswith('y'): - resource_plural = resource.replace('y', 'ies') - else: - resource_plural = resource + 's' - - res = self._list(resource_plural, - neutron_context=neutron_context, - query_params=query_params) - resource = resource.replace('-', '_') - self.assertEqual(sorted([i['id'] for i in res[resource_plural]]), - sorted([i[resource]['id'] for i in items])) - - def _get_test_firewall_rule_attrs(self, name='firewall_rule1'): - attrs = {'name': name, - 'tenant_id': self._tenant_id, - 'shared': SHARED, - 'protocol': PROTOCOL, - 'ip_version': IP_VERSION, - 'source_ip_address': SOURCE_IP_ADDRESS_RAW, - 'destination_ip_address': DESTINATION_IP_ADDRESS_RAW, - 'source_port': SOURCE_PORT, - 'destination_port': DESTINATION_PORT, - 'action': ACTION, - 'enabled': ENABLED} - return attrs - - def _get_test_firewall_policy_attrs(self, name='firewall_policy1'): - attrs = {'name': name, - 'description': DESCRIPTION, - 'tenant_id': self._tenant_id, - 'shared': SHARED, - 'firewall_rules': [], - 'audited': AUDITED} - return attrs - - def _get_test_firewall_attrs(self, name='firewall_1'): - attrs = {'name': name, - 'tenant_id': self._tenant_id, - 'admin_state_up': ADMIN_STATE_UP, - 'status': 'PENDING_CREATE'} - - return attrs - - def _create_firewall_policy(self, fmt, name, description, shared, - firewall_rules, audited, - expected_res_status=None, **kwargs): - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'firewall_policy': {'name': name, - 'description': description, - 'tenant_id': tenant_id, - 'shared': shared, - 'firewall_rules': firewall_rules, - 'audited': audited}} - - fw_policy_req = self.new_create_request('firewall_policies', data, fmt) - fw_policy_res = fw_policy_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(fw_policy_res.status_int, expected_res_status) - - return fw_policy_res - - def _replace_firewall_status(self, attrs, old_status, new_status): - if attrs['status'] is old_status: - attrs['status'] = new_status - return attrs - - @contextlib.contextmanager - def firewall_policy(self, fmt=None, name='firewall_policy1', - description=DESCRIPTION, shared=True, - firewall_rules=None, audited=True, - no_delete=False, **kwargs): - if firewall_rules is None: - firewall_rules = [] - if not fmt: - fmt = self.fmt - res = self._create_firewall_policy(fmt, name, description, shared, - firewall_rules, audited, - **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - firewall_policy = self.deserialize(fmt or self.fmt, res) - yield firewall_policy - if not no_delete: - self._delete('firewall_policies', - firewall_policy['firewall_policy']['id']) - - def _create_firewall_rule(self, fmt, name, shared, protocol, - ip_version, source_ip_address, - destination_ip_address, source_port, - destination_port, action, enabled, - expected_res_status=None, **kwargs): - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'firewall_rule': {'name': name, - 'tenant_id': tenant_id, - 'shared': shared, - 'protocol': protocol, - 'ip_version': ip_version, - 'source_ip_address': source_ip_address, - 'destination_ip_address': - destination_ip_address, - 'source_port': source_port, - 'destination_port': destination_port, - 'action': action, - 'enabled': enabled}} - - fw_rule_req = self.new_create_request('firewall_rules', data, fmt) - fw_rule_res = fw_rule_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(fw_rule_res.status_int, expected_res_status) - - return fw_rule_res - - @contextlib.contextmanager - def firewall_rule(self, fmt=None, name='firewall_rule1', - shared=SHARED, protocol=PROTOCOL, ip_version=IP_VERSION, - source_ip_address=SOURCE_IP_ADDRESS_RAW, - destination_ip_address=DESTINATION_IP_ADDRESS_RAW, - source_port=SOURCE_PORT, - destination_port=DESTINATION_PORT, - action=ACTION, enabled=ENABLED, - no_delete=False, **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_firewall_rule(fmt, name, shared, protocol, - ip_version, source_ip_address, - destination_ip_address, - source_port, destination_port, - action, enabled, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - firewall_rule = self.deserialize(fmt or self.fmt, res) - yield firewall_rule - if not no_delete: - self._delete('firewall_rules', - firewall_rule['firewall_rule']['id']) - - def _create_firewall(self, fmt, name, description, firewall_policy_id, - admin_state_up=True, expected_res_status=None, - **kwargs): - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'firewall': {'name': name, - 'description': description, - 'firewall_policy_id': firewall_policy_id, - 'admin_state_up': admin_state_up, - 'tenant_id': tenant_id}} - - firewall_req = self.new_create_request('firewalls', data, fmt) - firewall_res = firewall_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(firewall_res.status_int, expected_res_status) - - return firewall_res - - @contextlib.contextmanager - def firewall(self, fmt=None, name='firewall_1', description=DESCRIPTION, - firewall_policy_id=None, admin_state_up=True, - no_delete=False, **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_firewall(fmt, name, description, firewall_policy_id, - admin_state_up, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - firewall = self.deserialize(fmt or self.fmt, res) - yield firewall - if not no_delete: - self._delete('firewalls', firewall['firewall']['id']) - - def _rule_action(self, action, id, firewall_rule_id, insert_before=None, - insert_after=None, expected_code=webob.exc.HTTPOk.code, - expected_body=None, body_data=None): - # We intentionally do this check for None since we want to distinguish - # from empty dictionary - if body_data is None: - if action == 'insert': - body_data = {'firewall_rule_id': firewall_rule_id, - 'insert_before': insert_before, - 'insert_after': insert_after} - else: - body_data = {'firewall_rule_id': firewall_rule_id} - - req = self.new_action_request('firewall_policies', - body_data, id, - "%s_rule" % action) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, expected_code) - response = self.deserialize(self.fmt, res) - if expected_body: - self.assertEqual(response, expected_body) - return response - - def _compare_firewall_rule_lists(self, firewall_policy_id, - list1, list2): - position = 0 - for r1, r2 in zip(list1, list2): - rule = r1['firewall_rule'] - rule['firewall_policy_id'] = firewall_policy_id - position += 1 - rule['position'] = position - for k in rule: - self.assertEqual(rule[k], r2[k]) - - -class TestFirewallDBPlugin(FirewallPluginDbTestCase): - - def test_create_firewall_policy(self): - name = "firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name) - - with self.firewall_policy(name=name, shared=SHARED, - firewall_rules=None, - audited=AUDITED) as firewall_policy: - for k, v in attrs.iteritems(): - self.assertEqual(firewall_policy['firewall_policy'][k], v) - - def test_create_firewall_policy_with_rules(self): - name = "firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name) - - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as fr: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - attrs['firewall_rules'] = fw_rule_ids - with self.firewall_policy(name=name, shared=SHARED, - firewall_rules=fw_rule_ids, - audited=AUDITED) as fwp: - for k, v in attrs.iteritems(): - self.assertEqual(fwp['firewall_policy'][k], v) - - def test_create_firewall_policy_with_previously_associated_rule(self): - with self.firewall_rule() as fwr: - fw_rule_ids = [fwr['firewall_rule']['id']] - with self.firewall_policy(firewall_rules=fw_rule_ids): - res = self._create_firewall_policy( - None, 'firewall_policy2', description=DESCRIPTION, - shared=SHARED, firewall_rules=fw_rule_ids, - audited=AUDITED) - self.assertEqual(res.status_int, 409) - - def test_show_firewall_policy(self): - name = "firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name) - - with self.firewall_policy(name=name, shared=SHARED, - firewall_rules=None, - audited=AUDITED) as fwp: - req = self.new_show_request('firewall_policies', - fwp['firewall_policy']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_policy'][k], v) - - def test_list_firewall_policies(self): - with contextlib.nested(self.firewall_policy(name='fwp1', - description='fwp'), - self.firewall_policy(name='fwp2', - description='fwp'), - self.firewall_policy(name='fwp3', - description='fwp') - ) as fw_policies: - self._test_list_resources('firewall_policy', - fw_policies, - query_params='description=fwp') - - def test_update_firewall_policy(self): - name = "new_firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name) - - with self.firewall_policy(shared=SHARED, - firewall_rules=None, - audited=AUDITED) as fwp: - data = {'firewall_policy': {'name': name}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_policy'][k], v) - - def test_update_firewall_policy_with_rules(self): - attrs = self._get_test_firewall_policy_attrs() - - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as fr: - with self.firewall_policy() as fwp: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - attrs['firewall_rules'] = fw_rule_ids - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs['audited'] = False - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_policy'][k], v) - - def test_update_firewall_policy_replace_rules(self): - attrs = self._get_test_firewall_policy_attrs() - - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3'), - self.firewall_rule(name='fwr4')) as frs: - fr1 = frs[0:2] - fr2 = frs[2:4] - with self.firewall_policy() as fwp: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr1] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - - fw_rule_ids = [r['firewall_rule']['id'] for r in fr2] - attrs['firewall_rules'] = fw_rule_ids - new_data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', new_data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs['audited'] = False - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_policy'][k], v) - - def test_update_firewall_policy_reorder_rules(self): - attrs = self._get_test_firewall_policy_attrs() - - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3'), - self.firewall_rule(name='fwr4')) as fr: - with self.firewall_policy() as fwp: - fw_rule_ids = [fr[2]['firewall_rule']['id'], - fr[3]['firewall_rule']['id']] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - # shuffle the rules, add more rules - fw_rule_ids = [fr[1]['firewall_rule']['id'], - fr[3]['firewall_rule']['id'], - fr[2]['firewall_rule']['id'], - fr[0]['firewall_rule']['id']] - attrs['firewall_rules'] = fw_rule_ids - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - rules = [] - for rule_id in fw_rule_ids: - req = self.new_show_request('firewall_rules', - rule_id, - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - rules.append(res['firewall_rule']) - self.assertEqual(rules[0]['position'], 1) - self.assertEqual(rules[0]['id'], fr[1]['firewall_rule']['id']) - self.assertEqual(rules[1]['position'], 2) - self.assertEqual(rules[1]['id'], fr[3]['firewall_rule']['id']) - self.assertEqual(rules[2]['position'], 3) - self.assertEqual(rules[2]['id'], fr[2]['firewall_rule']['id']) - self.assertEqual(rules[3]['position'], 4) - self.assertEqual(rules[3]['id'], fr[0]['firewall_rule']['id']) - - def test_update_firewall_policy_with_non_existing_rule(self): - attrs = self._get_test_firewall_policy_attrs() - - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2')) as fr: - with self.firewall_policy() as fwp: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - # appending non-existent rule - fw_rule_ids.append(uuidutils.generate_uuid()) - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = req.get_response(self.ext_api) - #check that the firewall_rule was not found - self.assertEqual(res.status_int, 404) - #check if none of the rules got added to the policy - req = self.new_show_request('firewall_policies', - fwp['firewall_policy']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_policy'][k], v) - - def test_delete_firewall_policy(self): - ctx = context.get_admin_context() - with self.firewall_policy(no_delete=True) as fwp: - fwp_id = fwp['firewall_policy']['id'] - req = self.new_delete_request('firewall_policies', fwp_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - self.assertRaises(firewall.FirewallPolicyNotFound, - self.plugin.get_firewall_policy, - ctx, fwp_id) - - def test_delete_firewall_policy_with_rule(self): - ctx = context.get_admin_context() - attrs = self._get_test_firewall_policy_attrs() - with self.firewall_policy(no_delete=True) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall_rule(name='fwr1') as fr: - fr_id = fr['firewall_rule']['id'] - fw_rule_ids = [fr_id] - attrs['firewall_rules'] = fw_rule_ids - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - fw_rule = self.plugin.get_firewall_rule(ctx, fr_id) - self.assertEqual(fw_rule['firewall_policy_id'], fwp_id) - req = self.new_delete_request('firewall_policies', fwp_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - self.assertRaises(firewall.FirewallPolicyNotFound, - self.plugin.get_firewall_policy, - ctx, fwp_id) - fw_rule = self.plugin.get_firewall_rule(ctx, fr_id) - self.assertIsNone(fw_rule['firewall_policy_id']) - - def test_delete_firewall_policy_with_firewall_association(self): - attrs = self._get_test_firewall_attrs() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - ADMIN_STATE_UP): - req = self.new_delete_request('firewall_policies', fwp_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 409) - - def test_create_firewall_rule(self): - attrs = self._get_test_firewall_rule_attrs() - - with self.firewall_rule() as firewall_rule: - for k, v in attrs.iteritems(): - self.assertEqual(firewall_rule['firewall_rule'][k], v) - - attrs['source_port'] = None - attrs['destination_port'] = None - with self.firewall_rule(source_port=None, - destination_port=None) as firewall_rule: - for k, v in attrs.iteritems(): - self.assertEqual(firewall_rule['firewall_rule'][k], v) - - attrs['source_port'] = '10000' - attrs['destination_port'] = '80' - with self.firewall_rule(source_port=10000, - destination_port=80) as firewall_rule: - for k, v in attrs.iteritems(): - self.assertEqual(firewall_rule['firewall_rule'][k], v) - - attrs['source_port'] = '10000' - attrs['destination_port'] = '80' - with self.firewall_rule(source_port='10000', - destination_port='80') as firewall_rule: - for k, v in attrs.iteritems(): - self.assertEqual(firewall_rule['firewall_rule'][k], v) - - def test_create_firewall_rule_icmp_with_port(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['protocol'] = 'icmp' - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) - - def test_create_firewall_rule_icmp_without_port(self): - attrs = self._get_test_firewall_rule_attrs() - - attrs['protocol'] = 'icmp' - attrs['source_port'] = None - attrs['destination_port'] = None - with self.firewall_rule(source_port=None, - destination_port=None, - protocol='icmp') as firewall_rule: - for k, v in attrs.iteritems(): - self.assertEqual(firewall_rule['firewall_rule'][k], v) - - def test_show_firewall_rule_with_fw_policy_not_associated(self): - attrs = self._get_test_firewall_rule_attrs() - with self.firewall_rule() as fw_rule: - req = self.new_show_request('firewall_rules', - fw_rule['firewall_rule']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - def test_show_firewall_rule_with_fw_policy_associated(self): - attrs = self._get_test_firewall_rule_attrs() - with self.firewall_rule() as fw_rule: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - data = {'firewall_policy': - {'firewall_rules': - [fw_rule['firewall_rule']['id']]}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - req = self.new_show_request('firewall_rules', - fw_rule['firewall_rule']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - def test_list_firewall_rules(self): - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as fr: - query_params = 'protocol=tcp' - self._test_list_resources('firewall_rule', fr, - query_params=query_params) - - def test_update_firewall_rule(self): - name = "new_firewall_rule1" - attrs = self._get_test_firewall_rule_attrs(name) - - attrs['source_port'] = '10:20' - attrs['destination_port'] = '30:40' - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'source_port': '10:20', - 'destination_port': '30:40'}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - attrs['source_port'] = '10000' - attrs['destination_port'] = '80' - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'source_port': 10000, - 'destination_port': 80}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - attrs['source_port'] = '10000' - attrs['destination_port'] = '80' - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'source_port': '10000', - 'destination_port': '80'}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - attrs['source_port'] = None - attrs['destination_port'] = None - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'source_port': None, - 'destination_port': None}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - def test_update_firewall_rule_with_policy_associated(self): - name = "new_firewall_rule1" - attrs = self._get_test_firewall_rule_attrs(name) - with self.firewall_rule() as fwr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - fwr_id = fwr['firewall_rule']['id'] - data = {'firewall_policy': {'firewall_rules': [fwr_id]}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - data = {'firewall_rule': {'name': name}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs['firewall_policy_id'] = fwp_id - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - req = self.new_show_request('firewall_policies', - fwp['firewall_policy']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - self.assertEqual(res['firewall_policy']['firewall_rules'], - [fwr_id]) - self.assertEqual(res['firewall_policy']['audited'], False) - - def test_delete_firewall_rule(self): - ctx = context.get_admin_context() - with self.firewall_rule(no_delete=True) as fwr: - fwr_id = fwr['firewall_rule']['id'] - req = self.new_delete_request('firewall_rules', fwr_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - self.assertRaises(firewall.FirewallRuleNotFound, - self.plugin.get_firewall_rule, - ctx, fwr_id) - - def test_delete_firewall_rule_with_policy_associated(self): - attrs = self._get_test_firewall_rule_attrs() - with self.firewall_rule() as fwr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - fwr_id = fwr['firewall_rule']['id'] - data = {'firewall_policy': {'firewall_rules': [fwr_id]}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - req = self.new_delete_request('firewall_rules', fwr_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 409) - - def test_create_firewall(self): - name = "firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall(name=name, - firewall_policy_id=fwp_id, - admin_state_up= - ADMIN_STATE_UP) as firewall: - for k, v in attrs.iteritems(): - self.assertEqual(firewall['firewall'][k], v) - - def test_show_firewall(self): - name = "firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall(name=name, - firewall_policy_id=fwp_id, - admin_state_up= - ADMIN_STATE_UP) as firewall: - req = self.new_show_request('firewalls', - firewall['firewall']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall'][k], v) - - def test_list_firewalls(self): - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with contextlib.nested(self.firewall(name='fw1', - firewall_policy_id=fwp_id, - description='fw'), - self.firewall(name='fw2', - firewall_policy_id=fwp_id, - description='fw'), - self.firewall(name='fw3', - firewall_policy_id=fwp_id, - description='fw')) as fwalls: - self._test_list_resources('firewall', fwalls, - query_params='description=fw') - - def test_update_firewall(self): - name = "new_firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - ADMIN_STATE_UP) as firewall: - data = {'firewall': {'name': name}} - req = self.new_update_request('firewalls', data, - firewall['firewall']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall'][k], v) - - def test_delete_firewall(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - no_delete=True) as fw: - fw_id = fw['firewall']['id'] - req = self.new_delete_request('firewalls', fw_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - self.assertRaises(firewall.FirewallNotFound, - self.plugin.get_firewall, - ctx, fw_id) - - def test_insert_rule_in_policy_with_prior_rules_added_via_update(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as frs: - fr1 = frs[0:2] - fwr3 = frs[2] - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - fw_rule_ids = [r['firewall_rule']['id'] for r in fr1] - attrs['firewall_rules'] = fw_rule_ids[:] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - self._rule_action('insert', fwp_id, fw_rule_ids[0], - insert_before=fw_rule_ids[0], - insert_after=None, - expected_code=webob.exc.HTTPConflict.code, - expected_body=None) - fwr3_id = fwr3['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr3_id) - self._rule_action('insert', fwp_id, fwr3_id, - insert_before=fw_rule_ids[0], - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - - def test_insert_rule_in_policy_failures(self): - with self.firewall_rule(name='fwr1') as fr1: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - fr1_id = fr1['firewall_rule']['id'] - fw_rule_ids = [fr1_id] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - # test inserting with empty request body - self._rule_action('insert', fwp_id, '123', - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None, body_data={}) - # test inserting when firewall_rule_id is missing in - # request body - insert_data = {'insert_before': '123', - 'insert_after': '456'} - self._rule_action('insert', fwp_id, '123', - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None, - body_data=insert_data) - # test inserting when firewall_rule_id is None - insert_data = {'firewall_rule_id': None, - 'insert_before': '123', - 'insert_after': '456'} - self._rule_action('insert', fwp_id, '123', - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None, - body_data=insert_data) - # test inserting when firewall_policy_id is incorrect - self._rule_action('insert', '123', fr1_id, - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None) - # test inserting when firewall_policy_id is None - self._rule_action('insert', None, fr1_id, - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None) - - def test_insert_rule_for_previously_associated_rule(self): - with self.firewall_rule() as fwr: - fwr_id = fwr['firewall_rule']['id'] - fw_rule_ids = [fwr_id] - with self.firewall_policy(firewall_rules=fw_rule_ids): - with self.firewall_policy(name='firewall_policy2') as fwp: - fwp_id = fwp['firewall_policy']['id'] - insert_data = {'firewall_rule_id': fwr_id} - self._rule_action( - 'insert', fwp_id, fwr_id, insert_before=None, - insert_after=None, - expected_code=webob.exc.HTTPConflict.code, - expected_body=None, body_data=insert_data) - - def test_insert_rule_in_policy(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with contextlib.nested(self.firewall_rule(name='fwr0'), - self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3'), - self.firewall_rule(name='fwr4'), - self.firewall_rule(name='fwr5'), - self.firewall_rule(name='fwr6')) as fwr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - # test insert when rule list is empty - fwr0_id = fwr[0]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr0_id) - self._rule_action('insert', fwp_id, fwr0_id, - insert_before=None, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert at top of rule list, insert_before and - # insert_after not provided - fwr1_id = fwr[1]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr1_id) - insert_data = {'firewall_rule_id': fwr1_id} - self._rule_action('insert', fwp_id, fwr0_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs, body_data=insert_data) - # test insert at top of list above existing rule - fwr2_id = fwr[2]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr2_id) - self._rule_action('insert', fwp_id, fwr2_id, - insert_before=fwr1_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert at bottom of list - fwr3_id = fwr[3]['firewall_rule']['id'] - attrs['firewall_rules'].append(fwr3_id) - self._rule_action('insert', fwp_id, fwr3_id, - insert_before=None, - insert_after=fwr0_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert in the middle of the list using - # insert_before - fwr4_id = fwr[4]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr4_id) - self._rule_action('insert', fwp_id, fwr4_id, - insert_before=fwr1_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert in the middle of the list using - # insert_after - fwr5_id = fwr[5]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr5_id) - self._rule_action('insert', fwp_id, fwr5_id, - insert_before=None, - insert_after=fwr2_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert when both insert_before and - # insert_after are set - fwr6_id = fwr[6]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr6_id) - self._rule_action('insert', fwp_id, fwr6_id, - insert_before=fwr5_id, - insert_after=fwr5_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - - def test_remove_rule_from_policy(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as fr1: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - fw_rule_ids = [r['firewall_rule']['id'] for r in fr1] - attrs['firewall_rules'] = fw_rule_ids[:] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - # test removing a rule from a policy that does not exist - self._rule_action('remove', '123', fw_rule_ids[1], - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None) - # test removing a rule in the middle of the list - attrs['firewall_rules'].remove(fw_rule_ids[1]) - self._rule_action('remove', fwp_id, fw_rule_ids[1], - expected_body=attrs) - # test removing a rule at the top of the list - attrs['firewall_rules'].remove(fw_rule_ids[0]) - self._rule_action('remove', fwp_id, fw_rule_ids[0], - expected_body=attrs) - # test removing remaining rule in the list - attrs['firewall_rules'].remove(fw_rule_ids[2]) - self._rule_action('remove', fwp_id, fw_rule_ids[2], - expected_body=attrs) - # test removing rule that is not associated with the policy - self._rule_action('remove', fwp_id, fw_rule_ids[2], - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None) - - def test_remove_rule_from_policy_failures(self): - with self.firewall_rule(name='fwr1') as fr1: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - fw_rule_ids = [fr1['firewall_rule']['id']] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - # test removing rule that does not exist - self._rule_action('remove', fwp_id, '123', - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None) - # test removing rule with bad request - self._rule_action('remove', fwp_id, '123', - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None, body_data={}) - # test removing rule with firewall_rule_id set to None - self._rule_action('remove', fwp_id, '123', - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None, - body_data={'firewall_rule_id': None}) - - -class TestFirewallDBPluginXML(TestFirewallDBPlugin): - fmt = 'xml' diff --git a/neutron/tests/unit/db/loadbalancer/__init__.py b/neutron/tests/unit/db/loadbalancer/__init__.py deleted file mode 100644 index cae279d0a..000000000 --- a/neutron/tests/unit/db/loadbalancer/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack Foundation -# -# 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. diff --git a/neutron/tests/unit/db/loadbalancer/test_db_loadbalancer.py b/neutron/tests/unit/db/loadbalancer/test_db_loadbalancer.py deleted file mode 100644 index bc541c7c8..000000000 --- a/neutron/tests/unit/db/loadbalancer/test_db_loadbalancer.py +++ /dev/null @@ -1,1572 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 contextlib -import logging - -import mock -from oslo.config import cfg -import testtools -import webob.exc - -from neutron.api import extensions -from neutron.common import config -from neutron import context -import neutron.db.l3_db # noqa -from neutron.db.loadbalancer import loadbalancer_db as ldb -from neutron.db import servicetype_db as sdb -import neutron.extensions -from neutron.extensions import loadbalancer -from neutron.plugins.common import constants -from neutron.services.loadbalancer import ( - plugin as loadbalancer_plugin -) -from neutron.services.loadbalancer.drivers import abstract_driver -from neutron.services import provider_configuration as pconf -from neutron.tests.unit import test_db_plugin - - -LOG = logging.getLogger(__name__) - -DB_CORE_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2' -DB_LB_PLUGIN_KLASS = ( - "neutron.services.loadbalancer." - "plugin.LoadBalancerPlugin" -) -NOOP_DRIVER_KLASS = ('neutron.tests.unit.db.loadbalancer.test_db_loadbalancer.' - 'NoopLbaaSDriver') - -extensions_path = ':'.join(neutron.extensions.__path__) - -_subnet_id = "0c798ed8-33ba-11e2-8b28-000c291c4d14" - - -class NoopLbaaSDriver(abstract_driver.LoadBalancerAbstractDriver): - """A dummy lbass driver that that only performs object deletion.""" - - def __init__(self, plugin): - self.plugin = plugin - - def create_vip(self, context, vip): - pass - - def update_vip(self, context, old_vip, vip): - pass - - def delete_vip(self, context, vip): - self.plugin._delete_db_vip(context, vip["id"]) - - def create_pool(self, context, pool): - pass - - def update_pool(self, context, old_pool, pool): - pass - - def delete_pool(self, context, pool): - self.plugin._delete_db_pool(context, pool["id"]) - - def stats(self, context, pool_id): - return {"bytes_in": 0, - "bytes_out": 0, - "active_connections": 0, - "total_connections": 0} - - def create_member(self, context, member): - pass - - def update_member(self, context, old_member, member): - pass - - def delete_member(self, context, member): - self.plugin._delete_db_member(context, member["id"]) - - def update_pool_health_monitor(self, context, old_health_monitor, - health_monitor, - pool_association): - pass - - def create_pool_health_monitor(self, context, - health_monitor, pool_id): - pass - - def delete_pool_health_monitor(self, context, health_monitor, pool_id): - self.plugin._delete_db_pool_health_monitor( - context, health_monitor["id"], - pool_id - ) - - -class LoadBalancerTestMixin(object): - resource_prefix_map = dict( - (k, constants.COMMON_PREFIXES[constants.LOADBALANCER]) - for k in loadbalancer.RESOURCE_ATTRIBUTE_MAP.keys() - ) - - def _get_vip_optional_args(self): - return ('description', 'subnet_id', 'address', - 'session_persistence', 'connection_limit') - - def _create_vip(self, fmt, name, pool_id, protocol, protocol_port, - admin_state_up, expected_res_status=None, **kwargs): - data = {'vip': {'name': name, - 'pool_id': pool_id, - 'protocol': protocol, - 'protocol_port': protocol_port, - 'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id}} - args = self._get_vip_optional_args() - for arg in args: - if arg in kwargs and kwargs[arg] is not None: - data['vip'][arg] = kwargs[arg] - - vip_req = self.new_create_request('vips', data, fmt) - vip_res = vip_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(vip_res.status_int, expected_res_status) - - return vip_res - - def _create_pool(self, fmt, name, lb_method, protocol, admin_state_up, - expected_res_status=None, **kwargs): - data = {'pool': {'name': name, - 'subnet_id': _subnet_id, - 'lb_method': lb_method, - 'protocol': protocol, - 'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id}} - for arg in ('description', 'provider', 'subnet_id'): - if arg in kwargs and kwargs[arg] is not None: - data['pool'][arg] = kwargs[arg] - pool_req = self.new_create_request('pools', data, fmt) - pool_res = pool_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(pool_res.status_int, expected_res_status) - - return pool_res - - def _create_member(self, fmt, address, protocol_port, admin_state_up, - expected_res_status=None, **kwargs): - data = {'member': {'address': address, - 'protocol_port': protocol_port, - 'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id}} - for arg in ('weight', 'pool_id'): - if arg in kwargs and kwargs[arg] is not None: - data['member'][arg] = kwargs[arg] - - member_req = self.new_create_request('members', data, fmt) - member_res = member_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(member_res.status_int, expected_res_status) - - return member_res - - def _create_health_monitor(self, fmt, type, delay, timeout, max_retries, - admin_state_up, expected_res_status=None, - **kwargs): - data = {'health_monitor': {'type': type, - 'delay': delay, - 'timeout': timeout, - 'max_retries': max_retries, - 'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id}} - for arg in ('http_method', 'path', 'expected_code'): - if arg in kwargs and kwargs[arg] is not None: - data['health_monitor'][arg] = kwargs[arg] - - req = self.new_create_request('health_monitors', data, fmt) - - res = req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(res.status_int, expected_res_status) - - return res - - @contextlib.contextmanager - def vip(self, fmt=None, name='vip1', pool=None, subnet=None, - protocol='HTTP', protocol_port=80, admin_state_up=True, - no_delete=False, **kwargs): - if not fmt: - fmt = self.fmt - - with test_db_plugin.optional_ctx(subnet, self.subnet) as tmp_subnet: - with test_db_plugin.optional_ctx(pool, self.pool) as tmp_pool: - pool_id = tmp_pool['pool']['id'] - res = self._create_vip(fmt, - name, - pool_id, - protocol, - protocol_port, - admin_state_up, - subnet_id=tmp_subnet['subnet']['id'], - **kwargs) - if res.status_int >= webob.exc.HTTPClientError.code: - raise webob.exc.HTTPClientError( - explanation=_("Unexpected error code: %s") % - res.status_int - ) - vip = self.deserialize(fmt or self.fmt, res) - yield vip - if not no_delete: - self._delete('vips', vip['vip']['id']) - - @contextlib.contextmanager - def pool(self, fmt=None, name='pool1', lb_method='ROUND_ROBIN', - protocol='HTTP', admin_state_up=True, no_delete=False, - **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_pool(fmt, - name, - lb_method, - protocol, - admin_state_up, - **kwargs) - if res.status_int >= webob.exc.HTTPClientError.code: - raise webob.exc.HTTPClientError( - explanation=_("Unexpected error code: %s") % res.status_int - ) - pool = self.deserialize(fmt or self.fmt, res) - yield pool - if not no_delete: - self._delete('pools', pool['pool']['id']) - - @contextlib.contextmanager - def member(self, fmt=None, address='192.168.1.100', protocol_port=80, - admin_state_up=True, no_delete=False, **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_member(fmt, - address, - protocol_port, - admin_state_up, - **kwargs) - if res.status_int >= webob.exc.HTTPClientError.code: - raise webob.exc.HTTPClientError( - explanation=_("Unexpected error code: %s") % res.status_int - ) - member = self.deserialize(fmt or self.fmt, res) - yield member - if not no_delete: - self._delete('members', member['member']['id']) - - @contextlib.contextmanager - def health_monitor(self, fmt=None, type='TCP', - delay=30, timeout=10, max_retries=3, - admin_state_up=True, - no_delete=False, **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_health_monitor(fmt, - type, - delay, - timeout, - max_retries, - admin_state_up, - **kwargs) - if res.status_int >= webob.exc.HTTPClientError.code: - raise webob.exc.HTTPClientError( - explanation=_("Unexpected error code: %s") % res.status_int - ) - health_monitor = self.deserialize(fmt or self.fmt, res) - the_health_monitor = health_monitor['health_monitor'] - # make sure: - # 1. When the type is HTTP/S we have HTTP related attributes in - # the result - # 2. When the type is not HTTP/S we do not have HTTP related - # attributes in the result - http_related_attributes = ('http_method', 'url_path', 'expected_codes') - if type in ['HTTP', 'HTTPS']: - for arg in http_related_attributes: - self.assertIsNotNone(the_health_monitor.get(arg)) - else: - for arg in http_related_attributes: - self.assertIsNone(the_health_monitor.get(arg)) - yield health_monitor - if not no_delete: - self._delete('health_monitors', the_health_monitor['id']) - - -class LoadBalancerPluginDbTestCase(LoadBalancerTestMixin, - test_db_plugin.NeutronDbPluginV2TestCase): - def setUp(self, core_plugin=None, lb_plugin=None, lbaas_provider=None, - ext_mgr=None): - service_plugins = {'lb_plugin_name': DB_LB_PLUGIN_KLASS} - if not lbaas_provider: - lbaas_provider = ( - constants.LOADBALANCER + - ':lbaas:' + NOOP_DRIVER_KLASS + ':default') - cfg.CONF.set_override('service_provider', - [lbaas_provider], - 'service_providers') - #force service type manager to reload configuration: - sdb.ServiceTypeManager._instance = None - - super(LoadBalancerPluginDbTestCase, self).setUp( - ext_mgr=ext_mgr, - service_plugins=service_plugins - ) - - if not ext_mgr: - self.plugin = loadbalancer_plugin.LoadBalancerPlugin() - ext_mgr = extensions.PluginAwareExtensionManager( - extensions_path, - {constants.LOADBALANCER: self.plugin} - ) - app = config.load_paste_app('extensions_test_app') - self.ext_api = extensions.ExtensionMiddleware(app, ext_mgr=ext_mgr) - - get_lbaas_agent_patcher = mock.patch( - 'neutron.services.loadbalancer.agent_scheduler' - '.LbaasAgentSchedulerDbMixin.get_lbaas_agent_hosting_pool') - mock_lbaas_agent = mock.MagicMock() - get_lbaas_agent_patcher.start().return_value = mock_lbaas_agent - mock_lbaas_agent.__getitem__.return_value = {'host': 'host'} - - self._subnet_id = _subnet_id - - -class TestLoadBalancer(LoadBalancerPluginDbTestCase): - - def test_create_vip(self, **extras): - expected = { - 'name': 'vip1', - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': 'PENDING_CREATE', - 'tenant_id': self._tenant_id, - } - - expected.update(extras) - - with self.subnet() as subnet: - expected['subnet_id'] = subnet['subnet']['id'] - name = expected['name'] - - with self.vip(name=name, subnet=subnet, **extras) as vip: - for k in ('id', 'address', 'port_id', 'pool_id'): - self.assertTrue(vip['vip'].get(k, None)) - - self.assertEqual( - dict((k, v) - for k, v in vip['vip'].items() if k in expected), - expected - ) - return vip - - def test_create_vip_twice_for_same_pool(self): - """Test loadbalancer db plugin via extension and directly.""" - with self.subnet() as subnet: - with self.pool(name="pool1") as pool: - with self.vip(name='vip1', subnet=subnet, pool=pool): - vip_data = { - 'name': 'vip1', - 'pool_id': pool['pool']['id'], - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': 'PENDING_CREATE', - 'tenant_id': self._tenant_id, - 'session_persistence': '' - } - self.assertRaises(loadbalancer.VipExists, - self.plugin.create_vip, - context.get_admin_context(), - {'vip': vip_data}) - - def test_update_vip_raises_vip_exists(self): - with self.subnet() as subnet: - with contextlib.nested( - self.pool(name="pool1"), - self.pool(name="pool2") - ) as (pool1, pool2): - with contextlib.nested( - self.vip(name='vip1', subnet=subnet, pool=pool1), - self.vip(name='vip2', subnet=subnet, pool=pool2) - ) as (vip1, vip2): - vip_data = { - 'id': vip2['vip']['id'], - 'name': 'vip1', - 'pool_id': pool1['pool']['id'], - } - self.assertRaises(loadbalancer.VipExists, - self.plugin.update_vip, - context.get_admin_context(), - vip2['vip']['id'], - {'vip': vip_data}) - - def test_update_vip_change_pool(self): - with self.subnet() as subnet: - with contextlib.nested( - self.pool(name="pool1"), - self.pool(name="pool2") - ) as (pool1, pool2): - with self.vip(name='vip1', subnet=subnet, pool=pool1) as vip: - # change vip from pool1 to pool2 - vip_data = { - 'id': vip['vip']['id'], - 'name': 'vip1', - 'pool_id': pool2['pool']['id'], - } - ctx = context.get_admin_context() - self.plugin.update_vip(ctx, - vip['vip']['id'], - {'vip': vip_data}) - db_pool2 = (ctx.session.query(ldb.Pool). - filter_by(id=pool2['pool']['id']).one()) - db_pool1 = (ctx.session.query(ldb.Pool). - filter_by(id=pool1['pool']['id']).one()) - # check that pool1.vip became None - self.assertIsNone(db_pool1.vip) - # and pool2 got vip - self.assertEqual(db_pool2.vip.id, vip['vip']['id']) - - def test_create_vip_with_invalid_values(self): - invalid = { - 'protocol': 'UNSUPPORTED', - 'protocol_port': 'NOT_AN_INT', - 'protocol_port': 1000500, - 'subnet': {'subnet': {'id': 'invalid-subnet'}} - } - - for param, value in invalid.items(): - kwargs = {'name': 'the-vip', param: value} - with testtools.ExpectedException(webob.exc.HTTPClientError): - with self.vip(**kwargs): - pass - - def test_create_vip_with_address(self): - self.test_create_vip(address='10.0.0.7') - - def test_create_vip_with_address_outside_subnet(self): - with testtools.ExpectedException(webob.exc.HTTPClientError): - self.test_create_vip(address='9.9.9.9') - - def test_create_vip_with_session_persistence(self): - self.test_create_vip(session_persistence={'type': 'HTTP_COOKIE'}) - - def test_create_vip_with_session_persistence_with_app_cookie(self): - sp = {'type': 'APP_COOKIE', 'cookie_name': 'sessionId'} - self.test_create_vip(session_persistence=sp) - - def test_create_vip_with_session_persistence_unsupported_type(self): - with testtools.ExpectedException(webob.exc.HTTPClientError): - self.test_create_vip(session_persistence={'type': 'UNSUPPORTED'}) - - def test_create_vip_with_unnecessary_cookie_name(self): - sp = {'type': "SOURCE_IP", 'cookie_name': 'sessionId'} - with testtools.ExpectedException(webob.exc.HTTPClientError): - self.test_create_vip(session_persistence=sp) - - def test_create_vip_with_session_persistence_without_cookie_name(self): - sp = {'type': "APP_COOKIE"} - with testtools.ExpectedException(webob.exc.HTTPClientError): - self.test_create_vip(session_persistence=sp) - - def test_create_vip_with_protocol_mismatch(self): - with self.pool(protocol='TCP') as pool: - with testtools.ExpectedException(webob.exc.HTTPClientError): - self.test_create_vip(pool=pool, protocol='HTTP') - - def test_update_vip_with_protocol_mismatch(self): - with self.pool(protocol='TCP') as pool: - with self.vip(protocol='HTTP') as vip: - data = {'vip': {'pool_id': pool['pool']['id']}} - req = self.new_update_request('vips', data, vip['vip']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_reset_session_persistence(self): - name = 'vip4' - session_persistence = {'type': "HTTP_COOKIE"} - - update_info = {'vip': {'session_persistence': None}} - - with self.vip(name=name, session_persistence=session_persistence) as v: - # Ensure that vip has been created properly - self.assertEqual(v['vip']['session_persistence'], - session_persistence) - - # Try resetting session_persistence - req = self.new_update_request('vips', update_info, v['vip']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - - self.assertIsNone(res['vip']['session_persistence']) - - def test_update_vip(self): - name = 'new_vip' - keys = [('name', name), - ('address', "10.0.0.2"), - ('protocol_port', 80), - ('connection_limit', 100), - ('admin_state_up', False), - ('status', 'PENDING_UPDATE')] - - with self.vip(name=name) as vip: - keys.append(('subnet_id', vip['vip']['subnet_id'])) - data = {'vip': {'name': name, - 'connection_limit': 100, - 'session_persistence': - {'type': "APP_COOKIE", - 'cookie_name': "jesssionId"}, - 'admin_state_up': False}} - req = self.new_update_request('vips', data, vip['vip']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['vip'][k], v) - - def test_delete_vip(self): - with self.pool(): - with self.vip(no_delete=True) as vip: - req = self.new_delete_request('vips', - vip['vip']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_show_vip(self): - name = "vip_show" - keys = [('name', name), - ('address', "10.0.0.10"), - ('protocol_port', 80), - ('protocol', 'HTTP'), - ('connection_limit', -1), - ('admin_state_up', True), - ('status', 'PENDING_CREATE')] - with self.vip(name=name, address='10.0.0.10') as vip: - req = self.new_show_request('vips', - vip['vip']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['vip'][k], v) - - def test_list_vips(self): - name = "vips_list" - keys = [('name', name), - ('address', "10.0.0.2"), - ('protocol_port', 80), - ('protocol', 'HTTP'), - ('connection_limit', -1), - ('admin_state_up', True), - ('status', 'PENDING_CREATE')] - with self.vip(name=name) as vip: - keys.append(('subnet_id', vip['vip']['subnet_id'])) - req = self.new_list_request('vips') - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self.assertEqual(len(res['vips']), 1) - for k, v in keys: - self.assertEqual(res['vips'][0][k], v) - - def test_list_vips_with_sort_emulated(self): - with self.subnet() as subnet: - with contextlib.nested( - self.vip(name='vip1', subnet=subnet, protocol_port=81), - self.vip(name='vip2', subnet=subnet, protocol_port=82), - self.vip(name='vip3', subnet=subnet, protocol_port=82) - ) as (vip1, vip2, vip3): - self._test_list_with_sort( - 'vip', - (vip1, vip3, vip2), - [('protocol_port', 'asc'), ('name', 'desc')] - ) - - def test_list_vips_with_pagination_emulated(self): - with self.subnet() as subnet: - with contextlib.nested(self.vip(name='vip1', subnet=subnet), - self.vip(name='vip2', subnet=subnet), - self.vip(name='vip3', subnet=subnet) - ) as (vip1, vip2, vip3): - self._test_list_with_pagination('vip', - (vip1, vip2, vip3), - ('name', 'asc'), 2, 2) - - def test_list_vips_with_pagination_reverse_emulated(self): - with self.subnet() as subnet: - with contextlib.nested(self.vip(name='vip1', subnet=subnet), - self.vip(name='vip2', subnet=subnet), - self.vip(name='vip3', subnet=subnet) - ) as (vip1, vip2, vip3): - self._test_list_with_pagination_reverse('vip', - (vip1, vip2, vip3), - ('name', 'asc'), 2, 2) - - def test_create_pool_with_invalid_values(self): - name = 'pool3' - - pool = self.pool(name=name, protocol='UNSUPPORTED') - self.assertRaises(webob.exc.HTTPClientError, pool.__enter__) - - pool = self.pool(name=name, lb_method='UNSUPPORTED') - self.assertRaises(webob.exc.HTTPClientError, pool.__enter__) - - def _create_pool_directly_via_plugin(self, provider_name): - #default provider will be haproxy - prov1 = (constants.LOADBALANCER + - ':lbaas:' + NOOP_DRIVER_KLASS) - prov2 = (constants.LOADBALANCER + - ':haproxy:neutron.services.loadbalancer.' - 'drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver' - ':default') - cfg.CONF.set_override('service_provider', - [prov1, prov2], - 'service_providers') - sdb.ServiceTypeManager._instance = None - self.plugin = loadbalancer_plugin.LoadBalancerPlugin() - with self.subnet() as subnet: - ctx = context.get_admin_context() - #create pool with another provider - lbaas - #which is noop driver - pool = {'name': 'pool1', - 'subnet_id': subnet['subnet']['id'], - 'lb_method': 'ROUND_ROBIN', - 'protocol': 'HTTP', - 'admin_state_up': True, - 'tenant_id': self._tenant_id, - 'provider': provider_name, - 'description': ''} - self.plugin.create_pool(ctx, {'pool': pool}) - assoc = ctx.session.query(sdb.ProviderResourceAssociation).one() - self.assertEqual(assoc.provider_name, - pconf.normalize_provider_name(provider_name)) - - def test_create_pool_another_provider(self): - self._create_pool_directly_via_plugin('lbaas') - - def test_create_pool_unnormalized_provider_name(self): - self._create_pool_directly_via_plugin('LBAAS') - - def test_create_pool_unexisting_provider(self): - self.assertRaises( - pconf.ServiceProviderNotFound, - self._create_pool_directly_via_plugin, 'unexisting') - - def test_create_pool(self): - name = "pool1" - keys = [('name', name), - ('subnet_id', self._subnet_id), - ('tenant_id', self._tenant_id), - ('protocol', 'HTTP'), - ('lb_method', 'ROUND_ROBIN'), - ('admin_state_up', True), - ('status', 'PENDING_CREATE')] - - with self.pool(name=name) as pool: - for k, v in keys: - self.assertEqual(pool['pool'][k], v) - - def test_create_pool_with_members(self): - name = "pool2" - with self.pool(name=name) as pool: - pool_id = pool['pool']['id'] - res1 = self._create_member(self.fmt, - '192.168.1.100', - '80', - True, - pool_id=pool_id, - weight=1) - req = self.new_show_request('pools', - pool_id, - fmt=self.fmt) - pool_updated = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - - member1 = self.deserialize(self.fmt, res1) - self.assertEqual(member1['member']['id'], - pool_updated['pool']['members'][0]) - self.assertEqual(len(pool_updated['pool']['members']), 1) - - keys = [('address', '192.168.1.100'), - ('protocol_port', 80), - ('weight', 1), - ('pool_id', pool_id), - ('admin_state_up', True), - ('status', 'PENDING_CREATE')] - for k, v in keys: - self.assertEqual(member1['member'][k], v) - self._delete('members', member1['member']['id']) - - def test_delete_pool(self): - with self.pool(no_delete=True) as pool: - with self.member(no_delete=True, - pool_id=pool['pool']['id']): - req = self.new_delete_request('pools', - pool['pool']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_delete_pool_preserve_state(self): - with self.pool(no_delete=True) as pool: - with self.vip(pool=pool): - req = self.new_delete_request('pools', - pool['pool']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - req = self.new_show_request('pools', - pool['pool']['id'], - fmt=self.fmt) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPOk.code) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - self.assertEqual(res['pool']['status'], - constants.PENDING_CREATE) - req = self.new_delete_request('pools', - pool['pool']['id']) - - def test_show_pool(self): - name = "pool1" - keys = [('name', name), - ('subnet_id', self._subnet_id), - ('tenant_id', self._tenant_id), - ('protocol', 'HTTP'), - ('lb_method', 'ROUND_ROBIN'), - ('admin_state_up', True), - ('status', 'PENDING_CREATE')] - with self.pool(name=name) as pool: - req = self.new_show_request('pools', - pool['pool']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['pool'][k], v) - - def test_list_pools_with_sort_emulated(self): - with contextlib.nested(self.pool(name='p1'), - self.pool(name='p2'), - self.pool(name='p3') - ) as (p1, p2, p3): - self._test_list_with_sort('pool', (p3, p2, p1), - [('name', 'desc')]) - - def test_list_pools_with_pagination_emulated(self): - with contextlib.nested(self.pool(name='p1'), - self.pool(name='p2'), - self.pool(name='p3') - ) as (p1, p2, p3): - self._test_list_with_pagination('pool', - (p1, p2, p3), - ('name', 'asc'), 2, 2) - - def test_list_pools_with_pagination_reverse_emulated(self): - with contextlib.nested(self.pool(name='p1'), - self.pool(name='p2'), - self.pool(name='p3') - ) as (p1, p2, p3): - self._test_list_with_pagination_reverse('pool', - (p1, p2, p3), - ('name', 'asc'), 2, 2) - - def test_create_member(self): - with self.pool() as pool: - pool_id = pool['pool']['id'] - with self.member(address='192.168.1.100', - protocol_port=80, - pool_id=pool_id) as member1: - with self.member(address='192.168.1.101', - protocol_port=80, - pool_id=pool_id) as member2: - req = self.new_show_request('pools', - pool_id, - fmt=self.fmt) - pool_update = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - self.assertIn(member1['member']['id'], - pool_update['pool']['members']) - self.assertIn(member2['member']['id'], - pool_update['pool']['members']) - - def test_create_same_member_in_same_pool_raises_member_exists(self): - with self.subnet(): - with self.pool(name="pool1") as pool: - pool_id = pool['pool']['id'] - with self.member(address='192.168.1.100', - protocol_port=80, - pool_id=pool_id): - member_data = { - 'address': '192.168.1.100', - 'protocol_port': 80, - 'weight': 1, - 'admin_state_up': True, - 'pool_id': pool_id - } - self.assertRaises(loadbalancer.MemberExists, - self.plugin.create_member, - context.get_admin_context(), - {'member': member_data}) - - def test_update_member(self): - with self.pool(name="pool1") as pool1: - with self.pool(name="pool2") as pool2: - keys = [('address', "192.168.1.100"), - ('tenant_id', self._tenant_id), - ('protocol_port', 80), - ('weight', 10), - ('pool_id', pool2['pool']['id']), - ('admin_state_up', False), - ('status', 'PENDING_UPDATE')] - with self.member(pool_id=pool1['pool']['id']) as member: - req = self.new_show_request('pools', - pool1['pool']['id'], - fmt=self.fmt) - pool1_update = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - self.assertEqual(len(pool1_update['pool']['members']), 1) - - req = self.new_show_request('pools', - pool2['pool']['id'], - fmt=self.fmt) - pool2_update = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - self.assertEqual(len(pool1_update['pool']['members']), 1) - self.assertEqual(len(pool2_update['pool']['members']), 0) - - data = {'member': {'pool_id': pool2['pool']['id'], - 'weight': 10, - 'admin_state_up': False}} - req = self.new_update_request('members', - data, - member['member']['id']) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - for k, v in keys: - self.assertEqual(res['member'][k], v) - - req = self.new_show_request('pools', - pool1['pool']['id'], - fmt=self.fmt) - pool1_update = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - - req = self.new_show_request('pools', - pool2['pool']['id'], - fmt=self.fmt) - pool2_update = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - - self.assertEqual(len(pool2_update['pool']['members']), 1) - self.assertEqual(len(pool1_update['pool']['members']), 0) - - def test_delete_member(self): - with self.pool() as pool: - pool_id = pool['pool']['id'] - with self.member(pool_id=pool_id, - no_delete=True) as member: - req = self.new_delete_request('members', - member['member']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - req = self.new_show_request('pools', - pool_id, - fmt=self.fmt) - pool_update = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - self.assertEqual(len(pool_update['pool']['members']), 0) - - def test_show_member(self): - with self.pool() as pool: - keys = [('address', "192.168.1.100"), - ('tenant_id', self._tenant_id), - ('protocol_port', 80), - ('weight', 1), - ('pool_id', pool['pool']['id']), - ('admin_state_up', True), - ('status', 'PENDING_CREATE')] - with self.member(pool_id=pool['pool']['id']) as member: - req = self.new_show_request('members', - member['member']['id'], - fmt=self.fmt) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - for k, v in keys: - self.assertEqual(res['member'][k], v) - - def test_list_members_with_sort_emulated(self): - with self.pool() as pool: - with contextlib.nested(self.member(pool_id=pool['pool']['id'], - protocol_port=81), - self.member(pool_id=pool['pool']['id'], - protocol_port=82), - self.member(pool_id=pool['pool']['id'], - protocol_port=83) - ) as (m1, m2, m3): - self._test_list_with_sort('member', (m3, m2, m1), - [('protocol_port', 'desc')]) - - def test_list_members_with_pagination_emulated(self): - with self.pool() as pool: - with contextlib.nested(self.member(pool_id=pool['pool']['id'], - protocol_port=81), - self.member(pool_id=pool['pool']['id'], - protocol_port=82), - self.member(pool_id=pool['pool']['id'], - protocol_port=83) - ) as (m1, m2, m3): - self._test_list_with_pagination( - 'member', (m1, m2, m3), ('protocol_port', 'asc'), 2, 2 - ) - - def test_list_members_with_pagination_reverse_emulated(self): - with self.pool() as pool: - with contextlib.nested(self.member(pool_id=pool['pool']['id'], - protocol_port=81), - self.member(pool_id=pool['pool']['id'], - protocol_port=82), - self.member(pool_id=pool['pool']['id'], - protocol_port=83) - ) as (m1, m2, m3): - self._test_list_with_pagination_reverse( - 'member', (m1, m2, m3), ('protocol_port', 'asc'), 2, 2 - ) - - def test_create_healthmonitor(self): - keys = [('type', "TCP"), - ('tenant_id', self._tenant_id), - ('delay', 30), - ('timeout', 10), - ('max_retries', 3), - ('admin_state_up', True)] - with self.health_monitor() as monitor: - for k, v in keys: - self.assertEqual(monitor['health_monitor'][k], v) - - def test_create_health_monitor_with_timeout_delay_invalid(self): - data = {'health_monitor': {'type': type, - 'delay': 3, - 'timeout': 6, - 'max_retries': 2, - 'admin_state_up': True, - 'tenant_id': self._tenant_id}} - req = self.new_create_request('health_monitors', data, self.fmt) - res = req.get_response(self.ext_api) - self.assertEqual(webob.exc.HTTPBadRequest.code, res.status_int) - - def test_update_health_monitor_with_timeout_delay_invalid(self): - with self.health_monitor() as monitor: - data = {'health_monitor': {'delay': 10, - 'timeout': 20, - 'max_retries': 2, - 'admin_state_up': False}} - req = self.new_update_request("health_monitors", - data, - monitor['health_monitor']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(webob.exc.HTTPBadRequest.code, res.status_int) - - def test_update_healthmonitor(self): - keys = [('type', "TCP"), - ('tenant_id', self._tenant_id), - ('delay', 20), - ('timeout', 20), - ('max_retries', 2), - ('admin_state_up', False)] - with self.health_monitor() as monitor: - data = {'health_monitor': {'delay': 20, - 'timeout': 20, - 'max_retries': 2, - 'admin_state_up': False}} - req = self.new_update_request("health_monitors", - data, - monitor['health_monitor']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['health_monitor'][k], v) - - def test_delete_healthmonitor(self): - with self.health_monitor(no_delete=True) as monitor: - ctx = context.get_admin_context() - qry = ctx.session.query(ldb.HealthMonitor) - qry = qry.filter_by(id=monitor['health_monitor']['id']) - self.assertIsNotNone(qry.first()) - - req = self.new_delete_request('health_monitors', - monitor['health_monitor']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - qry = ctx.session.query(ldb.HealthMonitor) - qry = qry.filter_by(id=monitor['health_monitor']['id']) - self.assertIsNone(qry.first()) - - def test_delete_healthmonitor_with_associations_raises(self): - with self.health_monitor(type='HTTP') as monitor: - with self.pool() as pool: - data = { - 'health_monitor': { - 'id': monitor['health_monitor']['id'], - 'tenant_id': self._tenant_id - } - } - req = self.new_create_request( - 'pools', - data, - fmt=self.fmt, - id=pool['pool']['id'], - subresource='health_monitors') - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - ctx = context.get_admin_context() - - # check if we actually have corresponding Pool associations - qry = ctx.session.query(ldb.PoolMonitorAssociation) - qry = qry.filter_by(monitor_id=monitor['health_monitor']['id']) - self.assertTrue(qry.all()) - # try to delete the HealthMonitor instance - req = self.new_delete_request( - 'health_monitors', - monitor['health_monitor']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - qry = ctx.session.query(ldb.HealthMonitor) - qry = qry.filter_by(id=monitor['health_monitor']['id']) - self.assertIsNotNone(qry.first()) - # check if all corresponding Pool associations are not deleted - qry = ctx.session.query(ldb.PoolMonitorAssociation) - qry = qry.filter_by(monitor_id=monitor['health_monitor']['id']) - self.assertTrue(qry.all()) - - def test_show_healthmonitor(self): - with self.health_monitor() as monitor: - keys = [('type', "TCP"), - ('tenant_id', self._tenant_id), - ('delay', 30), - ('timeout', 10), - ('max_retries', 3), - ('admin_state_up', True)] - req = self.new_show_request('health_monitors', - monitor['health_monitor']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['health_monitor'][k], v) - - def test_list_healthmonitors_with_sort_emulated(self): - with contextlib.nested(self.health_monitor(delay=30), - self.health_monitor(delay=31), - self.health_monitor(delay=32) - ) as (m1, m2, m3): - self._test_list_with_sort('health_monitor', (m3, m2, m1), - [('delay', 'desc')]) - - def test_list_healthmonitors_with_pagination_emulated(self): - with contextlib.nested(self.health_monitor(delay=30), - self.health_monitor(delay=31), - self.health_monitor(delay=32) - ) as (m1, m2, m3): - self._test_list_with_pagination('health_monitor', - (m1, m2, m3), - ('delay', 'asc'), 2, 2) - - def test_list_healthmonitors_with_pagination_reverse_emulated(self): - with contextlib.nested(self.health_monitor(delay=30), - self.health_monitor(delay=31), - self.health_monitor(delay=32) - ) as (m1, m2, m3): - self._test_list_with_pagination_reverse('health_monitor', - (m1, m2, m3), - ('delay', 'asc'), 2, 2) - - def test_update_pool_stats_with_no_stats(self): - keys = ["bytes_in", "bytes_out", - "active_connections", - "total_connections"] - with self.pool() as pool: - pool_id = pool['pool']['id'] - ctx = context.get_admin_context() - self.plugin.update_pool_stats(ctx, pool_id) - pool_obj = ctx.session.query(ldb.Pool).filter_by(id=pool_id).one() - for key in keys: - self.assertEqual(pool_obj.stats.__dict__[key], 0) - - def test_update_pool_stats_with_negative_values(self): - stats_data = {"bytes_in": -1, - "bytes_out": -2, - "active_connections": -3, - "total_connections": -4} - for k, v in stats_data.items(): - self._test_update_pool_stats_with_negative_value(k, v) - - def _test_update_pool_stats_with_negative_value(self, k, v): - with self.pool() as pool: - pool_id = pool['pool']['id'] - ctx = context.get_admin_context() - self.assertRaises(ValueError, self.plugin.update_pool_stats, - ctx, pool_id, {k: v}) - - def test_update_pool_stats(self): - stats_data = {"bytes_in": 1, - "bytes_out": 2, - "active_connections": 3, - "total_connections": 4} - with self.pool() as pool: - pool_id = pool['pool']['id'] - ctx = context.get_admin_context() - self.plugin.update_pool_stats(ctx, pool_id, stats_data) - pool_obj = ctx.session.query(ldb.Pool).filter_by(id=pool_id).one() - for k, v in stats_data.items(): - self.assertEqual(pool_obj.stats.__dict__[k], v) - - def test_update_pool_stats_members_statuses(self): - with self.pool() as pool: - pool_id = pool['pool']['id'] - with self.member(pool_id=pool_id) as member: - member_id = member['member']['id'] - stats_data = {'members': { - member_id: { - 'status': 'INACTIVE' - } - }} - ctx = context.get_admin_context() - member = self.plugin.get_member(ctx, member_id) - self.assertEqual('PENDING_CREATE', member['status']) - self.plugin.update_pool_stats(ctx, pool_id, stats_data) - member = self.plugin.get_member(ctx, member_id) - self.assertEqual('INACTIVE', member['status']) - - def test_get_pool_stats(self): - keys = [("bytes_in", 0), - ("bytes_out", 0), - ("active_connections", 0), - ("total_connections", 0)] - with self.pool() as pool: - req = self.new_show_request("pools", - pool['pool']['id'], - subresource="stats", - fmt=self.fmt) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['stats'][k], v) - - def test_create_healthmonitor_of_pool(self): - with self.health_monitor(type="TCP") as monitor1: - with self.health_monitor(type="HTTP") as monitor2: - with self.pool() as pool: - data = {"health_monitor": { - "id": monitor1['health_monitor']['id'], - 'tenant_id': self._tenant_id}} - req = self.new_create_request( - "pools", - data, - fmt=self.fmt, - id=pool['pool']['id'], - subresource="health_monitors") - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, - webob.exc.HTTPCreated.code) - - data = {"health_monitor": { - "id": monitor2['health_monitor']['id'], - 'tenant_id': self._tenant_id}} - req = self.new_create_request( - "pools", - data, - fmt=self.fmt, - id=pool['pool']['id'], - subresource="health_monitors") - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, - webob.exc.HTTPCreated.code) - - req = self.new_show_request( - 'pools', - pool['pool']['id'], - fmt=self.fmt) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - self.assertIn(monitor1['health_monitor']['id'], - res['pool']['health_monitors']) - self.assertIn(monitor2['health_monitor']['id'], - res['pool']['health_monitors']) - expected = [ - {'monitor_id': monitor1['health_monitor']['id'], - 'status': 'PENDING_CREATE', - 'status_description': None}, - {'monitor_id': monitor2['health_monitor']['id'], - 'status': 'PENDING_CREATE', - 'status_description': None}] - self.assertEqual( - sorted(expected), - sorted(res['pool']['health_monitors_status'])) - - def test_delete_healthmonitor_of_pool(self): - with self.health_monitor(type="TCP") as monitor1: - with self.health_monitor(type="HTTP") as monitor2: - with self.pool() as pool: - # add the monitors to the pool - data = {"health_monitor": { - "id": monitor1['health_monitor']['id'], - 'tenant_id': self._tenant_id}} - req = self.new_create_request( - "pools", - data, - fmt=self.fmt, - id=pool['pool']['id'], - subresource="health_monitors") - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, - webob.exc.HTTPCreated.code) - - data = {"health_monitor": { - "id": monitor2['health_monitor']['id'], - 'tenant_id': self._tenant_id}} - req = self.new_create_request( - "pools", - data, - fmt=self.fmt, - id=pool['pool']['id'], - subresource="health_monitors") - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, - webob.exc.HTTPCreated.code) - - # remove one of healthmonitor from the pool - req = self.new_delete_request( - "pools", - fmt=self.fmt, - id=pool['pool']['id'], - sub_id=monitor1['health_monitor']['id'], - subresource="health_monitors") - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, - webob.exc.HTTPNoContent.code) - - req = self.new_show_request( - 'pools', - pool['pool']['id'], - fmt=self.fmt) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - self.assertNotIn(monitor1['health_monitor']['id'], - res['pool']['health_monitors']) - self.assertIn(monitor2['health_monitor']['id'], - res['pool']['health_monitors']) - expected = [ - {'monitor_id': monitor2['health_monitor']['id'], - 'status': 'PENDING_CREATE', - 'status_description': None} - ] - self.assertEqual(expected, - res['pool']['health_monitors_status']) - - def test_create_loadbalancer(self): - vip_name = "vip3" - pool_name = "pool3" - - with self.pool(name=pool_name) as pool: - with self.vip(name=vip_name, pool=pool) as vip: - pool_id = pool['pool']['id'] - vip_id = vip['vip']['id'] - # Add two members - res1 = self._create_member(self.fmt, - '192.168.1.100', - '80', - True, - pool_id=pool_id, - weight=1) - res2 = self._create_member(self.fmt, - '192.168.1.101', - '80', - True, - pool_id=pool_id, - weight=2) - # Add a health_monitor - req = self._create_health_monitor(self.fmt, - 'HTTP', - '10', - '10', - '3', - True) - health_monitor = self.deserialize(self.fmt, req) - self.assertEqual(req.status_int, webob.exc.HTTPCreated.code) - - # Associate the health_monitor to the pool - data = {"health_monitor": { - "id": health_monitor['health_monitor']['id'], - 'tenant_id': self._tenant_id}} - req = self.new_create_request("pools", - data, - fmt=self.fmt, - id=pool['pool']['id'], - subresource="health_monitors") - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - # Get pool and vip - req = self.new_show_request('pools', - pool_id, - fmt=self.fmt) - pool_updated = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - member1 = self.deserialize(self.fmt, res1) - member2 = self.deserialize(self.fmt, res2) - self.assertIn(member1['member']['id'], - pool_updated['pool']['members']) - self.assertIn(member2['member']['id'], - pool_updated['pool']['members']) - self.assertIn(health_monitor['health_monitor']['id'], - pool_updated['pool']['health_monitors']) - expected = [ - {'monitor_id': health_monitor['health_monitor']['id'], - 'status': 'PENDING_CREATE', - 'status_description': None} - ] - self.assertEqual( - expected, pool_updated['pool']['health_monitors_status']) - - req = self.new_show_request('vips', - vip_id, - fmt=self.fmt) - vip_updated = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - self.assertEqual(vip_updated['vip']['pool_id'], - pool_updated['pool']['id']) - - # clean up - # disassociate the health_monitor from the pool first - req = self.new_delete_request( - "pools", - fmt=self.fmt, - id=pool['pool']['id'], - subresource="health_monitors", - sub_id=health_monitor['health_monitor']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - self._delete('health_monitors', - health_monitor['health_monitor']['id']) - self._delete('members', member1['member']['id']) - self._delete('members', member2['member']['id']) - - def test_create_pool_health_monitor(self): - with contextlib.nested( - self.health_monitor(), - self.health_monitor(), - self.pool(name="pool") - ) as (health_mon1, health_mon2, pool): - res = self.plugin.create_pool_health_monitor( - context.get_admin_context(), - health_mon1, pool['pool']['id'] - ) - self.assertEqual({'health_monitor': - [health_mon1['health_monitor']['id']]}, - res) - - res = self.plugin.create_pool_health_monitor( - context.get_admin_context(), - health_mon2, pool['pool']['id'] - ) - self.assertEqual({'health_monitor': - [health_mon1['health_monitor']['id'], - health_mon2['health_monitor']['id']]}, - res) - - res = self.plugin.get_pool_health_monitor( - context.get_admin_context(), - health_mon2['health_monitor']['id'], pool['pool']['id']) - self.assertEqual(res['tenant_id'], - health_mon1['health_monitor']['tenant_id']) - - def test_driver_call_create_pool_health_monitor(self): - with mock.patch.object(self.plugin.drivers['lbaas'], - 'create_pool_health_monitor') as driver_call: - with contextlib.nested( - self.health_monitor(), - self.pool() - ) as (hm, pool): - data = {'health_monitor': { - 'id': hm['health_monitor']['id'], - 'tenant_id': self._tenant_id}} - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - data, pool['pool']['id'] - ) - hm['health_monitor']['pools'] = [ - {'pool_id': pool['pool']['id'], - 'status': 'PENDING_CREATE', - 'status_description': None}] - driver_call.assert_called_once_with( - mock.ANY, hm['health_monitor'], pool['pool']['id']) - - def test_pool_monitor_list_of_pools(self): - with contextlib.nested( - self.health_monitor(), - self.pool(), - self.pool() - ) as (hm, p1, p2): - ctx = context.get_admin_context() - data = {'health_monitor': { - 'id': hm['health_monitor']['id'], - 'tenant_id': self._tenant_id}} - self.plugin.create_pool_health_monitor( - ctx, data, p1['pool']['id']) - self.plugin.create_pool_health_monitor( - ctx, data, p2['pool']['id']) - healthmon = self.plugin.get_health_monitor( - ctx, hm['health_monitor']['id']) - pool_data = [{'pool_id': p1['pool']['id'], - 'status': 'PENDING_CREATE', - 'status_description': None}, - {'pool_id': p2['pool']['id'], - 'status': 'PENDING_CREATE', - 'status_description': None}] - self.assertEqual(sorted(healthmon['pools']), - sorted(pool_data)) - req = self.new_show_request( - 'health_monitors', - hm['health_monitor']['id'], - fmt=self.fmt) - hm = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - self.assertEqual(sorted(hm['health_monitor']['pools']), - sorted(pool_data)) - - def test_create_pool_health_monitor_already_associated(self): - with contextlib.nested( - self.health_monitor(), - self.pool(name="pool") - ) as (hm, pool): - res = self.plugin.create_pool_health_monitor( - context.get_admin_context(), - hm, pool['pool']['id'] - ) - self.assertEqual({'health_monitor': - [hm['health_monitor']['id']]}, - res) - self.assertRaises(loadbalancer.PoolMonitorAssociationExists, - self.plugin.create_pool_health_monitor, - context.get_admin_context(), - hm, - pool['pool']['id']) - - def test_create_pool_healthmon_invalid_pool_id(self): - with self.health_monitor() as healthmon: - self.assertRaises(loadbalancer.PoolNotFound, - self.plugin.create_pool_health_monitor, - context.get_admin_context(), - healthmon, - "123-456-789" - ) - - def test_update_status(self): - with self.pool() as pool: - self.assertEqual(pool['pool']['status'], 'PENDING_CREATE') - self.assertFalse(pool['pool']['status_description']) - - self.plugin.update_status(context.get_admin_context(), ldb.Pool, - pool['pool']['id'], 'ERROR', 'unknown') - updated_pool = self.plugin.get_pool(context.get_admin_context(), - pool['pool']['id']) - self.assertEqual(updated_pool['status'], 'ERROR') - self.assertEqual(updated_pool['status_description'], 'unknown') - - # update status to ACTIVE, status_description should be cleared - self.plugin.update_status(context.get_admin_context(), ldb.Pool, - pool['pool']['id'], 'ACTIVE') - updated_pool = self.plugin.get_pool(context.get_admin_context(), - pool['pool']['id']) - self.assertEqual(updated_pool['status'], 'ACTIVE') - self.assertFalse(updated_pool['status_description']) - - def test_update_pool_health_monitor(self): - with contextlib.nested( - self.health_monitor(), - self.pool(name="pool") - ) as (hm, pool): - res = self.plugin.create_pool_health_monitor( - context.get_admin_context(), - hm, pool['pool']['id']) - self.assertEqual({'health_monitor': - [hm['health_monitor']['id']]}, - res) - - assoc = self.plugin.get_pool_health_monitor( - context.get_admin_context(), - hm['health_monitor']['id'], - pool['pool']['id']) - self.assertEqual(assoc['status'], 'PENDING_CREATE') - self.assertIsNone(assoc['status_description']) - - self.plugin.update_pool_health_monitor( - context.get_admin_context(), - hm['health_monitor']['id'], - pool['pool']['id'], - 'ACTIVE', 'ok') - assoc = self.plugin.get_pool_health_monitor( - context.get_admin_context(), - hm['health_monitor']['id'], - pool['pool']['id']) - self.assertEqual(assoc['status'], 'ACTIVE') - self.assertEqual(assoc['status_description'], 'ok') - - def test_check_orphan_pool_associations(self): - with contextlib.nested( - #creating pools with default noop driver - self.pool(), - self.pool() - ) as (p1, p2): - #checking that 3 associations exist - ctx = context.get_admin_context() - qry = ctx.session.query(sdb.ProviderResourceAssociation) - self.assertEqual(qry.count(), 2) - #removing driver - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas1:' + NOOP_DRIVER_KLASS + - ':default'], - 'service_providers') - sdb.ServiceTypeManager._instance = None - # calling _remove_orphan... in constructor - self.assertRaises( - SystemExit, - loadbalancer_plugin.LoadBalancerPlugin - ) - - -class TestLoadBalancerXML(TestLoadBalancer): - fmt = 'xml' diff --git a/neutron/tests/unit/db/metering/__init__.py b/neutron/tests/unit/db/metering/__init__.py deleted file mode 100644 index 82a447213..000000000 --- a/neutron/tests/unit/db/metering/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2013 eNovance SAS -# -# Author: Sylvain Afchain -# -# 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. diff --git a/neutron/tests/unit/db/metering/test_db_metering.py b/neutron/tests/unit/db/metering/test_db_metering.py deleted file mode 100644 index 83e4996af..000000000 --- a/neutron/tests/unit/db/metering/test_db_metering.py +++ /dev/null @@ -1,291 +0,0 @@ -# Copyright (C) 2013 eNovance SAS -# -# Author: Sylvain Afchain -# -# 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 contextlib -import logging - -import webob.exc - -from neutron.api import extensions -from neutron.common import config -from neutron import context -import neutron.extensions -from neutron.extensions import metering -from neutron.plugins.common import constants -from neutron.services.metering import metering_plugin -from neutron.tests.unit import test_db_plugin - -LOG = logging.getLogger(__name__) - -DB_METERING_PLUGIN_KLASS = ( - "neutron.services.metering." - "metering_plugin.MeteringPlugin" -) - -extensions_path = ':'.join(neutron.extensions.__path__) - - -class MeteringPluginDbTestCaseMixin(object): - def _create_metering_label(self, fmt, name, description, **kwargs): - data = {'metering_label': {'name': name, - 'tenant_id': kwargs.get('tenant_id', - 'test_tenant'), - 'description': description}} - req = self.new_create_request('metering-labels', data, - fmt) - - if kwargs.get('set_context') and 'tenant_id' in kwargs: - # create a specific auth context for this request - req.environ['neutron.context'] = ( - context.Context('', kwargs['tenant_id'], - is_admin=kwargs.get('is_admin', True))) - - return req.get_response(self.ext_api) - - def _make_metering_label(self, fmt, name, description, **kwargs): - res = self._create_metering_label(fmt, name, description, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - def _create_metering_label_rule(self, fmt, metering_label_id, direction, - remote_ip_prefix, excluded, **kwargs): - data = {'metering_label_rule': - {'metering_label_id': metering_label_id, - 'tenant_id': kwargs.get('tenant_id', 'test_tenant'), - 'direction': direction, - 'excluded': excluded, - 'remote_ip_prefix': remote_ip_prefix}} - req = self.new_create_request('metering-label-rules', - data, fmt) - - if kwargs.get('set_context') and 'tenant_id' in kwargs: - # create a specific auth context for this request - req.environ['neutron.context'] = ( - context.Context('', kwargs['tenant_id'])) - - return req.get_response(self.ext_api) - - def _make_metering_label_rule(self, fmt, metering_label_id, direction, - remote_ip_prefix, excluded, **kwargs): - res = self._create_metering_label_rule(fmt, metering_label_id, - direction, remote_ip_prefix, - excluded, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - @contextlib.contextmanager - def metering_label(self, name='label', description='desc', - fmt=None, no_delete=False, **kwargs): - if not fmt: - fmt = self.fmt - metering_label = self._make_metering_label(fmt, name, - description, **kwargs) - yield metering_label - if not no_delete: - self._delete('metering-labels', - metering_label['metering_label']['id']) - - @contextlib.contextmanager - def metering_label_rule(self, metering_label_id=None, direction='ingress', - remote_ip_prefix='10.0.0.0/24', - excluded='false', fmt=None, no_delete=False): - if not fmt: - fmt = self.fmt - metering_label_rule = self._make_metering_label_rule(fmt, - metering_label_id, - direction, - remote_ip_prefix, - excluded) - yield metering_label_rule - if not no_delete: - self._delete('metering-label-rules', - metering_label_rule['metering_label_rule']['id']) - - -class MeteringPluginDbTestCase(test_db_plugin.NeutronDbPluginV2TestCase, - MeteringPluginDbTestCaseMixin): - fmt = 'json' - - resource_prefix_map = dict( - (k.replace('_', '-'), constants.COMMON_PREFIXES[constants.METERING]) - for k in metering.RESOURCE_ATTRIBUTE_MAP.keys() - ) - - def setUp(self, plugin=None): - service_plugins = {'metering_plugin_name': DB_METERING_PLUGIN_KLASS} - - super(MeteringPluginDbTestCase, self).setUp( - plugin=plugin, - service_plugins=service_plugins - ) - - self.plugin = metering_plugin.MeteringPlugin() - ext_mgr = extensions.PluginAwareExtensionManager( - extensions_path, - {constants.METERING: self.plugin} - ) - app = config.load_paste_app('extensions_test_app') - self.ext_api = extensions.ExtensionMiddleware(app, ext_mgr=ext_mgr) - - def test_create_metering_label(self): - name = 'my label' - description = 'my metering label' - keys = [('name', name,), ('description', description)] - with self.metering_label(name, description) as metering_label: - for k, v, in keys: - self.assertEqual(metering_label['metering_label'][k], v) - - def test_delete_metering_label(self): - name = 'my label' - description = 'my metering label' - - with self.metering_label(name, description, - no_delete=True) as metering_label: - metering_label_id = metering_label['metering_label']['id'] - self._delete('metering-labels', metering_label_id, 204) - - def test_list_metering_label(self): - name = 'my label' - description = 'my metering label' - - with contextlib.nested( - self.metering_label(name, description), - self.metering_label(name, description)) as metering_label: - - self._test_list_resources('metering-label', metering_label) - - def test_create_metering_label_rule(self): - name = 'my label' - description = 'my metering label' - - with self.metering_label(name, description) as metering_label: - metering_label_id = metering_label['metering_label']['id'] - - direction = 'egress' - remote_ip_prefix = '192.168.0.0/24' - excluded = True - - keys = [('metering_label_id', metering_label_id), - ('direction', direction), - ('excluded', excluded), - ('remote_ip_prefix', remote_ip_prefix)] - with self.metering_label_rule(metering_label_id, - direction, - remote_ip_prefix, - excluded) as label_rule: - for k, v, in keys: - self.assertEqual(label_rule['metering_label_rule'][k], v) - - def test_delete_metering_label_rule(self): - name = 'my label' - description = 'my metering label' - - with self.metering_label(name, description) as metering_label: - metering_label_id = metering_label['metering_label']['id'] - - direction = 'egress' - remote_ip_prefix = '192.168.0.0/24' - excluded = True - - with self.metering_label_rule(metering_label_id, - direction, - remote_ip_prefix, - excluded, - no_delete=True) as label_rule: - rule_id = label_rule['metering_label_rule']['id'] - self._delete('metering-label-rules', rule_id, 204) - - def test_list_metering_label_rule(self): - name = 'my label' - description = 'my metering label' - - with self.metering_label(name, description) as metering_label: - metering_label_id = metering_label['metering_label']['id'] - - direction = 'egress' - remote_ip_prefix = '192.168.0.0/24' - excluded = True - - with contextlib.nested( - self.metering_label_rule(metering_label_id, - direction, - remote_ip_prefix, - excluded), - self.metering_label_rule(metering_label_id, - 'ingress', - remote_ip_prefix, - excluded)) as metering_label_rule: - - self._test_list_resources('metering-label-rule', - metering_label_rule) - - def test_create_metering_label_rules(self): - name = 'my label' - description = 'my metering label' - - with self.metering_label(name, description) as metering_label: - metering_label_id = metering_label['metering_label']['id'] - - direction = 'egress' - remote_ip_prefix = '192.168.0.0/24' - excluded = True - - with contextlib.nested( - self.metering_label_rule(metering_label_id, - direction, - remote_ip_prefix, - excluded), - self.metering_label_rule(metering_label_id, - direction, - '0.0.0.0/0', - False)) as metering_label_rule: - - self._test_list_resources('metering-label-rule', - metering_label_rule) - - def test_create_metering_label_rule_two_labels(self): - name1 = 'my label 1' - name2 = 'my label 2' - description = 'my metering label' - - with self.metering_label(name1, description) as metering_label1: - metering_label_id1 = metering_label1['metering_label']['id'] - - with self.metering_label(name2, description) as metering_label2: - metering_label_id2 = metering_label2['metering_label']['id'] - - direction = 'egress' - remote_ip_prefix = '192.168.0.0/24' - excluded = True - - with contextlib.nested( - self.metering_label_rule(metering_label_id1, - direction, - remote_ip_prefix, - excluded), - self.metering_label_rule(metering_label_id2, - direction, - remote_ip_prefix, - excluded)) as metering_label_rule: - - self._test_list_resources('metering-label-rule', - metering_label_rule) - - -class TestMeteringDbXML(MeteringPluginDbTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/db/test_agent_db.py b/neutron/tests/unit/db/test_agent_db.py deleted file mode 100644 index e3dc5ee8f..000000000 --- a/neutron/tests/unit/db/test_agent_db.py +++ /dev/null @@ -1,86 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 neutron import context -from neutron.db import agents_db -from neutron.db import api as db -from neutron.db import db_base_plugin_v2 as base_plugin -from neutron.openstack.common.db import exception as exc -from neutron.tests import base - - -class FakePlugin(base_plugin.NeutronDbPluginV2, agents_db.AgentDbMixin): - """A fake plugin class containing all DB methods.""" - - -class TestAgentsDbMixin(base.BaseTestCase): - def setUp(self): - super(TestAgentsDbMixin, self).setUp() - - self.context = context.get_admin_context() - self.plugin = FakePlugin() - self.addCleanup(db.clear_db) - - self.agent_status = { - 'agent_type': 'Open vSwitch agent', - 'binary': 'neutron-openvswitch-agent', - 'host': 'overcloud-notcompute', - 'topic': 'N/A' - } - - def _assert_ref_fields_are_equal(self, reference, result): - """Compare (key, value) pairs of a reference dict with the result - - Note: the result MAY have additional keys - """ - - for field, value in reference.items(): - self.assertEqual(value, result[field], field) - - def test_create_or_update_agent_new_entry(self): - self.plugin.create_or_update_agent(self.context, self.agent_status) - - agent = self.plugin.get_agents(self.context)[0] - self._assert_ref_fields_are_equal(self.agent_status, agent) - - def test_create_or_update_agent_existing_entry(self): - self.plugin.create_or_update_agent(self.context, self.agent_status) - self.plugin.create_or_update_agent(self.context, self.agent_status) - self.plugin.create_or_update_agent(self.context, self.agent_status) - - agents = self.plugin.get_agents(self.context) - self.assertEqual(len(agents), 1) - - agent = agents[0] - self._assert_ref_fields_are_equal(self.agent_status, agent) - - def test_create_or_update_agent_concurrent_insert(self): - # NOTE(rpodolyaka): emulate violation of the unique constraint caused - # by a concurrent insert. Ensure we make another - # attempt on fail - with mock.patch('sqlalchemy.orm.Session.add') as add_mock: - add_mock.side_effect = [ - exc.DBDuplicateEntry(columns=['agent_type', 'host']), - None - ] - - self.plugin.create_or_update_agent(self.context, self.agent_status) - - self.assertEqual(add_mock.call_count, 2, - "Agent entry creation hasn't been retried") diff --git a/neutron/tests/unit/db/test_quota_db.py b/neutron/tests/unit/db/test_quota_db.py deleted file mode 100644 index 813f0166a..000000000 --- a/neutron/tests/unit/db/test_quota_db.py +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation. -# -# 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. -# -# @author: Sergio Cazzolato, Intel - -from neutron.common import exceptions -from neutron import context -from neutron.db import api as db -from neutron.db import db_base_plugin_v2 as base_plugin -from neutron.db import quota_db -from neutron.tests import base - - -class FakePlugin(base_plugin.NeutronDbPluginV2, quota_db.DbQuotaDriver): - """A fake plugin class containing all DB methods.""" - - -class TestResource(object): - """Describe a test resource for quota checking.""" - - def __init__(self, name, default): - self.name = name - self.quota = default - - @property - def default(self): - return self.quota - -PROJECT = 'prj_test' -RESOURCE = 'res_test' - - -class TestDbQuotaDriver(base.BaseTestCase): - def setUp(self): - super(TestDbQuotaDriver, self).setUp() - self.plugin = FakePlugin() - self.context = context.get_admin_context() - self.addCleanup(db.clear_db) - - def test_create_quota_limit(self): - defaults = {RESOURCE: TestResource(RESOURCE, 4)} - - self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - quotas = self.plugin.get_tenant_quotas(self.context, defaults, PROJECT) - self.assertEqual(2, quotas[RESOURCE]) - - def test_update_quota_limit(self): - defaults = {RESOURCE: TestResource(RESOURCE, 4)} - - self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 3) - quotas = self.plugin.get_tenant_quotas(self.context, defaults, PROJECT) - self.assertEqual(3, quotas[RESOURCE]) - - def test_delete_tenant_quota_restores_default_limit(self): - defaults = {RESOURCE: TestResource(RESOURCE, 4)} - - self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - self.plugin.delete_tenant_quota(self.context, PROJECT) - quotas = self.plugin.get_tenant_quotas(self.context, defaults, PROJECT) - self.assertEqual(4, quotas[RESOURCE]) - - def test_get_all_quotas(self): - project_1 = 'prj_test_1' - project_2 = 'prj_test_2' - resource_1 = 'res_test_1' - resource_2 = 'res_test_2' - - resources = {resource_1: TestResource(resource_1, 1), - resource_2: TestResource(resource_2, 1)} - - self.plugin.update_quota_limit(self.context, project_1, resource_1, 2) - self.plugin.update_quota_limit(self.context, project_2, resource_2, 2) - quotas = self.plugin.get_all_quotas(self.context, resources) - - self.assertEqual(2, len(quotas)) - - self.assertEqual(3, len(quotas[0])) - self.assertEqual(project_1, quotas[0]['tenant_id']) - self.assertEqual(2, quotas[0][resource_1]) - self.assertEqual(1, quotas[0][resource_2]) - - self.assertEqual(3, len(quotas[1])) - self.assertEqual(project_2, quotas[1]['tenant_id']) - self.assertEqual(1, quotas[1][resource_1]) - self.assertEqual(2, quotas[1][resource_2]) - - def test_limit_check(self): - resources = {RESOURCE: TestResource(RESOURCE, 2)} - values = {RESOURCE: 1} - - self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - self.plugin.limit_check(self.context, PROJECT, resources, values) - - def test_limit_check_over_quota(self): - resources = {RESOURCE: TestResource(RESOURCE, 2)} - values = {RESOURCE: 3} - - self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - - self.assertRaises(exceptions.OverQuota, self.plugin.limit_check, - context.get_admin_context(), PROJECT, resources, - values) - - def test_limit_check_equals_to_quota(self): - resources = {RESOURCE: TestResource(RESOURCE, 2)} - values = {RESOURCE: 2} - - self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - self.plugin.limit_check(self.context, PROJECT, resources, values) - - def test_limit_check_value_lower_than_zero(self): - resources = {RESOURCE: TestResource(RESOURCE, 2)} - values = {RESOURCE: -1} - - self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - self.assertRaises(exceptions.InvalidQuotaValue, - self.plugin.limit_check, context.get_admin_context(), - PROJECT, resources, values) - - def test_limit_check_wrong_values_size(self): - resource_1 = 'res_test_1' - resource_2 = 'res_test_2' - - resources = {resource_1: TestResource(resource_1, 2)} - values = {resource_1: 1, resource_2: 1} - - self.plugin.update_quota_limit(self.context, PROJECT, resource_1, 2) - self.assertRaises(exceptions.QuotaResourceUnknown, - self.plugin.limit_check, context.get_admin_context(), - PROJECT, resources, values) diff --git a/neutron/tests/unit/db/vpn/__init__.py b/neutron/tests/unit/db/vpn/__init__.py deleted file mode 100644 index b936bbcb8..000000000 --- a/neutron/tests/unit/db/vpn/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. -# All Rights Reserved. -# -# 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. -# @author: Swaminathan Vasudevan, Hewlett-Packard. diff --git a/neutron/tests/unit/db/vpn/test_db_vpnaas.py b/neutron/tests/unit/db/vpn/test_db_vpnaas.py deleted file mode 100644 index d685df96c..000000000 --- a/neutron/tests/unit/db/vpn/test_db_vpnaas.py +++ /dev/null @@ -1,1670 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. -# All Rights Reserved. -# -# 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. -# -# @author: Swaminathan Vasudevan, Hewlett-Packard. - -import contextlib -import os - -from oslo.config import cfg -import webob.exc - -from neutron.api import extensions as api_extensions -from neutron.common import config -from neutron import context -from neutron.db import agentschedulers_db -from neutron.db import l3_agentschedulers_db -from neutron.db import servicetype_db as sdb -from neutron.db.vpn import vpn_db -from neutron import extensions -from neutron.extensions import vpnaas -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.scheduler import l3_agent_scheduler -from neutron.services.vpn import plugin as vpn_plugin -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import test_l3_plugin - -DB_CORE_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2' -DB_VPN_PLUGIN_KLASS = "neutron.services.vpn.plugin.VPNPlugin" -ROOTDIR = os.path.normpath(os.path.join( - os.path.dirname(__file__), - '..', '..', '..', '..')) - -extensions_path = ':'.join(extensions.__path__) - - -class TestVpnCorePlugin(test_l3_plugin.TestL3NatIntPlugin, - l3_agentschedulers_db.L3AgentSchedulerDbMixin, - agentschedulers_db.DhcpAgentSchedulerDbMixin): - def __init__(self, configfile=None): - super(TestVpnCorePlugin, self).__init__() - self.router_scheduler = l3_agent_scheduler.ChanceScheduler() - - -class VPNTestMixin(object): - resource_prefix_map = dict( - (k.replace('_', '-'), - constants.COMMON_PREFIXES[constants.VPN]) - for k in vpnaas.RESOURCE_ATTRIBUTE_MAP - ) - - def _create_ikepolicy(self, fmt, - name='ikepolicy1', - auth_algorithm='sha1', - encryption_algorithm='aes-128', - phase1_negotiation_mode='main', - lifetime_units='seconds', - lifetime_value=3600, - ike_version='v1', - pfs='group5', - expected_res_status=None, **kwargs): - - data = {'ikepolicy': { - 'name': name, - 'auth_algorithm': auth_algorithm, - 'encryption_algorithm': encryption_algorithm, - 'phase1_negotiation_mode': phase1_negotiation_mode, - 'lifetime': { - 'units': lifetime_units, - 'value': lifetime_value}, - 'ike_version': ike_version, - 'pfs': pfs, - 'tenant_id': self._tenant_id - }} - for arg in ['description']: - if arg in kwargs and kwargs[arg] is not None: - data['ikepolicy'][arg] = kwargs[arg] - - ikepolicy_req = self.new_create_request('ikepolicies', data, fmt) - ikepolicy_res = ikepolicy_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(ikepolicy_res.status_int, expected_res_status) - - return ikepolicy_res - - @contextlib.contextmanager - def ikepolicy(self, fmt=None, - name='ikepolicy1', - auth_algorithm='sha1', - encryption_algorithm='aes-128', - phase1_negotiation_mode='main', - lifetime_units='seconds', - lifetime_value=3600, - ike_version='v1', - pfs='group5', - no_delete=False, - **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_ikepolicy(fmt, - name, - auth_algorithm, - encryption_algorithm, - phase1_negotiation_mode, - lifetime_units, - lifetime_value, - ike_version, - pfs, - **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - ikepolicy = self.deserialize(fmt or self.fmt, res) - yield ikepolicy - if not no_delete: - self._delete('ikepolicies', ikepolicy['ikepolicy']['id']) - - def _create_ipsecpolicy(self, fmt, - name='ipsecpolicy1', - auth_algorithm='sha1', - encryption_algorithm='aes-128', - encapsulation_mode='tunnel', - transform_protocol='esp', - lifetime_units='seconds', - lifetime_value=3600, - pfs='group5', - expected_res_status=None, - **kwargs): - - data = {'ipsecpolicy': {'name': name, - 'auth_algorithm': auth_algorithm, - 'encryption_algorithm': encryption_algorithm, - 'encapsulation_mode': encapsulation_mode, - 'transform_protocol': transform_protocol, - 'lifetime': {'units': lifetime_units, - 'value': lifetime_value}, - 'pfs': pfs, - 'tenant_id': self._tenant_id}} - for arg in ['description']: - if arg in kwargs and kwargs[arg] is not None: - data['ipsecpolicy'][arg] = kwargs[arg] - ipsecpolicy_req = self.new_create_request('ipsecpolicies', data, fmt) - ipsecpolicy_res = ipsecpolicy_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(ipsecpolicy_res.status_int, expected_res_status) - - return ipsecpolicy_res - - @contextlib.contextmanager - def ipsecpolicy(self, fmt=None, - name='ipsecpolicy1', - auth_algorithm='sha1', - encryption_algorithm='aes-128', - encapsulation_mode='tunnel', - transform_protocol='esp', - lifetime_units='seconds', - lifetime_value=3600, - pfs='group5', - no_delete=False, **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_ipsecpolicy(fmt, - name, - auth_algorithm, - encryption_algorithm, - encapsulation_mode, - transform_protocol, - lifetime_units, - lifetime_value, - pfs, - **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - ipsecpolicy = self.deserialize(fmt or self.fmt, res) - yield ipsecpolicy - if not no_delete: - self._delete('ipsecpolicies', ipsecpolicy['ipsecpolicy']['id']) - - def _create_vpnservice(self, fmt, name, - admin_state_up, - router_id, subnet_id, - expected_res_status=None, **kwargs): - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'vpnservice': {'name': name, - 'subnet_id': subnet_id, - 'router_id': router_id, - 'admin_state_up': admin_state_up, - 'tenant_id': tenant_id}} - for arg in ['description']: - if arg in kwargs and kwargs[arg] is not None: - data['vpnservice'][arg] = kwargs[arg] - vpnservice_req = self.new_create_request('vpnservices', data, fmt) - if (kwargs.get('set_context') and - 'tenant_id' in kwargs): - # create a specific auth context for this request - vpnservice_req.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - vpnservice_res = vpnservice_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(vpnservice_res.status_int, expected_res_status) - return vpnservice_res - - @contextlib.contextmanager - def vpnservice(self, fmt=None, name='vpnservice1', - subnet=None, - router=None, - admin_state_up=True, - no_delete=False, - plug_subnet=True, - external_subnet_cidr='192.168.100.0/24', - external_router=True, - **kwargs): - if not fmt: - fmt = self.fmt - with contextlib.nested( - test_db_plugin.optional_ctx(subnet, self.subnet), - test_db_plugin.optional_ctx(router, self.router), - self.subnet(cidr=external_subnet_cidr)) as (tmp_subnet, - tmp_router, - public_sub): - if external_router: - self._set_net_external( - public_sub['subnet']['network_id']) - self._add_external_gateway_to_router( - tmp_router['router']['id'], - public_sub['subnet']['network_id']) - tmp_router['router']['external_gateway_info'] = { - 'network_id': public_sub['subnet']['network_id']} - if plug_subnet: - self._router_interface_action( - 'add', - tmp_router['router']['id'], - tmp_subnet['subnet']['id'], None) - - res = self._create_vpnservice(fmt, - name, - admin_state_up, - router_id=(tmp_router['router'] - ['id']), - subnet_id=(tmp_subnet['subnet'] - ['id']), - **kwargs) - vpnservice = self.deserialize(fmt or self.fmt, res) - if res.status_int < 400: - yield vpnservice - - if not no_delete and vpnservice.get('vpnservice'): - self._delete('vpnservices', - vpnservice['vpnservice']['id']) - if plug_subnet: - self._router_interface_action( - 'remove', - tmp_router['router']['id'], - tmp_subnet['subnet']['id'], None) - if external_router: - external_gateway = tmp_router['router'].get( - 'external_gateway_info') - if external_gateway: - network_id = external_gateway['network_id'] - self._remove_external_gateway_from_router( - tmp_router['router']['id'], network_id) - if res.status_int >= 400: - raise webob.exc.HTTPClientError( - code=res.status_int, detail=vpnservice) - - def _create_ipsec_site_connection(self, fmt, name='test', - peer_address='192.168.1.10', - peer_id='192.168.1.10', - peer_cidrs=None, - mtu=1500, - psk='abcdefg', - initiator='bi-directional', - dpd_action='hold', - dpd_interval=30, - dpd_timeout=120, - vpnservice_id='fake_id', - ikepolicy_id='fake_id', - ipsecpolicy_id='fake_id', - admin_state_up=True, - expected_res_status=None, **kwargs): - data = { - 'ipsec_site_connection': {'name': name, - 'peer_address': peer_address, - 'peer_id': peer_id, - 'peer_cidrs': peer_cidrs, - 'mtu': mtu, - 'psk': psk, - 'initiator': initiator, - 'dpd': { - 'action': dpd_action, - 'interval': dpd_interval, - 'timeout': dpd_timeout, - }, - 'vpnservice_id': vpnservice_id, - 'ikepolicy_id': ikepolicy_id, - 'ipsecpolicy_id': ipsecpolicy_id, - 'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id} - } - for arg in ['description']: - if arg in kwargs and kwargs[arg] is not None: - data['ipsec_site_connection'][arg] = kwargs[arg] - - ipsec_site_connection_req = self.new_create_request( - 'ipsec-site-connections', data, fmt - ) - ipsec_site_connection_res = ipsec_site_connection_req.get_response( - self.ext_api - ) - if expected_res_status: - self.assertEqual( - ipsec_site_connection_res.status_int, expected_res_status - ) - - return ipsec_site_connection_res - - @contextlib.contextmanager - def ipsec_site_connection(self, fmt=None, name='ipsec_site_connection1', - peer_address='192.168.1.10', - peer_id='192.168.1.10', - peer_cidrs=None, - mtu=1500, - psk='abcdefg', - initiator='bi-directional', - dpd_action='hold', - dpd_interval=30, - dpd_timeout=120, - vpnservice=None, - ikepolicy=None, - ipsecpolicy=None, - admin_state_up=True, no_delete=False, - **kwargs): - if not fmt: - fmt = self.fmt - with contextlib.nested( - test_db_plugin.optional_ctx(vpnservice, - self.vpnservice), - test_db_plugin.optional_ctx(ikepolicy, - self.ikepolicy), - test_db_plugin.optional_ctx(ipsecpolicy, - self.ipsecpolicy) - ) as (tmp_vpnservice, tmp_ikepolicy, tmp_ipsecpolicy): - vpnservice_id = tmp_vpnservice['vpnservice']['id'] - ikepolicy_id = tmp_ikepolicy['ikepolicy']['id'] - ipsecpolicy_id = tmp_ipsecpolicy['ipsecpolicy']['id'] - res = self._create_ipsec_site_connection(fmt, - name, - peer_address, - peer_id, - peer_cidrs, - mtu, - psk, - initiator, - dpd_action, - dpd_interval, - dpd_timeout, - vpnservice_id, - ikepolicy_id, - ipsecpolicy_id, - admin_state_up, - **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - - ipsec_site_connection = self.deserialize( - fmt or self.fmt, res - ) - yield ipsec_site_connection - - if not no_delete: - self._delete( - 'ipsec-site-connections', - ipsec_site_connection[ - 'ipsec_site_connection']['id'] - ) - - def _check_ipsec_site_connection(self, ipsec_site_connection, keys, dpd): - self.assertEqual( - keys, - dict((k, v) for k, v - in ipsec_site_connection.items() - if k in keys)) - self.assertEqual( - dpd, - dict((k, v) for k, v - in ipsec_site_connection['dpd'].items() - if k in dpd)) - - def _set_active(self, model, resource_id): - service_plugin = manager.NeutronManager.get_service_plugins()[ - constants.VPN] - adminContext = context.get_admin_context() - with adminContext.session.begin(subtransactions=True): - resource_db = service_plugin._get_resource( - adminContext, - model, - resource_id) - resource_db.status = constants.ACTIVE - - -class VPNPluginDbTestCase(VPNTestMixin, - test_l3_plugin.L3NatTestCaseMixin, - test_db_plugin.NeutronDbPluginV2TestCase): - def setUp(self, core_plugin=None, vpnaas_plugin=DB_VPN_PLUGIN_KLASS, - vpnaas_provider=None): - if not vpnaas_provider: - vpnaas_provider = ( - constants.VPN + - ':vpnaas:neutron.services.vpn.' - 'service_drivers.ipsec.IPsecVPNDriver:default') - - cfg.CONF.set_override('service_provider', - [vpnaas_provider], - 'service_providers') - # force service type manager to reload configuration: - sdb.ServiceTypeManager._instance = None - - service_plugins = {'vpnaas_plugin': vpnaas_plugin} - plugin_str = ('neutron.tests.unit.db.vpn.' - 'test_db_vpnaas.TestVpnCorePlugin') - - super(VPNPluginDbTestCase, self).setUp( - plugin_str, - service_plugins=service_plugins - ) - self._subnet_id = uuidutils.generate_uuid() - self.core_plugin = TestVpnCorePlugin - self.plugin = vpn_plugin.VPNPlugin() - ext_mgr = api_extensions.PluginAwareExtensionManager( - extensions_path, - {constants.CORE: self.core_plugin, - constants.VPN: self.plugin} - ) - app = config.load_paste_app('extensions_test_app') - self.ext_api = api_extensions.ExtensionMiddleware(app, ext_mgr=ext_mgr) - - -class TestVpnaas(VPNPluginDbTestCase): - - def _check_policy(self, policy, keys, lifetime): - for k, v in keys: - self.assertEqual(policy[k], v) - for k, v in lifetime.iteritems(): - self.assertEqual(policy['lifetime'][k], v) - - def test_create_ikepolicy(self): - """Test case to create an ikepolicy.""" - name = "ikepolicy1" - description = 'ipsec-ikepolicy' - keys = [('name', name), - ('description', 'ipsec-ikepolicy'), - ('auth_algorithm', 'sha1'), - ('encryption_algorithm', 'aes-128'), - ('phase1_negotiation_mode', 'main'), - ('ike_version', 'v1'), - ('pfs', 'group5'), - ('tenant_id', self._tenant_id)] - lifetime = { - 'units': 'seconds', - 'value': 3600} - with self.ikepolicy(name=name, description=description) as ikepolicy: - self._check_policy(ikepolicy['ikepolicy'], keys, lifetime) - - def test_delete_ikepolicy(self): - """Test case to delete an ikepolicy.""" - with self.ikepolicy(no_delete=True) as ikepolicy: - req = self.new_delete_request('ikepolicies', - ikepolicy['ikepolicy']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - - def test_show_ikepolicy(self): - """Test case to show or get an ikepolicy.""" - name = "ikepolicy1" - description = 'ipsec-ikepolicy' - keys = [('name', name), - ('auth_algorithm', 'sha1'), - ('encryption_algorithm', 'aes-128'), - ('phase1_negotiation_mode', 'main'), - ('ike_version', 'v1'), - ('pfs', 'group5'), - ('tenant_id', self._tenant_id)] - lifetime = { - 'units': 'seconds', - 'value': 3600} - with self.ikepolicy(name=name, description=description) as ikepolicy: - req = self.new_show_request('ikepolicies', - ikepolicy['ikepolicy']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self._check_policy(res['ikepolicy'], keys, lifetime) - - def test_list_ikepolicies(self): - """Test case to list all ikepolicies.""" - name = "ikepolicy_list" - keys = [('name', name), - ('auth_algorithm', 'sha1'), - ('encryption_algorithm', 'aes-128'), - ('phase1_negotiation_mode', 'main'), - ('ike_version', 'v1'), - ('pfs', 'group5'), - ('tenant_id', self._tenant_id)] - lifetime = { - 'units': 'seconds', - 'value': 3600} - with self.ikepolicy(name=name) as ikepolicy: - keys.append(('id', ikepolicy['ikepolicy']['id'])) - req = self.new_list_request('ikepolicies') - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self.assertEqual(len(res), 1) - for k, v in keys: - self.assertEqual(res['ikepolicies'][0][k], v) - for k, v in lifetime.iteritems(): - self.assertEqual(res['ikepolicies'][0]['lifetime'][k], v) - - def test_list_ikepolicies_with_sort_emulated(self): - """Test case to list all ikepolicies.""" - with contextlib.nested(self.ikepolicy(name='ikepolicy1'), - self.ikepolicy(name='ikepolicy2'), - self.ikepolicy(name='ikepolicy3') - ) as (ikepolicy1, ikepolicy2, ikepolicy3): - self._test_list_with_sort('ikepolicy', (ikepolicy3, - ikepolicy2, - ikepolicy1), - [('name', 'desc')], - 'ikepolicies') - - def test_list_ikepolicies_with_pagination_emulated(self): - """Test case to list all ikepolicies with pagination.""" - with contextlib.nested(self.ikepolicy(name='ikepolicy1'), - self.ikepolicy(name='ikepolicy2'), - self.ikepolicy(name='ikepolicy3') - ) as (ikepolicy1, ikepolicy2, ikepolicy3): - self._test_list_with_pagination('ikepolicy', - (ikepolicy1, - ikepolicy2, - ikepolicy3), - ('name', 'asc'), 2, 2, - 'ikepolicies') - - def test_list_ikepolicies_with_pagination_reverse_emulated(self): - """Test case to list all ikepolicies with reverse pagination.""" - with contextlib.nested(self.ikepolicy(name='ikepolicy1'), - self.ikepolicy(name='ikepolicy2'), - self.ikepolicy(name='ikepolicy3') - ) as (ikepolicy1, ikepolicy2, ikepolicy3): - self._test_list_with_pagination_reverse('ikepolicy', - (ikepolicy1, - ikepolicy2, - ikepolicy3), - ('name', 'asc'), 2, 2, - 'ikepolicies') - - def test_update_ikepolicy(self): - """Test case to update an ikepolicy.""" - name = "new_ikepolicy1" - keys = [('name', name), - ('auth_algorithm', 'sha1'), - ('encryption_algorithm', 'aes-128'), - ('phase1_negotiation_mode', 'main'), - ('ike_version', 'v1'), - ('pfs', 'group5'), - ('tenant_id', self._tenant_id), - ('lifetime', {'units': 'seconds', - 'value': 60})] - with self.ikepolicy(name=name) as ikepolicy: - data = {'ikepolicy': {'name': name, - 'lifetime': {'units': 'seconds', - 'value': 60}}} - req = self.new_update_request("ikepolicies", - data, - ikepolicy['ikepolicy']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['ikepolicy'][k], v) - - def test_create_ikepolicy_with_invalid_values(self): - """Test case to test invalid values.""" - name = 'ikepolicy1' - self._create_ikepolicy(name=name, - fmt=self.fmt, - auth_algorithm='md5', - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - auth_algorithm=200, - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - encryption_algorithm='des', - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - encryption_algorithm=100, - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - phase1_negotiation_mode='aggressive', - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - phase1_negotiation_mode=-100, - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - ike_version='v6', - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - ike_version=500, - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - pfs='group1', - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - pfs=120, - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - lifetime_units='Megabytes', - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - lifetime_units=20000, - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - lifetime_value=-20, - expected_res_status=400) - self._create_ikepolicy(name=name, - fmt=self.fmt, - lifetime_value='Megabytes', - expected_res_status=400) - - def test_create_ipsecpolicy(self): - """Test case to create an ipsecpolicy.""" - name = "ipsecpolicy1" - description = 'my-ipsecpolicy' - keys = [('name', name), - ('description', 'my-ipsecpolicy'), - ('auth_algorithm', 'sha1'), - ('encryption_algorithm', 'aes-128'), - ('encapsulation_mode', 'tunnel'), - ('transform_protocol', 'esp'), - ('pfs', 'group5'), - ('tenant_id', self._tenant_id)] - lifetime = { - 'units': 'seconds', - 'value': 3600} - with self.ipsecpolicy(name=name, - description=description) as ipsecpolicy: - self._check_policy(ipsecpolicy['ipsecpolicy'], keys, lifetime) - - def test_delete_ipsecpolicy(self): - """Test case to delete an ipsecpolicy.""" - with self.ipsecpolicy(no_delete=True) as ipsecpolicy: - req = self.new_delete_request('ipsecpolicies', - ipsecpolicy['ipsecpolicy']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - - def test_show_ipsecpolicy(self): - """Test case to show or get an ipsecpolicy.""" - name = "ipsecpolicy1" - keys = [('name', name), - ('auth_algorithm', 'sha1'), - ('encryption_algorithm', 'aes-128'), - ('encapsulation_mode', 'tunnel'), - ('transform_protocol', 'esp'), - ('pfs', 'group5'), - ('tenant_id', self._tenant_id)] - lifetime = { - 'units': 'seconds', - 'value': 3600} - with self.ipsecpolicy(name=name) as ipsecpolicy: - req = self.new_show_request('ipsecpolicies', - ipsecpolicy['ipsecpolicy']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self._check_policy(res['ipsecpolicy'], keys, lifetime) - - def test_list_ipsecpolicies(self): - """Test case to list all ipsecpolicies.""" - name = "ipsecpolicy_list" - keys = [('name', name), - ('auth_algorithm', 'sha1'), - ('encryption_algorithm', 'aes-128'), - ('encapsulation_mode', 'tunnel'), - ('transform_protocol', 'esp'), - ('pfs', 'group5'), - ('tenant_id', self._tenant_id)] - lifetime = { - 'units': 'seconds', - 'value': 3600} - with self.ipsecpolicy(name=name) as ipsecpolicy: - keys.append(('id', ipsecpolicy['ipsecpolicy']['id'])) - req = self.new_list_request('ipsecpolicies') - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self.assertEqual(len(res), 1) - self._check_policy(res['ipsecpolicies'][0], keys, lifetime) - - def test_list_ipsecpolicies_with_sort_emulated(self): - """Test case to list all ipsecpolicies.""" - with contextlib.nested(self.ipsecpolicy(name='ipsecpolicy1'), - self.ipsecpolicy(name='ipsecpolicy2'), - self.ipsecpolicy(name='ipsecpolicy3') - ) as(ipsecpolicy1, ipsecpolicy2, ipsecpolicy3): - self._test_list_with_sort('ipsecpolicy', (ipsecpolicy3, - ipsecpolicy2, - ipsecpolicy1), - [('name', 'desc')], - 'ipsecpolicies') - - def test_list_ipsecpolicies_with_pagination_emulated(self): - """Test case to list all ipsecpolicies with pagination.""" - with contextlib.nested(self.ipsecpolicy(name='ipsecpolicy1'), - self.ipsecpolicy(name='ipsecpolicy2'), - self.ipsecpolicy(name='ipsecpolicy3') - ) as(ipsecpolicy1, ipsecpolicy2, ipsecpolicy3): - self._test_list_with_pagination('ipsecpolicy', - (ipsecpolicy1, - ipsecpolicy2, - ipsecpolicy3), - ('name', 'asc'), 2, 2, - 'ipsecpolicies') - - def test_list_ipsecpolicies_with_pagination_reverse_emulated(self): - """Test case to list all ipsecpolicies with reverse pagination.""" - with contextlib.nested(self.ipsecpolicy(name='ipsecpolicy1'), - self.ipsecpolicy(name='ipsecpolicy2'), - self.ipsecpolicy(name='ipsecpolicy3') - ) as(ipsecpolicy1, ipsecpolicy2, ipsecpolicy3): - self._test_list_with_pagination_reverse('ipsecpolicy', - (ipsecpolicy1, - ipsecpolicy2, - ipsecpolicy3), - ('name', 'asc'), 2, 2, - 'ipsecpolicies') - - def test_update_ipsecpolicy(self): - """Test case to update an ipsecpolicy.""" - name = "new_ipsecpolicy1" - keys = [('name', name), - ('auth_algorithm', 'sha1'), - ('encryption_algorithm', 'aes-128'), - ('encapsulation_mode', 'tunnel'), - ('transform_protocol', 'esp'), - ('pfs', 'group5'), - ('tenant_id', self._tenant_id), - ('lifetime', {'units': 'seconds', - 'value': 60})] - with self.ipsecpolicy(name=name) as ipsecpolicy: - data = {'ipsecpolicy': {'name': name, - 'lifetime': {'units': 'seconds', - 'value': 60}}} - req = self.new_update_request("ipsecpolicies", - data, - ipsecpolicy['ipsecpolicy']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['ipsecpolicy'][k], v) - - def test_update_ipsecpolicy_lifetime(self): - with self.ipsecpolicy() as ipsecpolicy: - data = {'ipsecpolicy': {'lifetime': {'units': 'seconds'}}} - req = self.new_update_request("ipsecpolicies", - data, - ipsecpolicy['ipsecpolicy']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self.assertEqual(res['ipsecpolicy']['lifetime']['units'], - 'seconds') - - data = {'ipsecpolicy': {'lifetime': {'value': 60}}} - req = self.new_update_request("ipsecpolicies", - data, - ipsecpolicy['ipsecpolicy']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self.assertEqual(res['ipsecpolicy']['lifetime']['value'], 60) - - def test_create_ipsecpolicy_with_invalid_values(self): - """Test case to test invalid values.""" - name = 'ipsecpolicy1' - - self._create_ipsecpolicy( - fmt=self.fmt, - name=name, auth_algorithm='md5', expected_res_status=400) - self._create_ipsecpolicy( - fmt=self.fmt, - name=name, auth_algorithm=100, expected_res_status=400) - - self._create_ipsecpolicy( - fmt=self.fmt, - name=name, encryption_algorithm='des', expected_res_status=400) - self._create_ipsecpolicy( - fmt=self.fmt, - name=name, encryption_algorithm=200, expected_res_status=400) - - self._create_ipsecpolicy( - fmt=self.fmt, - name=name, transform_protocol='abcd', expected_res_status=400) - self._create_ipsecpolicy( - fmt=self.fmt, - name=name, transform_protocol=500, expected_res_status=400) - - self._create_ipsecpolicy( - fmt=self.fmt, - name=name, - encapsulation_mode='unsupported', expected_res_status=400) - self._create_ipsecpolicy(name=name, - fmt=self.fmt, - encapsulation_mode=100, - expected_res_status=400) - - self._create_ipsecpolicy(name=name, - fmt=self.fmt, - pfs='group9', expected_res_status=400) - self._create_ipsecpolicy( - fmt=self.fmt, name=name, pfs=-1, expected_res_status=400) - - self._create_ipsecpolicy( - fmt=self.fmt, name=name, lifetime_units='minutes', - expected_res_status=400) - - self._create_ipsecpolicy(fmt=self.fmt, name=name, lifetime_units=100, - expected_res_status=400) - - self._create_ipsecpolicy(fmt=self.fmt, name=name, - lifetime_value=-800, expected_res_status=400) - self._create_ipsecpolicy(fmt=self.fmt, name=name, - lifetime_value='Megabytes', - expected_res_status=400) - - def test_create_vpnservice(self, **extras): - """Test case to create a vpnservice.""" - description = 'my-vpn-service' - expected = {'name': 'vpnservice1', - 'description': 'my-vpn-service', - 'admin_state_up': True, - 'status': 'PENDING_CREATE', - 'tenant_id': self._tenant_id, } - - expected.update(extras) - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - expected['router_id'] = router['router']['id'] - expected['subnet_id'] = subnet['subnet']['id'] - name = expected['name'] - with self.vpnservice(name=name, - subnet=subnet, - router=router, - description=description, - **extras) as vpnservice: - self.assertEqual(dict((k, v) for k, v in - vpnservice['vpnservice'].items() - if k in expected), - expected) - - def test_create_vpnservice_with_invalid_router(self): - """Test case to create a vpnservice with other tenant's router""" - with self.network( - set_context=True, - tenant_id='tenant_a') as network: - with self.subnet(network=network, - cidr='10.2.0.0/24') as subnet: - with self.router( - set_context=True, tenant_id='tenant_a') as router: - router_id = router['router']['id'] - subnet_id = subnet['subnet']['id'] - self._create_vpnservice( - self.fmt, 'fake', - True, router_id, subnet_id, - expected_res_status=webob.exc.HTTPNotFound.code, - set_context=True, tenant_id='tenant_b') - - def test_create_vpnservice_with_router_no_external_gateway(self): - """Test case to create a vpnservice with inner router""" - error_code = 0 - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - router_id = router['router']['id'] - try: - with self.vpnservice(subnet=subnet, - router=router, - external_router=False): - pass - except webob.exc.HTTPClientError as e: - error_code, error_detail = ( - e.status_code, e.detail['NeutronError']['message']) - self.assertEqual(400, error_code) - msg = str(vpnaas.RouterIsNotExternal(router_id=router_id)) - self.assertEqual(msg, error_detail) - - def test_create_vpnservice_with_nonconnected_subnet(self): - """Test case to create a vpnservice with nonconnected subnet.""" - with self.network() as network: - with self.subnet(network=network, - cidr='10.2.0.0/24') as subnet: - with self.router() as router: - router_id = router['router']['id'] - subnet_id = subnet['subnet']['id'] - self._create_vpnservice( - self.fmt, 'fake', - True, router_id, subnet_id, - expected_res_status=webob.exc.HTTPBadRequest.code) - - def test_delete_router_in_use_by_vpnservice(self): - """Test delete router in use by vpn service.""" - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - with self.vpnservice(subnet=subnet, - router=router): - self._delete('routers', router['router']['id'], - expected_code=webob.exc.HTTPConflict.code) - - def test_update_vpnservice(self): - """Test case to update a vpnservice.""" - name = 'new_vpnservice1' - keys = [('name', name)] - with contextlib.nested( - self.subnet(cidr='10.2.0.0/24'), - self.router()) as (subnet, router): - with self.vpnservice(name=name, - subnet=subnet, - router=router) as vpnservice: - keys.append(('subnet_id', - vpnservice['vpnservice']['subnet_id'])) - keys.append(('router_id', - vpnservice['vpnservice']['router_id'])) - data = {'vpnservice': {'name': name}} - self._set_active(vpn_db.VPNService, - vpnservice['vpnservice']['id']) - req = self.new_update_request( - 'vpnservices', - data, - vpnservice['vpnservice']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['vpnservice'][k], v) - - def test_update_vpnservice_with_invalid_state(self): - """Test case to update a vpnservice in invalid state .""" - name = 'new_vpnservice1' - keys = [('name', name)] - with contextlib.nested( - self.subnet(cidr='10.2.0.0/24'), - self.router()) as (subnet, router): - with self.vpnservice(name=name, - subnet=subnet, - router=router) as vpnservice: - keys.append(('subnet_id', - vpnservice['vpnservice']['subnet_id'])) - keys.append(('router_id', - vpnservice['vpnservice']['router_id'])) - data = {'vpnservice': {'name': name}} - req = self.new_update_request( - 'vpnservices', - data, - vpnservice['vpnservice']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(400, res.status_int) - res = self.deserialize(self.fmt, res) - self.assertIn(vpnservice['vpnservice']['id'], - res['NeutronError']['message']) - - def test_delete_vpnservice(self): - """Test case to delete a vpnservice.""" - with self.vpnservice(name='vpnserver', - no_delete=True) as vpnservice: - req = self.new_delete_request('vpnservices', - vpnservice['vpnservice']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - - def test_show_vpnservice(self): - """Test case to show or get a vpnservice.""" - name = "vpnservice1" - keys = [('name', name), - ('description', ''), - ('admin_state_up', True), - ('status', 'PENDING_CREATE')] - with self.vpnservice(name=name) as vpnservice: - req = self.new_show_request('vpnservices', - vpnservice['vpnservice']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['vpnservice'][k], v) - - def test_list_vpnservices(self): - """Test case to list all vpnservices.""" - name = "vpnservice_list" - keys = [('name', name), - ('description', ''), - ('admin_state_up', True), - ('status', 'PENDING_CREATE')] - with self.vpnservice(name=name) as vpnservice: - keys.append(('subnet_id', vpnservice['vpnservice']['subnet_id'])) - keys.append(('router_id', vpnservice['vpnservice']['router_id'])) - req = self.new_list_request('vpnservices') - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self.assertEqual(len(res), 1) - for k, v in keys: - self.assertEqual(res['vpnservices'][0][k], v) - - def test_list_vpnservices_with_sort_emulated(self): - """Test case to list all vpnservices with sorting.""" - with self.subnet() as subnet: - with self.router() as router: - with contextlib.nested( - self.vpnservice(name='vpnservice1', - subnet=subnet, - router=router, - external_subnet_cidr='192.168.10.0/24',), - self.vpnservice(name='vpnservice2', - subnet=subnet, - router=router, - plug_subnet=False, - external_router=False, - external_subnet_cidr='192.168.11.0/24',), - self.vpnservice(name='vpnservice3', - subnet=subnet, - router=router, - plug_subnet=False, - external_router=False, - external_subnet_cidr='192.168.13.0/24',) - ) as(vpnservice1, vpnservice2, vpnservice3): - self._test_list_with_sort('vpnservice', (vpnservice3, - vpnservice2, - vpnservice1), - [('name', 'desc')]) - - def test_list_vpnservice_with_pagination_emulated(self): - """Test case to list all vpnservices with pagination.""" - with self.subnet() as subnet: - with self.router() as router: - with contextlib.nested( - self.vpnservice(name='vpnservice1', - subnet=subnet, - router=router, - external_subnet_cidr='192.168.10.0/24'), - self.vpnservice(name='vpnservice2', - subnet=subnet, - router=router, - plug_subnet=False, - external_subnet_cidr='192.168.20.0/24', - external_router=False), - self.vpnservice(name='vpnservice3', - subnet=subnet, - router=router, - plug_subnet=False, - external_subnet_cidr='192.168.30.0/24', - external_router=False) - ) as(vpnservice1, vpnservice2, vpnservice3): - self._test_list_with_pagination('vpnservice', - (vpnservice1, - vpnservice2, - vpnservice3), - ('name', 'asc'), 2, 2) - - def test_list_vpnservice_with_pagination_reverse_emulated(self): - """Test case to list all vpnservices with reverse pagination.""" - with self.subnet() as subnet: - with self.router() as router: - with contextlib.nested( - self.vpnservice(name='vpnservice1', - subnet=subnet, - router=router, - external_subnet_cidr='192.168.10.0/24'), - self.vpnservice(name='vpnservice2', - subnet=subnet, - router=router, - plug_subnet=False, - external_subnet_cidr='192.168.11.0/24', - external_router=False), - self.vpnservice(name='vpnservice3', - subnet=subnet, - router=router, - plug_subnet=False, - external_subnet_cidr='192.168.12.0/24', - external_router=False) - ) as(vpnservice1, vpnservice2, vpnservice3): - self._test_list_with_pagination_reverse('vpnservice', - (vpnservice1, - vpnservice2, - vpnservice3), - ('name', 'asc'), - 2, 2) - - def test_create_ipsec_site_connection_with_invalid_values(self): - """Test case to create an ipsec_site_connection with invalid values.""" - name = 'connection1' - self._create_ipsec_site_connection( - fmt=self.fmt, - name=name, peer_cidrs='myname', expected_status_int=400) - self._create_ipsec_site_connection( - fmt=self.fmt, - name=name, mtu=-100, expected_status_int=400) - self._create_ipsec_site_connection( - fmt=self.fmt, - name=name, dpd_action='unsupported', expected_status_int=400) - self._create_ipsec_site_connection( - fmt=self.fmt, - name=name, dpd_interval=-1, expected_status_int=400) - self._create_ipsec_site_connection( - fmt=self.fmt, - name=name, dpd_timeout=-200, expected_status_int=400) - self._create_ipsec_site_connection( - fmt=self.fmt, - name=name, initiator='unsupported', expected_status_int=400) - self._create_ipsec_site_connection( - fmt=self.fmt, - name=name, - dpd_interval=30, - dpd_timeout=20, expected_status_int=400) - self._create_ipsec_site_connection( - fmt=self.fmt, - name=name, - dpd_interval=100, - dpd_timeout=100, expected_status_int=400) - - def _test_create_ipsec_site_connection(self, key_overrides=None, - setup_overrides=None, - expected_status_int=200): - """Create ipsec_site_connection and check results.""" - params = {'ikename': 'ikepolicy1', - 'ipsecname': 'ipsecpolicy1', - 'vpnsname': 'vpnservice1', - 'subnet_cidr': '10.2.0.0/24', - 'subnet_version': 4} - if setup_overrides is not None: - params.update(setup_overrides) - keys = {'name': 'connection1', - 'description': 'my-ipsec-connection', - 'peer_address': '192.168.1.10', - 'peer_id': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'], - 'initiator': 'bi-directional', - 'mtu': 1500, - 'tenant_id': self._tenant_id, - 'psk': 'abcd', - 'status': 'PENDING_CREATE', - 'admin_state_up': True} - if key_overrides is not None: - keys.update(key_overrides) - dpd = {'action': 'hold', - 'interval': 40, - 'timeout': 120} - with contextlib.nested( - self.ikepolicy(name=params['ikename']), - self.ipsecpolicy(name=params['ipsecname']), - self.subnet(cidr=params['subnet_cidr'], - ip_version=params['subnet_version']), - self.router()) as ( - ikepolicy, ipsecpolicy, subnet, router): - with self.vpnservice(name=params['vpnsname'], subnet=subnet, - router=router) as vpnservice1: - keys['ikepolicy_id'] = ikepolicy['ikepolicy']['id'] - keys['ipsecpolicy_id'] = ( - ipsecpolicy['ipsecpolicy']['id'] - ) - keys['vpnservice_id'] = ( - vpnservice1['vpnservice']['id'] - ) - try: - with self.ipsec_site_connection( - self.fmt, - keys['name'], - keys['peer_address'], - keys['peer_id'], - keys['peer_cidrs'], - keys['mtu'], - keys['psk'], - keys['initiator'], - dpd['action'], - dpd['interval'], - dpd['timeout'], - vpnservice1, - ikepolicy, - ipsecpolicy, - keys['admin_state_up'], - description=keys['description'] - ) as ipsec_site_connection: - if expected_status_int != 200: - self.fail("Expected failure on create") - self._check_ipsec_site_connection( - ipsec_site_connection['ipsec_site_connection'], - keys, - dpd) - except webob.exc.HTTPClientError as ce: - self.assertEqual(ce.code, expected_status_int) - - def test_create_ipsec_site_connection(self, **extras): - """Test case to create an ipsec_site_connection.""" - self._test_create_ipsec_site_connection(key_overrides=extras) - - def test_create_ipsec_site_connection_invalid_mtu(self): - """Test creating an ipsec_site_connection with invalid MTU.""" - self._test_create_ipsec_site_connection(key_overrides={'mtu': 67}, - expected_status_int=400) - ipv6_overrides = { - 'peer_address': 'fe80::c0a8:10a', - 'peer_id': 'fe80::c0a8:10a', - 'peer_cidrs': ['fe80::c0a8:200/120', 'fe80::c0a8:300/120'], - 'mtu': 1279} - ipv6_setup_params = {'subnet_cidr': 'fe80::a01:0/120', - 'subnet_version': 6} - self._test_create_ipsec_site_connection( - key_overrides=ipv6_overrides, - setup_overrides=ipv6_setup_params, - expected_status_int=400) - - def test_delete_ipsec_site_connection(self): - """Test case to delete a ipsec_site_connection.""" - with self.ipsec_site_connection( - no_delete=True) as ipsec_site_connection: - req = self.new_delete_request( - 'ipsec-site-connections', - ipsec_site_connection['ipsec_site_connection']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - - def test_update_ipsec_site_connection(self): - """Test case for valid updates to IPSec site connection.""" - dpd = {'action': 'hold', - 'interval': 40, - 'timeout': 120} - self._test_update_ipsec_site_connection(update={'dpd': dpd}) - self._test_update_ipsec_site_connection(update={'mtu': 2000}) - ipv6_settings = { - 'peer_address': 'fe80::c0a8:10a', - 'peer_id': 'fe80::c0a8:10a', - 'peer_cidrs': ['fe80::c0a8:200/120', 'fe80::c0a8:300/120'], - 'subnet_cidr': 'fe80::a02:0/120', - 'subnet_version': 6} - self._test_update_ipsec_site_connection(update={'mtu': 2000}, - overrides=ipv6_settings) - - def test_update_ipsec_site_connection_with_invalid_dpd(self): - """Test updates to ipsec_site_connection with invalid DPD settings.""" - dpd1 = {'action': 'hold', - 'interval': 100, - 'timeout': 100} - self._test_update_ipsec_site_connection( - update={'dpd': dpd1}, - expected_status_int=400) - dpd2 = {'action': 'hold', - 'interval': 100, - 'timeout': 60} - self._test_update_ipsec_site_connection( - update={'dpd': dpd2}, - expected_status_int=400) - dpd3 = {'action': 'hold', - 'interval': -50, - 'timeout': -100} - self._test_update_ipsec_site_connection( - update={'dpd': dpd3}, - expected_status_int=400) - - def test_update_ipsec_site_connection_with_invalid_mtu(self): - """Test updates to ipsec_site_connection with invalid MTU settings.""" - self._test_update_ipsec_site_connection( - update={'mtu': 67}, expected_status_int=400) - ipv6_settings = { - 'peer_address': 'fe80::c0a8:10a', - 'peer_id': 'fe80::c0a8:10a', - 'peer_cidrs': ['fe80::c0a8:200/120', 'fe80::c0a8:300/120'], - 'subnet_cidr': 'fe80::a02:0/120', - 'subnet_version': 6} - self._test_update_ipsec_site_connection( - update={'mtu': 1279}, - overrides=ipv6_settings, - expected_status_int=400) - - def test_update_ipsec_site_connection_with_invalid_state(self): - """Test updating an ipsec_site_connection in invalid state.""" - self._test_update_ipsec_site_connection( - overrides={'make_active': False}, - expected_status_int=400) - - def test_update_ipsec_site_connection_peer_cidrs(self): - """Test updating an ipsec_site_connection for peer_cidrs.""" - new_peers = {'peer_cidrs': ['192.168.4.0/24', - '192.168.5.0/24']} - self._test_update_ipsec_site_connection( - update=new_peers) - - def _test_update_ipsec_site_connection(self, - update={'name': 'new name'}, - overrides=None, - expected_status_int=200): - """Creates and then updates ipsec_site_connection.""" - keys = {'name': 'new_ipsec_site_connection', - 'ikename': 'ikepolicy1', - 'ipsecname': 'ipsecpolicy1', - 'vpnsname': 'vpnservice1', - 'description': 'my-ipsec-connection', - 'peer_address': '192.168.1.10', - 'peer_id': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'], - 'initiator': 'bi-directional', - 'mtu': 1500, - 'tenant_id': self._tenant_id, - 'psk': 'abcd', - 'status': 'ACTIVE', - 'admin_state_up': True, - 'action': 'hold', - 'interval': 40, - 'timeout': 120, - 'subnet_cidr': '10.2.0.0/24', - 'subnet_version': 4, - 'make_active': True} - if overrides is not None: - keys.update(overrides) - - with contextlib.nested( - self.ikepolicy(name=keys['ikename']), - self.ipsecpolicy(name=keys['ipsecname']), - self.subnet(cidr=keys['subnet_cidr'], - ip_version=keys['subnet_version']), - self.router()) as ( - ikepolicy, ipsecpolicy, subnet, router): - with self.vpnservice(name=keys['vpnsname'], subnet=subnet, - router=router) as vpnservice1: - keys['vpnservice_id'] = vpnservice1['vpnservice']['id'] - keys['ikepolicy_id'] = ikepolicy['ikepolicy']['id'] - keys['ipsecpolicy_id'] = ipsecpolicy['ipsecpolicy']['id'] - with self.ipsec_site_connection( - self.fmt, - keys['name'], - keys['peer_address'], - keys['peer_id'], - keys['peer_cidrs'], - keys['mtu'], - keys['psk'], - keys['initiator'], - keys['action'], - keys['interval'], - keys['timeout'], - vpnservice1, - ikepolicy, - ipsecpolicy, - keys['admin_state_up'], - description=keys['description'] - ) as ipsec_site_connection: - data = {'ipsec_site_connection': update} - if keys.get('make_active', None): - self._set_active( - vpn_db.IPsecSiteConnection, - (ipsec_site_connection['ipsec_site_connection'] - ['id'])) - req = self.new_update_request( - 'ipsec-site-connections', - data, - ipsec_site_connection['ipsec_site_connection']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(expected_status_int, res.status_int) - if expected_status_int == 200: - res_dict = self.deserialize(self.fmt, res) - for k, v in update.items(): - self.assertEqual( - res_dict['ipsec_site_connection'][k], v) - - def test_show_ipsec_site_connection(self): - """Test case to show a ipsec_site_connection.""" - ikename = "ikepolicy1" - ipsecname = "ipsecpolicy1" - vpnsname = "vpnservice1" - name = "connection1" - description = "my-ipsec-connection" - keys = {'name': name, - 'description': "my-ipsec-connection", - 'peer_address': '192.168.1.10', - 'peer_id': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'], - 'initiator': 'bi-directional', - 'mtu': 1500, - 'tenant_id': self._tenant_id, - 'psk': 'abcd', - 'status': 'PENDING_CREATE', - 'admin_state_up': True} - dpd = {'action': 'hold', - 'interval': 40, - 'timeout': 120} - with contextlib.nested( - self.ikepolicy(name=ikename), - self.ipsecpolicy(name=ipsecname), - self.subnet(), - self.router()) as ( - ikepolicy, ipsecpolicy, subnet, router): - with self.vpnservice(name=vpnsname, subnet=subnet, - router=router) as vpnservice1: - keys['ikepolicy_id'] = ikepolicy['ikepolicy']['id'] - keys['ipsecpolicy_id'] = ipsecpolicy['ipsecpolicy']['id'] - keys['vpnservice_id'] = vpnservice1['vpnservice']['id'] - with self.ipsec_site_connection( - self.fmt, - name, - keys['peer_address'], - keys['peer_id'], - keys['peer_cidrs'], - keys['mtu'], - keys['psk'], - keys['initiator'], - dpd['action'], - dpd['interval'], - dpd['timeout'], - vpnservice1, - ikepolicy, - ipsecpolicy, - keys['admin_state_up'], - description=description, - ) as ipsec_site_connection: - - req = self.new_show_request( - 'ipsec-site-connections', - ipsec_site_connection[ - 'ipsec_site_connection']['id'], - fmt=self.fmt - ) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - - self._check_ipsec_site_connection( - res['ipsec_site_connection'], - keys, - dpd) - - def test_list_ipsec_site_connections_with_sort_emulated(self): - """Test case to list all ipsec_site_connections with sort.""" - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - with self.vpnservice(subnet=subnet, - router=router - ) as vpnservice: - with contextlib.nested( - self.ipsec_site_connection( - name='connection1', vpnservice=vpnservice - ), - self.ipsec_site_connection( - name='connection2', vpnservice=vpnservice - ), - self.ipsec_site_connection( - name='connection3', vpnservice=vpnservice - ) - ) as(ipsec_site_connection1, - ipsec_site_connection2, - ipsec_site_connection3): - self._test_list_with_sort('ipsec-site-connection', - (ipsec_site_connection3, - ipsec_site_connection2, - ipsec_site_connection1), - [('name', 'desc')]) - - def test_list_ipsec_site_connections_with_pagination_emulated(self): - """Test case to list all ipsec_site_connections with pagination.""" - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - with self.vpnservice(subnet=subnet, - router=router - ) as vpnservice: - with contextlib.nested( - self.ipsec_site_connection( - name='ipsec_site_connection1', - vpnservice=vpnservice - ), - self.ipsec_site_connection( - name='ipsec_site_connection1', - vpnservice=vpnservice - ), - self.ipsec_site_connection( - name='ipsec_site_connection1', - vpnservice=vpnservice - ) - ) as(ipsec_site_connection1, - ipsec_site_connection2, - ipsec_site_connection3): - self._test_list_with_pagination( - 'ipsec-site-connection', - (ipsec_site_connection1, - ipsec_site_connection2, - ipsec_site_connection3), - ('name', 'asc'), 2, 2) - - def test_list_ipsec_site_conns_with_pagination_reverse_emulated(self): - """Test to list all ipsec_site_connections with reverse pagination.""" - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - with self.vpnservice(subnet=subnet, - router=router - ) as vpnservice: - with contextlib.nested( - self.ipsec_site_connection( - name='connection1', vpnservice=vpnservice - ), - self.ipsec_site_connection( - name='connection2', vpnservice=vpnservice - ), - self.ipsec_site_connection( - name='connection3', vpnservice=vpnservice - ) - ) as(ipsec_site_connection1, - ipsec_site_connection2, - ipsec_site_connection3): - self._test_list_with_pagination_reverse( - 'ipsec-site-connection', - (ipsec_site_connection1, - ipsec_site_connection2, - ipsec_site_connection3), - ('name', 'asc'), 2, 2 - ) - - def test_create_vpn(self): - """Test case to create a vpn.""" - vpns_name = "vpnservice1" - ike_name = "ikepolicy1" - ipsec_name = "ipsecpolicy1" - name1 = "ipsec_site_connection1" - with contextlib.nested( - self.ikepolicy(name=ike_name), - self.ipsecpolicy(name=ipsec_name), - self.vpnservice(name=vpns_name)) as ( - ikepolicy, ipsecpolicy, vpnservice): - vpnservice_id = vpnservice['vpnservice']['id'] - ikepolicy_id = ikepolicy['ikepolicy']['id'] - ipsecpolicy_id = ipsecpolicy['ipsecpolicy']['id'] - with self.ipsec_site_connection( - self.fmt, - name1, - '192.168.1.10', - '192.168.1.10', - ['192.168.2.0/24', - '192.168.3.0/24'], - 1500, - 'abcdef', - 'bi-directional', - 'hold', - 30, - 120, - vpnservice, - ikepolicy, - ipsecpolicy, - True - ) as vpnconn1: - - vpnservice_req = self.new_show_request( - 'vpnservices', - vpnservice_id, - fmt=self.fmt) - vpnservice_updated = self.deserialize( - self.fmt, - vpnservice_req.get_response(self.ext_api) - ) - self.assertEqual( - vpnservice_updated['vpnservice']['id'], - vpnconn1['ipsec_site_connection']['vpnservice_id'] - ) - ikepolicy_req = self.new_show_request('ikepolicies', - ikepolicy_id, - fmt=self.fmt) - ikepolicy_res = self.deserialize( - self.fmt, - ikepolicy_req.get_response(self.ext_api) - ) - self.assertEqual( - ikepolicy_res['ikepolicy']['id'], - vpnconn1['ipsec_site_connection']['ikepolicy_id']) - ipsecpolicy_req = self.new_show_request( - 'ipsecpolicies', - ipsecpolicy_id, - fmt=self.fmt) - ipsecpolicy_res = self.deserialize( - self.fmt, - ipsecpolicy_req.get_response(self.ext_api) - ) - self.assertEqual( - ipsecpolicy_res['ipsecpolicy']['id'], - vpnconn1['ipsec_site_connection']['ipsecpolicy_id'] - ) - - def test_delete_ikepolicy_inuse(self): - """Test case to delete an ikepolicy, that is in use.""" - vpns_name = "vpnservice1" - ike_name = "ikepolicy1" - ipsec_name = "ipsecpolicy1" - name1 = "ipsec_site_connection1" - with self.ikepolicy(name=ike_name) as ikepolicy: - with self.ipsecpolicy(name=ipsec_name) as ipsecpolicy: - with self.vpnservice(name=vpns_name) as vpnservice: - with self.ipsec_site_connection( - self.fmt, - name1, - '192.168.1.10', - '192.168.1.10', - ['192.168.2.0/24', - '192.168.3.0/24'], - 1500, - 'abcdef', - 'bi-directional', - 'hold', - 30, - 120, - vpnservice, - ikepolicy, - ipsecpolicy, - True - ): - delete_req = self.new_delete_request( - 'ikepolicies', - ikepolicy['ikepolicy']['id'] - ) - delete_res = delete_req.get_response(self.ext_api) - self.assertEqual(409, delete_res.status_int) - - def test_delete_ipsecpolicy_inuse(self): - """Test case to delete an ipsecpolicy, that is in use.""" - vpns_name = "vpnservice1" - ike_name = "ikepolicy1" - ipsec_name = "ipsecpolicy1" - name1 = "ipsec_site_connection1" - with self.ikepolicy(name=ike_name) as ikepolicy: - with self.ipsecpolicy(name=ipsec_name) as ipsecpolicy: - with self.vpnservice(name=vpns_name) as vpnservice: - with self.ipsec_site_connection( - self.fmt, - name1, - '192.168.1.10', - '192.168.1.10', - ['192.168.2.0/24', - '192.168.3.0/24'], - 1500, - 'abcdef', - 'bi-directional', - 'hold', - 30, - 120, - vpnservice, - ikepolicy, - ipsecpolicy, - True - ): - - delete_req = self.new_delete_request( - 'ipsecpolicies', - ipsecpolicy['ipsecpolicy']['id'] - ) - delete_res = delete_req.get_response(self.ext_api) - self.assertEqual(409, delete_res.status_int) - - -class TestVpnaasXML(TestVpnaas): - fmt = 'xml' diff --git a/neutron/tests/unit/dummy_plugin.py b/neutron/tests/unit/dummy_plugin.py deleted file mode 100644 index fc58a7e29..000000000 --- a/neutron/tests/unit/dummy_plugin.py +++ /dev/null @@ -1,139 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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. - -from neutron.api import extensions -from neutron.api.v2 import base -from neutron.common import exceptions -from neutron.db import servicetype_db -from neutron.extensions import servicetype -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.services import service_base - - -DUMMY_PLUGIN_NAME = "dummy_plugin" -RESOURCE_NAME = "dummy" -COLLECTION_NAME = "%ss" % RESOURCE_NAME - -# Attribute Map for dummy resource -RESOURCE_ATTRIBUTE_MAP = { - COLLECTION_NAME: { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'is_visible': True}, - 'service_type': {'allow_post': True, - 'allow_put': False, - 'validate': {'type:servicetype_ref': None}, - 'is_visible': True, - 'default': None} - } -} - - -class Dummy(object): - - @classmethod - def get_name(cls): - return "dummy" - - @classmethod - def get_alias(cls): - return "dummy" - - @classmethod - def get_description(cls): - return "Dummy stuff" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/neutron/dummy/api/v1.0" - - @classmethod - def get_updated(cls): - return "2012-11-20T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Extended Resource for dummy management.""" - q_mgr = manager.NeutronManager.get_instance() - dummy_inst = q_mgr.get_service_plugins()['DUMMY'] - controller = base.create_resource( - COLLECTION_NAME, RESOURCE_NAME, dummy_inst, - RESOURCE_ATTRIBUTE_MAP[COLLECTION_NAME]) - return [extensions.ResourceExtension(COLLECTION_NAME, - controller)] - - -class DummyServicePlugin(service_base.ServicePluginBase): - """This is a simple plugin for managing instantes of a fictional 'dummy' - service. This plugin is provided as a proof-of-concept of how - advanced service might leverage the service type extension. - Ideally, instances of real advanced services, such as load balancing - or VPN will adopt a similar solution. - """ - - supported_extension_aliases = ['dummy', servicetype.EXT_ALIAS] - agent_notifiers = {'dummy': 'dummy_agent_notifier'} - - def __init__(self): - self.svctype_mgr = servicetype_db.ServiceTypeManager.get_instance() - self.dummys = {} - - def get_plugin_type(self): - return constants.DUMMY - - def get_plugin_name(self): - return DUMMY_PLUGIN_NAME - - def get_plugin_description(self): - return "Neutron Dummy Service Plugin" - - def get_dummys(self, context, filters, fields): - return self.dummys.values() - - def get_dummy(self, context, id, fields): - try: - return self.dummys[id] - except KeyError: - raise exceptions.NotFound() - - def create_dummy(self, context, dummy): - d = dummy['dummy'] - d['id'] = uuidutils.generate_uuid() - self.dummys[d['id']] = d - self.svctype_mgr.increase_service_type_refcount(context, - d['service_type']) - return d - - def update_dummy(self, context, id, dummy): - pass - - def delete_dummy(self, context, id): - try: - svc_type_id = self.dummys[id]['service_type'] - del self.dummys[id] - self.svctype_mgr.decrease_service_type_refcount(context, - svc_type_id) - except KeyError: - raise exceptions.NotFound() diff --git a/neutron/tests/unit/embrane/__init__.py b/neutron/tests/unit/embrane/__init__.py deleted file mode 100644 index bb81770cd..000000000 --- a/neutron/tests/unit/embrane/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Embrane, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Ivar Lazzaro, Embrane, Inc. diff --git a/neutron/tests/unit/embrane/test_embrane_defaults.py b/neutron/tests/unit/embrane/test_embrane_defaults.py deleted file mode 100644 index ea84d63ab..000000000 --- a/neutron/tests/unit/embrane/test_embrane_defaults.py +++ /dev/null @@ -1,31 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Embrane, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Ivar Lazzaro, Embrane, Inc. - -from oslo.config import cfg - -from neutron.plugins.embrane.common import config # noqa -from neutron.tests import base - - -class ConfigurationTest(base.BaseTestCase): - - def test_defaults(self): - self.assertEqual('admin', cfg.CONF.heleos.admin_username) - self.assertEqual('default', cfg.CONF.heleos.resource_pool_id) - self.assertTrue(cfg.CONF.heleos.async_requests) diff --git a/neutron/tests/unit/embrane/test_embrane_l3_plugin.py b/neutron/tests/unit/embrane/test_embrane_l3_plugin.py deleted file mode 100644 index 548a1d432..000000000 --- a/neutron/tests/unit/embrane/test_embrane_l3_plugin.py +++ /dev/null @@ -1,41 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Embrane, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Ivar Lazzaro, Embrane, Inc. - -from oslo.config import cfg - -from neutron.db import api as db -from neutron.plugins.embrane.common import config # noqa -from neutron.tests.unit import test_extension_extraroute as extraroute_test -from neutron.tests.unit import test_l3_plugin as router_test - -PLUGIN_NAME = ('neutron.plugins.embrane.plugins.embrane_fake_plugin.' - 'EmbraneFakePlugin') - - -class TestEmbraneL3NatDBTestCase(router_test.L3NatDBIntTestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self): - cfg.CONF.set_override('admin_password', "admin123", 'heleos') - self.addCleanup(db.clear_db) - super(TestEmbraneL3NatDBTestCase, self).setUp() - - -class ExtraRouteDBTestCase(extraroute_test.ExtraRouteDBIntTestCase): - _plugin_name = PLUGIN_NAME diff --git a/neutron/tests/unit/embrane/test_embrane_neutron_plugin.py b/neutron/tests/unit/embrane/test_embrane_neutron_plugin.py deleted file mode 100644 index 74b64e415..000000000 --- a/neutron/tests/unit/embrane/test_embrane_neutron_plugin.py +++ /dev/null @@ -1,82 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Embrane, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Ivar Lazzaro, Embrane, Inc. -import sys - -import mock -from oslo.config import cfg - -from neutron.db import api as db -from neutron.plugins.embrane.common import config # noqa -from neutron.tests.unit import test_db_plugin as test_plugin - -PLUGIN_NAME = ('neutron.plugins.embrane.plugins.embrane_fake_plugin.' - 'EmbraneFakePlugin') - - -class EmbranePluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self): - cfg.CONF.set_override('admin_password', "admin123", 'heleos') - p = mock.patch.dict(sys.modules, {'heleosapi': mock.Mock()}) - p.start() - self.addCleanup(db.clear_db) - # dict patches must be explicitly stopped - self.addCleanup(p.stop) - super(EmbranePluginV2TestCase, self).setUp(self._plugin_name) - - -class TestEmbraneBasicGet(test_plugin.TestBasicGet, EmbranePluginV2TestCase): - pass - - -class TestEmbraneV2HTTPResponse(test_plugin.TestV2HTTPResponse, - EmbranePluginV2TestCase): - pass - - -class TestEmbranePortsV2(test_plugin.TestPortsV2, EmbranePluginV2TestCase): - - def test_create_ports_bulk_emulated_plugin_failure(self): - self.skip("Temporary skipping due to incompatibility with the" - " plugin dynamic class type") - - def test_recycle_expired_previously_run_within_context(self): - self.skip("Temporary skipping due to incompatibility with the" - " plugin dynamic class type") - - def test_recycle_held_ip_address(self): - self.skip("Temporary skipping due to incompatibility with the" - " plugin dynamic class type") - - -class TestEmbraneNetworksV2(test_plugin.TestNetworksV2, - EmbranePluginV2TestCase): - - def test_create_networks_bulk_emulated_plugin_failure(self): - self.skip("Temporary skipping due to incompatibility with the" - " plugin dynamic class type") - - -class TestEmbraneSubnetsV2(test_plugin.TestSubnetsV2, - EmbranePluginV2TestCase): - - def test_create_subnets_bulk_emulated_plugin_failure(self): - self.skip("Temporary skipping due to incompatibility with the" - " plugin dynamic class type") diff --git a/neutron/tests/unit/hyperv/__init__.py b/neutron/tests/unit/hyperv/__init__.py deleted file mode 100644 index 7ef4e09fa..000000000 --- a/neutron/tests/unit/hyperv/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Cloudbase Solutions SRL -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/hyperv/test_hyperv_neutron_agent.py b/neutron/tests/unit/hyperv/test_hyperv_neutron_agent.py deleted file mode 100644 index 5d2a24c0d..000000000 --- a/neutron/tests/unit/hyperv/test_hyperv_neutron_agent.py +++ /dev/null @@ -1,221 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Cloudbase Solutions SRL -# Copyright 2013 Pedro Navarro Perez -# All Rights Reserved. -# -# 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. - -""" -Unit tests for Windows Hyper-V virtual switch neutron driver -""" - -import mock -from oslo.config import cfg - -from neutron.plugins.hyperv.agent import hyperv_neutron_agent -from neutron.plugins.hyperv.agent import utilsfactory -from neutron.tests import base - -cfg.CONF.import_opt('enable_metrics_collection', - 'neutron.plugins.hyperv.agent.hyperv_neutron_agent', - 'AGENT') - - -class TestHyperVNeutronAgent(base.BaseTestCase): - - _FAKE_PORT_ID = 'fake_port_id' - - def setUp(self): - super(TestHyperVNeutronAgent, self).setUp() - # Avoid rpc initialization for unit tests - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - - utilsfactory._get_windows_version = mock.MagicMock( - return_value='6.2.0') - - class MockFixedIntervalLoopingCall(object): - def __init__(self, f): - self.f = f - - def start(self, interval=0): - self.f() - - mock.patch('neutron.openstack.common.loopingcall.' - 'FixedIntervalLoopingCall', - new=MockFixedIntervalLoopingCall).start() - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - self.agent = hyperv_neutron_agent.HyperVNeutronAgent() - self.agent.plugin_rpc = mock.Mock() - self.agent.sec_groups_agent = mock.MagicMock() - self.agent.context = mock.Mock() - self.agent.agent_id = mock.Mock() - - fake_agent_state = { - 'binary': 'neutron-hyperv-agent', - 'host': 'fake_host_name', - 'topic': 'N/A', - 'configurations': {'vswitch_mappings': ['*:MyVirtualSwitch']}, - 'agent_type': 'HyperV agent', - 'start_flag': True} - self.agent_state = fake_agent_state - - def test_port_bound_enable_metrics(self): - cfg.CONF.set_override('enable_metrics_collection', True, 'AGENT') - self._test_port_bound(True) - - def test_port_bound_no_metrics(self): - cfg.CONF.set_override('enable_metrics_collection', False, 'AGENT') - self._test_port_bound(False) - - def _test_port_bound(self, enable_metrics): - port = mock.MagicMock() - mock_enable_metrics = mock.MagicMock() - net_uuid = 'my-net-uuid' - - with mock.patch.multiple( - self.agent._utils, - connect_vnic_to_vswitch=mock.MagicMock(), - set_vswitch_port_vlan_id=mock.MagicMock(), - enable_port_metrics_collection=mock_enable_metrics): - - self.agent._port_bound(port, net_uuid, 'vlan', None, None) - - self.assertEqual(enable_metrics, mock_enable_metrics.called) - - def test_port_unbound(self): - map = { - 'network_type': 'vlan', - 'vswitch_name': 'fake-vswitch', - 'ports': [], - 'vlan_id': 1} - net_uuid = 'my-net-uuid' - network_vswitch_map = (net_uuid, map) - with mock.patch.object(self.agent, - '_get_network_vswitch_map_by_port_id', - return_value=network_vswitch_map): - with mock.patch.object( - self.agent._utils, - 'disconnect_switch_port'): - self.agent._port_unbound(net_uuid) - - def test_port_enable_control_metrics_ok(self): - cfg.CONF.set_override('enable_metrics_collection', True, 'AGENT') - self.agent._port_metric_retries[self._FAKE_PORT_ID] = ( - cfg.CONF.AGENT.metrics_max_retries) - - with mock.patch.multiple(self.agent._utils, - can_enable_control_metrics=mock.MagicMock(), - enable_control_metrics=mock.MagicMock()): - - self.agent._utils.can_enable_control_metrics.return_value = True - self.agent._port_enable_control_metrics() - self.agent._utils.enable_control_metrics.assert_called_with( - self._FAKE_PORT_ID) - - self.assertNotIn(self._FAKE_PORT_ID, self.agent._port_metric_retries) - - def test_port_enable_control_metrics_maxed(self): - cfg.CONF.set_override('enable_metrics_collection', True, 'AGENT') - cfg.CONF.set_override('metrics_max_retries', 3, 'AGENT') - self.agent._port_metric_retries[self._FAKE_PORT_ID] = ( - cfg.CONF.AGENT.metrics_max_retries) - - with mock.patch.multiple(self.agent._utils, - can_enable_control_metrics=mock.MagicMock(), - enable_control_metrics=mock.MagicMock()): - - self.agent._utils.can_enable_control_metrics.return_value = False - for i in range(cfg.CONF.AGENT.metrics_max_retries + 1): - self.assertIn(self._FAKE_PORT_ID, - self.agent._port_metric_retries) - self.agent._port_enable_control_metrics() - - self.assertNotIn(self._FAKE_PORT_ID, self.agent._port_metric_retries) - - def test_treat_devices_added_returns_true_for_missing_device(self): - attrs = {'get_device_details.side_effect': Exception()} - self.agent.plugin_rpc.configure_mock(**attrs) - self.assertTrue(self.agent._treat_devices_added([{}])) - - def mock_treat_devices_added(self, details, func_name): - """Mock treat devices added. - - :param details: the details to return for the device - :param func_name: the function that should be called - :returns: whether the named function was called - """ - attrs = {'get_device_details.return_value': details} - self.agent.plugin_rpc.configure_mock(**attrs) - with mock.patch.object(self.agent, func_name) as func: - self.assertFalse(self.agent._treat_devices_added([{}])) - return func.called - - def test_treat_devices_added_updates_known_port(self): - details = mock.MagicMock() - details.__contains__.side_effect = lambda x: True - with mock.patch.object(self.agent.plugin_rpc, - "update_device_up") as func: - self.assertTrue(self.mock_treat_devices_added(details, - '_treat_vif_port')) - self.assertTrue(func.called) - - def test_treat_devices_added_missing_port_id(self): - details = mock.MagicMock() - details.__contains__.side_effect = lambda x: False - with mock.patch.object(self.agent.plugin_rpc, - "update_device_up") as func: - self.assertFalse(self.mock_treat_devices_added(details, - '_treat_vif_port')) - self.assertFalse(func.called) - - def test_treat_devices_removed_returns_true_for_missing_device(self): - attrs = {'update_device_down.side_effect': Exception()} - self.agent.plugin_rpc.configure_mock(**attrs) - self.assertTrue(self.agent._treat_devices_removed([{}])) - - def mock_treat_devices_removed(self, port_exists): - details = dict(exists=port_exists) - attrs = {'update_device_down.return_value': details} - self.agent.plugin_rpc.configure_mock(**attrs) - with mock.patch.object(self.agent, '_port_unbound') as func: - self.assertFalse(self.agent._treat_devices_removed([{}])) - self.assertEqual(func.called, not port_exists) - - def test_treat_devices_removed_unbinds_port(self): - self.mock_treat_devices_removed(False) - - def test_treat_devices_removed_ignores_missing_port(self): - self.mock_treat_devices_removed(False) - - def test_report_state(self): - with mock.patch.object(self.agent.state_rpc, - "report_state") as report_st: - self.agent._report_state() - report_st.assert_called_with(self.agent.context, - self.agent.agent_state) - self.assertNotIn("start_flag", self.agent.agent_state) - - def test_main(self): - with mock.patch.object(hyperv_neutron_agent, - 'HyperVNeutronAgent') as plugin: - with mock.patch.object(hyperv_neutron_agent, - 'common_config') as common_config: - hyperv_neutron_agent.main() - - self.assertTrue(common_config.init.called) - self.assertTrue(common_config.setup_logging.called) - plugin.assert_has_calls([mock.call().daemon_loop()]) diff --git a/neutron/tests/unit/hyperv/test_hyperv_neutron_plugin.py b/neutron/tests/unit/hyperv/test_hyperv_neutron_plugin.py deleted file mode 100644 index 8e34777c2..000000000 --- a/neutron/tests/unit/hyperv/test_hyperv_neutron_plugin.py +++ /dev/null @@ -1,69 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Cloudbase Solutions SRL -# Copyright 2013 Pedro Navarro Perez -# All Rights Reserved. -# -# 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 contextlib - -from oslo.config import cfg - -from neutron import context -from neutron.extensions import portbindings -from neutron import manager -from neutron.tests.unit import test_db_plugin as test_plugin - - -class HyperVNeutronPluginTestCase(test_plugin.NeutronDbPluginV2TestCase): - - _plugin_name = ('neutron.plugins.hyperv.' - 'hyperv_neutron_plugin.HyperVNeutronPlugin') - - def setUp(self): - super(HyperVNeutronPluginTestCase, self).setUp(self._plugin_name) - - -class TestHyperVVirtualSwitchBasicGet( - test_plugin.TestBasicGet, HyperVNeutronPluginTestCase): - pass - - -class TestHyperVVirtualSwitchV2HTTPResponse( - test_plugin.TestV2HTTPResponse, HyperVNeutronPluginTestCase): - pass - - -class TestHyperVVirtualSwitchPortsV2( - test_plugin.TestPortsV2, HyperVNeutronPluginTestCase): - def test_port_vif_details(self): - with self.port(name='name') as port: - self.assertEqual(port['port']['binding:vif_type'], - portbindings.VIF_TYPE_HYPERV) - - def test_ports_vif_details(self): - cfg.CONF.set_default('allow_overlapping_ips', True) - plugin = manager.NeutronManager.get_plugin() - with contextlib.nested(self.port(), self.port()) as (port1, port2): - ctx = context.get_admin_context() - ports = plugin.get_ports(ctx) - self.assertEqual(len(ports), 2) - for port in ports: - self.assertEqual(port['binding:vif_type'], - portbindings.VIF_TYPE_HYPERV) - - -class TestHyperVVirtualSwitchNetworksV2( - test_plugin.TestNetworksV2, HyperVNeutronPluginTestCase): - pass diff --git a/neutron/tests/unit/hyperv/test_hyperv_rpcapi.py b/neutron/tests/unit/hyperv/test_hyperv_rpcapi.py deleted file mode 100644 index 965842738..000000000 --- a/neutron/tests/unit/hyperv/test_hyperv_rpcapi.py +++ /dev/null @@ -1,125 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Cloudbase Solutions SRL -# Copyright 2013 Pedro Navarro Perez -# All Rights Reserved. -# -# 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. - -""" -Unit Tests for hyperv neutron rpc -""" - -import mock - -from neutron.agent import rpc as agent_rpc -from neutron.common import rpc_compat -from neutron.common import topics -from neutron.openstack.common import context -from neutron.plugins.hyperv import agent_notifier_api as ana -from neutron.plugins.hyperv.common import constants -from neutron.tests import base - - -class rpcHyperVApiTestCase(base.BaseTestCase): - - def _test_hyperv_neutron_api( - self, rpcapi, topic, method, rpc_method, **kwargs): - ctxt = context.RequestContext('fake_user', 'fake_project') - expected_retval = 'foo' if method == 'call' else None - expected_msg = rpcapi.make_msg(method, **kwargs) - if rpc_method == 'cast' and method == 'run_instance': - kwargs['call'] = False - - proxy = rpc_compat.RpcProxy - with mock.patch.object(proxy, rpc_method) as rpc_method_mock: - rpc_method_mock.return_value = expected_retval - retval = getattr(rpcapi, method)(ctxt, **kwargs) - - self.assertEqual(retval, expected_retval) - expected = [ - mock.call(ctxt, expected_msg, topic=topic) - ] - rpc_method_mock.assert_has_calls(expected) - - def test_delete_network(self): - rpcapi = ana.AgentNotifierApi(topics.AGENT) - self._test_hyperv_neutron_api( - rpcapi, - topics.get_topic_name( - topics.AGENT, - topics.NETWORK, - topics.DELETE), - 'network_delete', rpc_method='fanout_cast', - network_id='fake_request_spec') - - def test_port_update(self): - rpcapi = ana.AgentNotifierApi(topics.AGENT) - self._test_hyperv_neutron_api( - rpcapi, - topics.get_topic_name( - topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - port='fake_port', - network_type='fake_network_type', - segmentation_id='fake_segmentation_id', - physical_network='fake_physical_network') - - def test_port_delete(self): - rpcapi = ana.AgentNotifierApi(topics.AGENT) - self._test_hyperv_neutron_api( - rpcapi, - topics.get_topic_name( - topics.AGENT, - topics.PORT, - topics.DELETE), - 'port_delete', rpc_method='fanout_cast', - port_id='port_id') - - def test_tunnel_update(self): - rpcapi = ana.AgentNotifierApi(topics.AGENT) - self._test_hyperv_neutron_api( - rpcapi, - topics.get_topic_name( - topics.AGENT, - constants.TUNNEL, - topics.UPDATE), - 'tunnel_update', rpc_method='fanout_cast', - tunnel_ip='fake_ip', tunnel_id='fake_id') - - def test_device_details(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_hyperv_neutron_api( - rpcapi, topics.PLUGIN, - 'get_device_details', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id') - - def test_update_device_down(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_hyperv_neutron_api( - rpcapi, topics.PLUGIN, - 'update_device_down', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') - - def test_tunnel_sync(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_hyperv_neutron_api( - rpcapi, topics.PLUGIN, - 'tunnel_sync', rpc_method='call', - tunnel_ip='fake_tunnel_ip', - tunnel_type=None) diff --git a/neutron/tests/unit/hyperv/test_hyperv_security_groups_driver.py b/neutron/tests/unit/hyperv/test_hyperv_security_groups_driver.py deleted file mode 100644 index bcbe6ba0e..000000000 --- a/neutron/tests/unit/hyperv/test_hyperv_security_groups_driver.py +++ /dev/null @@ -1,189 +0,0 @@ -# Copyright 2014 Cloudbase Solutions SRL -# All Rights Reserved. -# -# 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. -# @author: Claudiu Belu, Cloudbase Solutions Srl - -""" -Unit tests for the Hyper-V Security Groups Driver. -""" - -import mock -from oslo.config import cfg - -from neutron.plugins.hyperv.agent import security_groups_driver as sg_driver -from neutron.plugins.hyperv.agent import utilsfactory -from neutron.tests import base - -CONF = cfg.CONF - - -class TestHyperVSecurityGroupsDriver(base.BaseTestCase): - - _FAKE_DEVICE = 'fake_device' - _FAKE_ID = 'fake_id' - _FAKE_DIRECTION = 'ingress' - _FAKE_ETHERTYPE = 'IPv4' - _FAKE_ETHERTYPE_IPV6 = 'IPv6' - _FAKE_DEST_IP_PREFIX = 'fake_dest_ip_prefix' - _FAKE_SOURCE_IP_PREFIX = 'fake_source_ip_prefix' - _FAKE_PARAM_NAME = 'fake_param_name' - _FAKE_PARAM_VALUE = 'fake_param_value' - - _FAKE_PORT_MIN = 9001 - _FAKE_PORT_MAX = 9011 - - def setUp(self): - super(TestHyperVSecurityGroupsDriver, self).setUp() - self._mock_windows_version = mock.patch.object(utilsfactory, - 'get_hypervutils') - self._mock_windows_version.start() - self._driver = sg_driver.HyperVSecurityGroupsDriver() - self._driver._utils = mock.MagicMock() - - @mock.patch('neutron.plugins.hyperv.agent.security_groups_driver' - '.HyperVSecurityGroupsDriver._create_port_rules') - def test_prepare_port_filter(self, mock_create_rules): - mock_port = self._get_port() - mock_utils_method = self._driver._utils.create_default_reject_all_rules - self._driver.prepare_port_filter(mock_port) - - self.assertEqual(mock_port, - self._driver._security_ports[self._FAKE_DEVICE]) - mock_utils_method.assert_called_once_with(self._FAKE_ID) - self._driver._create_port_rules.assert_called_once_with( - self._FAKE_ID, mock_port['security_group_rules']) - - def test_update_port_filter(self): - mock_port = self._get_port() - new_mock_port = self._get_port() - new_mock_port['id'] += '2' - new_mock_port['security_group_rules'][0]['ethertype'] += "2" - - self._driver._security_ports[mock_port['device']] = mock_port - self._driver._create_port_rules = mock.MagicMock() - self._driver._remove_port_rules = mock.MagicMock() - self._driver.update_port_filter(new_mock_port) - - self._driver._remove_port_rules.assert_called_once_with( - mock_port['id'], mock_port['security_group_rules']) - self._driver._create_port_rules.assert_called_once_with( - new_mock_port['id'], new_mock_port['security_group_rules']) - self.assertEqual(new_mock_port, - self._driver._security_ports[new_mock_port['device']]) - - @mock.patch('neutron.plugins.hyperv.agent.security_groups_driver' - '.HyperVSecurityGroupsDriver.prepare_port_filter') - def test_update_port_filter_new_port(self, mock_method): - mock_port = self._get_port() - self._driver.prepare_port_filter = mock.MagicMock() - self._driver.update_port_filter(mock_port) - - self._driver.prepare_port_filter.assert_called_once_with(mock_port) - - def test_remove_port_filter(self): - mock_port = self._get_port() - self._driver._security_ports[mock_port['device']] = mock_port - self._driver.remove_port_filter(mock_port) - self.assertFalse(mock_port['device'] in self._driver._security_ports) - - def test_create_port_rules_exception(self): - fake_rule = self._create_security_rule() - self._driver._utils.create_security_rule.side_effect = Exception( - 'Generated Exception for testing.') - self._driver._create_port_rules(self._FAKE_ID, [fake_rule]) - - def test_create_param_map(self): - fake_rule = self._create_security_rule() - self._driver._get_rule_remote_address = mock.MagicMock( - return_value=self._FAKE_SOURCE_IP_PREFIX) - actual = self._driver._create_param_map(fake_rule) - expected = { - 'direction': self._driver._ACL_PROP_MAP[ - 'direction'][self._FAKE_DIRECTION], - 'acl_type': self._driver._ACL_PROP_MAP[ - 'ethertype'][self._FAKE_ETHERTYPE], - 'local_port': '%s-%s' % (self._FAKE_PORT_MIN, self._FAKE_PORT_MAX), - 'protocol': self._driver._ACL_PROP_MAP['default'], - 'remote_address': self._FAKE_SOURCE_IP_PREFIX - } - - self.assertEqual(expected, actual) - - @mock.patch('neutron.plugins.hyperv.agent.security_groups_driver' - '.HyperVSecurityGroupsDriver._create_param_map') - def test_create_port_rules(self, mock_method): - fake_rule = self._create_security_rule() - mock_method.return_value = { - self._FAKE_PARAM_NAME: self._FAKE_PARAM_VALUE} - self._driver._create_port_rules(self._FAKE_ID, [fake_rule]) - - self._driver._utils.create_security_rule.assert_called_once_with( - self._FAKE_ID, fake_param_name=self._FAKE_PARAM_VALUE) - - def test_convert_any_address_to_same_ingress(self): - rule = self._create_security_rule() - actual = self._driver._get_rule_remote_address(rule) - self.assertEqual(self._FAKE_SOURCE_IP_PREFIX, actual) - - def test_convert_any_address_to_same_egress(self): - rule = self._create_security_rule() - rule['direction'] += '2' - actual = self._driver._get_rule_remote_address(rule) - self.assertEqual(self._FAKE_DEST_IP_PREFIX, actual) - - def test_convert_any_address_to_ipv4(self): - rule = self._create_security_rule() - del rule['source_ip_prefix'] - actual = self._driver._get_rule_remote_address(rule) - self.assertEqual(self._driver._ACL_PROP_MAP['address_default']['IPv4'], - actual) - - def test_convert_any_address_to_ipv6(self): - rule = self._create_security_rule() - del rule['source_ip_prefix'] - rule['ethertype'] = self._FAKE_ETHERTYPE_IPV6 - actual = self._driver._get_rule_remote_address(rule) - self.assertEqual(self._driver._ACL_PROP_MAP['address_default']['IPv6'], - actual) - - def test_get_rule_protocol_icmp(self): - self._test_get_rule_protocol( - 'icmp', self._driver._ACL_PROP_MAP['protocol']['icmp']) - - def test_get_rule_protocol_no_icmp(self): - self._test_get_rule_protocol('tcp', 'tcp') - - def _test_get_rule_protocol(self, protocol, expected): - rule = self._create_security_rule() - rule['protocol'] = protocol - actual = self._driver._get_rule_protocol(rule) - - self.assertEqual(expected, actual) - - def _get_port(self): - return { - 'device': self._FAKE_DEVICE, - 'id': self._FAKE_ID, - 'security_group_rules': [self._create_security_rule()] - } - - def _create_security_rule(self): - return { - 'direction': self._FAKE_DIRECTION, - 'ethertype': self._FAKE_ETHERTYPE, - 'dest_ip_prefix': self._FAKE_DEST_IP_PREFIX, - 'source_ip_prefix': self._FAKE_SOURCE_IP_PREFIX, - 'port_range_min': self._FAKE_PORT_MIN, - 'port_range_max': self._FAKE_PORT_MAX - } diff --git a/neutron/tests/unit/hyperv/test_hyperv_utilsfactory.py b/neutron/tests/unit/hyperv/test_hyperv_utilsfactory.py deleted file mode 100644 index fef96d734..000000000 --- a/neutron/tests/unit/hyperv/test_hyperv_utilsfactory.py +++ /dev/null @@ -1,54 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Cloudbase Solutions SRL -# All Rights Reserved. -# -# 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. -# @author: Claudiu Belu, Cloudbase Solutions Srl - -""" -Unit tests for the Hyper-V utils factory. -""" - -import mock - -from oslo.config import cfg - -from neutron.plugins.hyperv.agent import utils -from neutron.plugins.hyperv.agent import utilsfactory -from neutron.plugins.hyperv.agent import utilsv2 -from neutron.tests import base - -CONF = cfg.CONF - - -class TestHyperVUtilsFactory(base.BaseTestCase): - - def test_get_hypervutils_v2_r2(self): - self._test_returned_class(utilsv2.HyperVUtilsV2R2, True, '6.3.0') - - def test_get_hypervutils_v2(self): - self._test_returned_class(utilsv2.HyperVUtilsV2, False, '6.2.0') - - def test_get_hypervutils_v1_old_version(self): - self._test_returned_class(utils.HyperVUtils, False, '6.1.0') - - def test_get_hypervutils_v1_forced(self): - self._test_returned_class(utils.HyperVUtils, True, '6.2.0') - - def _test_returned_class(self, expected_class, force_v1, os_version): - CONF.hyperv.force_hyperv_utils_v1 = force_v1 - utilsfactory._get_windows_version = mock.MagicMock( - return_value=os_version) - actual_class = type(utilsfactory.get_hypervutils()) - self.assertEqual(actual_class, expected_class) diff --git a/neutron/tests/unit/hyperv/test_hyperv_utilsv2.py b/neutron/tests/unit/hyperv/test_hyperv_utilsv2.py deleted file mode 100644 index c020f16e0..000000000 --- a/neutron/tests/unit/hyperv/test_hyperv_utilsv2.py +++ /dev/null @@ -1,519 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Cloudbase Solutions SRL -# All Rights Reserved. -# -# 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. -# @author: Alessandro Pilotti, Cloudbase Solutions Srl - -""" -Unit tests for the Hyper-V utils V2. -""" - -import mock - -from neutron.plugins.hyperv.agent import utils -from neutron.plugins.hyperv.agent import utilsv2 -from neutron.tests import base - - -class TestHyperVUtilsV2(base.BaseTestCase): - - _FAKE_VSWITCH_NAME = "fake_vswitch_name" - _FAKE_PORT_NAME = "fake_port_name" - _FAKE_JOB_PATH = 'fake_job_path' - _FAKE_RET_VAL = 0 - _FAKE_VM_PATH = "fake_vm_path" - _FAKE_RES_DATA = "fake_res_data" - _FAKE_RES_PATH = "fake_res_path" - _FAKE_VSWITCH = "fake_vswitch" - _FAKE_VLAN_ID = "fake_vlan_id" - _FAKE_CLASS_NAME = "fake_class_name" - _FAKE_ELEMENT_NAME = "fake_element_name" - _FAKE_HYPERV_VM_STATE = 'fake_hyperv_state' - - _FAKE_ACL_ACT = 'fake_acl_action' - _FAKE_ACL_DIR = 'fake_acl_dir' - _FAKE_ACL_TYPE = 'fake_acl_type' - _FAKE_LOCAL_PORT = 'fake_local_port' - _FAKE_PROTOCOL = 'fake_port_protocol' - _FAKE_REMOTE_ADDR = '0.0.0.0/0' - _FAKE_WEIGHT = 'fake_weight' - - def setUp(self): - super(TestHyperVUtilsV2, self).setUp() - self._utils = utilsv2.HyperVUtilsV2() - self._utils._wmi_conn = mock.MagicMock() - - def test_connect_vnic_to_vswitch_found(self): - self._test_connect_vnic_to_vswitch(True) - - def test_connect_vnic_to_vswitch_not_found(self): - self._test_connect_vnic_to_vswitch(False) - - def _test_connect_vnic_to_vswitch(self, found): - self._utils._get_vnic_settings = mock.MagicMock() - - if not found: - mock_vm = mock.MagicMock() - self._utils._get_vm_from_res_setting_data = mock.MagicMock( - return_value=mock_vm) - self._utils._add_virt_resource = mock.MagicMock() - else: - self._utils._modify_virt_resource = mock.MagicMock() - - self._utils._get_vswitch = mock.MagicMock() - self._utils._get_switch_port_allocation = mock.MagicMock() - - mock_port = mock.MagicMock() - self._utils._get_switch_port_allocation.return_value = (mock_port, - found) - - self._utils.connect_vnic_to_vswitch(self._FAKE_VSWITCH_NAME, - self._FAKE_PORT_NAME) - - if not found: - self._utils._add_virt_resource.assert_called_with(mock_vm, - mock_port) - else: - self._utils._modify_virt_resource.assert_called_with(mock_port) - - def test_add_virt_resource(self): - self._test_virt_method('AddResourceSettings', 3, '_add_virt_resource', - True, self._FAKE_VM_PATH, [self._FAKE_RES_DATA]) - - def test_add_virt_feature(self): - self._test_virt_method('AddFeatureSettings', 3, '_add_virt_feature', - True, self._FAKE_VM_PATH, [self._FAKE_RES_DATA]) - - def test_modify_virt_resource(self): - self._test_virt_method('ModifyResourceSettings', 3, - '_modify_virt_resource', False, - ResourceSettings=[self._FAKE_RES_DATA]) - - def test_remove_virt_resource(self): - self._test_virt_method('RemoveResourceSettings', 2, - '_remove_virt_resource', False, - ResourceSettings=[self._FAKE_RES_PATH]) - - def test_remove_virt_feature(self): - self._test_virt_method('RemoveFeatureSettings', 2, - '_remove_virt_feature', False, - FeatureSettings=[self._FAKE_RES_PATH]) - - def _test_virt_method(self, vsms_method_name, return_count, - utils_method_name, with_mock_vm, *args, **kwargs): - mock_svc = self._utils._conn.Msvm_VirtualSystemManagementService()[0] - vsms_method = getattr(mock_svc, vsms_method_name) - mock_rsd = self._mock_vsms_method(vsms_method, return_count) - if with_mock_vm: - mock_vm = mock.MagicMock() - mock_vm.path_.return_value = self._FAKE_VM_PATH - getattr(self._utils, utils_method_name)(mock_vm, mock_rsd) - else: - getattr(self._utils, utils_method_name)(mock_rsd) - - if args: - vsms_method.assert_called_once_with(*args) - else: - vsms_method.assert_called_once_with(**kwargs) - - def _mock_vsms_method(self, vsms_method, return_count): - args = None - if return_count == 3: - args = (self._FAKE_JOB_PATH, mock.MagicMock(), self._FAKE_RET_VAL) - else: - args = (self._FAKE_JOB_PATH, self._FAKE_RET_VAL) - - vsms_method.return_value = args - mock_res_setting_data = mock.MagicMock() - mock_res_setting_data.GetText_.return_value = self._FAKE_RES_DATA - mock_res_setting_data.path_.return_value = self._FAKE_RES_PATH - - self._utils._check_job_status = mock.MagicMock() - - return mock_res_setting_data - - def test_disconnect_switch_port_delete_port(self): - self._test_disconnect_switch_port(True) - - def test_disconnect_switch_port_modify_port(self): - self._test_disconnect_switch_port(False) - - def _test_disconnect_switch_port(self, delete_port): - self._utils._get_switch_port_allocation = mock.MagicMock() - - mock_sw_port = mock.MagicMock() - self._utils._get_switch_port_allocation.return_value = (mock_sw_port, - True) - - if delete_port: - self._utils._remove_virt_resource = mock.MagicMock() - else: - self._utils._modify_virt_resource = mock.MagicMock() - - self._utils.disconnect_switch_port(self._FAKE_VSWITCH_NAME, - self._FAKE_PORT_NAME, - delete_port) - - if delete_port: - self._utils._remove_virt_resource.assert_called_with(mock_sw_port) - else: - self._utils._modify_virt_resource.assert_called_with(mock_sw_port) - - def test_get_vswitch(self): - self._utils._conn.Msvm_VirtualEthernetSwitch.return_value = [ - self._FAKE_VSWITCH] - vswitch = self._utils._get_vswitch(self._FAKE_VSWITCH_NAME) - - self.assertEqual(self._FAKE_VSWITCH, vswitch) - - def test_get_vswitch_not_found(self): - self._utils._conn.Msvm_VirtualEthernetSwitch.return_value = [] - self.assertRaises(utils.HyperVException, self._utils._get_vswitch, - self._FAKE_VSWITCH_NAME) - - def test_get_vswitch_external_port(self): - mock_vswitch = mock.MagicMock() - mock_sw_port = mock.MagicMock() - mock_vswitch.associators.return_value = [mock_sw_port] - mock_le = mock_sw_port.associators.return_value - mock_le.__len__.return_value = 1 - mock_le1 = mock_le[0].associators.return_value - mock_le1.__len__.return_value = 1 - - vswitch_port = self._utils._get_vswitch_external_port(mock_vswitch) - - self.assertEqual(mock_sw_port, vswitch_port) - - def test_set_vswitch_port_vlan_id(self): - mock_port_alloc = mock.MagicMock() - self._utils._get_switch_port_allocation = mock.MagicMock(return_value=( - mock_port_alloc, True)) - self._utils._get_vlan_setting_data_from_port_alloc = mock.MagicMock() - - mock_svc = self._utils._conn.Msvm_VirtualSystemManagementService()[0] - mock_svc.RemoveFeatureSettings.return_value = (self._FAKE_JOB_PATH, - self._FAKE_RET_VAL) - mock_vlan_settings = mock.MagicMock() - self._utils._get_vlan_setting_data = mock.MagicMock(return_value=( - mock_vlan_settings, True)) - - mock_svc.AddFeatureSettings.return_value = (self._FAKE_JOB_PATH, - None, - self._FAKE_RET_VAL) - - self._utils.set_vswitch_port_vlan_id(self._FAKE_VLAN_ID, - self._FAKE_PORT_NAME) - - self.assertTrue(mock_svc.RemoveFeatureSettings.called) - self.assertTrue(mock_svc.AddFeatureSettings.called) - - def test_get_setting_data(self): - self._utils._get_first_item = mock.MagicMock(return_value=None) - - mock_data = mock.MagicMock() - self._utils._get_default_setting_data = mock.MagicMock( - return_value=mock_data) - - ret_val = self._utils._get_setting_data(self._FAKE_CLASS_NAME, - self._FAKE_ELEMENT_NAME, - True) - - self.assertEqual(ret_val, (mock_data, False)) - - def test_enable_port_metrics_collection(self): - mock_port = mock.MagicMock() - self._utils._get_switch_port_allocation = mock.MagicMock(return_value=( - mock_port, True)) - - mock_acl = mock.MagicMock() - - with mock.patch.multiple( - self._utils, - _get_default_setting_data=mock.MagicMock(return_value=mock_acl), - _add_virt_feature=mock.MagicMock()): - - self._utils.enable_port_metrics_collection(self._FAKE_PORT_NAME) - - self.assertEqual(4, len(self._utils._add_virt_feature.mock_calls)) - self._utils._add_virt_feature.assert_called_with( - mock_port, mock_acl) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._get_switch_port_allocation') - def test_enable_control_metrics_ok(self, mock_get_port_allocation): - mock_metrics_svc = self._utils._conn.Msvm_MetricService()[0] - mock_metrics_def_source = self._utils._conn.CIM_BaseMetricDefinition - mock_metric_def = mock.MagicMock() - mock_port = mock.MagicMock() - mock_get_port_allocation.return_value = (mock_port, True) - - mock_metrics_def_source.return_value = [mock_metric_def] - m_call = mock.call(Subject=mock_port.path_.return_value, - Definition=mock_metric_def.path_.return_value, - MetricCollectionEnabled=self._utils._METRIC_ENABLED) - - self._utils.enable_control_metrics(self._FAKE_PORT_NAME) - - mock_metrics_svc.ControlMetrics.assert_has_calls([m_call, m_call]) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._get_switch_port_allocation') - def test_enable_control_metrics_no_port(self, mock_get_port_allocation): - mock_metrics_svc = self._utils._conn.Msvm_MetricService()[0] - mock_get_port_allocation.return_value = (None, False) - - self._utils.enable_control_metrics(self._FAKE_PORT_NAME) - self.assertEqual(0, mock_metrics_svc.ControlMetrics.call_count) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._get_switch_port_allocation') - def test_enable_control_metrics_no_def(self, mock_get_port_allocation): - mock_metrics_svc = self._utils._conn.Msvm_MetricService()[0] - mock_metrics_def_source = self._utils._conn.CIM_BaseMetricDefinition - mock_port = mock.MagicMock() - - mock_get_port_allocation.return_value = (mock_port, True) - mock_metrics_def_source.return_value = None - - self._utils.enable_control_metrics(self._FAKE_PORT_NAME) - self.assertEqual(0, mock_metrics_svc.ControlMetrics.call_count) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._is_port_vm_started') - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._get_switch_port_allocation') - def test_can_enable_control_metrics_true(self, mock_get, mock_is_started): - mock_acl = mock.MagicMock() - mock_acl.Action = self._utils._ACL_ACTION_METER - self._test_can_enable_control_metrics(mock_get, mock_is_started, - [mock_acl, mock_acl], True) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._is_port_vm_started') - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._get_switch_port_allocation') - def test_can_enable_control_metrics_false(self, mock_get, mock_is_started): - self._test_can_enable_control_metrics(mock_get, mock_is_started, [], - False) - - def _test_can_enable_control_metrics(self, mock_get_port, mock_vm_started, - acls, expected_result): - mock_port = mock.MagicMock() - mock_acl = mock.MagicMock() - mock_acl.Action = self._utils._ACL_ACTION_METER - - mock_port.associators.return_value = acls - mock_get_port.return_value = (mock_port, True) - mock_vm_started.return_value = True - - result = self._utils.can_enable_control_metrics(self._FAKE_PORT_NAME) - self.assertEqual(expected_result, result) - - def test_is_port_vm_started_true(self): - self._test_is_port_vm_started(self._utils._HYPERV_VM_STATE_ENABLED, - True) - - def test_is_port_vm_started_false(self): - self._test_is_port_vm_started(self._FAKE_HYPERV_VM_STATE, False) - - def _test_is_port_vm_started(self, vm_state, expected_result): - mock_svc = self._utils._conn.Msvm_VirtualSystemManagementService()[0] - mock_port = mock.MagicMock() - mock_vmsettings = mock.MagicMock() - mock_summary = mock.MagicMock() - mock_summary.EnabledState = vm_state - mock_vmsettings.path_.return_value = self._FAKE_RES_PATH - - mock_port.associators.return_value = [mock_vmsettings] - mock_svc.GetSummaryInformation.return_value = (self._FAKE_RET_VAL, - [mock_summary]) - - result = self._utils._is_port_vm_started(mock_port) - self.assertEqual(expected_result, result) - mock_svc.GetSummaryInformation.assert_called_once_with( - [self._utils._VM_SUMMARY_ENABLED_STATE], - [self._FAKE_RES_PATH]) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._remove_virt_feature') - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._bind_security_rule') - def test_create_default_reject_all_rules(self, mock_bind, mock_remove): - (m_port, m_acl) = self._setup_security_rule_test() - m_acl.Action = self._utils._ACL_ACTION_DENY - self._utils.create_default_reject_all_rules(self._FAKE_PORT_NAME) - - calls = [] - ipv4_pair = (self._utils._ACL_TYPE_IPV4, self._utils._IPV4_ANY) - ipv6_pair = (self._utils._ACL_TYPE_IPV6, self._utils._IPV6_ANY) - for direction in [self._utils._ACL_DIR_IN, self._utils._ACL_DIR_OUT]: - for acl_type, address in [ipv4_pair, ipv6_pair]: - for protocol in [self._utils._TCP_PROTOCOL, - self._utils._UDP_PROTOCOL, - self._utils._ICMP_PROTOCOL]: - calls.append(mock.call(m_port, direction, acl_type, - self._utils._ACL_ACTION_DENY, - self._utils._ACL_DEFAULT, - protocol, address, mock.ANY)) - - self._utils._remove_virt_feature.assert_called_once_with(m_acl) - self._utils._bind_security_rule.assert_has_calls(calls) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._remove_virt_feature') - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._bind_security_rule') - def test_create_default_reject_all_rules_already_added(self, mock_bind, - mock_remove): - (m_port, m_acl) = self._setup_security_rule_test() - m_acl.Action = self._utils._ACL_ACTION_DENY - m_port.associators.return_value = [ - m_acl] * self._utils._REJECT_ACLS_COUNT - self._utils.create_default_reject_all_rules(self._FAKE_PORT_NAME) - - self.assertFalse(self._utils._remove_virt_feature.called) - self.assertFalse(self._utils._bind_security_rule.called) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._remove_virt_feature') - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._add_virt_feature') - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._create_security_acl') - def test_bind_security_rule(self, mock_create_acl, mock_add, mock_remove): - (m_port, m_acl) = self._setup_security_rule_test() - mock_create_acl.return_value = m_acl - - self._utils._bind_security_rule( - m_port, self._FAKE_ACL_DIR, self._FAKE_ACL_TYPE, - self._FAKE_ACL_ACT, self._FAKE_LOCAL_PORT, self._FAKE_PROTOCOL, - self._FAKE_REMOTE_ADDR, self._FAKE_WEIGHT) - - self._utils._add_virt_feature.assert_called_once_with(m_port, m_acl) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._remove_virt_feature') - def test_remove_security_rule(self, mock_remove_feature): - mock_acl = self._setup_security_rule_test()[1] - self._utils.remove_security_rule( - self._FAKE_PORT_NAME, self._FAKE_ACL_DIR, self._FAKE_ACL_TYPE, - self._FAKE_LOCAL_PORT, self._FAKE_PROTOCOL, self._FAKE_REMOTE_ADDR) - self._utils._remove_virt_feature.assert_called_once_with(mock_acl) - - @mock.patch('neutron.plugins.hyperv.agent.utilsv2.HyperVUtilsV2' - '._remove_multiple_virt_features') - def test_remove_all_security_rules(self, mock_remove_feature): - mock_acl = self._setup_security_rule_test()[1] - self._utils.remove_all_security_rules(self._FAKE_PORT_NAME) - self._utils._remove_multiple_virt_features.assert_called_once_with( - [mock_acl]) - - def _setup_security_rule_test(self): - mock_port = mock.MagicMock() - mock_acl = mock.MagicMock() - mock_port.associators.return_value = [mock_acl] - - self._utils._get_switch_port_allocation = mock.MagicMock(return_value=( - mock_port, True)) - self._utils._filter_security_acls = mock.MagicMock( - return_value=[mock_acl]) - - return (mock_port, mock_acl) - - def test_filter_acls(self): - mock_acl = mock.MagicMock() - mock_acl.Action = self._FAKE_ACL_ACT - mock_acl.Applicability = self._utils._ACL_APPLICABILITY_LOCAL - mock_acl.Direction = self._FAKE_ACL_DIR - mock_acl.AclType = self._FAKE_ACL_TYPE - mock_acl.RemoteAddress = self._FAKE_REMOTE_ADDR - - acls = [mock_acl, mock_acl] - good_acls = self._utils._filter_acls( - acls, self._FAKE_ACL_ACT, self._FAKE_ACL_DIR, - self._FAKE_ACL_TYPE, self._FAKE_REMOTE_ADDR) - bad_acls = self._utils._filter_acls( - acls, self._FAKE_ACL_ACT, self._FAKE_ACL_DIR, self._FAKE_ACL_TYPE) - - self.assertEqual(acls, good_acls) - self.assertEqual([], bad_acls) - - -class TestHyperVUtilsV2R2(base.BaseTestCase): - _FAKE_ACL_ACT = 'fake_acl_action' - _FAKE_ACL_DIR = 'fake_direction' - _FAKE_ACL_TYPE = 'fake_acl_type' - _FAKE_LOCAL_PORT = 'fake_local_port' - _FAKE_PROTOCOL = 'fake_port_protocol' - _FAKE_REMOTE_ADDR = '10.0.0.0/0' - - def setUp(self): - super(TestHyperVUtilsV2R2, self).setUp() - self._utils = utilsv2.HyperVUtilsV2R2() - - def test_filter_security_acls(self): - self._test_filter_security_acls( - self._FAKE_LOCAL_PORT, self._FAKE_PROTOCOL, self._FAKE_REMOTE_ADDR) - - def test_filter_security_acls_default(self): - default = self._utils._ACL_DEFAULT - self._test_filter_security_acls( - default, default, self._FAKE_REMOTE_ADDR) - - def _test_filter_security_acls(self, local_port, protocol, remote_addr): - acls = [] - default = self._utils._ACL_DEFAULT - for port, proto in [(default, default), (local_port, protocol)]: - mock_acl = mock.MagicMock() - mock_acl.Action = self._utils._ACL_ACTION_ALLOW - mock_acl.Direction = self._FAKE_ACL_DIR - mock_acl.LocalPort = port - mock_acl.Protocol = proto - mock_acl.RemoteIPAddress = remote_addr - acls.append(mock_acl) - - right_acls = [a for a in acls if a.LocalPort == local_port] - - good_acls = self._utils._filter_security_acls( - acls, mock_acl.Action, self._FAKE_ACL_DIR, self._FAKE_ACL_TYPE, - local_port, protocol, remote_addr) - bad_acls = self._utils._filter_security_acls( - acls, self._FAKE_ACL_ACT, self._FAKE_ACL_DIR, self._FAKE_ACL_TYPE, - local_port, protocol, remote_addr) - - self.assertEqual(right_acls, good_acls) - self.assertEqual([], bad_acls) - - def test_get_new_weight(self): - mockacl1 = mock.MagicMock() - mockacl1.Weight = self._utils._MAX_WEIGHT - 1 - mockacl2 = mock.MagicMock() - mockacl2.Weight = self._utils._MAX_WEIGHT - 3 - self.assertEqual(self._utils._MAX_WEIGHT - 2, - self._utils._get_new_weight([mockacl1, mockacl2])) - - def test_get_new_weight_no_acls(self): - self.assertEqual(self._utils._MAX_WEIGHT - 1, - self._utils._get_new_weight([])) - - def test_get_new_weight_default_acls(self): - mockacl1 = mock.MagicMock() - mockacl1.Weight = self._utils._MAX_WEIGHT - 1 - mockacl2 = mock.MagicMock() - mockacl2.Weight = self._utils._MAX_WEIGHT - 2 - mockacl2.Action = self._utils._ACL_ACTION_DENY - - self.assertEqual(self._utils._MAX_WEIGHT - 2, - self._utils._get_new_weight([mockacl1, mockacl2])) diff --git a/neutron/tests/unit/ibm/__init__.py b/neutron/tests/unit/ibm/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/ibm/test_sdnve_agent.py b/neutron/tests/unit/ibm/test_sdnve_agent.py deleted file mode 100644 index 3b33d901e..000000000 --- a/neutron/tests/unit/ibm/test_sdnve_agent.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# All Rights Reserved. -# -# 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. -# -# @author: Mohammad Banikazemi, IBM Corp - - -import contextlib - -import mock -from oslo.config import cfg - -from neutron.agent.linux import ip_lib -from neutron.plugins.ibm.agent import sdnve_neutron_agent -from neutron.tests import base - - -NOTIFIER = ('neutron.plugins.ibm.' - 'sdnve_neutron_plugin.AgentNotifierApi') - - -class CreateAgentConfigMap(base.BaseTestCase): - - def test_create_agent_config_map_succeeds(self): - self.assertTrue(sdnve_neutron_agent.create_agent_config_map(cfg.CONF)) - - def test_create_agent_config_using_controller_ips(self): - cfg.CONF.set_override('controller_ips', - ['10.10.10.1', '10.10.10.2'], group='SDNVE') - cfgmap = sdnve_neutron_agent.create_agent_config_map(cfg.CONF) - self.assertEqual(cfgmap['controller_ip'], '10.10.10.1') - - def test_create_agent_config_using_interface_mappings(self): - cfg.CONF.set_override('interface_mappings', - ['interface1 : eth1', 'interface2 : eth2'], - group='SDNVE') - cfgmap = sdnve_neutron_agent.create_agent_config_map(cfg.CONF) - self.assertEqual(cfgmap['interface_mappings'], - {'interface1': 'eth1', 'interface2': 'eth2'}) - - -class TestSdnveNeutronAgent(base.BaseTestCase): - - def setUp(self): - super(TestSdnveNeutronAgent, self).setUp() - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - # Avoid rpc initialization for unit tests - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - cfg.CONF.set_override('integration_bridge', - 'br_int', group='SDNVE') - kwargs = sdnve_neutron_agent.create_agent_config_map(cfg.CONF) - - class MockFixedIntervalLoopingCall(object): - def __init__(self, f): - self.f = f - - def start(self, interval=0): - self.f() - - with contextlib.nested( - mock.patch('neutron.plugins.ibm.agent.sdnve_neutron_agent.' - 'SdnveNeutronAgent.setup_integration_br', - return_value=mock.Mock()), - mock.patch('neutron.openstack.common.loopingcall.' - 'FixedIntervalLoopingCall', - new=MockFixedIntervalLoopingCall)): - self.agent = sdnve_neutron_agent.SdnveNeutronAgent(**kwargs) - - def test_setup_physical_interfaces(self): - with mock.patch.object(self.agent.int_br, - 'add_port') as add_port_func: - with mock.patch.object(ip_lib, - 'device_exists', - return_valxue=True): - self.agent.setup_physical_interfaces({"interface1": "eth1"}) - add_port_func.assert_called_once_with('eth1') - - def test_setup_physical_interfaces_none(self): - with mock.patch.object(self.agent.int_br, - 'add_port') as add_port_func: - with mock.patch.object(ip_lib, - 'device_exists', - return_valxue=True): - self.agent.setup_physical_interfaces({}) - self.assertFalse(add_port_func.called) - - def test_get_info_set_controller(self): - with mock.patch.object(self.agent.int_br, - 'run_vsctl') as run_vsctl_func: - kwargs = {} - kwargs['info'] = {'new_controller': '10.10.10.1'} - self.agent.info_update('dummy', **kwargs) - run_vsctl_func.assert_called_once_with(['set-controller', - 'br_int', - 'tcp:10.10.10.1']) - - def test_get_info(self): - with mock.patch.object(self.agent.int_br, - 'run_vsctl') as run_vsctl_func: - kwargs = {} - self.agent.info_update('dummy', **kwargs) - self.assertFalse(run_vsctl_func.called) diff --git a/neutron/tests/unit/ibm/test_sdnve_api.py b/neutron/tests/unit/ibm/test_sdnve_api.py deleted file mode 100644 index f1f8d60b8..000000000 --- a/neutron/tests/unit/ibm/test_sdnve_api.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# All Rights Reserved. -# -# 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. -# -# @author: Mohammad Banikazemi, IBM Corp - - -import mock - -from neutron.openstack.common import uuidutils -from neutron.plugins.ibm.common import constants -from neutron.plugins.ibm import sdnve_api -from neutron.tests import base - -RESOURCE_PATH = { - 'network': "ln/networks/", -} -RESOURCE = 'network' -HTTP_OK = 200 -TENANT_ID = uuidutils.generate_uuid() - - -class TestSdnveApi(base.BaseTestCase): - - def setUp(self): - super(TestSdnveApi, self).setUp() - - class MockKeystoneClient(object): - def __init__(self, **kwargs): - pass - - def get_tenant_name(self, id): - return 'test tenant name' - - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'KeystoneClient', - new=MockKeystoneClient): - self.api = sdnve_api.Client() - - def mock_do_request(self, method, url, body=None, headers=None, - params=None, connection_type=None): - return (HTTP_OK, url) - - def mock_do_request_tenant(self, method, url, body=None, headers=None, - params=None, connection_type=None): - return (HTTP_OK, {'id': TENANT_ID, - 'network_type': constants.TENANT_TYPE_OF}) - - def mock_do_request_no_tenant(self, method, url, body=None, headers=None, - params=None, connection_type=None): - return (None, None) - - def mock_process_request(self, body): - return body - - def test_sdnve_api_list(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - result = self.api.sdnve_list(RESOURCE) - self.assertEqual(result, (HTTP_OK, RESOURCE_PATH[RESOURCE])) - - def test_sdnve_api_show(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - result = self.api.sdnve_show(RESOURCE, TENANT_ID) - self.assertEqual(result, - (HTTP_OK, RESOURCE_PATH[RESOURCE] + TENANT_ID)) - - def test_sdnve_api_create(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.process_request', - new=self.mock_process_request): - result = self.api.sdnve_create(RESOURCE, '') - self.assertEqual(result, (HTTP_OK, RESOURCE_PATH[RESOURCE])) - - def test_sdnve_api_update(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.process_request', - new=self.mock_process_request): - result = self.api.sdnve_update(RESOURCE, TENANT_ID, '') - self.assertEqual(result, - (HTTP_OK, - RESOURCE_PATH[RESOURCE] + TENANT_ID)) - - def test_sdnve_api_delete(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - result = self.api.sdnve_delete(RESOURCE, TENANT_ID) - self.assertEqual(result, - (HTTP_OK, RESOURCE_PATH[RESOURCE] + TENANT_ID)) - - def test_sdnve_get_tenant_by_id(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request_tenant): - id = TENANT_ID - result = self.api.sdnve_get_tenant_byid(id) - self.assertEqual(result, - (TENANT_ID, constants.TENANT_TYPE_OF)) - - def test_sdnve_check_and_create_tenant(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request_tenant): - id = TENANT_ID - result = self.api.sdnve_check_and_create_tenant(id) - self.assertEqual(result, TENANT_ID) - - def test_sdnve_check_and_create_tenant_fail(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request_no_tenant): - id = TENANT_ID - result = self.api.sdnve_check_and_create_tenant( - id, constants.TENANT_TYPE_OF) - self.assertIsNone(result) - - def test_process_request(self): - my_request = {'key_1': 'value_1', 'router:external': 'True', - 'key_2': 'value_2'} - expected = {'key_1': 'value_1', 'router_external': 'True', - 'key_2': 'value_2'} - result = self.api.process_request(my_request) - self.assertEqual(expected, result) diff --git a/neutron/tests/unit/ibm/test_sdnve_plugin.py b/neutron/tests/unit/ibm/test_sdnve_plugin.py deleted file mode 100644 index 4e4c967cc..000000000 --- a/neutron/tests/unit/ibm/test_sdnve_plugin.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# All Rights Reserved. -# -# 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. -# -# @author: Mohammad Banikazemi, IBM Corp - - -import contextlib -import mock - -from neutron.extensions import portbindings -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_l3_plugin as test_l3_plugin - -from neutron.plugins.ibm.common import constants - - -_plugin_name = ('neutron.plugins.ibm.' - 'sdnve_neutron_plugin.SdnvePluginV2') -HTTP_OK = 200 - - -class MockClient(object): - def sdnve_list(self, resource, **params): - return (HTTP_OK, 'body') - - def sdnve_show(self, resource, specific, **params): - return (HTTP_OK, 'body') - - def sdnve_create(self, resource, body): - return (HTTP_OK, 'body') - - def sdnve_update(self, resource, specific, body=None): - return (HTTP_OK, 'body') - - def sdnve_delete(self, resource, specific): - return (HTTP_OK, 'body') - - def sdnve_get_tenant_byid(self, os_tenant_id): - return (os_tenant_id, constants.TENANT_TYPE_OF) - - def sdnve_check_and_create_tenant( - self, os_tenant_id, network_type=None): - return os_tenant_id - - def sdnve_get_controller(self): - return - - -class MockKeystoneClient(object): - def __init__(self, **kwargs): - pass - - def get_tenant_type(self, id): - return constants.TENANT_TYPE_OF - - def get_tenant_name(self, id): - return "tenant name" - - -class IBMPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - def setUp(self): - with contextlib.nested( - mock.patch('neutron.plugins.ibm.sdnve_api.' - 'KeystoneClient', - new=MockKeystoneClient), - mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client', - new=MockClient)): - super(IBMPluginV2TestCase, self).setUp(plugin=_plugin_name) - - -class TestIBMBasicGet(test_plugin.TestBasicGet, - IBMPluginV2TestCase): - pass - - -class TestIBMV2HTTPResponse(test_plugin.TestV2HTTPResponse, - IBMPluginV2TestCase): - pass - - -class TestIBMNetworksV2(test_plugin.TestNetworksV2, - IBMPluginV2TestCase): - pass - - -class TestIBMPortsV2(test_plugin.TestPortsV2, - IBMPluginV2TestCase): - pass - - -class TestIBMSubnetsV2(test_plugin.TestSubnetsV2, - IBMPluginV2TestCase): - pass - - -class TestIBMPortBinding(IBMPluginV2TestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - - -class IBMPluginRouterTestCase(test_l3_plugin.L3NatDBIntTestCase): - - def setUp(self): - with contextlib.nested( - mock.patch('neutron.plugins.ibm.sdnve_api.' - 'KeystoneClient', - new=MockKeystoneClient), - mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client', - new=MockClient)): - super(IBMPluginRouterTestCase, self).setUp(plugin=_plugin_name) diff --git a/neutron/tests/unit/linuxbridge/__init__.py b/neutron/tests/unit/linuxbridge/__init__.py deleted file mode 100644 index 7e503debd..000000000 --- a/neutron/tests/unit/linuxbridge/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/linuxbridge/test_agent_scheduler.py b/neutron/tests/unit/linuxbridge/test_agent_scheduler.py deleted file mode 100644 index 397baaf5c..000000000 --- a/neutron/tests/unit/linuxbridge/test_agent_scheduler.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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. - -from neutron.tests.unit.linuxbridge import test_linuxbridge_plugin -from neutron.tests.unit.openvswitch import test_agent_scheduler - - -class LbAgentSchedulerTestCase( - test_agent_scheduler.OvsAgentSchedulerTestCase): - plugin_str = test_linuxbridge_plugin.PLUGIN_NAME - l3_plugin = None - - -class LbL3AgentNotifierTestCase( - test_agent_scheduler.OvsL3AgentNotifierTestCase): - plugin_str = test_linuxbridge_plugin.PLUGIN_NAME - l3_plugin = None - - -class LbDhcpAgentNotifierTestCase( - test_agent_scheduler.OvsDhcpAgentNotifierTestCase): - plugin_str = test_linuxbridge_plugin.PLUGIN_NAME diff --git a/neutron/tests/unit/linuxbridge/test_defaults.py b/neutron/tests/unit/linuxbridge/test_defaults.py deleted file mode 100644 index 1c395e81d..000000000 --- a/neutron/tests/unit/linuxbridge/test_defaults.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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. - -from oslo.config import cfg - -from neutron.plugins.linuxbridge.common import config # noqa -from neutron.tests import base - - -class ConfigurationTest(base.BaseTestCase): - - def test_defaults(self): - self.assertEqual(2, - cfg.CONF.AGENT.polling_interval) - self.assertEqual(False, - cfg.CONF.AGENT.rpc_support_old_agents) - self.assertEqual('sudo', - cfg.CONF.AGENT.root_helper) - self.assertEqual('local', - cfg.CONF.VLANS.tenant_network_type) - self.assertEqual(0, - len(cfg.CONF.VLANS.network_vlan_ranges)) - self.assertEqual(0, - len(cfg.CONF.LINUX_BRIDGE. - physical_interface_mappings)) - self.assertEqual(False, cfg.CONF.VXLAN.enable_vxlan) - self.assertEqual(config.DEFAULT_VXLAN_GROUP, - cfg.CONF.VXLAN.vxlan_group) - self.assertEqual(0, len(cfg.CONF.VXLAN.local_ip)) - self.assertEqual(False, cfg.CONF.VXLAN.l2_population) diff --git a/neutron/tests/unit/linuxbridge/test_lb_db.py b/neutron/tests/unit/linuxbridge/test_lb_db.py deleted file mode 100644 index 41f56b52e..000000000 --- a/neutron/tests/unit/linuxbridge/test_lb_db.py +++ /dev/null @@ -1,172 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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. - -from oslo.config import cfg -from six import moves -import testtools -from testtools import matchers - -from neutron.common import exceptions as n_exc -from neutron.db import api as db -from neutron.plugins.linuxbridge.db import l2network_db_v2 as lb_db -from neutron.tests import base -from neutron.tests.unit import test_db_plugin as test_plugin - -PHYS_NET = 'physnet1' -PHYS_NET_2 = 'physnet2' -VLAN_MIN = 10 -VLAN_MAX = 19 -VLAN_RANGES = {PHYS_NET: [(VLAN_MIN, VLAN_MAX)]} -UPDATED_VLAN_RANGES = {PHYS_NET: [(VLAN_MIN + 5, VLAN_MAX + 5)], - PHYS_NET_2: [(VLAN_MIN + 20, VLAN_MAX + 20)]} - -PLUGIN_NAME = ('neutron.plugins.linuxbridge.' - 'lb_neutron_plugin.LinuxBridgePluginV2') - - -class NetworkStatesTest(base.BaseTestCase): - def setUp(self): - super(NetworkStatesTest, self).setUp() - db.configure_db() - lb_db.sync_network_states(VLAN_RANGES) - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_sync_network_states(self): - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MIN - 1)) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX - 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX).allocated) - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 1)) - - lb_db.sync_network_states(UPDATED_VLAN_RANGES) - - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 5 - 1)) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 5).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 5 + 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 5 - 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 5).allocated) - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 5 + 1)) - - self.assertIsNone(lb_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20 - 1)) - self.assertFalse(lb_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20 + 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20 - 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20).allocated) - self.assertIsNone(lb_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20 + 1)) - - lb_db.sync_network_states(VLAN_RANGES) - - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MIN - 1)) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX - 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX).allocated) - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 1)) - - self.assertIsNone(lb_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20)) - self.assertIsNone(lb_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20)) - - def test_network_pool(self): - vlan_ids = set() - for x in moves.xrange(VLAN_MIN, VLAN_MAX + 1): - physical_network, vlan_id = lb_db.reserve_network(self.session) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - with testtools.ExpectedException(n_exc.NoNetworkAvailable): - physical_network, vlan_id = lb_db.reserve_network(self.session) - - for vlan_id in vlan_ids: - lb_db.release_network(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - - def test_specific_network_inside_pool(self): - vlan_id = VLAN_MIN + 5 - self.assertFalse(lb_db.get_network_state(PHYS_NET, - vlan_id).allocated) - lb_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - self.assertTrue(lb_db.get_network_state(PHYS_NET, - vlan_id).allocated) - - with testtools.ExpectedException(n_exc.VlanIdInUse): - lb_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - - lb_db.release_network(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - vlan_id).allocated) - - def test_specific_network_outside_pool(self): - vlan_id = VLAN_MAX + 5 - self.assertIsNone(lb_db.get_network_state(PHYS_NET, vlan_id)) - lb_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - self.assertTrue(lb_db.get_network_state(PHYS_NET, - vlan_id).allocated) - - with testtools.ExpectedException(n_exc.VlanIdInUse): - lb_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - - lb_db.release_network(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - self.assertIsNone(lb_db.get_network_state(PHYS_NET, vlan_id)) - - -class NetworkBindingsTest(test_plugin.NeutronDbPluginV2TestCase): - def setUp(self): - cfg.CONF.set_override('network_vlan_ranges', ['physnet1:1000:2999'], - group='VLANS') - super(NetworkBindingsTest, self).setUp(plugin=PLUGIN_NAME) - db.configure_db() - self.session = db.get_session() - - def test_add_network_binding(self): - params = {'provider:network_type': 'vlan', - 'provider:physical_network': PHYS_NET, - 'provider:segmentation_id': 1234} - params['arg_list'] = tuple(params.keys()) - with self.network(**params) as network: - TEST_NETWORK_ID = network['network']['id'] - binding = lb_db.get_network_binding(self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.physical_network, PHYS_NET) - self.assertEqual(binding.vlan_id, 1234) diff --git a/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py b/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py deleted file mode 100644 index d72b5615f..000000000 --- a/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py +++ /dev/null @@ -1,1054 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 contextlib -import os - -import mock -from oslo.config import cfg -import testtools - -from neutron.agent.linux import ip_lib -from neutron.agent.linux import utils -from neutron.common import constants -from neutron.common import exceptions -from neutron.plugins.common import constants as p_const -from neutron.plugins.linuxbridge.agent import linuxbridge_neutron_agent -from neutron.plugins.linuxbridge.common import constants as lconst -from neutron.tests import base - -LOCAL_IP = '192.168.0.33' -DEVICE_1 = 'tapabcdef01-12' - - -class FakeIpLinkCommand(object): - def set_up(self): - pass - - -class FakeIpDevice(object): - def __init__(self): - self.link = FakeIpLinkCommand() - - -class TestLinuxBridge(base.BaseTestCase): - - def setUp(self): - super(TestLinuxBridge, self).setUp() - interface_mappings = {'physnet1': 'eth1'} - root_helper = cfg.CONF.AGENT.root_helper - - self.linux_bridge = linuxbridge_neutron_agent.LinuxBridgeManager( - interface_mappings, root_helper) - - def test_ensure_physical_in_bridge_invalid(self): - result = self.linux_bridge.ensure_physical_in_bridge('network_id', - p_const.TYPE_VLAN, - 'physnetx', - 7) - self.assertFalse(result) - - def test_ensure_physical_in_bridge_flat(self): - with mock.patch.object(self.linux_bridge, - 'ensure_flat_bridge') as flat_bridge_func: - self.linux_bridge.ensure_physical_in_bridge( - 'network_id', p_const.TYPE_FLAT, 'physnet1', None) - self.assertTrue(flat_bridge_func.called) - - def test_ensure_physical_in_bridge_vlan(self): - with mock.patch.object(self.linux_bridge, - 'ensure_vlan_bridge') as vlan_bridge_func: - self.linux_bridge.ensure_physical_in_bridge( - 'network_id', p_const.TYPE_VLAN, 'physnet1', 7) - self.assertTrue(vlan_bridge_func.called) - - def test_ensure_physical_in_bridge_vxlan(self): - self.linux_bridge.vxlan_mode = lconst.VXLAN_UCAST - with mock.patch.object(self.linux_bridge, - 'ensure_vxlan_bridge') as vxlan_bridge_func: - self.linux_bridge.ensure_physical_in_bridge( - 'network_id', 'vxlan', 'physnet1', 7) - self.assertTrue(vxlan_bridge_func.called) - - -class TestLinuxBridgeAgent(base.BaseTestCase): - - LINK_SAMPLE = [ - '1: lo: mtu 16436 qdisc noqueue \\' - 'state UNKNOWN \\' - 'link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00', - '2: eth77: mtu 1500 \\' - 'qdisc mq state UP qlen 1000\ link/ether \\' - 'cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff'] - - def setUp(self): - super(TestLinuxBridgeAgent, self).setUp() - # disable setting up periodic state reporting - cfg.CONF.set_override('report_interval', 0, 'AGENT') - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - self.execute_p = mock.patch.object(ip_lib.IPWrapper, '_execute') - self.execute = self.execute_p.start() - self.execute.return_value = '\n'.join(self.LINK_SAMPLE) - self.get_mac_p = mock.patch('neutron.agent.linux.utils.' - 'get_interface_mac') - self.get_mac = self.get_mac_p.start() - self.get_mac.return_value = '00:00:00:00:00:01' - self.agent = linuxbridge_neutron_agent.LinuxBridgeNeutronAgentRPC({}, - 0, - None) - - def test_treat_devices_removed_with_existed_device(self): - agent = linuxbridge_neutron_agent.LinuxBridgeNeutronAgentRPC({}, - 0, - None) - devices = [DEVICE_1] - with contextlib.nested( - mock.patch.object(agent.plugin_rpc, "update_device_down"), - mock.patch.object(agent, "remove_devices_filter") - ) as (fn_udd, fn_rdf): - fn_udd.return_value = {'device': DEVICE_1, - 'exists': True} - with mock.patch.object(linuxbridge_neutron_agent.LOG, - 'info') as log: - resync = agent.treat_devices_removed(devices) - self.assertEqual(2, log.call_count) - self.assertFalse(resync) - self.assertTrue(fn_udd.called) - self.assertTrue(fn_rdf.called) - - def test_treat_devices_removed_with_not_existed_device(self): - agent = linuxbridge_neutron_agent.LinuxBridgeNeutronAgentRPC({}, - 0, - None) - devices = [DEVICE_1] - with contextlib.nested( - mock.patch.object(agent.plugin_rpc, "update_device_down"), - mock.patch.object(agent, "remove_devices_filter") - ) as (fn_udd, fn_rdf): - fn_udd.return_value = {'device': DEVICE_1, - 'exists': False} - with mock.patch.object(linuxbridge_neutron_agent.LOG, - 'debug') as log: - resync = agent.treat_devices_removed(devices) - self.assertEqual(1, log.call_count) - self.assertFalse(resync) - self.assertTrue(fn_udd.called) - self.assertTrue(fn_rdf.called) - - def test_treat_devices_removed_failed(self): - agent = linuxbridge_neutron_agent.LinuxBridgeNeutronAgentRPC({}, - 0, - None) - devices = [DEVICE_1] - with contextlib.nested( - mock.patch.object(agent.plugin_rpc, "update_device_down"), - mock.patch.object(agent, "remove_devices_filter") - ) as (fn_udd, fn_rdf): - fn_udd.side_effect = Exception() - with mock.patch.object(linuxbridge_neutron_agent.LOG, - 'debug') as log: - resync = agent.treat_devices_removed(devices) - self.assertEqual(2, log.call_count) - self.assertTrue(resync) - self.assertTrue(fn_udd.called) - self.assertTrue(fn_rdf.called) - - def test_loop_restores_updated_devices_on_exception(self): - agent = self.agent - agent.updated_devices = set(['tap1', 'tap2']) - - with contextlib.nested( - mock.patch.object(agent, 'scan_devices'), - mock.patch.object(linuxbridge_neutron_agent.LOG, 'info'), - mock.patch.object(agent, 'process_network_devices') - ) as (scan_devices, log, process_network_devices): - # Simulate effect of 2 port_update()s when loop is running. - # And break out of loop at start of 2nd iteration. - log.side_effect = [agent.updated_devices.add('tap3'), - agent.updated_devices.add('tap4'), - ValueError] - scan_devices.side_effect = RuntimeError - - with testtools.ExpectedException(ValueError): - agent.daemon_loop() - - # Check that the originals {tap1,tap2} have been restored - # and the new updates {tap3, tap4} have not been overwritten. - self.assertEqual(set(['tap1', 'tap2', 'tap3', 'tap4']), - agent.updated_devices) - self.assertEqual(3, log.call_count) - - def mock_scan_devices(self, expected, mock_current, - registered_devices, updated_devices): - self.agent.br_mgr = mock.Mock() - self.agent.br_mgr.get_tap_devices.return_value = mock_current - - results = self.agent.scan_devices(registered_devices, updated_devices) - self.assertEqual(expected, results) - - def test_scan_devices_returns_empty_sets(self): - registered = set() - updated = set() - mock_current = set() - expected = {'current': set(), - 'updated': set(), - 'added': set(), - 'removed': set()} - self.mock_scan_devices(expected, mock_current, registered, updated) - - def test_scan_devices_no_changes(self): - registered = set(['tap1', 'tap2']) - updated = set() - mock_current = set(['tap1', 'tap2']) - expected = {'current': set(['tap1', 'tap2']), - 'updated': set(), - 'added': set(), - 'removed': set()} - self.mock_scan_devices(expected, mock_current, registered, updated) - - def test_scan_devices_new_and_removed(self): - registered = set(['tap1', 'tap2']) - updated = set() - mock_current = set(['tap2', 'tap3']) - expected = {'current': set(['tap2', 'tap3']), - 'updated': set(), - 'added': set(['tap3']), - 'removed': set(['tap1'])} - self.mock_scan_devices(expected, mock_current, registered, updated) - - def test_scan_devices_new_updates(self): - registered = set(['tap1']) - updated = set(['tap2']) - mock_current = set(['tap1', 'tap2']) - expected = {'current': set(['tap1', 'tap2']), - 'updated': set(['tap2']), - 'added': set(['tap2']), - 'removed': set()} - self.mock_scan_devices(expected, mock_current, registered, updated) - - def test_scan_devices_updated_missing(self): - registered = set(['tap1']) - updated = set(['tap2']) - mock_current = set(['tap1']) - expected = {'current': set(['tap1']), - 'updated': set(), - 'added': set(), - 'removed': set()} - self.mock_scan_devices(expected, mock_current, registered, updated) - - def test_process_network_devices(self): - agent = self.agent - device_info = {'current': set(), - 'added': set(['tap3', 'tap4']), - 'updated': set(['tap2', 'tap3']), - 'removed': set(['tap1'])} - agent.prepare_devices_filter = mock.Mock() - agent.refresh_firewall = mock.Mock() - agent.treat_devices_added_updated = mock.Mock(return_value=False) - agent.treat_devices_removed = mock.Mock(return_value=False) - - agent.process_network_devices(device_info) - - agent.prepare_devices_filter.assert_called_with(set(['tap3', 'tap4'])) - self.assertTrue(agent.refresh_firewall.called) - agent.treat_devices_added_updated.assert_called_with(set(['tap2', - 'tap3', - 'tap4'])) - agent.treat_devices_removed.assert_called_with(set(['tap1'])) - - def test_treat_devices_added_updated_admin_state_up_true(self): - agent = self.agent - mock_details = {'port_id': 'port123', - 'network_id': 'net123', - 'admin_state_up': True, - 'network_type': 'vlan', - 'segmentation_id': 100, - 'physical_network': 'physnet1'} - agent.plugin_rpc = mock.Mock() - agent.plugin_rpc.get_device_details.return_value = mock_details - agent.br_mgr = mock.Mock() - agent.br_mgr.add_interface.return_value = True - - resync_needed = agent.treat_devices_added_updated(set(['tap1'])) - - self.assertFalse(resync_needed) - agent.br_mgr.add_interface.assert_called_with('net123', 'vlan', - 'physnet1', 100, - 'port123') - self.assertTrue(agent.plugin_rpc.update_device_up.called) - - def test_treat_devices_added_updated_admin_state_up_false(self): - mock_details = {'port_id': 'port123', - 'network_id': 'net123', - 'admin_state_up': False, - 'network_type': 'vlan', - 'segmentation_id': 100, - 'physical_network': 'physnet1'} - self.agent.plugin_rpc = mock.Mock() - self.agent.plugin_rpc.get_device_details.return_value = mock_details - self.agent.remove_port_binding = mock.Mock() - - resync_needed = self.agent.treat_devices_added_updated(set(['tap1'])) - - self.assertFalse(resync_needed) - self.agent.remove_port_binding.assert_called_with('net123', 'port123') - self.assertFalse(self.agent.plugin_rpc.update_device_up.called) - - -class TestLinuxBridgeManager(base.BaseTestCase): - def setUp(self): - super(TestLinuxBridgeManager, self).setUp() - self.interface_mappings = {'physnet1': 'eth1'} - self.root_helper = cfg.CONF.AGENT.root_helper - - self.lbm = linuxbridge_neutron_agent.LinuxBridgeManager( - self.interface_mappings, self.root_helper) - - def test_interface_exists_on_bridge(self): - with mock.patch.object(os, 'listdir') as listdir_fn: - listdir_fn.return_value = ["abc"] - self.assertTrue( - self.lbm.interface_exists_on_bridge("br-int", "abc") - ) - self.assertFalse( - self.lbm.interface_exists_on_bridge("br-int", "abd") - ) - - def test_get_bridge_name(self): - nw_id = "123456789101112" - self.assertEqual(self.lbm.get_bridge_name(nw_id), - "brq" + nw_id[0:11]) - nw_id = "" - self.assertEqual(self.lbm.get_bridge_name(nw_id), - "brq") - - def test_get_subinterface_name(self): - self.assertEqual(self.lbm.get_subinterface_name("eth0", "0"), - "eth0.0") - self.assertEqual(self.lbm.get_subinterface_name("eth0", ""), - "eth0.") - - def test_get_tap_device_name(self): - if_id = "123456789101112" - self.assertEqual(self.lbm.get_tap_device_name(if_id), - "tap" + if_id[0:11]) - if_id = "" - self.assertEqual(self.lbm.get_tap_device_name(if_id), - "tap") - - def test_get_vxlan_device_name(self): - vn_id = constants.MAX_VXLAN_VNI - self.assertEqual(self.lbm.get_vxlan_device_name(vn_id), - "vxlan-" + str(vn_id)) - self.assertIsNone(self.lbm.get_vxlan_device_name(vn_id + 1)) - - def test_get_all_neutron_bridges(self): - br_list = ["br-int", "brq1", "brq2", "br-ex"] - with mock.patch.object(os, 'listdir') as listdir_fn: - listdir_fn.return_value = br_list - self.assertEqual(self.lbm.get_all_neutron_bridges(), - br_list[1:3]) - self.assertTrue(listdir_fn.called) - - def test_get_interfaces_on_bridge(self): - with contextlib.nested( - mock.patch.object(utils, 'execute'), - mock.patch.object(os, 'listdir'), - mock.patch.object(ip_lib, 'device_exists', return_value=True) - ) as (exec_fn, listdir_fn, dev_exists_fn): - listdir_fn.return_value = ["qbr1"] - self.assertEqual(self.lbm.get_interfaces_on_bridge("br0"), - ["qbr1"]) - - def test_get_interfaces_on_bridge_not_existing(self): - with mock.patch.object(ip_lib, 'device_exists', return_value=False): - self.assertEqual([], self.lbm.get_interfaces_on_bridge("br0")) - - def test_get_tap_devices_count(self): - with mock.patch.object(os, 'listdir') as listdir_fn: - listdir_fn.return_value = ['tap2101', 'eth0.100', 'vxlan-1000'] - self.assertEqual(self.lbm.get_tap_devices_count('br0'), 1) - listdir_fn.side_effect = OSError() - self.assertEqual(self.lbm.get_tap_devices_count('br0'), 0) - - def test_get_interface_by_ip(self): - with contextlib.nested( - mock.patch.object(ip_lib.IPWrapper, 'get_devices'), - mock.patch.object(ip_lib.IpAddrCommand, 'list') - ) as (get_dev_fn, ip_list_fn): - device = mock.Mock() - device.name = 'dev_name' - get_dev_fn.return_value = [device] - ip_list_fn.returnvalue = mock.Mock() - self.assertEqual(self.lbm.get_interface_by_ip(LOCAL_IP), - 'dev_name') - - def test_get_bridge_for_tap_device(self): - with contextlib.nested( - mock.patch.object(self.lbm, "get_all_neutron_bridges"), - mock.patch.object(self.lbm, "get_interfaces_on_bridge") - ) as (get_all_qbr_fn, get_if_fn): - get_all_qbr_fn.return_value = ["br-int", "br-ex"] - get_if_fn.return_value = ["tap1", "tap2", "tap3"] - self.assertEqual(self.lbm.get_bridge_for_tap_device("tap1"), - "br-int") - self.assertIsNone(self.lbm.get_bridge_for_tap_device("tap4")) - - def test_is_device_on_bridge(self): - self.assertTrue(not self.lbm.is_device_on_bridge("")) - with mock.patch.object(os.path, 'exists') as exists_fn: - exists_fn.return_value = True - self.assertTrue(self.lbm.is_device_on_bridge("tap1")) - exists_fn.assert_called_with( - "/sys/devices/virtual/net/tap1/brport" - ) - - def test_get_interface_details(self): - with contextlib.nested( - mock.patch.object(ip_lib.IpAddrCommand, 'list'), - mock.patch.object(ip_lib.IpRouteCommand, 'get_gateway') - ) as (list_fn, getgw_fn): - gwdict = dict(gateway='1.1.1.1') - getgw_fn.return_value = gwdict - ipdict = dict(cidr='1.1.1.1/24', - broadcast='1.1.1.255', - scope='global', - ip_version=4, - dynamic=False) - list_fn.return_value = ipdict - ret = self.lbm.get_interface_details("eth0") - - self.assertTrue(list_fn.called) - self.assertTrue(getgw_fn.called) - self.assertEqual(ret, (ipdict, gwdict)) - - def test_ensure_flat_bridge(self): - with contextlib.nested( - mock.patch.object(ip_lib.IpAddrCommand, 'list'), - mock.patch.object(ip_lib.IpRouteCommand, 'get_gateway') - ) as (list_fn, getgw_fn): - gwdict = dict(gateway='1.1.1.1') - getgw_fn.return_value = gwdict - ipdict = dict(cidr='1.1.1.1/24', - broadcast='1.1.1.255', - scope='global', - ip_version=4, - dynamic=False) - list_fn.return_value = ipdict - with mock.patch.object(self.lbm, 'ensure_bridge') as ens: - self.assertEqual( - self.lbm.ensure_flat_bridge("123", "eth0"), - "eth0" - ) - self.assertTrue(list_fn.called) - self.assertTrue(getgw_fn.called) - ens.assert_called_once_with("brq123", "eth0", - ipdict, gwdict) - - def test_ensure_vlan_bridge(self): - with contextlib.nested( - mock.patch.object(self.lbm, 'ensure_vlan'), - mock.patch.object(self.lbm, 'ensure_bridge'), - mock.patch.object(self.lbm, 'get_interface_details'), - ) as (ens_vl_fn, ens, get_int_det_fn): - ens_vl_fn.return_value = "eth0.1" - get_int_det_fn.return_value = (None, None) - self.assertEqual(self.lbm.ensure_vlan_bridge("123", "eth0", "1"), - "eth0.1") - ens.assert_called_with("brq123", "eth0.1", None, None) - - get_int_det_fn.return_value = ("ips", "gateway") - self.assertEqual(self.lbm.ensure_vlan_bridge("123", "eth0", "1"), - "eth0.1") - ens.assert_called_with("brq123", "eth0.1", "ips", "gateway") - - def test_ensure_local_bridge(self): - with mock.patch.object(self.lbm, 'ensure_bridge') as ens_fn: - self.lbm.ensure_local_bridge("54321") - ens_fn.assert_called_once_with("brq54321") - - def test_ensure_vlan(self): - with mock.patch.object(ip_lib, 'device_exists') as de_fn: - de_fn.return_value = True - self.assertEqual(self.lbm.ensure_vlan("eth0", "1"), "eth0.1") - de_fn.return_value = False - with mock.patch.object(utils, 'execute') as exec_fn: - exec_fn.return_value = False - self.assertEqual(self.lbm.ensure_vlan("eth0", "1"), "eth0.1") - # FIXME(kevinbenton): validate the params to the exec_fn calls - self.assertEqual(exec_fn.call_count, 2) - exec_fn.return_value = True - self.assertIsNone(self.lbm.ensure_vlan("eth0", "1")) - self.assertEqual(exec_fn.call_count, 3) - - def test_ensure_vxlan(self): - seg_id = "12345678" - self.lbm.local_int = 'eth0' - self.lbm.vxlan_mode = lconst.VXLAN_MCAST - with mock.patch.object(ip_lib, 'device_exists') as de_fn: - de_fn.return_value = True - self.assertEqual(self.lbm.ensure_vxlan(seg_id), "vxlan-" + seg_id) - de_fn.return_value = False - with mock.patch.object(self.lbm.ip, - 'add_vxlan') as add_vxlan_fn: - add_vxlan_fn.return_value = FakeIpDevice() - self.assertEqual(self.lbm.ensure_vxlan(seg_id), - "vxlan-" + seg_id) - add_vxlan_fn.assert_called_with("vxlan-" + seg_id, seg_id, - group="224.0.0.1", - dev=self.lbm.local_int) - cfg.CONF.set_override('l2_population', 'True', 'VXLAN') - self.assertEqual(self.lbm.ensure_vxlan(seg_id), - "vxlan-" + seg_id) - add_vxlan_fn.assert_called_with("vxlan-" + seg_id, seg_id, - group="224.0.0.1", - dev=self.lbm.local_int, - proxy=True) - - def test_update_interface_ip_details(self): - gwdict = dict(gateway='1.1.1.1', - metric=50) - ipdict = dict(cidr='1.1.1.1/24', - broadcast='1.1.1.255', - scope='global', - ip_version=4, - dynamic=False) - with contextlib.nested( - mock.patch.object(ip_lib.IpAddrCommand, 'add'), - mock.patch.object(ip_lib.IpAddrCommand, 'delete') - ) as (add_fn, del_fn): - self.lbm.update_interface_ip_details("br0", "eth0", - [ipdict], None) - self.assertTrue(add_fn.called) - self.assertTrue(del_fn.called) - - with contextlib.nested( - mock.patch.object(ip_lib.IpRouteCommand, 'add_gateway'), - mock.patch.object(ip_lib.IpRouteCommand, 'delete_gateway') - ) as (addgw_fn, delgw_fn): - self.lbm.update_interface_ip_details("br0", "eth0", - None, gwdict) - self.assertTrue(addgw_fn.called) - self.assertTrue(delgw_fn.called) - - def test_bridge_exists_and_ensure_up(self): - ip_lib_mock = mock.Mock() - with mock.patch.object(ip_lib, 'IPDevice', return_value=ip_lib_mock): - # device exists - self.assertTrue(self.lbm._bridge_exists_and_ensure_up("br0")) - self.assertTrue(ip_lib_mock.link.set_up.called) - # device doesn't exists - ip_lib_mock.link.set_up.side_effect = RuntimeError - self.assertFalse(self.lbm._bridge_exists_and_ensure_up("br0")) - - def test_ensure_bridge(self): - with contextlib.nested( - mock.patch.object(self.lbm, '_bridge_exists_and_ensure_up'), - mock.patch.object(utils, 'execute'), - mock.patch.object(self.lbm, 'update_interface_ip_details'), - mock.patch.object(self.lbm, 'interface_exists_on_bridge'), - mock.patch.object(self.lbm, 'is_device_on_bridge'), - mock.patch.object(self.lbm, 'get_bridge_for_tap_device'), - ) as (de_fn, exec_fn, upd_fn, ie_fn, if_br_fn, get_if_br_fn): - de_fn.return_value = False - exec_fn.return_value = False - self.assertEqual(self.lbm.ensure_bridge("br0", None), "br0") - ie_fn.return_Value = False - self.lbm.ensure_bridge("br0", "eth0") - upd_fn.assert_called_with("br0", "eth0", None, None) - ie_fn.assert_called_with("br0", "eth0") - - self.lbm.ensure_bridge("br0", "eth0", "ips", "gateway") - upd_fn.assert_called_with("br0", "eth0", "ips", "gateway") - ie_fn.assert_called_with("br0", "eth0") - - exec_fn.side_effect = Exception() - de_fn.return_value = True - self.lbm.ensure_bridge("br0", "eth0") - ie_fn.assert_called_with("br0", "eth0") - - exec_fn.reset_mock() - exec_fn.side_effect = None - de_fn.return_value = True - ie_fn.return_value = False - get_if_br_fn.return_value = "br1" - self.lbm.ensure_bridge("br0", "eth0") - expected = [ - mock.call(['brctl', 'delif', 'br1', 'eth0'], - root_helper=self.root_helper), - mock.call(['brctl', 'addif', 'br0', 'eth0'], - root_helper=self.root_helper), - ] - exec_fn.assert_has_calls(expected) - - def test_ensure_physical_in_bridge(self): - self.assertFalse( - self.lbm.ensure_physical_in_bridge("123", p_const.TYPE_VLAN, - "phys", "1") - ) - with mock.patch.object(self.lbm, "ensure_flat_bridge") as flbr_fn: - self.assertTrue( - self.lbm.ensure_physical_in_bridge("123", p_const.TYPE_FLAT, - "physnet1", None) - ) - self.assertTrue(flbr_fn.called) - with mock.patch.object(self.lbm, "ensure_vlan_bridge") as vlbr_fn: - self.assertTrue( - self.lbm.ensure_physical_in_bridge("123", p_const.TYPE_VLAN, - "physnet1", "1") - ) - self.assertTrue(vlbr_fn.called) - - with mock.patch.object(self.lbm, "ensure_vxlan_bridge") as vlbr_fn: - self.lbm.vxlan_mode = lconst.VXLAN_MCAST - self.assertTrue( - self.lbm.ensure_physical_in_bridge("123", p_const.TYPE_VXLAN, - "physnet1", "1") - ) - self.assertTrue(vlbr_fn.called) - - def test_add_tap_interface(self): - with mock.patch.object(ip_lib, "device_exists") as de_fn: - de_fn.return_value = False - self.assertFalse( - self.lbm.add_tap_interface("123", p_const.TYPE_VLAN, - "physnet1", "1", "tap1") - ) - - de_fn.return_value = True - with contextlib.nested( - mock.patch.object(self.lbm, "ensure_local_bridge"), - mock.patch.object(utils, "execute"), - mock.patch.object(self.lbm, "get_bridge_for_tap_device") - ) as (en_fn, exec_fn, get_br): - exec_fn.return_value = False - get_br.return_value = True - self.assertTrue(self.lbm.add_tap_interface("123", - p_const.TYPE_LOCAL, - "physnet1", None, - "tap1")) - en_fn.assert_called_with("123") - - get_br.return_value = False - exec_fn.return_value = True - self.assertFalse(self.lbm.add_tap_interface("123", - p_const.TYPE_LOCAL, - "physnet1", None, - "tap1")) - - with mock.patch.object(self.lbm, - "ensure_physical_in_bridge") as ens_fn: - ens_fn.return_value = False - self.assertFalse(self.lbm.add_tap_interface("123", - p_const.TYPE_VLAN, - "physnet1", "1", - "tap1")) - - def test_add_interface(self): - with mock.patch.object(self.lbm, "add_tap_interface") as add_tap: - self.lbm.add_interface("123", p_const.TYPE_VLAN, "physnet-1", - "1", "234") - add_tap.assert_called_with("123", p_const.TYPE_VLAN, "physnet-1", - "1", "tap234") - - def test_delete_vlan_bridge(self): - with contextlib.nested( - mock.patch.object(ip_lib, "device_exists"), - mock.patch.object(self.lbm, "get_interfaces_on_bridge"), - mock.patch.object(self.lbm, "remove_interface"), - mock.patch.object(self.lbm, "get_interface_details"), - mock.patch.object(self.lbm, "update_interface_ip_details"), - mock.patch.object(self.lbm, "delete_vxlan"), - mock.patch.object(utils, "execute") - ) as (de_fn, getif_fn, remif_fn, if_det_fn, - updif_fn, del_vxlan, exec_fn): - de_fn.return_value = False - self.lbm.delete_vlan_bridge("br0") - self.assertFalse(getif_fn.called) - - de_fn.return_value = True - getif_fn.return_value = ["eth0", "eth1", "vxlan-1002"] - if_det_fn.return_value = ("ips", "gateway") - exec_fn.return_value = False - self.lbm.delete_vlan_bridge("br0") - updif_fn.assert_called_with("eth1", "br0", "ips", "gateway") - del_vxlan.assert_called_with("vxlan-1002") - - def test_delete_vlan_bridge_with_ip(self): - with contextlib.nested( - mock.patch.object(ip_lib, "device_exists"), - mock.patch.object(self.lbm, "get_interfaces_on_bridge"), - mock.patch.object(self.lbm, "remove_interface"), - mock.patch.object(self.lbm, "get_interface_details"), - mock.patch.object(self.lbm, "update_interface_ip_details"), - mock.patch.object(self.lbm, "delete_vlan"), - mock.patch.object(utils, "execute") - ) as (de_fn, getif_fn, remif_fn, if_det_fn, - updif_fn, del_vlan, exec_fn): - de_fn.return_value = True - getif_fn.return_value = ["eth0", "eth1.1"] - if_det_fn.return_value = ("ips", "gateway") - exec_fn.return_value = False - self.lbm.delete_vlan_bridge("br0") - updif_fn.assert_called_with("eth1.1", "br0", "ips", "gateway") - self.assertFalse(del_vlan.called) - - def test_delete_vlan_bridge_no_ip(self): - with contextlib.nested( - mock.patch.object(ip_lib, "device_exists"), - mock.patch.object(self.lbm, "get_interfaces_on_bridge"), - mock.patch.object(self.lbm, "remove_interface"), - mock.patch.object(self.lbm, "get_interface_details"), - mock.patch.object(self.lbm, "update_interface_ip_details"), - mock.patch.object(self.lbm, "delete_vlan"), - mock.patch.object(utils, "execute") - ) as (de_fn, getif_fn, remif_fn, if_det_fn, - updif_fn, del_vlan, exec_fn): - de_fn.return_value = True - getif_fn.return_value = ["eth0", "eth1.1"] - exec_fn.return_value = False - if_det_fn.return_value = ([], None) - self.lbm.delete_vlan_bridge("br0") - del_vlan.assert_called_with("eth1.1") - self.assertFalse(updif_fn.called) - - def test_delete_vxlan_bridge_no_int_mappings(self): - interface_mappings = {} - lbm = linuxbridge_neutron_agent.LinuxBridgeManager( - interface_mappings, self.root_helper) - - with contextlib.nested( - mock.patch.object(ip_lib, "device_exists"), - mock.patch.object(lbm, "get_interfaces_on_bridge"), - mock.patch.object(lbm, "remove_interface"), - mock.patch.object(lbm, "delete_vxlan"), - mock.patch.object(utils, "execute") - ) as (de_fn, getif_fn, remif_fn, del_vxlan, exec_fn): - de_fn.return_value = False - lbm.delete_vlan_bridge("br0") - self.assertFalse(getif_fn.called) - - de_fn.return_value = True - getif_fn.return_value = ["vxlan-1002"] - exec_fn.return_value = False - lbm.delete_vlan_bridge("br0") - del_vxlan.assert_called_with("vxlan-1002") - - def test_remove_empty_bridges(self): - self.lbm.network_map = {'net1': mock.Mock(), 'net2': mock.Mock()} - - def tap_count_side_effect(*args): - return 0 if args[0] == 'brqnet1' else 1 - - with contextlib.nested( - mock.patch.object(self.lbm, "delete_vlan_bridge"), - mock.patch.object(self.lbm, "get_tap_devices_count", - side_effect=tap_count_side_effect), - ) as (del_br_fn, count_tap_fn): - self.lbm.remove_empty_bridges() - del_br_fn.assert_called_once_with('brqnet1') - - def test_remove_interface(self): - with contextlib.nested( - mock.patch.object(ip_lib, "device_exists"), - mock.patch.object(self.lbm, "is_device_on_bridge"), - mock.patch.object(utils, "execute") - ) as (de_fn, isdev_fn, exec_fn): - de_fn.return_value = False - self.assertFalse(self.lbm.remove_interface("br0", "eth0")) - self.assertFalse(isdev_fn.called) - - de_fn.return_value = True - isdev_fn.return_value = False - self.assertTrue(self.lbm.remove_interface("br0", "eth0")) - - isdev_fn.return_value = True - exec_fn.return_value = True - self.assertFalse(self.lbm.remove_interface("br0", "eth0")) - - exec_fn.return_value = False - self.assertTrue(self.lbm.remove_interface("br0", "eth0")) - - def test_delete_vlan(self): - with contextlib.nested( - mock.patch.object(ip_lib, "device_exists"), - mock.patch.object(utils, "execute") - ) as (de_fn, exec_fn): - de_fn.return_value = False - self.lbm.delete_vlan("eth1.1") - self.assertFalse(exec_fn.called) - - de_fn.return_value = True - exec_fn.return_value = False - self.lbm.delete_vlan("eth1.1") - self.assertTrue(exec_fn.called) - - def _check_vxlan_support(self, expected, vxlan_module_supported, - vxlan_ucast_supported, vxlan_mcast_supported): - with contextlib.nested( - mock.patch.object(self.lbm, 'vxlan_module_supported', - return_value=vxlan_module_supported), - mock.patch.object(self.lbm, 'vxlan_ucast_supported', - return_value=vxlan_ucast_supported), - mock.patch.object(self.lbm, 'vxlan_mcast_supported', - return_value=vxlan_mcast_supported)): - if expected == lconst.VXLAN_NONE: - self.assertRaises(exceptions.VxlanNetworkUnsupported, - self.lbm.check_vxlan_support) - self.assertEqual(expected, self.lbm.vxlan_mode) - else: - self.lbm.check_vxlan_support() - self.assertEqual(expected, self.lbm.vxlan_mode) - - def test_check_vxlan_support(self): - self._check_vxlan_support(expected=lconst.VXLAN_UCAST, - vxlan_module_supported=True, - vxlan_ucast_supported=True, - vxlan_mcast_supported=True) - self._check_vxlan_support(expected=lconst.VXLAN_MCAST, - vxlan_module_supported=True, - vxlan_ucast_supported=False, - vxlan_mcast_supported=True) - - self._check_vxlan_support(expected=lconst.VXLAN_NONE, - vxlan_module_supported=False, - vxlan_ucast_supported=False, - vxlan_mcast_supported=False) - self._check_vxlan_support(expected=lconst.VXLAN_NONE, - vxlan_module_supported=True, - vxlan_ucast_supported=False, - vxlan_mcast_supported=False) - - def _check_vxlan_module_supported(self, expected, execute_side_effect): - with mock.patch.object( - utils, 'execute', - side_effect=execute_side_effect): - self.assertEqual(expected, self.lbm.vxlan_module_supported()) - - def test_vxlan_module_supported(self): - self._check_vxlan_module_supported( - expected=True, - execute_side_effect=None) - self._check_vxlan_module_supported( - expected=False, - execute_side_effect=RuntimeError()) - - def _check_vxlan_ucast_supported( - self, expected, l2_population, iproute_arg_supported, fdb_append): - cfg.CONF.set_override('l2_population', l2_population, 'VXLAN') - with contextlib.nested( - mock.patch.object( - ip_lib, 'device_exists', return_value=False), - mock.patch.object(self.lbm, 'delete_vxlan', return_value=None), - mock.patch.object(self.lbm, 'ensure_vxlan', return_value=None), - mock.patch.object( - utils, 'execute', - side_effect=None if fdb_append else RuntimeError()), - mock.patch.object( - ip_lib, 'iproute_arg_supported', - return_value=iproute_arg_supported)): - self.assertEqual(expected, self.lbm.vxlan_ucast_supported()) - - def test_vxlan_ucast_supported(self): - self._check_vxlan_ucast_supported( - expected=False, - l2_population=False, iproute_arg_supported=True, fdb_append=True) - self._check_vxlan_ucast_supported( - expected=False, - l2_population=True, iproute_arg_supported=False, fdb_append=True) - self._check_vxlan_ucast_supported( - expected=False, - l2_population=True, iproute_arg_supported=True, fdb_append=False) - self._check_vxlan_ucast_supported( - expected=True, - l2_population=True, iproute_arg_supported=True, fdb_append=True) - - def _check_vxlan_mcast_supported( - self, expected, vxlan_group, iproute_arg_supported): - cfg.CONF.set_override('vxlan_group', vxlan_group, 'VXLAN') - with mock.patch.object( - ip_lib, 'iproute_arg_supported', - return_value=iproute_arg_supported): - self.assertEqual(expected, self.lbm.vxlan_mcast_supported()) - - def test_vxlan_mcast_supported(self): - self._check_vxlan_mcast_supported( - expected=False, - vxlan_group='', - iproute_arg_supported=True) - self._check_vxlan_mcast_supported( - expected=False, - vxlan_group='224.0.0.1', - iproute_arg_supported=False) - self._check_vxlan_mcast_supported( - expected=True, - vxlan_group='224.0.0.1', - iproute_arg_supported=True) - - -class TestLinuxBridgeRpcCallbacks(base.BaseTestCase): - def setUp(self): - cfg.CONF.set_override('local_ip', LOCAL_IP, 'VXLAN') - super(TestLinuxBridgeRpcCallbacks, self).setUp() - - self.u_execute_p = mock.patch('neutron.agent.linux.utils.execute') - self.u_execute = self.u_execute_p.start() - - class FakeLBAgent(object): - def __init__(self): - self.agent_id = 1 - self.br_mgr = (linuxbridge_neutron_agent. - LinuxBridgeManager({'physnet1': 'eth1'}, - cfg.CONF.AGENT.root_helper)) - - self.br_mgr.vxlan_mode = lconst.VXLAN_UCAST - segment = mock.Mock() - segment.network_type = 'vxlan' - segment.segmentation_id = 1 - self.br_mgr.network_map['net_id'] = segment - - self.lb_rpc = linuxbridge_neutron_agent.LinuxBridgeRpcCallbacks( - object(), - FakeLBAgent() - ) - - self.root_helper = cfg.CONF.AGENT.root_helper - - def test_network_delete(self): - with contextlib.nested( - mock.patch.object(self.lb_rpc.agent.br_mgr, "get_bridge_name"), - mock.patch.object(self.lb_rpc.agent.br_mgr, "delete_vlan_bridge") - ) as (get_br_fn, del_fn): - get_br_fn.return_value = "br0" - self.lb_rpc.network_delete("anycontext", network_id="123") - get_br_fn.assert_called_with("123") - del_fn.assert_called_with("br0") - - def test_fdb_add(self): - fdb_entries = {'net_id': - {'ports': - {'agent_ip': [constants.FLOODING_ENTRY, - ['port_mac', 'port_ip']]}, - 'network_type': 'vxlan', - 'segment_id': 1}} - - with mock.patch.object(utils, 'execute', - return_value='') as execute_fn: - self.lb_rpc.fdb_add(None, fdb_entries) - - expected = [ - mock.call(['bridge', 'fdb', 'show', 'dev', 'vxlan-1'], - root_helper=self.root_helper), - mock.call(['bridge', 'fdb', 'add', - constants.FLOODING_ENTRY[0], - 'dev', 'vxlan-1', 'dst', 'agent_ip'], - root_helper=self.root_helper, - check_exit_code=False), - mock.call(['ip', 'neigh', 'replace', 'port_ip', 'lladdr', - 'port_mac', 'dev', 'vxlan-1', 'nud', 'permanent'], - root_helper=self.root_helper, - check_exit_code=False), - mock.call(['bridge', 'fdb', 'add', 'port_mac', 'dev', - 'vxlan-1', 'dst', 'agent_ip'], - root_helper=self.root_helper, - check_exit_code=False), - ] - execute_fn.assert_has_calls(expected) - - def test_fdb_ignore(self): - fdb_entries = {'net_id': - {'ports': - {LOCAL_IP: [constants.FLOODING_ENTRY, - ['port_mac', 'port_ip']]}, - 'network_type': 'vxlan', - 'segment_id': 1}} - - with mock.patch.object(utils, 'execute', - return_value='') as execute_fn: - self.lb_rpc.fdb_add(None, fdb_entries) - self.lb_rpc.fdb_remove(None, fdb_entries) - - self.assertFalse(execute_fn.called) - - fdb_entries = {'other_net_id': - {'ports': - {'192.168.0.67': [constants.FLOODING_ENTRY, - ['port_mac', 'port_ip']]}, - 'network_type': 'vxlan', - 'segment_id': 1}} - - with mock.patch.object(utils, 'execute', - return_value='') as execute_fn: - self.lb_rpc.fdb_add(None, fdb_entries) - self.lb_rpc.fdb_remove(None, fdb_entries) - - self.assertFalse(execute_fn.called) - - def test_fdb_remove(self): - fdb_entries = {'net_id': - {'ports': - {'agent_ip': [constants.FLOODING_ENTRY, - ['port_mac', 'port_ip']]}, - 'network_type': 'vxlan', - 'segment_id': 1}} - - with mock.patch.object(utils, 'execute', - return_value='') as execute_fn: - self.lb_rpc.fdb_remove(None, fdb_entries) - - expected = [ - mock.call(['bridge', 'fdb', 'del', - constants.FLOODING_ENTRY[0], - 'dev', 'vxlan-1', 'dst', 'agent_ip'], - root_helper=self.root_helper, - check_exit_code=False), - mock.call(['ip', 'neigh', 'del', 'port_ip', 'lladdr', - 'port_mac', 'dev', 'vxlan-1'], - root_helper=self.root_helper, - check_exit_code=False), - mock.call(['bridge', 'fdb', 'del', 'port_mac', - 'dev', 'vxlan-1', 'dst', 'agent_ip'], - root_helper=self.root_helper, - check_exit_code=False), - ] - execute_fn.assert_has_calls(expected) - - def test_fdb_update_chg_ip(self): - fdb_entries = {'chg_ip': - {'net_id': - {'agent_ip': - {'before': [['port_mac', 'port_ip_1']], - 'after': [['port_mac', 'port_ip_2']]}}}} - - with mock.patch.object(utils, 'execute', - return_value='') as execute_fn: - self.lb_rpc.fdb_update(None, fdb_entries) - - expected = [ - mock.call(['ip', 'neigh', 'replace', 'port_ip_2', 'lladdr', - 'port_mac', 'dev', 'vxlan-1', 'nud', 'permanent'], - root_helper=self.root_helper, - check_exit_code=False), - mock.call(['ip', 'neigh', 'del', 'port_ip_1', 'lladdr', - 'port_mac', 'dev', 'vxlan-1'], - root_helper=self.root_helper, - check_exit_code=False) - ] - execute_fn.assert_has_calls(expected) diff --git a/neutron/tests/unit/linuxbridge/test_lb_security_group.py b/neutron/tests/unit/linuxbridge/test_lb_security_group.py deleted file mode 100644 index 62662036a..000000000 --- a/neutron/tests/unit/linuxbridge/test_lb_security_group.py +++ /dev/null @@ -1,99 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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 neutron.api.v2 import attributes -from neutron.extensions import securitygroup as ext_sg -from neutron.plugins.linuxbridge.db import l2network_db_v2 as lb_db -from neutron.tests.unit import test_extension_security_group as test_sg -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - - -PLUGIN_NAME = ('neutron.plugins.linuxbridge.' - 'lb_neutron_plugin.LinuxBridgePluginV2') -NOTIFIER = ('neutron.plugins.linuxbridge.' - 'lb_neutron_plugin.AgentNotifierApi') - - -class LinuxBridgeSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self, plugin=None): - test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_IPTABLES_DRIVER) - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - self._attribute_map_bk_ = {} - for item in attributes.RESOURCE_ATTRIBUTE_MAP: - self._attribute_map_bk_[item] = (attributes. - RESOURCE_ATTRIBUTE_MAP[item]. - copy()) - super(LinuxBridgeSecurityGroupsTestCase, self).setUp(PLUGIN_NAME) - - def tearDown(self): - attributes.RESOURCE_ATTRIBUTE_MAP = self._attribute_map_bk_ - super(LinuxBridgeSecurityGroupsTestCase, self).tearDown() - - -class TestLinuxBridgeSecurityGroups(LinuxBridgeSecurityGroupsTestCase, - test_sg.TestSecurityGroups, - test_sg_rpc.SGNotificationTestMixin): - pass - - -class TestLinuxBridgeSecurityGroupsXML(TestLinuxBridgeSecurityGroups): - fmt = 'xml' - - -class TestLinuxBridgeSecurityGroupsDB(LinuxBridgeSecurityGroupsTestCase): - def test_security_group_get_port_from_device(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - security_group_id = sg['security_group']['id'] - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - fixed_ips = port['port']['fixed_ips'] - data = {'port': {'fixed_ips': fixed_ips, - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: - [security_group_id]}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - port_id = res['port']['id'] - device_id = port_id[:8] - port_dict = lb_db.get_port_from_device(device_id) - self.assertEqual(port_id, port_dict['id']) - self.assertEqual([security_group_id], - port_dict[ext_sg.SECURITYGROUPS]) - self.assertEqual([], port_dict['security_group_rules']) - self.assertEqual([fixed_ips[0]['ip_address']], - port_dict['fixed_ips']) - self._delete('ports', port['port']['id']) - - def test_security_group_get_port_from_device_with_no_port(self): - port_dict = lb_db.get_port_from_device('bad_device_id') - self.assertIsNone(port_dict) - - -class TestLinuxBridgeSecurityGroupsDBXML(TestLinuxBridgeSecurityGroupsDB): - fmt = 'xml' diff --git a/neutron/tests/unit/linuxbridge/test_linuxbridge_plugin.py b/neutron/tests/unit/linuxbridge/test_linuxbridge_plugin.py deleted file mode 100644 index 3ff0f7592..000000000 --- a/neutron/tests/unit/linuxbridge/test_linuxbridge_plugin.py +++ /dev/null @@ -1,132 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 contextlib - -import mock -from oslo.config import cfg - -from neutron.common import constants as q_const -from neutron.extensions import portbindings -from neutron import manager -from neutron.plugins.linuxbridge import lb_neutron_plugin -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - -PLUGIN_NAME = ('neutron.plugins.linuxbridge.' - 'lb_neutron_plugin.LinuxBridgePluginV2') - - -class LinuxBridgePluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self): - super(LinuxBridgePluginV2TestCase, self).setUp(PLUGIN_NAME) - self.port_create_status = 'DOWN' - - -class TestLinuxBridgeBasicGet(test_plugin.TestBasicGet, - LinuxBridgePluginV2TestCase): - pass - - -class TestLinuxBridgeV2HTTPResponse(test_plugin.TestV2HTTPResponse, - LinuxBridgePluginV2TestCase): - pass - - -class TestLinuxBridgeNetworksV2(test_plugin.TestNetworksV2, - LinuxBridgePluginV2TestCase): - pass - - -class TestLinuxBridgePortsV2(test_plugin.TestPortsV2, - LinuxBridgePluginV2TestCase): - - def test_update_port_status_build(self): - with self.port() as port: - self.assertEqual(port['port']['status'], 'DOWN') - self.assertEqual(self.port_create_status, 'DOWN') - - -class TestLinuxBridgePortBinding(LinuxBridgePluginV2TestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = portbindings.VIF_TYPE_BRIDGE - HAS_PORT_FILTER = True - ENABLE_SG = True - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_IPTABLES_DRIVER - - def setUp(self): - test_sg_rpc.set_firewall_driver(self.FIREWALL_DRIVER) - cfg.CONF.set_override( - 'enable_security_group', self.ENABLE_SG, - group='SECURITYGROUP') - super(TestLinuxBridgePortBinding, self).setUp() - - -class TestLinuxBridgePortBindingNoSG(TestLinuxBridgePortBinding): - HAS_PORT_FILTER = False - ENABLE_SG = False - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER - - -class TestLinuxBridgePortBindingHost( - LinuxBridgePluginV2TestCase, - test_bindings.PortBindingsHostTestCaseMixin): - pass - - -class TestLinuxBridgePluginRpcCallbacks(test_plugin.NeutronDbPluginV2TestCase): - def setUp(self): - super(TestLinuxBridgePluginRpcCallbacks, self).setUp(PLUGIN_NAME) - self.callbacks = lb_neutron_plugin.LinuxBridgeRpcCallbacks() - - def test_update_device_down(self): - with contextlib.nested( - mock.patch.object(self.callbacks, "get_port_from_device", - return_value=None), - mock.patch.object(manager.NeutronManager, "get_plugin") - ) as (gpfd, gp): - self.assertEqual( - self.callbacks.update_device_down("fake_context", - agent_id="123", - device="device", - host="host"), - {'device': 'device', 'exists': False} - ) - gpfd.return_value = {'id': 'fakeid', - 'status': q_const.PORT_STATUS_ACTIVE} - self.assertEqual( - self.callbacks.update_device_down("fake_context", - agent_id="123", - device="device", - host="host"), - {'device': 'device', 'exists': True} - ) - - def test_update_device_up(self): - with contextlib.nested( - mock.patch.object(self.callbacks, "get_port_from_device", - return_value=None), - mock.patch.object(manager.NeutronManager, "get_plugin") - ) as (gpfd, gp): - gpfd.return_value = {'id': 'fakeid', - 'status': q_const.PORT_STATUS_ACTIVE} - self.callbacks.update_device_up("fake_context", - agent_id="123", - device="device", - host="host") - gpfd.assert_called_once_with('device') diff --git a/neutron/tests/unit/linuxbridge/test_rpcapi.py b/neutron/tests/unit/linuxbridge/test_rpcapi.py deleted file mode 100644 index 616a06acd..000000000 --- a/neutron/tests/unit/linuxbridge/test_rpcapi.py +++ /dev/null @@ -1,132 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012, Red Hat, Inc. -# -# 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. - -""" -Unit Tests for linuxbridge rpc -""" - -import fixtures -from oslo.config import cfg - -from neutron.agent import rpc as agent_rpc -from neutron.common import topics -from neutron.openstack.common import context -from neutron.plugins.linuxbridge import lb_neutron_plugin as plb -from neutron.tests import base - - -class rpcApiTestCase(base.BaseTestCase): - def _test_lb_api(self, rpcapi, topic, method, rpc_method, - expected_msg=None, **kwargs): - ctxt = context.RequestContext('fake_user', 'fake_project') - expected_retval = 'foo' if method == 'call' else None - if not expected_msg: - expected_msg = rpcapi.make_msg(method, **kwargs) - if rpc_method == 'cast' and method == 'run_instance': - kwargs['call'] = False - - self.fake_args = None - self.fake_kwargs = None - - def _fake_rpc_method(*args, **kwargs): - self.fake_args = args - self.fake_kwargs = kwargs - if expected_retval: - return expected_retval - - self.useFixture(fixtures.MonkeyPatch( - 'neutron.common.rpc_compat.RpcProxy.' + rpc_method, - _fake_rpc_method)) - - retval = getattr(rpcapi, method)(ctxt, **kwargs) - - self.assertEqual(expected_retval, retval) - expected_args = [ctxt, expected_msg] - expected_kwargs = {'topic': topic} - - # skip the first argument which is 'self' - for arg, expected_arg in zip(self.fake_args[1:], expected_args): - self.assertEqual(expected_arg, arg) - self.assertEqual(expected_kwargs, self.fake_kwargs) - - def test_delete_network(self): - rpcapi = plb.AgentNotifierApi(topics.AGENT) - self._test_lb_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.NETWORK, - topics.DELETE), - 'network_delete', rpc_method='fanout_cast', - network_id='fake_request_spec') - - def test_port_update(self): - cfg.CONF.set_override('rpc_support_old_agents', False, 'AGENT') - rpcapi = plb.AgentNotifierApi(topics.AGENT) - expected_msg = rpcapi.make_msg('port_update', - port='fake_port', - network_type='vlan', - physical_network='fake_net', - segmentation_id='fake_vlan_id') - self._test_lb_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - expected_msg=expected_msg, - port='fake_port', - physical_network='fake_net', - vlan_id='fake_vlan_id') - - def test_port_update_old_agent(self): - cfg.CONF.set_override('rpc_support_old_agents', True, 'AGENT') - rpcapi = plb.AgentNotifierApi(topics.AGENT) - expected_msg = rpcapi.make_msg('port_update', - port='fake_port', - network_type='vlan', - physical_network='fake_net', - segmentation_id='fake_vlan_id', - vlan_id='fake_vlan_id') - self._test_lb_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - expected_msg=expected_msg, - port='fake_port', - physical_network='fake_net', - vlan_id='fake_vlan_id') - - def test_device_details(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_lb_api(rpcapi, topics.PLUGIN, - 'get_device_details', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id') - - def test_update_device_down(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_lb_api(rpcapi, topics.PLUGIN, - 'update_device_down', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') - - def test_update_device_up(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_lb_api(rpcapi, topics.PLUGIN, - 'update_device_up', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') diff --git a/neutron/tests/unit/metaplugin/__init__.py b/neutron/tests/unit/metaplugin/__init__.py deleted file mode 100644 index d8bce7745..000000000 --- a/neutron/tests/unit/metaplugin/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/metaplugin/fake_plugin.py b/neutron/tests/unit/metaplugin/fake_plugin.py deleted file mode 100644 index 1430697f3..000000000 --- a/neutron/tests/unit/metaplugin/fake_plugin.py +++ /dev/null @@ -1,79 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012, Nachi Ueno, NTT MCL, Inc. -# -# 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. - -from neutron.db import db_base_plugin_v2 -from neutron.db import external_net_db -from neutron.db import l3_gwmode_db - - -class Fake1(db_base_plugin_v2.NeutronDbPluginV2, - external_net_db.External_net_db_mixin, - l3_gwmode_db.L3_NAT_db_mixin): - supported_extension_aliases = ['external-net', 'router'] - - def fake_func(self): - return 'fake1' - - def create_network(self, context, network): - session = context.session - with session.begin(subtransactions=True): - net = super(Fake1, self).create_network(context, network) - self._process_l3_create(context, net, network['network']) - return net - - def update_network(self, context, id, network): - session = context.session - with session.begin(subtransactions=True): - net = super(Fake1, self).update_network(context, id, - network) - self._process_l3_update(context, net, network['network']) - return net - - def delete_network(self, context, id): - session = context.session - with session.begin(subtransactions=True): - self._process_l3_delete(context, id) - return super(Fake1, self).delete_network(context, id) - - def create_port(self, context, port): - port = super(Fake1, self).create_port(context, port) - return port - - def create_subnet(self, context, subnet): - subnet = super(Fake1, self).create_subnet(context, subnet) - return subnet - - def update_port(self, context, id, port): - port = super(Fake1, self).update_port(context, id, port) - return port - - def delete_port(self, context, id, l3_port_check=True): - if l3_port_check: - self.prevent_l3_port_deletion(context, id) - self.disassociate_floatingips(context, id) - return super(Fake1, self).delete_port(context, id) - - -class Fake2(Fake1): - def fake_func(self): - return 'fake2' - - def fake_func2(self): - return 'fake2' - - def start_rpc_listeners(self): - # return value is only used to confirm this method was called. - return 'OK' diff --git a/neutron/tests/unit/metaplugin/test_basic.py b/neutron/tests/unit/metaplugin/test_basic.py deleted file mode 100644 index 5f2046957..000000000 --- a/neutron/tests/unit/metaplugin/test_basic.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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. - -from neutron.tests.unit.metaplugin import test_metaplugin -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_l3_plugin - - -class MetaPluginV2DBTestCase(test_plugin.NeutronDbPluginV2TestCase): - - _plugin_name = ('neutron.plugins.metaplugin.' - 'meta_neutron_plugin.MetaPluginV2') - - def setUp(self, plugin=None, ext_mgr=None, - service_plugins=None): - # NOTE(salv-orlando): The plugin keyword argument is ignored, - # as this class will always invoke super with self._plugin_name. - # These keyword parameters ensure setUp methods always have the - # same signature. - test_metaplugin.setup_metaplugin_conf() - ext_mgr = ext_mgr or test_l3_plugin.L3TestExtensionManager() - self.addCleanup(test_metaplugin.unregister_meta_hooks) - super(MetaPluginV2DBTestCase, self).setUp( - plugin=self._plugin_name, ext_mgr=ext_mgr, - service_plugins=service_plugins) - - -class TestMetaBasicGet(test_plugin.TestBasicGet, - MetaPluginV2DBTestCase): - pass - - -class TestMetaV2HTTPResponse(test_plugin.TestV2HTTPResponse, - MetaPluginV2DBTestCase): - pass - - -class TestMetaPortsV2(test_plugin.TestPortsV2, - MetaPluginV2DBTestCase): - pass - - -class TestMetaNetworksV2(test_plugin.TestNetworksV2, - MetaPluginV2DBTestCase): - pass - - -class TestMetaSubnetsV2(test_plugin.TestSubnetsV2, - MetaPluginV2DBTestCase): - #TODO(nati) This test fails if we run all test, but It success just one - def test_update_subnet_route(self): - pass - - def test_update_subnet_dns_to_None(self): - pass - - def test_update_subnet_route_to_None(self): - pass - - def test_update_subnet_dns(self): - pass - - -class TestMetaL3NatDBTestCase(test_l3_plugin.L3NatDBIntTestCase, - MetaPluginV2DBTestCase): - pass diff --git a/neutron/tests/unit/metaplugin/test_metaplugin.py b/neutron/tests/unit/metaplugin/test_metaplugin.py deleted file mode 100644 index 7dc621978..000000000 --- a/neutron/tests/unit/metaplugin/test_metaplugin.py +++ /dev/null @@ -1,404 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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 oslo.config import cfg -import testtools - -from neutron.common import exceptions as exc -from neutron.common import topics -from neutron import context -from neutron.db import api as db -from neutron.db import db_base_plugin_v2 -from neutron.db import models_v2 -from neutron.extensions import flavor as ext_flavor -from neutron.openstack.common import uuidutils -from neutron.plugins.metaplugin import meta_neutron_plugin -from neutron.tests import base - -CONF_FILE = "" -META_PATH = "neutron.plugins.metaplugin" -FAKE_PATH = "neutron.tests.unit.metaplugin" -PROXY_PATH = "%s.proxy_neutron_plugin.ProxyPluginV2" % META_PATH -PLUGIN_LIST = """ -fake1:%s.fake_plugin.Fake1,fake2:%s.fake_plugin.Fake2,proxy:%s -""".strip() % (FAKE_PATH, FAKE_PATH, PROXY_PATH) -L3_PLUGIN_LIST = """ -fake1:%s.fake_plugin.Fake1,fake2:%s.fake_plugin.Fake2 -""".strip() % (FAKE_PATH, FAKE_PATH) - - -def setup_metaplugin_conf(has_l3=True): - cfg.CONF.set_override('auth_url', 'http://localhost:35357/v2.0', - 'PROXY') - cfg.CONF.set_override('auth_region', 'RegionOne', 'PROXY') - cfg.CONF.set_override('admin_user', 'neutron', 'PROXY') - cfg.CONF.set_override('admin_password', 'password', 'PROXY') - cfg.CONF.set_override('admin_tenant_name', 'service', 'PROXY') - cfg.CONF.set_override('plugin_list', PLUGIN_LIST, 'META') - if has_l3: - cfg.CONF.set_override('l3_plugin_list', L3_PLUGIN_LIST, 'META') - else: - cfg.CONF.set_override('l3_plugin_list', "", 'META') - cfg.CONF.set_override('default_flavor', 'fake2', 'META') - cfg.CONF.set_override('default_l3_flavor', 'fake1', 'META') - cfg.CONF.set_override('base_mac', "12:34:56:78:90:ab") - #TODO(nati) remove this after subnet quota change is merged - cfg.CONF.set_override('max_dns_nameservers', 10) - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - - -# Hooks registered by metaplugin must not exist for other plugins UT. -# So hooks must be unregistered (overwrite to None in fact). -def unregister_meta_hooks(): - db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook( - models_v2.Network, 'metaplugin_net', None, None, None) - db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook( - models_v2.Port, 'metaplugin_port', None, None, None) - - -class MetaNeutronPluginV2Test(base.BaseTestCase): - """Class conisting of MetaNeutronPluginV2 unit tests.""" - - has_l3 = True - - def setUp(self): - super(MetaNeutronPluginV2Test, self).setUp() - db._ENGINE = None - db._MAKER = None - self.fake_tenant_id = uuidutils.generate_uuid() - self.context = context.get_admin_context() - - db.configure_db() - self.addCleanup(db.clear_db) - self.addCleanup(unregister_meta_hooks) - - setup_metaplugin_conf(self.has_l3) - - self.client_cls_p = mock.patch('neutronclient.v2_0.client.Client') - client_cls = self.client_cls_p.start() - self.client_inst = mock.Mock() - client_cls.return_value = self.client_inst - self.client_inst.create_network.return_value = \ - {'id': 'fake_id'} - self.client_inst.create_port.return_value = \ - {'id': 'fake_id'} - self.client_inst.create_subnet.return_value = \ - {'id': 'fake_id'} - self.client_inst.update_network.return_value = \ - {'id': 'fake_id'} - self.client_inst.update_port.return_value = \ - {'id': 'fake_id'} - self.client_inst.update_subnet.return_value = \ - {'id': 'fake_id'} - self.client_inst.delete_network.return_value = True - self.client_inst.delete_port.return_value = True - self.client_inst.delete_subnet.return_value = True - plugin = (meta_neutron_plugin.MetaPluginV2.__module__ + '.' - + meta_neutron_plugin.MetaPluginV2.__name__) - self.setup_coreplugin(plugin) - self.plugin = meta_neutron_plugin.MetaPluginV2(configfile=None) - - def _fake_network(self, flavor): - data = {'network': {'name': flavor, - 'admin_state_up': True, - 'shared': False, - 'router:external': [], - 'tenant_id': self.fake_tenant_id, - ext_flavor.FLAVOR_NETWORK: flavor}} - return data - - def _fake_port(self, net_id): - return {'port': {'name': net_id, - 'network_id': net_id, - 'admin_state_up': True, - 'device_id': 'bad_device_id', - 'device_owner': 'bad_device_owner', - 'admin_state_up': True, - 'host_routes': [], - 'fixed_ips': [], - 'mac_address': - self.plugin._generate_mac(self.context, net_id), - 'tenant_id': self.fake_tenant_id}} - - def _fake_subnet(self, net_id): - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.254'}] - return {'subnet': {'name': net_id, - 'network_id': net_id, - 'gateway_ip': '10.0.0.1', - 'dns_nameservers': ['10.0.0.2'], - 'host_routes': [], - 'cidr': '10.0.0.0/24', - 'allocation_pools': allocation_pools, - 'enable_dhcp': True, - 'ip_version': 4}} - - def _fake_router(self, flavor): - data = {'router': {'name': flavor, 'admin_state_up': True, - 'tenant_id': self.fake_tenant_id, - ext_flavor.FLAVOR_ROUTER: flavor, - 'external_gateway_info': None}} - return data - - def test_create_delete_network(self): - network1 = self._fake_network('fake1') - ret1 = self.plugin.create_network(self.context, network1) - self.assertEqual('fake1', ret1[ext_flavor.FLAVOR_NETWORK]) - - network2 = self._fake_network('fake2') - ret2 = self.plugin.create_network(self.context, network2) - self.assertEqual('fake2', ret2[ext_flavor.FLAVOR_NETWORK]) - - network3 = self._fake_network('proxy') - ret3 = self.plugin.create_network(self.context, network3) - self.assertEqual('proxy', ret3[ext_flavor.FLAVOR_NETWORK]) - - db_ret1 = self.plugin.get_network(self.context, ret1['id']) - self.assertEqual('fake1', db_ret1['name']) - - db_ret2 = self.plugin.get_network(self.context, ret2['id']) - self.assertEqual('fake2', db_ret2['name']) - - db_ret3 = self.plugin.get_network(self.context, ret3['id']) - self.assertEqual('proxy', db_ret3['name']) - - db_ret4 = self.plugin.get_networks(self.context) - self.assertEqual(3, len(db_ret4)) - - db_ret5 = self.plugin.get_networks( - self.context, - {ext_flavor.FLAVOR_NETWORK: ['fake1']}) - self.assertEqual(1, len(db_ret5)) - self.assertEqual('fake1', db_ret5[0]['name']) - self.plugin.delete_network(self.context, ret1['id']) - self.plugin.delete_network(self.context, ret2['id']) - self.plugin.delete_network(self.context, ret3['id']) - - def test_create_delete_port(self): - network1 = self._fake_network('fake1') - network_ret1 = self.plugin.create_network(self.context, network1) - network2 = self._fake_network('fake2') - network_ret2 = self.plugin.create_network(self.context, network2) - network3 = self._fake_network('proxy') - network_ret3 = self.plugin.create_network(self.context, network3) - - port1 = self._fake_port(network_ret1['id']) - port2 = self._fake_port(network_ret2['id']) - port3 = self._fake_port(network_ret3['id']) - - port1_ret = self.plugin.create_port(self.context, port1) - port2_ret = self.plugin.create_port(self.context, port2) - port3_ret = self.plugin.create_port(self.context, port3) - ports_all = self.plugin.get_ports(self.context) - - self.assertEqual(network_ret1['id'], port1_ret['network_id']) - self.assertEqual(network_ret2['id'], port2_ret['network_id']) - self.assertEqual(network_ret3['id'], port3_ret['network_id']) - self.assertEqual(3, len(ports_all)) - - port1_dict = self.plugin._make_port_dict(port1_ret) - port2_dict = self.plugin._make_port_dict(port2_ret) - port3_dict = self.plugin._make_port_dict(port3_ret) - - self.assertEqual(port1_dict, port1_ret) - self.assertEqual(port2_dict, port2_ret) - self.assertEqual(port3_dict, port3_ret) - - port1['port']['admin_state_up'] = False - port2['port']['admin_state_up'] = False - port3['port']['admin_state_up'] = False - self.plugin.update_port(self.context, port1_ret['id'], port1) - self.plugin.update_port(self.context, port2_ret['id'], port2) - self.plugin.update_port(self.context, port3_ret['id'], port3) - port_in_db1 = self.plugin.get_port(self.context, port1_ret['id']) - port_in_db2 = self.plugin.get_port(self.context, port2_ret['id']) - port_in_db3 = self.plugin.get_port(self.context, port3_ret['id']) - self.assertEqual(False, port_in_db1['admin_state_up']) - self.assertEqual(False, port_in_db2['admin_state_up']) - self.assertEqual(False, port_in_db3['admin_state_up']) - - self.plugin.delete_port(self.context, port1_ret['id']) - self.plugin.delete_port(self.context, port2_ret['id']) - self.plugin.delete_port(self.context, port3_ret['id']) - - self.plugin.delete_network(self.context, network_ret1['id']) - self.plugin.delete_network(self.context, network_ret2['id']) - self.plugin.delete_network(self.context, network_ret3['id']) - - def test_create_delete_subnet(self): - # for this test we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - network1 = self._fake_network('fake1') - network_ret1 = self.plugin.create_network(self.context, network1) - network2 = self._fake_network('fake2') - network_ret2 = self.plugin.create_network(self.context, network2) - network3 = self._fake_network('proxy') - network_ret3 = self.plugin.create_network(self.context, network3) - - subnet1 = self._fake_subnet(network_ret1['id']) - subnet2 = self._fake_subnet(network_ret2['id']) - subnet3 = self._fake_subnet(network_ret3['id']) - - subnet1_ret = self.plugin.create_subnet(self.context, subnet1) - subnet2_ret = self.plugin.create_subnet(self.context, subnet2) - subnet3_ret = self.plugin.create_subnet(self.context, subnet3) - self.assertEqual(network_ret1['id'], subnet1_ret['network_id']) - self.assertEqual(network_ret2['id'], subnet2_ret['network_id']) - self.assertEqual(network_ret3['id'], subnet3_ret['network_id']) - - subnet_in_db1 = self.plugin.get_subnet(self.context, subnet1_ret['id']) - subnet_in_db2 = self.plugin.get_subnet(self.context, subnet2_ret['id']) - subnet_in_db3 = self.plugin.get_subnet(self.context, subnet3_ret['id']) - - subnet1['subnet']['allocation_pools'].pop() - subnet2['subnet']['allocation_pools'].pop() - subnet3['subnet']['allocation_pools'].pop() - - self.plugin.update_subnet(self.context, - subnet1_ret['id'], subnet1) - self.plugin.update_subnet(self.context, - subnet2_ret['id'], subnet2) - self.plugin.update_subnet(self.context, - subnet3_ret['id'], subnet3) - subnet_in_db1 = self.plugin.get_subnet(self.context, subnet1_ret['id']) - subnet_in_db2 = self.plugin.get_subnet(self.context, subnet2_ret['id']) - subnet_in_db3 = self.plugin.get_subnet(self.context, subnet3_ret['id']) - - self.assertEqual(4, subnet_in_db1['ip_version']) - self.assertEqual(4, subnet_in_db2['ip_version']) - self.assertEqual(4, subnet_in_db3['ip_version']) - - self.plugin.delete_subnet(self.context, subnet1_ret['id']) - self.plugin.delete_subnet(self.context, subnet2_ret['id']) - self.plugin.delete_subnet(self.context, subnet3_ret['id']) - - self.plugin.delete_network(self.context, network_ret1['id']) - self.plugin.delete_network(self.context, network_ret2['id']) - self.plugin.delete_network(self.context, network_ret3['id']) - - def test_create_delete_router(self): - router1 = self._fake_router('fake1') - router_ret1 = self.plugin.create_router(self.context, router1) - router2 = self._fake_router('fake2') - router_ret2 = self.plugin.create_router(self.context, router2) - - self.assertEqual('fake1', router_ret1[ext_flavor.FLAVOR_ROUTER]) - self.assertEqual('fake2', router_ret2[ext_flavor.FLAVOR_ROUTER]) - - router_in_db1 = self.plugin.get_router(self.context, router_ret1['id']) - router_in_db2 = self.plugin.get_router(self.context, router_ret2['id']) - - self.assertEqual('fake1', router_in_db1[ext_flavor.FLAVOR_ROUTER]) - self.assertEqual('fake2', router_in_db2[ext_flavor.FLAVOR_ROUTER]) - - self.plugin.delete_router(self.context, router_ret1['id']) - self.plugin.delete_router(self.context, router_ret2['id']) - with testtools.ExpectedException(meta_neutron_plugin.FlavorNotFound): - self.plugin.get_router(self.context, router_ret1['id']) - - def test_extension_method(self): - self.assertEqual('fake1', self.plugin.fake_func()) - self.assertEqual('fake2', self.plugin.fake_func2()) - - def test_extension_not_implemented_method(self): - try: - self.plugin.not_implemented() - except AttributeError: - return - except Exception: - self.fail("AttributeError Error is not raised") - - self.fail("No Error is not raised") - - def test_create_network_flavor_fail(self): - with mock.patch('neutron.plugins.metaplugin.meta_db_v2.' - 'add_network_flavor_binding', - side_effect=Exception): - network = self._fake_network('fake1') - self.assertRaises(meta_neutron_plugin.FaildToAddFlavorBinding, - self.plugin.create_network, - self.context, - network) - count = self.plugin.get_networks_count(self.context) - self.assertEqual(count, 0) - - def test_create_router_flavor_fail(self): - with mock.patch('neutron.plugins.metaplugin.meta_db_v2.' - 'add_router_flavor_binding', - side_effect=Exception): - router = self._fake_router('fake1') - self.assertRaises(meta_neutron_plugin.FaildToAddFlavorBinding, - self.plugin.create_router, - self.context, - router) - count = self.plugin.get_routers_count(self.context) - self.assertEqual(count, 0) - - -class MetaNeutronPluginV2TestWithoutL3(MetaNeutronPluginV2Test): - """Tests without l3_plugin_list configration.""" - - has_l3 = False - - def test_supported_extension_aliases(self): - self.assertEqual(self.plugin.supported_extension_aliases, - ['flavor', 'external-net']) - - def test_create_delete_router(self): - self.skipTest("Test case without router") - - def test_create_router_flavor_fail(self): - self.skipTest("Test case without router") - - -class MetaNeutronPluginV2TestRpcFlavor(base.BaseTestCase): - """Tests for rpc_flavor.""" - - def setUp(self): - super(MetaNeutronPluginV2TestRpcFlavor, self).setUp() - db._ENGINE = None - db._MAKER = None - db.configure_db() - self.addCleanup(db.clear_db) - self.addCleanup(unregister_meta_hooks) - - def test_rpc_flavor(self): - setup_metaplugin_conf() - cfg.CONF.set_override('rpc_flavor', 'fake1', 'META') - self.plugin = meta_neutron_plugin.MetaPluginV2() - self.assertEqual(topics.PLUGIN, 'q-plugin') - ret = self.plugin.rpc_workers_supported() - self.assertFalse(ret) - - def test_invalid_rpc_flavor(self): - setup_metaplugin_conf() - cfg.CONF.set_override('rpc_flavor', 'fake-fake', 'META') - self.assertRaises(exc.Invalid, - meta_neutron_plugin.MetaPluginV2) - self.assertEqual(topics.PLUGIN, 'q-plugin') - - def test_rpc_flavor_multiple_rpc_workers(self): - setup_metaplugin_conf() - cfg.CONF.set_override('rpc_flavor', 'fake2', 'META') - self.plugin = meta_neutron_plugin.MetaPluginV2() - self.assertEqual(topics.PLUGIN, 'q-plugin') - ret = self.plugin.rpc_workers_supported() - self.assertTrue(ret) - ret = self.plugin.start_rpc_listeners() - self.assertEqual('OK', ret) diff --git a/neutron/tests/unit/midonet/__init__.py b/neutron/tests/unit/midonet/__init__.py deleted file mode 100644 index 439ff6594..000000000 --- a/neutron/tests/unit/midonet/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (C) 2012 Midokura Japan K.K. -# Copyright (C) 2013 Midokura PTE LTD -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/midonet/etc/midonet.ini.test b/neutron/tests/unit/midonet/etc/midonet.ini.test deleted file mode 100644 index 8e4fc847f..000000000 --- a/neutron/tests/unit/midonet/etc/midonet.ini.test +++ /dev/null @@ -1,16 +0,0 @@ -[midonet] - -# MidoNet API server URI -midonet_uri = http://localhost:8080/midonet-api - -# MidoNet admin username -username = admin - -# MidoNet admin password -password = passw0rd - -# Virtual provider router ID -provider_router_id = 00112233-0011-0011-0011-001122334455 - -# Virtual metadata router ID -metadata_router_id = ffeeddcc-ffee-ffee-ffee-ffeeddccbbaa diff --git a/neutron/tests/unit/midonet/mock_lib.py b/neutron/tests/unit/midonet/mock_lib.py deleted file mode 100644 index 9fdae9cd6..000000000 --- a/neutron/tests/unit/midonet/mock_lib.py +++ /dev/null @@ -1,265 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (C) 2013 Midokura PTE LTD -# All Rights Reserved. -# -# 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. -# -# @author: Ryu Ishimoto, Midokura Japan KK - -import mock -import uuid - - -def get_bridge_mock(id=None, **kwargs): - if id is None: - id = str(uuid.uuid4()) - - bridge = mock.Mock() - bridge.get_id.return_value = id - bridge.get_tenant_id.return_value = kwargs.get("tenant_id", "test-tenant") - bridge.get_name.return_value = kwargs.get("name", "net") - bridge.get_ports.return_value = [] - bridge.get_peer_ports.return_value = [] - bridge.get_admin_state_up.return_value = kwargs.get("admin_state_up", True) - return bridge - - -def get_bridge_port_mock(id=None, bridge_id=None, **kwargs): - if id is None: - id = str(uuid.uuid4()) - if bridge_id is None: - bridge_id = str(uuid.uuid4()) - - port = mock.Mock() - port.get_id.return_value = id - port.get_bridge_id.return_value = bridge_id - port.get_admin_state_up.return_value = kwargs.get("admin_state_up", True) - port.get_type.return_value = "Bridge" - port.create.return_value = port - return port - - -def get_chain_mock(id=None, tenant_id='test-tenant', name='chain', - rules=None): - if id is None: - id = str(uuid.uuid4()) - - if rules is None: - rules = [] - - chain = mock.Mock() - chain.get_id.return_value = id - chain.get_tenant_id.return_value = tenant_id - chain.get_name.return_value = name - chain.get_rules.return_value = rules - return chain - - -def get_port_group_mock(id=None, tenant_id='test-tenant', name='pg'): - if id is None: - id = str(uuid.uuid4()) - - port_group = mock.Mock() - port_group.get_id.return_value = id - port_group.get_tenant_id.return_value = tenant_id - port_group.get_name.return_value = name - return port_group - - -def get_router_mock(id=None, **kwargs): - if id is None: - id = str(uuid.uuid4()) - - router = mock.Mock() - router.get_id.return_value = id - router.get_tenant_id.return_value = kwargs.get("tenant_id", "test-tenant") - router.get_name.return_value = kwargs.get("name", "router") - router.get_ports.return_value = [] - router.get_peer_ports.return_value = [] - router.get_routes.return_value = [] - router.get_admin_state_up.return_value = kwargs.get("admin_state_up", True) - return router - - -def get_rule_mock(id=None, chain_id=None, properties=None): - if id is None: - id = str(uuid.uuid4()) - - if chain_id is None: - chain_id = str(uuid.uuid4()) - - if properties is None: - properties = {} - - rule = mock.Mock() - rule.get_id.return_value = id - rule.get_chain_id.return_value = chain_id - rule.get_properties.return_value = properties - return rule - - -def get_subnet_mock(bridge_id=None, gateway_ip='10.0.0.1', - subnet_prefix='10.0.0.0', subnet_len=int(24)): - if bridge_id is None: - bridge_id = str(uuid.uuid4()) - - subnet = mock.Mock() - subnet.get_id.return_value = subnet_prefix + '/' + str(subnet_len) - subnet.get_bridge_id.return_value = bridge_id - subnet.get_default_gateway.return_value = gateway_ip - subnet.get_subnet_prefix.return_value = subnet_prefix - subnet.get_subnet_length.return_value = subnet_len - return subnet - - -class MidonetLibMockConfig(): - - def __init__(self, inst): - self.inst = inst - - def _create_bridge(self, **kwargs): - return get_bridge_mock(**kwargs) - - def _create_router(self, **kwargs): - return get_router_mock(**kwargs) - - def _create_subnet(self, bridge, gateway_ip, subnet_prefix, subnet_len): - return get_subnet_mock(bridge.get_id(), gateway_ip=gateway_ip, - subnet_prefix=subnet_prefix, - subnet_len=subnet_len) - - def _add_bridge_port(self, bridge, **kwargs): - return get_bridge_port_mock(bridge_id=bridge.get_id(), **kwargs) - - def _get_bridge(self, id): - return get_bridge_mock(id=id) - - def _get_port(self, id): - return get_bridge_port_mock(id=id) - - def _get_router(self, id): - return get_router_mock(id=id) - - def _update_bridge(self, id, **kwargs): - return get_bridge_mock(id=id, **kwargs) - - def setup(self): - # Bridge methods side effects - self.inst.create_bridge.side_effect = self._create_bridge - self.inst.get_bridge.side_effect = self._get_bridge - self.inst.update_bridge.side_effect = self._update_bridge - - # Subnet methods side effects - self.inst.create_subnet.side_effect = self._create_subnet - - # Port methods side effects - ex_bp = self.inst.add_bridge_port - ex_bp.side_effect = self._add_bridge_port - self.inst.get_port.side_effect = self._get_port - - # Router methods side effects - self.inst.create_router.side_effect = self._create_router - self.inst.get_router.side_effect = self._get_router - - -class MidoClientMockConfig(): - - def __init__(self, inst): - self.inst = inst - self.chains_in = None - self.port_groups_in = None - self.chains_out = None - self.rules_out = None - self.port_groups_out = None - - def _get_query_tenant_id(self, query): - if query is not None and query['tenant_id']: - tenant_id = query['tenant_id'] - else: - tenant_id = 'test-tenant' - return tenant_id - - def _get_bridge(self, id): - return get_bridge_mock(id=id) - - def _get_chain(self, id, query=None): - if not self.chains_in: - return [] - - tenant_id = self._get_query_tenant_id(query) - for chain in self.chains_in: - chain_id = chain['id'] - if chain_id is id: - rule_mocks = [] - if 'rules' in chain: - for rule in chain['rules']: - rule_mocks.append( - get_rule_mock(id=rule['id'], - chain_id=id, - properties=rule['properties'])) - - return get_chain_mock(id=chain_id, name=chain['name'], - tenant_id=tenant_id, rules=rule_mocks) - return None - - def _get_chains(self, query=None): - if not self.chains_in: - return [] - - tenant_id = self._get_query_tenant_id(query) - self.chains_out = [] - self.rules_out = [] - for chain in self.chains_in: - chain_id = chain['id'] - - rule_mocks = [] - if 'rules' in chain: - for rule in chain['rules']: - rule_mocks.append( - get_rule_mock(id=rule['id'], - chain_id=id, - properties=rule['properties'])) - self.rules_out += rule_mocks - - self.chains_out.append(get_chain_mock(id=chain_id, - name=chain['name'], - tenant_id=tenant_id, - rules=rule_mocks)) - return self.chains_out - - def _get_port_groups(self, query=None): - if not self.port_groups_in: - return [] - - tenant_id = self._get_query_tenant_id(query) - self.port_groups_out = [] - for port_group in self.port_groups_in: - self.port_groups_out.append(get_port_group_mock( - id=port_group['id'], name=port_group['name'], - tenant_id=tenant_id)) - return self.port_groups_out - - def _get_router(self, id): - return get_router_mock(id=id) - - def _add_bridge_port(self, bridge): - return get_bridge_port_mock(bridge_id=bridge.get_id()) - - def setup(self): - self.inst.get_bridge.side_effect = self._get_bridge - self.inst.get_chains.side_effect = self._get_chains - self.inst.get_chain.side_effect = self._get_chain - self.inst.get_port_groups.side_effect = self._get_port_groups - self.inst.get_router.side_effect = self._get_router - self.inst.add_bridge_port.side_effect = self._add_bridge_port diff --git a/neutron/tests/unit/midonet/test_midonet_driver.py b/neutron/tests/unit/midonet/test_midonet_driver.py deleted file mode 100644 index 67677c92a..000000000 --- a/neutron/tests/unit/midonet/test_midonet_driver.py +++ /dev/null @@ -1,55 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (C) 2012 Midokura Japan K.K. -# Copyright (C) 2013 Midokura PTE LTD -# All Rights Reserved. -# -# 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. -# -# @author: Rossella Sblendido, Midokura Japan KK - -import mock - -from neutron.agent.common import config -from neutron.agent.linux import dhcp -from neutron.common import config as base_config -import neutron.plugins.midonet.agent.midonet_driver as driver -from neutron.tests import base - - -class FakeNetwork: - id = 'aaaabbbb-cccc-dddd-eeee-ffff00001111' - namespace = 'qdhcp-ns' - - -class TestDhcpNoOpDriver(base.BaseTestCase): - def setUp(self): - super(TestDhcpNoOpDriver, self).setUp() - self.conf = config.setup_conf() - config.register_interface_driver_opts_helper(self.conf) - self.conf.register_opts(base_config.core_opts) - self.conf.register_opts(dhcp.OPTS) - self.conf.enable_isolated_metadata = True - self.conf.use_namespaces = True - instance = mock.patch("neutron.agent.linux.dhcp.DeviceManager") - self.mock_mgr = instance.start() - - def test_disable_no_retain_port(self): - dhcp_driver = driver.DhcpNoOpDriver(self.conf, FakeNetwork()) - dhcp_driver.disable(retain_port=False) - self.assertTrue(self.mock_mgr.return_value.destroy.called) - - def test_disable_retain_port(self): - dhcp_driver = driver.DhcpNoOpDriver(self.conf, FakeNetwork()) - dhcp_driver.disable(retain_port=True) - self.assertFalse(self.mock_mgr.return_value.destroy.called) diff --git a/neutron/tests/unit/midonet/test_midonet_lib.py b/neutron/tests/unit/midonet/test_midonet_lib.py deleted file mode 100644 index bed900fa3..000000000 --- a/neutron/tests/unit/midonet/test_midonet_lib.py +++ /dev/null @@ -1,189 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (C) 2012 Midokura Japan K.K. -# Copyright (C) 2013 Midokura PTE LTD -# All Rights Reserved. -# -# 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. -# -# @author: Ryu Ishimoto, Midokura Japan KK -# @author: Tomoe Sugihara, Midokura Japan KK -import sys - -import mock -import testtools -import webob.exc as w_exc - -from neutron.openstack.common import uuidutils -with mock.patch.dict(sys.modules, {'midonetclient': mock.Mock()}): - from neutron.plugins.midonet import midonet_lib -import neutron.tests.unit.midonet.mock_lib as mock_lib - - -def _create_test_chain(id, name, tenant_id): - return {'id': id, 'name': name, 'tenant_id': tenant_id} - - -def _create_test_port_group(id, name, tenant_id): - return {"id": id, "name": name, "tenant_id": tenant_id} - - -class MidoClientTestCase(testtools.TestCase): - - def setUp(self): - super(MidoClientTestCase, self).setUp() - self._tenant_id = 'test-tenant' - self.mock_api = mock.Mock() - self.mock_api_cfg = mock_lib.MidoClientMockConfig(self.mock_api) - self.mock_api_cfg.setup() - self.client = midonet_lib.MidoClient(self.mock_api) - - def test_delete_chains_by_names(self): - - tenant_id = uuidutils.generate_uuid() - chain1_id = uuidutils.generate_uuid() - chain1 = _create_test_chain(chain1_id, "chain1", tenant_id) - - chain2_id = uuidutils.generate_uuid() - chain2 = _create_test_chain(chain2_id, "chain2", tenant_id) - - calls = [mock.call.delete_chain(chain1_id), - mock.call.delete_chain(chain2_id)] - self.mock_api_cfg.chains_in = [chain2, chain1] - self.client.delete_chains_by_names(tenant_id, ["chain1", "chain2"]) - - self.mock_api.assert_has_calls(calls, any_order=True) - - def test_delete_port_group_by_name(self): - - tenant_id = uuidutils.generate_uuid() - pg1_id = uuidutils.generate_uuid() - pg1 = _create_test_port_group(pg1_id, "pg1", tenant_id) - pg2_id = uuidutils.generate_uuid() - pg2 = _create_test_port_group(pg2_id, "pg2", tenant_id) - - self.mock_api_cfg.port_groups_in = [pg1, pg2] - self.client.delete_port_group_by_name(tenant_id, "pg1") - self.mock_api.delete_port_group.assert_called_once_with(pg1_id) - - def test_create_dhcp(self): - - bridge = mock.Mock() - - gateway_ip = "192.168.1.1" - cidr = "192.168.1.0/24" - host_rts = [{'destination': '10.0.0.0/24', 'nexthop': '10.0.0.1'}, - {'destination': '10.0.1.0/24', 'nexthop': '10.0.1.1'}] - dns_servers = ["8.8.8.8", "8.8.4.4"] - - dhcp_call = mock.call.add_bridge_dhcp(bridge, gateway_ip, cidr, - host_rts=host_rts, - dns_nservers=dns_servers) - - self.client.create_dhcp(bridge, gateway_ip, cidr, host_rts=host_rts, - dns_servers=dns_servers) - self.mock_api.assert_has_calls([dhcp_call]) - - def test_delete_dhcp(self): - - bridge = mock.Mock() - subnet = mock.Mock() - subnet.get_subnet_prefix.return_value = "10.0.0.0" - subnets = mock.MagicMock(return_value=[subnet]) - bridge.get_dhcp_subnets.side_effect = subnets - self.client.delete_dhcp(bridge, "10.0.0.0/24") - bridge.assert_has_calls(mock.call.get_dhcp_subnets) - subnet.assert_has_calls([mock.call.get_subnet_prefix(), - mock.call.delete()]) - - def test_add_dhcp_host(self): - - bridge = mock.Mock() - dhcp_subnet_call = mock.call.get_dhcp_subnet("10.0.0.0_24") - ip_addr_call = dhcp_subnet_call.add_dhcp_host().ip_addr("10.0.0.10") - mac_addr_call = ip_addr_call.mac_addr("2A:DB:6B:8C:19:99") - calls = [dhcp_subnet_call, ip_addr_call, mac_addr_call, - mac_addr_call.create()] - - self.client.add_dhcp_host(bridge, "10.0.0.0/24", "10.0.0.10", - "2A:DB:6B:8C:19:99") - bridge.assert_has_calls(calls, any_order=True) - - def test_add_dhcp_route_option(self): - - bridge = mock.Mock() - subnet = bridge.get_dhcp_subnet.return_value - subnet.get_opt121_routes.return_value = None - dhcp_subnet_call = mock.call.get_dhcp_subnet("10.0.0.0_24") - dst_ip = "10.0.0.3/24" - gw_ip = "10.0.0.1" - prefix, length = dst_ip.split("/") - routes = [{'destinationPrefix': prefix, 'destinationLength': length, - 'gatewayAddr': gw_ip}] - opt121_routes_call = dhcp_subnet_call.opt121_routes(routes) - calls = [dhcp_subnet_call, opt121_routes_call, - opt121_routes_call.update()] - - self.client.add_dhcp_route_option(bridge, "10.0.0.0/24", - gw_ip, dst_ip) - bridge.assert_has_calls(calls, any_order=True) - - def test_get_router_error(self): - self.mock_api.get_router.side_effect = w_exc.HTTPInternalServerError() - self.assertRaises(midonet_lib.MidonetApiException, - self.client.get_router, uuidutils.generate_uuid()) - - def test_get_router_not_found(self): - self.mock_api.get_router.side_effect = w_exc.HTTPNotFound() - self.assertRaises(midonet_lib.MidonetResourceNotFound, - self.client.get_router, uuidutils.generate_uuid()) - - def test_get_bridge_error(self): - self.mock_api.get_bridge.side_effect = w_exc.HTTPInternalServerError() - self.assertRaises(midonet_lib.MidonetApiException, - self.client.get_bridge, uuidutils.generate_uuid()) - - def test_get_bridge_not_found(self): - self.mock_api.get_bridge.side_effect = w_exc.HTTPNotFound() - self.assertRaises(midonet_lib.MidonetResourceNotFound, - self.client.get_bridge, uuidutils.generate_uuid()) - - def test_get_bridge(self): - bridge_id = uuidutils.generate_uuid() - - bridge = self.client.get_bridge(bridge_id) - - self.assertIsNotNone(bridge) - self.assertEqual(bridge.get_id(), bridge_id) - self.assertTrue(bridge.get_admin_state_up()) - - def test_add_bridge_port(self): - bridge_id = uuidutils.generate_uuid() - - bridge = self.client.get_bridge(bridge_id) - - self.assertIsNotNone(bridge) - - port = self.client.add_bridge_port(bridge) - - self.assertEqual(bridge.get_id(), port.get_bridge_id()) - self.assertTrue(port.get_admin_state_up()) - - def test_get_router(self): - router_id = uuidutils.generate_uuid() - - router = self.client.get_router(router_id) - - self.assertIsNotNone(router) - self.assertEqual(router.get_id(), router_id) - self.assertTrue(router.get_admin_state_up()) diff --git a/neutron/tests/unit/midonet/test_midonet_plugin.py b/neutron/tests/unit/midonet/test_midonet_plugin.py deleted file mode 100644 index 46ed5bf0d..000000000 --- a/neutron/tests/unit/midonet/test_midonet_plugin.py +++ /dev/null @@ -1,218 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (C) 2012 Midokura Japan K.K. -# Copyright (C) 2013 Midokura PTE LTD -# All Rights Reserved. -# -# 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. -# -# @author: Rossella Sblendido, Midokura Europe SARL -# @author: Ryu Ishimoto, Midokura Japan KK -# @author: Tomoe Sugihara, Midokura Japan KK - -import mock -import os -import sys - -import neutron.common.test_lib as test_lib -from neutron.extensions import portbindings -from neutron.tests.unit import _test_extension_portbindings as test_bindings -import neutron.tests.unit.midonet.mock_lib as mock_lib -import neutron.tests.unit.test_db_plugin as test_plugin -import neutron.tests.unit.test_extension_security_group as sg -import neutron.tests.unit.test_l3_plugin as test_l3_plugin - -MIDOKURA_PKG_PATH = "neutron.plugins.midonet.plugin" -MIDONET_PLUGIN_NAME = ('%s.MidonetPluginV2' % MIDOKURA_PKG_PATH) - - -class MidonetPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - - def setUp(self, - plugin=MIDONET_PLUGIN_NAME, - ext_mgr=None, - service_plugins=None): - self.mock_api = mock.patch( - 'neutron.plugins.midonet.midonet_lib.MidoClient') - etc_path = os.path.join(os.path.dirname(__file__), 'etc') - test_lib.test_config['config_files'] = [os.path.join( - etc_path, 'midonet.ini.test')] - - p = mock.patch.dict(sys.modules, {'midonetclient': mock.Mock()}) - p.start() - # dict patches must be explicitly stopped - self.addCleanup(p.stop) - self.instance = self.mock_api.start() - mock_cfg = mock_lib.MidonetLibMockConfig(self.instance.return_value) - mock_cfg.setup() - super(MidonetPluginV2TestCase, self).setUp(plugin=plugin, - ext_mgr=ext_mgr) - - def tearDown(self): - super(MidonetPluginV2TestCase, self).tearDown() - self.mock_api.stop() - - -class TestMidonetNetworksV2(test_plugin.TestNetworksV2, - MidonetPluginV2TestCase): - - pass - - -class TestMidonetL3NatTestCase(MidonetPluginV2TestCase, - test_l3_plugin.L3NatDBIntTestCase): - def setUp(self, - plugin=MIDONET_PLUGIN_NAME, - ext_mgr=None, - service_plugins=None): - super(TestMidonetL3NatTestCase, self).setUp(plugin=plugin, - ext_mgr=None, - service_plugins=None) - - def test_floatingip_with_invalid_create_port(self): - self._test_floatingip_with_invalid_create_port(MIDONET_PLUGIN_NAME) - - def test_floatingip_assoc_no_port(self): - with self.subnet(cidr='200.0.0.0/24') as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - res = super(TestMidonetL3NatTestCase, self)._create_floatingip( - self.fmt, public_sub['subnet']['network_id']) - # Cleanup - floatingip = self.deserialize(self.fmt, res) - self._delete('floatingips', floatingip['floatingip']['id']) - self.assertFalse(self.instance.return_value.add_static_nat.called) - - def test_floatingip_assoc_with_port(self): - with self.subnet(cidr='200.0.0.0/24') as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - with self.port() as private_port: - with self.router() as r: - # We need to hook up the private subnet to the external - # network in order to associate the fip. - sid = private_port['port']['fixed_ips'][0]['subnet_id'] - private_sub = {'subnet': {'id': sid}} - self._add_external_gateway_to_router( - r['router']['id'], - public_sub['subnet']['network_id']) - - # Check that get_link_port was called - if not, Source NAT - # will not be set up correctly on the MidoNet side - self.assertTrue( - self.instance.return_value.get_link_port.called) - - self._router_interface_action('add', r['router']['id'], - private_sub['subnet']['id'], - None) - - # Create the fip. - res = super(TestMidonetL3NatTestCase, - self)._create_floatingip( - self.fmt, - public_sub['subnet']['network_id'], - port_id=private_port['port']['id']) - - # Cleanup the resources used for the test - floatingip = self.deserialize(self.fmt, res) - self._delete('floatingips', floatingip['floatingip']['id']) - self._remove_external_gateway_from_router( - r['router']['id'], - public_sub['subnet']['network_id']) - self._router_interface_action('remove', - r['router']['id'], - private_sub['subnet']['id'], - None) - self.assertTrue(self.instance.return_value.add_static_nat.called) - - -class TestMidonetSecurityGroupsTestCase(sg.SecurityGroupDBTestCase): - - _plugin_name = ('%s.MidonetPluginV2' % MIDOKURA_PKG_PATH) - - def setUp(self): - self.mock_api = mock.patch( - 'neutron.plugins.midonet.midonet_lib.MidoClient') - etc_path = os.path.join(os.path.dirname(__file__), 'etc') - test_lib.test_config['config_files'] = [os.path.join( - etc_path, 'midonet.ini.test')] - - self.instance = self.mock_api.start() - mock_cfg = mock_lib.MidonetLibMockConfig(self.instance.return_value) - mock_cfg.setup() - p = mock.patch.dict(sys.modules, {'midonetclient': mock.Mock()}) - p.start() - # dict patches must be explicitly stopped - self.addCleanup(p.stop) - super(TestMidonetSecurityGroupsTestCase, self).setUp(self._plugin_name) - - -class TestMidonetSecurityGroup(sg.TestSecurityGroups, - TestMidonetSecurityGroupsTestCase): - - pass - - -class TestMidonetSubnetsV2(test_plugin.TestSubnetsV2, - MidonetPluginV2TestCase): - - # IPv6 is not supported by MidoNet yet. Ignore tests that attempt to - # create IPv6 subnet. - def test_create_subnet_inconsistent_ipv6_cidrv4(self): - pass - - def test_create_subnet_inconsistent_ipv6_dns_v4(self): - pass - - def test_create_subnet_with_v6_allocation_pool(self): - pass - - def test_update_subnet_inconsistent_ipv6_gatewayv4(self): - pass - - def test_update_subnet_inconsistent_ipv6_hostroute_dst_v4(self): - pass - - def test_update_subnet_inconsistent_ipv6_hostroute_np_v4(self): - pass - - def test_create_subnet_inconsistent_ipv6_gatewayv4(self): - pass - - def test_create_subnet_dhcp_disabled(self): - super(TestMidonetSubnetsV2, self)._test_create_subnet( - enable_dhcp=False) - self.assertFalse(self.instance.return_value.create_dhcp.called) - - -class TestMidonetPortsV2(test_plugin.TestPortsV2, - MidonetPluginV2TestCase): - - # IPv6 is not supported by MidoNet yet. Ignore tests that attempt to - # create IPv6 subnet. - - def test_requested_subnet_id_v4_and_v6(self): - pass - - def test_vif_port_binding(self): - with self.port(name='myname') as port: - self.assertEqual('midonet', port['port']['binding:vif_type']) - self.assertTrue(port['port']['admin_state_up']) - - -class TestMidonetPluginPortBinding(test_bindings.PortBindingsTestCase, - MidonetPluginV2TestCase): - - VIF_TYPE = portbindings.VIF_TYPE_MIDONET - HAS_PORT_FILTER = True - - def setUp(self): - super(TestMidonetPluginPortBinding, self).setUp() diff --git a/neutron/tests/unit/ml2/__init__.py b/neutron/tests/unit/ml2/__init__.py deleted file mode 100644 index 788cea1f7..000000000 --- a/neutron/tests/unit/ml2/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/ml2/_test_mech_agent.py b/neutron/tests/unit/ml2/_test_mech_agent.py deleted file mode 100644 index 4fbdc10e5..000000000 --- a/neutron/tests/unit/ml2/_test_mech_agent.py +++ /dev/null @@ -1,218 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - - -from neutron.extensions import portbindings -from neutron.plugins.ml2 import driver_api as api -from neutron.tests import base - -NETWORK_ID = "fake_network" -PORT_ID = "fake_port" - - -class FakeNetworkContext(api.NetworkContext): - def __init__(self, segments): - self._network_segments = segments - - @property - def current(self): - return {'id': NETWORK_ID} - - @property - def original(self): - return None - - @property - def network_segments(self): - return self._network_segments - - -class FakePortContext(api.PortContext): - def __init__(self, agent_type, agents, segments, - vnic_type=portbindings.VNIC_NORMAL): - self._agent_type = agent_type - self._agents = agents - self._network_context = FakeNetworkContext(segments) - self._bound_vnic_type = vnic_type - self._bound_segment_id = None - self._bound_vif_type = None - self._bound_vif_details = None - - @property - def current(self): - return {'id': PORT_ID, - 'binding:vnic_type': self._bound_vnic_type} - - @property - def original(self): - return None - - @property - def network(self): - return self._network_context - - @property - def bound_segment(self): - if self._bound_segment_id: - for segment in self._network_context.network_segments: - if segment[api.ID] == self._bound_segment_id: - return segment - - @property - def original_bound_segment(self): - return None - - @property - def bound_driver(self): - return None - - @property - def original_bound_driver(self): - return None - - def host_agents(self, agent_type): - if agent_type == self._agent_type: - return self._agents - else: - return [] - - def set_binding(self, segment_id, vif_type, vif_details): - self._bound_segment_id = segment_id - self._bound_vif_type = vif_type - self._bound_vif_details = vif_details - - -class AgentMechanismBaseTestCase(base.BaseTestCase): - # These following must be overriden for the specific mechanism - # driver being tested: - VIF_TYPE = None - CAP_PORT_FILTER = None - AGENT_TYPE = None - AGENTS = None - AGENTS_DEAD = None - AGENTS_BAD = None - - def _check_unbound(self, context): - self.assertIsNone(context._bound_segment_id) - self.assertIsNone(context._bound_vif_type) - self.assertIsNone(context._bound_vif_details) - - def _check_bound(self, context, segment): - self.assertEqual(context._bound_segment_id, segment[api.ID]) - self.assertEqual(context._bound_vif_type, self.VIF_TYPE) - vif_details = context._bound_vif_details - self.assertIsNotNone(vif_details) - self.assertEqual(vif_details[portbindings.CAP_PORT_FILTER], - self.CAP_PORT_FILTER) - - -class AgentMechanismGenericTestCase(AgentMechanismBaseTestCase): - UNKNOWN_TYPE_SEGMENTS = [{api.ID: 'unknown_segment_id', - api.NETWORK_TYPE: 'no_such_type'}] - - def test_unknown_type(self): - context = FakePortContext(self.AGENT_TYPE, - self.AGENTS, - self.UNKNOWN_TYPE_SEGMENTS) - self.driver.bind_port(context) - self._check_unbound(context) - - -class AgentMechanismLocalTestCase(AgentMechanismBaseTestCase): - LOCAL_SEGMENTS = [{api.ID: 'unknown_segment_id', - api.NETWORK_TYPE: 'no_such_type'}, - {api.ID: 'local_segment_id', - api.NETWORK_TYPE: 'local'}] - - def test_type_local(self): - context = FakePortContext(self.AGENT_TYPE, - self.AGENTS, - self.LOCAL_SEGMENTS) - self.driver.bind_port(context) - self._check_bound(context, self.LOCAL_SEGMENTS[1]) - - def test_type_local_dead(self): - context = FakePortContext(self.AGENT_TYPE, - self.AGENTS_DEAD, - self.LOCAL_SEGMENTS) - self.driver.bind_port(context) - self._check_unbound(context) - - -class AgentMechanismFlatTestCase(AgentMechanismBaseTestCase): - FLAT_SEGMENTS = [{api.ID: 'unknown_segment_id', - api.NETWORK_TYPE: 'no_such_type'}, - {api.ID: 'flat_segment_id', - api.NETWORK_TYPE: 'flat', - api.PHYSICAL_NETWORK: 'fake_physical_network'}] - - def test_type_flat(self): - context = FakePortContext(self.AGENT_TYPE, - self.AGENTS, - self.FLAT_SEGMENTS) - self.driver.bind_port(context) - self._check_bound(context, self.FLAT_SEGMENTS[1]) - - def test_type_flat_bad(self): - context = FakePortContext(self.AGENT_TYPE, - self.AGENTS_BAD, - self.FLAT_SEGMENTS) - self.driver.bind_port(context) - self._check_unbound(context) - - -class AgentMechanismVlanTestCase(AgentMechanismBaseTestCase): - VLAN_SEGMENTS = [{api.ID: 'unknown_segment_id', - api.NETWORK_TYPE: 'no_such_type'}, - {api.ID: 'vlan_segment_id', - api.NETWORK_TYPE: 'vlan', - api.PHYSICAL_NETWORK: 'fake_physical_network', - api.SEGMENTATION_ID: 1234}] - - def test_type_vlan(self): - context = FakePortContext(self.AGENT_TYPE, - self.AGENTS, - self.VLAN_SEGMENTS) - self.driver.bind_port(context) - self._check_bound(context, self.VLAN_SEGMENTS[1]) - - def test_type_vlan_bad(self): - context = FakePortContext(self.AGENT_TYPE, - self.AGENTS_BAD, - self.VLAN_SEGMENTS) - self.driver.bind_port(context) - self._check_unbound(context) - - -class AgentMechanismGreTestCase(AgentMechanismBaseTestCase): - GRE_SEGMENTS = [{api.ID: 'unknown_segment_id', - api.NETWORK_TYPE: 'no_such_type'}, - {api.ID: 'gre_segment_id', - api.NETWORK_TYPE: 'gre', - api.SEGMENTATION_ID: 1234}] - - def test_type_gre(self): - context = FakePortContext(self.AGENT_TYPE, - self.AGENTS, - self.GRE_SEGMENTS) - self.driver.bind_port(context) - self._check_bound(context, self.GRE_SEGMENTS[1]) - - def test_type_gre_bad(self): - context = FakePortContext(self.AGENT_TYPE, - self.AGENTS_BAD, - self.GRE_SEGMENTS) - self.driver.bind_port(context) - self._check_unbound(context) diff --git a/neutron/tests/unit/ml2/drivers/__init__.py b/neutron/tests/unit/ml2/drivers/__init__.py deleted file mode 100644 index 788cea1f7..000000000 --- a/neutron/tests/unit/ml2/drivers/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/ml2/drivers/brocade/__init__.py b/neutron/tests/unit/ml2/drivers/brocade/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/ml2/drivers/brocade/test_brocade_mechanism_driver.py b/neutron/tests/unit/ml2/drivers/brocade/test_brocade_mechanism_driver.py deleted file mode 100644 index 2dac0fe2a..000000000 --- a/neutron/tests/unit/ml2/drivers/brocade/test_brocade_mechanism_driver.py +++ /dev/null @@ -1,69 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2013 OpenStack Foundation -# -# 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 neutron.openstack.common import importutils -from neutron.openstack.common import log as logging -from neutron.plugins.ml2 import config as ml2_config -from neutron.plugins.ml2.drivers.brocade import (mechanism_brocade - as brocademechanism) -from neutron.tests.unit import test_db_plugin - -LOG = logging.getLogger(__name__) -MECHANISM_NAME = ('neutron.plugins.ml2.' - 'drivers.brocade.mechanism_brocade.BrocadeMechanism') - - -class TestBrocadeMechDriverV2(test_db_plugin.NeutronDbPluginV2TestCase): - """Test Brocade VCS/VDX mechanism driver. - """ - - _mechanism_name = MECHANISM_NAME - - def setUp(self): - - _mechanism_name = MECHANISM_NAME - - ml2_opts = { - 'mechanism_drivers': ['brocade'], - 'tenant_network_types': ['vlan']} - - for opt, val in ml2_opts.items(): - ml2_config.cfg.CONF.set_override(opt, val, 'ml2') - - def mocked_brocade_init(self): - self._driver = mock.MagicMock() - - with mock.patch.object(brocademechanism.BrocadeMechanism, - 'brocade_init', new=mocked_brocade_init): - super(TestBrocadeMechDriverV2, self).setUp() - self.mechanism_driver = importutils.import_object(_mechanism_name) - - -class TestBrocadeMechDriverNetworksV2(test_db_plugin.TestNetworksV2, - TestBrocadeMechDriverV2): - pass - - -class TestBrocadeMechDriverPortsV2(test_db_plugin.TestPortsV2, - TestBrocadeMechDriverV2): - pass - - -class TestBrocadeMechDriverSubnetsV2(test_db_plugin.TestSubnetsV2, - TestBrocadeMechDriverV2): - pass diff --git a/neutron/tests/unit/ml2/drivers/cisco/__init__.py b/neutron/tests/unit/ml2/drivers/cisco/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/ml2/drivers/cisco/apic/__init__.py b/neutron/tests/unit/ml2/drivers/cisco/apic/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_client.py b/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_client.py deleted file mode 100644 index 23444033a..000000000 --- a/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_client.py +++ /dev/null @@ -1,272 +0,0 @@ -# Copyright (c) 2014 Cisco Systems -# All Rights Reserved. -# -# 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. -# -# @author: Henry Gessau, Cisco Systems - -import mock -import requests -import requests.exceptions - -from neutron.plugins.ml2.drivers.cisco.apic import apic_client as apic -from neutron.plugins.ml2.drivers.cisco.apic import exceptions as cexc -from neutron.tests import base -from neutron.tests.unit.ml2.drivers.cisco.apic import ( - test_cisco_apic_common as mocked) - - -class TestCiscoApicClient(base.BaseTestCase, mocked.ControllerMixin): - - def setUp(self): - super(TestCiscoApicClient, self).setUp() - self.set_up_mocks() - self.apic = apic.RestClient(mocked.APIC_HOST) - self.addCleanup(mock.patch.stopall) - - def _mock_authenticate(self, timeout=300): - self.reset_reponses() - self.mock_apic_manager_login_responses(timeout=timeout) - self.apic.login(mocked.APIC_USR, mocked.APIC_PWD) - - def test_login_by_instantiation(self): - self.reset_reponses() - self.mock_apic_manager_login_responses() - apic2 = apic.RestClient(mocked.APIC_HOST, - usr=mocked.APIC_USR, pwd=mocked.APIC_PWD) - self.assertIsNotNone(apic2.authentication) - self.assertEqual(apic2.username, mocked.APIC_USR) - - def test_client_session_login_ok(self): - self._mock_authenticate() - self.assertEqual( - self.apic.authentication['userName'], mocked.APIC_USR) - self.assertTrue(self.apic.api_base.startswith('http://')) - self.assertEqual(self.apic.username, mocked.APIC_USR) - self.assertIsNotNone(self.apic.authentication) - self.apic = apic.RestClient(mocked.APIC_HOST, mocked.APIC_PORT, - ssl=True) - self.assertTrue(self.apic.api_base.startswith('https://')) - - def test_client_session_login_fail(self): - self.mock_error_post_response(requests.codes.unauthorized, - code='599', - text=u'Fake error') - self.assertRaises(cexc.ApicResponseNotOk, self.apic.login, - mocked.APIC_USR, mocked.APIC_PWD) - - def test_client_session_login_timeout(self): - self.response['post'].append(requests.exceptions.Timeout) - self.assertRaises(cexc.ApicHostNoResponse, self.apic.login, - mocked.APIC_USR, mocked.APIC_PWD) - - def test_client_session_logout_ok(self): - self.mock_response_for_post('aaaLogout') - self.apic.logout() - self.assertIsNone(self.apic.authentication) - # Multiple signouts should not cause an error - self.apic.logout() - self.assertIsNone(self.apic.authentication) - - def test_client_session_logout_fail(self): - self._mock_authenticate() - self.mock_error_post_response(requests.codes.timeout, - code='123', text='failed') - self.assertRaises(cexc.ApicResponseNotOk, self.apic.logout) - - def test_query_not_logged_in(self): - self.apic.authentication = None - self.assertRaises(cexc.ApicSessionNotLoggedIn, - self.apic.fvTenant.get, mocked.APIC_TENANT) - - def test_query_no_response(self): - self._mock_authenticate() - requests.Session.get = mock.Mock(return_value=None) - self.assertRaises(cexc.ApicHostNoResponse, - self.apic.fvTenant.get, mocked.APIC_TENANT) - - def test_query_error_response_no_data(self): - self._mock_authenticate() - self.mock_error_get_response(requests.codes.bad) # No error attrs. - self.assertRaises(cexc.ApicResponseNotOk, - self.apic.fvTenant.get, mocked.APIC_TENANT) - - def test_generic_get_data(self): - self._mock_authenticate() - self.mock_response_for_get('topSystem', name='ifc1') - top_system = self.apic.get_data('class/topSystem') - self.assertIsNotNone(top_system) - name = top_system[0]['topSystem']['attributes']['name'] - self.assertEqual(name, 'ifc1') - - def test_session_timeout_refresh_ok(self): - self._mock_authenticate(timeout=-1) - # Client will do refresh before getting tenant - self.mock_response_for_get('aaaLogin', token='ok', - refreshTimeoutSeconds=300) - self.mock_response_for_get('fvTenant', name=mocked.APIC_TENANT) - tenant = self.apic.fvTenant.get(mocked.APIC_TENANT) - self.assertEqual(tenant['name'], mocked.APIC_TENANT) - - def test_session_timeout_refresh_no_cookie(self): - self._mock_authenticate(timeout=-1) - # Client will do refresh before getting tenant - self.mock_response_for_get('aaaLogin', notoken='test') - self.assertRaises(cexc.ApicResponseNoCookie, - self.apic.fvTenant.get, mocked.APIC_TENANT) - - def test_session_timeout_refresh_error(self): - self._mock_authenticate(timeout=-1) - self.mock_error_get_response(requests.codes.timeout, - code='503', text=u'timed out') - self.assertRaises(cexc.ApicResponseNotOk, - self.apic.fvTenant.get, mocked.APIC_TENANT) - - def test_session_timeout_refresh_timeout_error(self): - self._mock_authenticate(timeout=-1) - # Client will try to get refresh, we fake a refresh error. - self.mock_error_get_response(requests.codes.bad_request, - code='403', - text=u'Token was invalid. Expired.') - # Client will then try to re-login. - self.mock_apic_manager_login_responses() - # Finally the client will try to get the tenant. - self.mock_response_for_get('fvTenant', name=mocked.APIC_TENANT) - tenant = self.apic.fvTenant.get(mocked.APIC_TENANT) - self.assertEqual(tenant['name'], mocked.APIC_TENANT) - - def test_lookup_mo_bad_token_retry(self): - self._mock_authenticate() - # For the first get request we mock a bad token. - self.mock_error_get_response(requests.codes.bad_request, - code='403', - text=u'Token was invalid. Expired.') - # Client will then try to re-login. - self.mock_apic_manager_login_responses() - # Then the client will retry to get the tenant. - self.mock_response_for_get('fvTenant', name=mocked.APIC_TENANT) - tenant = self.apic.fvTenant.get(mocked.APIC_TENANT) - self.assertEqual(tenant['name'], mocked.APIC_TENANT) - - def test_use_unsupported_managed_object(self): - self._mock_authenticate() - # unittest.assertRaises cannot catch exceptions raised in - # __getattr__, so we need to defer the evaluation using lambda. - self.assertRaises(cexc.ApicManagedObjectNotSupported, - lambda: self.apic.nonexistentObject) - - def test_lookup_nonexistant_mo(self): - self._mock_authenticate() - self.mock_response_for_get('fvTenant') - self.assertIsNone(self.apic.fvTenant.get(mocked.APIC_TENANT)) - - def test_lookup_existing_mo(self): - self._mock_authenticate() - self.mock_response_for_get('fvTenant', name='infra') - tenant = self.apic.fvTenant.get('infra') - self.assertEqual(tenant['name'], 'infra') - - def test_list_mos_ok(self): - self._mock_authenticate() - self.mock_response_for_get('fvTenant', name='t1') - self.mock_append_to_response('fvTenant', name='t2') - tlist = self.apic.fvTenant.list_all() - self.assertIsNotNone(tlist) - self.assertEqual(len(tlist), 2) - self.assertIn({'name': 't1'}, tlist) - self.assertIn({'name': 't2'}, tlist) - - def test_list_mo_names_ok(self): - self._mock_authenticate() - self.mock_response_for_get('fvTenant', name='t1') - self.mock_append_to_response('fvTenant', name='t2') - tnlist = self.apic.fvTenant.list_names() - self.assertIsNotNone(tnlist) - self.assertEqual(len(tnlist), 2) - self.assertIn('t1', tnlist) - self.assertIn('t2', tnlist) - - def test_list_mos_split_class_fail(self): - self._mock_authenticate() - self.mock_response_for_get('fvnsEncapBlk', name='Blk1') - encap_blks = self.apic.fvnsEncapBlk__vlan.list_all() - self.assertEqual(len(encap_blks), 1) - - def test_delete_mo_ok(self): - self._mock_authenticate() - self.mock_response_for_post('fvTenant') - self.assertTrue(self.apic.fvTenant.delete(mocked.APIC_TENANT)) - - def test_create_mo_ok(self): - self._mock_authenticate() - self.mock_response_for_post('fvTenant', name=mocked.APIC_TENANT) - self.mock_response_for_get('fvTenant', name=mocked.APIC_TENANT) - self.apic.fvTenant.create(mocked.APIC_TENANT) - tenant = self.apic.fvTenant.get(mocked.APIC_TENANT) - self.assertEqual(tenant['name'], mocked.APIC_TENANT) - - def test_create_mo_already_exists(self): - self._mock_authenticate() - self.mock_error_post_response(requests.codes.bad_request, - code='103', - text=u'Fake 103 error') - self.assertRaises(cexc.ApicResponseNotOk, - self.apic.vmmProvP.create, mocked.APIC_VMMP) - - def test_create_mo_with_prereq(self): - self._mock_authenticate() - self.mock_response_for_post('fvTenant', name=mocked.APIC_TENANT) - self.mock_response_for_post('fvBD', name=mocked.APIC_NETWORK) - self.mock_response_for_get('fvBD', name=mocked.APIC_NETWORK) - bd_args = mocked.APIC_TENANT, mocked.APIC_NETWORK - self.apic.fvBD.create(*bd_args) - network = self.apic.fvBD.get(*bd_args) - self.assertEqual(network['name'], mocked.APIC_NETWORK) - - def test_create_mo_prereq_exists(self): - self._mock_authenticate() - self.mock_response_for_post('vmmDomP', name=mocked.APIC_DOMAIN) - self.mock_response_for_get('vmmDomP', name=mocked.APIC_DOMAIN) - self.apic.vmmDomP.create(mocked.APIC_VMMP, mocked.APIC_DOMAIN) - dom = self.apic.vmmDomP.get(mocked.APIC_VMMP, mocked.APIC_DOMAIN) - self.assertEqual(dom['name'], mocked.APIC_DOMAIN) - - def test_create_mo_fails(self): - self._mock_authenticate() - self.mock_response_for_post('fvTenant', name=mocked.APIC_TENANT) - self.mock_error_post_response(requests.codes.bad_request, - code='not103', - text=u'Fake not103 error') - bd_args = mocked.APIC_TENANT, mocked.APIC_NETWORK - self.assertRaises(cexc.ApicResponseNotOk, - self.apic.fvBD.create, *bd_args) - - def test_update_mo(self): - self._mock_authenticate() - self.mock_response_for_post('fvTenant', name=mocked.APIC_TENANT) - self.mock_response_for_get('fvTenant', name=mocked.APIC_TENANT, - more='extra') - self.apic.fvTenant.update(mocked.APIC_TENANT, more='extra') - tenant = self.apic.fvTenant.get(mocked.APIC_TENANT) - self.assertEqual(tenant['name'], mocked.APIC_TENANT) - self.assertEqual(tenant['more'], 'extra') - - def test_attr_fail_empty_list(self): - self._mock_authenticate() - self.mock_response_for_get('fvTenant') # No attrs for tenant. - self.assertIsNone(self.apic.fvTenant.get(mocked.APIC_TENANT)) - - def test_attr_fail_other_obj(self): - self._mock_authenticate() - self.mock_response_for_get('other', name=mocked.APIC_TENANT) - self.assertIsNone(self.apic.fvTenant.get(mocked.APIC_TENANT)) diff --git a/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_common.py b/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_common.py deleted file mode 100644 index e150c1f09..000000000 --- a/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_common.py +++ /dev/null @@ -1,225 +0,0 @@ -# Copyright (c) 2014 Cisco Systems -# All Rights Reserved. -# -# 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. -# -# @author: Henry Gessau, Cisco Systems - -import mock -import requests - -from oslo.config import cfg - -from neutron.common import config as neutron_config -from neutron.plugins.ml2 import config as ml2_config -from neutron.plugins.ml2.drivers.cisco.apic import apic_client as apic -from neutron.tests import base - - -OK = requests.codes.ok - -APIC_HOST = 'fake.controller.local' -APIC_PORT = 7580 -APIC_USR = 'notadmin' -APIC_PWD = 'topsecret' - -APIC_TENANT = 'citizen14' -APIC_NETWORK = 'network99' -APIC_NETNAME = 'net99name' -APIC_SUBNET = '10.3.2.1/24' -APIC_L3CTX = 'layer3context' -APIC_AP = 'appProfile001' -APIC_EPG = 'endPointGroup001' - -APIC_CONTRACT = 'signedContract' -APIC_SUBJECT = 'testSubject' -APIC_FILTER = 'carbonFilter' -APIC_ENTRY = 'forcedEntry' - -APIC_VMMP = 'OpenStack' -APIC_DOMAIN = 'cumuloNimbus' -APIC_PDOM = 'rainStorm' - -APIC_NODE_PROF = 'red' -APIC_LEAF = 'green' -APIC_LEAF_TYPE = 'range' -APIC_NODE_BLK = 'blue' -APIC_PORT_PROF = 'yellow' -APIC_PORT_SEL = 'front' -APIC_PORT_TYPE = 'range' -APIC_PORT_BLK1 = 'block01' -APIC_PORT_BLK2 = 'block02' -APIC_ACC_PORT_GRP = 'alpha' -APIC_FUNC_PROF = 'beta' -APIC_ATT_ENT_PROF = 'delta' -APIC_VLAN_NAME = 'gamma' -APIC_VLAN_MODE = 'dynamic' -APIC_VLANID_FROM = 2900 -APIC_VLANID_TO = 2999 -APIC_VLAN_FROM = 'vlan-%d' % APIC_VLANID_FROM -APIC_VLAN_TO = 'vlan-%d' % APIC_VLANID_TO - - -class ControllerMixin(object): - - """Mock the controller for APIC driver and service unit tests.""" - - def __init__(self): - self.response = None - - def set_up_mocks(self): - # The mocked responses from the server are lists used by - # mock.side_effect, which means each call to post or get will - # return the next item in the list. This allows the test cases - # to stage a sequence of responses to method(s) under test. - self.response = {'post': [], 'get': []} - self.reset_reponses() - - def reset_reponses(self, req=None): - # Clear all staged responses. - reqs = req and [req] or ['post', 'get'] # Both if none specified. - for req in reqs: - del self.response[req][:] - self.restart_responses(req) - - def restart_responses(self, req): - responses = mock.MagicMock(side_effect=self.response[req]) - if req == 'post': - requests.Session.post = responses - elif req == 'get': - requests.Session.get = responses - - def mock_response_for_post(self, mo, **attrs): - attrs['debug_mo'] = mo # useful for debugging - self._stage_mocked_response('post', OK, mo, **attrs) - - def mock_response_for_get(self, mo, **attrs): - self._stage_mocked_response('get', OK, mo, **attrs) - - def mock_append_to_response(self, mo, **attrs): - # Append a MO to the last get response. - mo_attrs = attrs and {mo: {'attributes': attrs}} or {} - self.response['get'][-1].json.return_value['imdata'].append(mo_attrs) - - def mock_error_post_response(self, status, **attrs): - self._stage_mocked_response('post', status, 'error', **attrs) - - def mock_error_get_response(self, status, **attrs): - self._stage_mocked_response('get', status, 'error', **attrs) - - def _stage_mocked_response(self, req, mock_status, mo, **attrs): - response = mock.MagicMock() - response.status_code = mock_status - mo_attrs = attrs and [{mo: {'attributes': attrs}}] or [] - response.json.return_value = {'imdata': mo_attrs} - self.response[req].append(response) - - def mock_responses_for_create(self, obj): - self._mock_container_responses_for_create( - apic.ManagedObjectClass(obj).container) - name = '-'.join([obj, 'name']) # useful for debugging - self._stage_mocked_response('post', OK, obj, name=name) - - def _mock_container_responses_for_create(self, obj): - # Recursively generate responses for creating obj's containers. - if obj: - mo = apic.ManagedObjectClass(obj) - if mo.can_create: - if mo.container: - self._mock_container_responses_for_create(mo.container) - name = '-'.join([obj, 'name']) # useful for debugging - self._stage_mocked_response('post', OK, obj, debug_name=name) - - def mock_apic_manager_login_responses(self, timeout=300): - # APIC Manager tests are based on authenticated session - self.mock_response_for_post('aaaLogin', userName=APIC_USR, - token='ok', refreshTimeoutSeconds=timeout) - - def assert_responses_drained(self, req=None): - """Fail if all the expected responses have not been consumed.""" - request = {'post': self.session.post, 'get': self.session.get} - reqs = req and [req] or ['post', 'get'] # Both if none specified. - for req in reqs: - try: - request[req]('some url') - except StopIteration: - pass - else: - # User-friendly error message - msg = req + ' response queue not drained' - self.fail(msg=msg) - - -class ConfigMixin(object): - - """Mock the config for APIC driver and service unit tests.""" - - def __init__(self): - self.mocked_parser = None - - def set_up_mocks(self): - # Mock the configuration file - args = ['--config-file', base.etcdir('neutron.conf.test')] - neutron_config.init(args=args) - - # Configure the ML2 mechanism drivers and network types - ml2_opts = { - 'mechanism_drivers': ['apic'], - 'tenant_network_types': ['vlan'], - } - for opt, val in ml2_opts.items(): - ml2_config.cfg.CONF.set_override(opt, val, 'ml2') - - # Configure the Cisco APIC mechanism driver - apic_test_config = { - 'apic_host': APIC_HOST, - 'apic_username': APIC_USR, - 'apic_password': APIC_PWD, - 'apic_port': APIC_PORT, - 'apic_vmm_domain': APIC_DOMAIN, - 'apic_vlan_ns_name': APIC_VLAN_NAME, - 'apic_vlan_range': '%d:%d' % (APIC_VLANID_FROM, APIC_VLANID_TO), - 'apic_node_profile': APIC_NODE_PROF, - 'apic_entity_profile': APIC_ATT_ENT_PROF, - 'apic_function_profile': APIC_FUNC_PROF, - } - for opt, val in apic_test_config.items(): - cfg.CONF.set_override(opt, val, 'ml2_cisco_apic') - - apic_switch_cfg = { - 'apic_switch:east01': {'ubuntu1,ubuntu2': ['3/11']}, - 'apic_switch:east02': {'rhel01,rhel02': ['4/21'], - 'rhel03': ['4/22']}, - } - self.mocked_parser = mock.patch.object(cfg, - 'MultiConfigParser').start() - self.mocked_parser.return_value.read.return_value = [apic_switch_cfg] - self.mocked_parser.return_value.parsed = [apic_switch_cfg] - - -class DbModelMixin(object): - - """Mock the DB models for the APIC driver and service unit tests.""" - - def __init__(self): - self.mocked_session = None - - def set_up_mocks(self): - self.mocked_session = mock.Mock() - get_session = mock.patch('neutron.db.api.get_session').start() - get_session.return_value = self.mocked_session - - def mock_db_query_filterby_first_return(self, value): - """Mock db.session.query().filterby().first() to return value.""" - query = self.mocked_session.query.return_value - query.filter_by.return_value.first.return_value = value diff --git a/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_manager.py b/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_manager.py deleted file mode 100644 index 24a2c217d..000000000 --- a/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_manager.py +++ /dev/null @@ -1,698 +0,0 @@ -# Copyright (c) 2014 Cisco Systems -# All Rights Reserved. -# -# 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. -# -# @author: Henry Gessau, Cisco Systems - -import mock -from webob import exc as wexc - -from neutron.openstack.common import uuidutils - -from neutron.plugins.ml2.drivers.cisco.apic import apic_manager -from neutron.plugins.ml2.drivers.cisco.apic import exceptions as cexc -from neutron.tests import base -from neutron.tests.unit.ml2.drivers.cisco.apic import ( - test_cisco_apic_common as mocked) - - -class TestCiscoApicManager(base.BaseTestCase, - mocked.ControllerMixin, - mocked.ConfigMixin, - mocked.DbModelMixin): - - def setUp(self): - super(TestCiscoApicManager, self).setUp() - mocked.ControllerMixin.set_up_mocks(self) - mocked.ConfigMixin.set_up_mocks(self) - mocked.DbModelMixin.set_up_mocks(self) - - self.mock_apic_manager_login_responses() - self.mgr = apic_manager.APICManager() - self.session = self.mgr.apic.session - self.assert_responses_drained() - self.reset_reponses() - - def test_mgr_session_login(self): - login = self.mgr.apic.authentication - self.assertEqual(login['userName'], mocked.APIC_USR) - - def test_mgr_session_logout(self): - self.mock_response_for_post('aaaLogout') - self.mgr.apic.logout() - self.assert_responses_drained() - self.assertIsNone(self.mgr.apic.authentication) - - def test_to_range(self): - port_list = [4, 2, 3, 1, 7, 8, 10, 20, 6, 22, 21] - expected_ranges = [(1, 4), (6, 8), (10, 10), (20, 22)] - port_ranges = [r for r in apic_manager.group_by_ranges(port_list)] - self.assertEqual(port_ranges, expected_ranges) - - def test_get_profiles(self): - self.mock_db_query_filterby_first_return('faked') - self.assertEqual( - self.mgr.db.get_port_profile_for_node('node'), - 'faked' - ) - self.assertEqual( - self.mgr.db.get_profile_for_module('node', 'prof', 'module'), - 'faked' - ) - self.assertEqual( - self.mgr.db.get_profile_for_module_and_ports( - 'node', 'prof', 'module', 'from', 'to' - ), - 'faked' - ) - - def test_add_profile(self): - self.mgr.db.add_profile_for_module_and_ports( - 'node', 'prof', 'hpselc', 'module', 'from', 'to') - self.assertTrue(self.mocked_session.add.called) - self.assertTrue(self.mocked_session.flush.called) - - def test_ensure_port_profile_created(self): - port_name = mocked.APIC_PORT - self.mock_responses_for_create('infraAccPortP') - self.mock_response_for_get('infraAccPortP', name=port_name) - port = self.mgr.ensure_port_profile_created_on_apic(port_name) - self.assert_responses_drained() - self.assertEqual(port['name'], port_name) - - def test_ensure_port_profile_created_exc(self): - port_name = mocked.APIC_PORT - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('infraAccPortP') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_port_profile_created_on_apic, - port_name) - self.assert_responses_drained() - - def test_ensure_node_profile_created_for_switch_old(self): - old_switch = mocked.APIC_NODE_PROF - self.mock_response_for_get('infraNodeP', name=old_switch) - self.mgr.ensure_node_profile_created_for_switch(old_switch) - self.assert_responses_drained() - old_name = self.mgr.node_profiles[old_switch]['object']['name'] - self.assertEqual(old_name, old_switch) - - def test_ensure_node_profile_created_for_switch_new(self): - new_switch = mocked.APIC_NODE_PROF - self.mock_response_for_get('infraNodeP') - self.mock_responses_for_create('infraNodeP') - self.mock_responses_for_create('infraLeafS') - self.mock_responses_for_create('infraNodeBlk') - self.mock_response_for_get('infraNodeP', name=new_switch) - self.mgr.ensure_node_profile_created_for_switch(new_switch) - self.assert_responses_drained() - new_name = self.mgr.node_profiles[new_switch]['object']['name'] - self.assertEqual(new_name, new_switch) - - def test_ensure_node_profile_created_for_switch_new_exc(self): - new_switch = mocked.APIC_NODE_PROF - self.mock_response_for_get('infraNodeP') - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('infraNodeP') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_node_profile_created_for_switch, - new_switch) - self.assert_responses_drained() - - def test_ensure_vmm_domain_created_old(self): - dom = mocked.APIC_DOMAIN - self.mock_response_for_get('vmmDomP', name=dom) - self.mgr.ensure_vmm_domain_created_on_apic(dom) - self.assert_responses_drained() - old_dom = self.mgr.vmm_domain['name'] - self.assertEqual(old_dom, dom) - - def _mock_new_vmm_dom_responses(self, dom, seg_type=None): - vmm = mocked.APIC_VMMP - dn = self.mgr.apic.vmmDomP.mo.dn(vmm, dom) - self.mock_response_for_get('vmmDomP') - self.mock_responses_for_create('vmmDomP') - if seg_type: - self.mock_responses_for_create(seg_type) - self.mock_response_for_get('vmmDomP', name=dom, dn=dn) - - def test_ensure_vmm_domain_created_new_no_vlan_ns(self): - dom = mocked.APIC_DOMAIN - self._mock_new_vmm_dom_responses(dom) - self.mgr.ensure_vmm_domain_created_on_apic(dom) - self.assert_responses_drained() - new_dom = self.mgr.vmm_domain['name'] - self.assertEqual(new_dom, dom) - - def test_ensure_vmm_domain_created_new_no_vlan_ns_exc(self): - dom = mocked.APIC_DOMAIN - self.mock_response_for_get('vmmDomP') - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('vmmDomP') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_vmm_domain_created_on_apic, dom) - self.assert_responses_drained() - - def test_ensure_vmm_domain_created_new_with_vlan_ns(self): - dom = mocked.APIC_DOMAIN - self._mock_new_vmm_dom_responses(dom, seg_type='infraRsVlanNs__vmm') - ns = {'dn': 'test_vlan_ns'} - self.mgr.ensure_vmm_domain_created_on_apic(dom, vlan_ns=ns) - self.assert_responses_drained() - new_dom = self.mgr.vmm_domain['name'] - self.assertEqual(new_dom, dom) - - def test_ensure_vmm_domain_created_new_with_vxlan_ns(self): - dom = mocked.APIC_DOMAIN - # TODO(Henry): mock seg_type vxlan when vxlan is ready - self._mock_new_vmm_dom_responses(dom, seg_type=None) - ns = {'dn': 'test_vxlan_ns'} - self.mgr.ensure_vmm_domain_created_on_apic(dom, vxlan_ns=ns) - self.assert_responses_drained() - new_dom = self.mgr.vmm_domain['name'] - self.assertEqual(new_dom, dom) - - def test_ensure_infra_created_no_infra(self): - self.mgr.switch_dict = {} - self.mgr.ensure_infra_created_on_apic() - - def _ensure_infra_created_seq1_setup(self): - am = 'neutron.plugins.ml2.drivers.cisco.apic.apic_manager.APICManager' - np_create_for_switch = mock.patch( - am + '.ensure_node_profile_created_for_switch').start() - self.mock_db_query_filterby_first_return(None) - pp_create_for_switch = mock.patch( - am + '.ensure_port_profile_created_on_apic').start() - pp_create_for_switch.return_value = {'dn': 'port_profile_dn'} - return np_create_for_switch, pp_create_for_switch - - def test_ensure_infra_created_seq1(self): - np_create_for_switch, pp_create_for_switch = ( - self._ensure_infra_created_seq1_setup()) - - def _profile_for_module(aswitch, ppn, module): - profile = mock.Mock() - profile.ppn = ppn - profile.hpselc_id = '-'.join([aswitch, module, 'hpselc_id']) - return profile - - self.mgr.db.get_profile_for_module = mock.Mock( - side_effect=_profile_for_module) - self.mgr.db.get_profile_for_module_and_ports = mock.Mock( - return_value=None) - self.mgr.db.add_profile_for_module_and_ports = mock.Mock() - - num_switches = len(self.mgr.switch_dict) - for loop in range(num_switches): - self.mock_responses_for_create('infraRsAccPortP') - self.mock_responses_for_create('infraPortBlk') - - self.mgr.ensure_infra_created_on_apic() - self.assert_responses_drained() - self.assertEqual(np_create_for_switch.call_count, num_switches) - self.assertEqual(pp_create_for_switch.call_count, num_switches) - for switch in self.mgr.switch_dict: - np_create_for_switch.assert_any_call(switch) - - def test_ensure_infra_created_seq1_exc(self): - np_create_for_switch, __ = self._ensure_infra_created_seq1_setup() - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('infraAccPortP') - - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_infra_created_on_apic) - self.assert_responses_drained() - self.assertTrue(np_create_for_switch.called) - self.assertEqual(np_create_for_switch.call_count, 1) - - def _ensure_infra_created_seq2_setup(self): - am = 'neutron.plugins.ml2.drivers.cisco.apic.apic_manager.APICManager' - np_create_for_switch = mock.patch( - am + '.ensure_node_profile_created_for_switch').start() - - def _profile_for_node(aswitch): - profile = mock.Mock() - profile.profile_id = '-'.join([aswitch, 'profile_id']) - return profile - - self.mgr.db.get_port_profile_for_node = mock.Mock( - side_effect=_profile_for_node) - self.mgr.db.get_profile_for_module = mock.Mock( - return_value=None) - self.mgr.function_profile = {'dn': 'dn'} - self.mgr.db.get_profile_for_module_and_ports = mock.Mock( - return_value=True) - - return np_create_for_switch - - def test_ensure_infra_created_seq2(self): - np_create_for_switch = self._ensure_infra_created_seq2_setup() - - num_switches = len(self.mgr.switch_dict) - for loop in range(num_switches): - self.mock_responses_for_create('infraHPortS') - self.mock_responses_for_create('infraRsAccBaseGrp') - - self.mgr.ensure_infra_created_on_apic() - self.assert_responses_drained() - self.assertEqual(np_create_for_switch.call_count, num_switches) - for switch in self.mgr.switch_dict: - np_create_for_switch.assert_any_call(switch) - - def test_ensure_infra_created_seq2_exc(self): - np_create_for_switch = self._ensure_infra_created_seq2_setup() - - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('infraHPortS') - - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_infra_created_on_apic) - self.assert_responses_drained() - self.assertTrue(np_create_for_switch.called) - self.assertEqual(np_create_for_switch.call_count, 1) - - def test_ensure_context_unenforced_new_ctx(self): - self.mock_response_for_get('fvCtx') - self.mock_responses_for_create('fvCtx') - self.mgr.ensure_context_unenforced() - self.assert_responses_drained() - - def test_ensure_context_unenforced_pref1(self): - self.mock_response_for_get('fvCtx', pcEnfPref='1') - self.mock_response_for_post('fvCtx') - self.mgr.ensure_context_unenforced() - self.assert_responses_drained() - - def test_ensure_context_unenforced_pref2(self): - self.mock_response_for_get('fvCtx', pcEnfPref='2') - self.mgr.ensure_context_unenforced() - self.assert_responses_drained() - - def _mock_vmm_dom_prereq(self, dom): - self._mock_new_vmm_dom_responses(dom) - self.mgr.ensure_vmm_domain_created_on_apic(dom) - - def _mock_new_phys_dom_responses(self, dom, seg_type=None): - dn = self.mgr.apic.physDomP.mo.dn(dom) - self.mock_response_for_get('physDomP') - self.mock_responses_for_create('physDomP') - if seg_type: - self.mock_responses_for_create(seg_type) - self.mock_response_for_get('physDomP', name=dom, dn=dn) - - def _mock_phys_dom_prereq(self, dom): - self._mock_new_phys_dom_responses(dom) - self.mgr.ensure_phys_domain_created_on_apic(dom) - - def test_ensure_entity_profile_created_old(self): - ep = mocked.APIC_ATT_ENT_PROF - self.mock_response_for_get('infraAttEntityP', name=ep) - self.mgr.ensure_entity_profile_created_on_apic(ep) - self.assert_responses_drained() - - def _mock_new_entity_profile(self, exc=None): - self.mock_response_for_get('infraAttEntityP') - self.mock_responses_for_create('infraAttEntityP') - self.mock_responses_for_create('infraRsDomP') - if exc: - self.mock_error_get_response(exc, code='103', text=u'Fail') - else: - self.mock_response_for_get('infraAttEntityP') - - def test_ensure_entity_profile_created_new(self): - self._mock_phys_dom_prereq(mocked.APIC_PDOM) - ep = mocked.APIC_ATT_ENT_PROF - self._mock_new_entity_profile() - self.mgr.ensure_entity_profile_created_on_apic(ep) - self.assert_responses_drained() - - def test_ensure_entity_profile_created_new_exc(self): - self._mock_phys_dom_prereq(mocked.APIC_PDOM) - ep = mocked.APIC_ATT_ENT_PROF - self._mock_new_entity_profile(exc=wexc.HTTPBadRequest) - self.mock_response_for_post('infraAttEntityP') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_entity_profile_created_on_apic, ep) - self.assert_responses_drained() - - def _mock_entity_profile_preqreq(self): - self._mock_phys_dom_prereq(mocked.APIC_PDOM) - ep = mocked.APIC_ATT_ENT_PROF - self._mock_new_entity_profile() - self.mgr.ensure_entity_profile_created_on_apic(ep) - - def test_ensure_function_profile_created_old(self): - self._mock_entity_profile_preqreq() - fp = mocked.APIC_FUNC_PROF - self.mock_response_for_get('infraAccPortGrp', name=fp) - self.mgr.ensure_function_profile_created_on_apic(fp) - self.assert_responses_drained() - old_fp = self.mgr.function_profile['name'] - self.assertEqual(old_fp, fp) - - def _mock_new_function_profile(self, fp): - dn = self.mgr.apic.infraAttEntityP.mo.dn(fp) - self.mock_responses_for_create('infraAccPortGrp') - self.mock_responses_for_create('infraRsAttEntP') - self.mock_response_for_get('infraAccPortGrp', name=fp, dn=dn) - - def test_ensure_function_profile_created_new(self): - fp = mocked.APIC_FUNC_PROF - dn = self.mgr.apic.infraAttEntityP.mo.dn(fp) - self.mgr.entity_profile = {'dn': dn} - self.mock_response_for_get('infraAccPortGrp') - self.mock_responses_for_create('infraAccPortGrp') - self.mock_responses_for_create('infraRsAttEntP') - self.mock_response_for_get('infraAccPortGrp', name=fp, dn=dn) - self.mgr.ensure_function_profile_created_on_apic(fp) - self.assert_responses_drained() - new_fp = self.mgr.function_profile['name'] - self.assertEqual(new_fp, fp) - - def test_ensure_function_profile_created_new_exc(self): - fp = mocked.APIC_FUNC_PROF - dn = self.mgr.apic.infraAttEntityP.mo.dn(fp) - self.mgr.entity_profile = {'dn': dn} - self.mock_response_for_get('infraAccPortGrp') - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('infraAccPortGrp') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_function_profile_created_on_apic, fp) - self.assert_responses_drained() - - def test_ensure_vlan_ns_created_old(self): - ns = mocked.APIC_VLAN_NAME - mode = mocked.APIC_VLAN_MODE - self.mock_response_for_get('fvnsVlanInstP', name=ns, mode=mode) - new_ns = self.mgr.ensure_vlan_ns_created_on_apic(ns, '100', '199') - self.assert_responses_drained() - self.assertIsNone(new_ns) - - def _mock_new_vlan_instance(self, ns, vlan_encap=None): - self.mock_responses_for_create('fvnsVlanInstP') - if vlan_encap: - self.mock_response_for_get('fvnsEncapBlk', **vlan_encap) - else: - self.mock_response_for_get('fvnsEncapBlk') - self.mock_responses_for_create('fvnsEncapBlk__vlan') - self.mock_response_for_get('fvnsVlanInstP', name=ns) - - def test_ensure_vlan_ns_created_new_no_encap(self): - ns = mocked.APIC_VLAN_NAME - self.mock_response_for_get('fvnsVlanInstP') - self._mock_new_vlan_instance(ns) - new_ns = self.mgr.ensure_vlan_ns_created_on_apic(ns, '200', '299') - self.assert_responses_drained() - self.assertEqual(new_ns['name'], ns) - - def test_ensure_vlan_ns_created_new_exc(self): - ns = mocked.APIC_VLAN_NAME - self.mock_response_for_get('fvnsVlanInstP') - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('fvnsVlanInstP') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_vlan_ns_created_on_apic, - ns, '200', '299') - self.assert_responses_drained() - - def test_ensure_vlan_ns_created_new_with_encap(self): - ns = mocked.APIC_VLAN_NAME - self.mock_response_for_get('fvnsVlanInstP') - ns_args = {'name': 'encap', 'from': '300', 'to': '399'} - self._mock_new_vlan_instance(ns, vlan_encap=ns_args) - new_ns = self.mgr.ensure_vlan_ns_created_on_apic(ns, '300', '399') - self.assert_responses_drained() - self.assertEqual(new_ns['name'], ns) - - def test_ensure_tenant_created_on_apic(self): - self.mock_response_for_get('fvTenant', name='any') - self.mgr.ensure_tenant_created_on_apic('two') - self.mock_response_for_get('fvTenant') - self.mock_responses_for_create('fvTenant') - self.mgr.ensure_tenant_created_on_apic('four') - self.assert_responses_drained() - - def test_ensure_bd_created_existing_bd(self): - self.mock_response_for_get('fvBD', name='BD') - self.mgr.ensure_bd_created_on_apic('t1', 'two') - self.assert_responses_drained() - - def test_ensure_bd_created_not_ctx(self): - self.mock_response_for_get('fvBD') - self.mock_responses_for_create('fvBD') - self.mock_response_for_get('fvCtx') - self.mock_responses_for_create('fvCtx') - self.mock_responses_for_create('fvRsCtx') - self.mgr.ensure_bd_created_on_apic('t2', 'three') - self.assert_responses_drained() - - def test_ensure_bd_created_exc(self): - self.mock_response_for_get('fvBD') - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('fvBD') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_bd_created_on_apic, 't2', 'three') - self.assert_responses_drained() - - def test_ensure_bd_created_ctx_pref1(self): - self.mock_response_for_get('fvBD') - self.mock_responses_for_create('fvBD') - self.mock_response_for_get('fvCtx', pcEnfPref='1') - self.mock_responses_for_create('fvRsCtx') - self.mgr.ensure_bd_created_on_apic('t3', 'four') - self.assert_responses_drained() - - def test_ensure_bd_created_ctx_pref2(self): - self.mock_response_for_get('fvBD') - self.mock_responses_for_create('fvBD') - self.mock_response_for_get('fvCtx', pcEnfPref='2') - self.mock_response_for_post('fvCtx') - self.mock_responses_for_create('fvRsCtx') - self.mgr.ensure_bd_created_on_apic('t3', 'four') - self.assert_responses_drained() - - def test_delete_bd(self): - self.mock_response_for_post('fvBD') - self.mgr.delete_bd_on_apic('t1', 'bd') - self.assert_responses_drained() - - def test_ensure_subnet_created(self): - self.mock_response_for_get('fvSubnet', name='sn1') - self.mgr.ensure_subnet_created_on_apic('t0', 'bd1', '2.2.2.2/8') - self.mock_response_for_get('fvSubnet') - self.mock_responses_for_create('fvSubnet') - self.mgr.ensure_subnet_created_on_apic('t2', 'bd3', '4.4.4.4/16') - self.assert_responses_drained() - - def test_ensure_filter_created(self): - self.mock_response_for_get('vzFilter', name='f1') - self.mgr.ensure_filter_created_on_apic('t1', 'two') - self.mock_response_for_get('vzFilter') - self.mock_responses_for_create('vzFilter') - self.mgr.ensure_filter_created_on_apic('t2', 'four') - self.assert_responses_drained() - - def test_ensure_epg_created_for_network_old(self): - self.mock_db_query_filterby_first_return('faked') - epg = self.mgr.ensure_epg_created_for_network('X', 'Y', 'Z') - self.assertEqual(epg, 'faked') - - def test_ensure_epg_created_for_network_new(self): - tenant = mocked.APIC_TENANT - network = mocked.APIC_NETWORK - netname = mocked.APIC_NETNAME - self._mock_phys_dom_prereq(mocked.APIC_PDOM) - self.mock_db_query_filterby_first_return(None) - self.mock_responses_for_create('fvAEPg') - self.mock_response_for_get('fvBD', name=network) - self.mock_responses_for_create('fvRsBd') - self.mock_responses_for_create('fvRsDomAtt') - new_epg = self.mgr.ensure_epg_created_for_network(tenant, - network, netname) - self.assert_responses_drained() - self.assertEqual(new_epg.network_id, network) - self.assertTrue(self.mocked_session.add.called) - self.assertTrue(self.mocked_session.flush.called) - - def test_ensure_epg_created_for_network_exc(self): - tenant = mocked.APIC_TENANT - network = mocked.APIC_NETWORK - netname = mocked.APIC_NETNAME - self.mock_db_query_filterby_first_return(None) - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('fvAEPg') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.ensure_epg_created_for_network, - tenant, network, netname) - self.assert_responses_drained() - - def test_delete_epg_for_network_no_epg(self): - self.mock_db_query_filterby_first_return(None) - self.mgr.delete_epg_for_network('tenant', 'network') - - def test_delete_epg_for_network(self): - epg = mock.Mock() - epg.epg_id = mocked.APIC_EPG - self.mock_db_query_filterby_first_return(epg) - self.mock_response_for_post('fvAEPg') - self.mgr.delete_epg_for_network('tenant', 'network') - self.assertTrue(self.mocked_session.delete.called) - self.assertTrue(self.mocked_session.flush.called) - - def test_ensure_path_created_for_port(self): - epg = mock.Mock() - epg.epg_id = 'epg01' - eepg = mock.Mock(return_value=epg) - apic_manager.APICManager.ensure_epg_created_for_network = eepg - self.mock_response_for_get('fvRsPathAtt', tDn='foo') - self.mgr.ensure_path_created_for_port('tenant', 'network', 'rhel01', - 'static', 'netname') - self.assert_responses_drained() - - def test_ensure_path_created_for_port_no_path_att(self): - epg = mock.Mock() - epg.epg_id = 'epg2' - eepg = mock.Mock(return_value=epg) - self.mgr.ensure_epg_created_for_network = eepg - self.mock_response_for_get('fvRsPathAtt') - self.mock_responses_for_create('fvRsPathAtt') - self.mgr.ensure_path_created_for_port('tenant', 'network', 'ubuntu2', - 'static', 'netname') - self.assert_responses_drained() - - def test_ensure_path_created_for_port_unknown_host(self): - epg = mock.Mock() - epg.epg_id = 'epg3' - eepg = mock.Mock(return_value=epg) - apic_manager.APICManager.ensure_epg_created_for_network = eepg - self.mock_response_for_get('fvRsPathAtt', tDn='foo') - self.assertRaises(cexc.ApicHostNotConfigured, - self.mgr.ensure_path_created_for_port, - 'tenant', 'network', 'cirros3', 'static', 'netname') - - def test_create_tenant_filter(self): - tenant = mocked.APIC_TENANT - self.mock_responses_for_create('vzFilter') - self.mock_responses_for_create('vzEntry') - filter_id = self.mgr.create_tenant_filter(tenant) - self.assert_responses_drained() - self.assertTrue(uuidutils.is_uuid_like(str(filter_id))) - - def test_create_tenant_filter_exc(self): - tenant = mocked.APIC_TENANT - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('vzFilter') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.create_tenant_filter, tenant) - self.assert_responses_drained() - - def test_set_contract_for_epg_consumer(self): - tenant = mocked.APIC_TENANT - epg = mocked.APIC_EPG - contract = mocked.APIC_CONTRACT - self.mock_responses_for_create('fvRsCons') - self.mgr.set_contract_for_epg(tenant, epg, contract) - self.assert_responses_drained() - - def test_set_contract_for_epg_provider(self): - tenant = mocked.APIC_TENANT - epg = mocked.APIC_EPG - contract = mocked.APIC_CONTRACT - epg_obj = mock.Mock() - epg_obj.epg_id = epg - epg_obj.provider = False - self.mock_db_query_filterby_first_return(epg_obj) - self.mock_responses_for_create('fvRsProv') - self.mock_response_for_post('vzBrCP') - self.mgr.set_contract_for_epg(tenant, epg, contract, provider=True) - self.assert_responses_drained() - self.assertTrue(self.mocked_session.merge.called) - self.assertTrue(self.mocked_session.flush.called) - self.assertTrue(epg_obj.provider) - - def test_set_contract_for_epg_provider_exc(self): - tenant = mocked.APIC_TENANT - epg = mocked.APIC_EPG - contract = mocked.APIC_CONTRACT - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('vzBrCP') - self.mock_response_for_post('fvRsProv') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.set_contract_for_epg, - tenant, epg, contract, provider=True) - self.assert_responses_drained() - - def test_delete_contract_for_epg_consumer(self): - tenant = mocked.APIC_TENANT - epg = mocked.APIC_EPG - contract = mocked.APIC_CONTRACT - self.mock_response_for_post('fvRsCons') - self.mgr.delete_contract_for_epg(tenant, epg, contract) - self.assert_responses_drained() - - def test_delete_contract_for_epg_provider(self): - tenant = mocked.APIC_TENANT - epg = mocked.APIC_EPG - contract = mocked.APIC_CONTRACT - epg_obj = mock.Mock() - epg_obj.epg_id = epg + '-other' - epg_obj.provider = False - self.mock_db_query_filterby_first_return(epg_obj) - self.mock_response_for_post('fvRsProv') - self.mock_response_for_post('fvRsCons') - self.mock_responses_for_create('fvRsProv') - self.mock_response_for_post('vzBrCP') - self.mgr.delete_contract_for_epg(tenant, epg, contract, provider=True) - self.assert_responses_drained() - self.assertTrue(self.mocked_session.merge.called) - self.assertTrue(self.mocked_session.flush.called) - self.assertTrue(epg_obj.provider) - - def test_create_tenant_contract_existing(self): - tenant = mocked.APIC_TENANT - contract = mocked.APIC_CONTRACT - self.mock_db_query_filterby_first_return(contract) - new_contract = self.mgr.create_tenant_contract(tenant) - self.assertEqual(new_contract, contract) - - def test_create_tenant_contract_new(self): - tenant = mocked.APIC_TENANT - contract = mocked.APIC_CONTRACT - dn = self.mgr.apic.vzBrCP.mo.dn(tenant, contract) - self.mock_db_query_filterby_first_return(None) - self.mock_responses_for_create('vzBrCP') - self.mock_response_for_get('vzBrCP', dn=dn) - self.mock_responses_for_create('vzSubj') - self.mock_responses_for_create('vzFilter') - self.mock_responses_for_create('vzEntry') - self.mock_responses_for_create('vzInTerm') - self.mock_responses_for_create('vzRsFiltAtt__In') - self.mock_responses_for_create('vzOutTerm') - self.mock_responses_for_create('vzRsFiltAtt__Out') - self.mock_responses_for_create('vzCPIf') - self.mock_responses_for_create('vzRsIf') - new_contract = self.mgr.create_tenant_contract(tenant) - self.assert_responses_drained() - self.assertTrue(self.mocked_session.add.called) - self.assertTrue(self.mocked_session.flush.called) - self.assertEqual(new_contract['tenant_id'], tenant) - - def test_create_tenant_contract_exc(self): - tenant = mocked.APIC_TENANT - self.mock_db_query_filterby_first_return(None) - self.mock_error_post_response(wexc.HTTPBadRequest) - self.mock_response_for_post('vzBrCP') - self.assertRaises(cexc.ApicResponseNotOk, - self.mgr.create_tenant_contract, tenant) - self.assert_responses_drained() diff --git a/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_mechanism_driver.py b/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_mechanism_driver.py deleted file mode 100644 index 6addd4382..000000000 --- a/neutron/tests/unit/ml2/drivers/cisco/apic/test_cisco_apic_mechanism_driver.py +++ /dev/null @@ -1,226 +0,0 @@ -# Copyright (c) 2014 Cisco Systems -# All Rights Reserved. -# -# 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. -# -# @author: Henry Gessau, Cisco Systems - -import mock - -from oslo.config import cfg - -from neutron.plugins.ml2.drivers.cisco.apic import mechanism_apic as md -from neutron.plugins.ml2.drivers import type_vlan # noqa -from neutron.tests import base -from neutron.tests.unit.ml2.drivers.cisco.apic import ( - test_cisco_apic_common as mocked) - - -HOST_ID1 = 'ubuntu' -HOST_ID2 = 'rhel' -ENCAP = '101' - -SUBNET_GATEWAY = '10.3.2.1' -SUBNET_CIDR = '10.3.1.0/24' -SUBNET_NETMASK = '24' - -TEST_SEGMENT1 = 'test-segment1' -TEST_SEGMENT2 = 'test-segment2' - - -class TestCiscoApicMechDriver(base.BaseTestCase, - mocked.ControllerMixin, - mocked.ConfigMixin, - mocked.DbModelMixin): - - def setUp(self): - super(TestCiscoApicMechDriver, self).setUp() - mocked.ControllerMixin.set_up_mocks(self) - mocked.ConfigMixin.set_up_mocks(self) - mocked.DbModelMixin.set_up_mocks(self) - - self.mock_apic_manager_login_responses() - self.driver = md.APICMechanismDriver() - self.driver.vif_type = 'test-vif_type' - self.driver.cap_port_filter = 'test-cap_port_filter' - - def test_initialize(self): - cfg.CONF.set_override('network_vlan_ranges', ['physnet1:100:199'], - 'ml2_type_vlan') - ns = mocked.APIC_VLAN_NAME - mode = mocked.APIC_VLAN_MODE - self.mock_response_for_get('fvnsVlanInstP', name=ns, mode=mode) - self.mock_response_for_get('physDomP', name=mocked.APIC_DOMAIN) - self.mock_response_for_get('infraAttEntityP', - name=mocked.APIC_ATT_ENT_PROF) - self.mock_response_for_get('infraAccPortGrp', - name=mocked.APIC_ACC_PORT_GRP) - mock.patch('neutron.plugins.ml2.drivers.cisco.apic.apic_manager.' - 'APICManager.ensure_infra_created_on_apic').start() - self.driver.initialize() - self.session = self.driver.apic_manager.apic.session - self.assert_responses_drained() - - def test_update_port_postcommit(self): - net_ctx = self._get_network_context(mocked.APIC_TENANT, - mocked.APIC_NETWORK, - TEST_SEGMENT1) - port_ctx = self._get_port_context(mocked.APIC_TENANT, - mocked.APIC_NETWORK, - 'vm1', net_ctx, HOST_ID1) - mgr = self.driver.apic_manager = mock.Mock() - self.driver.update_port_postcommit(port_ctx) - mgr.ensure_tenant_created_on_apic.assert_called_once_with( - mocked.APIC_TENANT) - mgr.ensure_path_created_for_port.assert_called_once_with( - mocked.APIC_TENANT, mocked.APIC_NETWORK, HOST_ID1, - ENCAP, mocked.APIC_NETWORK + '-name') - - def test_create_network_postcommit(self): - ctx = self._get_network_context(mocked.APIC_TENANT, - mocked.APIC_NETWORK, - TEST_SEGMENT1) - mgr = self.driver.apic_manager = mock.Mock() - self.driver.create_network_postcommit(ctx) - mgr.ensure_bd_created_on_apic.assert_called_once_with( - mocked.APIC_TENANT, mocked.APIC_NETWORK) - mgr.ensure_epg_created_for_network.assert_called_once_with( - mocked.APIC_TENANT, mocked.APIC_NETWORK, - mocked.APIC_NETWORK + '-name') - - def test_delete_network_postcommit(self): - ctx = self._get_network_context(mocked.APIC_TENANT, - mocked.APIC_NETWORK, - TEST_SEGMENT1) - mgr = self.driver.apic_manager = mock.Mock() - self.driver.delete_network_postcommit(ctx) - mgr.delete_bd_on_apic.assert_called_once_with( - mocked.APIC_TENANT, mocked.APIC_NETWORK) - mgr.delete_epg_for_network.assert_called_once_with( - mocked.APIC_TENANT, mocked.APIC_NETWORK) - - def test_create_subnet_postcommit(self): - net_ctx = self._get_network_context(mocked.APIC_TENANT, - mocked.APIC_NETWORK, - TEST_SEGMENT1) - subnet_ctx = self._get_subnet_context(SUBNET_GATEWAY, - SUBNET_CIDR, - net_ctx) - mgr = self.driver.apic_manager = mock.Mock() - self.driver.create_subnet_postcommit(subnet_ctx) - mgr.ensure_subnet_created_on_apic.assert_called_once_with( - mocked.APIC_TENANT, mocked.APIC_NETWORK, - '%s/%s' % (SUBNET_GATEWAY, SUBNET_NETMASK)) - - def _get_network_context(self, tenant_id, net_id, seg_id=None, - seg_type='vlan'): - network = {'id': net_id, - 'name': net_id + '-name', - 'tenant_id': tenant_id, - 'provider:segmentation_id': seg_id} - if seg_id: - network_segments = [{'id': seg_id, - 'segmentation_id': ENCAP, - 'network_type': seg_type, - 'physical_network': 'physnet1'}] - else: - network_segments = [] - return FakeNetworkContext(network, network_segments) - - def _get_subnet_context(self, gateway_ip, cidr, network): - subnet = {'tenant_id': network.current['tenant_id'], - 'network_id': network.current['id'], - 'id': '[%s/%s]' % (gateway_ip, cidr), - 'gateway_ip': gateway_ip, - 'cidr': cidr} - return FakeSubnetContext(subnet, network) - - def _get_port_context(self, tenant_id, net_id, vm_id, network, host): - port = {'device_id': vm_id, - 'device_owner': 'compute', - 'binding:host_id': host, - 'tenant_id': tenant_id, - 'id': mocked.APIC_PORT, - 'name': mocked.APIC_PORT, - 'network_id': net_id} - return FakePortContext(port, network) - - -class FakeNetworkContext(object): - """To generate network context for testing purposes only.""" - - def __init__(self, network, segments): - self._network = network - self._segments = segments - - @property - def current(self): - return self._network - - @property - def network_segments(self): - return self._segments - - -class FakeSubnetContext(object): - """To generate subnet context for testing purposes only.""" - - def __init__(self, subnet, network): - self._subnet = subnet - self._network = network - - @property - def current(self): - return self._subnet - - @property - def network(self): - return self._network - - -class FakePortContext(object): - """To generate port context for testing purposes only.""" - - def __init__(self, port, network): - self._fake_plugin = mock.Mock() - self._fake_plugin.get_ports.return_value = [] - self._fake_plugin_context = None - self._port = port - self._network = network - if network.network_segments: - self._bound_segment = network.network_segments[0] - else: - self._bound_segment = None - - @property - def current(self): - return self._port - - @property - def _plugin(self): - return self._fake_plugin - - @property - def _plugin_context(self): - return self._fake_plugin_context - - @property - def network(self): - return self._network - - @property - def bound_segment(self): - return self._bound_segment - - def set_binding(self, segment_id, vif_type, cap_port_filter): - pass diff --git a/neutron/tests/unit/ml2/drivers/cisco/nexus/__init__.py b/neutron/tests/unit/ml2/drivers/cisco/nexus/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_config.py b/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_config.py deleted file mode 100644 index 55f0db3da..000000000 --- a/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_config.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2014 Cisco Systems, Inc. -# All rights reserved. -# -# 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 oslo.config import cfg - -from neutron.plugins.ml2.drivers.cisco.nexus import config as cisco_config -from neutron.tests import base - - -class TestCiscoNexusPluginConfig(base.BaseTestCase): - - def setUp(self): - self.config_parse() - super(TestCiscoNexusPluginConfig, self).setUp() - - def test_config_parse_error(self): - """Check that config error is raised upon config parser failure.""" - with mock.patch.object(cfg, 'MultiConfigParser') as parser: - parser.return_value.read.return_value = [] - self.assertRaises(cfg.Error, cisco_config.ML2MechCiscoConfig) - - def test_create_device_dictionary(self): - """Test creation of the device dictionary based on nexus config.""" - test_config = { - 'ml2_mech_cisco_nexus:1.1.1.1': { - 'username': ['admin'], - 'password': ['mySecretPassword'], - 'ssh_port': [22], - 'compute1': ['1/1'], - 'compute2': ['1/2'], - }, - 'ml2_mech_cisco_nexus:2.2.2.2': { - 'username': ['admin'], - 'password': ['mySecretPassword'], - 'ssh_port': [22], - 'compute3': ['1/1'], - 'compute4': ['1/2'], - }, - } - expected_dev_dict = { - ('1.1.1.1', 'username'): 'admin', - ('1.1.1.1', 'password'): 'mySecretPassword', - ('1.1.1.1', 'ssh_port'): 22, - ('1.1.1.1', 'compute1'): '1/1', - ('1.1.1.1', 'compute2'): '1/2', - ('2.2.2.2', 'username'): 'admin', - ('2.2.2.2', 'password'): 'mySecretPassword', - ('2.2.2.2', 'ssh_port'): 22, - ('2.2.2.2', 'compute3'): '1/1', - ('2.2.2.2', 'compute4'): '1/2', - } - with mock.patch.object(cfg, 'MultiConfigParser') as parser: - parser.return_value.read.return_value = cfg.CONF.config_file - parser.return_value.parsed = [test_config] - cisco_config.ML2MechCiscoConfig() - self.assertEqual(expected_dev_dict, - cisco_config.ML2MechCiscoConfig.nexus_dict) diff --git a/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_mech.py b/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_mech.py deleted file mode 100644 index 55717ebe2..000000000 --- a/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_mech.py +++ /dev/null @@ -1,715 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 contextlib -import mock - -import webob.exc as wexc - -from neutron.api.v2 import base -from neutron.common import constants as n_const -from neutron import context -from neutron.extensions import portbindings -from neutron import manager -from neutron.openstack.common import log as logging -from neutron.plugins.common import constants as p_const -from neutron.plugins.ml2 import config as ml2_config -from neutron.plugins.ml2 import driver_api as api -from neutron.plugins.ml2 import driver_context -from neutron.plugins.ml2.drivers.cisco.nexus import config as cisco_config -from neutron.plugins.ml2.drivers.cisco.nexus import exceptions as c_exc -from neutron.plugins.ml2.drivers.cisco.nexus import mech_cisco_nexus -from neutron.plugins.ml2.drivers.cisco.nexus import nexus_db_v2 -from neutron.plugins.ml2.drivers.cisco.nexus import nexus_network_driver -from neutron.plugins.ml2.drivers import type_vlan as vlan_config -from neutron.tests.unit import test_db_plugin - - -LOG = logging.getLogger(__name__) -ML2_PLUGIN = 'neutron.plugins.ml2.plugin.Ml2Plugin' -PHYS_NET = 'physnet1' -COMP_HOST_NAME = 'testhost' -COMP_HOST_NAME_2 = 'testhost_2' -VLAN_START = 1000 -VLAN_END = 1100 -NEXUS_IP_ADDR = '1.1.1.1' -NETWORK_NAME = 'test_network' -NETWORK_NAME_2 = 'test_network_2' -NEXUS_INTERFACE = '1/1' -NEXUS_INTERFACE_2 = '1/2' -CIDR_1 = '10.0.0.0/24' -CIDR_2 = '10.0.1.0/24' -DEVICE_ID_1 = '11111111-1111-1111-1111-111111111111' -DEVICE_ID_2 = '22222222-2222-2222-2222-222222222222' -DEVICE_OWNER = 'compute:None' -BOUND_SEGMENT1 = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: PHYS_NET, - api.SEGMENTATION_ID: VLAN_START} -BOUND_SEGMENT2 = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: PHYS_NET, - api.SEGMENTATION_ID: VLAN_START + 1} - - -class CiscoML2MechanismTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - - def setUp(self): - """Configure for end-to-end neutron testing using a mock ncclient. - - This setup includes: - - Configure the ML2 plugin to use VLANs in the range of 1000-1100. - - Configure the Cisco mechanism driver to use an imaginary switch - at NEXUS_IP_ADDR. - - Create a mock NETCONF client (ncclient) for the Cisco mechanism - driver - - """ - - # Configure the ML2 mechanism drivers and network types - ml2_opts = { - 'mechanism_drivers': ['cisco_nexus'], - 'tenant_network_types': ['vlan'], - } - for opt, val in ml2_opts.items(): - ml2_config.cfg.CONF.set_override(opt, val, 'ml2') - - # Configure the ML2 VLAN parameters - phys_vrange = ':'.join([PHYS_NET, str(VLAN_START), str(VLAN_END)]) - vlan_config.cfg.CONF.set_override('network_vlan_ranges', - [phys_vrange], - 'ml2_type_vlan') - - # Configure the Cisco Nexus mechanism driver - nexus_config = { - (NEXUS_IP_ADDR, 'username'): 'admin', - (NEXUS_IP_ADDR, 'password'): 'mySecretPassword', - (NEXUS_IP_ADDR, 'ssh_port'): 22, - (NEXUS_IP_ADDR, COMP_HOST_NAME): NEXUS_INTERFACE, - (NEXUS_IP_ADDR, COMP_HOST_NAME_2): NEXUS_INTERFACE_2} - nexus_patch = mock.patch.dict( - cisco_config.ML2MechCiscoConfig.nexus_dict, - nexus_config) - nexus_patch.start() - self.addCleanup(nexus_patch.stop) - - # The NETCONF client module is not included in the DevStack - # distribution, so mock this module for unit testing. - self.mock_ncclient = mock.Mock() - mock.patch.object(nexus_network_driver.CiscoNexusDriver, - '_import_ncclient', - return_value=self.mock_ncclient).start() - - # Mock port context values for bound_segments and 'status'. - self.mock_bound_segment = mock.patch.object( - driver_context.PortContext, - 'bound_segment', - new_callable=mock.PropertyMock).start() - self.mock_bound_segment.return_value = BOUND_SEGMENT1 - - self.mock_original_bound_segment = mock.patch.object( - driver_context.PortContext, - 'original_bound_segment', - new_callable=mock.PropertyMock).start() - self.mock_original_bound_segment.return_value = None - - mock_status = mock.patch.object( - mech_cisco_nexus.CiscoNexusMechanismDriver, - '_is_status_active').start() - mock_status.return_value = n_const.PORT_STATUS_ACTIVE - - super(CiscoML2MechanismTestCase, self).setUp(ML2_PLUGIN) - - self.port_create_status = 'DOWN' - - @contextlib.contextmanager - def _patch_ncclient(self, attr, value): - """Configure an attribute on the mock ncclient module. - - This method can be used to inject errors by setting a side effect - or a return value for an ncclient method. - - :param attr: ncclient attribute (typically method) to be configured. - :param value: Value to be configured on the attribute. - - """ - # Configure attribute. - config = {attr: value} - self.mock_ncclient.configure_mock(**config) - # Continue testing - yield - # Unconfigure attribute - config = {attr: None} - self.mock_ncclient.configure_mock(**config) - - @staticmethod - def _config_dependent_side_effect(match_config, exc): - """Generates a config-dependent side effect for ncclient edit_config. - - This method generates a mock side-effect function which can be - configured on the mock ncclient module for the edit_config method. - This side effect will cause a given exception to be raised whenever - the XML config string that is passed to edit_config contains all - words in a given match config string. - - :param match_config: String containing keywords to be matched - :param exc: Exception to be raised when match is found - :return: Side effect function for the mock ncclient module's - edit_config method. - - """ - keywords = match_config.split() - - def _side_effect_function(target, config): - if all(word in config for word in keywords): - raise exc - return _side_effect_function - - def _is_in_nexus_cfg(self, words): - """Check if any config sent to Nexus contains all words in a list.""" - for call in (self.mock_ncclient.connect.return_value. - edit_config.mock_calls): - configlet = call[2]['config'] - if all(word in configlet for word in words): - return True - return False - - def _is_in_last_nexus_cfg(self, words): - """Confirm last config sent to Nexus contains specified keywords.""" - last_cfg = (self.mock_ncclient.connect.return_value. - edit_config.mock_calls[-1][2]['config']) - return all(word in last_cfg for word in words) - - def _is_vlan_configured(self, vlan_creation_expected=True, - add_keyword_expected=False): - vlan_created = self._is_in_nexus_cfg(['vlan', 'vlan-name']) - add_appears = self._is_in_last_nexus_cfg(['add']) - return (self._is_in_last_nexus_cfg(['allowed', 'vlan']) and - vlan_created == vlan_creation_expected and - add_appears == add_keyword_expected) - - def _is_vlan_unconfigured(self, vlan_deletion_expected=True): - vlan_deleted = self._is_in_last_nexus_cfg( - ['no', 'vlan', 'vlan-id-create-delete']) - return (self._is_in_nexus_cfg(['allowed', 'vlan', 'remove']) and - vlan_deleted == vlan_deletion_expected) - - -class TestCiscoBasicGet(CiscoML2MechanismTestCase, - test_db_plugin.TestBasicGet): - - pass - - -class TestCiscoV2HTTPResponse(CiscoML2MechanismTestCase, - test_db_plugin.TestV2HTTPResponse): - - pass - - -class TestCiscoPortsV2(CiscoML2MechanismTestCase, - test_db_plugin.TestPortsV2): - - @contextlib.contextmanager - def _create_resources(self, name=NETWORK_NAME, cidr=CIDR_1, - device_id=DEVICE_ID_1, - host_id=COMP_HOST_NAME): - """Create network, subnet, and port resources for test cases. - - Create a network, subnet, port and then update the port, yield the - result, then delete the port, subnet and network. - - :param name: Name of network to be created. - :param cidr: cidr address of subnetwork to be created. - :param device_id: Device ID to use for port to be created/updated. - :param host_id: Host ID to use for port create/update. - - """ - with self.network(name=name) as network: - with self.subnet(network=network, cidr=cidr) as subnet: - with self.port(subnet=subnet, cidr=cidr) as port: - data = {'port': {portbindings.HOST_ID: host_id, - 'device_id': device_id, - 'device_owner': 'compute:none', - 'admin_state_up': True}} - req = self.new_update_request('ports', data, - port['port']['id']) - yield req.get_response(self.api) - - def _assertExpectedHTTP(self, status, exc): - """Confirm that an HTTP status corresponds to an expected exception. - - Confirm that an HTTP status which has been returned for an - neutron API request matches the HTTP status corresponding - to an expected exception. - - :param status: HTTP status - :param exc: Expected exception - - """ - if exc in base.FAULT_MAP: - expected_http = base.FAULT_MAP[exc].code - else: - expected_http = wexc.HTTPInternalServerError.code - self.assertEqual(status, expected_http) - - def test_create_ports_bulk_emulated_plugin_failure(self): - real_has_attr = hasattr - - #ensures the API chooses the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - plugin_obj = manager.NeutronManager.get_plugin() - orig = plugin_obj.create_port - with mock.patch.object(plugin_obj, - 'create_port') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - with self.network() as net: - res = self._create_port_bulk(self.fmt, 2, - net['network']['id'], - 'test', - True) - # Expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'ports', - wexc.HTTPInternalServerError.code) - - def test_create_ports_bulk_native(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk port create") - - def test_create_ports_bulk_emulated(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk port create") - - def test_create_ports_bulk_native_plugin_failure(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk port create") - ctx = context.get_admin_context() - with self.network() as net: - plugin_obj = manager.NeutronManager.get_plugin() - orig = plugin_obj.create_port - with mock.patch.object(plugin_obj, - 'create_port') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - res = self._create_port_bulk(self.fmt, 2, net['network']['id'], - 'test', True, context=ctx) - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'ports', - wexc.HTTPInternalServerError.code) - - def test_nexus_enable_vlan_cmd(self): - """Verify the syntax of the command to enable a vlan on an intf. - - Confirm that for the first VLAN configured on a Nexus interface, - the command string sent to the switch does not contain the - keyword 'add'. - - Confirm that for the second VLAN configured on a Nexus interface, - the command string sent to the switch contains the keyword 'add'. - - """ - # First vlan should be configured without 'add' keyword - with self._create_resources(): - self.assertTrue(self._is_vlan_configured( - vlan_creation_expected=True, - add_keyword_expected=False)) - self.mock_ncclient.reset_mock() - self.mock_bound_segment.return_value = BOUND_SEGMENT2 - - # Second vlan should be configured with 'add' keyword - with self._create_resources(name=NETWORK_NAME_2, - device_id=DEVICE_ID_2, - cidr=CIDR_2): - self.assertTrue(self._is_vlan_configured( - vlan_creation_expected=True, - add_keyword_expected=True)) - - # Return to first segment for delete port calls. - self.mock_bound_segment.return_value = BOUND_SEGMENT1 - - def test_nexus_add_trunk(self): - """Verify syntax to enable a vlan on an interface. - - Test also verifies that the vlan interface is not created. - - Test of the following ml2_conf_cisco_ini config: - [ml2_mech_cisco_nexus:1.1.1.1] - hostA=1/1 - hostB=1/2 - where vlan_id = 100 - - Confirm that for the first host configured on a Nexus interface, - the command string sent to the switch does not contain the - keyword 'add'. - - Confirm that for the second host configured on a Nexus interface, - the command staring sent to the switch contains does not contain - the keyword 'name' [signifies vlan intf creation]. - - """ - with self._create_resources(name='net1', cidr=CIDR_1): - self.assertTrue(self._is_in_last_nexus_cfg(['allowed', 'vlan'])) - self.assertFalse(self._is_in_last_nexus_cfg(['add'])) - with self._create_resources(name='net2', - cidr=CIDR_2, host_id=COMP_HOST_NAME_2): - self.assertTrue( - self._is_in_last_nexus_cfg(['allowed', 'vlan'])) - self.assertFalse(self._is_in_last_nexus_cfg(['name'])) - - def test_nexus_connect_fail(self): - """Test failure to connect to a Nexus switch. - - While creating a network, subnet, and port, simulate a connection - failure to a nexus switch. Confirm that the expected HTTP code - is returned for the create port operation. - - """ - with self._patch_ncclient('connect.side_effect', - AttributeError): - with self._create_resources() as result: - self._assertExpectedHTTP(result.status_int, - c_exc.NexusConnectFailed) - - def test_nexus_vlan_config_two_hosts(self): - """Verify config/unconfig of vlan on two compute hosts.""" - - @contextlib.contextmanager - def _create_port_check_vlan(comp_host_name, device_id, - vlan_creation_expected=True): - with self.port(subnet=subnet, fmt=self.fmt) as port: - data = {'port': {portbindings.HOST_ID: comp_host_name, - 'device_id': device_id, - 'device_owner': DEVICE_OWNER, - 'admin_state_up': True}} - req = self.new_update_request('ports', data, - port['port']['id']) - req.get_response(self.api) - self.assertTrue(self._is_vlan_configured( - vlan_creation_expected=vlan_creation_expected, - add_keyword_expected=False)) - self.mock_ncclient.reset_mock() - yield - - # Create network and subnet - with self.network(name=NETWORK_NAME) as network: - with self.subnet(network=network, cidr=CIDR_1) as subnet: - - # Create an instance on first compute host - with _create_port_check_vlan(COMP_HOST_NAME, DEVICE_ID_1, - vlan_creation_expected=True): - # Create an instance on second compute host - with _create_port_check_vlan(COMP_HOST_NAME_2, DEVICE_ID_2, - vlan_creation_expected=False): - pass - - # Instance on second host is now terminated. - # Vlan should be untrunked from port, but vlan should - # still exist on the switch. - self.assertTrue(self._is_vlan_unconfigured( - vlan_deletion_expected=False)) - self.mock_ncclient.reset_mock() - - # Instance on first host is now terminated. - # Vlan should be untrunked from port and vlan should have - # been deleted from the switch. - self.assertTrue(self._is_vlan_unconfigured( - vlan_deletion_expected=True)) - - def test_nexus_vm_migration(self): - """Verify VM (live) migration. - - Simulate the following: - Nova informs neutron of live-migration with port-update(new host). - This should trigger two update_port_pre/postcommit() calls. - - The first one should only change the current host_id and remove the - binding resulting in the mechanism drivers receiving: - PortContext.original['binding:host_id']: previous value - PortContext.original_bound_segment: previous value - PortContext.current['binding:host_id']: current (new) value - PortContext.bound_segment: None - - The second one binds the new host resulting in the mechanism - drivers receiving: - PortContext.original['binding:host_id']: previous value - PortContext.original_bound_segment: None - PortContext.current['binding:host_id']: previous value - PortContext.bound_segment: new value - """ - - # Create network, subnet and port. - with self._create_resources() as result: - # Verify initial database entry. - # Use port_id to verify that 1st host name was used. - binding = nexus_db_v2.get_nexusvm_bindings(VLAN_START, - DEVICE_ID_1)[0] - intf_type, nexus_port = binding.port_id.split(':') - self.assertEqual(nexus_port, NEXUS_INTERFACE) - - port = self.deserialize(self.fmt, result) - port_id = port['port']['id'] - - # Trigger update event to unbind segment. - # Results in port being deleted from nexus DB and switch. - data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME_2}} - self.mock_bound_segment.return_value = None - self.mock_original_bound_segment.return_value = BOUND_SEGMENT1 - self.new_update_request('ports', data, - port_id).get_response(self.api) - - # Verify that port entry has been deleted. - self.assertRaises(c_exc.NexusPortBindingNotFound, - nexus_db_v2.get_nexusvm_bindings, - VLAN_START, DEVICE_ID_1) - - # Trigger update event to bind segment with new host. - self.mock_bound_segment.return_value = BOUND_SEGMENT1 - self.mock_original_bound_segment.return_value = None - self.new_update_request('ports', data, - port_id).get_response(self.api) - - # Verify that port entry has been added using new host name. - # Use port_id to verify that 2nd host name was used. - binding = nexus_db_v2.get_nexusvm_bindings(VLAN_START, - DEVICE_ID_1)[0] - intf_type, nexus_port = binding.port_id.split(':') - self.assertEqual(nexus_port, NEXUS_INTERFACE_2) - - def test_nexus_config_fail(self): - """Test a Nexus switch configuration failure. - - While creating a network, subnet, and port, simulate a nexus - switch configuration error. Confirm that the expected HTTP code - is returned for the create port operation. - - """ - with self._patch_ncclient( - 'connect.return_value.edit_config.side_effect', - AttributeError): - with self._create_resources() as result: - self._assertExpectedHTTP(result.status_int, - c_exc.NexusConfigFailed) - - def test_nexus_extended_vlan_range_failure(self): - """Test that extended VLAN range config errors are ignored. - - Some versions of Nexus switch do not allow state changes for - the extended VLAN range (1006-4094), but these errors can be - ignored (default values are appropriate). Test that such errors - are ignored by the Nexus plugin. - - """ - def mock_edit_config_a(target, config): - if all(word in config for word in ['state', 'active']): - raise Exception("Can't modify state for extended") - - with self._patch_ncclient( - 'connect.return_value.edit_config.side_effect', - mock_edit_config_a): - with self._create_resources() as result: - self.assertEqual(result.status_int, wexc.HTTPOk.code) - - def mock_edit_config_b(target, config): - if all(word in config for word in ['no', 'shutdown']): - raise Exception("Command is only allowed on VLAN") - - with self._patch_ncclient( - 'connect.return_value.edit_config.side_effect', - mock_edit_config_b): - with self._create_resources() as result: - self.assertEqual(result.status_int, wexc.HTTPOk.code) - - def test_nexus_vlan_config_rollback(self): - """Test rollback following Nexus VLAN state config failure. - - Test that the Cisco Nexus plugin correctly deletes the VLAN - on the Nexus switch when the 'state active' command fails (for - a reason other than state configuration change is rejected - for the extended VLAN range). - - """ - vlan_state_configs = ['state active', 'no shutdown'] - for config in vlan_state_configs: - with self._patch_ncclient( - 'connect.return_value.edit_config.side_effect', - self._config_dependent_side_effect(config, ValueError)): - with self._create_resources() as result: - # Confirm that the last configuration sent to the Nexus - # switch was deletion of the VLAN. - self.assertTrue( - self._is_in_last_nexus_cfg(['', '']) - ) - self._assertExpectedHTTP(result.status_int, - c_exc.NexusConfigFailed) - - def test_nexus_host_not_configured(self): - """Test handling of a NexusComputeHostNotConfigured exception. - - Test the Cisco NexusComputeHostNotConfigured exception by using - a fictitious host name during port creation. - - """ - with self._create_resources(host_id='fake_host') as result: - self._assertExpectedHTTP(result.status_int, - c_exc.NexusComputeHostNotConfigured) - - def test_nexus_missing_fields(self): - """Test handling of a NexusMissingRequiredFields exception. - - Test the Cisco NexusMissingRequiredFields exception by using - empty host_id and device_id values during port creation. - - """ - with self._create_resources(device_id='', host_id='') as result: - self._assertExpectedHTTP(result.status_int, - c_exc.NexusMissingRequiredFields) - - -class TestCiscoNetworksV2(CiscoML2MechanismTestCase, - test_db_plugin.TestNetworksV2): - - def test_create_networks_bulk_emulated_plugin_failure(self): - real_has_attr = hasattr - - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - plugin_obj = manager.NeutronManager.get_plugin() - orig = plugin_obj.create_network - #ensures the API choose the emulation code path - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - with mock.patch.object(plugin_obj, - 'create_network') as patched_plugin: - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - patched_plugin.side_effect = side_effect - res = self._create_network_bulk(self.fmt, 2, 'test', True) - LOG.debug("response is %s" % res) - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'networks', - wexc.HTTPInternalServerError.code) - - def test_create_networks_bulk_native_plugin_failure(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk network create") - plugin_obj = manager.NeutronManager.get_plugin() - orig = plugin_obj.create_network - with mock.patch.object(plugin_obj, - 'create_network') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - res = self._create_network_bulk(self.fmt, 2, 'test', True) - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'networks', - wexc.HTTPInternalServerError.code) - - -class TestCiscoSubnetsV2(CiscoML2MechanismTestCase, - test_db_plugin.TestSubnetsV2): - - def test_create_subnets_bulk_emulated_plugin_failure(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - plugin_obj = manager.NeutronManager.get_plugin() - orig = plugin_obj.create_subnet - with mock.patch.object(plugin_obj, - 'create_subnet') as patched_plugin: - - def side_effect(*args, **kwargs): - self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - with self.network() as net: - res = self._create_subnet_bulk(self.fmt, 2, - net['network']['id'], - 'test') - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'subnets', - wexc.HTTPInternalServerError.code) - - def test_create_subnets_bulk_native_plugin_failure(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk subnet create") - plugin_obj = manager.NeutronManager.get_plugin() - orig = plugin_obj.create_subnet - with mock.patch.object(plugin_obj, - 'create_subnet') as patched_plugin: - def side_effect(*args, **kwargs): - return self._do_side_effect(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - with self.network() as net: - res = self._create_subnet_bulk(self.fmt, 2, - net['network']['id'], - 'test') - - # We expect an internal server error as we injected a fault - self._validate_behavior_on_bulk_failure( - res, - 'subnets', - wexc.HTTPInternalServerError.code) - - -class TestCiscoPortsV2XML(TestCiscoPortsV2): - fmt = 'xml' - - -class TestCiscoNetworksV2XML(TestCiscoNetworksV2): - fmt = 'xml' - - -class TestCiscoSubnetsV2XML(TestCiscoSubnetsV2): - fmt = 'xml' diff --git a/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_nexus.py b/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_nexus.py deleted file mode 100644 index 31573b82b..000000000 --- a/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_nexus.py +++ /dev/null @@ -1,201 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 collections -import mock -import testtools - -from neutron.common import constants as n_const -from neutron.db import api as db -from neutron.extensions import portbindings -from neutron.openstack.common import importutils -from neutron.plugins.ml2 import driver_api as api -from neutron.plugins.ml2.drivers.cisco.nexus import constants -from neutron.plugins.ml2.drivers.cisco.nexus import exceptions -from neutron.plugins.ml2.drivers.cisco.nexus import mech_cisco_nexus -from neutron.plugins.ml2.drivers.cisco.nexus import nexus_db_v2 -from neutron.plugins.ml2.drivers.cisco.nexus import nexus_network_driver -from neutron.tests import base - - -NEXUS_IP_ADDRESS = '1.1.1.1' -NEXUS_IP_ADDRESS_PC = '2.2.2.2' -HOST_NAME_1 = 'testhost1' -HOST_NAME_2 = 'testhost2' -HOST_NAME_PC = 'testpchost' -INSTANCE_1 = 'testvm1' -INSTANCE_2 = 'testvm2' -INSTANCE_PC = 'testpcvm' -NEXUS_PORT_1 = 'ethernet:1/10' -NEXUS_PORT_2 = 'ethernet:1/20' -NEXUS_PORTCHANNELS = 'portchannel:2' -VLAN_ID_1 = 267 -VLAN_ID_2 = 265 -VLAN_ID_PC = 268 -DEVICE_OWNER = 'compute:test' -NEXUS_SSH_PORT = '22' -PORT_STATE = n_const.PORT_STATUS_ACTIVE -NETWORK_TYPE = 'vlan' -NEXUS_DRIVER = ('neutron.plugins.ml2.drivers.cisco.nexus.' - 'nexus_network_driver.CiscoNexusDriver') - - -class FakeNetworkContext(object): - - """Network context for testing purposes only.""" - - def __init__(self, segment_id): - self._network_segments = {api.SEGMENTATION_ID: segment_id, - api.NETWORK_TYPE: NETWORK_TYPE} - - @property - def network_segments(self): - return self._network_segments - - -class FakePortContext(object): - - """Port context for testing purposes only.""" - - def __init__(self, device_id, host_name, network_context): - self._port = { - 'status': PORT_STATE, - 'device_id': device_id, - 'device_owner': DEVICE_OWNER, - portbindings.HOST_ID: host_name - } - self._network = network_context - self._segment = network_context.network_segments - - @property - def current(self): - return self._port - - @property - def network(self): - return self._network - - @property - def bound_segment(self): - return self._segment - - -class TestCiscoNexusDevice(base.BaseTestCase): - - """Unit tests for Cisco ML2 Nexus device driver.""" - - TestConfigObj = collections.namedtuple( - 'TestConfigObj', - 'nexus_ip_addr host_name nexus_port instance_id vlan_id') - - test_configs = { - 'test_config1': TestConfigObj( - NEXUS_IP_ADDRESS, - HOST_NAME_1, - NEXUS_PORT_1, - INSTANCE_1, - VLAN_ID_1), - 'test_config2': TestConfigObj( - NEXUS_IP_ADDRESS, - HOST_NAME_2, - NEXUS_PORT_2, - INSTANCE_2, - VLAN_ID_2), - 'test_config_portchannel': TestConfigObj( - NEXUS_IP_ADDRESS_PC, - HOST_NAME_PC, - NEXUS_PORTCHANNELS, - INSTANCE_PC, - VLAN_ID_PC), - } - - def setUp(self): - """Sets up mock ncclient, and switch and credentials dictionaries.""" - super(TestCiscoNexusDevice, self).setUp() - - # Use a mock netconf client - mock_ncclient = mock.Mock() - mock.patch.object(nexus_network_driver.CiscoNexusDriver, - '_import_ncclient', - return_value=mock_ncclient).start() - - def new_nexus_init(mech_instance): - mech_instance.driver = importutils.import_object(NEXUS_DRIVER) - - mech_instance._nexus_switches = {} - for name, config in TestCiscoNexusDevice.test_configs.items(): - ip_addr = config.nexus_ip_addr - host_name = config.host_name - nexus_port = config.nexus_port - mech_instance._nexus_switches[(ip_addr, - host_name)] = nexus_port - mech_instance._nexus_switches[(ip_addr, - 'ssh_port')] = NEXUS_SSH_PORT - mech_instance._nexus_switches[(ip_addr, - constants.USERNAME)] = 'admin' - mech_instance._nexus_switches[(ip_addr, - constants.PASSWORD)] = 'password' - mech_instance.driver.nexus_switches = ( - mech_instance._nexus_switches) - - db.configure_db() - - mock.patch.object(mech_cisco_nexus.CiscoNexusMechanismDriver, - '__init__', new=new_nexus_init).start() - self._cisco_mech_driver = (mech_cisco_nexus. - CiscoNexusMechanismDriver()) - - self.addCleanup(db.clear_db) - - def _create_delete_port(self, port_config): - """Tests creation and deletion of a virtual port.""" - nexus_ip_addr = port_config.nexus_ip_addr - host_name = port_config.host_name - nexus_port = port_config.nexus_port - instance_id = port_config.instance_id - vlan_id = port_config.vlan_id - - network_context = FakeNetworkContext(vlan_id) - port_context = FakePortContext(instance_id, host_name, - network_context) - - self._cisco_mech_driver.update_port_precommit(port_context) - self._cisco_mech_driver.update_port_postcommit(port_context) - bindings = nexus_db_v2.get_nexusport_binding(nexus_port, - vlan_id, - nexus_ip_addr, - instance_id) - self.assertEqual(len(bindings), 1) - - self._cisco_mech_driver.delete_port_precommit(port_context) - self._cisco_mech_driver.delete_port_postcommit(port_context) - with testtools.ExpectedException(exceptions.NexusPortBindingNotFound): - nexus_db_v2.get_nexusport_binding(nexus_port, - vlan_id, - nexus_ip_addr, - instance_id) - - def test_create_delete_ports(self): - """Tests creation and deletion of two new virtual Ports.""" - self._create_delete_port( - TestCiscoNexusDevice.test_configs['test_config1']) - - self._create_delete_port( - TestCiscoNexusDevice.test_configs['test_config2']) - - def test_create_delete_portchannel(self): - """Tests creation of a port over a portchannel.""" - self._create_delete_port( - TestCiscoNexusDevice.test_configs['test_config_portchannel']) diff --git a/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_nexus_db.py b/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_nexus_db.py deleted file mode 100644 index 08cc9a951..000000000 --- a/neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_nexus_db.py +++ /dev/null @@ -1,206 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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 collections -import testtools - -from neutron.db import api as db -from neutron.plugins.ml2.drivers.cisco.nexus import exceptions -from neutron.plugins.ml2.drivers.cisco.nexus import nexus_db_v2 -from neutron.tests import base - - -class CiscoNexusDbTest(base.BaseTestCase): - - """Unit tests for Cisco mechanism driver's Nexus port binding database.""" - - NpbObj = collections.namedtuple('NpbObj', 'port vlan switch instance') - - def setUp(self): - super(CiscoNexusDbTest, self).setUp() - db.configure_db() - self.addCleanup(db.clear_db) - - def _npb_test_obj(self, pnum, vnum, switch='10.9.8.7', instance=None): - """Creates a Nexus port binding test object from a pair of numbers.""" - if pnum is 'router': - port = pnum - else: - port = '1/%s' % pnum - if instance is None: - instance = 'instance_%s_%s' % (pnum, vnum) - return self.NpbObj(port, vnum, switch, instance) - - def _assert_bindings_match(self, npb, npb_obj): - """Asserts that a port binding matches a port binding test obj.""" - self.assertEqual(npb.port_id, npb_obj.port) - self.assertEqual(npb.vlan_id, npb_obj.vlan) - self.assertEqual(npb.switch_ip, npb_obj.switch) - self.assertEqual(npb.instance_id, npb_obj.instance) - - def _add_binding_to_db(self, npb): - """Adds a port binding to the Nexus database.""" - return nexus_db_v2.add_nexusport_binding( - npb.port, npb.vlan, npb.switch, npb.instance) - - def _add_bindings_to_db(self, npbs): - """Adds a list of port bindings to the Nexus database.""" - for npb in npbs: - nexus_db_v2.add_nexusport_binding( - npb.port, npb.vlan, npb.switch, npb.instance) - - def _remove_binding_from_db(self, npb): - """Removes a port binding from the Nexus database.""" - return nexus_db_v2.remove_nexusport_binding( - npb.port, npb.vlan, npb.switch, npb.instance) - - def _get_nexusport_binding(self, npb): - """Gets a port binding based on port, vlan, switch, and instance.""" - return nexus_db_v2.get_nexusport_binding( - npb.port, npb.vlan, npb.switch, npb.instance) - - def _get_nexusvlan_binding(self, npb): - """Gets port bindings based on vlan and switch.""" - return nexus_db_v2.get_nexusvlan_binding(npb.vlan, npb.switch) - - def _get_nexusvm_binding(self, npb): - """Gets port binding based on vlan and instance.""" - return nexus_db_v2.get_nexusvm_bindings(npb.vlan, npb.instance)[0] - - def _get_port_vlan_switch_binding(self, npb): - """Gets port bindings based on port, vlan, and switch.""" - return nexus_db_v2.get_port_vlan_switch_binding( - npb.port, npb.vlan, npb.switch) - - def _get_port_switch_bindings(self, npb): - """Get port bindings based on port and switch.""" - return nexus_db_v2.get_port_switch_bindings(npb.port, npb.switch) - - def test_nexusportbinding_add_remove(self): - """Tests add and removal of port bindings from the Nexus database.""" - npb11 = self._npb_test_obj(10, 100) - npb = self._add_binding_to_db(npb11) - self._assert_bindings_match(npb, npb11) - npb = self._remove_binding_from_db(npb11) - self.assertEqual(len(npb), 1) - self._assert_bindings_match(npb[0], npb11) - with testtools.ExpectedException(exceptions.NexusPortBindingNotFound): - self._remove_binding_from_db(npb11) - - def test_nexusportbinding_get(self): - """Tests get of specific port bindings from the database.""" - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100) - npb22 = self._npb_test_obj(20, 200) - self._add_bindings_to_db([npb11, npb21, npb22]) - - npb = self._get_nexusport_binding(npb11) - self.assertEqual(len(npb), 1) - self._assert_bindings_match(npb[0], npb11) - npb = self._get_nexusport_binding(npb21) - self.assertEqual(len(npb), 1) - self._assert_bindings_match(npb[0], npb21) - npb = self._get_nexusport_binding(npb22) - self.assertEqual(len(npb), 1) - self._assert_bindings_match(npb[0], npb22) - - with testtools.ExpectedException(exceptions.NexusPortBindingNotFound): - nexus_db_v2.get_nexusport_binding( - npb21.port, npb21.vlan, npb21.switch, "dummyInstance") - - def test_nexusvlanbinding_get(self): - """Test get of port bindings based on vlan and switch.""" - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100) - npb22 = self._npb_test_obj(20, 200) - self._add_bindings_to_db([npb11, npb21, npb22]) - - npb_all_v100 = self._get_nexusvlan_binding(npb11) - self.assertEqual(len(npb_all_v100), 2) - npb_v200 = self._get_nexusvlan_binding(npb22) - self.assertEqual(len(npb_v200), 1) - self._assert_bindings_match(npb_v200[0], npb22) - - with testtools.ExpectedException(exceptions.NexusPortBindingNotFound): - nexus_db_v2.get_nexusvlan_binding(npb21.vlan, "dummySwitch") - - def test_nexusvmbinding_get(self): - """Test get of port bindings based on vlan and instance.""" - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100) - npb22 = self._npb_test_obj(20, 200) - self._add_bindings_to_db([npb11, npb21, npb22]) - - npb = self._get_nexusvm_binding(npb21) - self._assert_bindings_match(npb, npb21) - npb = self._get_nexusvm_binding(npb22) - self._assert_bindings_match(npb, npb22) - - with testtools.ExpectedException(exceptions.NexusPortBindingNotFound): - nexus_db_v2.get_nexusvm_bindings(npb21.vlan, "dummyInstance")[0] - - def test_nexusportvlanswitchbinding_get(self): - """Tests get of port bindings based on port, vlan, and switch.""" - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100) - self._add_bindings_to_db([npb11, npb21]) - - npb = self._get_port_vlan_switch_binding(npb11) - self.assertEqual(len(npb), 1) - self._assert_bindings_match(npb[0], npb11) - - with testtools.ExpectedException(exceptions.NexusPortBindingNotFound): - nexus_db_v2.get_port_vlan_switch_binding( - npb21.port, npb21.vlan, "dummySwitch") - - def test_nexusportswitchbinding_get(self): - """Tests get of port bindings based on port and switch.""" - npb11 = self._npb_test_obj(10, 100) - npb21 = self._npb_test_obj(20, 100, switch='2.2.2.2') - npb22 = self._npb_test_obj(20, 200, switch='2.2.2.2') - self._add_bindings_to_db([npb11, npb21, npb22]) - - npb = self._get_port_switch_bindings(npb11) - self.assertEqual(len(npb), 1) - self._assert_bindings_match(npb[0], npb11) - npb_all_p20 = self._get_port_switch_bindings(npb21) - self.assertEqual(len(npb_all_p20), 2) - - npb = nexus_db_v2.get_port_switch_bindings(npb21.port, "dummySwitch") - self.assertIsNone(npb) - - def test_nexusbinding_update(self): - """Tests update of vlan IDs for port bindings.""" - npb11 = self._npb_test_obj(10, 100, switch='1.1.1.1', instance='test') - npb21 = self._npb_test_obj(20, 100, switch='1.1.1.1', instance='test') - self._add_bindings_to_db([npb11, npb21]) - - npb_all_v100 = nexus_db_v2.get_nexusvlan_binding(100, '1.1.1.1') - self.assertEqual(len(npb_all_v100), 2) - - npb22 = self._npb_test_obj(20, 200, switch='1.1.1.1', instance='test') - npb = nexus_db_v2.update_nexusport_binding(npb21.port, 200) - self._assert_bindings_match(npb, npb22) - - npb_all_v100 = nexus_db_v2.get_nexusvlan_binding(100, '1.1.1.1') - self.assertEqual(len(npb_all_v100), 1) - self._assert_bindings_match(npb_all_v100[0], npb11) - - npb = nexus_db_v2.update_nexusport_binding(npb21.port, 0) - self.assertIsNone(npb) - - npb33 = self._npb_test_obj(30, 300, switch='1.1.1.1', instance='test') - with testtools.ExpectedException(exceptions.NexusPortBindingNotFound): - nexus_db_v2.update_nexusport_binding(npb33.port, 200) diff --git a/neutron/tests/unit/ml2/drivers/mechanism_bulkless.py b/neutron/tests/unit/ml2/drivers/mechanism_bulkless.py deleted file mode 100644 index 0a0d3de93..000000000 --- a/neutron/tests/unit/ml2/drivers/mechanism_bulkless.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.plugins.ml2 import driver_api as api - - -class BulklessMechanismDriver(api.MechanismDriver): - """Test mechanism driver for testing bulk emulation.""" - - def initialize(self): - self.native_bulk_support = False diff --git a/neutron/tests/unit/ml2/drivers/mechanism_logger.py b/neutron/tests/unit/ml2/drivers/mechanism_logger.py deleted file mode 100644 index 401badb16..000000000 --- a/neutron/tests/unit/ml2/drivers/mechanism_logger.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.openstack.common import log -from neutron.plugins.ml2 import driver_api as api - -LOG = log.getLogger(__name__) - - -class LoggerMechanismDriver(api.MechanismDriver): - """Mechanism driver that logs all calls and parameters made. - - Generally used for testing and debugging. - """ - - def initialize(self): - pass - - def _log_network_call(self, method_name, context): - LOG.info(_("%(method)s called with network settings %(current)s " - "(original settings %(original)s) and " - "network segments %(segments)s"), - {'method': method_name, - 'current': context.current, - 'original': context.original, - 'segments': context.network_segments}) - - def create_network_precommit(self, context): - self._log_network_call("create_network_precommit", context) - - def create_network_postcommit(self, context): - self._log_network_call("create_network_postcommit", context) - - def update_network_precommit(self, context): - self._log_network_call("update_network_precommit", context) - - def update_network_postcommit(self, context): - self._log_network_call("update_network_postcommit", context) - - def delete_network_precommit(self, context): - self._log_network_call("delete_network_precommit", context) - - def delete_network_postcommit(self, context): - self._log_network_call("delete_network_postcommit", context) - - def _log_subnet_call(self, method_name, context): - LOG.info(_("%(method)s called with subnet settings %(current)s " - "(original settings %(original)s)"), - {'method': method_name, - 'current': context.current, - 'original': context.original}) - - def create_subnet_precommit(self, context): - self._log_subnet_call("create_subnet_precommit", context) - - def create_subnet_postcommit(self, context): - self._log_subnet_call("create_subnet_postcommit", context) - - def update_subnet_precommit(self, context): - self._log_subnet_call("update_subnet_precommit", context) - - def update_subnet_postcommit(self, context): - self._log_subnet_call("update_subnet_postcommit", context) - - def delete_subnet_precommit(self, context): - self._log_subnet_call("delete_subnet_precommit", context) - - def delete_subnet_postcommit(self, context): - self._log_subnet_call("delete_subnet_postcommit", context) - - def _log_port_call(self, method_name, context): - network_context = context.network - LOG.info(_("%(method)s called with port settings %(current)s " - "(original settings %(original)s) " - "bound to segment %(segment)s " - "(original segment %(original_segment)s) " - "using driver %(driver)s " - "(original driver %(original_driver)s) " - "on network %(network)s"), - {'method': method_name, - 'current': context.current, - 'original': context.original, - 'segment': context.bound_segment, - 'original_segment': context.original_bound_segment, - 'driver': context.bound_driver, - 'original_driver': context.original_bound_driver, - 'network': network_context.current}) - - def create_port_precommit(self, context): - self._log_port_call("create_port_precommit", context) - - def create_port_postcommit(self, context): - self._log_port_call("create_port_postcommit", context) - - def update_port_precommit(self, context): - self._log_port_call("update_port_precommit", context) - - def update_port_postcommit(self, context): - self._log_port_call("update_port_postcommit", context) - - def delete_port_precommit(self, context): - self._log_port_call("delete_port_precommit", context) - - def delete_port_postcommit(self, context): - self._log_port_call("delete_port_postcommit", context) - - def bind_port(self, context): - self._log_port_call("bind_port", context) diff --git a/neutron/tests/unit/ml2/drivers/mechanism_test.py b/neutron/tests/unit/ml2/drivers/mechanism_test.py deleted file mode 100644 index 6a0ca1e86..000000000 --- a/neutron/tests/unit/ml2/drivers/mechanism_test.py +++ /dev/null @@ -1,171 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.common import constants as const -from neutron.extensions import portbindings -from neutron.plugins.ml2 import driver_api as api - - -class TestMechanismDriver(api.MechanismDriver): - """Test mechanism driver for testing mechanism driver api.""" - - def initialize(self): - self.bound_ports = set() - - def _check_network_context(self, context, original_expected): - assert(isinstance(context, api.NetworkContext)) - assert(isinstance(context.current, dict)) - assert(context.current['id'] is not None) - if original_expected: - assert(isinstance(context.original, dict)) - assert(context.current['id'] == context.original['id']) - else: - assert(not context.original) - assert(context.network_segments) - - def create_network_precommit(self, context): - self._check_network_context(context, False) - - def create_network_postcommit(self, context): - self._check_network_context(context, False) - - def update_network_precommit(self, context): - self._check_network_context(context, True) - - def update_network_postcommit(self, context): - self._check_network_context(context, True) - - def delete_network_precommit(self, context): - self._check_network_context(context, False) - - def delete_network_postcommit(self, context): - self._check_network_context(context, False) - - def _check_subnet_context(self, context, original_expected): - assert(isinstance(context, api.SubnetContext)) - assert(isinstance(context.current, dict)) - assert(context.current['id'] is not None) - if original_expected: - assert(isinstance(context.original, dict)) - assert(context.current['id'] == context.original['id']) - else: - assert(not context.original) - - def create_subnet_precommit(self, context): - self._check_subnet_context(context, False) - - def create_subnet_postcommit(self, context): - self._check_subnet_context(context, False) - - def update_subnet_precommit(self, context): - self._check_subnet_context(context, True) - - def update_subnet_postcommit(self, context): - self._check_subnet_context(context, True) - - def delete_subnet_precommit(self, context): - self._check_subnet_context(context, False) - - def delete_subnet_postcommit(self, context): - self._check_subnet_context(context, False) - - def _check_port_context(self, context, original_expected): - assert(isinstance(context, api.PortContext)) - assert(isinstance(context.current, dict)) - assert(context.current['id'] is not None) - - vif_type = context.current.get(portbindings.VIF_TYPE) - assert(vif_type is not None) - - if vif_type in (portbindings.VIF_TYPE_UNBOUND, - portbindings.VIF_TYPE_BINDING_FAILED): - assert(context.bound_segment is None) - assert(context.bound_driver is None) - assert(context.current['id'] not in self.bound_ports) - else: - assert(isinstance(context.bound_segment, dict)) - assert(context.bound_driver == 'test') - assert(context.current['id'] in self.bound_ports) - - if original_expected: - assert(isinstance(context.original, dict)) - assert(context.current['id'] == context.original['id']) - vif_type = context.original.get(portbindings.VIF_TYPE) - assert(vif_type is not None) - if vif_type in (portbindings.VIF_TYPE_UNBOUND, - portbindings.VIF_TYPE_BINDING_FAILED): - assert(context.original_bound_segment is None) - assert(context.original_bound_driver is None) - else: - assert(isinstance(context.original_bound_segment, dict)) - assert(context.original_bound_driver == 'test') - else: - assert(context.original is None) - assert(context.original_bound_segment is None) - assert(context.original_bound_driver is None) - - network_context = context.network - assert(isinstance(network_context, api.NetworkContext)) - self._check_network_context(network_context, False) - - def create_port_precommit(self, context): - self._check_port_context(context, False) - - def create_port_postcommit(self, context): - self._check_port_context(context, False) - - def update_port_precommit(self, context): - if (context.original_bound_driver == 'test' and - context.bound_driver != 'test'): - self.bound_ports.remove(context.original['id']) - self._check_port_context(context, True) - - def update_port_postcommit(self, context): - self._check_port_context(context, True) - - def delete_port_precommit(self, context): - self._check_port_context(context, False) - - def delete_port_postcommit(self, context): - self._check_port_context(context, False) - - def bind_port(self, context): - # REVISIT(rkukura): The upcoming fix for bug 1276391 will - # ensure the MDs see the unbinding of the port as a port - # update prior to re-binding, at which point this should be - # removed. - self.bound_ports.discard(context.current['id']) - - # REVISIT(rkukura): Currently, bind_port() is called as part - # of either a create or update transaction. The fix for bug - # 1276391 will change it to be called outside any transaction, - # so the context.original* will no longer be available. - self._check_port_context(context, context.original is not None) - - host = context.current.get(portbindings.HOST_ID, None) - segment = context.network.network_segments[0][api.ID] - if host == "host-ovs-no_filter": - context.set_binding(segment, portbindings.VIF_TYPE_OVS, - {portbindings.CAP_PORT_FILTER: False}) - self.bound_ports.add(context.current['id']) - elif host == "host-bridge-filter": - context.set_binding(segment, portbindings.VIF_TYPE_BRIDGE, - {portbindings.CAP_PORT_FILTER: True}) - self.bound_ports.add(context.current['id']) - elif host == "host-ovs-filter-active": - context.set_binding(segment, portbindings.VIF_TYPE_OVS, - {portbindings.CAP_PORT_FILTER: True}, - status=const.PORT_STATUS_ACTIVE) - self.bound_ports.add(context.current['id']) diff --git a/neutron/tests/unit/ml2/drivers/test_arista_mechanism_driver.py b/neutron/tests/unit/ml2/drivers/test_arista_mechanism_driver.py deleted file mode 100644 index 039839532..000000000 --- a/neutron/tests/unit/ml2/drivers/test_arista_mechanism_driver.py +++ /dev/null @@ -1,726 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2013 OpenStack Foundation -# -# 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 oslo.config import cfg - -from neutron.common import constants as n_const -import neutron.db.api as ndb -from neutron.plugins.ml2.drivers.mech_arista import db -from neutron.plugins.ml2.drivers.mech_arista import exceptions as arista_exc -from neutron.plugins.ml2.drivers.mech_arista import mechanism_arista as arista -from neutron.tests import base - - -def setup_arista_wrapper_config(value=''): - cfg.CONF.keystone_authtoken = fake_keystone_info_class() - cfg.CONF.set_override('eapi_host', value, "ml2_arista") - cfg.CONF.set_override('eapi_username', value, "ml2_arista") - - -def setup_valid_config(): - # Config is not valid if value is not set - setup_arista_wrapper_config('value') - - -class AristaProvisionedVlansStorageTestCase(base.BaseTestCase): - """Test storing and retriving functionality of Arista mechanism driver. - - Tests all methods of this class by invoking them separately as well - as a group. - """ - - def setUp(self): - super(AristaProvisionedVlansStorageTestCase, self).setUp() - ndb.configure_db() - self.addCleanup(ndb.clear_db) - - def test_tenant_is_remembered(self): - tenant_id = 'test' - - db.remember_tenant(tenant_id) - net_provisioned = db.is_tenant_provisioned(tenant_id) - self.assertTrue(net_provisioned, 'Tenant must be provisioned') - - def test_tenant_is_removed(self): - tenant_id = 'test' - - db.remember_tenant(tenant_id) - db.forget_tenant(tenant_id) - net_provisioned = db.is_tenant_provisioned(tenant_id) - self.assertFalse(net_provisioned, 'The Tenant should be deleted') - - def test_network_is_remembered(self): - tenant_id = 'test' - network_id = '123' - segmentation_id = 456 - - db.remember_network(tenant_id, network_id, segmentation_id) - net_provisioned = db.is_network_provisioned(tenant_id, - network_id) - self.assertTrue(net_provisioned, 'Network must be provisioned') - - def test_network_is_removed(self): - tenant_id = 'test' - network_id = '123' - - db.remember_network(tenant_id, network_id, '123') - db.forget_network(tenant_id, network_id) - net_provisioned = db.is_network_provisioned(tenant_id, network_id) - self.assertFalse(net_provisioned, 'The network should be deleted') - - def test_vm_is_remembered(self): - vm_id = 'VM-1' - tenant_id = 'test' - network_id = '123' - port_id = 456 - host_id = 'ubuntu1' - - db.remember_vm(vm_id, host_id, port_id, network_id, tenant_id) - vm_provisioned = db.is_vm_provisioned(vm_id, host_id, port_id, - network_id, tenant_id) - self.assertTrue(vm_provisioned, 'VM must be provisioned') - - def test_vm_is_removed(self): - vm_id = 'VM-1' - tenant_id = 'test' - network_id = '123' - port_id = 456 - host_id = 'ubuntu1' - - db.remember_vm(vm_id, host_id, port_id, network_id, tenant_id) - db.forget_vm(vm_id, host_id, port_id, network_id, tenant_id) - vm_provisioned = db.is_vm_provisioned(vm_id, host_id, port_id, - network_id, tenant_id) - self.assertFalse(vm_provisioned, 'The vm should be deleted') - - def test_remembers_multiple_networks(self): - tenant_id = 'test' - expected_num_nets = 100 - nets = ['id%s' % n for n in range(expected_num_nets)] - for net_id in nets: - db.remember_network(tenant_id, net_id, 123) - - num_nets_provisioned = db.num_nets_provisioned(tenant_id) - self.assertEqual(expected_num_nets, num_nets_provisioned, - 'There should be %d nets, not %d' % - (expected_num_nets, num_nets_provisioned)) - - def test_removes_all_networks(self): - tenant_id = 'test' - num_nets = 100 - old_nets = db.num_nets_provisioned(tenant_id) - nets = ['id_%s' % n for n in range(num_nets)] - for net_id in nets: - db.remember_network(tenant_id, net_id, 123) - for net_id in nets: - db.forget_network(tenant_id, net_id) - - num_nets_provisioned = db.num_nets_provisioned(tenant_id) - expected = old_nets - self.assertEqual(expected, num_nets_provisioned, - 'There should be %d nets, not %d' % - (expected, num_nets_provisioned)) - - def test_remembers_multiple_tenants(self): - expected_num_tenants = 100 - tenants = ['id%s' % n for n in range(expected_num_tenants)] - for tenant_id in tenants: - db.remember_tenant(tenant_id) - - num_tenants_provisioned = db.num_provisioned_tenants() - self.assertEqual(expected_num_tenants, num_tenants_provisioned, - 'There should be %d tenants, not %d' % - (expected_num_tenants, num_tenants_provisioned)) - - def test_removes_multiple_tenants(self): - num_tenants = 100 - tenants = ['id%s' % n for n in range(num_tenants)] - for tenant_id in tenants: - db.remember_tenant(tenant_id) - for tenant_id in tenants: - db.forget_tenant(tenant_id) - - num_tenants_provisioned = db.num_provisioned_tenants() - expected = 0 - self.assertEqual(expected, num_tenants_provisioned, - 'There should be %d tenants, not %d' % - (expected, num_tenants_provisioned)) - - def test_num_vm_is_valid(self): - tenant_id = 'test' - network_id = '123' - port_id = 456 - host_id = 'ubuntu1' - - vm_to_remember = ['vm1', 'vm2', 'vm3'] - vm_to_forget = ['vm2', 'vm1'] - - for vm in vm_to_remember: - db.remember_vm(vm, host_id, port_id, network_id, tenant_id) - for vm in vm_to_forget: - db.forget_vm(vm, host_id, port_id, network_id, tenant_id) - - num_vms = len(db.get_vms(tenant_id)) - expected = len(vm_to_remember) - len(vm_to_forget) - - self.assertEqual(expected, num_vms, - 'There should be %d records, ' - 'got %d records' % (expected, num_vms)) - # clean up afterwards - db.forget_vm('vm3', host_id, port_id, network_id, tenant_id) - - def test_get_network_list_returns_eos_compatible_data(self): - tenant = u'test-1' - segm_type = 'vlan' - network_id = u'123' - network2_id = u'1234' - vlan_id = 123 - vlan2_id = 1234 - expected_eos_net_list = {network_id: {u'networkId': network_id, - u'segmentationTypeId': vlan_id, - u'segmentationType': segm_type}, - network2_id: {u'networkId': network2_id, - u'segmentationTypeId': vlan2_id, - u'segmentationType': segm_type}} - - db.remember_network(tenant, network_id, vlan_id) - db.remember_network(tenant, network2_id, vlan2_id) - - net_list = db.get_networks(tenant) - self.assertNotEqual(net_list != expected_eos_net_list, ('%s != %s' % - (net_list, expected_eos_net_list))) - - -class PositiveRPCWrapperValidConfigTestCase(base.BaseTestCase): - """Test cases to test the RPC between Arista Driver and EOS. - - Tests all methods used to send commands between Arista Driver and EOS - """ - - def setUp(self): - super(PositiveRPCWrapperValidConfigTestCase, self).setUp() - setup_valid_config() - self.drv = arista.AristaRPCWrapper() - self.region = 'RegionOne' - self.drv._server = mock.MagicMock() - - def _get_exit_mode_cmds(self, modes): - return ['exit'] * len(modes) - - def test_no_exception_on_correct_configuration(self): - self.assertIsNotNone(self.drv) - - def test_plug_host_into_network(self): - tenant_id = 'ten-1' - vm_id = 'vm-1' - port_id = 123 - network_id = 'net-id' - host = 'host' - port_name = '123-port' - - self.drv.plug_host_into_network(vm_id, host, port_id, - network_id, tenant_id, port_name) - cmds = ['enable', 'configure', 'cvx', 'service openstack', - 'region RegionOne', - 'tenant ten-1', 'vm id vm-1 hostid host', - 'port id 123 name "123-port" network-id net-id', - 'exit', 'exit', 'exit', 'exit', 'exit'] - - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_plug_dhcp_port_into_network(self): - tenant_id = 'ten-1' - vm_id = 'vm-1' - port_id = 123 - network_id = 'net-id' - host = 'host' - port_name = '123-port' - - self.drv.plug_dhcp_port_into_network(vm_id, host, port_id, - network_id, tenant_id, port_name) - cmds = ['enable', 'configure', 'cvx', 'service openstack', - 'region RegionOne', - 'tenant ten-1', 'network id net-id', - 'dhcp id vm-1 hostid host port-id 123 name "123-port"', - 'exit', 'exit', 'exit', 'exit'] - - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_unplug_host_from_network(self): - tenant_id = 'ten-1' - vm_id = 'vm-1' - port_id = 123 - network_id = 'net-id' - host = 'host' - self.drv.unplug_host_from_network(vm_id, host, port_id, - network_id, tenant_id) - cmds = ['enable', 'configure', 'cvx', 'service openstack', - 'region RegionOne', - 'tenant ten-1', 'vm id vm-1 hostid host', - 'no port id 123', - 'exit', 'exit', 'exit', 'exit', 'exit'] - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_unplug_dhcp_port_from_network(self): - tenant_id = 'ten-1' - vm_id = 'vm-1' - port_id = 123 - network_id = 'net-id' - host = 'host' - - self.drv.unplug_dhcp_port_from_network(vm_id, host, port_id, - network_id, tenant_id) - cmds = ['enable', 'configure', 'cvx', 'service openstack', - 'region RegionOne', - 'tenant ten-1', 'network id net-id', - 'no dhcp id vm-1 port-id 123', - 'exit', 'exit', 'exit', 'exit'] - - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_create_network(self): - tenant_id = 'ten-1' - network = { - 'network_id': 'net-id', - 'network_name': 'net-name', - 'segmentation_id': 123} - self.drv.create_network(tenant_id, network) - cmds = ['enable', 'configure', 'cvx', 'service openstack', - 'region RegionOne', - 'tenant ten-1', 'network id net-id name "net-name"', - 'segment 1 type vlan id 123', - 'exit', 'exit', 'exit', 'exit', 'exit', 'exit'] - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_create_network_bulk(self): - tenant_id = 'ten-2' - num_networks = 10 - networks = [{ - 'network_id': 'net-id-%d' % net_id, - 'network_name': 'net-name-%d' % net_id, - 'segmentation_id': net_id} for net_id in range(1, num_networks) - ] - - self.drv.create_network_bulk(tenant_id, networks) - cmds = ['enable', - 'configure', - 'cvx', - 'service openstack', - 'region RegionOne', - 'tenant ten-2'] - for net_id in range(1, num_networks): - cmds.append('network id net-id-%d name "net-name-%d"' % - (net_id, net_id)) - cmds.append('segment 1 type vlan id %d' % net_id) - - cmds.extend(self._get_exit_mode_cmds(['tenant', 'region', 'openstack', - 'cvx', 'configure', 'enable'])) - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_delete_network(self): - tenant_id = 'ten-1' - network_id = 'net-id' - self.drv.delete_network(tenant_id, network_id) - cmds = ['enable', 'configure', 'cvx', 'service openstack', - 'region RegionOne', - 'tenant ten-1', 'no network id net-id', - 'exit', 'exit', 'exit', 'exit', 'exit'] - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_delete_network_bulk(self): - tenant_id = 'ten-2' - num_networks = 10 - networks = [{ - 'network_id': 'net-id-%d' % net_id, - 'network_name': 'net-name-%d' % net_id, - 'segmentation_id': net_id} for net_id in range(1, num_networks) - ] - - networks = ['net-id-%d' % net_id for net_id in range(1, num_networks)] - self.drv.delete_network_bulk(tenant_id, networks) - cmds = ['enable', - 'configure', - 'cvx', - 'service openstack', - 'region RegionOne', - 'tenant ten-2'] - for net_id in range(1, num_networks): - cmds.append('no network id net-id-%d' % net_id) - - cmds.extend(self._get_exit_mode_cmds(['tenant', 'region', 'openstack', - 'cvx', 'configure'])) - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_delete_vm(self): - tenant_id = 'ten-1' - vm_id = 'vm-id' - self.drv.delete_vm(tenant_id, vm_id) - cmds = ['enable', 'configure', 'cvx', 'service openstack', - 'region RegionOne', - 'tenant ten-1', 'no vm id vm-id', - 'exit', 'exit', 'exit', 'exit', 'exit'] - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_delete_vm_bulk(self): - tenant_id = 'ten-2' - num_vms = 10 - vm_ids = ['vm-id-%d' % vm_id for vm_id in range(1, num_vms)] - self.drv.delete_vm_bulk(tenant_id, vm_ids) - - cmds = ['enable', - 'configure', - 'cvx', - 'service openstack', - 'region RegionOne', - 'tenant ten-2'] - - for vm_id in range(1, num_vms): - cmds.append('no vm id vm-id-%d' % vm_id) - - cmds.extend(self._get_exit_mode_cmds(['tenant', 'region', 'openstack', - 'cvx', 'configure'])) - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_create_vm_port_bulk(self): - tenant_id = 'ten-3' - num_vms = 10 - num_ports_per_vm = 2 - - vms = dict( - ('vm-id-%d' % vm_id, { - 'vmId': 'vm-id-%d' % vm_id, - 'host': 'host_%d' % vm_id, - } - ) for vm_id in range(1, num_vms) - ) - - devices = [n_const.DEVICE_OWNER_DHCP, 'compute'] - vm_port_list = [] - - net_count = 1 - for vm_id in range(1, num_vms): - for port_id in range(1, num_ports_per_vm): - port = { - 'id': 'port-id-%d-%d' % (vm_id, port_id), - 'device_id': 'vm-id-%d' % vm_id, - 'device_owner': devices[(vm_id + port_id) % 2], - 'network_id': 'network-id-%d' % net_count, - 'name': 'port-%d-%d' % (vm_id, port_id) - } - vm_port_list.append(port) - net_count += 1 - - self.drv.create_vm_port_bulk(tenant_id, vm_port_list, vms) - cmds = ['enable', - 'configure', - 'cvx', - 'service openstack', - 'region RegionOne', - 'tenant ten-3'] - - net_count = 1 - for vm_count in range(1, num_vms): - host = 'host_%s' % vm_count - for port_count in range(1, num_ports_per_vm): - vm_id = 'vm-id-%d' % vm_count - device_owner = devices[(vm_count + port_count) % 2] - port_name = '"port-%d-%d"' % (vm_count, port_count) - network_id = 'network-id-%d' % net_count - port_id = 'port-id-%d-%d' % (vm_count, port_count) - if device_owner == 'network:dhcp': - cmds.append('network id %s' % network_id) - cmds.append('dhcp id %s hostid %s port-id %s name %s' % ( - vm_id, host, port_id, port_name)) - elif device_owner == 'compute': - cmds.append('vm id %s hostid %s' % (vm_id, host)) - cmds.append('port id %s name %s network-id %s' % ( - port_id, port_name, network_id)) - net_count += 1 - - cmds.extend(self._get_exit_mode_cmds(['tenant', 'region', - 'openstack', 'cvx'])) - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_delete_tenant(self): - tenant_id = 'ten-1' - self.drv.delete_tenant(tenant_id) - cmds = ['enable', 'configure', 'cvx', 'service openstack', - 'region RegionOne', 'no tenant ten-1', - 'exit', 'exit', 'exit', 'exit'] - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_delete_tenant_bulk(self): - num_tenants = 10 - tenant_list = ['ten-%d' % t_id for t_id in range(1, num_tenants)] - self.drv.delete_tenant_bulk(tenant_list) - cmds = ['enable', - 'configure', - 'cvx', - 'service openstack', - 'region RegionOne'] - for ten_id in range(1, num_tenants): - cmds.append('no tenant ten-%d' % ten_id) - - cmds.extend(self._get_exit_mode_cmds(['region', 'openstack', - 'cvx', 'configure'])) - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - def test_get_network_info_returns_none_when_no_such_net(self): - expected = [] - self.drv.get_tenants = mock.MagicMock() - self.drv.get_tenants.return_value = [] - - net_info = self.drv.get_tenants() - - self.drv.get_tenants.assert_called_once_with() - self.assertEqual(net_info, expected, ('Network info must be "None"' - 'for unknown network')) - - def test_get_network_info_returns_info_for_available_net(self): - valid_network_id = '12345' - valid_net_info = {'network_id': valid_network_id, - 'some_info': 'net info'} - known_nets = valid_net_info - - self.drv.get_tenants = mock.MagicMock() - self.drv.get_tenants.return_value = known_nets - - net_info = self.drv.get_tenants() - self.assertEqual(net_info, valid_net_info, - ('Must return network info for a valid net')) - - def test_check_cli_commands(self): - self.drv.check_cli_commands() - cmds = ['show openstack config region RegionOne timestamp'] - self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) - - -class AristaRPCWrapperInvalidConfigTestCase(base.BaseTestCase): - """Negative test cases to test the Arista Driver configuration.""" - - def setUp(self): - super(AristaRPCWrapperInvalidConfigTestCase, self).setUp() - self.setup_invalid_config() # Invalid config, required options not set - - def setup_invalid_config(self): - setup_arista_wrapper_config('') - - def test_raises_exception_on_wrong_configuration(self): - self.assertRaises(arista_exc.AristaConfigError, - arista.AristaRPCWrapper) - - -class NegativeRPCWrapperTestCase(base.BaseTestCase): - """Negative test cases to test the RPC between Arista Driver and EOS.""" - - def setUp(self): - super(NegativeRPCWrapperTestCase, self).setUp() - setup_valid_config() - - def test_exception_is_raised_on_json_server_error(self): - drv = arista.AristaRPCWrapper() - - drv._server = mock.MagicMock() - drv._server.runCmds.side_effect = Exception('server error') - self.assertRaises(arista_exc.AristaRpcError, drv.get_tenants) - - -class RealNetStorageAristaDriverTestCase(base.BaseTestCase): - """Main test cases for Arista Mechanism driver. - - Tests all mechanism driver APIs supported by Arista Driver. It invokes - all the APIs as they would be invoked in real world scenarios and - verifies the functionality. - """ - def setUp(self): - super(RealNetStorageAristaDriverTestCase, self).setUp() - self.fake_rpc = mock.MagicMock() - ndb.configure_db() - self.drv = arista.AristaDriver(self.fake_rpc) - - def tearDown(self): - super(RealNetStorageAristaDriverTestCase, self).tearDown() - self.drv.stop_synchronization_thread() - - def test_create_and_delete_network(self): - tenant_id = 'ten-1' - network_id = 'net1-id' - segmentation_id = 1001 - - network_context = self._get_network_context(tenant_id, - network_id, - segmentation_id) - self.drv.create_network_precommit(network_context) - net_provisioned = db.is_network_provisioned(tenant_id, network_id) - self.assertTrue(net_provisioned, 'The network should be created') - - expected_num_nets = 1 - num_nets_provisioned = db.num_nets_provisioned(tenant_id) - self.assertEqual(expected_num_nets, num_nets_provisioned, - 'There should be %d nets, not %d' % - (expected_num_nets, num_nets_provisioned)) - - #Now test the delete network - self.drv.delete_network_precommit(network_context) - net_provisioned = db.is_network_provisioned(tenant_id, network_id) - self.assertFalse(net_provisioned, 'The network should be created') - - expected_num_nets = 0 - num_nets_provisioned = db.num_nets_provisioned(tenant_id) - self.assertEqual(expected_num_nets, num_nets_provisioned, - 'There should be %d nets, not %d' % - (expected_num_nets, num_nets_provisioned)) - - def test_create_and_delete_multiple_networks(self): - tenant_id = 'ten-1' - expected_num_nets = 100 - segmentation_id = 1001 - nets = ['id%s' % n for n in range(expected_num_nets)] - for net_id in nets: - network_context = self._get_network_context(tenant_id, - net_id, - segmentation_id) - self.drv.create_network_precommit(network_context) - - num_nets_provisioned = db.num_nets_provisioned(tenant_id) - self.assertEqual(expected_num_nets, num_nets_provisioned, - 'There should be %d nets, not %d' % - (expected_num_nets, num_nets_provisioned)) - - #now test the delete networks - for net_id in nets: - network_context = self._get_network_context(tenant_id, - net_id, - segmentation_id) - self.drv.delete_network_precommit(network_context) - - num_nets_provisioned = db.num_nets_provisioned(tenant_id) - expected_num_nets = 0 - self.assertEqual(expected_num_nets, num_nets_provisioned, - 'There should be %d nets, not %d' % - (expected_num_nets, num_nets_provisioned)) - - def test_create_and_delete_ports(self): - tenant_id = 'ten-1' - network_id = 'net1-id' - segmentation_id = 1001 - vms = ['vm1', 'vm2', 'vm3'] - - network_context = self._get_network_context(tenant_id, - network_id, - segmentation_id) - self.drv.create_network_precommit(network_context) - - for vm_id in vms: - port_context = self._get_port_context(tenant_id, - network_id, - vm_id, - network_context) - self.drv.create_port_precommit(port_context) - - vm_list = db.get_vms(tenant_id) - provisioned_vms = len(vm_list) - expected_vms = len(vms) - self.assertEqual(expected_vms, provisioned_vms, - 'There should be %d ' - 'hosts, not %d' % (expected_vms, provisioned_vms)) - - # Now test the delete ports - for vm_id in vms: - port_context = self._get_port_context(tenant_id, - network_id, - vm_id, - network_context) - self.drv.delete_port_precommit(port_context) - - vm_list = db.get_vms(tenant_id) - provisioned_vms = len(vm_list) - expected_vms = 0 - self.assertEqual(expected_vms, provisioned_vms, - 'There should be %d ' - 'VMs, not %d' % (expected_vms, provisioned_vms)) - - def _get_network_context(self, tenant_id, net_id, seg_id): - network = {'id': net_id, - 'tenant_id': tenant_id} - network_segments = [{'segmentation_id': seg_id}] - return FakeNetworkContext(network, network_segments, network) - - def _get_port_context(self, tenant_id, net_id, vm_id, network): - port = {'device_id': vm_id, - 'device_owner': 'compute', - 'binding:host_id': 'ubuntu1', - 'tenant_id': tenant_id, - 'id': 101, - 'network_id': net_id - } - return FakePortContext(port, port, network) - - -class fake_keystone_info_class(object): - """To generate fake Keystone Authentification token information - - Arista Driver expects Keystone auth info. This fake information - is for testing only - """ - auth_protocol = 'abc' - auth_host = 'host' - auth_port = 5000 - admin_user = 'neutron' - admin_password = 'fun' - - -class FakeNetworkContext(object): - """To generate network context for testing purposes only.""" - - def __init__(self, network, segments=None, original_network=None): - self._network = network - self._original_network = original_network - self._segments = segments - - @property - def current(self): - return self._network - - @property - def original(self): - return self._original_network - - @property - def network_segments(self): - return self._segments - - -class FakePortContext(object): - """To generate port context for testing purposes only.""" - - def __init__(self, port, original_port, network): - self._port = port - self._original_port = original_port - self._network_context = network - - @property - def current(self): - return self._port - - @property - def original(self): - return self._original_port - - @property - def network(self): - return self._network_context diff --git a/neutron/tests/unit/ml2/drivers/test_bigswitch_mech.py b/neutron/tests/unit/ml2/drivers/test_bigswitch_mech.py deleted file mode 100644 index ea884ae51..000000000 --- a/neutron/tests/unit/ml2/drivers/test_bigswitch_mech.py +++ /dev/null @@ -1,144 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2014 Big Switch Networks, Inc. -# All Rights Reserved. -# -# 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 contextlib -import mock -import webob.exc - -from neutron import context as neutron_context -from neutron.extensions import portbindings -from neutron import manager -from neutron.plugins.bigswitch import servermanager -from neutron.plugins.ml2 import config as ml2_config -from neutron.plugins.ml2.drivers import type_vlan as vlan_config -import neutron.tests.unit.bigswitch.test_restproxy_plugin as trp -from neutron.tests.unit.ml2 import test_ml2_plugin -from neutron.tests.unit import test_db_plugin - -PHYS_NET = 'physnet1' -VLAN_START = 1000 -VLAN_END = 1100 -SERVER_POOL = 'neutron.plugins.bigswitch.servermanager.ServerPool' -DRIVER_MOD = 'neutron.plugins.ml2.drivers.mech_bigswitch.driver' -DRIVER = DRIVER_MOD + '.BigSwitchMechanismDriver' - - -class TestBigSwitchMechDriverBase(trp.BigSwitchProxyPluginV2TestCase): - - def setUp(self): - # Configure the ML2 mechanism drivers and network types - ml2_opts = { - 'mechanism_drivers': ['bigswitch'], - 'tenant_network_types': ['vlan'], - } - for opt, val in ml2_opts.items(): - ml2_config.cfg.CONF.set_override(opt, val, 'ml2') - - # Configure the ML2 VLAN parameters - phys_vrange = ':'.join([PHYS_NET, str(VLAN_START), str(VLAN_END)]) - vlan_config.cfg.CONF.set_override('network_vlan_ranges', - [phys_vrange], - 'ml2_type_vlan') - super(TestBigSwitchMechDriverBase, - self).setUp(test_ml2_plugin.PLUGIN_NAME) - - -class TestBigSwitchMechDriverNetworksV2(test_db_plugin.TestNetworksV2, - TestBigSwitchMechDriverBase): - pass - - -class TestBigSwitchMechDriverPortsV2(test_db_plugin.TestPortsV2, - TestBigSwitchMechDriverBase): - - VIF_TYPE = portbindings.VIF_TYPE_OVS - - def setUp(self): - super(TestBigSwitchMechDriverPortsV2, self).setUp() - self.port_create_status = 'DOWN' - - def test_update_port_status_build(self): - with self.port() as port: - self.assertEqual(port['port']['status'], 'DOWN') - self.assertEqual(self.port_create_status, 'DOWN') - - def _make_port(self, fmt, net_id, expected_res_status=None, arg_list=None, - **kwargs): - arg_list = arg_list or () - arg_list += ('binding:host_id', ) - res = self._create_port(fmt, net_id, expected_res_status, - arg_list, **kwargs) - # Things can go wrong - raise HTTP exc with res code only - # so it can be caught by unit tests - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - def test_create404_triggers_background_sync(self): - # allow the async background thread to run for this test - self.spawn_p.stop() - with contextlib.nested( - mock.patch(SERVER_POOL + '.rest_create_port', - side_effect=servermanager.RemoteRestError( - reason=servermanager.NXNETWORK, status=404)), - mock.patch(DRIVER + '._send_all_data'), - self.port(**{'device_id': 'devid', 'binding:host_id': 'host'}) - ) as (mock_http, mock_send_all, p): - # wait for thread to finish - mm = manager.NeutronManager.get_plugin().mechanism_manager - bigdriver = mm.mech_drivers['bigswitch'].obj - bigdriver.evpool.waitall() - mock_send_all.assert_has_calls([ - mock.call( - send_routers=False, send_ports=True, - send_floating_ips=False, - triggered_by_tenant=p['port']['tenant_id'] - ) - ]) - self.spawn_p.start() - - def test_udpate404_triggers_background_sync(self): - with contextlib.nested( - mock.patch(SERVER_POOL + '.rest_update_port', - side_effect=servermanager.RemoteRestError( - reason=servermanager.NXNETWORK, status=404)), - mock.patch(DRIVER + '._send_all_data'), - self.port() - ) as (mock_update, mock_send_all, p): - plugin = manager.NeutronManager.get_plugin() - context = neutron_context.get_admin_context() - plugin.update_port(context, p['port']['id'], - {'port': {'device_id': 'devid', - 'binding:host_id': 'host'}}) - mock_send_all.assert_has_calls([ - mock.call( - send_routers=False, send_ports=True, - send_floating_ips=False, - triggered_by_tenant=p['port']['tenant_id'] - ) - ]) - - def test_backend_request_contents(self): - with contextlib.nested( - mock.patch(SERVER_POOL + '.rest_create_port'), - self.port(**{'device_id': 'devid', 'binding:host_id': 'host'}) - ) as (mock_rest, p): - # make sure basic expected keys are present in the port body - pb = mock_rest.mock_calls[0][1][2] - self.assertEqual('host', pb['binding:host_id']) - self.assertIn('bound_segment', pb) - self.assertIn('network', pb) diff --git a/neutron/tests/unit/ml2/drivers/test_l2population.py b/neutron/tests/unit/ml2/drivers/test_l2population.py deleted file mode 100644 index d96be1ccd..000000000 --- a/neutron/tests/unit/ml2/drivers/test_l2population.py +++ /dev/null @@ -1,724 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. -# -# @author: Sylvain Afchain, eNovance SAS -# @author: Francois Eleouet, Orange -# @author: Mathieu Rohon, Orange - -import mock - -from neutron.common import constants -from neutron.common import topics -from neutron import context -from neutron.db import agents_db -from neutron.db import api as db_api -from neutron.extensions import portbindings -from neutron.extensions import providernet as pnet -from neutron import manager -from neutron.openstack.common import timeutils -from neutron.plugins.ml2 import config as config -from neutron.plugins.ml2.drivers.l2pop import constants as l2_consts -from neutron.plugins.ml2 import managers -from neutron.plugins.ml2 import rpc -from neutron.tests.unit import test_db_plugin as test_plugin - -HOST = 'my_l2_host' -L2_AGENT = { - 'binary': 'neutron-openvswitch-agent', - 'host': HOST, - 'topic': constants.L2_AGENT_TOPIC, - 'configurations': {'tunneling_ip': '20.0.0.1', - 'tunnel_types': ['vxlan']}, - 'agent_type': constants.AGENT_TYPE_OVS, - 'tunnel_type': [], - 'start_flag': True -} - -L2_AGENT_2 = { - 'binary': 'neutron-openvswitch-agent', - 'host': HOST + '_2', - 'topic': constants.L2_AGENT_TOPIC, - 'configurations': {'tunneling_ip': '20.0.0.2', - 'tunnel_types': ['vxlan']}, - 'agent_type': constants.AGENT_TYPE_OVS, - 'tunnel_type': [], - 'start_flag': True -} - -L2_AGENT_3 = { - 'binary': 'neutron-openvswitch-agent', - 'host': HOST + '_3', - 'topic': constants.L2_AGENT_TOPIC, - 'configurations': {'tunneling_ip': '20.0.0.3', - 'tunnel_types': []}, - 'agent_type': constants.AGENT_TYPE_OVS, - 'tunnel_type': [], - 'start_flag': True -} - -L2_AGENT_4 = { - 'binary': 'neutron-openvswitch-agent', - 'host': HOST + '_4', - 'topic': constants.L2_AGENT_TOPIC, - 'configurations': {'tunneling_ip': '20.0.0.4', - 'tunnel_types': ['vxlan']}, - 'agent_type': constants.AGENT_TYPE_OVS, - 'tunnel_type': [], - 'start_flag': True -} - -PLUGIN_NAME = 'neutron.plugins.ml2.plugin.Ml2Plugin' -NOTIFIER = 'neutron.plugins.ml2.rpc.AgentNotifierApi' - - -class TestL2PopulationRpcTestCase(test_plugin.NeutronDbPluginV2TestCase): - - def setUp(self): - # Enable the test mechanism driver to ensure that - # we can successfully call through to all mechanism - # driver apis. - config.cfg.CONF.set_override('mechanism_drivers', - ['openvswitch', 'linuxbridge', - 'l2population'], - 'ml2') - super(TestL2PopulationRpcTestCase, self).setUp(PLUGIN_NAME) - - self.adminContext = context.get_admin_context() - - self.type_manager = managers.TypeManager() - self.notifier = rpc.AgentNotifierApi(topics.AGENT) - self.callbacks = rpc.RpcCallbacks(self.notifier, self.type_manager) - - self.orig_supported_agents = l2_consts.SUPPORTED_AGENT_TYPES - l2_consts.SUPPORTED_AGENT_TYPES = [constants.AGENT_TYPE_OVS] - - net_arg = {pnet.NETWORK_TYPE: 'vxlan', - pnet.SEGMENTATION_ID: '1'} - self._network = self._make_network(self.fmt, 'net1', True, - arg_list=(pnet.NETWORK_TYPE, - pnet.SEGMENTATION_ID,), - **net_arg) - - notifier_patch = mock.patch(NOTIFIER) - notifier_patch.start() - - self.fanout_topic = topics.get_topic_name(topics.AGENT, - topics.L2POPULATION, - topics.UPDATE) - fanout = ('neutron.common.rpc_compat.RpcProxy.fanout_cast') - fanout_patch = mock.patch(fanout) - self.mock_fanout = fanout_patch.start() - - cast = ('neutron.common.rpc_compat.RpcProxy.cast') - cast_patch = mock.patch(cast) - self.mock_cast = cast_patch.start() - - uptime = ('neutron.plugins.ml2.drivers.l2pop.db.L2populationDbMixin.' - 'get_agent_uptime') - uptime_patch = mock.patch(uptime, return_value=190) - uptime_patch.start() - - self.addCleanup(db_api.clear_db) - - def tearDown(self): - l2_consts.SUPPORTED_AGENT_TYPES = self.orig_supported_agents - super(TestL2PopulationRpcTestCase, self).tearDown() - - def _register_ml2_agents(self): - callback = agents_db.AgentExtRpcCallback() - callback.report_state(self.adminContext, - agent_state={'agent_state': L2_AGENT}, - time=timeutils.strtime()) - callback.report_state(self.adminContext, - agent_state={'agent_state': L2_AGENT_2}, - time=timeutils.strtime()) - callback.report_state(self.adminContext, - agent_state={'agent_state': L2_AGENT_3}, - time=timeutils.strtime()) - callback.report_state(self.adminContext, - agent_state={'agent_state': L2_AGENT_4}, - time=timeutils.strtime()) - - def test_fdb_add_called(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port1: - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg): - p1 = port1['port'] - - device = 'tap' + p1['id'] - - self.mock_fanout.reset_mock() - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device) - - p1_ips = [p['ip_address'] for p in p1['fixed_ips']] - expected = {'args': - {'fdb_entries': - {p1['network_id']: - {'ports': - {'20.0.0.1': [constants.FLOODING_ENTRY, - [p1['mac_address'], - p1_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'add_fdb_entries'} - - self.mock_fanout.assert_called_with( - mock.ANY, expected, topic=self.fanout_topic) - - def test_fdb_add_not_called_type_local(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST + '_3'} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port1: - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg): - p1 = port1['port'] - - device = 'tap' + p1['id'] - - self.mock_fanout.reset_mock() - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device) - - self.assertFalse(self.mock_fanout.called) - - def test_fdb_add_two_agents(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST, - 'admin_state_up': True} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID, 'admin_state_up',), - **host_arg) as port1: - host_arg = {portbindings.HOST_ID: HOST + '_2', - 'admin_state_up': True} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID, - 'admin_state_up',), - **host_arg) as port2: - p1 = port1['port'] - p2 = port2['port'] - - device = 'tap' + p1['id'] - - self.mock_cast.reset_mock() - self.mock_fanout.reset_mock() - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device) - - p1_ips = [p['ip_address'] for p in p1['fixed_ips']] - p2_ips = [p['ip_address'] for p in p2['fixed_ips']] - - expected1 = {'args': - {'fdb_entries': - {p1['network_id']: - {'ports': - {'20.0.0.2': [constants.FLOODING_ENTRY, - [p2['mac_address'], - p2_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'add_fdb_entries'} - - topic = topics.get_topic_name(topics.AGENT, - topics.L2POPULATION, - topics.UPDATE, - HOST) - - self.mock_cast.assert_called_with(mock.ANY, - expected1, - topic=topic) - - expected2 = {'args': - {'fdb_entries': - {p1['network_id']: - {'ports': - {'20.0.0.1': [constants.FLOODING_ENTRY, - [p1['mac_address'], - p1_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'add_fdb_entries'} - - self.mock_fanout.assert_called_with( - mock.ANY, expected2, topic=self.fanout_topic) - - def test_fdb_add_called_two_networks(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST + '_2'} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port1: - with self.subnet(cidr='10.1.0.0/24') as subnet2: - with self.port(subnet=subnet2, - arg_list=(portbindings.HOST_ID,), - **host_arg): - host_arg = {portbindings.HOST_ID: HOST} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port3: - p1 = port1['port'] - p3 = port3['port'] - - device = 'tap' + p3['id'] - - self.mock_cast.reset_mock() - self.mock_fanout.reset_mock() - self.callbacks.update_device_up( - self.adminContext, agent_id=HOST, - device=device) - - p1_ips = [p['ip_address'] - for p in p1['fixed_ips']] - expected1 = {'args': - {'fdb_entries': - {p1['network_id']: - {'ports': - {'20.0.0.2': - [constants.FLOODING_ENTRY, - [p1['mac_address'], - p1_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'add_fdb_entries'} - - topic = topics.get_topic_name(topics.AGENT, - topics.L2POPULATION, - topics.UPDATE, - HOST) - - self.mock_cast.assert_called_with(mock.ANY, - expected1, - topic=topic) - - p3_ips = [p['ip_address'] - for p in p3['fixed_ips']] - expected2 = {'args': - {'fdb_entries': - {p1['network_id']: - {'ports': - {'20.0.0.1': - [constants.FLOODING_ENTRY, - [p3['mac_address'], - p3_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'add_fdb_entries'} - - self.mock_fanout.assert_called_with( - mock.ANY, expected2, - topic=self.fanout_topic) - - def test_update_port_down(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port1: - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port2: - p2 = port2['port'] - device2 = 'tap' + p2['id'] - - self.mock_fanout.reset_mock() - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device2) - - p1 = port1['port'] - device1 = 'tap' + p1['id'] - - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device1) - self.mock_fanout.reset_mock() - self.callbacks.update_device_down(self.adminContext, - agent_id=HOST, - device=device2) - - p2_ips = [p['ip_address'] for p in p2['fixed_ips']] - expected = {'args': - {'fdb_entries': - {p2['network_id']: - {'ports': - {'20.0.0.1': [[p2['mac_address'], - p2_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'remove_fdb_entries'} - - self.mock_fanout.assert_called_with( - mock.ANY, expected, topic=self.fanout_topic) - - def test_update_port_down_last_port_up(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg): - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port2: - p2 = port2['port'] - device2 = 'tap' + p2['id'] - - self.mock_fanout.reset_mock() - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device2) - - self.callbacks.update_device_down(self.adminContext, - agent_id=HOST, - device=device2) - - p2_ips = [p['ip_address'] for p in p2['fixed_ips']] - expected = {'args': - {'fdb_entries': - {p2['network_id']: - {'ports': - {'20.0.0.1': [constants.FLOODING_ENTRY, - [p2['mac_address'], - p2_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'remove_fdb_entries'} - - self.mock_fanout.assert_called_with( - mock.ANY, expected, topic=self.fanout_topic) - - def test_delete_port(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port: - p1 = port['port'] - device = 'tap' + p1['id'] - - self.mock_fanout.reset_mock() - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device) - - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port2: - p2 = port2['port'] - device1 = 'tap' + p2['id'] - - self.mock_fanout.reset_mock() - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device1) - - p2_ips = [p['ip_address'] for p in p2['fixed_ips']] - expected = {'args': - {'fdb_entries': - {p2['network_id']: - {'ports': - {'20.0.0.1': [[p2['mac_address'], - p2_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'remove_fdb_entries'} - - self.mock_fanout.assert_any_call( - mock.ANY, expected, topic=self.fanout_topic) - - def test_delete_port_last_port_up(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST} - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg): - with self.port(subnet=subnet, - arg_list=(portbindings.HOST_ID,), - **host_arg) as port: - p1 = port['port'] - - device = 'tap' + p1['id'] - - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device) - - p1_ips = [p['ip_address'] for p in p1['fixed_ips']] - expected = {'args': - {'fdb_entries': - {p1['network_id']: - {'ports': - {'20.0.0.1': [constants.FLOODING_ENTRY, - [p1['mac_address'], - p1_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'remove_fdb_entries'} - - self.mock_fanout.assert_any_call( - mock.ANY, expected, topic=self.fanout_topic) - - def test_fixed_ips_changed(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST} - with self.port(subnet=subnet, cidr='10.0.0.0/24', - arg_list=(portbindings.HOST_ID,), - **host_arg) as port1: - p1 = port1['port'] - - device = 'tap' + p1['id'] - - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device) - - self.mock_fanout.reset_mock() - - data = {'port': {'fixed_ips': [{'ip_address': '10.0.0.2'}, - {'ip_address': '10.0.0.10'}]}} - req = self.new_update_request('ports', data, p1['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - ips = res['port']['fixed_ips'] - self.assertEqual(len(ips), 2) - - add_expected = {'args': - {'fdb_entries': - {'chg_ip': - {p1['network_id']: - {'20.0.0.1': - {'after': [[p1['mac_address'], - '10.0.0.10']]}}}}}, - 'namespace': None, - 'method': 'update_fdb_entries'} - - self.mock_fanout.assert_any_call( - mock.ANY, add_expected, topic=self.fanout_topic) - - self.mock_fanout.reset_mock() - - data = {'port': {'fixed_ips': [{'ip_address': '10.0.0.2'}, - {'ip_address': '10.0.0.16'}]}} - req = self.new_update_request('ports', data, p1['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - ips = res['port']['fixed_ips'] - self.assertEqual(len(ips), 2) - - upd_expected = {'args': - {'fdb_entries': - {'chg_ip': - {p1['network_id']: - {'20.0.0.1': - {'before': [[p1['mac_address'], - '10.0.0.10']], - 'after': [[p1['mac_address'], - '10.0.0.16']]}}}}}, - 'namespace': None, - 'method': 'update_fdb_entries'} - - self.mock_fanout.assert_any_call( - mock.ANY, upd_expected, topic=self.fanout_topic) - - self.mock_fanout.reset_mock() - - data = {'port': {'fixed_ips': [{'ip_address': '10.0.0.16'}]}} - req = self.new_update_request('ports', data, p1['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - ips = res['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - - del_expected = {'args': - {'fdb_entries': - {'chg_ip': - {p1['network_id']: - {'20.0.0.1': - {'before': [[p1['mac_address'], - '10.0.0.2']]}}}}}, - 'namespace': None, - 'method': 'update_fdb_entries'} - - self.mock_fanout.assert_any_call( - mock.ANY, del_expected, topic=self.fanout_topic) - - def test_no_fdb_updates_without_port_updates(self): - self._register_ml2_agents() - - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST} - with self.port(subnet=subnet, cidr='10.0.0.0/24', - arg_list=(portbindings.HOST_ID,), - **host_arg) as port1: - p1 = port1['port'] - - device = 'tap' + p1['id'] - - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device) - p1['status'] = 'ACTIVE' - self.mock_fanout.reset_mock() - - fanout = ('neutron.plugins.ml2.drivers.l2pop.rpc.' - 'L2populationAgentNotifyAPI._notification_fanout') - fanout_patch = mock.patch(fanout) - mock_fanout = fanout_patch.start() - - plugin = manager.NeutronManager.get_plugin() - plugin.update_port(self.adminContext, p1['id'], port1) - - self.assertFalse(mock_fanout.called) - fanout_patch.stop() - - def test_host_changed(self): - self._register_ml2_agents() - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: L2_AGENT['host']} - host2_arg = {portbindings.HOST_ID: L2_AGENT_2['host']} - with self.port(subnet=subnet, cidr='10.0.0.0/24', - arg_list=(portbindings.HOST_ID,), - **host_arg) as port1: - with self.port(subnet=subnet, cidr='10.0.0.0/24', - arg_list=(portbindings.HOST_ID,), - **host2_arg) as port2: - p1 = port1['port'] - device1 = 'tap' + p1['id'] - self.callbacks.update_device_up( - self.adminContext, - agent_id=L2_AGENT['host'], - device=device1) - p2 = port2['port'] - device2 = 'tap' + p2['id'] - self.callbacks.update_device_up( - self.adminContext, - agent_id=L2_AGENT_2['host'], - device=device2) - data2 = {'port': {'binding:host_id': L2_AGENT_2['host']}} - req = self.new_update_request('ports', data2, p1['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - self.assertEqual(res['port']['binding:host_id'], - L2_AGENT_2['host']) - self.mock_fanout.reset_mock() - self.callbacks.get_device_details( - self.adminContext, - device=device1, - agent_id=L2_AGENT_2['host']) - p1_ips = [p['ip_address'] for p in p1['fixed_ips']] - expected = {'args': - {'fdb_entries': - {p1['network_id']: - {'ports': - {'20.0.0.1': [constants.FLOODING_ENTRY, - [p1['mac_address'], - p1_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'remove_fdb_entries'} - - self.mock_fanout.assert_called_with( - mock.ANY, expected, topic=self.fanout_topic) - - def test_host_changed_twice(self): - self._register_ml2_agents() - with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: L2_AGENT['host']} - host2_arg = {portbindings.HOST_ID: L2_AGENT_2['host']} - with self.port(subnet=subnet, cidr='10.0.0.0/24', - arg_list=(portbindings.HOST_ID,), - **host_arg) as port1: - with self.port(subnet=subnet, cidr='10.0.0.0/24', - arg_list=(portbindings.HOST_ID,), - **host2_arg) as port2: - p1 = port1['port'] - device1 = 'tap' + p1['id'] - self.callbacks.update_device_up( - self.adminContext, - agent_id=L2_AGENT['host'], - device=device1) - p2 = port2['port'] - device2 = 'tap' + p2['id'] - self.callbacks.update_device_up( - self.adminContext, - agent_id=L2_AGENT_2['host'], - device=device2) - data2 = {'port': {'binding:host_id': L2_AGENT_2['host']}} - req = self.new_update_request('ports', data2, p1['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - self.assertEqual(res['port']['binding:host_id'], - L2_AGENT_2['host']) - data4 = {'port': {'binding:host_id': L2_AGENT_4['host']}} - req = self.new_update_request('ports', data4, p1['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - self.assertEqual(res['port']['binding:host_id'], - L2_AGENT_4['host']) - self.mock_fanout.reset_mock() - self.callbacks.get_device_details( - self.adminContext, - device=device1, - agent_id=L2_AGENT_4['host']) - p1_ips = [p['ip_address'] for p in p1['fixed_ips']] - expected = {'args': - {'fdb_entries': - {p1['network_id']: - {'ports': - {'20.0.0.1': [constants.FLOODING_ENTRY, - [p1['mac_address'], - p1_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'remove_fdb_entries'} - - self.mock_fanout.assert_called_with( - mock.ANY, expected, topic=self.fanout_topic) diff --git a/neutron/tests/unit/ml2/drivers/test_mech_mlnx.py b/neutron/tests/unit/ml2/drivers/test_mech_mlnx.py deleted file mode 100644 index 343af4233..000000000 --- a/neutron/tests/unit/ml2/drivers/test_mech_mlnx.py +++ /dev/null @@ -1,139 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation -# All Rights Reserved. -# -# 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 oslo.config import cfg - -from neutron.common import constants -from neutron.extensions import portbindings -from neutron.plugins.ml2 import driver_api as api -from neutron.plugins.ml2.drivers.mlnx import mech_mlnx -from neutron.tests.unit.ml2 import _test_mech_agent as base - - -class MlnxMechanismBaseTestCase(base.AgentMechanismBaseTestCase): - VIF_TYPE = portbindings.VIF_TYPE_MLNX_DIRECT - CAP_PORT_FILTER = False - AGENT_TYPE = constants.AGENT_TYPE_MLNX - - GOOD_MAPPINGS = {'fake_physical_network': 'fake_bridge'} - GOOD_CONFIGS = {'interface_mappings': GOOD_MAPPINGS} - - BAD_MAPPINGS = {'wrong_physical_network': 'wrong_bridge'} - BAD_CONFIGS = {'interface_mappings': BAD_MAPPINGS} - - AGENTS = [{'alive': True, - 'configurations': GOOD_CONFIGS}] - AGENTS_DEAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}] - AGENTS_BAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}, - {'alive': True, - 'configurations': BAD_CONFIGS}] - - def setUp(self): - super(MlnxMechanismBaseTestCase, self).setUp() - self.driver = mech_mlnx.MlnxMechanismDriver() - self.driver.initialize() - - -class MlnxMechanismGenericTestCase(MlnxMechanismBaseTestCase, - base.AgentMechanismGenericTestCase): - pass - - -class MlnxMechanismLocalTestCase(MlnxMechanismBaseTestCase, - base.AgentMechanismLocalTestCase): - pass - - -class MlnxMechanismFlatTestCase(MlnxMechanismBaseTestCase, - base.AgentMechanismFlatTestCase): - pass - - -class MlnxMechanismVlanTestCase(MlnxMechanismBaseTestCase, - base.AgentMechanismVlanTestCase): - pass - - -class MlnxMechanismVnicTypeTestCase(MlnxMechanismBaseTestCase, - base.AgentMechanismVlanTestCase): - def _check_vif_type_for_vnic_type(self, vnic_type, - expected_vif_type): - context = base.FakePortContext(self.AGENT_TYPE, - self.AGENTS, - self.VLAN_SEGMENTS, - vnic_type) - self.driver.bind_port(context) - self.assertEqual(expected_vif_type, context._bound_vif_type) - - def test_vnic_type_direct(self): - self._check_vif_type_for_vnic_type(portbindings.VNIC_DIRECT, - portbindings.VIF_TYPE_MLNX_HOSTDEV) - - def test_vnic_type_macvtap(self): - self._check_vif_type_for_vnic_type(portbindings.VNIC_MACVTAP, - portbindings.VIF_TYPE_MLNX_DIRECT) - - def test_vnic_type_normal(self): - self._check_vif_type_for_vnic_type(portbindings.VNIC_NORMAL, - self.VIF_TYPE) - - -class MlnxMechanismProfileTestCase(MlnxMechanismBaseTestCase): - def setUp(self): - cfg.CONF.set_override('apply_profile_patch', True, 'ESWITCH') - super(MlnxMechanismProfileTestCase, self).setUp() - - def test_profile_contains_physical_net(self): - VLAN_SEGMENTS = [{api.ID: 'vlan_segment_id', - api.NETWORK_TYPE: 'vlan', - api.PHYSICAL_NETWORK: 'fake_physical_network', - api.SEGMENTATION_ID: 1234}] - - context = base.FakePortContext(self.AGENT_TYPE, - self.AGENTS, - VLAN_SEGMENTS, - portbindings.VNIC_DIRECT) - context._binding = mock.Mock() - context._binding.profile = {} - segment = VLAN_SEGMENTS[0] - agent = self.AGENTS[0] - self.driver.try_to_bind_segment_for_agent(context, segment, agent) - self.assertEqual('{"physical_network": "fake_physical_network"}', - context._binding.profile) - - -class MlnxMechanismVifDetailsTestCase(MlnxMechanismBaseTestCase): - def setUp(self): - super(MlnxMechanismVifDetailsTestCase, self).setUp() - - def test_vif_details_contains_physical_net(self): - VLAN_SEGMENTS = [{api.ID: 'vlan_segment_id', - api.NETWORK_TYPE: 'vlan', - api.PHYSICAL_NETWORK: 'fake_physical_network', - api.SEGMENTATION_ID: 1234}] - - context = base.FakePortContext(self.AGENT_TYPE, - self.AGENTS, - VLAN_SEGMENTS, - portbindings.VNIC_DIRECT) - segment = VLAN_SEGMENTS[0] - agent = self.AGENTS[0] - self.driver.try_to_bind_segment_for_agent(context, segment, agent) - set({"physical_network": "fake_physical_network"}).issubset( - set(context._bound_vif_details.items())) diff --git a/neutron/tests/unit/ml2/drivers/test_ofagent_mech.py b/neutron/tests/unit/ml2/drivers/test_ofagent_mech.py deleted file mode 100644 index 63daf9ec0..000000000 --- a/neutron/tests/unit/ml2/drivers/test_ofagent_mech.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.common import constants -from neutron.extensions import portbindings -from neutron.plugins.ml2.drivers import mech_ofagent -from neutron.tests.unit.ml2 import _test_mech_agent as base - - -class OfagentMechanismBaseTestCase(base.AgentMechanismBaseTestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - CAP_PORT_FILTER = True - AGENT_TYPE = constants.AGENT_TYPE_OFA - - GOOD_MAPPINGS = {'fake_physical_network': 'fake_bridge'} - GOOD_TUNNEL_TYPES = ['gre', 'vxlan'] - GOOD_CONFIGS = {'bridge_mappings': GOOD_MAPPINGS, - 'tunnel_types': GOOD_TUNNEL_TYPES} - - BAD_MAPPINGS = {'wrong_physical_network': 'wrong_bridge'} - BAD_TUNNEL_TYPES = ['bad_tunnel_type'] - BAD_CONFIGS = {'bridge_mappings': BAD_MAPPINGS, - 'tunnel_types': BAD_TUNNEL_TYPES} - - AGENTS = [{'alive': True, - 'configurations': GOOD_CONFIGS}] - AGENTS_DEAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}] - AGENTS_BAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}, - {'alive': True, - 'configurations': BAD_CONFIGS}] - - def setUp(self): - super(OfagentMechanismBaseTestCase, self).setUp() - self.driver = mech_ofagent.OfagentMechanismDriver() - self.driver.initialize() - - -class OfagentMechanismGenericTestCase(OfagentMechanismBaseTestCase, - base.AgentMechanismGenericTestCase): - pass - - -class OfagentMechanismLocalTestCase(OfagentMechanismBaseTestCase, - base.AgentMechanismLocalTestCase): - pass - - -class OfagentMechanismFlatTestCase(OfagentMechanismBaseTestCase, - base.AgentMechanismFlatTestCase): - pass - - -class OfagentMechanismVlanTestCase(OfagentMechanismBaseTestCase, - base.AgentMechanismVlanTestCase): - pass - - -class OfagentMechanismGreTestCase(OfagentMechanismBaseTestCase, - base.AgentMechanismGreTestCase): - pass diff --git a/neutron/tests/unit/ml2/test_agent_scheduler.py b/neutron/tests/unit/ml2/test_agent_scheduler.py deleted file mode 100644 index fbf94a1b1..000000000 --- a/neutron/tests/unit/ml2/test_agent_scheduler.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.tests.unit.ml2 import test_ml2_plugin -from neutron.tests.unit.openvswitch import test_agent_scheduler - - -class Ml2AgentSchedulerTestCase( - test_agent_scheduler.OvsAgentSchedulerTestCase): - plugin_str = test_ml2_plugin.PLUGIN_NAME - l3_plugin = ('neutron.services.l3_router.' - 'l3_router_plugin.L3RouterPlugin') - - -class Ml2L3AgentNotifierTestCase( - test_agent_scheduler.OvsL3AgentNotifierTestCase): - plugin_str = test_ml2_plugin.PLUGIN_NAME - l3_plugin = ('neutron.services.l3_router.' - 'l3_router_plugin.L3RouterPlugin') - - -class Ml2DhcpAgentNotifierTestCase( - test_agent_scheduler.OvsDhcpAgentNotifierTestCase): - plugin_str = test_ml2_plugin.PLUGIN_NAME diff --git a/neutron/tests/unit/ml2/test_mech_hyperv.py b/neutron/tests/unit/ml2/test_mech_hyperv.py deleted file mode 100644 index 60ac1a620..000000000 --- a/neutron/tests/unit/ml2/test_mech_hyperv.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.common import constants -from neutron.extensions import portbindings -from neutron.plugins.ml2.drivers import mech_hyperv -from neutron.tests.unit.ml2 import _test_mech_agent as base - - -class HypervMechanismBaseTestCase(base.AgentMechanismBaseTestCase): - VIF_TYPE = portbindings.VIF_TYPE_HYPERV - CAP_PORT_FILTER = False - AGENT_TYPE = constants.AGENT_TYPE_HYPERV - - GOOD_MAPPINGS = {'fake_physical_network': 'fake_vswitch'} - GOOD_CONFIGS = {'vswitch_mappings': GOOD_MAPPINGS} - - BAD_MAPPINGS = {'wrong_physical_network': 'wrong_vswitch'} - BAD_CONFIGS = {'vswitch_mappings': BAD_MAPPINGS} - - AGENTS = [{'alive': True, - 'configurations': GOOD_CONFIGS}] - AGENTS_DEAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}] - AGENTS_BAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}, - {'alive': True, - 'configurations': BAD_CONFIGS}] - - def setUp(self): - super(HypervMechanismBaseTestCase, self).setUp() - self.driver = mech_hyperv.HypervMechanismDriver() - self.driver.initialize() - - -class HypervMechanismGenericTestCase(HypervMechanismBaseTestCase, - base.AgentMechanismGenericTestCase): - pass - - -class HypervMechanismLocalTestCase(HypervMechanismBaseTestCase, - base.AgentMechanismLocalTestCase): - pass - - -class HypervMechanismFlatTestCase(HypervMechanismBaseTestCase, - base.AgentMechanismFlatTestCase): - pass - - -class HypervMechanismVlanTestCase(HypervMechanismBaseTestCase, - base.AgentMechanismVlanTestCase): - pass diff --git a/neutron/tests/unit/ml2/test_mech_linuxbridge.py b/neutron/tests/unit/ml2/test_mech_linuxbridge.py deleted file mode 100644 index 66903c02b..000000000 --- a/neutron/tests/unit/ml2/test_mech_linuxbridge.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.common import constants -from neutron.extensions import portbindings -from neutron.plugins.ml2.drivers import mech_linuxbridge -from neutron.tests.unit.ml2 import _test_mech_agent as base - - -class LinuxbridgeMechanismBaseTestCase(base.AgentMechanismBaseTestCase): - VIF_TYPE = portbindings.VIF_TYPE_BRIDGE - CAP_PORT_FILTER = True - AGENT_TYPE = constants.AGENT_TYPE_LINUXBRIDGE - - GOOD_MAPPINGS = {'fake_physical_network': 'fake_interface'} - GOOD_TUNNEL_TYPES = ['gre', 'vxlan'] - GOOD_CONFIGS = {'interface_mappings': GOOD_MAPPINGS, - 'tunnel_types': GOOD_TUNNEL_TYPES} - - BAD_MAPPINGS = {'wrong_physical_network': 'wrong_interface'} - BAD_TUNNEL_TYPES = ['bad_tunnel_type'] - BAD_CONFIGS = {'interface_mappings': BAD_MAPPINGS, - 'tunnel_types': BAD_TUNNEL_TYPES} - - AGENTS = [{'alive': True, - 'configurations': GOOD_CONFIGS}] - AGENTS_DEAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}] - AGENTS_BAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}, - {'alive': True, - 'configurations': BAD_CONFIGS}] - - def setUp(self): - super(LinuxbridgeMechanismBaseTestCase, self).setUp() - self.driver = mech_linuxbridge.LinuxbridgeMechanismDriver() - self.driver.initialize() - - -class LinuxbridgeMechanismGenericTestCase(LinuxbridgeMechanismBaseTestCase, - base.AgentMechanismGenericTestCase): - pass - - -class LinuxbridgeMechanismLocalTestCase(LinuxbridgeMechanismBaseTestCase, - base.AgentMechanismLocalTestCase): - pass - - -class LinuxbridgeMechanismFlatTestCase(LinuxbridgeMechanismBaseTestCase, - base.AgentMechanismFlatTestCase): - pass - - -class LinuxbridgeMechanismVlanTestCase(LinuxbridgeMechanismBaseTestCase, - base.AgentMechanismVlanTestCase): - pass - - -class LinuxbridgeMechanismGreTestCase(LinuxbridgeMechanismBaseTestCase, - base.AgentMechanismGreTestCase): - pass diff --git a/neutron/tests/unit/ml2/test_mech_openvswitch.py b/neutron/tests/unit/ml2/test_mech_openvswitch.py deleted file mode 100644 index b1af1b7fa..000000000 --- a/neutron/tests/unit/ml2/test_mech_openvswitch.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.common import constants -from neutron.extensions import portbindings -from neutron.plugins.ml2.drivers import mech_openvswitch -from neutron.tests.unit.ml2 import _test_mech_agent as base - - -class OpenvswitchMechanismBaseTestCase(base.AgentMechanismBaseTestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - CAP_PORT_FILTER = True - AGENT_TYPE = constants.AGENT_TYPE_OVS - - GOOD_MAPPINGS = {'fake_physical_network': 'fake_bridge'} - GOOD_TUNNEL_TYPES = ['gre', 'vxlan'] - GOOD_CONFIGS = {'bridge_mappings': GOOD_MAPPINGS, - 'tunnel_types': GOOD_TUNNEL_TYPES} - - BAD_MAPPINGS = {'wrong_physical_network': 'wrong_bridge'} - BAD_TUNNEL_TYPES = ['bad_tunnel_type'] - BAD_CONFIGS = {'bridge_mappings': BAD_MAPPINGS, - 'tunnel_types': BAD_TUNNEL_TYPES} - - AGENTS = [{'alive': True, - 'configurations': GOOD_CONFIGS}] - AGENTS_DEAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}] - AGENTS_BAD = [{'alive': False, - 'configurations': GOOD_CONFIGS}, - {'alive': True, - 'configurations': BAD_CONFIGS}] - - def setUp(self): - super(OpenvswitchMechanismBaseTestCase, self).setUp() - self.driver = mech_openvswitch.OpenvswitchMechanismDriver() - self.driver.initialize() - - -class OpenvswitchMechanismGenericTestCase(OpenvswitchMechanismBaseTestCase, - base.AgentMechanismGenericTestCase): - pass - - -class OpenvswitchMechanismLocalTestCase(OpenvswitchMechanismBaseTestCase, - base.AgentMechanismLocalTestCase): - pass - - -class OpenvswitchMechanismFlatTestCase(OpenvswitchMechanismBaseTestCase, - base.AgentMechanismFlatTestCase): - pass - - -class OpenvswitchMechanismVlanTestCase(OpenvswitchMechanismBaseTestCase, - base.AgentMechanismVlanTestCase): - pass - - -class OpenvswitchMechanismGreTestCase(OpenvswitchMechanismBaseTestCase, - base.AgentMechanismGreTestCase): - pass diff --git a/neutron/tests/unit/ml2/test_mechanism_fslsdn.py b/neutron/tests/unit/ml2/test_mechanism_fslsdn.py deleted file mode 100644 index d39e5973f..000000000 --- a/neutron/tests/unit/ml2/test_mechanism_fslsdn.py +++ /dev/null @@ -1,293 +0,0 @@ -# Copyright (c) 2014 Freescale, Inc. -# -# 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. - -# @author: Trinath Somanchi, Freescale, Inc. - -import mock -from oslo.config import cfg - -from neutron.extensions import portbindings -from neutron.plugins.ml2.drivers import mechanism_fslsdn -from neutron.tests import base -from neutron.tests.unit import test_db_plugin - - -"""Unit testing for Freescale SDN mechanism driver.""" - - -def setup_driver_config(): - """Mechanism Driver specific configuration.""" - - # Configure mechanism driver as 'fslsdn' - cfg.CONF.set_override('mechanism_drivers', ['fslsdn'], 'ml2') - # Configure FSL SDN Mechanism driver specific options - cfg.CONF.set_override('crd_user_name', 'crd', 'ml2_fslsdn') - cfg.CONF.set_override('crd_password', 'CRD_PASS', 'ml2_fslsdn') - cfg.CONF.set_override('crd_tenant_name', 'service', 'ml2_fslsdn') - cfg.CONF.set_override('crd_auth_url', - 'http://127.0.0.1:5000/v2.0', 'ml2_fslsdn') - cfg.CONF.set_override('crd_url', - 'http://127.0.0.1:9797', 'ml2_fslsdn') - cfg.CONF.set_override('crd_auth_strategy', 'keystone', 'ml2_fslsdn') - - -class TestFslSdnMechDriverV2(test_db_plugin.NeutronDbPluginV2TestCase): - - """Testing mechanism driver with ML2 plugin.""" - - def setUp(self): - setup_driver_config() - - def mocked_fslsdn_init(self): - # Mock CRD client, since it requires CRD service running. - self._crdclieint = mock.Mock() - - with mock.patch.object(mechanism_fslsdn.FslsdnMechanismDriver, - 'initialize', new=mocked_fslsdn_init): - super(TestFslSdnMechDriverV2, self).setUp() - - -class TestFslSdnMechDriverNetworksV2(test_db_plugin.TestNetworksV2, - TestFslSdnMechDriverV2): - pass - - -class TestFslSdnMechDriverPortsV2(test_db_plugin.TestPortsV2, - TestFslSdnMechDriverV2): - VIF_TYPE = portbindings.VIF_TYPE_OVS - CAP_PORT_FILTER = True - - -class TestFslSdnMechDriverSubnetsV2(test_db_plugin.TestSubnetsV2, - TestFslSdnMechDriverV2): - pass - - -class TestFslSdnMechanismDriver(base.BaseTestCase): - - """Testing FSL SDN Mechanism driver.""" - - def setUp(self): - super(TestFslSdnMechanismDriver, self).setUp() - setup_driver_config() - self.driver = mechanism_fslsdn.FslsdnMechanismDriver() - self.driver.initialize() - self.client = self.driver._crdclient = mock.Mock() - - def test_create_update_delete_network_postcommit(self): - """Testing create/update/delete network postcommit operations.""" - - tenant_id = 'test' - network_id = '123' - segmentation_id = 456 - expected_seg = [{'segmentation_id': segmentation_id}] - expected_crd_network = {'network': - {'network_id': network_id, - 'tenant_id': tenant_id, - 'name': 'FakeNetwork', - 'status': 'ACTIVE', - 'admin_state_up': True, - 'segments': expected_seg}} - network_context = self._get_network_context(tenant_id, network_id, - segmentation_id) - network = network_context.current - segments = network_context.network_segments - net_id = network['id'] - req = self.driver._prepare_crd_network(network, segments) - # test crd network dict - self.assertEqual(expected_crd_network, req) - # test create_network. - self.driver.create_network_postcommit(network_context) - self.client.create_network.assert_called_once_with(body=req) - # test update_network. - self.driver.update_network_postcommit(network_context) - self.client.update_network.assert_called_once_with(net_id, body=req) - # test delete_network. - self.driver.delete_network_postcommit(network_context) - self.client.delete_network.assert_called_once_with(net_id) - - def test_create_update_delete_subnet_postcommit(self): - """Testing create/update/delete subnet postcommit operations.""" - - tenant_id = 'test' - network_id = '123' - subnet_id = '122' - cidr = '192.0.0.0/8' - gateway_ip = '192.0.0.1' - expected_crd_subnet = {'subnet': - {'subnet_id': subnet_id, 'tenant_id': tenant_id, - 'name': 'FakeSubnet', 'network_id': network_id, - 'ip_version': 4, 'cidr': cidr, - 'gateway_ip': gateway_ip, - 'dns_nameservers': '', - 'allocation_pools': '', - 'host_routes': ''}} - subnet_context = self._get_subnet_context(tenant_id, network_id, - subnet_id, cidr, gateway_ip) - subnet = subnet_context.current - subnet_id = subnet['id'] - req = self.driver._prepare_crd_subnet(subnet) - # test crd subnet dict - self.assertEqual(expected_crd_subnet, req) - # test create_subnet. - self.driver.create_subnet_postcommit(subnet_context) - self.client.create_subnet.assert_called_once_with(body=req) - # test update_subnet. - self.driver.update_subnet_postcommit(subnet_context) - self.client.update_subnet.assert_called_once_with(subnet_id, body=req) - # test delete_subnet. - self.driver.delete_subnet_postcommit(subnet_context) - self.client.delete_subnet.assert_called_once_with(subnet_id) - - def test_create_delete_port_postcommit(self): - """Testing create/delete port postcommit operations.""" - - tenant_id = 'test' - network_id = '123' - port_id = '453' - expected_crd_port = {'port': - {'port_id': port_id, 'tenant_id': tenant_id, - 'name': 'FakePort', 'network_id': network_id, - 'subnet_id': '', 'mac_address': 'aabb', - 'device_id': '1234', 'ip_address': '', - 'admin_state_up': True, 'status': 'ACTIVE', - 'device_owner': 'compute', - 'security_groups': ''}} - # Test with empty fixed IP - port_context = self._get_port_context(tenant_id, network_id, port_id) - port = port_context.current - req = self.driver._prepare_crd_port(port) - # Test crd port dict - self.assertEqual(expected_crd_port, req) - # test create_port. - self.driver.create_port_postcommit(port_context) - self.client.create_port.assert_called_once_with(body=req) - # Test delete_port - self.driver.delete_port_postcommit(port_context) - self.client.delete_port.assert_called_once_with(port['id']) - - def test_prepare_port_with_single_fixed_ip(self): - """Test _prepare_crd_port with single fixed_ip.""" - - tenant_id = 'test' - network_id = '123' - port_id = '453' - fips = [{"subnet_id": "sub-1", "ip_address": "10.0.0.1"}] - expected_crd_port = {'port': - {'port_id': port_id, 'tenant_id': tenant_id, - 'name': 'FakePort', 'network_id': network_id, - 'subnet_id': '', 'mac_address': 'aabb', - 'device_id': '1234', 'ip_address': '', - 'admin_state_up': True, 'status': 'ACTIVE', - 'device_owner': 'compute', - 'security_groups': ''}} - port_context = self._get_port_context(tenant_id, network_id, port_id, - fips) - port = port_context.current - req = self.driver._prepare_crd_port(port) - expected_crd_port['port']['subnet_id'] = 'sub-1' - expected_crd_port['port']['ip_address'] = '10.0.0.1' - self.assertEqual(expected_crd_port, req) - - def test_prepare_port_with_multiple_fixed_ips(self): - """Test _prepare_crd_port with multiple fixed_ips.""" - - tenant_id = 'test' - network_id = '123' - port_id = '453' - multiple_fips = [{"subnet_id": "sub-1", "ip_address": "10.0.0.1"}, - {"subnet_id": "sub-1", "ip_address": "10.0.0.4"}] - expected_crd_port = {'port': - {'port_id': port_id, 'tenant_id': tenant_id, - 'name': 'FakePort', 'network_id': network_id, - 'subnet_id': '', 'mac_address': 'aabb', - 'device_id': '1234', 'ip_address': '', - 'admin_state_up': True, 'status': 'ACTIVE', - 'device_owner': 'compute', - 'security_groups': ''}} - port_context = self._get_port_context(tenant_id, network_id, port_id, - multiple_fips) - port = port_context.current - req = self.driver._prepare_crd_port(port) - expected_crd_port['port']['subnet_id'] = 'sub-1' - expected_crd_port['port']['ip_address'] = '10.0.0.1' - self.assertEqual(expected_crd_port, req) - - def _get_subnet_context(self, tenant_id, net_id, subnet_id, cidr, - gateway_ip): - # sample data for testing purpose only. - subnet = {'tenant_id': tenant_id, - 'network_id': net_id, - 'id': subnet_id, - 'cidr': cidr, - 'name': 'FakeSubnet', - 'ip_version': 4, - 'gateway_ip': gateway_ip, - } - return FakeContext(subnet) - - def _get_port_context(self, tenant_id, net_id, port_id, - fixed_ips=[]): - # sample data for testing purpose only - port = {'device_id': '1234', - 'name': 'FakePort', - 'mac_address': 'aabb', - 'device_owner': 'compute', - 'tenant_id': tenant_id, - 'id': port_id, - 'fixed_ips': fixed_ips, - 'admin_state_up': True, - 'status': 'ACTIVE', - 'network_id': net_id} - return FakeContext(port) - - def _get_network_context(self, tenant_id, net_id, seg_id): - # sample data for testing purpose only. - network = {'id': net_id, - 'tenant_id': tenant_id, - 'admin_state_up': True, - 'status': 'ACTIVE', - 'name': 'FakeNetwork', } - segments = [{'segmentation_id': seg_id}] - return FakeNetworkContext(network, segments) - - -class FakeNetworkContext(object): - - """To generate network context for testing purposes only.""" - - def __init__(self, network, segments): - self._network = network - self._segments = segments - - @property - def current(self): - return self._network - - @property - def network_segments(self): - return self._segments - - -class FakeContext(object): - - """To generate context for testing purposes only.""" - - def __init__(self, record): - self._record = record - - @property - def current(self): - return self._record diff --git a/neutron/tests/unit/ml2/test_mechanism_ncs.py b/neutron/tests/unit/ml2/test_mechanism_ncs.py deleted file mode 100644 index 9ae267823..000000000 --- a/neutron/tests/unit/ml2/test_mechanism_ncs.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.plugins.ml2 import config as config -from neutron.plugins.ml2.drivers import mechanism_ncs -from neutron.tests.unit import test_db_plugin as test_plugin - -PLUGIN_NAME = 'neutron.plugins.ml2.plugin.Ml2Plugin' - - -class NCSTestCase(test_plugin.NeutronDbPluginV2TestCase): - - def setUp(self): - # Enable the test mechanism driver to ensure that - # we can successfully call through to all mechanism - # driver apis. - config.cfg.CONF.set_override('mechanism_drivers', - ['logger', 'ncs'], - 'ml2') - super(NCSTestCase, self).setUp(PLUGIN_NAME) - self.port_create_status = 'DOWN' - mechanism_ncs.NCSMechanismDriver.sendjson = self.check_sendjson - - def check_sendjson(self, method, urlpath, obj): - # Confirm fix for bug #1224981 - self.assertFalse(urlpath.startswith("http://")) - - -class NCSMechanismTestBasicGet(test_plugin.TestBasicGet, NCSTestCase): - pass - - -class NCSMechanismTestNetworksV2(test_plugin.TestNetworksV2, NCSTestCase): - pass - - -class NCSMechanismTestPortsV2(test_plugin.TestPortsV2, NCSTestCase): - pass diff --git a/neutron/tests/unit/ml2/test_mechanism_odl.py b/neutron/tests/unit/ml2/test_mechanism_odl.py deleted file mode 100644 index 472387c20..000000000 --- a/neutron/tests/unit/ml2/test_mechanism_odl.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright (c) 2013-2014 OpenStack Foundation -# All Rights Reserved. -# -# 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. -# @author: Kyle Mestery, Cisco Systems, Inc. - -from neutron.plugins.common import constants -from neutron.plugins.ml2 import config as config -from neutron.plugins.ml2 import driver_api as api -from neutron.plugins.ml2.drivers import mechanism_odl -from neutron.plugins.ml2 import plugin -from neutron.tests import base -from neutron.tests.unit import test_db_plugin as test_plugin - -PLUGIN_NAME = 'neutron.plugins.ml2.plugin.Ml2Plugin' - - -class OpenDaylightTestCase(test_plugin.NeutronDbPluginV2TestCase): - - def setUp(self): - # Enable the test mechanism driver to ensure that - # we can successfully call through to all mechanism - # driver apis. - config.cfg.CONF.set_override('mechanism_drivers', - ['logger', 'opendaylight'], - 'ml2') - # Set URL/user/pass so init doesn't throw a cfg required error. - # They are not used in these tests since sendjson is overwritten. - config.cfg.CONF.set_override('url', 'http://127.0.0.1:9999', 'ml2_odl') - config.cfg.CONF.set_override('username', 'someuser', 'ml2_odl') - config.cfg.CONF.set_override('password', 'somepass', 'ml2_odl') - - super(OpenDaylightTestCase, self).setUp(PLUGIN_NAME) - self.port_create_status = 'DOWN' - self.segment = {'api.NETWORK_TYPE': ""} - self.mech = mechanism_odl.OpenDaylightMechanismDriver() - mechanism_odl.OpenDaylightMechanismDriver.sendjson = ( - self.check_sendjson) - - def check_sendjson(self, method, urlpath, obj, ignorecodes=[]): - self.assertFalse(urlpath.startswith("http://")) - - def test_check_segment(self): - """Validate the check_segment call.""" - self.segment[api.NETWORK_TYPE] = constants.TYPE_LOCAL - self.assertTrue(self.mech.check_segment(self.segment)) - self.segment[api.NETWORK_TYPE] = constants.TYPE_FLAT - self.assertFalse(self.mech.check_segment(self.segment)) - self.segment[api.NETWORK_TYPE] = constants.TYPE_VLAN - self.assertTrue(self.mech.check_segment(self.segment)) - self.segment[api.NETWORK_TYPE] = constants.TYPE_GRE - self.assertTrue(self.mech.check_segment(self.segment)) - self.segment[api.NETWORK_TYPE] = constants.TYPE_VXLAN - self.assertTrue(self.mech.check_segment(self.segment)) - # Validate a network type not currently supported - self.segment[api.NETWORK_TYPE] = 'mpls' - self.assertFalse(self.mech.check_segment(self.segment)) - - -class OpenDayLightMechanismConfigTests(base.BaseTestCase): - - def _set_config(self, url='http://127.0.0.1:9999', username='someuser', - password='somepass'): - config.cfg.CONF.set_override('mechanism_drivers', - ['logger', 'opendaylight'], - 'ml2') - config.cfg.CONF.set_override('url', url, 'ml2_odl') - config.cfg.CONF.set_override('username', username, 'ml2_odl') - config.cfg.CONF.set_override('password', password, 'ml2_odl') - - def _test_missing_config(self, **kwargs): - self._set_config(**kwargs) - self.assertRaises(config.cfg.RequiredOptError, - plugin.Ml2Plugin) - - def test_valid_config(self): - self._set_config() - plugin.Ml2Plugin() - - def test_missing_url_raises_exception(self): - self._test_missing_config(url=None) - - def test_missing_username_raises_exception(self): - self._test_missing_config(username=None) - - def test_missing_password_raises_exception(self): - self._test_missing_config(password=None) - - -class OpenDaylightMechanismTestBasicGet(test_plugin.TestBasicGet, - OpenDaylightTestCase): - pass - - -class OpenDaylightMechanismTestNetworksV2(test_plugin.TestNetworksV2, - OpenDaylightTestCase): - pass - - -class OpenDaylightMechanismTestSubnetsV2(test_plugin.TestSubnetsV2, - OpenDaylightTestCase): - pass - - -class OpenDaylightMechanismTestPortsV2(test_plugin.TestPortsV2, - OpenDaylightTestCase): - pass diff --git a/neutron/tests/unit/ml2/test_ml2_plugin.py b/neutron/tests/unit/ml2/test_ml2_plugin.py deleted file mode 100644 index 20613a585..000000000 --- a/neutron/tests/unit/ml2/test_ml2_plugin.py +++ /dev/null @@ -1,477 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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 -import testtools -import webob - -from neutron.common import exceptions as exc -from neutron import context -from neutron.extensions import multiprovidernet as mpnet -from neutron.extensions import portbindings -from neutron.extensions import providernet as pnet -from neutron import manager -from neutron.plugins.ml2.common import exceptions as ml2_exc -from neutron.plugins.ml2 import config -from neutron.plugins.ml2 import driver_api -from neutron.plugins.ml2 import plugin as ml2_plugin -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit.ml2.drivers import mechanism_logger as mech_logger -from neutron.tests.unit.ml2.drivers import mechanism_test as mech_test -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_extension_allowedaddresspairs as test_pair -from neutron.tests.unit import test_extension_extradhcpopts as test_dhcpopts -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - - -config.cfg.CONF.import_opt('network_vlan_ranges', - 'neutron.plugins.ml2.drivers.type_vlan', - group='ml2_type_vlan') - - -PLUGIN_NAME = 'neutron.plugins.ml2.plugin.Ml2Plugin' - - -class Ml2PluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - - _plugin_name = PLUGIN_NAME - _mechanism_drivers = ['logger', 'test'] - - def setUp(self): - # We need a L3 service plugin - l3_plugin = ('neutron.tests.unit.test_l3_plugin.' - 'TestL3NatServicePlugin') - service_plugins = {'l3_plugin_name': l3_plugin} - # Enable the test mechanism driver to ensure that - # we can successfully call through to all mechanism - # driver apis. - config.cfg.CONF.set_override('mechanism_drivers', - self._mechanism_drivers, - group='ml2') - self.physnet = 'physnet1' - self.vlan_range = '1:100' - self.phys_vrange = ':'.join([self.physnet, self.vlan_range]) - config.cfg.CONF.set_override('network_vlan_ranges', [self.phys_vrange], - group='ml2_type_vlan') - super(Ml2PluginV2TestCase, self).setUp(PLUGIN_NAME, - service_plugins=service_plugins) - self.port_create_status = 'DOWN' - self.driver = ml2_plugin.Ml2Plugin() - self.context = context.get_admin_context() - - -class TestMl2BulkToggleWithBulkless(Ml2PluginV2TestCase): - - _mechanism_drivers = ['logger', 'test', 'bulkless'] - - def test_bulk_disable_with_bulkless_driver(self): - self.assertTrue(self._skip_native_bulk) - - -class TestMl2BulkToggleWithoutBulkless(Ml2PluginV2TestCase): - - _mechanism_drivers = ['logger', 'test'] - - def test_bulk_enabled_with_bulk_drivers(self): - self.assertFalse(self._skip_native_bulk) - - -class TestMl2BasicGet(test_plugin.TestBasicGet, - Ml2PluginV2TestCase): - pass - - -class TestMl2V2HTTPResponse(test_plugin.TestV2HTTPResponse, - Ml2PluginV2TestCase): - pass - - -class TestMl2NetworksV2(test_plugin.TestNetworksV2, - Ml2PluginV2TestCase): - pass - - -class TestMl2SubnetsV2(test_plugin.TestSubnetsV2, - Ml2PluginV2TestCase): - pass - - -class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase): - - def test_update_port_status_build(self): - with self.port() as port: - self.assertEqual(port['port']['status'], 'DOWN') - self.assertEqual(self.port_create_status, 'DOWN') - - def test_update_non_existent_port(self): - ctx = context.get_admin_context() - plugin = manager.NeutronManager.get_plugin() - data = {'port': {'admin_state_up': False}} - self.assertRaises(exc.PortNotFound, plugin.update_port, ctx, - 'invalid-uuid', data) - - def test_delete_non_existent_port(self): - ctx = context.get_admin_context() - plugin = manager.NeutronManager.get_plugin() - with mock.patch.object(ml2_plugin.LOG, 'debug') as log_debug: - plugin.delete_port(ctx, 'invalid-uuid', l3_port_check=False) - log_debug.assert_has_calls([ - mock.call(_("Deleting port %s"), 'invalid-uuid'), - mock.call(_("The port '%s' was deleted"), 'invalid-uuid') - ]) - - -class TestMl2PortBinding(Ml2PluginV2TestCase, - test_bindings.PortBindingsTestCase): - # Test case does not set binding:host_id, so ml2 does not attempt - # to bind port - VIF_TYPE = portbindings.VIF_TYPE_UNBOUND - HAS_PORT_FILTER = False - ENABLE_SG = True - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_HYBRID_DRIVER - - def setUp(self, firewall_driver=None): - test_sg_rpc.set_firewall_driver(self.FIREWALL_DRIVER) - config.cfg.CONF.set_override( - 'enable_security_group', self.ENABLE_SG, - group='SECURITYGROUP') - super(TestMl2PortBinding, self).setUp() - - def _check_port_binding_profile(self, port, profile=None): - self.assertIn('id', port) - self.assertIn(portbindings.PROFILE, port) - value = port[portbindings.PROFILE] - self.assertEqual(profile or {}, value) - - def test_create_port_binding_profile(self): - self._test_create_port_binding_profile({'a': 1, 'b': 2}) - - def test_update_port_binding_profile(self): - self._test_update_port_binding_profile({'c': 3}) - - def test_create_port_binding_profile_too_big(self): - s = 'x' * 5000 - profile_arg = {portbindings.PROFILE: {'d': s}} - try: - with self.port(expected_res_status=400, - arg_list=(portbindings.PROFILE,), - **profile_arg): - pass - except webob.exc.HTTPClientError: - pass - - def test_remove_port_binding_profile(self): - profile = {'e': 5} - profile_arg = {portbindings.PROFILE: profile} - with self.port(arg_list=(portbindings.PROFILE,), - **profile_arg) as port: - self._check_port_binding_profile(port['port'], profile) - port_id = port['port']['id'] - profile_arg = {portbindings.PROFILE: None} - port = self._update('ports', port_id, - {'port': profile_arg})['port'] - self._check_port_binding_profile(port) - port = self._show('ports', port_id)['port'] - self._check_port_binding_profile(port) - - -class TestMl2PortBindingNoSG(TestMl2PortBinding): - HAS_PORT_FILTER = False - ENABLE_SG = False - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER - - -class TestMl2PortBindingHost(Ml2PluginV2TestCase, - test_bindings.PortBindingsHostTestCaseMixin): - pass - - -class TestMl2PortBindingVnicType(Ml2PluginV2TestCase, - test_bindings.PortBindingsVnicTestCaseMixin): - pass - - -class TestMultiSegmentNetworks(Ml2PluginV2TestCase): - - def setUp(self, plugin=None): - super(TestMultiSegmentNetworks, self).setUp() - - def test_create_network_provider(self): - data = {'network': {'name': 'net1', - pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1, - 'tenant_id': 'tenant_one'}} - network_req = self.new_create_request('networks', data) - network = self.deserialize(self.fmt, - network_req.get_response(self.api)) - self.assertEqual(network['network'][pnet.NETWORK_TYPE], 'vlan') - self.assertEqual(network['network'][pnet.PHYSICAL_NETWORK], 'physnet1') - self.assertEqual(network['network'][pnet.SEGMENTATION_ID], 1) - self.assertNotIn(mpnet.SEGMENTS, network['network']) - - def test_create_network_single_multiprovider(self): - data = {'network': {'name': 'net1', - mpnet.SEGMENTS: - [{pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}], - 'tenant_id': 'tenant_one'}} - net_req = self.new_create_request('networks', data) - network = self.deserialize(self.fmt, net_req.get_response(self.api)) - self.assertEqual(network['network'][pnet.NETWORK_TYPE], 'vlan') - self.assertEqual(network['network'][pnet.PHYSICAL_NETWORK], 'physnet1') - self.assertEqual(network['network'][pnet.SEGMENTATION_ID], 1) - self.assertNotIn(mpnet.SEGMENTS, network['network']) - - # Tests get_network() - net_req = self.new_show_request('networks', network['network']['id']) - network = self.deserialize(self.fmt, net_req.get_response(self.api)) - self.assertEqual(network['network'][pnet.NETWORK_TYPE], 'vlan') - self.assertEqual(network['network'][pnet.PHYSICAL_NETWORK], 'physnet1') - self.assertEqual(network['network'][pnet.SEGMENTATION_ID], 1) - self.assertNotIn(mpnet.SEGMENTS, network['network']) - - def test_create_network_multiprovider(self): - data = {'network': {'name': 'net1', - mpnet.SEGMENTS: - [{pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}, - {pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 2}], - 'tenant_id': 'tenant_one'}} - network_req = self.new_create_request('networks', data) - network = self.deserialize(self.fmt, - network_req.get_response(self.api)) - tz = network['network'][mpnet.SEGMENTS] - for tz in data['network'][mpnet.SEGMENTS]: - for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID]: - self.assertEqual(tz.get(field), tz.get(field)) - - # Tests get_network() - net_req = self.new_show_request('networks', network['network']['id']) - network = self.deserialize(self.fmt, net_req.get_response(self.api)) - tz = network['network'][mpnet.SEGMENTS] - for tz in data['network'][mpnet.SEGMENTS]: - for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID]: - self.assertEqual(tz.get(field), tz.get(field)) - - def test_create_network_with_provider_and_multiprovider_fail(self): - data = {'network': {'name': 'net1', - mpnet.SEGMENTS: - [{pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}], - pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1, - 'tenant_id': 'tenant_one'}} - - network_req = self.new_create_request('networks', data) - res = network_req.get_response(self.api) - self.assertEqual(res.status_int, 400) - - def test_create_network_duplicate_segments(self): - data = {'network': {'name': 'net1', - mpnet.SEGMENTS: - [{pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}, - {pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}], - 'tenant_id': 'tenant_one'}} - network_req = self.new_create_request('networks', data) - res = network_req.get_response(self.api) - self.assertEqual(res.status_int, 400) - - def test_release_segment_no_type_driver(self): - segment = {driver_api.NETWORK_TYPE: 'faketype', - driver_api.PHYSICAL_NETWORK: 'physnet1', - driver_api.ID: 1} - with mock.patch('neutron.plugins.ml2.managers.LOG') as log: - self.driver.type_manager.release_segment(session=None, - segment=segment) - log.error.assert_called_once_with( - "Failed to release segment '%s' because " - "network type is not supported.", segment) - - def test_create_provider_fail(self): - segment = {pnet.NETWORK_TYPE: None, - pnet.PHYSICAL_NETWORK: 'phys_net', - pnet.SEGMENTATION_ID: None} - with testtools.ExpectedException(exc.InvalidInput): - self.driver._process_provider_create(segment) - - def test_create_network_plugin(self): - data = {'network': {'name': 'net1', - 'admin_state_up': True, - 'shared': False, - pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1, - 'tenant_id': 'tenant_one'}} - - def raise_mechanism_exc(*args, **kwargs): - raise ml2_exc.MechanismDriverError( - method='create_network_postcommit') - - with mock.patch('neutron.plugins.ml2.managers.MechanismManager.' - 'create_network_precommit', new=raise_mechanism_exc): - with testtools.ExpectedException(ml2_exc.MechanismDriverError): - self.driver.create_network(self.context, data) - - def test_extend_dictionary_no_segments(self): - network = dict(name='net_no_segment', id='5', tenant_id='tenant_one') - self.driver._extend_network_dict_provider(self.context, network) - self.assertIsNone(network[pnet.NETWORK_TYPE]) - self.assertIsNone(network[pnet.PHYSICAL_NETWORK]) - self.assertIsNone(network[pnet.SEGMENTATION_ID]) - - -class TestMl2AllowedAddressPairs(Ml2PluginV2TestCase, - test_pair.TestAllowedAddressPairs): - def setUp(self, plugin=None): - super(test_pair.TestAllowedAddressPairs, self).setUp( - plugin=PLUGIN_NAME) - - -class DHCPOptsTestCase(test_dhcpopts.TestExtraDhcpOpt): - - def setUp(self, plugin=None): - super(test_dhcpopts.ExtraDhcpOptDBTestCase, self).setUp( - plugin=PLUGIN_NAME) - - -class Ml2PluginV2FaultyDriverTestCase(test_plugin.NeutronDbPluginV2TestCase): - - def setUp(self): - # Enable the test mechanism driver to ensure that - # we can successfully call through to all mechanism - # driver apis. - config.cfg.CONF.set_override('mechanism_drivers', - ['test', 'logger'], - group='ml2') - super(Ml2PluginV2FaultyDriverTestCase, self).setUp(PLUGIN_NAME) - self.port_create_status = 'DOWN' - - -class TestFaultyMechansimDriver(Ml2PluginV2FaultyDriverTestCase): - - def test_update_network_faulty(self): - - def mock_update_network_postcommit(self, context): - raise ml2_exc.MechanismDriverError( - method='update_network_postcommit') - - with mock.patch.object(mech_test.TestMechanismDriver, - 'update_network_postcommit', - new=mock_update_network_postcommit): - with mock.patch.object(mech_logger.LoggerMechanismDriver, - 'update_network_postcommit') as unp: - - data = {'network': {'name': 'net1', - 'tenant_id': 'tenant_one'}} - network_req = self.new_create_request('networks', data) - network = self.deserialize( - self.fmt, - network_req.get_response(self.api)) - - data = {'network': {'name': 'a_brand_new_name'}} - req = self.new_update_request('networks', - data, - network['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 500) - # Test if other mechanism driver was called - self.assertTrue(unp.called) - - self._delete('networks', network['network']['id']) - - def test_update_subnet_faulty(self): - - def mock_update_subnet_postcommit(self, context): - raise ml2_exc.MechanismDriverError( - method='update_subnet_postcommit') - - with mock.patch.object(mech_test.TestMechanismDriver, - 'update_subnet_postcommit', - new=mock_update_subnet_postcommit): - with mock.patch.object(mech_logger.LoggerMechanismDriver, - 'update_subnet_postcommit') as usp: - - with self.network() as network: - data = {'subnet': {'network_id': - network['network']['id'], - 'cidr': '10.0.20.0/24', - 'ip_version': '4', - 'name': 'subnet1', - 'tenant_id': - network['network']['tenant_id'], - 'gateway_ip': '10.0.2.1'}} - subnet_req = self.new_create_request('subnets', data) - subnet = self.deserialize( - self.fmt, - subnet_req.get_response(self.api)) - - data = {'subnet': {'name': 'a_brand_new_name'}} - req = self.new_update_request('subnets', - data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 500) - # Test if other mechanism driver was called - self.assertTrue(usp.called) - - self._delete('subnets', subnet['subnet']['id']) - - def test_update_port_faulty(self): - - def mock_update_port_postcommit(self, context): - raise ml2_exc.MechanismDriverError( - method='update_port_postcommit') - - with mock.patch.object(mech_test.TestMechanismDriver, - 'update_port_postcommit', - new=mock_update_port_postcommit): - with mock.patch.object(mech_logger.LoggerMechanismDriver, - 'update_port_postcommit') as upp: - - with self.network() as network: - data = {'port': {'network_id': network['network']['id'], - 'tenant_id': - network['network']['tenant_id'], - 'name': 'port1', - 'admin_state_up': 1, - 'fixed_ips': []}} - port_req = self.new_create_request('ports', data) - port = self.deserialize( - self.fmt, - port_req.get_response(self.api)) - - data = {'port': {'name': 'a_brand_new_name'}} - req = self.new_update_request('ports', - data, - port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 500) - # Test if other mechanism driver was called - self.assertTrue(upp.called) - - self._delete('ports', port['port']['id']) diff --git a/neutron/tests/unit/ml2/test_port_binding.py b/neutron/tests/unit/ml2/test_port_binding.py deleted file mode 100644 index b4aa19a9c..000000000 --- a/neutron/tests/unit/ml2/test_port_binding.py +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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 neutron import context -from neutron.extensions import portbindings -from neutron import manager -from neutron.plugins.ml2 import config as config -from neutron.tests.unit import test_db_plugin as test_plugin - - -PLUGIN_NAME = 'neutron.plugins.ml2.plugin.Ml2Plugin' - - -class PortBindingTestCase(test_plugin.NeutronDbPluginV2TestCase): - - _plugin_name = PLUGIN_NAME - - def setUp(self): - # Enable the test mechanism driver to ensure that - # we can successfully call through to all mechanism - # driver apis. - config.cfg.CONF.set_override('mechanism_drivers', - ['logger', 'test'], - 'ml2') - super(PortBindingTestCase, self).setUp(PLUGIN_NAME) - self.port_create_status = 'DOWN' - self.plugin = manager.NeutronManager.get_plugin() - self.plugin.start_rpc_listeners() - - def _check_response(self, port, vif_type, has_port_filter, bound, status): - self.assertEqual(port[portbindings.VIF_TYPE], vif_type) - vif_details = port[portbindings.VIF_DETAILS] - port_status = port['status'] - if bound: - # TODO(rkukura): Replace with new VIF security details - self.assertEqual(vif_details[portbindings.CAP_PORT_FILTER], - has_port_filter) - self.assertEqual(port_status, status or 'DOWN') - else: - self.assertEqual(port_status, 'DOWN') - - def _test_port_binding(self, host, vif_type, has_port_filter, bound, - status=None): - host_arg = {portbindings.HOST_ID: host} - with self.port(name='name', arg_list=(portbindings.HOST_ID,), - **host_arg) as port: - self._check_response(port['port'], vif_type, has_port_filter, - bound, status) - port_id = port['port']['id'] - neutron_context = context.get_admin_context() - details = self.plugin.endpoints[0].get_device_details( - neutron_context, agent_id="theAgentId", device=port_id) - if bound: - self.assertEqual(details['network_type'], 'local') - else: - self.assertNotIn('network_type', details) - - def test_unbound(self): - self._test_port_binding("", - portbindings.VIF_TYPE_UNBOUND, - False, False) - - def test_binding_failed(self): - self._test_port_binding("host-fail", - portbindings.VIF_TYPE_BINDING_FAILED, - False, False) - - def test_binding_no_filter(self): - self._test_port_binding("host-ovs-no_filter", - portbindings.VIF_TYPE_OVS, - False, True) - - def test_binding_filter(self): - self._test_port_binding("host-bridge-filter", - portbindings.VIF_TYPE_BRIDGE, - True, True) - - def test_binding_status_active(self): - self._test_port_binding("host-ovs-filter-active", - portbindings.VIF_TYPE_OVS, - True, True, 'ACTIVE') - - def _test_update_port_binding(self, host, new_host=None): - with mock.patch.object(self.plugin, - '_notify_port_updated') as notify_mock: - host_arg = {portbindings.HOST_ID: host} - update_body = {'name': 'test_update'} - if new_host is not None: - update_body[portbindings.HOST_ID] = new_host - with self.port(name='name', arg_list=(portbindings.HOST_ID,), - **host_arg) as port: - neutron_context = context.get_admin_context() - updated_port = self._update('ports', port['port']['id'], - {'port': update_body}, - neutron_context=neutron_context) - port_data = updated_port['port'] - if new_host is not None: - self.assertEqual(port_data[portbindings.HOST_ID], - new_host) - else: - self.assertEqual(port_data[portbindings.HOST_ID], host) - if new_host is not None and new_host != host: - notify_mock.assert_called_once_with(mock.ANY) - else: - self.assertFalse(notify_mock.called) - - def test_update_with_new_host_binding_notifies_agent(self): - self._test_update_port_binding('host-ovs-no_filter', - 'host-bridge-filter') - - def test_update_with_same_host_binding_does_not_notify(self): - self._test_update_port_binding('host-ovs-no_filter', - 'host-ovs-no_filter') - - def test_update_without_binding_does_not_notify(self): - self._test_update_port_binding('host-ovs-no_filter') - - def testt_update_from_empty_to_host_binding_notifies_agent(self): - self._test_update_port_binding('', 'host-ovs-no_filter') - - def test_update_from_host_to_empty_binding_notifies_agent(self): - self._test_update_port_binding('host-ovs-no_filter', '') diff --git a/neutron/tests/unit/ml2/test_rpcapi.py b/neutron/tests/unit/ml2/test_rpcapi.py deleted file mode 100644 index af48a74f1..000000000 --- a/neutron/tests/unit/ml2/test_rpcapi.py +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -""" -Unit Tests for ml2 rpc -""" - -import mock - -from neutron.agent import rpc as agent_rpc -from neutron.common import rpc_compat -from neutron.common import topics -from neutron.openstack.common import context -from neutron.plugins.ml2.drivers import type_tunnel -from neutron.plugins.ml2 import rpc as plugin_rpc -from neutron.tests import base - - -class RpcApiTestCase(base.BaseTestCase): - - def _test_rpc_api(self, rpcapi, topic, method, rpc_method, **kwargs): - ctxt = context.RequestContext('fake_user', 'fake_project') - expected_retval = 'foo' if method == 'call' else None - expected_msg = rpcapi.make_msg(method, **kwargs) - if rpc_method == 'cast' and method == 'run_instance': - kwargs['call'] = False - - rpc = rpc_compat.RpcProxy - with mock.patch.object(rpc, rpc_method) as rpc_method_mock: - rpc_method_mock.return_value = expected_retval - retval = getattr(rpcapi, method)(ctxt, **kwargs) - - self.assertEqual(retval, expected_retval) - expected = [ - mock.call(ctxt, expected_msg, topic=topic) - ] - rpc_method_mock.assert_has_calls(expected) - - def test_delete_network(self): - rpcapi = plugin_rpc.AgentNotifierApi(topics.AGENT) - self._test_rpc_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.NETWORK, - topics.DELETE), - 'network_delete', rpc_method='fanout_cast', - network_id='fake_request_spec') - - def test_port_update(self): - rpcapi = plugin_rpc.AgentNotifierApi(topics.AGENT) - self._test_rpc_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - port='fake_port', - network_type='fake_network_type', - segmentation_id='fake_segmentation_id', - physical_network='fake_physical_network') - - def test_tunnel_update(self): - rpcapi = plugin_rpc.AgentNotifierApi(topics.AGENT) - self._test_rpc_api(rpcapi, - topics.get_topic_name(topics.AGENT, - type_tunnel.TUNNEL, - topics.UPDATE), - 'tunnel_update', rpc_method='fanout_cast', - tunnel_ip='fake_ip', tunnel_type='gre') - - def test_device_details(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_rpc_api(rpcapi, topics.PLUGIN, - 'get_device_details', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id') - - def test_update_device_down(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_rpc_api(rpcapi, topics.PLUGIN, - 'update_device_down', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') - - def test_tunnel_sync(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_rpc_api(rpcapi, topics.PLUGIN, - 'tunnel_sync', rpc_method='call', - tunnel_ip='fake_tunnel_ip', - tunnel_type=None) - - def test_update_device_up(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_rpc_api(rpcapi, topics.PLUGIN, - 'update_device_up', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') diff --git a/neutron/tests/unit/ml2/test_security_group.py b/neutron/tests/unit/ml2/test_security_group.py deleted file mode 100644 index 3e82c91e4..000000000 --- a/neutron/tests/unit/ml2/test_security_group.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# Copyright 2013, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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 neutron.api.v2 import attributes -from neutron.extensions import securitygroup as ext_sg -from neutron import manager -from neutron.tests.unit import test_extension_security_group as test_sg -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - -PLUGIN_NAME = 'neutron.plugins.ml2.plugin.Ml2Plugin' -NOTIFIER = 'neutron.plugins.ml2.rpc.AgentNotifierApi' - - -class Ml2SecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self, plugin=None): - test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER) - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - self._attribute_map_bk_ = {} - for item in attributes.RESOURCE_ATTRIBUTE_MAP: - self._attribute_map_bk_[item] = (attributes. - RESOURCE_ATTRIBUTE_MAP[item]. - copy()) - super(Ml2SecurityGroupsTestCase, self).setUp(PLUGIN_NAME) - - def tearDown(self): - super(Ml2SecurityGroupsTestCase, self).tearDown() - attributes.RESOURCE_ATTRIBUTE_MAP = self._attribute_map_bk_ - - -class TestMl2SecurityGroups(Ml2SecurityGroupsTestCase, - test_sg.TestSecurityGroups, - test_sg_rpc.SGNotificationTestMixin): - def setUp(self): - super(TestMl2SecurityGroups, self).setUp() - plugin = manager.NeutronManager.get_plugin() - plugin.start_rpc_listeners() - - def test_security_group_get_port_from_device(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - security_group_id = sg['security_group']['id'] - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - fixed_ips = port['port']['fixed_ips'] - data = {'port': {'fixed_ips': fixed_ips, - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: - [security_group_id]}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - port_id = res['port']['id'] - plugin = manager.NeutronManager.get_plugin() - callbacks = plugin.endpoints[0] - port_dict = callbacks.get_port_from_device(port_id) - self.assertEqual(port_id, port_dict['id']) - self.assertEqual([security_group_id], - port_dict[ext_sg.SECURITYGROUPS]) - self.assertEqual([], port_dict['security_group_rules']) - self.assertEqual([fixed_ips[0]['ip_address']], - port_dict['fixed_ips']) - self._delete('ports', port_id) - - def test_security_group_get_port_from_device_with_no_port(self): - plugin = manager.NeutronManager.get_plugin() - port_dict = plugin.endpoints[0].get_port_from_device('bad_device_id') - self.assertIsNone(port_dict) - - -class TestMl2SecurityGroupsXML(TestMl2SecurityGroups): - fmt = 'xml' - - -class TestMl2SGServerRpcCallBack( - Ml2SecurityGroupsTestCase, - test_sg_rpc.SGServerRpcCallBackMixinTestCase): - pass - - -class TestMl2SGServerRpcCallBackXML( - Ml2SecurityGroupsTestCase, - test_sg_rpc.SGServerRpcCallBackMixinTestCaseXML): - pass diff --git a/neutron/tests/unit/ml2/test_type_flat.py b/neutron/tests/unit/ml2/test_type_flat.py deleted file mode 100644 index 711418ccd..000000000 --- a/neutron/tests/unit/ml2/test_type_flat.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2014 Thales Services SAS -# All Rights Reserved. -# -# 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. - -from neutron.common import exceptions as exc -import neutron.db.api as db -from neutron.plugins.common import constants as p_const -from neutron.plugins.ml2 import driver_api as api -from neutron.plugins.ml2.drivers import type_flat -from neutron.tests import base - - -FLAT_NETWORKS = 'flat_net1, flat_net2' - - -class FlatTypeTest(base.BaseTestCase): - - def setUp(self): - super(FlatTypeTest, self).setUp() - db.configure_db() - self.driver = type_flat.FlatTypeDriver() - self.driver._parse_networks(FLAT_NETWORKS) - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def _get_allocation(self, session, segment): - return session.query(type_flat.FlatAllocation).filter_by( - physical_network=segment[api.PHYSICAL_NETWORK]).first() - - def test_validate_provider_segment(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_FLAT, - api.PHYSICAL_NETWORK: 'flat_net1'} - self.driver.validate_provider_segment(segment) - - def test_validate_provider_segment_without_physnet_restriction(self): - self.driver._parse_networks('*') - segment = {api.NETWORK_TYPE: p_const.TYPE_FLAT, - api.PHYSICAL_NETWORK: 'other_flat_net'} - self.driver.validate_provider_segment(segment) - - def test_validate_provider_segment_with_missing_physical_network(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_FLAT} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_validate_provider_segment_with_unsupported_physical_network(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_FLAT, - api.PHYSICAL_NETWORK: 'other_flat_net'} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_validate_provider_segment_with_unallowed_segmentation_id(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_FLAT, - api.PHYSICAL_NETWORK: 'flat_net1', - api.SEGMENTATION_ID: 1234} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_reserve_provider_segment(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_FLAT, - api.PHYSICAL_NETWORK: 'flat_net1'} - self.driver.reserve_provider_segment(self.session, segment) - alloc = self._get_allocation(self.session, segment) - self.assertEqual(segment[api.PHYSICAL_NETWORK], alloc.physical_network) - - def test_release_segment(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_FLAT, - api.PHYSICAL_NETWORK: 'flat_net1'} - self.driver.reserve_provider_segment(self.session, segment) - self.driver.release_segment(self.session, segment) - alloc = self._get_allocation(self.session, segment) - self.assertIsNone(alloc) - - def test_reserve_provider_segment_already_reserved(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_FLAT, - api.PHYSICAL_NETWORK: 'flat_net1'} - self.driver.reserve_provider_segment(self.session, segment) - self.assertRaises(exc.FlatNetworkInUse, - self.driver.reserve_provider_segment, - self.session, segment) - - def test_allocate_tenant_segment(self): - observed = self.driver.allocate_tenant_segment(self.session) - self.assertIsNone(observed) diff --git a/neutron/tests/unit/ml2/test_type_gre.py b/neutron/tests/unit/ml2/test_type_gre.py deleted file mode 100644 index 36420e2b6..000000000 --- a/neutron/tests/unit/ml2/test_type_gre.py +++ /dev/null @@ -1,208 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from six import moves -import testtools -from testtools import matchers - -from neutron.common import exceptions as exc -import neutron.db.api as db -from neutron.plugins.ml2 import driver_api as api -from neutron.plugins.ml2.drivers import type_gre -from neutron.tests import base - -TUNNEL_IP_ONE = "10.10.10.10" -TUNNEL_IP_TWO = "10.10.10.20" -TUN_MIN = 100 -TUN_MAX = 109 -TUNNEL_RANGES = [(TUN_MIN, TUN_MAX)] -UPDATED_TUNNEL_RANGES = [(TUN_MIN + 5, TUN_MAX + 5)] - - -class GreTypeTest(base.BaseTestCase): - - def setUp(self): - super(GreTypeTest, self).setUp() - db.configure_db() - self.driver = type_gre.GreTypeDriver() - self.driver.gre_id_ranges = TUNNEL_RANGES - self.driver._sync_gre_allocations() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_validate_provider_segment(self): - segment = {api.NETWORK_TYPE: 'gre', - api.PHYSICAL_NETWORK: 'phys_net', - api.SEGMENTATION_ID: None} - - with testtools.ExpectedException(exc.InvalidInput): - self.driver.validate_provider_segment(segment) - - segment[api.PHYSICAL_NETWORK] = None - with testtools.ExpectedException(exc.InvalidInput): - self.driver.validate_provider_segment(segment) - - def test_sync_tunnel_allocations(self): - self.assertIsNone( - self.driver.get_gre_allocation(self.session, - (TUN_MIN - 1)) - ) - self.assertFalse( - self.driver.get_gre_allocation(self.session, - (TUN_MIN)).allocated - ) - self.assertFalse( - self.driver.get_gre_allocation(self.session, - (TUN_MIN + 1)).allocated - ) - self.assertFalse( - self.driver.get_gre_allocation(self.session, - (TUN_MAX - 1)).allocated - ) - self.assertFalse( - self.driver.get_gre_allocation(self.session, - (TUN_MAX)).allocated - ) - self.assertIsNone( - self.driver.get_gre_allocation(self.session, - (TUN_MAX + 1)) - ) - - self.driver.gre_id_ranges = UPDATED_TUNNEL_RANGES - self.driver._sync_gre_allocations() - - self.assertIsNone( - self.driver.get_gre_allocation(self.session, - (TUN_MIN + 5 - 1)) - ) - self.assertFalse( - self.driver.get_gre_allocation(self.session, - (TUN_MIN + 5)).allocated - ) - self.assertFalse( - self.driver.get_gre_allocation(self.session, - (TUN_MIN + 5 + 1)).allocated - ) - self.assertFalse( - self.driver.get_gre_allocation(self.session, - (TUN_MAX + 5 - 1)).allocated - ) - self.assertFalse( - self.driver.get_gre_allocation(self.session, - (TUN_MAX + 5)).allocated - ) - self.assertIsNone( - self.driver.get_gre_allocation(self.session, - (TUN_MAX + 5 + 1)) - ) - - def test_reserve_provider_segment(self): - segment = {api.NETWORK_TYPE: 'gre', - api.PHYSICAL_NETWORK: 'None', - api.SEGMENTATION_ID: 101} - self.driver.reserve_provider_segment(self.session, segment) - alloc = self.driver.get_gre_allocation(self.session, - segment[api.SEGMENTATION_ID]) - self.assertTrue(alloc.allocated) - - with testtools.ExpectedException(exc.TunnelIdInUse): - self.driver.reserve_provider_segment(self.session, segment) - - self.driver.release_segment(self.session, segment) - alloc = self.driver.get_gre_allocation(self.session, - segment[api.SEGMENTATION_ID]) - self.assertFalse(alloc.allocated) - - segment[api.SEGMENTATION_ID] = 1000 - self.driver.reserve_provider_segment(self.session, segment) - alloc = self.driver.get_gre_allocation(self.session, - segment[api.SEGMENTATION_ID]) - self.assertTrue(alloc.allocated) - - self.driver.release_segment(self.session, segment) - alloc = self.driver.get_gre_allocation(self.session, - segment[api.SEGMENTATION_ID]) - self.assertIsNone(alloc) - - def test_allocate_tenant_segment(self): - tunnel_ids = set() - for x in moves.xrange(TUN_MIN, TUN_MAX + 1): - segment = self.driver.allocate_tenant_segment(self.session) - self.assertThat(segment[api.SEGMENTATION_ID], - matchers.GreaterThan(TUN_MIN - 1)) - self.assertThat(segment[api.SEGMENTATION_ID], - matchers.LessThan(TUN_MAX + 1)) - tunnel_ids.add(segment[api.SEGMENTATION_ID]) - - segment = self.driver.allocate_tenant_segment(self.session) - self.assertIsNone(segment) - - segment = {api.NETWORK_TYPE: 'gre', - api.PHYSICAL_NETWORK: 'None', - api.SEGMENTATION_ID: tunnel_ids.pop()} - self.driver.release_segment(self.session, segment) - segment = self.driver.allocate_tenant_segment(self.session) - self.assertThat(segment[api.SEGMENTATION_ID], - matchers.GreaterThan(TUN_MIN - 1)) - self.assertThat(segment[api.SEGMENTATION_ID], - matchers.LessThan(TUN_MAX + 1)) - tunnel_ids.add(segment[api.SEGMENTATION_ID]) - - for tunnel_id in tunnel_ids: - segment[api.SEGMENTATION_ID] = tunnel_id - self.driver.release_segment(self.session, segment) - - def test_gre_endpoints(self): - tun_1 = self.driver.add_endpoint(TUNNEL_IP_ONE) - tun_2 = self.driver.add_endpoint(TUNNEL_IP_TWO) - self.assertEqual(TUNNEL_IP_ONE, tun_1.ip_address) - self.assertEqual(TUNNEL_IP_TWO, tun_2.ip_address) - - # Get all the endpoints - endpoints = self.driver.get_endpoints() - for endpoint in endpoints: - self.assertIn(endpoint['ip_address'], - [TUNNEL_IP_ONE, TUNNEL_IP_TWO]) - - -class GreTypeMultiRangeTest(base.BaseTestCase): - - TUN_MIN0 = 100 - TUN_MAX0 = 101 - TUN_MIN1 = 200 - TUN_MAX1 = 201 - TUNNEL_MULTI_RANGES = [(TUN_MIN0, TUN_MAX0), (TUN_MIN1, TUN_MAX1)] - - def setUp(self): - super(GreTypeMultiRangeTest, self).setUp() - db.configure_db() - self.driver = type_gre.GreTypeDriver() - self.driver.gre_id_ranges = self.TUNNEL_MULTI_RANGES - self.driver._sync_gre_allocations() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_release_segment(self): - segments = [self.driver.allocate_tenant_segment(self.session) - for i in range(4)] - - # Release them in random order. No special meaning. - for i in (0, 2, 1, 3): - self.driver.release_segment(self.session, segments[i]) - - for key in (self.TUN_MIN0, self.TUN_MAX0, - self.TUN_MIN1, self.TUN_MAX1): - alloc = self.driver.get_gre_allocation(self.session, key) - self.assertFalse(alloc.allocated) diff --git a/neutron/tests/unit/ml2/test_type_local.py b/neutron/tests/unit/ml2/test_type_local.py deleted file mode 100644 index 8d835bfd4..000000000 --- a/neutron/tests/unit/ml2/test_type_local.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright (c) 2014 Thales Services SAS -# All Rights Reserved. -# -# 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. - -from neutron.common import exceptions as exc -from neutron.plugins.common import constants as p_const -from neutron.plugins.ml2 import driver_api as api -from neutron.plugins.ml2.drivers import type_local -from neutron.tests import base - - -class LocalTypeTest(base.BaseTestCase): - - def setUp(self): - super(LocalTypeTest, self).setUp() - self.driver = type_local.LocalTypeDriver() - self.session = None - - def test_validate_provider_segment(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_LOCAL} - self.driver.validate_provider_segment(segment) - - def test_validate_provider_segment_with_unallowed_physical_network(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_LOCAL, - api.PHYSICAL_NETWORK: 'phys_net'} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_validate_provider_segment_with_unallowed_segmentation_id(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_LOCAL, - api.SEGMENTATION_ID: 2} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_reserve_provider_segment(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_LOCAL} - self.driver.reserve_provider_segment(self.session, segment) - self.driver.release_segment(self.session, segment) - - def test_allocate_tenant_segment(self): - expected = {api.NETWORK_TYPE: p_const.TYPE_LOCAL} - observed = self.driver.allocate_tenant_segment(self.session) - self.assertEqual(expected, observed) diff --git a/neutron/tests/unit/ml2/test_type_vlan.py b/neutron/tests/unit/ml2/test_type_vlan.py deleted file mode 100644 index deb86c0af..000000000 --- a/neutron/tests/unit/ml2/test_type_vlan.py +++ /dev/null @@ -1,187 +0,0 @@ -# Copyright (c) 2014 Thales Services SAS -# All Rights Reserved. -# -# 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 testtools import matchers - -from neutron.common import exceptions as exc -import neutron.db.api as db -from neutron.plugins.common import constants as p_const -from neutron.plugins.ml2 import driver_api as api -from neutron.plugins.ml2.drivers import type_vlan -from neutron.tests import base - -PROVIDER_NET = 'phys_net1' -TENANT_NET = 'phys_net2' -VLAN_MIN = 200 -VLAN_MAX = 209 -NETWORK_VLAN_RANGES = { - PROVIDER_NET: [], - TENANT_NET: [(VLAN_MIN, VLAN_MAX)], -} -UPDATED_VLAN_RANGES = { - PROVIDER_NET: [], - TENANT_NET: [(VLAN_MIN + 5, VLAN_MAX + 5)], -} - - -class VlanTypeTest(base.BaseTestCase): - - def setUp(self): - super(VlanTypeTest, self).setUp() - db.configure_db() - self.driver = type_vlan.VlanTypeDriver() - self.driver.network_vlan_ranges = NETWORK_VLAN_RANGES - self.driver._sync_vlan_allocations() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def _get_allocation(self, session, segment): - return session.query(type_vlan.VlanAllocation).filter_by( - physical_network=segment[api.PHYSICAL_NETWORK], - vlan_id=segment[api.SEGMENTATION_ID]).first() - - def test_validate_provider_segment(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: PROVIDER_NET, - api.SEGMENTATION_ID: 1} - self.assertIsNone(self.driver.validate_provider_segment(segment)) - - def test_validate_provider_segment_with_missing_physical_network(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.SEGMENTATION_ID: 1} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_validate_provider_segment_with_missing_segmentation_id(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: PROVIDER_NET} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_validate_provider_segment_with_invalid_physical_network(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: 'other_phys_net', - api.SEGMENTATION_ID: 1} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_validate_provider_segment_with_invalid_segmentation_id(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: PROVIDER_NET, - api.SEGMENTATION_ID: 5000} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_validate_provider_segment_with_invalid_input(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: PROVIDER_NET, - api.SEGMENTATION_ID: 1, - 'invalid': 1} - self.assertRaises(exc.InvalidInput, - self.driver.validate_provider_segment, - segment) - - def test_sync_vlan_allocations(self): - def check_in_ranges(network_vlan_ranges): - vlan_min, vlan_max = network_vlan_ranges[TENANT_NET][0] - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: TENANT_NET} - - segment[api.SEGMENTATION_ID] = vlan_min - 1 - self.assertIsNone( - self._get_allocation(self.session, segment)) - segment[api.SEGMENTATION_ID] = vlan_max + 1 - self.assertIsNone( - self._get_allocation(self.session, segment)) - - segment[api.SEGMENTATION_ID] = vlan_min - self.assertFalse( - self._get_allocation(self.session, segment).allocated) - segment[api.SEGMENTATION_ID] = vlan_max - self.assertFalse( - self._get_allocation(self.session, segment).allocated) - - check_in_ranges(NETWORK_VLAN_RANGES) - self.driver.network_vlan_ranges = UPDATED_VLAN_RANGES - self.driver._sync_vlan_allocations() - check_in_ranges(UPDATED_VLAN_RANGES) - - def test_reserve_provider_segment(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: PROVIDER_NET, - api.SEGMENTATION_ID: 101} - alloc = self._get_allocation(self.session, segment) - self.assertIsNone(alloc) - self.driver.reserve_provider_segment(self.session, segment) - alloc = self._get_allocation(self.session, segment) - self.assertTrue(alloc.allocated) - - def test_reserve_provider_segment_already_allocated(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: PROVIDER_NET, - api.SEGMENTATION_ID: 101} - self.driver.reserve_provider_segment(self.session, segment) - self.assertRaises(exc.VlanIdInUse, - self.driver.reserve_provider_segment, - self.session, - segment) - - def test_reserve_provider_segment_in_tenant_pools(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: TENANT_NET, - api.SEGMENTATION_ID: VLAN_MIN} - alloc = self._get_allocation(self.session, segment) - self.assertFalse(alloc.allocated) - self.driver.reserve_provider_segment(self.session, segment) - alloc = self._get_allocation(self.session, segment) - self.assertTrue(alloc.allocated) - - def test_allocate_tenant_segment(self): - for __ in range(VLAN_MIN, VLAN_MAX + 1): - segment = self.driver.allocate_tenant_segment(self.session) - alloc = self._get_allocation(self.session, segment) - self.assertTrue(alloc.allocated) - vlan_id = segment[api.SEGMENTATION_ID] - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - self.assertEqual(TENANT_NET, segment[api.PHYSICAL_NETWORK]) - - def test_allocate_tenant_segment_no_available(self): - for __ in range(VLAN_MIN, VLAN_MAX + 1): - self.driver.allocate_tenant_segment(self.session) - segment = self.driver.allocate_tenant_segment(self.session) - self.assertIsNone(segment) - - def test_release_segment(self): - segment = self.driver.allocate_tenant_segment(self.session) - self.driver.release_segment(self.session, segment) - alloc = self._get_allocation(self.session, segment) - self.assertFalse(alloc.allocated) - - def test_release_segment_unallocated(self): - segment = {api.NETWORK_TYPE: p_const.TYPE_VLAN, - api.PHYSICAL_NETWORK: PROVIDER_NET, - api.SEGMENTATION_ID: 101} - with mock.patch.object(type_vlan.LOG, 'warning') as log_warn: - self.driver.release_segment(self.session, segment) - log_warn.assert_called_once_with( - "No vlan_id %(vlan_id)s found on physical network " - "%(physical_network)s", - {'vlan_id': 101, 'physical_network': PROVIDER_NET}) diff --git a/neutron/tests/unit/ml2/test_type_vxlan.py b/neutron/tests/unit/ml2/test_type_vxlan.py deleted file mode 100644 index 1242df2ab..000000000 --- a/neutron/tests/unit/ml2/test_type_vxlan.py +++ /dev/null @@ -1,227 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. -# @author: Kyle Mestery, Cisco Systems, Inc. - -from oslo.config import cfg -from six import moves -import testtools -from testtools import matchers - -from neutron.common import exceptions as exc -from neutron.db import api as db -from neutron.plugins.common import constants as p_const -from neutron.plugins.ml2 import driver_api as api -from neutron.plugins.ml2.drivers import type_vxlan -from neutron.tests import base - - -TUNNEL_IP_ONE = "10.10.10.10" -TUNNEL_IP_TWO = "10.10.10.20" -TUN_MIN = 100 -TUN_MAX = 109 -TUNNEL_RANGES = [(TUN_MIN, TUN_MAX)] -UPDATED_TUNNEL_RANGES = [(TUN_MIN + 5, TUN_MAX + 5)] -INVALID_VXLAN_VNI = 7337 -MULTICAST_GROUP = "239.1.1.1" -VXLAN_UDP_PORT_ONE = 9999 -VXLAN_UDP_PORT_TWO = 8888 - - -class VxlanTypeTest(base.BaseTestCase): - def setUp(self): - super(VxlanTypeTest, self).setUp() - db.configure_db() - cfg.CONF.set_override('vni_ranges', [TUNNEL_RANGES], - group='ml2_type_vxlan') - cfg.CONF.set_override('vxlan_group', MULTICAST_GROUP, - group='ml2_type_vxlan') - self.driver = type_vxlan.VxlanTypeDriver() - self.driver.vxlan_vni_ranges = TUNNEL_RANGES - self.driver._sync_vxlan_allocations() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_vxlan_tunnel_type(self): - self.assertEqual(self.driver.get_type(), p_const.TYPE_VXLAN) - - def test_validate_provider_segment(self): - segment = {api.NETWORK_TYPE: 'vxlan', - api.PHYSICAL_NETWORK: 'phys_net', - api.SEGMENTATION_ID: None} - - with testtools.ExpectedException(exc.InvalidInput): - self.driver.validate_provider_segment(segment) - - segment[api.PHYSICAL_NETWORK] = None - with testtools.ExpectedException(exc.InvalidInput): - self.driver.validate_provider_segment(segment) - - def test_sync_tunnel_allocations(self): - self.assertIsNone( - self.driver.get_vxlan_allocation(self.session, - (TUN_MIN - 1)) - ) - self.assertFalse( - self.driver.get_vxlan_allocation(self.session, - (TUN_MIN)).allocated - ) - self.assertFalse( - self.driver.get_vxlan_allocation(self.session, - (TUN_MIN + 1)).allocated - ) - self.assertFalse( - self.driver.get_vxlan_allocation(self.session, - (TUN_MAX - 1)).allocated - ) - self.assertFalse( - self.driver.get_vxlan_allocation(self.session, - (TUN_MAX)).allocated - ) - self.assertIsNone( - self.driver.get_vxlan_allocation(self.session, - (TUN_MAX + 1)) - ) - - self.driver.vxlan_vni_ranges = UPDATED_TUNNEL_RANGES - self.driver._sync_vxlan_allocations() - - self.assertIsNone(self.driver. - get_vxlan_allocation(self.session, - (TUN_MIN + 5 - 1))) - self.assertFalse(self.driver. - get_vxlan_allocation(self.session, (TUN_MIN + 5)). - allocated) - self.assertFalse(self.driver. - get_vxlan_allocation(self.session, (TUN_MIN + 5 + 1)). - allocated) - self.assertFalse(self.driver. - get_vxlan_allocation(self.session, (TUN_MAX + 5 - 1)). - allocated) - self.assertFalse(self.driver. - get_vxlan_allocation(self.session, (TUN_MAX + 5)). - allocated) - self.assertIsNone(self.driver. - get_vxlan_allocation(self.session, - (TUN_MAX + 5 + 1))) - - def test_reserve_provider_segment(self): - segment = {api.NETWORK_TYPE: 'vxlan', - api.PHYSICAL_NETWORK: 'None', - api.SEGMENTATION_ID: 101} - self.driver.reserve_provider_segment(self.session, segment) - alloc = self.driver.get_vxlan_allocation(self.session, - segment[api.SEGMENTATION_ID]) - self.assertTrue(alloc.allocated) - - with testtools.ExpectedException(exc.TunnelIdInUse): - self.driver.reserve_provider_segment(self.session, segment) - - self.driver.release_segment(self.session, segment) - alloc = self.driver.get_vxlan_allocation(self.session, - segment[api.SEGMENTATION_ID]) - self.assertFalse(alloc.allocated) - - segment[api.SEGMENTATION_ID] = 1000 - self.driver.reserve_provider_segment(self.session, segment) - alloc = self.driver.get_vxlan_allocation(self.session, - segment[api.SEGMENTATION_ID]) - self.assertTrue(alloc.allocated) - - self.driver.release_segment(self.session, segment) - alloc = self.driver.get_vxlan_allocation(self.session, - segment[api.SEGMENTATION_ID]) - self.assertIsNone(alloc) - - def test_allocate_tenant_segment(self): - tunnel_ids = set() - for x in moves.xrange(TUN_MIN, TUN_MAX + 1): - segment = self.driver.allocate_tenant_segment(self.session) - self.assertThat(segment[api.SEGMENTATION_ID], - matchers.GreaterThan(TUN_MIN - 1)) - self.assertThat(segment[api.SEGMENTATION_ID], - matchers.LessThan(TUN_MAX + 1)) - tunnel_ids.add(segment[api.SEGMENTATION_ID]) - - segment = self.driver.allocate_tenant_segment(self.session) - self.assertIsNone(segment) - - segment = {api.NETWORK_TYPE: 'vxlan', - api.PHYSICAL_NETWORK: 'None', - api.SEGMENTATION_ID: tunnel_ids.pop()} - self.driver.release_segment(self.session, segment) - segment = self.driver.allocate_tenant_segment(self.session) - self.assertThat(segment[api.SEGMENTATION_ID], - matchers.GreaterThan(TUN_MIN - 1)) - self.assertThat(segment[api.SEGMENTATION_ID], - matchers.LessThan(TUN_MAX + 1)) - tunnel_ids.add(segment[api.SEGMENTATION_ID]) - - for tunnel_id in tunnel_ids: - segment[api.SEGMENTATION_ID] = tunnel_id - self.driver.release_segment(self.session, segment) - - def test_vxlan_endpoints(self): - """Test VXLAN allocation/de-allocation.""" - - # Set first endpoint, verify it gets VXLAN VNI 1 - vxlan1_endpoint = self.driver.add_endpoint(TUNNEL_IP_ONE, - VXLAN_UDP_PORT_ONE) - self.assertEqual(TUNNEL_IP_ONE, vxlan1_endpoint.ip_address) - self.assertEqual(VXLAN_UDP_PORT_ONE, vxlan1_endpoint.udp_port) - - # Set second endpoint, verify it gets VXLAN VNI 2 - vxlan2_endpoint = self.driver.add_endpoint(TUNNEL_IP_TWO, - VXLAN_UDP_PORT_TWO) - self.assertEqual(TUNNEL_IP_TWO, vxlan2_endpoint.ip_address) - self.assertEqual(VXLAN_UDP_PORT_TWO, vxlan2_endpoint.udp_port) - - # Get all the endpoints - endpoints = self.driver.get_endpoints() - for endpoint in endpoints: - if endpoint['ip_address'] == TUNNEL_IP_ONE: - self.assertEqual(VXLAN_UDP_PORT_ONE, endpoint['udp_port']) - elif endpoint['ip_address'] == TUNNEL_IP_TWO: - self.assertEqual(VXLAN_UDP_PORT_TWO, endpoint['udp_port']) - - -class VxlanTypeMultiRangeTest(base.BaseTestCase): - - TUN_MIN0 = 100 - TUN_MAX0 = 101 - TUN_MIN1 = 200 - TUN_MAX1 = 201 - TUNNEL_MULTI_RANGES = [(TUN_MIN0, TUN_MAX0), (TUN_MIN1, TUN_MAX1)] - - def setUp(self): - super(VxlanTypeMultiRangeTest, self).setUp() - db.configure_db() - self.driver = type_vxlan.VxlanTypeDriver() - self.driver.vxlan_vni_ranges = self.TUNNEL_MULTI_RANGES - self.driver._sync_vxlan_allocations() - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_release_segment(self): - segments = [self.driver.allocate_tenant_segment(self.session) - for i in range(4)] - - # Release them in random order. No special meaning. - for i in (0, 2, 1, 3): - self.driver.release_segment(self.session, segments[i]) - - for key in (self.TUN_MIN0, self.TUN_MAX0, - self.TUN_MIN1, self.TUN_MAX1): - alloc = self.driver.get_vxlan_allocation(self.session, key) - self.assertFalse(alloc.allocated) diff --git a/neutron/tests/unit/mlnx/__init__.py b/neutron/tests/unit/mlnx/__init__.py deleted file mode 100644 index c818bfe31..000000000 --- a/neutron/tests/unit/mlnx/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 Mellanox Technologies, Ltd -# -# 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. diff --git a/neutron/tests/unit/mlnx/test_agent_scheduler.py b/neutron/tests/unit/mlnx/test_agent_scheduler.py deleted file mode 100644 index f53f40d3e..000000000 --- a/neutron/tests/unit/mlnx/test_agent_scheduler.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# -# 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. - -from neutron.tests.unit.mlnx import test_mlnx_plugin -from neutron.tests.unit.openvswitch import test_agent_scheduler - - -class MlnxAgentSchedulerTestCase( - test_agent_scheduler.OvsAgentSchedulerTestCase): - plugin_str = test_mlnx_plugin.PLUGIN_NAME - l3_plugin = None - - -class MlnxL3AgentNotifierTestCase( - test_agent_scheduler.OvsL3AgentNotifierTestCase): - plugin_str = test_mlnx_plugin.PLUGIN_NAME - l3_plugin = None - - -class MlnxDhcpAgentNotifierTestCase( - test_agent_scheduler.OvsDhcpAgentNotifierTestCase): - plugin_str = test_mlnx_plugin.PLUGIN_NAME diff --git a/neutron/tests/unit/mlnx/test_defaults.py b/neutron/tests/unit/mlnx/test_defaults.py deleted file mode 100644 index 8d9cc8c4e..000000000 --- a/neutron/tests/unit/mlnx/test_defaults.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# -# 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. - -from oslo.config import cfg - -#NOTE this import loads tests required options -from neutron.plugins.mlnx.common import config # noqa -from neutron.tests import base - - -class ConfigurationTest(base.BaseTestCase): - - def test_defaults(self): - self.assertEqual(2, - cfg.CONF.AGENT.polling_interval) - self.assertEqual('vlan', - cfg.CONF.MLNX.tenant_network_type) - self.assertEqual(1, - len(cfg.CONF.MLNX.network_vlan_ranges)) - self.assertEqual('eth', - cfg.CONF.MLNX.physical_network_type) - self.assertFalse(cfg.CONF.MLNX.physical_network_type_mappings) - self.assertEqual(0, - len(cfg.CONF.ESWITCH. - physical_interface_mappings)) - self.assertEqual('tcp://127.0.0.1:60001', - cfg.CONF.ESWITCH.daemon_endpoint) diff --git a/neutron/tests/unit/mlnx/test_mlnx_comm_utils.py b/neutron/tests/unit/mlnx/test_mlnx_comm_utils.py deleted file mode 100644 index bb8bdcced..000000000 --- a/neutron/tests/unit/mlnx/test_mlnx_comm_utils.py +++ /dev/null @@ -1,139 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# -# 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 oslo.config import cfg - -from neutron.plugins.mlnx.common import comm_utils -from neutron.plugins.mlnx.common import config # noqa -from neutron.plugins.mlnx.common import exceptions -from neutron.tests import base - - -class WrongException(Exception): - pass - - -class TestRetryDecorator(base.BaseTestCase): - def setUp(self): - super(TestRetryDecorator, self).setUp() - self.sleep_fn_p = mock.patch.object(comm_utils.RetryDecorator, - 'sleep_fn') - self.sleep_fn = self.sleep_fn_p.start() - - def test_no_retry_required(self): - self.counter = 0 - - @comm_utils.RetryDecorator(exceptions.RequestTimeout, interval=2, - retries=3, backoff_rate=2) - def succeeds(): - self.counter += 1 - return 'success' - - ret = succeeds() - self.assertFalse(self.sleep_fn.called) - self.assertEqual(ret, 'success') - self.assertEqual(self.counter, 1) - - def test_retry_zero_times(self): - self.counter = 0 - interval = 2 - backoff_rate = 2 - retries = 0 - - @comm_utils.RetryDecorator(exceptions.RequestTimeout, interval, - retries, backoff_rate) - def always_fails(): - self.counter += 1 - raise exceptions.RequestTimeout() - - self.assertRaises(exceptions.RequestTimeout, always_fails) - self.assertEqual(self.counter, 1) - self.assertFalse(self.sleep_fn.called) - - def test_retries_once(self): - self.counter = 0 - interval = 2 - backoff_rate = 2 - retries = 3 - - @comm_utils.RetryDecorator(exceptions.RequestTimeout, interval, - retries, backoff_rate) - def fails_once(): - self.counter += 1 - if self.counter < 2: - raise exceptions.RequestTimeout() - else: - return 'success' - - ret = fails_once() - self.assertEqual(ret, 'success') - self.assertEqual(self.counter, 2) - self.assertEqual(self.sleep_fn.call_count, 1) - self.sleep_fn.assert_called_with(interval) - - def test_limit_is_reached(self): - self.counter = 0 - retries = 3 - interval = 2 - backoff_rate = 4 - - @comm_utils.RetryDecorator(exceptions.RequestTimeout, interval, - retries, backoff_rate) - def always_fails(): - self.counter += 1 - raise exceptions.RequestTimeout() - - self.assertRaises(exceptions.RequestTimeout, always_fails) - self.assertEqual(self.counter, retries + 1) - self.assertEqual(self.sleep_fn.call_count, retries) - - expected_sleep_fn_arg = [] - for i in range(retries): - expected_sleep_fn_arg.append(interval) - interval *= backoff_rate - - self.sleep_fn.assert_has_calls(map(mock.call, expected_sleep_fn_arg)) - - def test_limit_is_reached_with_conf(self): - self.counter = 0 - - @comm_utils.RetryDecorator(exceptions.RequestTimeout) - def always_fails(): - self.counter += 1 - raise exceptions.RequestTimeout() - - retry = cfg.CONF.ESWITCH.retries - interval = cfg.CONF.ESWITCH.request_timeout / 1000 - delay_rate = cfg.CONF.ESWITCH.backoff_rate - - expected_sleep_fn_arg = [] - for i in range(retry): - expected_sleep_fn_arg.append(interval) - interval *= delay_rate - - self.assertRaises(exceptions.RequestTimeout, always_fails) - self.assertEqual(self.counter, retry + 1) - self.assertEqual(self.sleep_fn.call_count, retry) - self.sleep_fn.assert_has_calls(map(mock.call, expected_sleep_fn_arg)) - - def test_wrong_exception_no_retry(self): - - @comm_utils.RetryDecorator(exceptions.RequestTimeout) - def raise_unexpected_error(): - raise WrongException("wrong exception") - - self.assertRaises(WrongException, raise_unexpected_error) - self.assertFalse(self.sleep_fn.called) diff --git a/neutron/tests/unit/mlnx/test_mlnx_db.py b/neutron/tests/unit/mlnx/test_mlnx_db.py deleted file mode 100644 index a72ed0865..000000000 --- a/neutron/tests/unit/mlnx/test_mlnx_db.py +++ /dev/null @@ -1,181 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# -# 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. - -from six import moves -from testtools import matchers - -from neutron.common import exceptions as n_exc -from neutron.db import api as db -from neutron.plugins.mlnx.db import mlnx_db_v2 as mlnx_db -from neutron.tests import base -from neutron.tests.unit import test_db_plugin as test_plugin - -PHYS_NET = 'physnet1' -PHYS_NET_2 = 'physnet2' -NET_TYPE = 'vlan' -VLAN_MIN = 10 -VLAN_MAX = 19 -VLAN_RANGES = {PHYS_NET: [(VLAN_MIN, VLAN_MAX)]} -UPDATED_VLAN_RANGES = {PHYS_NET: [(VLAN_MIN + 5, VLAN_MAX + 5)], - PHYS_NET_2: [(VLAN_MIN + 20, VLAN_MAX + 20)]} -TEST_NETWORK_ID = 'abcdefghijklmnopqrstuvwxyz' - - -class SegmentationIdAllocationTest(base.BaseTestCase): - def setUp(self): - super(SegmentationIdAllocationTest, self).setUp() - db.configure_db() - mlnx_db.sync_network_states(VLAN_RANGES) - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_sync_segmentationIdAllocation(self): - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET, - VLAN_MIN - 1)) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MIN + 1).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MAX - 1).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MAX).allocated) - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET, - VLAN_MAX + 1)) - - mlnx_db.sync_network_states(UPDATED_VLAN_RANGES) - - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET, - VLAN_MIN + 5 - 1)) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MIN + 5).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MIN + 5 + 1).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MAX + 5 - 1).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MAX + 5).allocated) - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET, - VLAN_MAX + 5 + 1)) - - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20 - 1)) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20).allocated) - self.assertFalse( - mlnx_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20 + 1).allocated) - self.assertFalse( - mlnx_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20 - 1).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20).allocated) - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20 + 1)) - - mlnx_db.sync_network_states(VLAN_RANGES) - - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET, - VLAN_MIN - 1)) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MIN + 1).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MAX - 1).allocated) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - VLAN_MAX).allocated) - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET, - VLAN_MAX + 1)) - - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20)) - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20)) - - def test_segmentationId_pool(self): - vlan_ids = set() - for x in moves.xrange(VLAN_MIN, VLAN_MAX + 1): - physical_network, vlan_id = mlnx_db.reserve_network(self.session) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - self.assertRaises(n_exc.NoNetworkAvailable, - mlnx_db.reserve_network, - self.session) - for vlan_id in vlan_ids: - mlnx_db.release_network(self.session, PHYS_NET, - vlan_id, VLAN_RANGES) - - def test_specific_segmentationId_inside_pool(self): - vlan_id = VLAN_MIN + 5 - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - vlan_id).allocated) - mlnx_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - self.assertTrue(mlnx_db.get_network_state(PHYS_NET, - vlan_id).allocated) - - self.assertRaises(n_exc.VlanIdInUse, - mlnx_db.reserve_specific_network, - self.session, - PHYS_NET, - vlan_id) - - mlnx_db.release_network(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - self.assertFalse(mlnx_db.get_network_state(PHYS_NET, - vlan_id).allocated) - - def test_specific_segmentationId_outside_pool(self): - vlan_id = VLAN_MAX + 5 - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET, vlan_id)) - mlnx_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - self.assertTrue(mlnx_db.get_network_state(PHYS_NET, - vlan_id).allocated) - - self.assertRaises(n_exc.VlanIdInUse, - mlnx_db.reserve_specific_network, - self.session, - PHYS_NET, - vlan_id) - - mlnx_db.release_network(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - self.assertIsNone(mlnx_db.get_network_state(PHYS_NET, vlan_id)) - - -class NetworkBindingsTest(test_plugin.NeutronDbPluginV2TestCase): - def setUp(self): - super(NetworkBindingsTest, self).setUp() - db.configure_db() - self.session = db.get_session() - - def test_add_network_binding(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - self.assertIsNone(mlnx_db.get_network_binding(self.session, - TEST_NETWORK_ID)) - mlnx_db.add_network_binding(self.session, - TEST_NETWORK_ID, - NET_TYPE, - PHYS_NET, - 1234) - binding = mlnx_db.get_network_binding(self.session, - TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, NET_TYPE) - self.assertEqual(binding.physical_network, PHYS_NET) - self.assertEqual(binding.segmentation_id, 1234) diff --git a/neutron/tests/unit/mlnx/test_mlnx_neutron_agent.py b/neutron/tests/unit/mlnx/test_mlnx_neutron_agent.py deleted file mode 100644 index 7191f0b38..000000000 --- a/neutron/tests/unit/mlnx/test_mlnx_neutron_agent.py +++ /dev/null @@ -1,156 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2014 Mellanox Technologies, Ltd -# -# 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 contextlib - -import mock -from oslo.config import cfg -import testtools - -from neutron.plugins.mlnx.agent import eswitch_neutron_agent -from neutron.plugins.mlnx.agent import utils -from neutron.plugins.mlnx.common import exceptions -from neutron.tests import base - - -class TestEswichManager(base.BaseTestCase): - - def setUp(self): - super(TestEswichManager, self).setUp() - - class MockEswitchUtils(object): - def __init__(self, endpoint, timeout): - pass - - mock.patch('neutron.plugins.mlnx.agent.utils.EswitchManager', - new=MockEswitchUtils) - - with mock.patch.object(utils, 'zmq'): - self.manager = eswitch_neutron_agent.EswitchManager({}, None, None) - - def test_get_not_exist_port_id(self): - with testtools.ExpectedException(exceptions.MlnxException): - self.manager.get_port_id_by_mac('no-such-mac') - - -class TestEswitchAgent(base.BaseTestCase): - - def setUp(self): - super(TestEswitchAgent, self).setUp() - # Avoid rpc initialization for unit tests - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - - class MockFixedIntervalLoopingCall(object): - def __init__(self, f): - self.f = f - - def start(self, interval=0): - self.f() - - mock.patch('neutron.openstack.common.loopingcall.' - 'FixedIntervalLoopingCall', - new=MockFixedIntervalLoopingCall) - - with mock.patch.object(utils, 'zmq'): - self.agent = eswitch_neutron_agent.MlnxEswitchNeutronAgent({}) - self.agent.plugin_rpc = mock.Mock() - self.agent.context = mock.Mock() - self.agent.agent_id = mock.Mock() - self.agent.eswitch = mock.Mock() - self.agent.eswitch.get_vnics_mac.return_value = [] - - def test_treat_devices_added_returns_true_for_missing_device(self): - attrs = {'get_device_details.side_effect': Exception()} - self.agent.plugin_rpc.configure_mock(**attrs) - with contextlib.nested( - mock.patch('neutron.plugins.mlnx.agent.eswitch_neutron_agent.' - 'EswitchManager.get_vnics_mac', - return_value=[])): - self.assertTrue(self.agent.treat_devices_added([{}])) - - def _mock_treat_devices_added(self, details, func_name): - """Mock treat devices added. - - :param details: the details to return for the device - :param func_name: the function that should be called - :returns: whether the named function was called - """ - with contextlib.nested( - mock.patch('neutron.plugins.mlnx.agent.eswitch_neutron_agent.' - 'EswitchManager.get_vnics_mac', - return_value=[]), - mock.patch.object(self.agent.plugin_rpc, 'get_device_details', - return_value=details), - mock.patch.object(self.agent.plugin_rpc, 'update_device_up'), - mock.patch.object(self.agent, func_name) - ) as (vnics_fn, get_dev_fn, upd_dev_up, func): - self.assertFalse(self.agent.treat_devices_added([{}])) - return (func.called, upd_dev_up.called) - - def test_treat_devices_added_updates_known_port(self): - details = mock.MagicMock() - details.__contains__.side_effect = lambda x: True - func, dev_up = self._mock_treat_devices_added(details, - 'treat_vif_port') - self.assertTrue(func) - self.assertTrue(dev_up) - - def test_treat_devices_added_updates_known_port_admin_down(self): - details = {'port_id': '1234567890', - 'device': '01:02:03:04:05:06', - 'network_id': '123456789', - 'network_type': 'vlan', - 'physical_network': 'default', - 'segmentation_id': 2, - 'admin_state_up': False} - func, dev_up = self._mock_treat_devices_added(details, - 'treat_vif_port') - self.assertTrue(func) - self.assertFalse(dev_up) - - def test_treat_devices_removed_returns_true_for_missing_device(self): - with mock.patch.object(self.agent.plugin_rpc, 'update_device_down', - side_effect=Exception()): - self.assertTrue(self.agent.treat_devices_removed([{}])) - - def test_treat_devices_removed_releases_port(self): - details = dict(exists=False) - with mock.patch.object(self.agent.plugin_rpc, 'update_device_down', - return_value=details): - with mock.patch.object(self.agent.eswitch, - 'port_release') as port_release: - self.assertFalse(self.agent.treat_devices_removed([{}])) - self.assertTrue(port_release.called) - - def test_process_network_ports(self): - current_ports = set(['01:02:03:04:05:06']) - added_ports = set(['10:20:30:40:50:60']) - removed_ports = set(['11:22:33:44:55:66']) - reply = {'current': current_ports, - 'removed': removed_ports, - 'added': added_ports} - with mock.patch.object(self.agent, 'treat_devices_added', - return_value=False) as device_added: - with mock.patch.object(self.agent, 'treat_devices_removed', - return_value=False) as device_removed: - self.assertFalse(self.agent.process_network_ports(reply)) - device_added.assert_called_once_with(added_ports) - device_removed.assert_called_once_with(removed_ports) diff --git a/neutron/tests/unit/mlnx/test_mlnx_plugin.py b/neutron/tests/unit/mlnx/test_mlnx_plugin.py deleted file mode 100644 index f3c83ac8d..000000000 --- a/neutron/tests/unit/mlnx/test_mlnx_plugin.py +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# -# 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. - -from oslo.config import cfg -from webob import exc - -from neutron.extensions import portbindings -from neutron.plugins.mlnx.common import constants -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - - -PLUGIN_NAME = ('neutron.plugins.mlnx.mlnx_plugin.MellanoxEswitchPlugin') - - -class MlnxPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self): - super(MlnxPluginV2TestCase, self).setUp(self._plugin_name) - self.port_create_status = 'DOWN' - - -class TestMlnxBasicGet(test_plugin.TestBasicGet, MlnxPluginV2TestCase): - pass - - -class TestMlnxV2HTTPResponse(test_plugin.TestV2HTTPResponse, - MlnxPluginV2TestCase): - pass - - -class TestMlnxPortsV2(test_plugin.TestPortsV2, - MlnxPluginV2TestCase): - pass - - -class TestMlnxNetworksV2(test_plugin.TestNetworksV2, MlnxPluginV2TestCase): - pass - - -class TestMlnxPortBinding(MlnxPluginV2TestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = constants.VIF_TYPE_DIRECT - ENABLE_SG = False - HAS_PORT_FILTER = False - - def setUp(self, firewall_driver=None): - cfg.CONF.set_override( - 'enable_security_group', self.ENABLE_SG, - group='SECURITYGROUP') - super(TestMlnxPortBinding, self).setUp() - - def _check_default_port_binding_profole(self, port, - expected_vif_type=None): - if expected_vif_type is None: - expected_vif_type = constants.VIF_TYPE_DIRECT - p = port['port'] - self.assertIn('id', p) - self.assertEqual(expected_vif_type, p[portbindings.VIF_TYPE]) - self.assertEqual({'physical_network': 'default'}, - p[portbindings.PROFILE]) - - def test_create_port_no_binding_profile(self): - with self.port() as port: - self._check_default_port_binding_profole(port) - - def test_create_port_binding_profile_none(self): - profile_arg = {portbindings.PROFILE: None} - with self.port(arg_list=(portbindings.PROFILE,), - **profile_arg) as port: - self._check_default_port_binding_profole(port) - - def test_create_port_binding_profile_vif_type(self): - for vif_type in [constants.VIF_TYPE_HOSTDEV, - constants.VIF_TYPE_DIRECT]: - profile_arg = {portbindings.PROFILE: - {constants.VNIC_TYPE: vif_type}} - with self.port(arg_list=(portbindings.PROFILE,), - **profile_arg) as port: - self._check_default_port_binding_profole( - port, expected_vif_type=vif_type) - - def test_create_port_binding_profile_with_empty_dict(self): - profile_arg = {portbindings.PROFILE: {}} - try: - with self.port(arg_list=(portbindings.PROFILE,), - expected_res_status=400, **profile_arg): - pass - except exc.HTTPClientError: - pass - - -class TestMlnxPortBindingNoSG(TestMlnxPortBinding): - HAS_PORT_FILTER = False - ENABLE_SG = False - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER - - -class TestMlnxPortBindingHost( - MlnxPluginV2TestCase, - test_bindings.PortBindingsHostTestCaseMixin): - pass diff --git a/neutron/tests/unit/mlnx/test_mlnx_plugin_config.py b/neutron/tests/unit/mlnx/test_mlnx_plugin_config.py deleted file mode 100644 index 70f3d2df4..000000000 --- a/neutron/tests/unit/mlnx/test_mlnx_plugin_config.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation -# -# 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 oslo.config import cfg - -#NOTE this import loads tests required options -from neutron.plugins.mlnx.common import config # noqa -from neutron.plugins.mlnx.common import constants -from neutron.plugins.mlnx import mlnx_plugin -from neutron.tests import base - - -class TestMlnxPluginConfig(base.BaseTestCase): - expected_vlan_mappings = {'physnet1': [(1, 1000)], - 'physnet2': [(1, 1000)]} - expected_network_types = {'physnet1': constants.TYPE_ETH, - 'physnet2': constants.TYPE_IB} - config_vlan_ranges = ['physnet1:1:1000', 'physnet2:1:1000'] - config_network_types = ['physnet1:eth', 'physnet2:ib'] - - def setUp(self): - super(TestMlnxPluginConfig, self).setUp() - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - cfg.CONF.set_override(group='MLNX', - name='network_vlan_ranges', - override=self.config_vlan_ranges) - - def _create_mlnx_plugin(self): - with mock.patch('neutron.plugins.mlnx.db.mlnx_db_v2'): - return mlnx_plugin.MellanoxEswitchPlugin() - - def _assert_expected_config(self): - plugin = self._create_mlnx_plugin() - self.assertEqual(plugin.network_vlan_ranges, - self.expected_vlan_mappings) - self.assertEqual(plugin.phys_network_type_maps, - self.expected_network_types) - - def test_vlan_ranges_with_network_type(self): - cfg.CONF.set_override(group='MLNX', - name='physical_network_type_mappings', - override=self.config_network_types) - self._assert_expected_config() - - def test_vlan_ranges_partial_network_type(self): - cfg.CONF.set_override(group='MLNX', - name='physical_network_type_mappings', - override=self.config_network_types[:1]) - cfg.CONF.set_override(group='MLNX', - name='physical_network_type', - override=constants.TYPE_IB) - self._assert_expected_config() - - def test_vlan_ranges_no_network_type(self): - cfg.CONF.set_override(group='MLNX', - name='physical_network_type', - override=constants.TYPE_IB) - cfg.CONF.set_override(group='MLNX', - name='physical_network_type_mappings', - override=[]) - self.expected_network_types.update({'physnet1': constants.TYPE_IB}) - self._assert_expected_config() - self.expected_network_types.update({'physnet1': constants.TYPE_ETH}) - - def test_parse_physical_network_mappings_invalid_type(self): - cfg.CONF.set_override(group='MLNX', - name='physical_network_type_mappings', - override=['physnet:invalid-type']) - self.assertRaises(SystemExit, self._create_mlnx_plugin) - - def test_invalid_network_type(self): - cfg.CONF.set_override(group='MLNX', - name='physical_network_type', - override='invalid-type') - self.assertRaises(SystemExit, self._create_mlnx_plugin) diff --git a/neutron/tests/unit/mlnx/test_mlnx_security_group.py b/neutron/tests/unit/mlnx/test_mlnx_security_group.py deleted file mode 100644 index 347de62c8..000000000 --- a/neutron/tests/unit/mlnx/test_mlnx_security_group.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# -# 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 -import webob.exc - -from neutron.api.v2 import attributes -from neutron.extensions import securitygroup as ext_sg -from neutron.plugins.mlnx.db import mlnx_db_v2 as mlnx_db -from neutron.tests.unit import test_extension_security_group as test_sg -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - - -PLUGIN_NAME = ('neutron.plugins.mlnx.' - 'mlnx_plugin.MellanoxEswitchPlugin') -NOTIFIER = ('neutron.plugins.mlnx.' - 'agent_notify_api.AgentNotifierApi') - - -class MlnxSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self, plugin=None): - test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_IPTABLES_DRIVER) - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - self._attribute_map_bk_ = {} - for item in attributes.RESOURCE_ATTRIBUTE_MAP: - self._attribute_map_bk_[item] = (attributes. - RESOURCE_ATTRIBUTE_MAP[item]. - copy()) - super(MlnxSecurityGroupsTestCase, self).setUp(PLUGIN_NAME) - - def tearDown(self): - attributes.RESOURCE_ATTRIBUTE_MAP = self._attribute_map_bk_ - super(MlnxSecurityGroupsTestCase, self).tearDown() - - -class TestMlnxSecurityGroups(MlnxSecurityGroupsTestCase, - test_sg.TestSecurityGroups, - test_sg_rpc.SGNotificationTestMixin): - pass - - -class TestMlnxSecurityGroupsXML(TestMlnxSecurityGroups): - fmt = 'xml' - - -class TestMlnxSecurityGroupsDB(MlnxSecurityGroupsTestCase): - def test_security_group_get_port_from_device(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - security_group_id = sg['security_group']['id'] - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - fixed_ips = port['port']['fixed_ips'] - data = {'port': {'fixed_ips': fixed_ips, - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: - [security_group_id]}} - - req = self.new_update_request('ports', data, - port['port']['id']) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - port_id = res['port']['id'] - device_id = port_id[:8] - port_dict = mlnx_db.get_port_from_device(device_id) - self.assertEqual(port_id, port_dict['id']) - self.assertEqual([security_group_id], - port_dict[ext_sg.SECURITYGROUPS]) - self.assertEqual([], port_dict['security_group_rules']) - self.assertEqual([fixed_ips[0]['ip_address']], - port_dict['fixed_ips']) - self._delete('ports', port['port']['id']) - - def test_security_group_get_port_from_device_with_no_port(self): - port_dict = mlnx_db.get_port_from_device('bad_device_id') - self.assertIsNone(port_dict) - - -class TestMlnxSecurityGroupsDBXML(TestMlnxSecurityGroupsDB): - fmt = 'xml' diff --git a/neutron/tests/unit/mlnx/test_rpcapi.py b/neutron/tests/unit/mlnx/test_rpcapi.py deleted file mode 100644 index ea34a840b..000000000 --- a/neutron/tests/unit/mlnx/test_rpcapi.py +++ /dev/null @@ -1,155 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 Mellanox Technologies, Ltd -# -# 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. - -""" -Unit Tests for Mellanox RPC (major reuse of linuxbridge rpc unit tests) -""" - -import fixtures -from oslo.config import cfg - -from neutron.agent import rpc as agent_rpc -from neutron.common import topics -from neutron.openstack.common import context -from neutron.plugins.mlnx import agent_notify_api -from neutron.tests import base - - -class rpcApiTestCase(base.BaseTestCase): - - def _test_mlnx_api(self, rpcapi, topic, method, rpc_method, - expected_msg=None, **kwargs): - ctxt = context.RequestContext('fake_user', 'fake_project') - expected_retval = 'foo' if method == 'call' else None - if not expected_msg: - expected_msg = rpcapi.make_msg(method, **kwargs) - if rpc_method == 'cast' and method == 'run_instance': - kwargs['call'] = False - - self.fake_args = None - self.fake_kwargs = None - - def _fake_rpc_method(*args, **kwargs): - self.fake_args = args - self.fake_kwargs = kwargs - if expected_retval: - return expected_retval - - self.useFixture(fixtures.MonkeyPatch( - 'neutron.common.rpc_compat.RpcProxy.' + rpc_method, - _fake_rpc_method)) - - retval = getattr(rpcapi, method)(ctxt, **kwargs) - - self.assertEqual(expected_retval, retval) - expected_args = [ctxt, expected_msg] - expected_kwargs = {'topic': topic} - - # skip the first argument which is 'self' - for arg, expected_arg in zip(self.fake_args[1:], expected_args): - self.assertEqual(expected_arg, arg) - self.assertEqual(expected_kwargs, self.fake_kwargs) - - def test_delete_network(self): - rpcapi = agent_notify_api.AgentNotifierApi(topics.AGENT) - self._test_mlnx_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.NETWORK, - topics.DELETE), - 'network_delete', rpc_method='fanout_cast', - network_id='fake_request_spec') - - def test_port_update(self): - cfg.CONF.set_override('rpc_support_old_agents', False, 'AGENT') - rpcapi = agent_notify_api.AgentNotifierApi(topics.AGENT) - expected_msg = rpcapi.make_msg('port_update', - port='fake_port', - network_type='vlan', - physical_network='fake_net', - segmentation_id='fake_vlan_id') - self._test_mlnx_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - expected_msg=expected_msg, - port='fake_port', - network_type='vlan', - physical_network='fake_net', - vlan_id='fake_vlan_id') - - def test_port_update_ib(self): - cfg.CONF.set_override('rpc_support_old_agents', False, 'AGENT') - rpcapi = agent_notify_api.AgentNotifierApi(topics.AGENT) - expected_msg = rpcapi.make_msg('port_update', - port='fake_port', - network_type='ib', - physical_network='fake_net', - segmentation_id='fake_vlan_id') - self._test_mlnx_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - expected_msg=expected_msg, - port='fake_port', - network_type='ib', - physical_network='fake_net', - vlan_id='fake_vlan_id') - - def test_port_update_old_agent(self): - cfg.CONF.set_override('rpc_support_old_agents', True, 'AGENT') - rpcapi = agent_notify_api.AgentNotifierApi(topics.AGENT) - expected_msg = rpcapi.make_msg('port_update', - port='fake_port', - network_type='vlan', - physical_network='fake_net', - segmentation_id='fake_vlan_id', - vlan_id='fake_vlan_id') - self._test_mlnx_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - expected_msg=expected_msg, - port='fake_port', - network_type='vlan', - physical_network='fake_net', - vlan_id='fake_vlan_id') - - def test_device_details(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_mlnx_api(rpcapi, topics.PLUGIN, - 'get_device_details', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id') - - def test_update_device_down(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_mlnx_api(rpcapi, topics.PLUGIN, - 'update_device_down', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') - - def test_update_device_up(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_mlnx_api(rpcapi, topics.PLUGIN, - 'update_device_up', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') diff --git a/neutron/tests/unit/nec/__init__.py b/neutron/tests/unit/nec/__init__.py deleted file mode 100644 index 362a36068..000000000 --- a/neutron/tests/unit/nec/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012 NEC Corporation. All rights reserved. -# -# 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. diff --git a/neutron/tests/unit/nec/fake_ofc_manager.py b/neutron/tests/unit/nec/fake_ofc_manager.py deleted file mode 100644 index d64b11d03..000000000 --- a/neutron/tests/unit/nec/fake_ofc_manager.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 - - -OFC_MANAGER = 'neutron.plugins.nec.nec_plugin.ofc_manager.OFCManager' - - -def patch_ofc_manager(): - m = mock.patch(OFC_MANAGER).start() - f = FakeOFCManager() - - m.create_ofc_tenant.side_effect = f.create_ofc_tenant - m.delete_ofc_tenant.side_effect = f.delete_ofc_tenant - m.exists_ofc_tenant.side_effect = f.exists_ofc_tenant - m.create_ofc_network.side_effect = f.create_ofc_net - m.delete_ofc_network.side_effect = f.delete_ofc_net - m.exists_ofc_network.side_effect = f.exists_ofc_net - m.create_ofc_port.side_effect = f.create_ofc_port - m.delete_ofc_port.side_effect = f.delete_ofc_port - m.exists_ofc_port.side_effect = f.exists_ofc_port - m.create_ofc_packet_filter.side_effect = f.create_ofc_pf - m.delete_ofc_packet_filter.side_effect = f.delete_ofc_pf - m.exists_ofc_packet_filter.side_effect = f.exists_ofc_pf - m.set_raise_exc = f.set_raise_exc - - return m - - -class FakeOFCManager(object): - - def __init__(self): - self.ofc_tenants = {} - self.ofc_nets = {} - self.ofc_ports = {} - self.ofc_pfs = {} - self.raise_exc_map = {} - - def set_raise_exc(self, func, raise_exc): - self.raise_exc_map.update({func: raise_exc}) - - def _raise_exc(self, func): - exc = self.raise_exc_map.get(func) - if exc: - raise exc - - def create_ofc_tenant(self, context, tenant_id): - self._raise_exc('create_ofc_tenant') - self.ofc_tenants.update({tenant_id: True}) - - def exists_ofc_tenant(self, context, tenant_id): - self._raise_exc('exists_ofc_tenant') - return self.ofc_tenants.get(tenant_id, False) - - def delete_ofc_tenant(self, context, tenant_id): - self._raise_exc('delete_ofc_tenant') - del self.ofc_tenants[tenant_id] - - def create_ofc_net(self, context, tenant_id, net_id, net_name=None): - self._raise_exc('create_ofc_network') - self.ofc_nets.update({net_id: True}) - - def exists_ofc_net(self, context, net_id): - self._raise_exc('exists_ofc_network') - return self.ofc_nets.get(net_id, False) - - def delete_ofc_net(self, context, net_id, net): - self._raise_exc('delete_ofc_network') - del self.ofc_nets[net_id] - - def create_ofc_port(self, context, port_id, port): - self._raise_exc('create_ofc_port') - self.ofc_ports.update({port_id: True}) - - def exists_ofc_port(self, context, port_id): - self._raise_exc('exists_ofc_port') - return self.ofc_ports.get(port_id, False) - - def delete_ofc_port(self, context, port_id, port): - self._raise_exc('delete_ofc_port') - del self.ofc_ports[port_id] - - def create_ofc_pf(self, context, pf_id, pf_dict): - self._raise_exc('create_ofc_packet_filter') - self.ofc_pfs.update({pf_id: True}) - - def exists_ofc_pf(self, context, pf_id): - self._raise_exc('exists_ofc_packet_filter') - return self.ofc_pfs.get(pf_id, False) - - def delete_ofc_pf(self, context, pf_id): - self._raise_exc('delete_ofc_packet_filter') - del self.ofc_pfs[pf_id] diff --git a/neutron/tests/unit/nec/stub_ofc_driver.py b/neutron/tests/unit/nec/stub_ofc_driver.py deleted file mode 100644 index d03744ffa..000000000 --- a/neutron/tests/unit/nec/stub_ofc_driver.py +++ /dev/null @@ -1,293 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012 NEC Corporation. All rights reserved. -# -# 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. -# @author: Ryota MIBU - -import netaddr - -from neutron.common import log as call_log -from neutron.openstack.common import log as logging -from neutron.openstack.common import uuidutils -from neutron.plugins.nec.common import exceptions as nexc -from neutron.plugins.nec import ofc_driver_base - - -LOG = logging.getLogger(__name__) - -MAX_NUM_OPENFLOW_ROUTER = 2 - - -class StubOFCDriver(ofc_driver_base.OFCDriverBase): - """Stub OFC driver for testing. - - This driver can be used not only for unit tests but also for real testing - as a logging driver. It stores the created resources on OFC and returns - them in get methods(). - - If autocheck is enabled, it checks whether the specified resource exists - in OFC and raises an exception if it is different from expected status. - """ - - def __init__(self, conf): - self.autocheck = False - self.reset_all() - - def reset_all(self): - self.ofc_tenant_dict = {} - self.ofc_network_dict = {} - self.ofc_port_dict = {} - self.ofc_filter_dict = {} - self.ofc_router_dict = {} - self.ofc_router_inf_dict = {} - self.ofc_router_route_dict = {} - - def enable_autocheck(self): - self.autocheck = True - - def disable_autocheck(self): - self.autocheck = False - - @call_log.log - def create_tenant(self, description, tenant_id=None): - ofc_id = "ofc-" + tenant_id[:-4] - if self.autocheck: - if ofc_id in self.ofc_tenant_dict: - raise Exception(_('(create_tenant) OFC tenant %s ' - 'already exists') % ofc_id) - self.ofc_tenant_dict[ofc_id] = {'tenant_id': tenant_id, - 'description': description} - return ofc_id - - @call_log.log - def delete_tenant(self, ofc_tenant_id): - if ofc_tenant_id in self.ofc_tenant_dict: - del self.ofc_tenant_dict[ofc_tenant_id] - else: - if self.autocheck: - raise Exception(_('(delete_tenant) OFC tenant %s not found') - % ofc_tenant_id) - LOG.debug(_('delete_tenant: SUCCEED')) - - @call_log.log - def create_network(self, ofc_tenant_id, description, network_id=None): - ofc_id = "ofc-" + network_id[:-4] - if self.autocheck: - if ofc_tenant_id not in self.ofc_tenant_dict: - raise Exception(_('(create_network) OFC tenant %s not found') - % ofc_tenant_id) - if ofc_id in self.ofc_network_dict: - raise Exception(_('(create_network) OFC network %s ' - 'already exists') % ofc_id) - self.ofc_network_dict[ofc_id] = {'tenant_id': ofc_tenant_id, - 'network_id': network_id, - 'description': description} - return ofc_id - - @call_log.log - def update_network(self, ofc_network_id, description): - if self.autocheck: - if ofc_network_id not in self.ofc_network_dict: - raise Exception(_('(update_network) OFC network %s not found') - % ofc_network_id) - data = {'description': description} - self.ofc_network_dict[ofc_network_id].update(data) - LOG.debug(_('update_network: SUCCEED')) - - @call_log.log - def delete_network(self, ofc_network_id): - if ofc_network_id in self.ofc_network_dict: - del self.ofc_network_dict[ofc_network_id] - else: - if self.autocheck: - raise Exception(_('(delete_network) OFC network %s not found') - % ofc_network_id) - LOG.debug(_('delete_network: SUCCEED')) - - @call_log.log - def create_port(self, ofc_network_id, info, port_id=None, filters=None): - ofc_id = "ofc-" + port_id[:-4] - if self.autocheck: - if ofc_network_id not in self.ofc_network_dict: - raise Exception(_('(create_port) OFC network %s not found') - % ofc_network_id) - if ofc_id in self.ofc_port_dict: - raise Exception(_('(create_port) OFC port %s already exists') - % ofc_id) - self.ofc_port_dict[ofc_id] = {'network_id': ofc_network_id, - 'port_id': port_id} - if filters: - self.ofc_port_dict[ofc_id]['filters'] = filters - return ofc_id - - @call_log.log - def delete_port(self, ofc_port_id): - if ofc_port_id in self.ofc_port_dict: - del self.ofc_port_dict[ofc_port_id] - else: - if self.autocheck: - raise Exception(_('(delete_port) OFC port %s not found') - % ofc_port_id) - LOG.debug(_('delete_port: SUCCEED')) - - @classmethod - def filter_supported(cls): - return True - - def create_filter(self, ofc_network_id, filter_dict, - portinfo=None, filter_id=None, apply_ports=None): - return "ofc-" + filter_id[:-4] - - def delete_filter(self, ofc_filter_id): - pass - - def convert_ofc_tenant_id(self, context, ofc_tenant_id): - return ofc_tenant_id - - def convert_ofc_network_id(self, context, ofc_network_id, tenant_id): - return ofc_network_id - - def convert_ofc_port_id(self, context, ofc_port_id, tenant_id, network_id): - return ofc_port_id - - def convert_ofc_filter_id(self, context, ofc_filter_id): - return ofc_filter_id - - router_supported = True - router_nat_supported = True - - @call_log.log - def create_router(self, ofc_tenant_id, router_id, description): - ofc_id = "ofc-" + router_id[:-4] - if self.autocheck: - if ofc_tenant_id not in self.ofc_tenant_dict: - raise Exception(_('(create_router) OFC tenant %s not found') - % ofc_tenant_id) - if ofc_id in self.ofc_router_dict: - raise Exception(_('(create_router) OFC router %s ' - 'already exists') % ofc_id) - if len(self.ofc_router_dict) >= MAX_NUM_OPENFLOW_ROUTER: - params = {'reason': _("Operation on OFC is failed"), - 'status': 409} - raise nexc.OFCException(**params) - self.ofc_router_dict[ofc_id] = {'tenant_id': ofc_tenant_id, - 'router_id': router_id, - 'description': description} - return ofc_id - - @call_log.log - def delete_router(self, ofc_router_id): - if ofc_router_id in self.ofc_router_dict: - del self.ofc_router_dict[ofc_router_id] - else: - if self.autocheck: - raise Exception(_('(delete_router) OFC router %s not found') - % ofc_router_id) - LOG.debug(_('delete_router: SUCCEED')) - - @call_log.log - def add_router_interface(self, ofc_router_id, ofc_net_id, - ip_address=None, mac_address=None): - if_id = "ofc-" + uuidutils.generate_uuid()[:-4] - # IP address should have a format of a.b.c.d/N - if ip_address != str(netaddr.IPNetwork(ip_address)): - raise Exception(_('(add_router_interface) ' - 'ip_address %s is not a valid format (a.b.c.d/N).') - % ip_address) - if self.autocheck: - if ofc_router_id not in self.ofc_router_dict: - raise Exception(_('(add_router_interface) ' - 'OFC router %s not found') % ofc_router_id) - if ofc_net_id not in self.ofc_network_dict: - raise Exception(_('(add_router_interface) ' - 'OFC network %s not found') % ofc_net_id) - # Check duplicate destination - self.ofc_router_inf_dict[if_id] = {'router_id': ofc_router_id, - 'network_id': ofc_net_id, - 'ip_address': ip_address, - 'mac_address': mac_address} - LOG.debug(_('add_router_interface: SUCCEED (if_id=%s)'), if_id) - return if_id - - @call_log.log - def update_router_interface(self, ofc_router_inf_id, - ip_address=None, mac_address=None): - if ofc_router_inf_id not in self.ofc_router_inf_dict: - if self.autocheck: - raise Exception(_('(delete_router_interface) ' - 'OFC router interface %s not found') - % ofc_router_inf_id) - self.ofc_router_inf_dict[ofc_router_inf_id] = {} - inf = self.ofc_router_inf_dict[ofc_router_inf_id] - if ip_address: - inf.update({'ip_address': ip_address}) - if mac_address: - inf.update({'mac_address': mac_address}) - LOG.debug(_('update_router_route: SUCCEED')) - - @call_log.log - def delete_router_interface(self, ofc_router_inf_id): - if ofc_router_inf_id in self.ofc_router_inf_dict: - del self.ofc_router_inf_dict[ofc_router_inf_id] - else: - if self.autocheck: - raise Exception(_('(delete_router_interface) ' - 'OFC router interface %s not found') - % ofc_router_inf_id) - LOG.debug(_('delete_router_interface: SUCCEED')) - - @call_log.log - def add_router_route(self, ofc_router_id, destination, nexthop): - route_id = "ofc-" + uuidutils.generate_uuid()[:-4] - # IP address format check - netaddr.IPNetwork(destination) - netaddr.IPAddress(nexthop) - if self.autocheck: - if ofc_router_id not in self.ofc_router_dict: - raise Exception(_('(add_router_route) OFC router %s not found') - % ofc_router_id) - # Check duplicate destination - if destination in [route['destination'] for route in - self.ofc_router_route_dict.values()]: - raise Exception(_('(add_router_route) ' - 'route to "%s" already exists') % destination) - self.ofc_router_route_dict[route_id] = {'router_id': ofc_router_id, - 'destination': destination, - 'nexthop': nexthop} - LOG.debug(_('add_router_route: SUCCEED (route_id=%s)'), route_id) - return route_id - - @call_log.log - def delete_router_route(self, ofc_router_route_id): - if ofc_router_route_id in self.ofc_router_route_dict: - del self.ofc_router_route_dict[ofc_router_route_id] - else: - if self.autocheck: - raise Exception(_('(delete_router_route) OFC router route %s ' - 'not found') % ofc_router_route_id) - LOG.debug(_('delete_router_route: SUCCEED')) - - @call_log.log - def list_router_routes(self, ofc_router_id): - if self.autocheck: - if ofc_router_id not in self.ofc_router_dict: - raise Exception(_('(delete_router) OFC router %s not found') - % ofc_router_id) - routes = [{'id': k, - 'destination': v['destination'], - 'nexthop': v['nexthop']} - for k, v in self.ofc_router_route_dict.items() - if v['router_id'] == ofc_router_id] - LOG.debug(_('list_router_routes: routes=%s'), routes) - return routes diff --git a/neutron/tests/unit/nec/test_agent_scheduler.py b/neutron/tests/unit/nec/test_agent_scheduler.py deleted file mode 100644 index 60c1770a5..000000000 --- a/neutron/tests/unit/nec/test_agent_scheduler.py +++ /dev/null @@ -1,118 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 NEC Corporation. All rights reserved. -# -# 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 contextlib - -from neutron.common import constants -from neutron.db import l3_rpc_base -from neutron.tests.unit.nec import test_nec_plugin -from neutron.tests.unit.openvswitch import test_agent_scheduler - -L3_HOSTA = test_agent_scheduler.L3_HOSTA -L3_HOSTB = test_agent_scheduler.L3_HOSTB - - -class NecAgentSchedulerTestCase( - test_agent_scheduler.OvsAgentSchedulerTestCase, - test_nec_plugin.NecPluginV2TestCaseBase): - - plugin_str = test_nec_plugin.PLUGIN_NAME - l3_plugin = None - - def setUp(self): - self.setup_nec_plugin_base() - super(NecAgentSchedulerTestCase, self).setUp() - - -class NecDhcpAgentNotifierTestCase( - test_agent_scheduler.OvsDhcpAgentNotifierTestCase, - test_nec_plugin.NecPluginV2TestCaseBase): - - plugin_str = test_nec_plugin.PLUGIN_NAME - - def setUp(self): - self.setup_nec_plugin_base() - super(NecDhcpAgentNotifierTestCase, self).setUp() - - -class NecL3AgentNotifierTestCase( - test_agent_scheduler.OvsL3AgentNotifierTestCase, - test_nec_plugin.NecPluginV2TestCaseBase): - - plugin_str = test_nec_plugin.PLUGIN_NAME - l3_plugin = None - - def setUp(self): - self.setup_nec_plugin_base() - super(NecL3AgentNotifierTestCase, self).setUp() - - -class NecL3AgentSchedulerWithOpenFlowRouter( - test_agent_scheduler.OvsAgentSchedulerTestCaseBase, - test_nec_plugin.NecPluginV2TestCaseBase): - - plugin_str = test_nec_plugin.PLUGIN_NAME - - def setUp(self): - self.setup_nec_plugin_base() - super(NecL3AgentSchedulerWithOpenFlowRouter, self).setUp() - - def test_router_auto_schedule_with_l3agent_and_openflow(self): - with contextlib.nested( - self.router(), - self.router(arg_list=('provider',), - provider='openflow' - )) as (r1, r2): - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_agent_states() - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - ret_b = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTB) - l3_agents = self._list_l3_agents_hosting_router( - r1['router']['id']) - self.assertEqual(1, len(ret_a)) - self.assertFalse(len(ret_b)) - self.assertIn(r1['router']['id'], [r['id'] for r in ret_a]) - self.assertNotIn(r2['router']['id'], [r['id'] for r in ret_a]) - self.assertEqual(1, len(l3_agents['agents'])) - self.assertEqual(L3_HOSTA, l3_agents['agents'][0]['host']) - - def test_router_auto_schedule_only_with_openflow_router(self): - with contextlib.nested( - self.router(arg_list=('provider',), provider='openflow'), - self.router(arg_list=('provider',), provider='openflow') - ) as (r1, r2): - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_agent_states() - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - l3_agents_1 = self._list_l3_agents_hosting_router( - r1['router']['id']) - l3_agents_2 = self._list_l3_agents_hosting_router( - r2['router']['id']) - self.assertFalse(len(ret_a)) - self.assertNotIn(r1['router']['id'], [r['id'] for r in ret_a]) - self.assertNotIn(r2['router']['id'], [r['id'] for r in ret_a]) - self.assertFalse(len(l3_agents_1['agents'])) - self.assertFalse(len(l3_agents_2['agents'])) - - def test_add_router_to_l3_agent_for_openflow_router(self): - with self.router(arg_list=('provider',), provider='openflow') as r1: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - self._add_router_to_l3_agent(hosta_id, - r1['router']['id'], - expected_code=409) diff --git a/neutron/tests/unit/nec/test_config.py b/neutron/tests/unit/nec/test_config.py deleted file mode 100644 index 9d9fad521..000000000 --- a/neutron/tests/unit/nec/test_config.py +++ /dev/null @@ -1,44 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012 NEC Corporation. All rights reserved. -# -# 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. -# @author: Ryota MIBU - -from neutron.plugins.nec.common import config -from neutron.tests import base - - -class ConfigurationTest(base.BaseTestCase): - - def test_defaults(self): - self.assertEqual('br-int', config.CONF.OVS.integration_bridge) - self.assertEqual(2, config.CONF.AGENT.polling_interval) - self.assertEqual('sudo', config.CONF.AGENT.root_helper) - - self.assertEqual('127.0.0.1', config.CONF.OFC.host) - self.assertEqual('8888', config.CONF.OFC.port) - # Check path_prefix is an empty string explicitly. - self.assertEqual('', config.CONF.OFC.path_prefix) - self.assertEqual('trema', config.CONF.OFC.driver) - self.assertTrue(config.CONF.OFC.enable_packet_filter) - self.assertFalse(config.CONF.OFC.use_ssl) - self.assertIsNone(config.CONF.OFC.key_file) - self.assertIsNone(config.CONF.OFC.cert_file) - - def test_shortcuts(self): - self.assertEqual(config.CONF.OVS.integration_bridge, - config.OVS.integration_bridge) - self.assertEqual(config.CONF.AGENT.polling_interval, - config.AGENT.polling_interval) - self.assertEqual(config.CONF.OFC.host, config.OFC.host) diff --git a/neutron/tests/unit/nec/test_db.py b/neutron/tests/unit/nec/test_db.py deleted file mode 100644 index e3b886907..000000000 --- a/neutron/tests/unit/nec/test_db.py +++ /dev/null @@ -1,176 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 NEC Corporation. All rights reserved. -# -# 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. -# @author: Ryota MIBU - -import contextlib -import random - -from neutron.common import constants as q_const -from neutron.openstack.common import uuidutils -from neutron.plugins.nec.common import exceptions as nexc -from neutron.plugins.nec.db import api as ndb -from neutron.plugins.nec.db import models as nmodels # noqa -from neutron.tests.unit.nec import test_nec_plugin - - -class NECPluginV2DBTestBase(test_nec_plugin.NecPluginV2TestCase): - """Class conisting of NECPluginV2 DB unit tests.""" - - def setUp(self): - """Setup for tests.""" - super(NECPluginV2DBTestBase, self).setUp() - self.session = self.context.session - - def get_ofc_item_random_params(self): - """create random parameters for ofc_item test.""" - ofc_id = uuidutils.generate_uuid() - neutron_id = uuidutils.generate_uuid() - none = uuidutils.generate_uuid() - return ofc_id, neutron_id, none - - @contextlib.contextmanager - def portinfo_random_params(self): - with self.port() as port: - params = {'port_id': port['port']['id'], - 'datapath_id': hex(random.randint(0, 0xffffffff)), - 'port_no': random.randint(1, 100), - 'vlan_id': random.randint(q_const.MIN_VLAN_TAG, - q_const.MAX_VLAN_TAG), - 'mac': ':'.join(["%02x" % random.randint(0, 0xff) - for x in range(6)]) - } - yield params - - -class NECPluginV2DBOfcMappingTest(NECPluginV2DBTestBase): - - def test_add_ofc_item(self): - """test add OFC item.""" - o, q, n = self.get_ofc_item_random_params() - tenant = ndb.add_ofc_item(self.session, 'ofc_tenant', q, o) - self.assertEqual(tenant.ofc_id, o) - self.assertEqual(tenant.neutron_id, q) - - def test_add_ofc_item_duplicate_entry(self): - o, q, n = self.get_ofc_item_random_params() - ndb.add_ofc_item(self.session, 'ofc_tenant', q, o) - self.assertRaises(nexc.NECDBException, - ndb.add_ofc_item, - self.session, 'ofc_tenant', q, o) - - def test_get_ofc_item(self): - o, q, n = self.get_ofc_item_random_params() - ndb.add_ofc_item(self.session, 'ofc_tenant', q, o) - tenant = ndb.get_ofc_item(self.session, 'ofc_tenant', q) - self.assertEqual(tenant.ofc_id, o) - self.assertEqual(tenant.neutron_id, q) - - def test_get_ofc_item_for_nonexisting_entry(self): - self.assertIsNone( - ndb.get_ofc_item(self.session, 'ofc_tenant', 'non-exist-id')) - - def test_get_ofc_id(self): - o, q, n = self.get_ofc_item_random_params() - ndb.add_ofc_item(self.session, 'ofc_tenant', q, o) - tenant_id = ndb.get_ofc_id(self.session, 'ofc_tenant', q) - self.assertEqual(tenant_id, o) - - def test_get_ofc_id_for_nonexisting_entry(self): - self.assertRaises(nexc.OFCMappingNotFound, - ndb.get_ofc_id, - self.session, 'ofc_tenant', 'non-exist-id') - - def test_exists_ofc_item(self): - o, q, n = self.get_ofc_item_random_params() - self.assertFalse(ndb.exists_ofc_item(self.session, 'ofc_tenant', q)) - - ndb.add_ofc_item(self.session, 'ofc_tenant', q, o) - self.assertTrue(ndb.exists_ofc_item(self.session, 'ofc_tenant', q)) - - ndb.del_ofc_item(self.session, 'ofc_tenant', q) - self.assertFalse(ndb.exists_ofc_item(self.session, 'ofc_tenant', q)) - - def test_find_ofc_item(self): - o, q, n = self.get_ofc_item_random_params() - ndb.add_ofc_item(self.session, 'ofc_tenant', q, o) - tenant = ndb.find_ofc_item(self.session, 'ofc_tenant', o) - self.assertEqual(tenant.ofc_id, o) - self.assertEqual(tenant.neutron_id, q) - - def test_find_ofc_item_for_nonexisting_entry(self): - self.assertIsNone( - ndb.find_ofc_item(self.session, 'ofc_tenant', 'non-existi-id')) - - def test_del_ofc_item(self): - o, q, n = self.get_ofc_item_random_params() - ndb.add_ofc_item(self.session, 'ofc_tenant', q, o) - self.assertTrue(ndb.del_ofc_item(self.session, 'ofc_tenant', q)) - - self.assertIsNone(ndb.get_ofc_item(self.session, 'ofc_tenant', q)) - self.assertIsNone(ndb.find_ofc_item(self.session, 'ofc_tenant', o)) - - def test_del_ofc_item_for_nonexisting_entry(self): - self.assertFalse( - ndb.del_ofc_item(self.session, 'ofc_tenant', 'non-existi-id')) - - -class NECPluginV2DBPortInfoTest(NECPluginV2DBTestBase): - - def _compare_portinfo(self, portinfo, expected): - self.assertEqual(portinfo.id, expected['port_id']) - self.assertEqual(portinfo.datapath_id, expected['datapath_id']) - self.assertEqual(portinfo.port_no, expected['port_no']) - self.assertEqual(portinfo.vlan_id, expected['vlan_id']) - self.assertEqual(portinfo.mac, expected['mac']) - - def _add_portinfo(self, session, params): - return ndb.add_portinfo(session, params['port_id'], - params['datapath_id'], params['port_no'], - params['vlan_id'], params['mac']) - - def testd_add_portinfo(self): - """test add portinfo.""" - with self.portinfo_random_params() as params: - portinfo = self._add_portinfo(self.session, params) - self._compare_portinfo(portinfo, params) - - exception_raised = False - try: - self._add_portinfo(self.session, params) - except nexc.NECDBException: - exception_raised = True - self.assertTrue(exception_raised) - - def teste_get_portinfo(self): - """test get portinfo.""" - with self.portinfo_random_params() as params: - self._add_portinfo(self.session, params) - portinfo = ndb.get_portinfo(self.session, params['port_id']) - self._compare_portinfo(portinfo, params) - - nonexist_id = uuidutils.generate_uuid() - portinfo_none = ndb.get_portinfo(self.session, nonexist_id) - self.assertIsNone(portinfo_none) - - def testf_del_portinfo(self): - """test delete portinfo.""" - with self.portinfo_random_params() as params: - self._add_portinfo(self.session, params) - portinfo = ndb.get_portinfo(self.session, params['port_id']) - self.assertEqual(portinfo.id, params['port_id']) - ndb.del_portinfo(self.session, params['port_id']) - portinfo_none = ndb.get_portinfo(self.session, params['port_id']) - self.assertIsNone(portinfo_none) diff --git a/neutron/tests/unit/nec/test_nec_agent.py b/neutron/tests/unit/nec/test_nec_agent.py deleted file mode 100644 index 26396aeb9..000000000 --- a/neutron/tests/unit/nec/test_nec_agent.py +++ /dev/null @@ -1,366 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 NEC Corporation. All rights reserved. -# -# 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 contextlib -import copy -import itertools -import time - -import mock -from oslo.config import cfg -from six import moves -import testtools - -from neutron.agent.linux import ovs_lib -from neutron.extensions import securitygroup as ext_sg -from neutron.plugins.nec.agent import nec_neutron_agent -from neutron.tests import base - -DAEMON_LOOP_COUNT = 10 -OVS_DPID = '00000629355b6943' -OVS_DPID_0X = '0x' + OVS_DPID - - -class TestNecAgentBase(base.BaseTestCase): - - def setUp(self): - super(TestNecAgentBase, self).setUp() - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - cfg.CONF.set_override('host', 'dummy-host') - with contextlib.nested( - mock.patch.object(ovs_lib.OVSBridge, 'get_datapath_id', - return_value=OVS_DPID), - mock.patch('socket.gethostname', return_value='dummy-host'), - mock.patch('neutron.openstack.common.loopingcall.' - 'FixedIntervalLoopingCall'), - mock.patch('neutron.agent.rpc.PluginReportStateAPI') - ) as (get_datapath_id, gethostname, - loopingcall, state_rpc_api): - kwargs = {'integ_br': 'integ_br', - 'root_helper': 'dummy_wrapper', - 'polling_interval': 1} - self.agent = nec_neutron_agent.NECNeutronAgent(**kwargs) - self.loopingcall = loopingcall - self.state_rpc_api = state_rpc_api - - -class TestNecAgent(TestNecAgentBase): - - def _setup_mock(self): - vif_ports = [ovs_lib.VifPort('port1', '1', 'id-1', 'mac-1', - self.agent.int_br), - ovs_lib.VifPort('port2', '2', 'id-2', 'mac-2', - self.agent.int_br)] - self.get_vif_ports = mock.patch.object( - ovs_lib.OVSBridge, 'get_vif_ports', - return_value=vif_ports).start() - self.update_ports = mock.patch.object( - nec_neutron_agent.NECPluginApi, 'update_ports').start() - self.prepare_devices_filter = mock.patch.object( - self.agent.sg_agent, 'prepare_devices_filter').start() - self.remove_devices_filter = mock.patch.object( - self.agent.sg_agent, 'remove_devices_filter').start() - - def _test_single_loop(self, with_exc=False, need_sync=False): - self.agent.cur_ports = ['id-0', 'id-1'] - self.agent.need_sync = need_sync - - self.agent.loop_handler() - if with_exc: - self.assertEqual(self.agent.cur_ports, ['id-0', 'id-1']) - self.assertTrue(self.agent.need_sync) - else: - self.assertEqual(self.agent.cur_ports, ['id-1', 'id-2']) - self.assertFalse(self.agent.need_sync) - - def test_single_loop_normal(self): - self._setup_mock() - self._test_single_loop() - agent_id = 'nec-q-agent.dummy-host' - self.update_ports.assert_called_once_with( - mock.ANY, agent_id, OVS_DPID_0X, - [{'id': 'id-2', 'mac': 'mac-2', 'port_no': '2'}], - ['id-0']) - self.prepare_devices_filter.assert_called_once_with(['id-2']) - self.remove_devices_filter.assert_called_once_with(['id-0']) - - def test_single_loop_need_sync(self): - self._setup_mock() - self._test_single_loop(need_sync=True) - agent_id = 'nec-q-agent.dummy-host' - self.update_ports.assert_called_once_with( - mock.ANY, agent_id, OVS_DPID_0X, - [{'id': 'id-1', 'mac': 'mac-1', 'port_no': '1'}, - {'id': 'id-2', 'mac': 'mac-2', 'port_no': '2'}], - []) - self.prepare_devices_filter.assert_called_once_with(['id-1', 'id-2']) - self.assertFalse(self.remove_devices_filter.call_count) - - def test_single_loop_with_sg_exception_remove(self): - self._setup_mock() - self.update_ports.side_effect = Exception() - self._test_single_loop(with_exc=True) - - def test_single_loop_with_sg_exception_prepare(self): - self._setup_mock() - self.prepare_devices_filter.side_effect = Exception() - self._test_single_loop(with_exc=True) - - def test_single_loop_with_update_ports_exception(self): - self._setup_mock() - self.remove_devices_filter.side_effect = Exception() - self._test_single_loop(with_exc=True) - - def test_daemon_loop(self): - - def state_check(index): - self.assertEqual(len(self.vif_ports_scenario[index]), - len(self.agent.cur_ports)) - - # Fake time.sleep to stop the infinite loop in daemon_loop() - self.sleep_count = 0 - - def sleep_mock(*args, **kwargs): - state_check(self.sleep_count) - self.sleep_count += 1 - if self.sleep_count >= DAEMON_LOOP_COUNT: - raise RuntimeError() - - vif_ports = [ovs_lib.VifPort('port1', '1', 'id-1', 'mac-1', - self.agent.int_br), - ovs_lib.VifPort('port2', '2', 'id-2', 'mac-2', - self.agent.int_br)] - - self.vif_ports_scenario = [[], [], vif_ports[0:1], vif_ports[0:2], - vif_ports[1:2], []] - - # Ensure vif_ports_scenario is longer than DAEMON_LOOP_COUNT - if len(self.vif_ports_scenario) < DAEMON_LOOP_COUNT: - self.vif_ports_scenario.extend( - [] for _i in moves.xrange(DAEMON_LOOP_COUNT - - len(self.vif_ports_scenario))) - - with contextlib.nested( - mock.patch.object(time, 'sleep', side_effect=sleep_mock), - mock.patch.object(ovs_lib.OVSBridge, 'get_vif_ports'), - mock.patch.object(nec_neutron_agent.NECPluginApi, 'update_ports'), - mock.patch.object(self.agent.sg_agent, 'prepare_devices_filter'), - mock.patch.object(self.agent.sg_agent, 'remove_devices_filter') - ) as (sleep, get_vif_potrs, update_ports, - prepare_devices_filter, remove_devices_filter): - get_vif_potrs.side_effect = self.vif_ports_scenario - - with testtools.ExpectedException(RuntimeError): - self.agent.daemon_loop() - self.assertEqual(update_ports.call_count, 4) - self.assertEqual(sleep.call_count, DAEMON_LOOP_COUNT) - - agent_id = 'nec-q-agent.dummy-host' - expected = [ - mock.call(mock.ANY, agent_id, OVS_DPID_0X, - [{'id': 'id-1', 'mac': 'mac-1', 'port_no': '1'}], - []), - mock.call(mock.ANY, agent_id, OVS_DPID_0X, - [{'id': 'id-2', 'mac': 'mac-2', 'port_no': '2'}], - []), - mock.call(mock.ANY, agent_id, OVS_DPID_0X, - [], ['id-1']), - mock.call(mock.ANY, agent_id, OVS_DPID_0X, - [], ['id-2']) - ] - update_ports.assert_has_calls(expected) - - expected = [mock.call(['id-1']), - mock.call(['id-2'])] - self.assertEqual(prepare_devices_filter.call_count, 2) - prepare_devices_filter.assert_has_calls(expected) - self.assertEqual(remove_devices_filter.call_count, 2) - remove_devices_filter.assert_has_calls(expected) - - sleep.assert_called_with(self.agent.polling_interval) - - def test_report_state_installed(self): - self.loopingcall.assert_called_once_with(self.agent._report_state) - instance = self.loopingcall.return_value - self.assertTrue(instance.start.called) - - def _check_report_state(self, cur_ports, num_ports, fail_mode, - first=False): - self.assertEqual(first or fail_mode, - 'start_flag' in self.agent.agent_state) - self.agent.cur_ports = cur_ports - - self.agent._report_state() - - self.assertEqual(fail_mode, - 'start_flag' in self.agent.agent_state) - self.assertEqual(self.agent. - agent_state['configurations']['devices'], - num_ports) - self.num_ports_hist.append(num_ports) - - def _test_report_state(self, fail_mode): - log_mocked = mock.patch.object(nec_neutron_agent, 'LOG') - log_patched = log_mocked.start() - - def record_state(*args, **kwargs): - self.record_calls.append(copy.deepcopy(args)) - if fail_mode: - raise Exception() - - self.record_calls = [] - self.num_ports_hist = [] - state_rpc = self.state_rpc_api.return_value - state_rpc.report_state.side_effect = record_state - dummy_vif = ovs_lib.VifPort('port1', '1', 'id-1', 'mac-1', None) - - self.state_rpc_api.assert_called_once_with('q-plugin') - self.assertIn('start_flag', self.agent.agent_state) - - self._check_report_state([], 0, fail_mode, first=True) - self._check_report_state([dummy_vif] * 2, 2, fail_mode) - self._check_report_state([dummy_vif] * 5, 5, fail_mode) - self._check_report_state([], 0, fail_mode) - - # Since loopingcall start is mocked, call_count is same as - # the call count of check_report_state. - self.assertEqual(state_rpc.report_state.call_count, 4) - self.assertEqual(len(self.record_calls), 4) - - for i, x in enumerate(itertools.izip(self.record_calls, - self.num_ports_hist)): - rec, num_ports = x - expected_state = { - 'binary': 'neutron-nec-agent', - 'host': 'dummy-host', - 'topic': 'N/A', - 'configurations': {'devices': 0}, - 'agent_type': 'NEC plugin agent'} - expected_state['configurations']['devices'] = num_ports - if i == 0 or fail_mode: - expected_state['start_flag'] = True - self.assertEqual(expected_state, rec[1]) - - self.assertEqual(fail_mode, log_patched.exception.called) - - def test_report_state(self): - self._test_report_state(fail_mode=False) - - def test_report_state_fail(self): - self._test_report_state(fail_mode=True) - - -class TestNecAgentCallback(TestNecAgentBase): - - def test_port_update(self): - with contextlib.nested( - mock.patch.object(ovs_lib.OVSBridge, 'get_vif_port_by_id'), - mock.patch.object(self.agent.sg_agent, 'refresh_firewall') - ) as (get_vif_port_by_id, refresh_firewall): - context = mock.Mock() - vifport = ovs_lib.VifPort('port1', '1', 'id-1', 'mac-1', - self.agent.int_br) - - # The OVS port does not exist. - get_vif_port_by_id.return_value = None - port = {'id': 'update-port-1'} - self.agent.callback_nec.port_update(context, port=port) - self.assertEqual(get_vif_port_by_id.call_count, 1) - self.assertFalse(refresh_firewall.call_count) - - # The OVS port exists but no security group is associated. - get_vif_port_by_id.return_value = vifport - port = {'id': 'update-port-1'} - self.agent.callback_nec.port_update(context, port=port) - self.assertEqual(get_vif_port_by_id.call_count, 2) - self.assertFalse(refresh_firewall.call_count) - - # The OVS port exists but a security group is associated. - get_vif_port_by_id.return_value = vifport - port = {'id': 'update-port-1', - ext_sg.SECURITYGROUPS: ['default']} - self.agent.callback_nec.port_update(context, port=port) - self.assertEqual(get_vif_port_by_id.call_count, 3) - self.assertEqual(refresh_firewall.call_count, 1) - - get_vif_port_by_id.return_value = None - port = {'id': 'update-port-1', - ext_sg.SECURITYGROUPS: ['default']} - self.agent.callback_nec.port_update(context, port=port) - self.assertEqual(get_vif_port_by_id.call_count, 4) - self.assertEqual(refresh_firewall.call_count, 1) - - -class TestNecAgentPluginApi(TestNecAgentBase): - - def _test_plugin_api(self, expected_failure=False): - with contextlib.nested( - mock.patch.object(nec_neutron_agent.NECPluginApi, 'make_msg'), - mock.patch.object(nec_neutron_agent.NECPluginApi, 'call'), - mock.patch.object(nec_neutron_agent, 'LOG') - ) as (make_msg, apicall, log): - agent_id = 'nec-q-agent.dummy-host' - if expected_failure: - apicall.side_effect = Exception() - - self.agent.plugin_rpc.update_ports( - mock.sentinel.ctx, agent_id, OVS_DPID_0X, - # port_added - [{'id': 'id-1', 'mac': 'mac-1', 'port_no': '1'}, - {'id': 'id-2', 'mac': 'mac-2', 'port_no': '2'}], - # port_removed - ['id-3', 'id-4', 'id-5']) - - make_msg.assert_called_once_with( - 'update_ports', topic='q-agent-notifier', - agent_id=agent_id, datapath_id=OVS_DPID_0X, - port_added=[{'id': 'id-1', 'mac': 'mac-1', 'port_no': '1'}, - {'id': 'id-2', 'mac': 'mac-2', 'port_no': '2'}], - port_removed=['id-3', 'id-4', 'id-5']) - - apicall.assert_called_once_with(mock.sentinel.ctx, - make_msg.return_value) - - self.assertTrue(log.info.called) - if expected_failure: - self.assertTrue(log.warn.called) - - def test_plugin_api(self): - self._test_plugin_api() - - -class TestNecAgentMain(base.BaseTestCase): - def test_main(self): - with contextlib.nested( - mock.patch.object(nec_neutron_agent, 'NECNeutronAgent'), - mock.patch.object(nec_neutron_agent, 'common_config'), - mock.patch.object(nec_neutron_agent, 'config') - ) as (agent, common_config, cfg): - cfg.OVS.integration_bridge = 'br-int-x' - cfg.AGENT.root_helper = 'dummy-helper' - cfg.AGENT.polling_interval = 10 - - nec_neutron_agent.main() - - self.assertTrue(common_config.setup_logging.called) - agent.assert_has_calls([ - mock.call('br-int-x', 'dummy-helper', 10), - mock.call().daemon_loop() - ]) diff --git a/neutron/tests/unit/nec/test_nec_plugin.py b/neutron/tests/unit/nec/test_nec_plugin.py deleted file mode 100644 index 0a012b793..000000000 --- a/neutron/tests/unit/nec/test_nec_plugin.py +++ /dev/null @@ -1,930 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 os - -import fixtures -import mock -import webob.exc - -from neutron.common import constants -from neutron.common import test_lib -from neutron.common import topics -from neutron import context -from neutron.db import db_base_plugin_v2 -from neutron import manager -from neutron.plugins.nec.common import exceptions as nexc -from neutron.plugins.nec.db import api as ndb -from neutron.plugins.nec import nec_plugin -from neutron.tests.unit.nec import fake_ofc_manager -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_extension_allowedaddresspairs as test_pair - - -PLUGIN_NAME = 'neutron.plugins.nec.nec_plugin.NECPluginV2' -OFC_MANAGER = 'neutron.plugins.nec.nec_plugin.ofc_manager.OFCManager' -NOTIFIER = 'neutron.plugins.nec.nec_plugin.NECPluginV2AgentNotifierApi' -NEC_PLUGIN_INI = """ -[DEFAULT] -api_extensions_path = neutron/plugins/nec/extensions -[OFC] -driver = neutron.tests.unit.nec.stub_ofc_driver.StubOFCDriver -enable_packet_filter = False -""" - - -class NecPluginV2TestCaseBase(object): - _nec_ini = NEC_PLUGIN_INI - - def _set_nec_ini(self): - self.nec_ini_file = self.useFixture(fixtures.TempDir()).join("nec.ini") - with open(self.nec_ini_file, 'w') as f: - f.write(self._nec_ini) - if 'config_files' in test_lib.test_config.keys(): - for c in test_lib.test_config['config_files']: - if c.rfind("/nec.ini") > -1: - test_lib.test_config['config_files'].remove(c) - test_lib.test_config['config_files'].append(self.nec_ini_file) - else: - test_lib.test_config['config_files'] = [self.nec_ini_file] - - def _clean_nec_ini(self): - test_lib.test_config['config_files'].remove(self.nec_ini_file) - os.remove(self.nec_ini_file) - self.nec_ini_file = None - - def patch_remote_calls(self): - self.plugin_notifier_p = mock.patch(NOTIFIER) - self.ofc_manager_p = mock.patch(OFC_MANAGER) - self.plugin_notifier_p.start() - self.ofc_manager_p.start() - - def setup_nec_plugin_base(self): - self._set_nec_ini() - self.addCleanup(self._clean_nec_ini) - self.patch_remote_calls() - - -class NecPluginV2TestCase(NecPluginV2TestCaseBase, - test_plugin.NeutronDbPluginV2TestCase): - - _plugin_name = PLUGIN_NAME - - def rpcapi_update_ports(self, agent_id='nec-q-agent.fake', - datapath_id="0xabc", added=[], removed=[]): - kwargs = {'topic': topics.AGENT, - 'agent_id': agent_id, - 'datapath_id': datapath_id, - 'port_added': added, 'port_removed': removed} - self.callback_nec.update_ports(self.context, **kwargs) - - def setUp(self, plugin=None, ext_mgr=None): - - self._set_nec_ini() - self.addCleanup(self._clean_nec_ini) - plugin = plugin or self._plugin_name - super(NecPluginV2TestCase, self).setUp(plugin, ext_mgr=ext_mgr) - - self.plugin = manager.NeutronManager.get_plugin() - self.plugin.ofc = fake_ofc_manager.patch_ofc_manager() - self.ofc = self.plugin.ofc - self.callback_nec = nec_plugin.NECPluginV2RPCCallbacks(self.plugin) - self.context = context.get_admin_context() - self.net_create_status = 'ACTIVE' - self.port_create_status = 'DOWN' - - -class TestNecBasicGet(test_plugin.TestBasicGet, NecPluginV2TestCase): - pass - - -class TestNecV2HTTPResponse(test_plugin.TestV2HTTPResponse, - NecPluginV2TestCase): - pass - - -class TestNecNetworksV2(test_plugin.TestNetworksV2, NecPluginV2TestCase): - pass - - -class TestNecPortsV2Callback(NecPluginV2TestCase): - - def _get_portinfo(self, port_id): - return ndb.get_portinfo(self.context.session, port_id) - - def test_portinfo_create(self): - with self.port() as port: - port_id = port['port']['id'] - sport = self.plugin.get_port(self.context, port_id) - self.assertEqual(sport['status'], 'DOWN') - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - self.assertIsNone(self._get_portinfo(port_id)) - - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - - sport = self.plugin.get_port(self.context, port_id) - self.assertEqual(sport['status'], 'ACTIVE') - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertIsNotNone(self._get_portinfo(port_id)) - - expected = [ - mock.call.exists_ofc_port(mock.ANY, port_id), - mock.call.create_ofc_port(mock.ANY, port_id, mock.ANY), - ] - self.ofc.assert_has_calls(expected) - - def test_portinfo_delete_before_port_deletion(self): - self._test_portinfo_delete() - - def test_portinfo_delete_after_port_deletion(self): - self._test_portinfo_delete(portinfo_delete_first=False) - - def _test_portinfo_delete(self, portinfo_delete_first=True): - with self.port() as port: - port_id = port['port']['id'] - portinfo = {'id': port_id, 'port_no': 456} - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - self.assertIsNone(self._get_portinfo(port_id)) - - self.rpcapi_update_ports(added=[portinfo]) - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - self.assertIsNotNone(self._get_portinfo(port_id)) - - # Before port-deletion, switch port removed message is sent. - if portinfo_delete_first: - self.rpcapi_update_ports(removed=[port_id]) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - self.assertIsNone(self._get_portinfo(port_id)) - - # The port and portinfo is expected to delete when exiting with-clause. - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - self.assertIsNone(self._get_portinfo(port_id)) - if not portinfo_delete_first: - self.rpcapi_update_ports(removed=[port_id]) - - # Ensure port deletion is called once. - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - self.assertIsNone(self._get_portinfo(port_id)) - - expected = [ - mock.call.exists_ofc_port(mock.ANY, port_id), - mock.call.create_ofc_port(mock.ANY, port_id, mock.ANY), - mock.call.exists_ofc_port(mock.ANY, port_id), - mock.call.delete_ofc_port(mock.ANY, port_id, mock.ANY), - ] - self.ofc.assert_has_calls(expected) - - def test_portinfo_added_unknown_port(self): - portinfo = {'id': 'dummy-p1', 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - self.assertIsNone(ndb.get_portinfo(self.context.session, - 'dummy-p1')) - self.assertEqual(self.ofc.exists_ofc_port.call_count, 0) - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - - def _test_portinfo_change(self, portinfo_change_first=True): - with self.port() as port: - port_id = port['port']['id'] - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - self.assertEqual(ndb.get_portinfo(self.context.session, - port_id).port_no, 123) - - if portinfo_change_first: - portinfo = {'id': port_id, 'port_no': 456} - self.rpcapi_update_ports(added=[portinfo]) - # OFC port is recreated. - self.assertEqual(self.ofc.create_ofc_port.call_count, 2) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - self.assertEqual(ndb.get_portinfo(self.context.session, - port_id).port_no, 456) - - if not portinfo_change_first: - # The port is expected to delete when exiting with-clause. - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - - portinfo = {'id': port_id, 'port_no': 456} - self.rpcapi_update_ports(added=[portinfo]) - # No OFC operations are expected. - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - self.assertIsNone(ndb.get_portinfo(self.context.session, port_id)) - - def test_portinfo_change(self): - self._test_portinfo_change() - - def test_portinfo_change_for_nonexisting_port(self): - self._test_portinfo_change(portinfo_change_first=False) - - def test_port_migration(self): - agent_id_a, datapath_id_a, port_no_a = 'nec-q-agent.aa', '0xaaa', 10 - agent_id_b, datapath_id_b, port_no_b = 'nec-q-agent.bb', '0xbbb', 11 - - with self.port() as port: - port_id = port['port']['id'] - sport = self.plugin.get_port(self.context, port_id) - self.assertEqual(sport['status'], 'DOWN') - - portinfo_a = {'id': port_id, 'port_no': port_no_a} - self.rpcapi_update_ports(agent_id=agent_id_a, - datapath_id=datapath_id_a, - added=[portinfo_a]) - - portinfo_b = {'id': port_id, 'port_no': port_no_b} - self.rpcapi_update_ports(agent_id=agent_id_b, - datapath_id=datapath_id_b, - added=[portinfo_b]) - - self.rpcapi_update_ports(agent_id=agent_id_a, - datapath_id=datapath_id_a, - removed=[port_id]) - - sport = self.plugin.get_port(self.context, port_id) - self.assertEqual(sport['status'], 'ACTIVE') - self.assertTrue(self.ofc.ofc_ports[port_id]) - - expected = [ - mock.call.exists_ofc_port(mock.ANY, port_id), - mock.call.create_ofc_port(mock.ANY, port_id, mock.ANY), - mock.call.exists_ofc_port(mock.ANY, port_id), - mock.call.delete_ofc_port(mock.ANY, port_id, mock.ANY), - mock.call.exists_ofc_port(mock.ANY, port_id), - mock.call.create_ofc_port(mock.ANY, port_id, mock.ANY), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(2, self.ofc.create_ofc_port.call_count) - self.assertEqual(1, self.ofc.delete_ofc_port.call_count) - - def test_portinfo_readd(self): - with self.port() as port: - port_id = port['port']['id'] - self.plugin.get_port(self.context, port_id) - - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - - sport = self.plugin.get_port(self.context, port_id) - self.assertEqual(sport['status'], 'ACTIVE') - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - self.assertIsNotNone(self._get_portinfo(port_id)) - - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - - sport = self.plugin.get_port(self.context, port_id) - self.assertEqual(sport['status'], 'ACTIVE') - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - self.assertIsNotNone(self._get_portinfo(port_id)) - - -class TestNecPluginDbTest(NecPluginV2TestCase): - - def test_update_resource(self): - with self.network() as network: - self.assertEqual("ACTIVE", network['network']['status']) - net_id = network['network']['id'] - for status in ["DOWN", "BUILD", "ERROR", "ACTIVE"]: - self.plugin._update_resource_status( - self.context, 'network', net_id, - getattr(constants, 'NET_STATUS_%s' % status)) - n = self.plugin._get_network(self.context, net_id) - self.assertEqual(status, n.status) - - -class TestNecPluginOfcManager(NecPluginV2TestCase): - def setUp(self): - super(TestNecPluginOfcManager, self).setUp() - self.ofc = self.plugin.ofc - - def _create_resource(self, resource, data): - collection = resource + 's' - data = {resource: data} - req = self.new_create_request(collection, data) - res = self.deserialize(self.fmt, req.get_response(self.api)) - return res[resource] - - def _update_resource(self, resource, id, data): - collection = resource + 's' - data = {resource: data} - req = self.new_update_request(collection, data, id) - res = self.deserialize(self.fmt, req.get_response(self.api)) - return res[resource] - - def _show_resource(self, resource, id): - collection = resource + 's' - req = self.new_show_request(collection, id) - res = self.deserialize(self.fmt, req.get_response(self.api)) - return res[resource] - - def _list_resource(self, resource): - collection = resource + 's' - req = self.new_list_request(collection) - res = req.get_response(self.api) - return res[collection] - - def _delete_resource(self, resource, id): - collection = resource + 's' - req = self.new_delete_request(collection, id) - res = req.get_response(self.api) - return res.status_int - - def test_create_network(self): - net = None - ctx = mock.ANY - with self.network() as network: - net = network['network'] - self.assertEqual(network['network']['status'], 'ACTIVE') - - expected = [ - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, net['id'], - net['name']), - mock.call.exists_ofc_network(ctx, net['id']), - mock.call.delete_ofc_network(ctx, net['id'], mock.ANY), - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.delete_ofc_tenant(ctx, self._tenant_id) - ] - self.ofc.assert_has_calls(expected) - - def test_create_network_with_admin_state_down(self): - net = None - ctx = mock.ANY - with self.network(admin_state_up=False) as network: - net = network['network'] - self.assertEqual(network['network']['status'], 'DOWN') - - expected = [ - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, net['id'], - net['name']), - mock.call.exists_ofc_network(ctx, net['id']), - mock.call.delete_ofc_network(ctx, net['id'], mock.ANY), - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.delete_ofc_tenant(ctx, self._tenant_id) - ] - self.ofc.assert_has_calls(expected) - - def test_create_two_network(self): - nets = [] - ctx = mock.ANY - with self.network() as net1: - nets.append(net1['network']) - self.assertEqual(net1['network']['status'], 'ACTIVE') - with self.network() as net2: - nets.append(net2['network']) - self.assertEqual(net2['network']['status'], 'ACTIVE') - - expected = [ - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, nets[0]['id'], - nets[0]['name']), - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, nets[1]['id'], - nets[1]['name']), - mock.call.exists_ofc_network(ctx, nets[1]['id']), - mock.call.delete_ofc_network(ctx, nets[1]['id'], mock.ANY), - mock.call.exists_ofc_network(ctx, nets[0]['id']), - mock.call.delete_ofc_network(ctx, nets[0]['id'], mock.ANY), - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.delete_ofc_tenant(ctx, self._tenant_id) - ] - self.ofc.assert_has_calls(expected) - - def test_create_network_fail(self): - self.ofc.create_ofc_network.side_effect = nexc.OFCException( - reason='hoge') - - net = None - ctx = mock.ANY - # NOTE: We don't delete network through api, but db will be cleaned in - # tearDown(). When OFCManager has failed to create a network on OFC, - # it does not keeps ofc_network entry and will fail to delete this - # network from OFC. Deletion of network is not the scope of this test. - with self.network(do_delete=False) as network: - net = network['network'] - self.assertEqual(net['status'], 'ERROR') - net_ref = self._show('networks', net['id']) - self.assertEqual(net_ref['network']['status'], 'ERROR') - - expected = [ - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, net['id'], - net['name']) - ] - self.ofc.assert_has_calls(expected) - - def test_update_network(self): - net = None - ctx = mock.ANY - with self.network() as network: - net = network['network'] - self.assertEqual(network['network']['status'], 'ACTIVE') - - net_ref = self._show('networks', net['id']) - self.assertEqual(net_ref['network']['status'], 'ACTIVE') - - # Set admin_state_up to False - res = self._update_resource('network', net['id'], - {'admin_state_up': False}) - self.assertFalse(res['admin_state_up']) - self.assertEqual(res['status'], 'DOWN') - - net_ref = self._show('networks', net['id']) - self.assertEqual(net_ref['network']['status'], 'DOWN') - - # Set admin_state_up to True - res = self._update_resource('network', net['id'], - {'admin_state_up': True}) - self.assertTrue(res['admin_state_up']) - self.assertEqual(res['status'], 'ACTIVE') - - net_ref = self._show('networks', net['id']) - self.assertEqual(net_ref['network']['status'], 'ACTIVE') - - expected = [ - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, net['id'], - net['name']), - mock.call.exists_ofc_network(ctx, net['id']), - mock.call.delete_ofc_network(ctx, net['id'], mock.ANY), - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.delete_ofc_tenant(ctx, self._tenant_id) - ] - self.ofc.assert_has_calls(expected) - - def test_create_port_no_ofc_creation(self): - net = None - p1 = None - ctx = mock.ANY - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - p1 = port['port'] - net_id = port['port']['network_id'] - net = self._show_resource('network', net_id) - self.assertEqual(net['status'], 'ACTIVE') - self.assertEqual(p1['status'], 'DOWN') - - p1_ref = self._show('ports', p1['id']) - self.assertEqual(p1_ref['port']['status'], 'DOWN') - - expected = [ - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, net['id'], - net['name']), - - mock.call.exists_ofc_port(ctx, p1['id']), - mock.call.exists_ofc_network(ctx, net['id']), - mock.call.delete_ofc_network(ctx, net['id'], mock.ANY), - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.delete_ofc_tenant(ctx, self._tenant_id) - ] - self.ofc.assert_has_calls(expected) - - def test_create_port_with_ofc_creation(self): - net = None - p1 = None - ctx = mock.ANY - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - p1 = port['port'] - net_id = port['port']['network_id'] - net = self._show_resource('network', net_id) - self.assertEqual(net['status'], 'ACTIVE') - self.assertEqual(p1['status'], 'DOWN') - - p1_ref = self._show('ports', p1['id']) - self.assertEqual(p1_ref['port']['status'], 'DOWN') - - # Check the port is not created on OFC - self.assertFalse(self.ofc.create_ofc_port.call_count) - - # Register portinfo, then the port is created on OFC - portinfo = {'id': p1['id'], 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - - p1_ref = self._show('ports', p1['id']) - self.assertEqual(p1_ref['port']['status'], 'ACTIVE') - - expected = [ - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, net['id'], - net['name']), - - mock.call.exists_ofc_port(ctx, p1['id']), - mock.call.create_ofc_port(ctx, p1['id'], mock.ANY), - - mock.call.exists_ofc_port(ctx, p1['id']), - mock.call.delete_ofc_port(ctx, p1['id'], mock.ANY), - mock.call.exists_ofc_network(ctx, net['id']), - mock.call.delete_ofc_network(ctx, net['id'], mock.ANY), - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.delete_ofc_tenant(ctx, self._tenant_id) - ] - self.ofc.assert_has_calls(expected) - - def test_delete_network_with_dhcp_port(self): - ctx = mock.ANY - with self.network() as network: - with self.subnet(network=network): - net = network['network'] - p = self._create_resource( - 'port', - {'network_id': net['id'], - 'tenant_id': net['tenant_id'], - 'device_owner': constants.DEVICE_OWNER_DHCP, - 'device_id': 'dhcp-port1'}) - # Make sure that the port is created on OFC. - portinfo = {'id': p['id'], 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - # In a case of dhcp port, the port is deleted automatically - # when delete_network. - - expected = [ - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, - net['id'], net['name']), - mock.call.exists_ofc_port(ctx, p['id']), - mock.call.create_ofc_port(ctx, p['id'], mock.ANY), - mock.call.exists_ofc_port(ctx, p['id']), - mock.call.delete_ofc_port(ctx, p['id'], mock.ANY), - mock.call.exists_ofc_network(ctx, net['id']), - mock.call.delete_ofc_network(ctx, net['id'], mock.ANY), - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.delete_ofc_tenant(ctx, self._tenant_id) - ] - self.ofc.assert_has_calls(expected) - - def test_delete_network_with_error_status(self): - self.ofc.set_raise_exc('create_ofc_network', - nexc.OFCException(reason='fake error')) - - with self.network() as net: - net_id = net['network']['id'] - net_ref = self._show('networks', net_id) - self.assertEqual(net_ref['network']['status'], 'ERROR') - - ctx = mock.ANY - tenant_id = self._tenant_id - net_name = mock.ANY - net = mock.ANY - expected = [ - mock.call.exists_ofc_tenant(ctx, tenant_id), - mock.call.create_ofc_tenant(ctx, tenant_id), - mock.call.create_ofc_network(ctx, tenant_id, net_id, net_name), - mock.call.exists_ofc_network(ctx, net_id), - mock.call.exists_ofc_tenant(ctx, tenant_id), - mock.call.delete_ofc_tenant(ctx, tenant_id), - ] - self.ofc.assert_has_calls(expected) - self.assertFalse(self.ofc.delete_ofc_network.call_count) - - def test_delete_network_with_ofc_deletion_failure(self): - self.ofc.set_raise_exc('delete_ofc_network', - nexc.OFCException(reason='hoge')) - - with self.network() as net: - net_id = net['network']['id'] - - self._delete('networks', net_id, - expected_code=webob.exc.HTTPInternalServerError.code) - - net_ref = self._show('networks', net_id) - self.assertEqual(net_ref['network']['status'], 'ERROR') - - self.ofc.set_raise_exc('delete_ofc_network', None) - - ctx = mock.ANY - tenant = mock.ANY - net_name = mock.ANY - net = mock.ANY - expected = [ - mock.call.create_ofc_network(ctx, tenant, net_id, net_name), - mock.call.exists_ofc_network(ctx, net_id), - mock.call.delete_ofc_network(ctx, net_id, net), - mock.call.exists_ofc_network(ctx, net_id), - mock.call.delete_ofc_network(ctx, net_id, net), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.delete_ofc_network.call_count, 2) - - def test_delete_network_with_deactivating_auto_delete_port_failure(self): - self.ofc.set_raise_exc('delete_ofc_port', - nexc.OFCException(reason='hoge')) - - with self.network(do_delete=False) as net: - net_id = net['network']['id'] - - device_owner = db_base_plugin_v2.AUTO_DELETE_PORT_OWNERS[0] - port = self._make_port(self.fmt, net_id, device_owner=device_owner) - port_id = port['port']['id'] - - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - - self._delete('networks', net_id, - expected_code=webob.exc.HTTPInternalServerError.code) - - net_ref = self._show('networks', net_id) - self.assertEqual(net_ref['network']['status'], 'ACTIVE') - port_ref = self._show('ports', port_id) - self.assertEqual(port_ref['port']['status'], 'ERROR') - - self.ofc.set_raise_exc('delete_ofc_port', None) - self._delete('networks', net_id) - - ctx = mock.ANY - tenant = mock.ANY - net_name = mock.ANY - net = mock.ANY - port = mock.ANY - expected = [ - mock.call.create_ofc_network(ctx, tenant, net_id, net_name), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.create_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.delete_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.delete_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_network(ctx, net_id), - mock.call.delete_ofc_network(ctx, net_id, net) - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.delete_ofc_network.call_count, 1) - - def test_update_port(self): - self._test_update_port_with_admin_state(resource='port') - - def test_update_network_with_ofc_port(self): - self._test_update_port_with_admin_state(resource='network') - - def _test_update_port_with_admin_state(self, resource='port'): - net = None - p1 = None - ctx = mock.ANY - - if resource == 'network': - net_ini_admin_state = False - port_ini_admin_state = True - else: - net_ini_admin_state = True - port_ini_admin_state = False - - with self.network(admin_state_up=net_ini_admin_state) as network: - with self.subnet(network=network) as subnet: - with self.port(subnet=subnet, - admin_state_up=port_ini_admin_state) as port: - p1 = port['port'] - net_id = port['port']['network_id'] - res_id = net_id if resource == 'network' else p1['id'] - self.assertEqual(p1['status'], 'DOWN') - - net = self._show_resource('network', net_id) - - # Check the port is not created on OFC - self.assertFalse(self.ofc.create_ofc_port.call_count) - - # Register portinfo, then the port is created on OFC - portinfo = {'id': p1['id'], 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - self.assertFalse(self.ofc.create_ofc_port.call_count) - - res = self._update_resource(resource, res_id, - {'admin_state_up': True}) - self.assertEqual(res['status'], 'ACTIVE') - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertFalse(self.ofc.delete_ofc_port.call_count) - - res = self._update_resource(resource, res_id, - {'admin_state_up': False}) - self.assertEqual(res['status'], 'DOWN') - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - - expected = [ - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_tenant(ctx, self._tenant_id), - mock.call.create_ofc_network(ctx, self._tenant_id, net['id'], - net['name']), - - mock.call.exists_ofc_port(ctx, p1['id']), - mock.call.create_ofc_port(ctx, p1['id'], mock.ANY), - - mock.call.exists_ofc_port(ctx, p1['id']), - mock.call.delete_ofc_port(ctx, p1['id'], mock.ANY), - - mock.call.exists_ofc_port(ctx, p1['id']), - mock.call.exists_ofc_network(ctx, net['id']), - mock.call.delete_ofc_network(ctx, net['id'], mock.ANY), - mock.call.exists_ofc_tenant(ctx, self._tenant_id), - mock.call.delete_ofc_tenant(ctx, self._tenant_id) - ] - self.ofc.assert_has_calls(expected) - - def test_update_port_with_ofc_creation_failure(self): - with self.port(admin_state_up=False) as port: - port_id = port['port']['id'] - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - - self.ofc.set_raise_exc('create_ofc_port', - nexc.OFCException(reason='hoge')) - - body = {'port': {'admin_state_up': True}} - res = self._update('ports', port_id, body) - self.assertEqual(res['port']['status'], 'ERROR') - port_ref = self._show('ports', port_id) - self.assertEqual(port_ref['port']['status'], 'ERROR') - - body = {'port': {'admin_state_up': False}} - res = self._update('ports', port_id, body) - self.assertEqual(res['port']['status'], 'ERROR') - port_ref = self._show('ports', port_id) - self.assertEqual(port_ref['port']['status'], 'ERROR') - - self.ofc.set_raise_exc('create_ofc_port', None) - - body = {'port': {'admin_state_up': True}} - res = self._update('ports', port_id, body) - self.assertEqual(res['port']['status'], 'ACTIVE') - port_ref = self._show('ports', port_id) - self.assertEqual(port_ref['port']['status'], 'ACTIVE') - - ctx = mock.ANY - port = mock.ANY - expected = [ - mock.call.exists_ofc_port(ctx, port_id), - mock.call.create_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.create_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.delete_ofc_port(ctx, port_id, port), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.create_ofc_port.call_count, 2) - - def test_update_port_with_ofc_deletion_failure(self): - with self.port() as port: - port_id = port['port']['id'] - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - - self.ofc.set_raise_exc('delete_ofc_port', - nexc.OFCException(reason='hoge')) - - body = {'port': {'admin_state_up': False}} - self._update('ports', port_id, body, - expected_code=webob.exc.HTTPInternalServerError.code) - port_ref = self._show('ports', port_id) - self.assertEqual(port_ref['port']['status'], 'ERROR') - - body = {'port': {'admin_state_up': True}} - res = self._update('ports', port_id, body) - self.assertEqual(res['port']['status'], 'ERROR') - port_ref = self._show('ports', port_id) - self.assertEqual(port_ref['port']['status'], 'ERROR') - - self.ofc.set_raise_exc('delete_ofc_port', None) - - body = {'port': {'admin_state_up': False}} - res = self._update('ports', port_id, body) - self.assertEqual(res['port']['status'], 'DOWN') - port_ref = self._show('ports', port_id) - self.assertEqual(port_ref['port']['status'], 'DOWN') - - ctx = mock.ANY - port = mock.ANY - expected = [ - mock.call.exists_ofc_port(ctx, port_id), - mock.call.create_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.delete_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.delete_ofc_port(ctx, port_id, port), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 2) - - def test_delete_port_with_error_status(self): - self.ofc.set_raise_exc('create_ofc_port', - nexc.OFCException(reason='fake')) - - with self.port() as port: - port_id = port['port']['id'] - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - port_ref = self._show('ports', port_id) - self.assertEqual(port_ref['port']['status'], 'ERROR') - - ctx = mock.ANY - port = mock.ANY - expected = [ - mock.call.exists_ofc_port(ctx, port_id), - mock.call.create_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - ] - self.ofc.assert_has_calls(expected) - self.assertFalse(self.ofc.delete_ofc_port.call_count) - - def test_delete_port_with_ofc_deletion_failure(self): - self.ofc.set_raise_exc('delete_ofc_port', - nexc.OFCException(reason='hoge')) - - with self.port() as port: - port_id = port['port']['id'] - - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - - self._delete('ports', port_id, - expected_code=webob.exc.HTTPInternalServerError.code) - - port_ref = self._show('ports', port_id) - self.assertEqual(port_ref['port']['status'], 'ERROR') - - self.ofc.set_raise_exc('delete_ofc_port', None) - - ctx = mock.ANY - port = mock.ANY - expected = [ - mock.call.exists_ofc_port(ctx, port_id), - mock.call.create_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.delete_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.delete_ofc_port(ctx, port_id, port) - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 2) - - def _test_delete_port_for_disappeared_ofc_port(self, raised_exc): - self.ofc.set_raise_exc('delete_ofc_port', raised_exc) - - with self.port(no_delete=True) as port: - port_id = port['port']['id'] - - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(added=[portinfo]) - - self._delete('ports', port_id) - - # Check the port on neutron db is deleted. NotFound for - # neutron port itself should be handled by called. It is - # consistent with ML2 behavior, but it may need to be - # revisit. - self._show('ports', port_id, - expected_code=webob.exc.HTTPNotFound.code) - - ctx = mock.ANY - port = mock.ANY - expected = [ - mock.call.exists_ofc_port(ctx, port_id), - mock.call.create_ofc_port(ctx, port_id, port), - mock.call.exists_ofc_port(ctx, port_id), - mock.call.delete_ofc_port(ctx, port_id, port), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - - def test_delete_port_for_nonexist_ofc_port(self): - self._test_delete_port_for_disappeared_ofc_port( - nexc.OFCResourceNotFound(resource='ofc_port')) - - def test_delete_port_for_noofcmap_ofc_port(self): - self._test_delete_port_for_disappeared_ofc_port( - nexc.OFCMappingNotFound(resource='port', neutron_id='port1')) - - -class TestNecAllowedAddressPairs(NecPluginV2TestCase, - test_pair.TestAllowedAddressPairs): - pass diff --git a/neutron/tests/unit/nec/test_ofc_client.py b/neutron/tests/unit/nec/test_ofc_client.py deleted file mode 100644 index 93f75a2b0..000000000 --- a/neutron/tests/unit/nec/test_ofc_client.py +++ /dev/null @@ -1,179 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 NEC Corporation. All rights reserved. -# -# 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. -# -# @author: Akihiro Motoki - -import mock -from oslo.config import cfg -import requests - -from neutron.openstack.common import jsonutils as json -from neutron.plugins.nec.common import config -from neutron.plugins.nec.common import exceptions as nexc -from neutron.plugins.nec.common import ofc_client -from neutron.tests import base - - -class FakeResponse(requests.Response): - def __init__(self, status_code=None, text=None, headers=None): - self._text = text - self.status_code = status_code - if headers is not None: - self.headers = headers - - @property - def text(self): - return self._text - - -class OFCClientTest(base.BaseTestCase): - - def _test_do_request(self, status, resbody, expected_data, exctype=None, - exc_checks=None, path_prefix=None): - req = mock.Mock(return_value=(FakeResponse(status, resbody))) - - with mock.patch.object(requests, 'request', req): - client = ofc_client.OFCClient() - path = '/somewhere' - realpath = path_prefix + path if path_prefix else path - if exctype: - e = self.assertRaises(exctype, client.do_request, - 'GET', path, body={}) - self.assertEqual(expected_data, str(e)) - if exc_checks: - for k, v in exc_checks.items(): - self.assertEqual(v, getattr(e, k)) - else: - response = client.do_request('GET', path, body={}) - self.assertEqual(response, expected_data) - - headers = {"Content-Type": "application/json"} - req.assert_called_with('GET', 'http://127.0.0.1:8888' + realpath, - verify=True, cert={}, data='{}', - headers=headers) - - def test_do_request_200_json_value(self): - self._test_do_request(200, json.dumps([1, 2, 3]), [1, 2, 3]) - - def test_do_request_200_string(self): - self._test_do_request(200, 'abcdef', 'abcdef') - - def test_do_request_200_no_body(self): - self._test_do_request(200, None, None) - - def test_do_request_other_success_codes(self): - for status in [201, 202, 204]: - self._test_do_request(status, None, None) - - def test_do_request_with_path_prefix(self): - config.CONF.set_override('path_prefix', '/dummy', group='OFC') - self._test_do_request(200, json.dumps([1, 2, 3]), [1, 2, 3], - path_prefix='/dummy') - - def test_do_request_returns_404(self): - resbody = '' - errmsg = _("The specified OFC resource (/somewhere) is not found.") - self._test_do_request(404, resbody, errmsg, nexc.OFCResourceNotFound) - - def test_do_request_error_no_body(self): - errmsg = _("An OFC exception has occurred: Operation on OFC failed") - exc_checks = {'status': 400, 'err_code': None, 'err_msg': None} - self._test_do_request(400, None, errmsg, nexc.OFCException, exc_checks) - - def test_do_request_error_string_body(self): - resbody = 'This is an error.' - errmsg = _("An OFC exception has occurred: Operation on OFC failed") - exc_checks = {'status': 400, 'err_code': None, - 'err_msg': 'This is an error.'} - self._test_do_request(400, resbody, errmsg, nexc.OFCException, - exc_checks) - - def test_do_request_error_json_body(self): - resbody = json.dumps({'err_code': 40022, - 'err_msg': 'This is an error.'}) - errmsg = _("An OFC exception has occurred: Operation on OFC failed") - exc_checks = {'status': 400, 'err_code': 40022, - 'err_msg': 'This is an error.'} - self._test_do_request(400, resbody, errmsg, nexc.OFCException, - exc_checks) - - def test_do_request_socket_error(self): - data = _("An OFC exception has occurred: Failed to connect OFC : ") - - req = mock.Mock() - req.side_effect = requests.exceptions.RequestException - - with mock.patch.object(requests, 'request', req): - client = ofc_client.OFCClient() - - e = self.assertRaises(nexc.OFCException, client.do_request, - 'GET', '/somewhere', body={}) - self.assertEqual(data, str(e)) - for k in ['status', 'err_code', 'err_msg']: - self.assertIsNone(getattr(e, k)) - - headers = {"Content-Type": "application/json"} - req.assert_called_with('GET', 'http://127.0.0.1:8888/somewhere', - verify=True, cert={}, data='{}', - headers=headers) - - def test_do_request_retry_fail_after_one_attempts(self): - self._test_do_request_retry_after(1, api_max_attempts=1) - - def test_do_request_retry_fail_with_max_attempts(self): - self._test_do_request_retry_after(3) - - def test_do_request_retry_succeed_with_2nd_attempt(self): - self._test_do_request_retry_after(2, succeed_final=True) - - def test_do_request_retry_succeed_with_1st_attempt(self): - self._test_do_request_retry_after(1, succeed_final=True) - - def _test_do_request_retry_after(self, exp_request_count, - api_max_attempts=None, - succeed_final=False): - if api_max_attempts is not None: - cfg.CONF.set_override('api_max_attempts', api_max_attempts, - group='OFC') - - res_unavail = FakeResponse(503, headers={'retry-after': '10'}) - res_ok = FakeResponse(200) - - req = mock.Mock() - if succeed_final: - req.side_effect = ([res_unavail] * (exp_request_count - 1) - + [res_ok]) - else: - req.side_effect = [res_unavail] * exp_request_count - - with mock.patch.object(requests, 'request', req): - with mock.patch('time.sleep') as sleep: - client = ofc_client.OFCClient() - if succeed_final: - ret = client.do_request('GET', '/somewhere') - self.assertIsNone(ret) - else: - e = self.assertRaises(nexc.OFCServiceUnavailable, - client.do_request, - 'GET', '/somewhere') - self.assertEqual('10', e.retry_after) - - headers = {"Content-Type": "application/json"} - req.assert_called_with('GET', 'http://127.0.0.1:8888/somewhere', - verify=True, cert={}, data=None, - headers=headers) - self.assertEqual(exp_request_count, req.call_count) - self.assertEqual(exp_request_count - 1, sleep.call_count) diff --git a/neutron/tests/unit/nec/test_ofc_manager.py b/neutron/tests/unit/nec/test_ofc_manager.py deleted file mode 100644 index e4543c21f..000000000 --- a/neutron/tests/unit/nec/test_ofc_manager.py +++ /dev/null @@ -1,297 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 NEC Corporation. All rights reserved. -# -# 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. -# @author: Ryota MIBU - -import mock - -from neutron import context -from neutron.db import api as db -from neutron.openstack.common import uuidutils -from neutron.plugins.nec.common import config -from neutron.plugins.nec.db import api as ndb -from neutron.plugins.nec.db import models as nmodels # noqa -from neutron.plugins.nec import ofc_manager -from neutron.tests import base - - -class FakePortInfo(object): - def __init__(self, id, datapath_id, port_no=0, - vlan_id=65535, mac='00:11:22:33:44:55'): - self.data = {'id': id, 'datapath_id': datapath_id, - 'port_no': port_no, 'vlan_id': vlan_id, 'mac': mac} - - def __getattr__(self, name): - if name in self.fields: - return self[name] - else: - raise AttributeError(name) - - -class OFCManagerTestBase(base.BaseTestCase): - """Class conisting of OFCManager unit tests.""" - - def setUp(self): - super(OFCManagerTestBase, self).setUp() - db.configure_db() - driver = "neutron.tests.unit.nec.stub_ofc_driver.StubOFCDriver" - config.CONF.set_override('driver', driver, 'OFC') - self.addCleanup(ndb.clear_db) - self.plugin = mock.Mock() - self.plugin.get_packet_filters_for_port.return_value = None - self.ofc = ofc_manager.OFCManager(self.plugin) - # NOTE: enable_autocheck() is a feature of StubOFCDriver - self.ofc.driver.enable_autocheck() - self.ctx = context.get_admin_context() - - def get_random_params(self): - """create random parameters for portinfo test.""" - tenant = uuidutils.generate_uuid() - network = uuidutils.generate_uuid() - port = uuidutils.generate_uuid() - _filter = uuidutils.generate_uuid() - none = uuidutils.generate_uuid() - return tenant, network, port, _filter, none - - -class OFCManagerTest(OFCManagerTestBase): - def testa_create_ofc_tenant(self): - """test create ofc_tenant.""" - t, n, p, f, none = self.get_random_params() - self.assertFalse(ndb.get_ofc_item(self.ctx.session, 'ofc_tenant', t)) - self.ofc.create_ofc_tenant(self.ctx, t) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_tenant', t)) - tenant = ndb.get_ofc_item(self.ctx.session, 'ofc_tenant', t) - self.assertEqual(tenant.ofc_id, "ofc-" + t[:-4]) - - def testb_exists_ofc_tenant(self): - """test exists_ofc_tenant.""" - t, n, p, f, none = self.get_random_params() - self.assertFalse(self.ofc.exists_ofc_tenant(self.ctx, t)) - self.ofc.create_ofc_tenant(self.ctx, t) - self.assertTrue(self.ofc.exists_ofc_tenant(self.ctx, t)) - - def testc_delete_ofc_tenant(self): - """test delete ofc_tenant.""" - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_tenant', t)) - self.ofc.delete_ofc_tenant(self.ctx, t) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, 'ofc_tenant', t)) - - def testd_create_ofc_network(self): - """test create ofc_network.""" - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, 'ofc_network', n)) - self.ofc.create_ofc_network(self.ctx, t, n) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_network', n)) - network = ndb.get_ofc_item(self.ctx.session, 'ofc_network', n) - self.assertEqual(network.ofc_id, "ofc-" + n[:-4]) - - def teste_exists_ofc_network(self): - """test exists_ofc_network.""" - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.assertFalse(self.ofc.exists_ofc_network(self.ctx, n)) - self.ofc.create_ofc_network(self.ctx, t, n) - self.assertTrue(self.ofc.exists_ofc_network(self.ctx, n)) - - def testf_delete_ofc_network(self): - """test delete ofc_network.""" - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_network(self.ctx, t, n) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_network', n)) - self.ofc.delete_ofc_network(self.ctx, n, {'tenant_id': t}) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, 'ofc_network', n)) - - def _mock_get_portinfo(self, port_id, datapath_id='0xabc', port_no=1): - get_portinfo = mock.patch.object(ndb, 'get_portinfo').start() - fake_portinfo = FakePortInfo(id=port_id, datapath_id=datapath_id, - port_no=port_no) - get_portinfo.return_value = fake_portinfo - return get_portinfo - - def _test_create_ofc_port(self, with_filter=False): - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_network(self.ctx, t, n) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, 'ofc_port', p)) - get_portinfo = self._mock_get_portinfo(p) - port = {'tenant_id': t, 'network_id': n} - if with_filter: - _filters = ['filter1', 'filter2'] - self.plugin.get_packet_filters_for_port.return_value = _filters - self.ofc.create_ofc_port(self.ctx, p, port) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_port', p)) - port = ndb.get_ofc_item(self.ctx.session, 'ofc_port', p) - self.assertEqual(port.ofc_id, "ofc-" + p[:-4]) - get_portinfo.assert_called_once_with(mock.ANY, p) - portval = self.ofc.driver.ofc_port_dict[port.ofc_id] - if with_filter: - self.assertEqual(_filters, portval['filters']) - else: - self.assertFalse('filters' in portval) - - def testg_create_ofc_port(self): - """test create ofc_port.""" - self._test_create_ofc_port(with_filter=False) - - def testg_create_ofc_port_with_filters(self): - """test create ofc_port.""" - self._test_create_ofc_port(with_filter=True) - - def testh_exists_ofc_port(self): - """test exists_ofc_port.""" - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_network(self.ctx, t, n) - self.assertFalse(self.ofc.exists_ofc_port(self.ctx, p)) - get_portinfo = self._mock_get_portinfo(p) - port = {'tenant_id': t, 'network_id': n} - self.ofc.create_ofc_port(self.ctx, p, port) - self.assertTrue(self.ofc.exists_ofc_port(self.ctx, p)) - get_portinfo.assert_called_once_with(mock.ANY, p) - - def testi_delete_ofc_port(self): - """test delete ofc_port.""" - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_network(self.ctx, t, n) - get_portinfo = self._mock_get_portinfo(p) - port = {'tenant_id': t, 'network_id': n} - self.ofc.create_ofc_port(self.ctx, p, port) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_port', p)) - self.ofc.delete_ofc_port(self.ctx, p, port) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, 'ofc_port', p)) - get_portinfo.assert_called_once_with(mock.ANY, p) - - -class OFCManagerFilterTest(OFCManagerTestBase): - def testj_create_ofc_packet_filter(self): - """test create ofc_filter.""" - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_network(self.ctx, t, n) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, - 'ofc_packet_filter', f)) - pf = {'tenant_id': t, 'network_id': n} - self.ofc.create_ofc_packet_filter(self.ctx, f, pf) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, - 'ofc_packet_filter', f)) - _filter = ndb.get_ofc_item(self.ctx.session, 'ofc_packet_filter', f) - self.assertEqual(_filter.ofc_id, "ofc-" + f[:-4]) - - def testk_exists_ofc_packet_filter(self): - """test exists_ofc_packet_filter.""" - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_network(self.ctx, t, n) - self.assertFalse(self.ofc.exists_ofc_packet_filter(self.ctx, f)) - pf = {'tenant_id': t, 'network_id': n} - self.ofc.create_ofc_packet_filter(self.ctx, f, pf) - self.assertTrue(self.ofc.exists_ofc_packet_filter(self.ctx, f)) - - def testl_delete_ofc_packet_filter(self): - """test delete ofc_filter.""" - t, n, p, f, none = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_network(self.ctx, t, n) - pf = {'tenant_id': t, 'network_id': n} - self.ofc.create_ofc_packet_filter(self.ctx, f, pf) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, - 'ofc_packet_filter', f)) - self.ofc.delete_ofc_packet_filter(self.ctx, f) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, - 'ofc_packet_filter', f)) - - -class OFCManagerRouterTest(OFCManagerTestBase): - def get_random_params(self): - tenant = uuidutils.generate_uuid() - router = uuidutils.generate_uuid() - network = uuidutils.generate_uuid() - return (tenant, router, network) - - def test_create_ofc_router(self): - """test create ofc_router""" - t, r, _n = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, 'ofc_router', r)) - self.ofc.create_ofc_router(self.ctx, t, r, 'test router') - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_router', r)) - router = ndb.get_ofc_item(self.ctx.session, 'ofc_router', r) - self.assertEqual(router.ofc_id, "ofc-" + r[:-4]) - - def test_exists_ofc_router(self): - """test exists_ofc_router""" - t, r, _n = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.assertFalse(self.ofc.exists_ofc_router(self.ctx, r)) - self.ofc.create_ofc_router(self.ctx, t, r) - self.assertTrue(self.ofc.exists_ofc_router(self.ctx, r)) - - def test_delete_ofc_router(self): - """test delete ofc_router""" - t, r, _n = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_router(self.ctx, t, r) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_router', r)) - self.ofc.delete_ofc_router(self.ctx, r, {'tenant_id': t}) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, 'ofc_network', r)) - - def test_router_interface(self): - t, r, n = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_router(self.ctx, t, r) - self.ofc.create_ofc_network(self.ctx, t, n) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_router', r)) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_network', n)) - - p = {'id': uuidutils.generate_uuid(), - 'network_id': n, 'ip_address': '10.1.1.1', 'cidr': '10.1.0.0/20', - 'mac_address': '11:22:33:44:55:66'} - self.ofc.add_ofc_router_interface(self.ctx, r, p['id'], p) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, - 'ofc_port', p['id'])) - self.ofc.delete_ofc_router_interface(self.ctx, r, p['id']) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, - 'ofc_port', p['id'])) - self.ofc.delete_ofc_router(self.ctx, r, {'tenant_id': t}) - self.assertFalse(ndb.get_ofc_item(self.ctx.session, 'ofc_network', r)) - - def test_router_route(self): - t, r, _n = self.get_random_params() - self.ofc.create_ofc_tenant(self.ctx, t) - self.ofc.create_ofc_router(self.ctx, t, r) - self.assertTrue(ndb.get_ofc_item(self.ctx.session, 'ofc_router', r)) - - routes = [{'destination': '2.2.2.0/24', 'nexthop': '1.1.1.10'}] - self.ofc.update_ofc_router_route(self.ctx, r, routes) - self.assertEqual(len(self.ofc.driver.ofc_router_route_dict), 1) - - routes = [{'destination': '3.3.3.0/24', 'nexthop': '1.1.1.11'}, - {'destination': '4.4.4.0/24', 'nexthop': '1.1.1.11'}] - self.ofc.update_ofc_router_route(self.ctx, r, routes) - self.assertEqual(len(self.ofc.driver.ofc_router_route_dict), 2) - - routes = [{'destination': '2.2.2.0/24', 'nexthop': '1.1.1.10'}] - self.ofc.update_ofc_router_route(self.ctx, r, routes) - self.assertEqual(len(self.ofc.driver.ofc_router_route_dict), 1) - - routes = [] - self.ofc.update_ofc_router_route(self.ctx, r, routes) - self.assertEqual(len(self.ofc.driver.ofc_router_route_dict), 0) diff --git a/neutron/tests/unit/nec/test_packet_filter.py b/neutron/tests/unit/nec/test_packet_filter.py deleted file mode 100644 index b87a9255a..000000000 --- a/neutron/tests/unit/nec/test_packet_filter.py +++ /dev/null @@ -1,714 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 contextlib - -import mock -import webob.exc - -from neutron.api.v2 import attributes -from neutron import context -from neutron.plugins.nec.common import exceptions as nexc -from neutron.plugins.nec.extensions import packetfilter as ext_pf -from neutron.tests.unit.nec import test_nec_plugin -from neutron.tests.unit import test_db_plugin as test_plugin - - -NEC_PLUGIN_PF_INI = """ -[DEFAULT] -api_extensions_path = neutron/plugins/nec/extensions -[OFC] -driver = neutron.tests.unit.nec.stub_ofc_driver.StubOFCDriver -enable_packet_filter = True -""" - - -class PacketfilterExtensionManager(ext_pf.Packetfilter): - - @classmethod - def get_resources(cls): - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - {'packet_filters': ext_pf.PACKET_FILTER_ATTR_MAP}) - return super(PacketfilterExtensionManager, cls).get_resources() - - -class TestNecPluginPacketFilterBase(test_nec_plugin.NecPluginV2TestCase): - - _nec_ini = NEC_PLUGIN_PF_INI - - def setUp(self): - ext_mgr = PacketfilterExtensionManager() - super(TestNecPluginPacketFilterBase, self).setUp(ext_mgr=ext_mgr) - - def _create_packet_filter(self, fmt, net_id, expected_res_status=None, - arg_list=None, **kwargs): - data = {'packet_filter': {'network_id': net_id, - 'tenant_id': self._tenant_id, - 'priority': '1', - 'action': 'ALLOW'}} - - for arg in (('name', 'admin_state_up', 'action', 'priority', 'in_port', - 'src_mac', 'dst_mac', 'eth_type', 'src_cidr', 'dst_cidr', - 'protocol', 'src_port', 'dst_port') + - (arg_list or ())): - # Arg must be present - if arg in kwargs: - data['packet_filter'][arg] = kwargs[arg] - pf_req = self.new_create_request('packet_filters', data, fmt) - if (kwargs.get('set_context') and 'tenant_id' in kwargs): - # create a specific auth context for this request - pf_req.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - - pf_res = pf_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(pf_res.status_int, expected_res_status) - return pf_res - - def _make_packet_filter(self, fmt, net_id, expected_res_status=None, - **kwargs): - res = self._create_packet_filter(fmt, net_id, expected_res_status, - **kwargs) - # Things can go wrong - raise HTTP exc with res code only - # so it can be caught by unit tests - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - @contextlib.contextmanager - def packet_filter_on_network(self, network=None, fmt=None, do_delete=True, - **kwargs): - with test_plugin.optional_ctx(network, self.network) as network_to_use: - net_id = network_to_use['network']['id'] - pf = self._make_packet_filter(fmt or self.fmt, net_id, **kwargs) - yield pf - if do_delete: - self._delete('packet_filters', pf['packet_filter']['id']) - - @contextlib.contextmanager - def packet_filter_on_port(self, port=None, fmt=None, do_delete=True, - set_portinfo=True, **kwargs): - with test_plugin.optional_ctx(port, self.port) as port_to_use: - net_id = port_to_use['port']['network_id'] - port_id = port_to_use['port']['id'] - - if set_portinfo: - portinfo = {'id': port_id, - 'port_no': kwargs.get('port_no', 123)} - kw = {'added': [portinfo]} - if 'datapath_id' in kwargs: - kw['datapath_id'] = kwargs['datapath_id'] - self.rpcapi_update_ports(**kw) - - kwargs['in_port'] = port_id - pf = self._make_packet_filter(fmt or self.fmt, net_id, **kwargs) - self.assertEqual(port_id, pf['packet_filter']['in_port']) - yield pf - if do_delete: - self._delete('packet_filters', pf['packet_filter']['id']) - - -class TestNecPluginPacketFilter(TestNecPluginPacketFilterBase): - - def setUp(self): - super(TestNecPluginPacketFilter, self).setUp() - # Remove attributes explicitly from mock object to check - # a case where there are no update_filter and validate_*. - del self.ofc.driver.update_filter - del self.ofc.driver.validate_filter_create - del self.ofc.driver.validate_filter_update - - def test_list_packet_filters(self): - self._list('packet_filters') - - def test_create_pf_on_network_no_ofc_creation(self): - with self.packet_filter_on_network(admin_state_up=False) as pf: - self.assertEqual(pf['packet_filter']['status'], 'DOWN') - - self.assertFalse(self.ofc.create_ofc_packet_filter.called) - self.assertFalse(self.ofc.delete_ofc_packet_filter.called) - - def test_create_pf_on_port_no_ofc_creation(self): - with self.packet_filter_on_port(admin_state_up=False, - set_portinfo=False) as pf: - self.assertEqual(pf['packet_filter']['status'], 'DOWN') - - self.assertFalse(self.ofc.create_ofc_packet_filter.called) - self.assertFalse(self.ofc.delete_ofc_packet_filter.called) - - def test_create_pf_on_network_with_ofc_creation(self): - with self.packet_filter_on_network() as pf: - pf_id = pf['packet_filter']['id'] - self.assertEqual(pf['packet_filter']['status'], 'ACTIVE') - - ctx = mock.ANY - pf_dict = mock.ANY - expected = [ - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 1) - - def test_create_pf_on_port_with_ofc_creation(self): - with self.packet_filter_on_port() as pf: - pf_id = pf['packet_filter']['id'] - self.assertEqual(pf['packet_filter']['status'], 'ACTIVE') - - ctx = mock.ANY - pf_dict = mock.ANY - expected = [ - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 1) - - def _test_create_pf_with_protocol(self, protocol, expected_eth_type): - with self.packet_filter_on_network(protocol=protocol) as pf: - pf_data = pf['packet_filter'] - self.assertEqual(protocol, pf_data['protocol']) - self.assertEqual(expected_eth_type, pf_data['eth_type']) - - def test_create_pf_with_protocol_tcp(self): - self._test_create_pf_with_protocol('TCP', 0x800) - - def test_create_pf_with_protocol_udp(self): - self._test_create_pf_with_protocol('UDP', 0x800) - - def test_create_pf_with_protocol_icmp(self): - self._test_create_pf_with_protocol('ICMP', 0x800) - - def test_create_pf_with_protocol_arp(self): - self._test_create_pf_with_protocol('ARP', 0x806) - - def test_create_pf_with_inconsistent_protocol_and_eth_type(self): - with self.packet_filter_on_network(protocol='TCP') as pf: - pf_data = pf['packet_filter'] - pf_id = pf_data['id'] - self.assertEqual('TCP', pf_data['protocol']) - self.assertEqual(0x800, pf_data['eth_type']) - data = {'packet_filter': {'eth_type': 0x806}} - self._update('packet_filters', pf_id, data, - expected_code=409) - - def test_create_pf_with_invalid_priority(self): - with self.network() as net: - net_id = net['network']['id'] - kwargs = {'priority': 'high'} - self._create_packet_filter(self.fmt, net_id, - webob.exc.HTTPBadRequest.code, - **kwargs) - self.assertFalse(self.ofc.create_ofc_packet_filter.called) - - def test_create_pf_with_ofc_creation_failure(self): - self.ofc.set_raise_exc('create_ofc_packet_filter', - nexc.OFCException(reason='hoge')) - - with self.packet_filter_on_network() as pf: - pf_id = pf['packet_filter']['id'] - pf_ref = self._show('packet_filters', pf_id) - self.assertEqual(pf_ref['packet_filter']['status'], 'ERROR') - - self.ofc.set_raise_exc('create_ofc_packet_filter', None) - - # Retry activate packet_filter (even if there is no change). - data = {'packet_filter': {}} - self._update('packet_filters', pf_id, data) - - pf_ref = self._show('packet_filters', pf_id) - self.assertEqual(pf_ref['packet_filter']['status'], 'ACTIVE') - - ctx = mock.ANY - pf_dict = mock.ANY - expected = [ - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - - mock.call.exists_ofc_packet_filter(ctx, pf_id), - - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 2) - - def test_show_pf_on_network(self): - kwargs = { - 'name': 'test-pf-net', - 'admin_state_up': False, - 'action': 'DENY', - 'priority': '102', - 'src_mac': '00:11:22:33:44:55', - 'dst_mac': '66:77:88:99:aa:bb', - 'eth_type': '2048', - 'src_cidr': '192.168.1.0/24', - 'dst_cidr': '192.168.2.0/24', - 'protocol': 'TCP', - 'src_port': '35001', - 'dst_port': '22' - } - - with self.packet_filter_on_network(**kwargs) as pf: - pf_id = pf['packet_filter']['id'] - pf_ref = self._show('packet_filters', pf_id) - - # convert string to int. - kwargs.update({'priority': 102, 'eth_type': 2048, - 'src_port': 35001, 'dst_port': 22, - 'in_port': None}) - - self.assertEqual(pf_id, pf_ref['packet_filter']['id']) - for key in kwargs: - self.assertEqual(kwargs[key], pf_ref['packet_filter'][key]) - - def test_show_pf_on_network_with_wildcards(self): - kwargs = { - 'name': 'test-pf-net', - 'admin_state_up': False, - 'action': 'DENY', - 'priority': '102', - } - - with self.packet_filter_on_network(**kwargs) as pf: - pf_id = pf['packet_filter']['id'] - pf_ref = self._show('packet_filters', pf_id) - - # convert string to int. - kwargs.update({'priority': 102, - 'in_port': None, - 'src_mac': None, - 'dst_mac': None, - 'eth_type': None, - 'src_cidr': None, - 'dst_cidr': None, - 'protocol': None, - 'src_port': None, - 'dst_port': None}) - - self.assertEqual(pf_id, pf_ref['packet_filter']['id']) - for key in kwargs: - self.assertEqual(kwargs[key], pf_ref['packet_filter'][key]) - - def test_show_pf_on_port(self): - kwargs = { - 'name': 'test-pf-port', - 'admin_state_up': False, - 'action': 'DENY', - 'priority': '0o147', - 'src_mac': '00:11:22:33:44:55', - 'dst_mac': '66:77:88:99:aa:bb', - 'eth_type': 2048, - 'src_cidr': '192.168.1.0/24', - 'dst_cidr': '192.168.2.0/24', - 'protocol': 'TCP', - 'dst_port': '0x50' - } - - with self.packet_filter_on_port(**kwargs) as pf: - pf_id = pf['packet_filter']['id'] - pf_ref = self._show('packet_filters', pf_id) - - # convert string to int. - kwargs.update({'priority': 103, 'eth_type': 2048, - 'dst_port': 80, - # wildcard field is None in a response. - 'src_port': None}) - - self.assertEqual(pf_id, pf_ref['packet_filter']['id']) - self.assertTrue(pf_ref['packet_filter']['in_port']) - for key in kwargs: - self.assertEqual(kwargs[key], pf_ref['packet_filter'][key]) - - def test_show_pf_not_found(self): - pf_id = '00000000-ffff-ffff-ffff-000000000000' - - self._show('packet_filters', pf_id, - expected_code=webob.exc.HTTPNotFound.code) - - def test_update_pf_on_network(self): - ctx = mock.ANY - pf_dict = mock.ANY - with self.packet_filter_on_network(admin_state_up=False) as pf: - pf_id = pf['packet_filter']['id'] - - self.assertFalse(self.ofc.create_ofc_packet_filter.called) - data = {'packet_filter': {'admin_state_up': True}} - self._update('packet_filters', pf_id, data) - self.ofc.create_ofc_packet_filter.assert_called_once_with( - ctx, pf_id, pf_dict) - - self.assertFalse(self.ofc.delete_ofc_packet_filter.called) - data = {'packet_filter': {'admin_state_up': False}} - self._update('packet_filters', pf_id, data) - self.ofc.delete_ofc_packet_filter.assert_called_once_with( - ctx, pf_id) - - def test_update_pf_on_port(self): - ctx = mock.ANY - pf_dict = mock.ANY - with self.packet_filter_on_port(admin_state_up=False) as pf: - pf_id = pf['packet_filter']['id'] - - self.assertFalse(self.ofc.create_ofc_packet_filter.called) - data = {'packet_filter': {'admin_state_up': True}} - self._update('packet_filters', pf_id, data) - self.ofc.create_ofc_packet_filter.assert_called_once_with( - ctx, pf_id, pf_dict) - - self.assertFalse(self.ofc.delete_ofc_packet_filter.called) - data = {'packet_filter': {'admin_state_up': False}} - self._update('packet_filters', pf_id, data) - self.ofc.delete_ofc_packet_filter.assert_called_once_with( - ctx, pf_id) - - def test_delete_pf_with_error_status(self): - self.ofc.set_raise_exc('create_ofc_packet_filter', - nexc.OFCException(reason='fake')) - with self.packet_filter_on_network() as pf: - pf_id = pf['packet_filter']['id'] - pf_ref = self._show('packet_filters', pf_id) - self.assertEqual(pf_ref['packet_filter']['status'], 'ERROR') - - ctx = mock.ANY - pf_dict = mock.ANY - expected = [ - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - mock.call.exists_ofc_packet_filter(ctx, pf_id), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(1, self.ofc.create_ofc_packet_filter.call_count) - self.assertEqual(0, self.ofc.delete_ofc_packet_filter.call_count) - - def test_activate_pf_on_port_triggered_by_update_port(self): - ctx = mock.ANY - pf_dict = mock.ANY - with self.packet_filter_on_port(set_portinfo=False) as pf: - pf_id = pf['packet_filter']['id'] - in_port_id = pf['packet_filter']['in_port'] - - self.assertFalse(self.ofc.create_ofc_packet_filter.called) - portinfo = {'id': in_port_id, 'port_no': 123} - kw = {'added': [portinfo]} - self.rpcapi_update_ports(**kw) - self.ofc.create_ofc_packet_filter.assert_called_once_with( - ctx, pf_id, pf_dict) - - self.assertFalse(self.ofc.delete_ofc_packet_filter.called) - kw = {'removed': [in_port_id]} - self.rpcapi_update_ports(**kw) - self.ofc.delete_ofc_packet_filter.assert_called_once_with( - ctx, pf_id) - - # Ensure pf was created before in_port has activated. - ctx = mock.ANY - pf_dict = mock.ANY - port_dict = mock.ANY - expected = [ - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - mock.call.exists_ofc_port(ctx, in_port_id), - mock.call.create_ofc_port(ctx, in_port_id, port_dict), - - mock.call.exists_ofc_port(ctx, in_port_id), - mock.call.delete_ofc_port(ctx, in_port_id, port_dict), - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 1) - - def test_activate_pf_while_exists_on_ofc(self): - ctx = mock.ANY - with self.packet_filter_on_network() as pf: - pf_id = pf['packet_filter']['id'] - - self.ofc.set_raise_exc('delete_ofc_packet_filter', - nexc.OFCException(reason='hoge')) - - # This update request will make plugin reactivate pf. - data = {'packet_filter': {'priority': 1000}} - self._update('packet_filters', pf_id, data, - expected_code=webob.exc.HTTPInternalServerError.code) - - self.ofc.set_raise_exc('delete_ofc_packet_filter', None) - - ctx = mock.ANY - pf_dict = mock.ANY - expected = [ - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 2) - - def test_deactivate_pf_with_ofc_deletion_failure(self): - ctx = mock.ANY - with self.packet_filter_on_network() as pf: - pf_id = pf['packet_filter']['id'] - - self.ofc.set_raise_exc('delete_ofc_packet_filter', - nexc.OFCException(reason='hoge')) - - data = {'packet_filter': {'admin_state_up': False}} - self._update('packet_filters', pf_id, data, - expected_code=webob.exc.HTTPInternalServerError.code) - - pf_ref = self._show('packet_filters', pf_id) - self.assertEqual(pf_ref['packet_filter']['status'], 'ERROR') - - self.ofc.set_raise_exc('delete_ofc_packet_filter', None) - - data = {'packet_filter': {'priority': 1000}} - self._update('packet_filters', pf_id, data) - - pf_ref = self._show('packet_filters', pf_id) - self.assertEqual(pf_ref['packet_filter']['status'], 'DOWN') - - ctx = mock.ANY - pf_dict = mock.ANY - expected = [ - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - - mock.call.exists_ofc_packet_filter(ctx, pf_id), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 2) - - def test_delete_pf_with_ofc_deletion_failure(self): - self.ofc.set_raise_exc('delete_ofc_packet_filter', - nexc.OFCException(reason='hoge')) - - with self.packet_filter_on_network() as pf: - pf_id = pf['packet_filter']['id'] - - self._delete('packet_filters', pf_id, - expected_code=webob.exc.HTTPInternalServerError.code) - - pf_ref = self._show('packet_filters', pf_id) - self.assertEqual(pf_ref['packet_filter']['status'], 'ERROR') - - self.ofc.set_raise_exc('delete_ofc_packet_filter', None) - # Then, self._delete('packet_filters', pf_id) will success. - - ctx = mock.ANY - pf_dict = mock.ANY - expected = [ - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 2) - - def test_auto_delete_pf_in_network_deletion(self): - with self.packet_filter_on_network(admin_state_up=False, - do_delete=False) as pf: - pf_id = pf['packet_filter']['id'] - - self._show('packet_filters', pf_id, - expected_code=webob.exc.HTTPNotFound.code) - - def test_auto_delete_pf_in_port_deletion(self): - with self.port(no_delete=True) as port: - network = self._show('networks', port['port']['network_id']) - - with self.packet_filter_on_network(network=network) as pfn: - with self.packet_filter_on_port(port=port, do_delete=False, - set_portinfo=False) as pf: - pf_id = pf['packet_filter']['id'] - in_port_id = pf['packet_filter']['in_port'] - - self._delete('ports', in_port_id) - # Check the packet filter on the port is deleted. - self._show('packet_filters', pf_id, - expected_code=webob.exc.HTTPNotFound.code) - # Check the packet filter on the network is not deleted. - self._show('packet_filters', pfn['packet_filter']['id']) - - def test_no_pf_activation_while_port_operations(self): - with self.packet_filter_on_port() as pf: - in_port_id = pf['packet_filter']['in_port'] - self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 0) - - data = {'port': {'admin_state_up': False}} - self._update('ports', in_port_id, data) - self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 0) - - data = {'port': {'admin_state_up': True}} - self._update('ports', in_port_id, data) - self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 0) - - -class TestNecPluginPacketFilterWithValidate(TestNecPluginPacketFilterBase): - - def setUp(self): - super(TestNecPluginPacketFilterWithValidate, self).setUp() - # Remove attributes explicitly from mock object to check - # a case where there are no update_filter. - del self.ofc.driver.update_filter - self.validate_create = self.ofc.driver.validate_filter_create - self.validate_update = self.ofc.driver.validate_filter_update - - def test_create_pf_on_network(self): - with self.packet_filter_on_network() as pf: - pf_id = pf['packet_filter']['id'] - self.assertEqual(pf['packet_filter']['status'], 'ACTIVE') - - ctx = mock.ANY - pf_dict = mock.ANY - expected = [ - mock.call.driver.validate_filter_create(ctx, pf_dict), - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.create_ofc_packet_filter(ctx, pf_id, pf_dict), - mock.call.exists_ofc_packet_filter(ctx, pf_id), - mock.call.delete_ofc_packet_filter(ctx, pf_id), - ] - self.ofc.assert_has_calls(expected) - self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 1) - - def test_update_pf_on_network(self): - ctx = mock.ANY - pf_dict = mock.ANY - with self.packet_filter_on_network(admin_state_up=False) as pf: - pf_id = pf['packet_filter']['id'] - - self.assertFalse(self.ofc.create_ofc_packet_filter.called) - data = {'packet_filter': {'admin_state_up': True}} - self._update('packet_filters', pf_id, data) - self.ofc.create_ofc_packet_filter.assert_called_once_with( - ctx, pf_id, pf_dict) - self.ofc.driver.validate_filter_update.assert_called_once_with( - ctx, data['packet_filter']) - - self.assertFalse(self.ofc.delete_ofc_packet_filter.called) - data = {'packet_filter': {'admin_state_up': False}} - self._update('packet_filters', pf_id, data) - self.ofc.delete_ofc_packet_filter.assert_called_once_with( - ctx, pf_id) - self.assertEqual( - 2, self.ofc.driver.validate_filter_update.call_count) - - def test_create_pf_on_network_with_validation_error(self): - self.validate_create.side_effect = ext_pf.PacketFilterInvalidPriority( - min=1, max=65535) - with self.network() as net: - net_id = net['network']['id'] - e = self.assertRaises(webob.exc.HTTPClientError, - self._make_packet_filter, - self.fmt, net_id, expected_res_status=400) - self.assertEqual(400, e.status_int) - - def test_update_pf_on_network_with_validation_error(self): - self.validate_update.side_effect = ( - ext_pf.PacketFilterUpdateNotSupported(field='priority')) - with self.packet_filter_on_network() as pf: - pf_id = pf['packet_filter']['id'] - pf_ref = self._show('packet_filters', pf_id) - self.assertEqual(pf_ref['packet_filter']['status'], 'ACTIVE') - data = {'packet_filter': {'priority': 1000}} - self._update('packet_filters', pf_id, data, - expected_code=400) - - -class TestNecPluginPacketFilterWithFilterUpdate(TestNecPluginPacketFilterBase): - - def setUp(self): - super(TestNecPluginPacketFilterWithFilterUpdate, self).setUp() - # Remove attributes explicitly from mock object to check - # a case where there are no update_filter and validate_*. - del self.ofc.driver.validate_filter_create - del self.ofc.driver.validate_filter_update - - def test_update_pf_toggle_admin_state(self): - ctx = mock.ANY - pf_dict = mock.ANY - with self.packet_filter_on_network(admin_state_up=False) as pf: - pf_id = pf['packet_filter']['id'] - - self.assertFalse(self.ofc.create_ofc_packet_filter.called) - data = {'packet_filter': {'admin_state_up': True}} - self._update('packet_filters', pf_id, data) - self.ofc.create_ofc_packet_filter.assert_called_once_with( - ctx, pf_id, pf_dict) - - self.assertFalse(self.ofc.delete_ofc_packet_filter.called) - data = {'packet_filter': {'admin_state_up': False}} - self._update('packet_filters', pf_id, data) - self.ofc.delete_ofc_packet_filter.assert_called_once_with( - ctx, pf_id) - - def test_update_pf_change_field(self): - ctx = mock.ANY - with self.packet_filter_on_network(admin_state_up=True) as pf: - pf_id = pf['packet_filter']['id'] - self.assertTrue(self.ofc.create_ofc_packet_filter.called) - - data = {'packet_filter': {'src_mac': '12:34:56:78:9a:bc'}} - self._update('packet_filters', pf_id, data) - self.ofc.update_ofc_packet_filter.assert_called_once_with( - ctx, pf_id, data['packet_filter']) - self.assertEqual(1, self.ofc.update_ofc_packet_filter.call_count) - - self.assertFalse(self.ofc.delete_ofc_packet_filter.called) - data = {'packet_filter': {'admin_state_up': False}} - self._update('packet_filters', pf_id, data) - self.ofc.delete_ofc_packet_filter.assert_called_once_with( - ctx, pf_id) - - data = {'packet_filter': {'src_mac': '11:22:33:44:55:66'}} - self._update('packet_filters', pf_id, data) - self.assertEqual(1, self.ofc.update_ofc_packet_filter.call_count) - - data = {'packet_filter': {'admin_state_up': True}} - self._update('packet_filters', pf_id, data) - - data = {'packet_filter': {'src_mac': '66:55:44:33:22:11'}} - self._update('packet_filters', pf_id, data) - self.assertEqual(2, self.ofc.update_ofc_packet_filter.call_count) diff --git a/neutron/tests/unit/nec/test_pfc_driver.py b/neutron/tests/unit/nec/test_pfc_driver.py deleted file mode 100644 index c198800c4..000000000 --- a/neutron/tests/unit/nec/test_pfc_driver.py +++ /dev/null @@ -1,705 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 NEC Corporation. All rights reserved. -# -# 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. -# @author: Ryota MIBU - -import random -import string -import uuid - -import mock -import netaddr - -from neutron.common import constants -from neutron.openstack.common import uuidutils -from neutron.plugins.nec.common import ofc_client as ofc -from neutron.plugins.nec.db import models as nmodels -from neutron.plugins.nec import drivers -from neutron.plugins.nec.drivers import pfc -from neutron.plugins.nec.extensions import packetfilter as ext_pf -from neutron.tests import base - - -class TestConfig(object): - """Configuration for this test.""" - host = '127.0.0.1' - port = 8888 - use_ssl = False - key_file = None - cert_file = None - insecure_ssl = False - - -def _ofc(id): - """OFC ID converter.""" - return "ofc-%s" % id - - -class PFCDriverTestBase(base.BaseTestCase): - - driver = 'neutron.plugins.nec.drivers.pfc.PFCDriverBase' - filter_supported = False - - def setUp(self): - super(PFCDriverTestBase, self).setUp() - self.driver = drivers.get_driver(self.driver)(TestConfig) - self.do_request = mock.patch.object(ofc.OFCClient, - 'do_request').start() - - def get_ofc_item_random_params(self): - """create random parameters for ofc_item test.""" - tenant_id = uuidutils.generate_uuid() - network_id = uuidutils.generate_uuid() - port_id = uuidutils.generate_uuid() - portinfo = nmodels.PortInfo(id=port_id, datapath_id="0x123456789", - port_no=1234, vlan_id=321, - mac="11:22:33:44:55:66") - return tenant_id, network_id, portinfo - - def _generate_ofc_tenant_id(self, tenant_id): - fields = tenant_id.split('-') - # Strip 1st character (UUID version) of 3rd field - fields[2] = fields[2][1:] - return ''.join(fields) - - def get_ofc_description(self, desc): - """OFC description consists of [A-Za-z0-9_].""" - return desc.replace('-', '_').replace(' ', '_') - - def _create_tenant(self, t, ofc_t, post_id=False, post_desc=False): - tenant_path = '/tenants/%s' % ofc_t - path = "/tenants" - description = "desc of %s" % t - body = {} - if post_desc: - ofc_description = self.get_ofc_description(description) - body['description'] = ofc_description - if post_id: - body['id'] = ofc_t - self.do_request.return_value = None - else: - self.do_request.return_value = {'id': ofc_t} - - ret = self.driver.create_tenant(description, t) - self.do_request.assert_called_once_with("POST", path, body=body) - self.assertEqual(ret, tenant_path) - - def testa_create_tenant(self): - t, n, p = self.get_ofc_item_random_params() - ofc_t = self._generate_ofc_tenant_id(t) - self._create_tenant(t, ofc_t, post_id=True) - - def testc_delete_tenant(self): - t, n, p = self.get_ofc_item_random_params() - - path = "/tenants/%s" % _ofc(t) - - self.driver.delete_tenant(path) - self.do_request.assert_called_once_with("DELETE", path) - - def testd_create_network(self): - t, n, p = self.get_ofc_item_random_params() - description = "desc of %s" % n - ofc_description = self.get_ofc_description(description) - - tenant_path = "/tenants/%s" % _ofc(t) - post_path = "%s/networks" % tenant_path - body = {'description': ofc_description} - network = {'id': _ofc(n)} - self.do_request.return_value = network - - ret = self.driver.create_network(tenant_path, description, n) - self.do_request.assert_called_once_with("POST", post_path, body=body) - net_path = "/tenants/%s/networks/%s" % (_ofc(t), _ofc(n)) - self.assertEqual(ret, net_path) - - def testf_delete_network(self): - t, n, p = self.get_ofc_item_random_params() - - net_path = "/tenants/%s/networks/%s" % (_ofc(t), _ofc(n)) - - self.driver.delete_network(net_path) - self.do_request.assert_called_once_with("DELETE", net_path) - - def _test_create_port(self, call_filters_arg=None, send_filters_arg=None): - t, n, p = self.get_ofc_item_random_params() - - net_path = "/tenants/%s/networks/%s" % (_ofc(t), _ofc(n)) - post_path = "%s/ports" % net_path - port_path = "/tenants/%s/networks/%s/ports/%s" % (_ofc(t), _ofc(n), - _ofc(p.id)) - body = {'datapath_id': p.datapath_id, - 'port': str(p.port_no), - 'vid': str(p.vlan_id)} - if send_filters_arg is not None: - body['filters'] = send_filters_arg - port = {'id': _ofc(p.id)} - self.do_request.return_value = port - - if call_filters_arg is not None: - ret = self.driver.create_port(net_path, p, p.id, call_filters_arg) - else: - ret = self.driver.create_port(net_path, p, p.id) - self.do_request.assert_called_once_with("POST", post_path, body=body) - self.assertEqual(ret, port_path) - - def testg_create_port(self): - self._test_create_port() - - def test_create_port_with_filters_argument(self): - # If no filter support, 'filters' argument is passed to OFC. - # Note that it will be overridden in a test class with filter support. - self._test_create_port(call_filters_arg=['dummy'], - send_filters_arg=None) - - def testh_delete_port(self): - t, n, p = self.get_ofc_item_random_params() - - port_path = "/tenants/%s/networks/%s/ports/%s" % (_ofc(t), _ofc(n), - _ofc(p.id)) - - self.driver.delete_port(port_path) - self.do_request.assert_called_once_with("DELETE", port_path) - - def test_filter_supported(self): - self.assertEqual(self.filter_supported, self.driver.filter_supported()) - - -class PFCDriverBaseTest(PFCDriverTestBase): - - def test_extract_ofc_network_id(self): - network_id = '/tenants/tenant-a/networks/network-a' - self.assertEqual('network-a', - self.driver._extract_ofc_network_id(network_id)) - - def test_extract_ofc_network_id_failure(self): - network_id = '/tenants/tenant-a/networks/network-a/dummy' - self.assertRaises(pfc.InvalidOFCIdFormat, - self.driver._extract_ofc_network_id, network_id) - - def test_extract_ofc_port_id(self): - port_id = '/tenants/tenant-a/networks/network-a/ports/port-a' - self.assertEqual({'tenant': 'tenant-a', - 'network': 'network-a', - 'port': 'port-a'}, - self.driver._extract_ofc_port_id(port_id)) - - def test_extract_ofc_port_id_failure(self): - port_id = '/tenants/tenant-a/dummy/network-a/ports/port-a' - self.assertRaises(pfc.InvalidOFCIdFormat, - self.driver._extract_ofc_port_id, port_id) - - -class PFCV3DriverTest(PFCDriverTestBase): - driver = 'pfc_v3' - - def testa_create_tenant(self): - t, n, p = self.get_ofc_item_random_params() - ret = self.driver.create_tenant('dummy_desc', t) - self.assertEqual(0, self.do_request.call_count) - ofc_t_path = "/tenants/" + self._generate_ofc_tenant_id(t) - self.assertEqual(ofc_t_path, ret) - - def testc_delete_tenant(self): - t, n, p = self.get_ofc_item_random_params() - path = "/tenants/%s" % _ofc(t) - self.driver.delete_tenant(path) - self.assertEqual(0, self.do_request.call_count) - - -class PFCV4DriverTest(PFCDriverTestBase): - driver = 'pfc_v4' - - -class PFCV5DriverTest(PFCDriverTestBase): - driver = 'pfc_v5' - - def test_create_router(self): - t = uuidutils.generate_uuid() - r = uuidutils.generate_uuid() - description = 'dummy_router_desc' - - tenant_path = "/tenants/%s" % _ofc(t) - post_path = "%s/routers" % tenant_path - router = {'id': _ofc(r)} - self.do_request.return_value = router - - ret = self.driver.create_router(tenant_path, description, r) - self.do_request.assert_called_once_with("POST", post_path, body=None) - router_path = "/tenants/%s/routers/%s" % (_ofc(t), _ofc(r)) - self.assertEqual(ret, router_path) - - def test_delete_router(self): - t = uuidutils.generate_uuid() - r = uuidutils.generate_uuid() - - router_path = "/tenants/%s/routers/%s" % (_ofc(t), _ofc(r)) - - self.driver.delete_router(router_path) - self.do_request.assert_called_once_with("DELETE", router_path) - - def test_add_router_interface(self): - t = uuidutils.generate_uuid() - r = uuidutils.generate_uuid() - n = uuidutils.generate_uuid() - p = uuidutils.generate_uuid() - - router_path = "/tenants/%s/routers/%s" % (_ofc(t), _ofc(r)) - infs_path = router_path + "/interfaces" - net_path = "/tenants/%s/networks/%s" % (_ofc(t), _ofc(n)) - ip_address = '10.1.1.1/24' - mac_address = '11:22:33:44:55:66' - body = {'net_id': _ofc(n), - 'ip_address': ip_address, - 'mac_address': mac_address} - inf = {'id': _ofc(p)} - self.do_request.return_value = inf - - ret = self.driver.add_router_interface(router_path, net_path, - ip_address, mac_address) - self.do_request.assert_called_once_with("POST", infs_path, body=body) - - inf_path = "%s/interfaces/%s" % (router_path, _ofc(p)) - self.assertEqual(ret, inf_path) - - def test_update_router_interface(self): - t = uuidutils.generate_uuid() - r = uuidutils.generate_uuid() - p = uuidutils.generate_uuid() - - router_path = "/tenants/%s/routers/%s" % (_ofc(t), _ofc(r)) - inf_path = "%s/interfaces/%s" % (router_path, _ofc(p)) - ip_address = '10.1.1.1/24' - mac_address = '11:22:33:44:55:66' - - self.driver.update_router_interface(inf_path, ip_address, mac_address) - self.driver.update_router_interface(inf_path, ip_address=ip_address) - self.driver.update_router_interface(inf_path, mac_address=mac_address) - - self.do_request.assert_has_calls([ - mock.call("PUT", inf_path, body={'ip_address': ip_address, - 'mac_address': mac_address}), - mock.call("PUT", inf_path, body={'ip_address': ip_address}), - mock.call("PUT", inf_path, body={'mac_address': mac_address}), - ]) - - def test_delete_router_interface(self): - t = uuidutils.generate_uuid() - r = uuidutils.generate_uuid() - p = uuidutils.generate_uuid() - - router_path = "/tenants/%s/routers/%s" % (_ofc(t), _ofc(r)) - inf_path = "%s/interfaces/%s" % (router_path, _ofc(p)) - - self.driver.delete_router_interface(inf_path) - self.do_request.assert_called_once_with("DELETE", inf_path) - - def _get_route_id(self, dest, nexthop): - dest = netaddr.IPNetwork(dest) - return '-'.join([str(dest.network), nexthop, str(dest.netmask)]) - - def test_add_router_route(self): - t = uuidutils.generate_uuid() - r = uuidutils.generate_uuid() - - router_path = "/tenants/%s/routers/%s" % (_ofc(t), _ofc(r)) - routes_path = router_path + "/routes" - dest = '10.1.1.0/24' - nexthop = '192.168.100.10' - body = {'destination': dest, 'nexthop': nexthop} - route_id = self._get_route_id(dest, nexthop) - self.do_request.return_value = {'id': route_id} - - ret = self.driver.add_router_route(router_path, '10.1.1.0/24', - '192.168.100.10') - self.do_request.assert_called_once_with("POST", routes_path, body=body) - route_path = routes_path + '/' + route_id - self.assertEqual(ret, route_path) - - def test_delete_router_route(self): - t = uuidutils.generate_uuid() - r = uuidutils.generate_uuid() - - router_path = "/tenants/%s/routers/%s" % (_ofc(t), _ofc(r)) - routes_path = router_path + "/routes" - - route_id = self._get_route_id('10.1.1.0/24', '192.168.100.10') - route_path = routes_path + '/' + route_id - - self.driver.delete_router_route(route_path) - self.do_request.assert_called_once_with("DELETE", route_path) - - def test_list_router_routes(self): - t = uuidutils.generate_uuid() - r = uuidutils.generate_uuid() - - router_path = "/tenants/%s/routers/%s" % (_ofc(t), _ofc(r)) - routes_path = router_path + "/routes" - - routes = [('10.1.1.0/24', '192.168.100.10'), - ('10.2.2.0/20', '192.168.100.20')] - data = {'routes': [{'id': self._get_route_id(route[0], route[1]), - 'destination': route[0], 'nexthop': route[1]} - for route in routes]} - self.do_request.return_value = data - - ret = self.driver.list_router_routes(router_path) - self.do_request.assert_called_once_with("GET", routes_path) - - expected = [{'id': (routes_path + "/" + - self._get_route_id(route[0], route[1])), - 'destination': route[0], 'nexthop': route[1]} - for route in routes] - self.assertEqual(len(routes), len(ret)) - self.assertEqual(data['routes'], expected) - - -class PFCFilterDriverTestMixin: - def _test_create_filter(self, filter_dict=None, filter_post=None, - apply_ports=None): - t, n, p = self.get_ofc_item_random_params() - - filter_id = uuidutils.generate_uuid() - f = {'priority': 123, 'action': "ACCEPT"} - if filter_dict: - f.update(filter_dict) - - net_path = "/networks/%s" % n - body = {'action': 'pass', 'priority': 123} - if filter_post: - body.update(filter_post) - - self.do_request.return_value = {'id': filter_id} - if apply_ports is not None: - ret = self.driver.create_filter(net_path, f, p, - apply_ports=apply_ports) - else: - ret = self.driver.create_filter(net_path, f, p) - self.do_request.assert_called_once_with("POST", "/filters", - body=body) - self.assertEqual(ret, '/filters/%s' % filter_id) - - def test_create_filter_accept(self): - self._test_create_filter(filter_dict={'action': 'ACCEPT'}) - - def test_create_filter_allow(self): - self._test_create_filter(filter_dict={'action': 'ALLOW'}) - - def test_create_filter_deny(self): - self._test_create_filter(filter_dict={'action': 'DENY'}, - filter_post={'action': 'drop'}) - - def test_create_filter_drop(self): - self._test_create_filter(filter_dict={'action': 'DROP'}, - filter_post={'action': 'drop'}) - - def test_create_filter_empty_field_not_post(self): - filter_dict = {'src_mac': '', 'src_cidr': '', 'src_port': 0, - 'dst_mac': '', 'dst_cidr': '', 'dst_port': 0, - 'protocol': '', 'eth_type': 0} - filter_post = {} - self._test_create_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_create_filter_none_field_not_post(self): - filter_dict = {'src_mac': None, 'src_cidr': None, 'src_port': None, - 'dst_mac': None, 'dst_cidr': None, 'dst_port': None, - 'protocol': None, 'eth_type': None} - filter_post = {} - self._test_create_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_create_filter_all_fields(self): - filter_dict = {'src_mac': '11:22:33:44:55:66', - 'dst_mac': '77:88:99:aa:bb:cc', - 'src_cidr': '192.168.3.0/24', - 'dst_cidr': '10.11.240.0/20', - 'src_port': 12345, - 'dst_port': 23456, - 'protocol': '0x10', - 'eth_type': 0x800} - filter_post = filter_dict.copy() - filter_post['protocol'] = 16 - filter_post['eth_type'] = '0x800' - self._test_create_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_create_filter_cidr_ip_addr_32(self): - filter_dict = {'src_cidr': '192.168.3.1', - 'dst_cidr': '10.11.240.2'} - filter_post = {'src_cidr': '192.168.3.1/32', - 'dst_cidr': '10.11.240.2/32'} - self._test_create_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_create_filter_proto_tcp(self): - filter_dict = {'protocol': 'TCP'} - filter_post = {'protocol': constants.PROTO_NUM_TCP} - self._test_create_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_create_filter_proto_udp(self): - filter_dict = {'protocol': 'UDP'} - filter_post = {'protocol': constants.PROTO_NUM_UDP} - self._test_create_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_create_filter_proto_icmp(self): - filter_dict = {'protocol': 'ICMP'} - filter_post = {'protocol': constants.PROTO_NUM_ICMP} - self._test_create_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_create_filter_proto_arp_not_proto_post(self): - filter_dict = {'protocol': 'ARP'} - filter_post = {} - self._test_create_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_create_filter_apply_ports(self): - apply_ports = [ - ('p1', '/tenants/tenant-1/networks/network-1/ports/port-1'), - ('p2', '/tenants/tenant-2/networks/network-2/ports/port-2')] - filter_post = {'apply_ports': [ - {'tenant': 'tenant-1', 'network': 'network-1', 'port': 'port-1'}, - {'tenant': 'tenant-2', 'network': 'network-2', 'port': 'port-2'} - ]} - self._test_create_filter(filter_dict={}, apply_ports=apply_ports, - filter_post=filter_post) - - def _test_update_filter(self, filter_dict=None, filter_post=None): - filter_id = uuidutils.generate_uuid() - ofc_filter_id = '/filters/%s' % filter_id - self.driver.update_filter(ofc_filter_id, filter_dict) - self.do_request.assert_called_once_with("PUT", ofc_filter_id, - body=filter_post) - - def test_update_filter_empty_fields(self): - filter_dict = {'src_mac': '', 'src_cidr': '', 'src_port': 0, - 'dst_mac': '', 'dst_cidr': '', 'dst_port': 0, - 'protocol': '', 'eth_type': 0} - filter_post = {'src_mac': '', 'src_cidr': '', 'src_port': '', - 'dst_mac': '', 'dst_cidr': '', 'dst_port': '', - 'protocol': '', 'eth_type': ''} - self._test_update_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_update_filter_none_fields(self): - filter_dict = {'src_mac': None, 'src_cidr': None, 'src_port': None, - 'dst_mac': None, 'dst_cidr': None, 'dst_port': None, - 'protocol': None, 'eth_type': None} - filter_post = {'src_mac': '', 'src_cidr': '', 'src_port': '', - 'dst_mac': '', 'dst_cidr': '', 'dst_port': '', - 'protocol': '', 'eth_type': ''} - self._test_update_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_update_filter_all_fields(self): - filter_dict = {'src_mac': '11:22:33:44:55:66', - 'dst_mac': '77:88:99:aa:bb:cc', - 'src_cidr': '192.168.3.0/24', - 'dst_cidr': '10.11.240.0/20', - 'src_port': 12345, - 'dst_port': 23456, - 'protocol': '0x10', - 'eth_type': 0x800} - filter_post = filter_dict.copy() - filter_post['protocol'] = 16 - filter_post['eth_type'] = '0x800' - self._test_update_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_update_filter_cidr_ip_addr_32(self): - filter_dict = {'src_cidr': '192.168.3.1', - 'dst_cidr': '10.11.240.2'} - filter_post = {'src_cidr': '192.168.3.1/32', - 'dst_cidr': '10.11.240.2/32'} - self._test_update_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_update_filter_proto_tcp(self): - filter_dict = {'protocol': 'TCP'} - filter_post = {'protocol': constants.PROTO_NUM_TCP} - self._test_update_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_update_filter_proto_udp(self): - filter_dict = {'protocol': 'UDP'} - filter_post = {'protocol': constants.PROTO_NUM_UDP} - self._test_update_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_update_filter_proto_icmp(self): - filter_dict = {'protocol': 'ICMP'} - filter_post = {'protocol': constants.PROTO_NUM_ICMP} - self._test_update_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_update_filter_proto_arp_post_empty(self): - filter_dict = {'protocol': 'ARP'} - filter_post = {'protocol': ''} - self._test_update_filter(filter_dict=filter_dict, - filter_post=filter_post) - - def test_delete_filter(self): - t, n, p = self.get_ofc_item_random_params() - f_path = "/filters/%s" % uuidutils.generate_uuid() - self.driver.delete_filter(f_path) - self.do_request.assert_called_once_with("DELETE", f_path) - - def _test_validate_filter_duplicate_priority(self, method, found_dup): - with mock.patch('neutron.manager.NeutronManager' - '.get_plugin') as get_plugin: - plugin = get_plugin.return_value - if found_dup: - plugin.get_packet_filters.return_value = ['found'] - else: - plugin.get_packet_filters.return_value = [] - network_id = str(uuid.uuid4()) - filter_dict = {'network_id': network_id, - 'priority': 12} - if found_dup: - self.assertRaises(ext_pf.PacketFilterDuplicatedPriority, - method, 'context', filter_dict) - else: - self.assertIsNone(method('context', filter_dict)) - plugin.get_packet_filters.assert_called_once_with( - 'context', - filters={'network_id': [network_id], - 'priority': [12]}, - fields=['id']) - - def test_validate_filter_create_no_duplicate_priority(self): - self._test_validate_filter_duplicate_priority( - self.driver.validate_filter_create, - found_dup=False) - - def test_validate_filter_create_duplicate_priority(self): - self._test_validate_filter_duplicate_priority( - self.driver.validate_filter_create, - found_dup=True) - - def test_validate_filter_update_action_raises_error(self): - filter_dict = {'action': 'ALLOW'} - self.assertRaises(ext_pf.PacketFilterUpdateNotSupported, - self.driver.validate_filter_update, - 'context', filter_dict) - - def test_validate_filter_update_priority_raises_error(self): - filter_dict = {'priority': '13'} - self.assertRaises(ext_pf.PacketFilterUpdateNotSupported, - self.driver.validate_filter_update, - 'context', filter_dict) - - def _test_validate_filter_ipv6_not_supported(self, field, create=True): - if create: - filter_dict = {'network_id': 'net1', 'priority': 12} - method = self.driver.validate_filter_create - else: - filter_dict = {} - method = self.driver.validate_filter_update - filter_dict[field] = 'fe80::1' - self.assertRaises(ext_pf.PacketFilterIpVersionNonSupported, - method, 'context', filter_dict) - filter_dict[field] = '10.56.3.3' - self.assertIsNone(method('context', filter_dict)) - - def test_validate_filter_create_ipv6_not_supported(self): - with mock.patch('neutron.manager.NeutronManager' - '.get_plugin') as get_plugin: - plugin = get_plugin.return_value - plugin.get_packet_filters.return_value = [] - self._test_validate_filter_ipv6_not_supported( - 'src_cidr', create=True) - self._test_validate_filter_ipv6_not_supported( - 'dst_cidr', create=True) - - def test_validate_filter_update_ipv6_not_supported(self): - self._test_validate_filter_ipv6_not_supported('src_cidr', create=False) - self._test_validate_filter_ipv6_not_supported('dst_cidr', create=False) - - def _test_validate_filter_priority_range_one(self, method, priority, ok): - filter_dict = {'priority': priority, 'network_id': 'net1'} - if ok: - self.assertIsNone(method('context', filter_dict)) - else: - self.assertRaises(ext_pf.PacketFilterInvalidPriority, - method, 'context', filter_dict) - - def test_validate_filter_create_priority_range(self): - with mock.patch('neutron.manager.NeutronManager' - '.get_plugin') as get_plugin: - plugin = get_plugin.return_value - plugin.get_packet_filters.return_value = [] - - method = self.driver.validate_filter_create - self._test_validate_filter_priority_range_one(method, 0, False) - self._test_validate_filter_priority_range_one(method, 1, True) - self._test_validate_filter_priority_range_one(method, 32766, True) - self._test_validate_filter_priority_range_one(method, 32767, False) - - -class PFCV51DriverTest(PFCFilterDriverTestMixin, PFCV5DriverTest): - driver = 'pfc_v51' - filter_supported = True - - def test_create_port_with_filters_argument(self): - self._test_create_port( - call_filters_arg=[('neutron-id-1', '/filters/filter-1'), - ('neutron-id-2', '/filters/filter-2')], - send_filters_arg=['filter-1', 'filter-2']) - - -class PFCDriverStringTest(base.BaseTestCase): - - driver = 'neutron.plugins.nec.drivers.pfc.PFCDriverBase' - - def setUp(self): - super(PFCDriverStringTest, self).setUp() - self.driver = drivers.get_driver(self.driver)(TestConfig) - - def test_generate_pfc_id_uuid(self): - id_str = uuidutils.generate_uuid() - exp_str = (id_str[:14] + id_str[15:]).replace('-', '')[:31] - - ret_str = self.driver._generate_pfc_id(id_str) - self.assertEqual(exp_str, ret_str) - - def test_generate_pfc_id_uuid_no_hyphen(self): - # Keystone tenant_id style uuid - id_str = uuidutils.generate_uuid() - id_no_hyphen = id_str.replace('-', '') - exp_str = (id_str[:14] + id_str[15:]).replace('-', '')[:31] - - ret_str = self.driver._generate_pfc_id(id_no_hyphen) - self.assertEqual(exp_str, ret_str) - - def test_generate_pfc_id_string(self): - id_str = uuidutils.generate_uuid() + 'x' - exp_str = id_str[:31].replace('-', '_') - - ret_str = self.driver._generate_pfc_id(id_str) - self.assertEqual(exp_str, ret_str) - - def test_generate_pfc_desc(self): - random_list = [random.choice(string.printable) for x in range(128)] - random_str = ''.join(random_list) - - accept_letters = string.letters + string.digits - exp_list = [x if x in accept_letters else '_' for x in random_list] - exp_str = ''.join(exp_list)[:127] - - ret_str = self.driver._generate_pfc_description(random_str) - self.assertEqual(exp_str, ret_str) diff --git a/neutron/tests/unit/nec/test_portbindings.py b/neutron/tests/unit/nec/test_portbindings.py deleted file mode 100644 index f9aca7294..000000000 --- a/neutron/tests/unit/nec/test_portbindings.py +++ /dev/null @@ -1,350 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 NEC Corporation -# All rights reserved. -# -# 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. -# -# @author: Akihiro Motoki, NEC Corporation - -from oslo.config import cfg -from testtools import matchers -from webob import exc - -from neutron.common import exceptions as n_exc -from neutron import context -from neutron.extensions import portbindings -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit.nec import test_nec_plugin -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - - -class TestNecPortBinding(test_bindings.PortBindingsTestCase, - test_nec_plugin.NecPluginV2TestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - HAS_PORT_FILTER = True - ENABLE_SG = True - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_HYBRID_DRIVER - - def setUp(self): - test_sg_rpc.set_firewall_driver(self.FIREWALL_DRIVER) - cfg.CONF.set_override( - 'enable_security_group', self.ENABLE_SG, - group='SECURITYGROUP') - super(TestNecPortBinding, self).setUp() - - -class TestNecPortBindingNoSG(TestNecPortBinding): - HAS_PORT_FILTER = False - ENABLE_SG = False - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER - - -class TestNecPortBindingHost( - test_bindings.PortBindingsHostTestCaseMixin, - test_nec_plugin.NecPluginV2TestCase): - pass - - -class TestNecPortBindingPortInfo(test_nec_plugin.NecPluginV2TestCase): - def _get_portinfo(self, datapath_id=None, port_no=None): - if datapath_id is None: - datapath_id = '0xabc' - if port_no is None: - port_no = 1 - return {'datapath_id': datapath_id, - 'port_no': port_no} - - def _check_response_portbinding_profile(self, port, datapath_id=None, - port_no=None): - expected = self._get_portinfo(datapath_id, port_no) - profile = port[portbindings.PROFILE] - self.assertEqual(len(profile), 2) - self.assertEqual(profile['datapath_id'], - expected['datapath_id']) - self.assertEqual(profile['port_no'], - expected['port_no']) - - def _check_response_portbinding_no_profile(self, port): - self.assertIn('status', port) - self.assertNotIn(portbindings.PROFILE, port) - - def _get_non_admin_context(self): - return context.Context(user_id=None, - tenant_id=self._tenant_id, - is_admin=False, - read_deleted="no") - - def test_port_create_portinfo(self): - profile_arg = {portbindings.PROFILE: self._get_portinfo()} - with self.port(arg_list=(portbindings.PROFILE,), - **profile_arg) as port: - port_id = port['port']['id'] - # Check a response of create_port - self._check_response_portbinding_profile(port['port']) - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - # Check a response of get_port - ctx = context.get_admin_context() - port = self._show('ports', port_id, neutron_context=ctx)['port'] - self._check_response_portbinding_profile(port) - # By default user is admin - now test non admin user - ctx = self._get_non_admin_context() - non_admin_port = self._show( - 'ports', port_id, neutron_context=ctx)['port'] - self._check_response_portbinding_no_profile(non_admin_port) - # port-update with non admin user should fail - self._update('ports', port_id, - {'port': profile_arg}, - expected_code=404, - neutron_context=ctx) - - def test_port_update_portinfo(self): - profile_arg = {portbindings.PROFILE: self._get_portinfo()} - with self.port() as port: - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - port_id = port['port']['id'] - # Check a response of create_port - self._check_response_portbinding_no_profile(port['port']) - # Check a response of update_port - ctx = context.get_admin_context() - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self._check_response_portbinding_profile(port) - port = self._show('ports', port_id, neutron_context=ctx)['port'] - self._check_response_portbinding_profile(port) - - def test_port_update_portinfo_detail(self): - with self.port() as port: - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - port_id = port['port']['id'] - ctx = context.get_admin_context() - - # add portinfo - profile_arg = {portbindings.PROFILE: self._get_portinfo()} - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - - # portinfo unchanged - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - - # modify portinfo - profile_arg = {portbindings.PROFILE: - self._get_portinfo(datapath_id='0x1234567890', - port_no=99)} - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self.assertEqual(self.ofc.create_ofc_port.call_count, 2) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - - # delete portinfo with an empty dict - profile_arg = {portbindings.PROFILE: {}} - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self.assertEqual(self.ofc.create_ofc_port.call_count, 2) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 2) - - def test_port_update_portinfo_detail_clear_with_none(self): - with self.port() as port: - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - port_id = port['port']['id'] - ctx = context.get_admin_context() - - # add portinfo - profile_arg = {portbindings.PROFILE: self._get_portinfo()} - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - - # delete portinfo with None - profile_arg = {portbindings.PROFILE: None} - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 1) - - def test_port_create_portinfo_with_empty_dict(self): - profile_arg = {portbindings.PROFILE: {}} - with self.port(arg_list=(portbindings.PROFILE,), - **profile_arg) as port: - port_id = port['port']['id'] - - # Check a response of create_port - self._check_response_portbinding_no_profile(port['port']) - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - # add portinfo - ctx = context.get_admin_context() - profile_arg = {portbindings.PROFILE: self._get_portinfo()} - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self._check_response_portbinding_profile(port) - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - - def test_port_create_portinfo_with_none(self): - profile_arg = {portbindings.PROFILE: None} - with self.port(arg_list=(portbindings.PROFILE,), - **profile_arg) as port: - port_id = port['port']['id'] - - # Check a response of create_port - self._check_response_portbinding_no_profile(port['port']) - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - # add portinfo - ctx = context.get_admin_context() - profile_arg = {portbindings.PROFILE: self._get_portinfo()} - port = self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx)['port'] - self._check_response_portbinding_profile(port) - self.assertEqual(self.ofc.create_ofc_port.call_count, 1) - self.assertEqual(self.ofc.delete_ofc_port.call_count, 0) - - def test_port_update_for_existing_port_with_different_padding_dpid(self): - ctx = context.get_admin_context() - with self.port() as port: - port_id = port['port']['id'] - portinfo = {'id': port_id, 'port_no': 123} - self.rpcapi_update_ports(datapath_id='0x000000000000abcd', - added=[portinfo]) - self.assertEqual(1, self.ofc.create_ofc_port.call_count) - self.assertEqual(0, self.ofc.delete_ofc_port.call_count) - - profile_arg = {portbindings.PROFILE: - self._get_portinfo(datapath_id='0xabcd', - port_no=123)} - self._update('ports', port_id, {'port': profile_arg}, - neutron_context=ctx) - # Check create_ofc_port/delete_ofc_port are not called. - self.assertEqual(1, self.ofc.create_ofc_port.call_count) - self.assertEqual(0, self.ofc.delete_ofc_port.call_count) - - def test_port_create_portinfo_non_admin(self): - with self.network(set_context=True, tenant_id='test') as net1: - with self.subnet(network=net1) as subnet1: - profile_arg = {portbindings.PROFILE: self._get_portinfo()} - try: - with self.port(subnet=subnet1, - expected_res_status=403, - arg_list=(portbindings.PROFILE,), - set_context=True, tenant_id='test', - **profile_arg): - pass - except exc.HTTPClientError: - pass - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - - def test_port_update_portinfo_non_admin(self): - profile_arg = {portbindings.PROFILE: self._get_portinfo()} - with self.network() as net1: - with self.subnet(network=net1) as subnet1: - with self.port(subnet=subnet1) as port: - # By default user is admin - now test non admin user - # Note that 404 is returned when prohibit by policy. - # See comment for PolicyNotAuthorized except clause - # in update() in neutron.api.v2.base.Controller. - port_id = port['port']['id'] - ctx = self._get_non_admin_context() - port = self._update('ports', port_id, - {'port': profile_arg}, - expected_code=404, - neutron_context=ctx) - self.assertEqual(self.ofc.create_ofc_port.call_count, 0) - - def test_port_create_portinfo_validation_called(self): - # Check validate_portinfo is called. - profile_arg = {portbindings.PROFILE: - {'datapath_id': '0xabc', - 'port_no': 0xffff + 1}} - try: - with self.port(arg_list=(portbindings.PROFILE,), - expected_res_status=400, - **profile_arg): - pass - except exc.HTTPClientError: - pass - - -class TestNecPortBindingValidatePortInfo(test_nec_plugin.NecPluginV2TestCase): - - def test_validate_portinfo_ok(self): - profile = {'datapath_id': '0x1234567890abcdef', - 'port_no': 123} - portinfo = self.plugin._validate_portinfo(profile) - # NOTE(mriedem): Handle long integer conversion universally. - self.assertEqual( - 0x1234567890abcdef, - int(portinfo['datapath_id'].replace('L', ''), 16) - ) - self.assertEqual(portinfo['port_no'], 123) - - def test_validate_portinfo_ok_without_0x(self): - profile = {'datapath_id': '1234567890abcdef', - 'port_no': 123} - portinfo = self.plugin._validate_portinfo(profile) - # NOTE(mriedem): Handle long integer conversion universally. - self.assertEqual( - 0x1234567890abcdef, - int(portinfo['datapath_id'].replace('L', ''), 16) - ) - self.assertEqual(portinfo['port_no'], 123) - - def _test_validate_exception(self, profile, expected_msg): - e = self.assertRaises(n_exc.InvalidInput, - self.plugin._validate_portinfo, profile) - self.assertThat(str(e), matchers.StartsWith(expected_msg)) - - def test_validate_portinfo_dict_validation(self): - expected_msg = ("Invalid input for operation: " - "Validation of dictionary's keys failed.") - - profile = {'port_no': 123} - self._test_validate_exception(profile, expected_msg) - - profile = {'datapath_id': '0xabcdef'} - self._test_validate_exception(profile, expected_msg) - - def test_validate_portinfo_negative_port_number(self): - profile = {'datapath_id': '0x1234567890abcdef', - 'port_no': -1} - expected_msg = ("Invalid input for operation: " - "'-1' should be non-negative.") - self._test_validate_exception(profile, expected_msg) - - def test_validate_portinfo_invalid_datapath_id(self): - expected_msg = ("Invalid input for operation: " - "datapath_id should be a hex string") - - # non hexidecimal datapath_id - profile = {'datapath_id': 'INVALID', - 'port_no': 123} - self._test_validate_exception(profile, expected_msg) - - # Too big datapath_id - profile = {'datapath_id': '0x10000000000000000', - 'port_no': 123} - self._test_validate_exception(profile, expected_msg) - - def test_validate_portinfo_too_big_port_number(self): - profile = {'datapath_id': '0x1234567890abcdef', - 'port_no': 65536} - expected_msg = ("Invalid input for operation: " - "port_no should be [0:65535]") - self._test_validate_exception(profile, expected_msg) diff --git a/neutron/tests/unit/nec/test_router.py b/neutron/tests/unit/nec/test_router.py deleted file mode 100644 index 5f3fc0035..000000000 --- a/neutron/tests/unit/nec/test_router.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 neutron import manager -from neutron.plugins.nec.common import config -from neutron.tests.unit.nec import test_nec_plugin -from neutron.tests.unit import test_extension_extraroute as test_ext_route - - -class NecRouterL3AgentTestCase(test_ext_route.ExtraRouteDBIntTestCase): - - _plugin_name = test_nec_plugin.PLUGIN_NAME - - def setUp(self): - mock.patch(test_nec_plugin.OFC_MANAGER).start() - super(NecRouterL3AgentTestCase, self).setUp(self._plugin_name) - - plugin = manager.NeutronManager.get_plugin() - plugin.network_scheduler = None - plugin.router_scheduler = None - - def test_floatingip_with_invalid_create_port(self): - self._test_floatingip_with_invalid_create_port(self._plugin_name) - - -class NecRouterOpenFlowTestCase(NecRouterL3AgentTestCase): - - def setUp(self): - config.CONF.set_override('default_router_provider', - 'openflow', 'PROVIDER') - super(NecRouterOpenFlowTestCase, self).setUp() diff --git a/neutron/tests/unit/nec/test_security_group.py b/neutron/tests/unit/nec/test_security_group.py deleted file mode 100644 index 5b2264596..000000000 --- a/neutron/tests/unit/nec/test_security_group.py +++ /dev/null @@ -1,101 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013, NEC Corporation -# All Rights Reserved. -# -# 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 contextlib - -import mock - -from neutron.api.v2 import attributes -from neutron.extensions import securitygroup as ext_sg -from neutron import manager -from neutron.plugins.nec.db import api as ndb # noqa -from neutron.tests.unit.nec import test_nec_plugin -from neutron.tests.unit import test_extension_security_group as test_sg -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - -PLUGIN_NAME = test_nec_plugin.PLUGIN_NAME -OFC_MANAGER = 'neutron.plugins.nec.nec_plugin.ofc_manager.OFCManager' -NOTIFIER = 'neutron.plugins.nec.nec_plugin.NECPluginV2AgentNotifierApi' - - -class NecSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): - - def setUp(self, plugin=None): - test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER) - mock.patch(NOTIFIER).start() - mock.patch(OFC_MANAGER).start() - self._attribute_map_bk_ = {} - for item in attributes.RESOURCE_ATTRIBUTE_MAP: - self._attribute_map_bk_[item] = (attributes. - RESOURCE_ATTRIBUTE_MAP[item]. - copy()) - super(NecSecurityGroupsTestCase, self).setUp(PLUGIN_NAME) - plugin = manager.NeutronManager.get_plugin() - self.notifier = plugin.notifier - self.rpc = plugin.callback_sg - - def tearDown(self): - super(NecSecurityGroupsTestCase, self).tearDown() - attributes.RESOURCE_ATTRIBUTE_MAP = self._attribute_map_bk_ - - -class TestNecSGServerRpcCallBack( - test_sg_rpc.SGServerRpcCallBackMixinTestCase, - NecSecurityGroupsTestCase): - pass - - -class TestNecSGServerRpcCallBackXML( - test_sg_rpc.SGServerRpcCallBackMixinTestCaseXML, - NecSecurityGroupsTestCase): - pass - - -class TestNecSecurityGroups(NecSecurityGroupsTestCase, - test_sg.TestSecurityGroups, - test_sg_rpc.SGNotificationTestMixin): - - def test_security_group_get_port_from_device(self): - with contextlib.nested(self.network(), - self.security_group()) as (n, sg): - with self.subnet(n): - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - port_id = port['port']['id'] - sg_id = sg['security_group']['id'] - fixed_ips = port['port']['fixed_ips'] - - data = {'port': {'fixed_ips': fixed_ips, - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: [sg_id]}} - req = self.new_update_request('ports', data, port_id) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - - plugin = manager.NeutronManager.get_plugin() - port_dict = plugin.callback_sg.get_port_from_device(port_id) - self.assertEqual(port_id, port_dict['id']) - self.assertEqual([sg_id], - port_dict[ext_sg.SECURITYGROUPS]) - self.assertEqual([], port_dict['security_group_rules']) - self.assertEqual([fixed_ips[0]['ip_address']], - port_dict['fixed_ips']) - self._delete('ports', port_id) - - -class TestNecSecurityGroupsXML(TestNecSecurityGroups): - fmt = 'xml' diff --git a/neutron/tests/unit/nec/test_trema_driver.py b/neutron/tests/unit/nec/test_trema_driver.py deleted file mode 100644 index 484d65dd9..000000000 --- a/neutron/tests/unit/nec/test_trema_driver.py +++ /dev/null @@ -1,353 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 NEC Corporation. All rights reserved. -# -# 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. -# @author: Ryota MIBU - -import random - -import mock -from six import moves - -from neutron.openstack.common import uuidutils -from neutron.plugins.nec.common import ofc_client -from neutron.plugins.nec.db import models as nmodels -from neutron.plugins.nec import drivers -from neutron.tests import base - - -class TestConfig(object): - """Configuration for this test.""" - host = '127.0.0.1' - port = 8888 - - -class TremaDriverTestBase(base.BaseTestCase): - - driver_name = "trema" - - def setUp(self): - super(TremaDriverTestBase, self).setUp() - self.driver = drivers.get_driver(self.driver_name)(TestConfig) - self.do_request = mock.patch.object(ofc_client.OFCClient, - 'do_request').start() - - def get_ofc_item_random_params(self): - """create random parameters for ofc_item test.""" - tenant_id = uuidutils.generate_uuid() - network_id = uuidutils.generate_uuid() - port_id = uuidutils.generate_uuid() - mac = ':'.join(['%x' % random.randint(0, 255) - for i in moves.xrange(6)]) - portinfo = nmodels.PortInfo(id=port_id, datapath_id="0x123456789", - port_no=1234, vlan_id=321, - mac=mac) - return tenant_id, network_id, portinfo - - -class TremaDriverNetworkTestBase(TremaDriverTestBase): - - def test_create_tenant(self): - t, n, p = self.get_ofc_item_random_params() - ret = self.driver.create_tenant('dummy_desc', t) - ofc_t_path = "/tenants/%s" % t - self.assertEqual(ofc_t_path, ret) - # There is no API call. - self.assertEqual(0, self.do_request.call_count) - - def test_update_tenant(self): - t, n, p = self.get_ofc_item_random_params() - path = "/tenants/%s" % t - self.driver.update_tenant(path, 'dummy_desc') - # There is no API call. - self.assertEqual(0, self.do_request.call_count) - - def testc_delete_tenant(self): - t, n, p = self.get_ofc_item_random_params() - path = "/tenants/%s" % t - self.driver.delete_tenant(path) - # There is no API call. - self.assertEqual(0, self.do_request.call_count) - - def testa_create_network(self): - t, n, p = self.get_ofc_item_random_params() - description = "desc of %s" % n - body = {'id': n, 'description': description} - ret = self.driver.create_network(t, description, n) - self.do_request.assert_called_once_with("POST", "/networks", body=body) - self.assertEqual(ret, '/networks/%s' % n) - - def testc_delete_network(self): - t, n, p = self.get_ofc_item_random_params() - net_path = "/networks/%s" % n - self.driver.delete_network(net_path) - self.do_request.assert_called_once_with("DELETE", net_path) - - -class TremaPortBaseDriverTest(TremaDriverNetworkTestBase): - - driver_name = "trema_port" - - def test_filter_supported(self): - self.assertTrue(self.driver.filter_supported()) - - def testd_create_port(self): - _t, n, p = self.get_ofc_item_random_params() - net_path = "/networks/%s" % n - body = {'id': p.id, - 'datapath_id': p.datapath_id, - 'port': str(p.port_no), - 'vid': str(p.vlan_id)} - ret = self.driver.create_port(net_path, p, p.id) - self.do_request.assert_called_once_with( - "POST", "/networks/%s/ports" % n, body=body) - self.assertEqual(ret, '/networks/%s/ports/%s' % (n, p.id)) - - def testd_delete_port(self): - t, n, p = self.get_ofc_item_random_params() - p_path = "/networks/%s/ports/%s" % (n, p.id) - self.driver.delete_port(p_path) - self.do_request.assert_called_once_with("DELETE", p_path) - - -class TremaPortMACBaseDriverTest(TremaDriverNetworkTestBase): - - driver_name = "trema_portmac" - - def test_filter_supported(self): - self.assertTrue(self.driver.filter_supported()) - - def testd_create_port(self): - t, n, p = self.get_ofc_item_random_params() - dummy_port = "dummy-%s" % p.id - - net_path = "/networks/%s" % n - path_1 = "/networks/%s/ports" % n - body_1 = {'id': dummy_port, - 'datapath_id': p.datapath_id, - 'port': str(p.port_no), - 'vid': str(p.vlan_id)} - path_2 = "/networks/%s/ports/%s/attachments" % (n, dummy_port) - body_2 = {'id': p.id, 'mac': p.mac} - path_3 = "/networks/%s/ports/%s" % (n, dummy_port) - ret = self.driver.create_port(net_path, p, p.id) - - self.do_request.assert_has_calls([ - mock.call("POST", path_1, body=body_1), - mock.call("POST", path_2, body=body_2), - mock.call("DELETE", path_3) - ]) - port_path = "/networks/%s/ports/%s/attachments/%s" % (n, dummy_port, - p.id) - self.assertEqual(ret, port_path) - - def testd_delete_port(self): - t, n, p = self.get_ofc_item_random_params() - dummy_port = "dummy-%s" % p.id - path = "/networks/%s/ports/%s/attachments/%s" % (n, dummy_port, p.id) - self.driver.delete_port(path) - self.do_request.assert_called_once_with("DELETE", path) - - -class TremaMACBaseDriverTest(TremaDriverNetworkTestBase): - - driver_name = "trema_mac" - - def test_filter_supported(self): - self.assertFalse(self.driver.filter_supported()) - - def testd_create_port(self): - t, n, p = self.get_ofc_item_random_params() - net_path = "/networks/%s" % n - path = "/networks/%s/attachments" % n - body = {'id': p.id, 'mac': p.mac} - ret = self.driver.create_port(net_path, p, p.id) - self.do_request.assert_called_once_with("POST", path, body=body) - self.assertEqual(ret, '/networks/%s/attachments/%s' % (n, p.id)) - - def testd_delete_port(self): - t, n, p = self.get_ofc_item_random_params() - path = "/networks/%s/attachments/%s" % (n, p.id) - self.driver.delete_port(path) - self.do_request.assert_called_once_with("DELETE", path) - - -class TremaFilterDriverTest(TremaDriverTestBase): - def _test_create_filter(self, filter_dict=None, filter_post=None, - filter_wildcards=None, no_portinfo=False): - t, n, p = self.get_ofc_item_random_params() - src_mac = ':'.join(['%x' % random.randint(0, 255) - for i in moves.xrange(6)]) - if filter_wildcards is None: - filter_wildcards = [] - - f = {'tenant_id': t, - 'id': uuidutils.generate_uuid(), - 'network_id': n, - 'priority': 123, - 'action': "ACCEPT", - 'in_port': p.id, - 'src_mac': src_mac, - 'dst_mac': "", - 'eth_type': 0, - 'src_cidr': "", - 'dst_cidr': "", - 'src_port': 0, - 'dst_port': 0, - 'protocol': "TCP", - 'admin_state_up': True, - 'status': "ACTIVE"} - if filter_dict: - f.update(filter_dict) - - net_path = "/networks/%s" % n - - all_wildcards_ofp = ['dl_vlan', 'dl_vlan_pcp', 'nw_tos', - 'in_port', 'dl_src', 'dl_dst', - 'nw_src', 'nw_dst', - 'dl_type', 'nw_proto', - 'tp_src', 'tp_dst'] - all_wildcards_non_ofp = ['in_datapath_id', 'slice'] - - body = {'id': f['id'], - 'action': 'ALLOW', - 'priority': 123, - 'slice': n, - 'in_datapath_id': '0x123456789', - 'in_port': 1234, - 'nw_proto': '0x6', - 'dl_type': '0x800', - 'dl_src': src_mac} - if filter_post: - body.update(filter_post) - - if no_portinfo: - filter_wildcards += ['in_datapath_id', 'in_port'] - p = None - - for field in filter_wildcards: - if field in body: - del body[field] - - ofp_wildcards = ["%s:32" % _f if _f in ['nw_src', 'nw_dst'] else _f - for _f in all_wildcards_ofp if _f not in body] - body['ofp_wildcards'] = set(ofp_wildcards) - - non_ofp_wildcards = [_f for _f in all_wildcards_non_ofp - if _f not in body] - if non_ofp_wildcards: - body['wildcards'] = set(non_ofp_wildcards) - - ret = self.driver.create_filter(net_path, f, p, f['id']) - # The content of 'body' is checked below. - self.do_request.assert_called_once_with("POST", "/filters", - body=mock.ANY) - self.assertEqual(ret, '/filters/%s' % f['id']) - - # ofp_wildcards and wildcards in body are comma-separated - # string but the order of elements are not considered, - # so we check these fields as set. - actual_body = self.do_request.call_args[1]['body'] - if 'ofp_wildcards' in actual_body: - ofp_wildcards = actual_body['ofp_wildcards'].split(',') - actual_body['ofp_wildcards'] = set(ofp_wildcards) - if 'wildcards' in actual_body: - actual_body['wildcards'] = set(actual_body['wildcards'].split(',')) - self.assertEqual(body, actual_body) - - def test_create_filter_accept(self): - self._test_create_filter(filter_dict={'action': 'ACCEPT'}) - - def test_create_filter_allow(self): - self._test_create_filter(filter_dict={'action': 'ALLOW'}) - - def test_create_filter_deny(self): - self._test_create_filter(filter_dict={'action': 'DENY'}, - filter_post={'action': 'DENY'}) - - def test_create_filter_drop(self): - self._test_create_filter(filter_dict={'action': 'DROP'}, - filter_post={'action': 'DENY'}) - - def test_create_filter_no_port(self): - self._test_create_filter(no_portinfo=True) - - def test_create_filter_src_mac_wildcard(self): - self._test_create_filter(filter_dict={'src_mac': ''}, - filter_wildcards=['dl_src']) - - def test_create_filter_dst_mac(self): - dst_mac = ':'.join(['%x' % random.randint(0, 255) - for i in moves.xrange(6)]) - self._test_create_filter(filter_dict={'dst_mac': dst_mac}, - filter_post={'dl_dst': dst_mac}) - - def test_create_filter_src_cidr(self): - src_cidr = '10.2.0.0/24' - self._test_create_filter(filter_dict={'src_cidr': src_cidr}, - filter_post={'nw_src': src_cidr}) - - def test_create_filter_dst_cidr(self): - dst_cidr = '192.168.10.0/24' - self._test_create_filter(filter_dict={'dst_cidr': dst_cidr}, - filter_post={'nw_dst': dst_cidr}) - - def test_create_filter_proto_icmp(self): - self._test_create_filter( - filter_dict={'protocol': 'icmp'}, - filter_post={'dl_type': '0x800', 'nw_proto': '0x1'}) - - def test_create_filter_proto_tcp(self): - self._test_create_filter( - filter_dict={'protocol': 'tcp'}, - filter_post={'dl_type': '0x800', 'nw_proto': '0x6'}) - - def test_create_filter_proto_udp(self): - self._test_create_filter( - filter_dict={'protocol': 'udp'}, - filter_post={'dl_type': '0x800', 'nw_proto': '0x11'}) - - def test_create_filter_proto_arp(self): - self._test_create_filter( - filter_dict={'protocol': 'arp'}, - filter_post={'dl_type': '0x806'}, - filter_wildcards=['nw_proto']) - - def test_create_filter_proto_misc(self): - self._test_create_filter( - filter_dict={'protocol': '0x33', 'eth_type': '0x900'}, - filter_post={'dl_type': '0x900', 'nw_proto': '0x33'}) - - def test_create_filter_proto_misc_dl_type_wildcard(self): - self._test_create_filter( - filter_dict={'protocol': '0x33', 'ether_type': ''}, - filter_post={'nw_proto': '0x33'}, - filter_wildcards=['dl_type']) - - def test_create_filter_proto_wildcard(self): - self._test_create_filter( - filter_dict={'protocol': ''}, - filter_wildcards=['dl_type', 'nw_proto']) - - def test_create_filter_src_dst_port(self): - self._test_create_filter(filter_dict={'src_port': 8192, - 'dst_port': 4096}, - filter_post={'tp_src': '0x2000', - 'tp_dst': '0x1000'}) - - def testb_delete_filter(self): - t, n, p = self.get_ofc_item_random_params() - f_path = "/filters/%s" % uuidutils.generate_uuid() - self.driver.delete_filter(f_path) - self.do_request.assert_called_once_with("DELETE", f_path) diff --git a/neutron/tests/unit/nec/test_utils.py b/neutron/tests/unit/nec/test_utils.py deleted file mode 100644 index c8a8ac7bc..000000000 --- a/neutron/tests/unit/nec/test_utils.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2014 NEC Corporation. All rights reserved. -# -# 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. - -from neutron.plugins.nec.common import utils -from neutron.tests import base - - -class NecUtilsTest(base.BaseTestCase): - - def test_cmp_dpid(self): - self.assertTrue(utils.cmp_dpid('0xabcd', '0xabcd')) - self.assertTrue(utils.cmp_dpid('abcd', '0xabcd')) - self.assertTrue(utils.cmp_dpid('0x000000000000abcd', '0xabcd')) - self.assertTrue(utils.cmp_dpid('0x000000000000abcd', '0x00abcd')) - self.assertFalse(utils.cmp_dpid('0x000000000000abcd', '0xabc0')) - self.assertFalse(utils.cmp_dpid('0x000000000000abcd', '0x00abc0')) - - def test_cmp_dpid_with_exception(self): - self.assertFalse(utils.cmp_dpid('0xabcx', '0xabcx')) - self.assertFalse(utils.cmp_dpid(None, None)) diff --git a/neutron/tests/unit/notifiers/__init__.py b/neutron/tests/unit/notifiers/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/notifiers/test_notifiers_nova.py b/neutron/tests/unit/notifiers/test_notifiers_nova.py deleted file mode 100644 index 7972ebf55..000000000 --- a/neutron/tests/unit/notifiers/test_notifiers_nova.py +++ /dev/null @@ -1,305 +0,0 @@ -# Copyright 2014 OpenStack Foundation -# All Rights Reserved. -# -# 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 novaclient import exceptions as nova_exceptions -from sqlalchemy.orm import attributes as sql_attr - -from oslo.config import cfg - -from neutron.common import constants -from neutron.db import models_v2 -from neutron.notifiers import nova -from neutron.openstack.common import uuidutils -from neutron.tests import base - - -class TestNovaNotify(base.BaseTestCase): - def setUp(self, plugin=None): - super(TestNovaNotify, self).setUp() - - class FakePlugin(object): - def get_port(self, context, port_id): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - return {'device_id': device_id, - 'device_owner': 'compute:None'} - - self.nova_notifier = nova.Notifier() - self.nova_notifier._plugin_ref = FakePlugin() - - def test_notify_port_status_all_values(self): - states = [constants.PORT_STATUS_ACTIVE, constants.PORT_STATUS_DOWN, - constants.PORT_STATUS_ERROR, constants.PORT_STATUS_BUILD, - sql_attr.NO_VALUE] - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - # test all combinations - for previous_port_status in states: - for current_port_status in states: - - port = models_v2.Port(id='port-uuid', device_id=device_id, - device_owner="compute:", - status=current_port_status) - self._record_port_status_changed_helper(current_port_status, - previous_port_status, - port) - - def test_port_without_uuid_device_id_no_notify(self): - port = models_v2.Port(id='port-uuid', device_id='compute_probe:', - device_owner='compute:', - status=constants.PORT_STATUS_ACTIVE) - self._record_port_status_changed_helper(constants.PORT_STATUS_ACTIVE, - sql_attr.NO_VALUE, - port) - - def test_port_without_device_owner_no_notify(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - port = models_v2.Port(id='port-uuid', device_id=device_id, - status=constants.PORT_STATUS_ACTIVE) - self._record_port_status_changed_helper(constants.PORT_STATUS_ACTIVE, - sql_attr.NO_VALUE, - port) - - def test_port_without_device_id_no_notify(self): - port = models_v2.Port(id='port-uuid', device_owner="network:dhcp", - status=constants.PORT_STATUS_ACTIVE) - self._record_port_status_changed_helper(constants.PORT_STATUS_ACTIVE, - sql_attr.NO_VALUE, - port) - - def test_port_without_id_no_notify(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - port = models_v2.Port(device_id=device_id, - device_owner="compute:", - status=constants.PORT_STATUS_ACTIVE) - self._record_port_status_changed_helper(constants.PORT_STATUS_ACTIVE, - sql_attr.NO_VALUE, - port) - - def test_non_compute_instances_no_notify(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - port = models_v2.Port(id='port-uuid', device_id=device_id, - device_owner="network:dhcp", - status=constants.PORT_STATUS_ACTIVE) - self._record_port_status_changed_helper(constants.PORT_STATUS_ACTIVE, - sql_attr.NO_VALUE, - port) - - def _record_port_status_changed_helper(self, current_port_status, - previous_port_status, port): - - if not (port.device_id and port.id and port.device_owner and - port.device_owner.startswith('compute:') and - uuidutils.is_uuid_like(port.device_id)): - return - - if (previous_port_status == constants.PORT_STATUS_ACTIVE and - current_port_status == constants.PORT_STATUS_DOWN): - event_name = nova.VIF_UNPLUGGED - - elif (previous_port_status in [sql_attr.NO_VALUE, - constants.PORT_STATUS_DOWN, - constants.PORT_STATUS_BUILD] - and current_port_status in [constants.PORT_STATUS_ACTIVE, - constants.PORT_STATUS_ERROR]): - event_name = nova.VIF_PLUGGED - - else: - return - - status = nova.NEUTRON_NOVA_EVENT_STATUS_MAP.get(current_port_status) - self.nova_notifier.record_port_status_changed(port, - current_port_status, - previous_port_status, - None) - - event = {'server_uuid': port.device_id, 'status': status, - 'name': event_name, 'tag': 'port-uuid'} - self.assertEqual(event, port._notify_event) - - def test_update_fixed_ip_changed(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - returned_obj = {'port': - {'device_owner': u'compute:dfd', - 'id': u'bee50827-bcee-4cc8-91c1-a27b0ce54222', - 'device_id': device_id}} - - expected_event = {'server_uuid': device_id, - 'name': 'network-changed'} - event = self.nova_notifier.create_port_changed_event('update_port', - {}, returned_obj) - self.assertEqual(event, expected_event) - - def test_create_floatingip_notify(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - returned_obj = {'floatingip': - {'port_id': u'bee50827-bcee-4cc8-91c1-a27b0ce54222'}} - - expected_event = {'server_uuid': device_id, - 'name': 'network-changed'} - event = self.nova_notifier.create_port_changed_event( - 'create_floatingip', {}, returned_obj) - self.assertEqual(event, expected_event) - - def test_create_floatingip_no_port_id_no_notify(self): - returned_obj = {'floatingip': - {'port_id': None}} - - event = self.nova_notifier.create_port_changed_event( - 'create_floatingip', {}, returned_obj) - self.assertFalse(event, None) - - def test_delete_floatingip_notify(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - returned_obj = {'floatingip': - {'port_id': u'bee50827-bcee-4cc8-91c1-a27b0ce54222'}} - - expected_event = {'server_uuid': device_id, - 'name': 'network-changed'} - event = self.nova_notifier.create_port_changed_event( - 'delete_floatingip', {}, returned_obj) - self.assertEqual(expected_event, event) - - def test_delete_floatingip_no_port_id_no_notify(self): - returned_obj = {'floatingip': - {'port_id': None}} - - event = self.nova_notifier.create_port_changed_event( - 'delete_floatingip', {}, returned_obj) - self.assertEqual(event, None) - - def test_associate_floatingip_notify(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - returned_obj = {'floatingip': - {'port_id': u'5a39def4-3d3f-473d-9ff4-8e90064b9cc1'}} - original_obj = {'port_id': None} - - expected_event = {'server_uuid': device_id, - 'name': 'network-changed'} - event = self.nova_notifier.create_port_changed_event( - 'update_floatingip', original_obj, returned_obj) - self.assertEqual(expected_event, event) - - def test_disassociate_floatingip_notify(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - returned_obj = {'floatingip': {'port_id': None}} - original_obj = {'port_id': '5a39def4-3d3f-473d-9ff4-8e90064b9cc1'} - - expected_event = {'server_uuid': device_id, - 'name': 'network-changed'} - - event = self.nova_notifier.create_port_changed_event( - 'update_floatingip', original_obj, returned_obj) - self.assertEqual(expected_event, event) - - def test_no_notification_notify_nova_on_port_data_changes_false(self): - cfg.CONF.set_override('notify_nova_on_port_data_changes', False) - - with mock.patch.object(self.nova_notifier, - 'send_events') as send_events: - self.nova_notifier.send_network_change('update_floatingip', - {}, {}) - self.assertFalse(send_events.called, False) - - def test_nova_send_events_returns_bad_list(self): - with mock.patch.object( - self.nova_notifier.nclient.server_external_events, - 'create') as nclient_create: - nclient_create.return_value = 'i am a string!' - self.nova_notifier.send_events() - - def test_nova_send_event_rasies_404(self): - with mock.patch.object( - self.nova_notifier.nclient.server_external_events, - 'create') as nclient_create: - nclient_create.side_effect = nova_exceptions.NotFound - self.nova_notifier.send_events() - - def test_nova_send_events_raises(self): - with mock.patch.object( - self.nova_notifier.nclient.server_external_events, - 'create') as nclient_create: - nclient_create.side_effect = Exception - self.nova_notifier.send_events() - - def test_nova_send_events_returns_non_200(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - with mock.patch.object( - self.nova_notifier.nclient.server_external_events, - 'create') as nclient_create: - nclient_create.return_value = [{'code': 404, - 'name': 'network-changed', - 'server_uuid': device_id}] - self.nova_notifier.pending_events.append( - {'name': 'network-changed', 'server_uuid': device_id}) - self.nova_notifier.send_events() - - def test_nova_send_events_return_200(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - with mock.patch.object( - self.nova_notifier.nclient.server_external_events, - 'create') as nclient_create: - nclient_create.return_value = [{'code': 200, - 'name': 'network-changed', - 'server_uuid': device_id}] - self.nova_notifier.pending_events.append( - {'name': 'network-changed', 'server_uuid': device_id}) - self.nova_notifier.send_events() - - def test_nova_send_events_multiple(self): - device_id = '32102d7b-1cf4-404d-b50a-97aae1f55f87' - with mock.patch.object( - self.nova_notifier.nclient.server_external_events, - 'create') as nclient_create: - nclient_create.return_value = [{'code': 200, - 'name': 'network-changed', - 'server_uuid': device_id}, - {'code': 200, - 'name': 'network-changed', - 'server_uuid': device_id}] - self.nova_notifier.pending_events.append( - {'name': 'network-changed', 'server_uuid': device_id}) - self.nova_notifier.pending_events.append( - {'name': 'network-changed', 'server_uuid': device_id}) - self.nova_notifier.send_events() - - def test_queue_event_no_event(self): - with mock.patch('eventlet.spawn_n') as spawn_n: - self.nova_notifier.queue_event(None) - self.assertEqual(0, len(self.nova_notifier.pending_events)) - self.assertEqual(0, spawn_n.call_count) - - def test_queue_event_first_event(self): - with mock.patch('eventlet.spawn_n') as spawn_n: - self.nova_notifier.queue_event(mock.Mock()) - self.assertEqual(1, len(self.nova_notifier.pending_events)) - self.assertEqual(1, spawn_n.call_count) - - def test_queue_event_multiple_events(self): - with mock.patch('eventlet.spawn_n') as spawn_n: - events = 6 - for i in range(0, events): - self.nova_notifier.queue_event(mock.Mock()) - self.assertEqual(events, len(self.nova_notifier.pending_events)) - self.assertEqual(1, spawn_n.call_count) - - def test_queue_event_call_send_events(self): - with mock.patch.object(self.nova_notifier, - 'send_events') as send_events: - with mock.patch('eventlet.spawn_n') as spawn_n: - spawn_n.side_effect = lambda func: func() - self.nova_notifier.queue_event(mock.Mock()) - self.assertFalse(self.nova_notifier._waiting_to_send) - send_events.assert_called_once_with() diff --git a/neutron/tests/unit/nuage/__init__.py b/neutron/tests/unit/nuage/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/nuage/fake_nuageclient.py b/neutron/tests/unit/nuage/fake_nuageclient.py deleted file mode 100644 index 2abcd8ddc..000000000 --- a/neutron/tests/unit/nuage/fake_nuageclient.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright 2014 Alcatel-Lucent USA Inc. -# -# 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. -# -# @author: Ronak Shah, Aniket Dandekar, Nuage Networks, Alcatel-Lucent USA Inc. - -from neutron.openstack.common import uuidutils - - -class FakeNuageClient(object): - def __init__(self, server, base_uri, serverssl, - serverauth, auth_resource, organization): - pass - - def rest_call(self, action, resource, data, extra_headers=None): - pass - - def vms_on_l2domain(self, l2dom_id): - pass - - def create_subnet(self, neutron_subnet, params): - nuage_subnet = { - 'nuage_l2template_id': uuidutils.generate_uuid(), - 'nuage_userid': uuidutils.generate_uuid(), - 'nuage_groupid': uuidutils.generate_uuid(), - 'nuage_l2domain_id': uuidutils.generate_uuid() - } - return nuage_subnet - - def delete_subnet(self, id, template_id): - pass - - def create_router(self, neutron_router, router, params): - nuage_router = { - 'nuage_userid': uuidutils.generate_uuid(), - 'nuage_groupid': uuidutils.generate_uuid(), - 'nuage_domain_id': uuidutils.generate_uuid(), - 'nuage_def_zone_id': uuidutils.generate_uuid(), - } - return nuage_router - - def delete_router(self, id): - pass - - def delete_user(self, id): - pass - - def delete_group(self, id): - pass - - def create_domain_subnet(self, neutron_subnet, params): - pass - - def delete_domain_subnet(self, id): - pass - - def create_net_partition(self, params): - fake_net_partition = { - 'nuage_entid': uuidutils.generate_uuid(), - 'l3dom_id': uuidutils.generate_uuid(), - 'l2dom_id': uuidutils.generate_uuid(), - } - return fake_net_partition - - def get_def_netpartition_data(self, default_net_part): - if default_net_part == 'default_test_np': - fake_defnetpart_data = { - 'np_id': uuidutils.generate_uuid(), - 'l3dom_tid': uuidutils.generate_uuid(), - 'l2dom_tid': uuidutils.generate_uuid(), - } - return fake_defnetpart_data - - def delete_net_partition(self, id, l3dom_id=None, l2dom_id=None): - pass - - def check_del_def_net_partition(self, ent_name): - pass - - def create_vms(self, params): - pass - - def delete_vms(self, params): - pass - - def create_nuage_staticroute(self, params): - return uuidutils.generate_uuid() - - def delete_nuage_staticroute(self, id): - pass - - def create_nuage_sharedresource(self, params): - return uuidutils.generate_uuid() - - def delete_nuage_sharedresource(self, id): - pass - - def create_nuage_floatingip(self, params): - return uuidutils.generate_uuid() - - def delete_nuage_floatingip(self, id): - pass - - def update_nuage_vm_vport(self, params): - pass diff --git a/neutron/tests/unit/nuage/test_netpartition.py b/neutron/tests/unit/nuage/test_netpartition.py deleted file mode 100644 index bf51bc40a..000000000 --- a/neutron/tests/unit/nuage/test_netpartition.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright 2014 Alcatel-Lucent USA Inc. -# -# 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. -# -# @author: Ronak Shah, Nuage Networks, Alcatel-Lucent USA Inc. - -import contextlib -import uuid -import webob.exc - -from neutron import manager -from neutron.plugins.nuage.extensions import netpartition as netpart_ext -from neutron.tests.unit.nuage import test_nuage_plugin -from neutron.tests.unit import test_extensions - - -class NetPartitionTestExtensionManager(object): - def get_resources(self): - return netpart_ext.Netpartition.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class NetPartitionTestCase(test_nuage_plugin.NuagePluginV2TestCase): - def setUp(self): - ext_mgr = NetPartitionTestExtensionManager() - super(NetPartitionTestCase, self).setUp() - self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr) - - def _make_netpartition(self, fmt, name): - data = { - 'net_partition': { - 'name': name, - 'tenant_id': uuid.uuid4() - } - } - netpart_req = self.new_create_request('net-partitions', data, fmt) - resp = netpart_req.get_response(self.ext_api) - if resp.status_int >= webob.exc.HTTPClientError.code: - raise webob.exc.HTTPClientError(code=resp.status_int) - return self.deserialize(fmt, resp) - - def _del_netpartition(self, id): - self._delete('net-partitions', id) - - @contextlib.contextmanager - def netpartition(self, name='netpartition1', - do_delete=True, - fmt=None, - **kwargs): - netpart = self._make_netpartition(fmt or self.fmt, name) - - yield netpart - if do_delete: - self._del_netpartition(netpart['net_partition']['id']) - - def test_create_netpartition(self): - name = 'netpart1' - keys = [('name', name)] - with self.netpartition(name=name) as netpart: - for k, v in keys: - self.assertEqual(netpart['net_partition'][k], v) - - def test_delete_netpartition(self): - name = 'netpart1' - netpart = self._make_netpartition(self.fmt, name) - req = self.new_delete_request('net-partitions', - netpart['net_partition']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_show_netpartition(self): - with self.netpartition(name='netpart1') as npart: - req = self.new_show_request('net-partitions', - npart['net_partition']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self.assertEqual(res['net_partition']['name'], - npart['net_partition']['name']) - - def test_create_existing_default_netpartition(self): - name = 'default_test_np' - netpart1 = self._make_netpartition(self.fmt, name) - nuage_plugin = manager.NeutronManager.get_plugin() - netpart2 = nuage_plugin._create_default_net_partition(name) - self.assertEqual(netpart1['net_partition']['name'], - netpart2['name']) diff --git a/neutron/tests/unit/nuage/test_nuage_plugin.py b/neutron/tests/unit/nuage/test_nuage_plugin.py deleted file mode 100644 index afbc91bb9..000000000 --- a/neutron/tests/unit/nuage/test_nuage_plugin.py +++ /dev/null @@ -1,283 +0,0 @@ -# Copyright 2014 Alcatel-Lucent USA Inc. -# -# 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. -# -# @author: Ronak Shah, Aniket Dandekar, Nuage Networks, Alcatel-Lucent USA Inc. - -import contextlib -import os - -import mock -from oslo.config import cfg -from webob import exc - -from neutron.extensions import external_net -from neutron.extensions import portbindings -from neutron.plugins.nuage import extensions -from neutron.plugins.nuage import plugin as nuage_plugin -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit.nuage import fake_nuageclient -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import test_extension_extraroute as extraroute_test -from neutron.tests.unit import test_l3_plugin - -API_EXT_PATH = os.path.dirname(extensions.__file__) -FAKE_DEFAULT_ENT = 'default' -NUAGE_PLUGIN_PATH = 'neutron.plugins.nuage.plugin' -FAKE_SERVER = '1.1.1.1' -FAKE_SERVER_AUTH = 'user:pass' -FAKE_SERVER_SSL = False -FAKE_BASE_URI = '/base/' -FAKE_AUTH_RESOURCE = '/auth' -FAKE_ORGANIZATION = 'fake_org' - -_plugin_name = ('%s.NuagePlugin' % NUAGE_PLUGIN_PATH) - - -class NuagePluginV2TestCase(test_db_plugin.NeutronDbPluginV2TestCase): - def setUp(self, plugin=_plugin_name, - ext_mgr=None, service_plugins=None): - def mock_nuageClient_init(self): - server = FAKE_SERVER - serverauth = FAKE_SERVER_AUTH - serverssl = FAKE_SERVER_SSL - base_uri = FAKE_BASE_URI - auth_resource = FAKE_AUTH_RESOURCE - organization = FAKE_ORGANIZATION - self.nuageclient = None - self.nuageclient = fake_nuageclient.FakeNuageClient(server, - base_uri, - serverssl, - serverauth, - auth_resource, - organization) - - with mock.patch.object(nuage_plugin.NuagePlugin, - 'nuageclient_init', new=mock_nuageClient_init): - cfg.CONF.set_override('api_extensions_path', - API_EXT_PATH) - super(NuagePluginV2TestCase, self).setUp(plugin=plugin, - ext_mgr=ext_mgr) - - def _assert_no_assoc_fip(self, fip): - body = self._show('floatingips', - fip['floatingip']['id']) - self.assertIsNone(body['floatingip']['port_id']) - self.assertIsNone( - body['floatingip']['fixed_ip_address']) - - def _associate_and_assert_fip(self, fip, port, allow=True): - port_id = port['port']['id'] - ip_address = (port['port']['fixed_ips'] - [0]['ip_address']) - if allow: - body = self._update( - 'floatingips', fip['floatingip']['id'], - {'floatingip': {'port_id': port_id}}) - self.assertEqual( - body['floatingip']['port_id'], port_id) - self.assertEqual( - body['floatingip']['fixed_ip_address'], - ip_address) - return body['floatingip']['router_id'] - else: - code = exc.HTTPInternalServerError.code - self._update( - 'floatingips', fip['floatingip']['id'], - {'floatingip': {'port_id': port_id}}, - expected_code=code) - - def _test_floatingip_update_different_router(self): - with contextlib.nested(self.subnet(cidr='10.0.0.0/24'), - self.subnet(cidr='10.0.1.0/24')) as ( - s1, s2): - with contextlib.nested(self.port(subnet=s1), - self.port(subnet=s2)) as (p1, p2): - private_sub1 = {'subnet': - {'id': - p1['port']['fixed_ips'][0]['subnet_id']}} - private_sub2 = {'subnet': - {'id': - p2['port']['fixed_ips'][0]['subnet_id']}} - with self.subnet(cidr='12.0.0.0/24') as public_sub: - with contextlib.nested( - self.floatingip_no_assoc_with_public_sub( - private_sub1, public_sub=public_sub), - self.floatingip_no_assoc_with_public_sub( - private_sub2, public_sub=public_sub)) as ( - (fip1, r1), (fip2, r2)): - - self._assert_no_assoc_fip(fip1) - self._assert_no_assoc_fip(fip2) - - fip1_r1_res = self._associate_and_assert_fip(fip1, p1) - self.assertEqual(fip1_r1_res, r1['router']['id']) - # The following operation will associate the floating - # ip to a different router and should fail - self._associate_and_assert_fip(fip1, p2, allow=False) - # disassociate fip1 - self._update( - 'floatingips', fip1['floatingip']['id'], - {'floatingip': {'port_id': None}}) - fip2_r2_res = self._associate_and_assert_fip(fip2, p2) - self.assertEqual(fip2_r2_res, r2['router']['id']) - - def _test_network_update_external_failure(self): - with self.router() as r: - with self.subnet() as s1: - self._set_net_external(s1['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s1['subnet']['network_id']) - self._update('networks', s1['subnet']['network_id'], - {'network': {external_net.EXTERNAL: False}}, - expected_code=exc.HTTPInternalServerError.code) - self._remove_external_gateway_from_router( - r['router']['id'], - s1['subnet']['network_id']) - - -class TestNuageBasicGet(NuagePluginV2TestCase, - test_db_plugin.TestBasicGet): - pass - - -class TestNuageV2HTTPResponse(NuagePluginV2TestCase, - test_db_plugin.TestV2HTTPResponse): - pass - - -class TestNuageNetworksV2(NuagePluginV2TestCase, - test_db_plugin.TestNetworksV2): - pass - - -class TestNuageSubnetsV2(NuagePluginV2TestCase, - test_db_plugin.TestSubnetsV2): - def test_create_subnet_bad_hostroutes(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_create_subnet_inconsistent_ipv4_hostroute_dst_v6(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_create_subnet_inconsistent_ipv4_hostroute_np_v6(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_update_subnet_adding_additional_host_routes_and_dns(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_update_subnet_inconsistent_ipv6_hostroute_dst_v4(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_update_subnet_inconsistent_ipv6_hostroute_np_v4(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_create_subnet_with_one_host_route(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_create_subnet_with_two_host_routes(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_create_subnet_with_too_many_routes(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_update_subnet_route(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_update_subnet_route_to_None(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_update_subnet_route_with_too_many_entries(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_delete_subnet_with_route(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_delete_subnet_with_dns_and_route(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_validate_subnet_host_routes_exhausted(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_validate_subnet_dns_nameservers_exhausted(self): - self.skipTest("Plugin does not support Neutron Subnet host-routes") - - def test_create_subnet_with_none_gateway(self): - self.skipTest("Plugin does not support " - "Neutron Subnet no-gateway option") - - def test_create_subnet_with_none_gateway_fully_allocated(self): - self.skipTest("Plugin does not support Neutron " - "Subnet no-gateway option") - - def test_create_subnet_with_none_gateway_allocation_pool(self): - self.skipTest("Plugin does not support Neutron " - "Subnet no-gateway option") - - -class TestNuagePluginPortBinding(NuagePluginV2TestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - - def setUp(self): - super(TestNuagePluginPortBinding, self).setUp() - - -class TestNuagePortsV2(NuagePluginV2TestCase, - test_db_plugin.TestPortsV2): - pass - - -class TestNuageL3NatTestCase(NuagePluginV2TestCase, - test_l3_plugin.L3NatDBIntTestCase): - - def test_floatingip_update_different_router(self): - self._test_floatingip_update_different_router() - - def test_network_update_external_failure(self): - self._test_network_update_external_failure() - - -class TestNuageExtrarouteTestCase(NuagePluginV2TestCase, - extraroute_test.ExtraRouteDBIntTestCase): - - def test_router_update_with_dup_destination_address(self): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - - routes = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}, - {'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.5'}] - - self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}, - expected_code=exc.HTTPBadRequest.code) - - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_floatingip_update_different_router(self): - self._test_floatingip_update_different_router() - - def test_network_update_external_failure(self): - self._test_network_update_external_failure() diff --git a/neutron/tests/unit/ofagent/__init__.py b/neutron/tests/unit/ofagent/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/ofagent/fake_oflib.py b/neutron/tests/unit/ofagent/fake_oflib.py deleted file mode 100644 index 68d21cb61..000000000 --- a/neutron/tests/unit/ofagent/fake_oflib.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright (C) 2014 VA Linux Systems Japan K.K. -# -# 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. -# -# @author: Fumihiko Kakuma, VA Linux Systems Japan K.K. -# @author: YAMAMOTO Takashi, VA Linux Systems Japan K.K. - -import mock - - -class _Eq(object): - def __eq__(self, other): - return repr(self) == repr(other) - - def __ne__(self, other): - return not self.__eq__(other) - - -class _Value(_Eq): - def __or__(self, b): - return _Op('|', self, b) - - def __ror__(self, a): - return _Op('|', a, self) - - -class _SimpleValue(_Value): - def __init__(self, name): - self.name = name - - def __repr__(self): - return self.name - - -class _Op(_Value): - def __init__(self, op, a, b): - self.op = op - self.a = a - self.b = b - - def __repr__(self): - return '%s%s%s' % (self.a, self.op, self.b) - - -def _mkcls(name): - class Cls(_Eq): - _name = name - - def __init__(self, *args, **kwargs): - self._args = args - self._kwargs = kwargs - self._hist = [] - - def __getattr__(self, name): - return name - - def __repr__(self): - args = map(repr, self._args) - kwargs = sorted(['%s=%s' % (x, y) for x, y in - self._kwargs.items()]) - return '%s(%s)' % (self._name, ', '.join(args + kwargs)) - - return Cls - - -class _Mod(object): - def __init__(self, name): - self._name = name - - def __getattr__(self, name): - fullname = '%s.%s' % (self._name, name) - if '_' in name: # constants are named like OFPxxx_yyy_zzz - return _SimpleValue(fullname) - return _mkcls(fullname) - - def __repr__(self): - return 'Mod(%s)' % (self._name,) - - -def patch_fake_oflib_of(): - ryu_mod = mock.Mock() - ryu_base_mod = ryu_mod.base - ryu_lib_mod = ryu_mod.lib - ryu_lib_hub = ryu_lib_mod.hub - ryu_ofproto_mod = ryu_mod.ofproto - ofp = _Mod('ryu.ofproto.ofproto_v1_3') - ofpp = _Mod('ryu.ofproto.ofproto_v1_3_parser') - ryu_ofproto_mod.ofproto_v1_3 = ofp - ryu_ofproto_mod.ofproto_v1_3_parser = ofpp - ryu_app_mod = ryu_mod.app - ryu_app_ofctl_mod = ryu_app_mod.ofctl - ryu_ofctl_api = ryu_app_ofctl_mod.api - modules = {'ryu': ryu_mod, - 'ryu.base': ryu_base_mod, - 'ryu.lib': ryu_lib_mod, - 'ryu.lib.hub': ryu_lib_hub, - 'ryu.ofproto': ryu_ofproto_mod, - 'ryu.ofproto.ofproto_v1_3': ofp, - 'ryu.ofproto.ofproto_v1_3_parser': ofpp, - 'ryu.app': ryu_app_mod, - 'ryu.app.ofctl': ryu_app_ofctl_mod, - 'ryu.app.ofctl.api': ryu_ofctl_api} - return mock.patch.dict('sys.modules', modules) diff --git a/neutron/tests/unit/ofagent/test_ofa_defaults.py b/neutron/tests/unit/ofagent/test_ofa_defaults.py deleted file mode 100644 index 635070b51..000000000 --- a/neutron/tests/unit/ofagent/test_ofa_defaults.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2014 VA Linux Systems Japan K.K. -# -# 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. -# @author: Fumihiko Kakuma, VA Linux Systems Japan K.K. - -from oslo.config import cfg - -from neutron.plugins.ofagent.common import config # noqa -from neutron.tests import base - - -class ConfigurationTest(base.BaseTestCase): - """Configuration file Tests.""" - def test_ml2_defaults(self): - self.assertEqual(60, cfg.CONF.AGENT.get_datapath_retry_times) diff --git a/neutron/tests/unit/ofagent/test_ofa_neutron_agent.py b/neutron/tests/unit/ofagent/test_ofa_neutron_agent.py deleted file mode 100644 index 6df549a2d..000000000 --- a/neutron/tests/unit/ofagent/test_ofa_neutron_agent.py +++ /dev/null @@ -1,1023 +0,0 @@ -# Copyright (C) 2014 VA Linux Systems Japan K.K. -# Based on test for openvswitch agent(test_ovs_neutron_agent.py). -# -# Copyright (c) 2012 OpenStack Foundation. -# -# 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. -# -# @author: Fumihiko Kakuma, VA Linux Systems Japan K.K. -# @author: YAMAMOTO Takashi, VA Linux Systems Japan K.K. - -import contextlib - -import mock -import netaddr -from oslo.config import cfg -import testtools - -from neutron.agent.linux import ip_lib -from neutron.agent.linux import ovs_lib -from neutron.agent.linux import utils -from neutron.openstack.common import importutils -from neutron.plugins.common import constants as p_const -from neutron.plugins.openvswitch.common import constants -from neutron.tests import base -from neutron.tests.unit.ofagent import fake_oflib - - -NOTIFIER = ('neutron.plugins.ml2.rpc.AgentNotifierApi') -OVS_LINUX_KERN_VERS_WITHOUT_VXLAN = "3.12.0" - - -class OFAAgentTestCase(base.BaseTestCase): - - _AGENT_NAME = 'neutron.plugins.ofagent.agent.ofa_neutron_agent' - - def setUp(self): - super(OFAAgentTestCase, self).setUp() - self.fake_oflib_of = fake_oflib.patch_fake_oflib_of().start() - self.mod_agent = importutils.import_module(self._AGENT_NAME) - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - self.ryuapp = mock.Mock() - cfg.CONF.register_cli_opts([ - cfg.StrOpt('ofp-listen-host', default='', - help='openflow listen host'), - cfg.IntOpt('ofp-tcp-listen-port', default=6633, - help='openflow tcp listen port') - ]) - cfg.CONF.set_override('root_helper', 'fake_helper', group='AGENT') - - -class CreateAgentConfigMap(OFAAgentTestCase): - - def test_create_agent_config_map_succeeds(self): - self.assertTrue(self.mod_agent.create_agent_config_map(cfg.CONF)) - - def test_create_agent_config_map_fails_for_invalid_tunnel_config(self): - # An ip address is required for tunneling but there is no default, - # verify this for both gre and vxlan tunnels. - cfg.CONF.set_override('tunnel_types', [p_const.TYPE_GRE], - group='AGENT') - with testtools.ExpectedException(ValueError): - self.mod_agent.create_agent_config_map(cfg.CONF) - cfg.CONF.set_override('tunnel_types', [p_const.TYPE_VXLAN], - group='AGENT') - with testtools.ExpectedException(ValueError): - self.mod_agent.create_agent_config_map(cfg.CONF) - - def test_create_agent_config_map_enable_tunneling(self): - # Verify setting only enable_tunneling will default tunnel_type to GRE - cfg.CONF.set_override('tunnel_types', None, group='AGENT') - cfg.CONF.set_override('enable_tunneling', True, group='OVS') - cfg.CONF.set_override('local_ip', '10.10.10.10', group='OVS') - cfgmap = self.mod_agent.create_agent_config_map(cfg.CONF) - self.assertEqual(cfgmap['tunnel_types'], [p_const.TYPE_GRE]) - - def test_create_agent_config_map_fails_no_local_ip(self): - # An ip address is required for tunneling but there is no default - cfg.CONF.set_override('enable_tunneling', True, group='OVS') - with testtools.ExpectedException(ValueError): - self.mod_agent.create_agent_config_map(cfg.CONF) - - def test_create_agent_config_map_fails_for_invalid_tunnel_type(self): - cfg.CONF.set_override('tunnel_types', ['foobar'], group='AGENT') - with testtools.ExpectedException(ValueError): - self.mod_agent.create_agent_config_map(cfg.CONF) - - def test_create_agent_config_map_multiple_tunnel_types(self): - cfg.CONF.set_override('local_ip', '10.10.10.10', group='OVS') - cfg.CONF.set_override('tunnel_types', [p_const.TYPE_GRE, - p_const.TYPE_VXLAN], group='AGENT') - cfgmap = self.mod_agent.create_agent_config_map(cfg.CONF) - self.assertEqual(cfgmap['tunnel_types'], - [p_const.TYPE_GRE, p_const.TYPE_VXLAN]) - - -class TestOFANeutronAgentOVSBridge(OFAAgentTestCase): - - def setUp(self): - super(TestOFANeutronAgentOVSBridge, self).setUp() - self.br_name = 'bridge1' - self.root_helper = 'fake_helper' - self.ovs = self.mod_agent.OVSBridge( - self.br_name, self.root_helper, self.ryuapp) - - def test_find_datapath_id(self): - with mock.patch.object(self.ovs, 'get_datapath_id', - return_value='12345'): - self.ovs.find_datapath_id() - self.assertEqual(self.ovs.datapath_id, '12345') - - def _fake_get_datapath(self, app, datapath_id): - if self.ovs.retry_count >= 2: - datapath = mock.Mock() - datapath.ofproto_parser = mock.Mock() - return datapath - self.ovs.retry_count += 1 - return None - - def test_get_datapath_normal(self): - self.ovs.retry_count = 0 - with mock.patch.object(self.mod_agent.ryu_api, 'get_datapath', - new=self._fake_get_datapath): - self.ovs.datapath_id = '0x64' - self.ovs.get_datapath(retry_max=4) - self.assertEqual(self.ovs.retry_count, 2) - - def test_get_datapath_retry_out_by_default_time(self): - cfg.CONF.set_override('get_datapath_retry_times', 3, group='AGENT') - with mock.patch.object(self.mod_agent.ryu_api, 'get_datapath', - return_value=None) as mock_get_datapath: - with testtools.ExpectedException(SystemExit): - self.ovs.datapath_id = '0x64' - self.ovs.get_datapath(retry_max=3) - self.assertEqual(mock_get_datapath.call_count, 3) - - def test_get_datapath_retry_out_by_specified_time(self): - with mock.patch.object(self.mod_agent.ryu_api, 'get_datapath', - return_value=None) as mock_get_datapath: - with testtools.ExpectedException(SystemExit): - self.ovs.datapath_id = '0x64' - self.ovs.get_datapath(retry_max=2) - self.assertEqual(mock_get_datapath.call_count, 2) - - def test_setup_ofp_default_par(self): - with contextlib.nested( - mock.patch.object(self.ovs, 'set_protocols'), - mock.patch.object(self.ovs, 'set_controller'), - mock.patch.object(self.ovs, 'find_datapath_id'), - mock.patch.object(self.ovs, 'get_datapath'), - ) as (mock_set_protocols, mock_set_controller, - mock_find_datapath_id, mock_get_datapath): - self.ovs.setup_ofp() - mock_set_protocols.assert_called_with('OpenFlow13') - mock_set_controller.assert_called_with(['tcp:127.0.0.1:6633']) - mock_get_datapath.assert_called_with( - cfg.CONF.AGENT.get_datapath_retry_times) - self.assertEqual(mock_find_datapath_id.call_count, 1) - - def test_setup_ofp_specify_par(self): - controller_names = ['tcp:192.168.10.10:1234', 'tcp:172.17.16.20:5555'] - with contextlib.nested( - mock.patch.object(self.ovs, 'set_protocols'), - mock.patch.object(self.ovs, 'set_controller'), - mock.patch.object(self.ovs, 'find_datapath_id'), - mock.patch.object(self.ovs, 'get_datapath'), - ) as (mock_set_protocols, mock_set_controller, - mock_find_datapath_id, mock_get_datapath): - self.ovs.setup_ofp(controller_names=controller_names, - protocols='OpenFlow133', - retry_max=11) - mock_set_protocols.assert_called_with('OpenFlow133') - mock_set_controller.assert_called_with(controller_names) - mock_get_datapath.assert_called_with(11) - self.assertEqual(mock_find_datapath_id.call_count, 1) - - def test_setup_ofp_with_except(self): - with contextlib.nested( - mock.patch.object(self.ovs, 'set_protocols', - side_effect=RuntimeError), - mock.patch.object(self.ovs, 'set_controller'), - mock.patch.object(self.ovs, 'find_datapath_id'), - mock.patch.object(self.ovs, 'get_datapath'), - ) as (mock_set_protocols, mock_set_controller, - mock_find_datapath_id, mock_get_datapath): - with testtools.ExpectedException(SystemExit): - self.ovs.setup_ofp() - - -class TestOFANeutronAgent(OFAAgentTestCase): - - def setUp(self): - super(TestOFANeutronAgent, self).setUp() - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - # Avoid rpc initialization for unit tests - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - kwargs = self.mod_agent.create_agent_config_map(cfg.CONF) - - class MockFixedIntervalLoopingCall(object): - def __init__(self, f): - self.f = f - - def start(self, interval=0): - self.f() - - def _mk_test_dp(name): - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - dp = mock.Mock() - dp.ofproto = ofp - dp.ofproto_parser = ofpp - dp.__repr__ = lambda _self: name - return dp - - def _mk_test_br(name): - dp = _mk_test_dp(name) - br = mock.Mock() - br.datapath = dp - br.ofproto = dp.ofproto - br.ofparser = dp.ofproto_parser - return br - - with contextlib.nested( - mock.patch.object(self.mod_agent.OFANeutronAgent, - 'setup_integration_br', - return_value=mock.Mock()), - mock.patch.object(self.mod_agent.OFANeutronAgent, - 'setup_ancillary_bridges', - return_value=[]), - mock.patch.object(self.mod_agent.OVSBridge, - 'get_local_port_mac', - return_value='00:00:00:00:00:01'), - mock.patch('neutron.agent.linux.utils.get_interface_mac', - return_value='00:00:00:00:00:01'), - mock.patch('neutron.openstack.common.loopingcall.' - 'FixedIntervalLoopingCall', - new=MockFixedIntervalLoopingCall)): - self.agent = self.mod_agent.OFANeutronAgent(self.ryuapp, **kwargs) - self.agent.tun_br = _mk_test_br('tun_br') - self.datapath = mock.Mock() - self.ofparser = mock.Mock() - self.agent.phys_brs['phys-net1'] = _mk_test_br('phys_br1') - self.agent.phys_ofports['phys-net1'] = 777 - self.agent.int_ofports['phys-net1'] = 666 - self.datapath.ofparser = self.ofparser - self.ofparser.OFPMatch = mock.Mock() - self.ofparser.OFPMatch.return_value = mock.Mock() - self.ofparser.OFPFlowMod = mock.Mock() - self.ofparser.OFPFlowMod.return_value = mock.Mock() - self.agent.int_br.ofparser = self.ofparser - self.agent.int_br.datapath = _mk_test_dp('int_br') - - self.agent.sg_agent = mock.Mock() - - def _mock_port_bound(self, ofport=None, new_local_vlan=None, - old_local_vlan=None): - port = mock.Mock() - port.ofport = ofport - net_uuid = 'my-net-uuid' - if old_local_vlan is not None: - self.agent.local_vlan_map[net_uuid] = ( - self.mod_agent.LocalVLANMapping( - old_local_vlan, None, None, None)) - with contextlib.nested( - mock.patch.object(self.mod_agent.OVSBridge, - 'set_db_attribute', return_value=True), - mock.patch.object(self.mod_agent.OVSBridge, - 'db_get_val', return_value=str(old_local_vlan)), - mock.patch.object(self.agent, 'ryu_send_msg') - ) as (set_ovs_db_func, get_ovs_db_func, ryu_send_msg_func): - self.agent.port_bound(port, net_uuid, 'local', None, None) - get_ovs_db_func.assert_called_once_with("Port", mock.ANY, "tag") - if new_local_vlan != old_local_vlan: - set_ovs_db_func.assert_called_once_with( - "Port", mock.ANY, "tag", str(new_local_vlan)) - if ofport != -1: - ryu_send_msg_func.assert_called_once_with( - self.ofparser.OFPFlowMod.return_value) - else: - self.assertFalse(ryu_send_msg_func.called) - else: - self.assertFalse(set_ovs_db_func.called) - self.assertFalse(ryu_send_msg_func.called) - - def test_port_bound_deletes_flows_for_valid_ofport(self): - self._mock_port_bound(ofport=1, new_local_vlan=1) - - def test_port_bound_ignores_flows_for_invalid_ofport(self): - self._mock_port_bound(ofport=-1, new_local_vlan=1) - - def test_port_bound_does_not_rewire_if_already_bound(self): - self._mock_port_bound(ofport=-1, new_local_vlan=1, old_local_vlan=1) - - def _test_port_dead(self, cur_tag=None): - port = mock.Mock() - port.ofport = 1 - with contextlib.nested( - mock.patch.object(self.mod_agent.OVSBridge, - 'set_db_attribute', return_value=True), - mock.patch.object(self.mod_agent.OVSBridge, - 'db_get_val', return_value=cur_tag), - mock.patch.object(self.agent, 'ryu_send_msg') - ) as (set_ovs_db_func, get_ovs_db_func, ryu_send_msg_func): - self.agent.port_dead(port) - get_ovs_db_func.assert_called_once_with("Port", mock.ANY, "tag") - if cur_tag == self.mod_agent.DEAD_VLAN_TAG: - self.assertFalse(set_ovs_db_func.called) - self.assertFalse(ryu_send_msg_func.called) - else: - set_ovs_db_func.assert_called_once_with( - "Port", mock.ANY, "tag", str(self.mod_agent.DEAD_VLAN_TAG)) - ryu_send_msg_func.assert_called_once_with( - self.ofparser.OFPFlowMod.return_value) - - def test_port_dead(self): - self._test_port_dead() - - def test_port_dead_with_port_already_dead(self): - self._test_port_dead(self.mod_agent.DEAD_VLAN_TAG) - - def mock_scan_ports(self, vif_port_set=None, registered_ports=None, - updated_ports=None, port_tags_dict=None): - port_tags_dict = port_tags_dict or {} - with contextlib.nested( - mock.patch.object(self.agent.int_br, 'get_vif_port_set', - return_value=vif_port_set), - mock.patch.object(self.agent.int_br, 'get_port_tag_dict', - return_value=port_tags_dict) - ): - return self.agent.scan_ports(registered_ports, updated_ports) - - def test_scan_ports_returns_current_only_for_unchanged_ports(self): - vif_port_set = set([1, 3]) - registered_ports = set([1, 3]) - expected = {'current': vif_port_set} - actual = self.mock_scan_ports(vif_port_set, registered_ports) - self.assertEqual(expected, actual) - - def test_scan_ports_returns_port_changes(self): - vif_port_set = set([1, 3]) - registered_ports = set([1, 2]) - expected = dict(current=vif_port_set, added=set([3]), removed=set([2])) - actual = self.mock_scan_ports(vif_port_set, registered_ports) - self.assertEqual(expected, actual) - - def _test_scan_ports_with_updated_ports(self, updated_ports): - vif_port_set = set([1, 3, 4]) - registered_ports = set([1, 2, 4]) - expected = dict(current=vif_port_set, added=set([3]), - removed=set([2]), updated=set([4])) - actual = self.mock_scan_ports(vif_port_set, registered_ports, - updated_ports) - self.assertEqual(expected, actual) - - def test_scan_ports_finds_known_updated_ports(self): - self._test_scan_ports_with_updated_ports(set([4])) - - def test_scan_ports_ignores_unknown_updated_ports(self): - # the port '5' was not seen on current ports. Hence it has either - # never been wired or already removed and should be ignored - self._test_scan_ports_with_updated_ports(set([4, 5])) - - def test_scan_ports_ignores_updated_port_if_removed(self): - vif_port_set = set([1, 3]) - registered_ports = set([1, 2]) - updated_ports = set([1, 2]) - expected = dict(current=vif_port_set, added=set([3]), - removed=set([2]), updated=set([1])) - actual = self.mock_scan_ports(vif_port_set, registered_ports, - updated_ports) - self.assertEqual(expected, actual) - - def test_scan_ports_no_vif_changes_returns_updated_port_only(self): - vif_port_set = set([1, 2, 3]) - registered_ports = set([1, 2, 3]) - updated_ports = set([2]) - expected = dict(current=vif_port_set, updated=set([2])) - actual = self.mock_scan_ports(vif_port_set, registered_ports, - updated_ports) - self.assertEqual(expected, actual) - - def test_update_ports_returns_lost_vlan_port(self): - br = self.mod_agent.OVSBridge('br-int', 'fake_helper', self.ryuapp) - mac = "ca:fe:de:ad:be:ef" - port = ovs_lib.VifPort(1, 1, 1, mac, br) - lvm = self.mod_agent.LocalVLANMapping( - 1, '1', None, 1, {port.vif_id: port}) - local_vlan_map = {'1': lvm} - vif_port_set = set([1, 3]) - registered_ports = set([1, 2]) - port_tags_dict = {1: []} - expected = dict( - added=set([3]), current=vif_port_set, - removed=set([2]), updated=set([1]) - ) - with mock.patch.dict(self.agent.local_vlan_map, local_vlan_map): - actual = self.mock_scan_ports( - vif_port_set, registered_ports, port_tags_dict=port_tags_dict) - self.assertEqual(expected, actual) - - def test_treat_devices_added_returns_true_for_missing_device(self): - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'get_device_details', - side_effect=Exception()), - mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', - return_value=mock.Mock())): - self.assertTrue(self.agent.treat_devices_added_or_updated([{}])) - - def _mock_treat_devices_added_updated(self, details, port, func_name): - """Mock treat devices added or updated. - - :param details: the details to return for the device - :param port: the port that get_vif_port_by_id should return - :param func_name: the function that should be called - :returns: whether the named function was called - """ - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'get_device_details', - return_value=details), - mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', - return_value=port), - mock.patch.object(self.agent.plugin_rpc, 'update_device_up'), - mock.patch.object(self.agent.plugin_rpc, 'update_device_down'), - mock.patch.object(self.agent, func_name) - ) as (get_dev_fn, get_vif_func, upd_dev_up, upd_dev_down, func): - self.assertFalse(self.agent.treat_devices_added_or_updated([{}])) - return func.called - - def test_treat_devices_added_updated_ignores_invalid_ofport(self): - port = mock.Mock() - port.ofport = -1 - self.assertFalse(self._mock_treat_devices_added_updated( - mock.MagicMock(), port, 'port_dead')) - - def test_treat_devices_added_updated_marks_unknown_port_as_dead(self): - port = mock.Mock() - port.ofport = 1 - self.assertTrue(self._mock_treat_devices_added_updated( - mock.MagicMock(), port, 'port_dead')) - - def test_treat_devices_added_does_not_process_missing_port(self): - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'get_device_details'), - mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', - return_value=None) - ) as (get_dev_fn, get_vif_func): - self.assertFalse(get_dev_fn.called) - - def test_treat_devices_added_updated_updates_known_port(self): - details = mock.MagicMock() - details.__contains__.side_effect = lambda x: True - self.assertTrue(self._mock_treat_devices_added_updated( - details, mock.Mock(), 'treat_vif_port')) - - def test_treat_devices_added_updated_put_port_down(self): - fake_details_dict = {'admin_state_up': False, - 'port_id': 'xxx', - 'device': 'xxx', - 'network_id': 'yyy', - 'physical_network': 'foo', - 'segmentation_id': 'bar', - 'network_type': 'baz'} - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'get_device_details', - return_value=fake_details_dict), - mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', - return_value=mock.MagicMock()), - mock.patch.object(self.agent.plugin_rpc, 'update_device_up'), - mock.patch.object(self.agent.plugin_rpc, 'update_device_down'), - mock.patch.object(self.agent, 'treat_vif_port') - ) as (get_dev_fn, get_vif_func, upd_dev_up, - upd_dev_down, treat_vif_port): - self.assertFalse(self.agent.treat_devices_added_or_updated([{}])) - self.assertTrue(treat_vif_port.called) - self.assertTrue(upd_dev_down.called) - - def test_treat_devices_removed_returns_true_for_missing_device(self): - with mock.patch.object(self.agent.plugin_rpc, 'update_device_down', - side_effect=Exception()): - self.assertTrue(self.agent.treat_devices_removed([{}])) - - def _mock_treat_devices_removed(self, port_exists): - details = dict(exists=port_exists) - with mock.patch.object(self.agent.plugin_rpc, 'update_device_down', - return_value=details): - with mock.patch.object(self.agent, 'port_unbound') as port_unbound: - self.assertFalse(self.agent.treat_devices_removed([{}])) - self.assertTrue(port_unbound.called) - - def test_treat_devices_removed_unbinds_port(self): - self._mock_treat_devices_removed(True) - - def test_treat_devices_removed_ignores_missing_port(self): - self._mock_treat_devices_removed(False) - - def _test_process_network_ports(self, port_info): - with contextlib.nested( - mock.patch.object(self.agent.sg_agent, "setup_port_filters"), - mock.patch.object(self.agent, "treat_devices_added_or_updated", - return_value=False), - mock.patch.object(self.agent, "treat_devices_removed", - return_value=False) - ) as (setup_port_filters, device_added_updated, device_removed): - self.assertFalse(self.agent.process_network_ports(port_info)) - setup_port_filters.assert_called_once_with( - port_info['added'], port_info.get('updated', set())) - device_added_updated.assert_called_once_with( - port_info['added'] | port_info.get('updated', set())) - device_removed.assert_called_once_with(port_info['removed']) - - def test_process_network_ports(self): - self._test_process_network_ports( - {'current': set(['tap0']), - 'removed': set(['eth0']), - 'added': set(['eth1'])}) - - def test_process_network_port_with_updated_ports(self): - self._test_process_network_ports( - {'current': set(['tap0', 'tap1']), - 'updated': set(['tap1', 'eth1']), - 'removed': set(['eth0']), - 'added': set(['eth1'])}) - - def test_report_state(self): - with mock.patch.object(self.agent.state_rpc, - "report_state") as report_st: - self.agent.int_br_device_count = 5 - self.agent._report_state() - report_st.assert_called_with(self.agent.context, - self.agent.agent_state) - self.assertNotIn("start_flag", self.agent.agent_state) - self.assertEqual( - self.agent.agent_state["configurations"]["devices"], - self.agent.int_br_device_count - ) - - def test_network_delete(self): - with mock.patch.object(self.agent, - "reclaim_local_vlan") as recl_fn: - self.agent.network_delete("unused_context", - network_id="123") - self.assertFalse(recl_fn.called) - self.agent.local_vlan_map["123"] = "LVM object" - self.agent.network_delete("unused_context", - network_id="123") - recl_fn.assert_called_with("123") - - def test_port_update(self): - port = {"id": "123", - "network_id": "124", - "admin_state_up": False} - self.agent.port_update("unused_context", - port=port, - network_type="vlan", - segmentation_id="1", - physical_network="physnet") - self.assertEqual(set(['123']), self.agent.updated_ports) - - def test_setup_physical_bridges(self): - with contextlib.nested( - mock.patch.object(ip_lib, "device_exists"), - mock.patch.object(utils, "execute"), - mock.patch.object(self.mod_agent.OVSBridge, "add_port"), - mock.patch.object(self.mod_agent.OVSBridge, "delete_port"), - mock.patch.object(self.mod_agent.OVSBridge, "set_protocols"), - mock.patch.object(self.mod_agent.OVSBridge, "set_controller"), - mock.patch.object(self.mod_agent.OVSBridge, "get_datapath_id", - return_value='0xa'), - mock.patch.object(self.agent.int_br, "add_port"), - mock.patch.object(self.agent.int_br, "delete_port"), - mock.patch.object(ip_lib.IPWrapper, "add_veth"), - mock.patch.object(ip_lib.IpLinkCommand, "delete"), - mock.patch.object(ip_lib.IpLinkCommand, "set_up"), - mock.patch.object(ip_lib.IpLinkCommand, "set_mtu"), - mock.patch.object(self.mod_agent.ryu_api, "get_datapath", - return_value=self.datapath) - ) as (devex_fn, utilsexec_fn, - ovs_addport_fn, ovs_delport_fn, ovs_set_protocols_fn, - ovs_set_controller_fn, ovs_datapath_id_fn, br_addport_fn, - br_delport_fn, addveth_fn, linkdel_fn, linkset_fn, linkmtu_fn, - ryu_api_fn): - devex_fn.return_value = True - parent = mock.MagicMock() - parent.attach_mock(utilsexec_fn, 'utils_execute') - parent.attach_mock(linkdel_fn, 'link_delete') - parent.attach_mock(addveth_fn, 'add_veth') - addveth_fn.return_value = (ip_lib.IPDevice("int-br-eth1"), - ip_lib.IPDevice("phy-br-eth1")) - ovs_addport_fn.return_value = "25" - br_addport_fn.return_value = "11" - self.agent.setup_physical_bridges({"physnet1": "br-eth"}) - expected_calls = [mock.call.link_delete(), - mock.call.utils_execute(['/sbin/udevadm', - 'settle', - '--timeout=10']), - mock.call.add_veth('int-br-eth', - 'phy-br-eth')] - parent.assert_has_calls(expected_calls, any_order=False) - self.assertEqual(self.agent.int_ofports["physnet1"], - "11") - self.assertEqual(self.agent.phys_ofports["physnet1"], - "25") - - def test_port_unbound(self): - with mock.patch.object(self.agent, "reclaim_local_vlan") as reclvl_fn: - self.agent.enable_tunneling = True - lvm = mock.Mock() - lvm.network_type = "gre" - lvm.vif_ports = {"vif1": mock.Mock()} - self.agent.local_vlan_map["netuid12345"] = lvm - self.agent.port_unbound("vif1", "netuid12345") - self.assertTrue(reclvl_fn.called) - reclvl_fn.called = False - - lvm.vif_ports = {} - self.agent.port_unbound("vif1", "netuid12345") - self.assertEqual(reclvl_fn.call_count, 2) - - lvm.vif_ports = {"vif1": mock.Mock()} - self.agent.port_unbound("vif3", "netuid12345") - self.assertEqual(reclvl_fn.call_count, 2) - - def test_daemon_loop_uses_polling_manager(self): - with mock.patch( - 'neutron.agent.linux.polling.get_polling_manager' - ) as mock_get_pm: - fake_pm = mock.Mock() - mock_get_pm.return_value = fake_pm - fake_pm.__enter__ = mock.Mock() - fake_pm.__exit__ = mock.Mock() - with mock.patch.object( - self.agent, 'ovsdb_monitor_loop' - ) as mock_loop: - self.agent.daemon_loop() - mock_get_pm.assert_called_once_with(True, 'fake_helper', - constants.DEFAULT_OVSDBMON_RESPAWN) - mock_loop.assert_called_once_with(polling_manager=fake_pm.__enter__()) - - def test_setup_tunnel_port_error_negative(self): - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'add_tunnel_port', - return_value='-1'), - mock.patch.object(self.mod_agent.LOG, 'error') - ) as (add_tunnel_port_fn, log_error_fn): - ofport = self.agent.setup_tunnel_port( - 'gre-1', 'remote_ip', p_const.TYPE_GRE) - add_tunnel_port_fn.assert_called_once_with( - 'gre-1', 'remote_ip', self.agent.local_ip, p_const.TYPE_GRE, - self.agent.vxlan_udp_port, self.agent.dont_fragment) - log_error_fn.assert_called_once_with( - _("Failed to set-up %(type)s tunnel port to %(ip)s"), - {'type': p_const.TYPE_GRE, 'ip': 'remote_ip'}) - self.assertEqual(ofport, 0) - - def test_setup_tunnel_port_error_not_int(self): - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'add_tunnel_port', - return_value=None), - mock.patch.object(self.mod_agent.LOG, 'exception'), - mock.patch.object(self.mod_agent.LOG, 'error') - ) as (add_tunnel_port_fn, log_exc_fn, log_error_fn): - ofport = self.agent.setup_tunnel_port( - 'gre-1', 'remote_ip', p_const.TYPE_GRE) - add_tunnel_port_fn.assert_called_once_with( - 'gre-1', 'remote_ip', self.agent.local_ip, p_const.TYPE_GRE, - self.agent.vxlan_udp_port, self.agent.dont_fragment) - log_exc_fn.assert_called_once_with( - _("ofport should have a value that can be " - "interpreted as an integer")) - log_error_fn.assert_called_once_with( - _("Failed to set-up %(type)s tunnel port to %(ip)s"), - {'type': p_const.TYPE_GRE, 'ip': 'remote_ip'}) - self.assertEqual(ofport, 0) - - def _create_tunnel_port_name(self, tunnel_ip, tunnel_type): - tunnel_ip_hex = '%08x' % netaddr.IPAddress(tunnel_ip, version=4) - return '%s-%s' % (tunnel_type, tunnel_ip_hex) - - def test_tunnel_sync_with_valid_ip_address_and_gre_type(self): - tunnel_ip = '100.101.102.103' - self.agent.tunnel_types = ['gre'] - tun_name = self._create_tunnel_port_name(tunnel_ip, - self.agent.tunnel_types[0]) - fake_tunnel_details = {'tunnels': [{'ip_address': tunnel_ip}]} - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'tunnel_sync', - return_value=fake_tunnel_details), - mock.patch.object(self.agent, 'setup_tunnel_port') - ) as (tunnel_sync_rpc_fn, setup_tunnel_port_fn): - self.agent.tunnel_sync() - expected_calls = [mock.call(tun_name, tunnel_ip, - self.agent.tunnel_types[0])] - setup_tunnel_port_fn.assert_has_calls(expected_calls) - - def test_tunnel_sync_with_valid_ip_address_and_vxlan_type(self): - tunnel_ip = '100.101.31.15' - self.agent.tunnel_types = ['vxlan'] - tun_name = self._create_tunnel_port_name(tunnel_ip, - self.agent.tunnel_types[0]) - fake_tunnel_details = {'tunnels': [{'ip_address': tunnel_ip}]} - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'tunnel_sync', - return_value=fake_tunnel_details), - mock.patch.object(self.agent, 'setup_tunnel_port') - ) as (tunnel_sync_rpc_fn, setup_tunnel_port_fn): - self.agent.tunnel_sync() - expected_calls = [mock.call(tun_name, tunnel_ip, - self.agent.tunnel_types[0])] - setup_tunnel_port_fn.assert_has_calls(expected_calls) - - def test_tunnel_sync_invalid_ip_address(self): - tunnel_ip = '100.100.100.100' - self.agent.tunnel_types = ['vxlan'] - tun_name = self._create_tunnel_port_name(tunnel_ip, - self.agent.tunnel_types[0]) - fake_tunnel_details = {'tunnels': [{'ip_address': '300.300.300.300'}, - {'ip_address': tunnel_ip}]} - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'tunnel_sync', - return_value=fake_tunnel_details), - mock.patch.object(self.agent, 'setup_tunnel_port') - ) as (tunnel_sync_rpc_fn, setup_tunnel_port_fn): - self.agent.tunnel_sync() - setup_tunnel_port_fn.assert_called_once_with( - tun_name, tunnel_ip, self.agent.tunnel_types[0]) - - def test_tunnel_update(self): - tunnel_ip = '10.10.10.10' - self.agent.tunnel_types = ['gre'] - tun_name = self._create_tunnel_port_name(tunnel_ip, - self.agent.tunnel_types[0]) - kwargs = {'tunnel_ip': tunnel_ip, - 'tunnel_type': self.agent.tunnel_types[0]} - self.agent.setup_tunnel_port = mock.Mock() - self.agent.enable_tunneling = True - self.agent.l2_pop = False - self.agent.tunnel_update(context=None, **kwargs) - expected_calls = [mock.call(tun_name, tunnel_ip, - self.agent.tunnel_types[0])] - self.agent.setup_tunnel_port.assert_has_calls(expected_calls) - - def test__provision_local_vlan_inbound_for_tunnel(self): - with mock.patch.object(self.agent, 'ryu_send_msg') as sendmsg: - self.agent._provision_local_vlan_inbound_for_tunnel(1, 'gre', 3) - - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - expected_msg = ofpp.OFPFlowMod( - self.agent.tun_br.datapath, - instructions=[ - ofpp.OFPInstructionActions( - ofp.OFPIT_APPLY_ACTIONS, - [ - ofpp.OFPActionPushVlan(), - ofpp.OFPActionSetField(vlan_vid=1 | - ofp.OFPVID_PRESENT), - ]), - ofpp.OFPInstructionGotoTable(table_id=10), - ], - match=ofpp.OFPMatch(tunnel_id=3), - priority=1, - table_id=2) - sendmsg.assert_has_calls([mock.call(expected_msg)]) - - def test__provision_local_vlan_outbound(self): - with mock.patch.object(self.agent, 'ryu_send_msg') as sendmsg: - self.agent._provision_local_vlan_outbound(888, 999, 'phys-net1') - - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - expected_msg = ofpp.OFPFlowMod( - self.agent.phys_brs['phys-net1'].datapath, - instructions=[ - ofpp.OFPInstructionActions( - ofp.OFPIT_APPLY_ACTIONS, - [ - ofpp.OFPActionSetField(vlan_vid=999), - ofpp.OFPActionOutput(ofp.OFPP_NORMAL, 0), - ] - ) - ], - match=ofpp.OFPMatch( - in_port=777, - vlan_vid=888 | ofp.OFPVID_PRESENT - ), - priority=4) - sendmsg.assert_has_calls([mock.call(expected_msg)]) - - def test__provision_local_vlan_inbound(self): - with mock.patch.object(self.agent, 'ryu_send_msg') as sendmsg: - self.agent._provision_local_vlan_inbound(888, 999, 'phys-net1') - - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - expected_msg = ofpp.OFPFlowMod( - self.agent.int_br.datapath, - instructions=[ - ofpp.OFPInstructionActions( - ofp.OFPIT_APPLY_ACTIONS, - [ - ofpp.OFPActionSetField( - vlan_vid=888 | ofp.OFPVID_PRESENT - ), - ofpp.OFPActionOutput(ofp.OFPP_NORMAL, 0), - ] - ) - ], - match=ofpp.OFPMatch(in_port=666, vlan_vid=999), - priority=3) - sendmsg.assert_has_calls([mock.call(expected_msg)]) - - def test__reclaim_local_vlan_outbound(self): - lvm = mock.Mock() - lvm.network_type = p_const.TYPE_VLAN - lvm.segmentation_id = 555 - lvm.vlan = 444 - lvm.physical_network = 'phys-net1' - with mock.patch.object(self.agent, 'ryu_send_msg') as sendmsg: - self.agent._reclaim_local_vlan_outbound(lvm) - - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - expected_msg = ofpp.OFPFlowMod( - self.agent.phys_brs['phys-net1'].datapath, - command=ofp.OFPFC_DELETE, - match=ofpp.OFPMatch( - in_port=777, - vlan_vid=444 | ofp.OFPVID_PRESENT - ), - out_group=ofp.OFPG_ANY, - out_port=ofp.OFPP_ANY, - table_id=ofp.OFPTT_ALL) - sendmsg.assert_has_calls([mock.call(expected_msg)]) - - def test__reclaim_local_vlan_inbound(self): - lvm = mock.Mock() - lvm.network_type = p_const.TYPE_VLAN - lvm.segmentation_id = 555 - lvm.vlan = 444 - lvm.physical_network = 'phys-net1' - with mock.patch.object(self.agent, 'ryu_send_msg') as sendmsg: - self.agent._reclaim_local_vlan_inbound(lvm) - - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - expected_msg = ofpp.OFPFlowMod( - self.agent.int_br.datapath, - command=ofp.OFPFC_DELETE, - match=ofpp.OFPMatch( - in_port=666, - vlan_vid=555 | ofp.OFPVID_PRESENT - ), - out_group=ofp.OFPG_ANY, - out_port=ofp.OFPP_ANY, - table_id=ofp.OFPTT_ALL) - sendmsg.assert_has_calls([mock.call(expected_msg)]) - - def test__provision_local_vlan_outbound_flat(self): - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - with mock.patch.object(self.agent, 'ryu_send_msg') as sendmsg: - self.agent._provision_local_vlan_outbound(888, ofp.OFPVID_NONE, - 'phys-net1') - - expected_msg = ofpp.OFPFlowMod( - self.agent.phys_brs['phys-net1'].datapath, - instructions=[ - ofpp.OFPInstructionActions( - ofp.OFPIT_APPLY_ACTIONS, - [ - ofpp.OFPActionPopVlan(), - ofpp.OFPActionOutput(ofp.OFPP_NORMAL, 0), - ] - ) - ], - match=ofpp.OFPMatch( - in_port=777, - vlan_vid=888 | ofp.OFPVID_PRESENT - ), - priority=4) - sendmsg.assert_has_calls([mock.call(expected_msg)]) - - def test__provision_local_vlan_inbound_flat(self): - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - with mock.patch.object(self.agent, 'ryu_send_msg') as sendmsg: - self.agent._provision_local_vlan_inbound(888, ofp.OFPVID_NONE, - 'phys-net1') - - expected_msg = ofpp.OFPFlowMod( - self.agent.int_br.datapath, - instructions=[ - ofpp.OFPInstructionActions( - ofp.OFPIT_APPLY_ACTIONS, - [ - ofpp.OFPActionPushVlan(), - ofpp.OFPActionSetField( - vlan_vid=888 | ofp.OFPVID_PRESENT - ), - ofpp.OFPActionOutput(ofp.OFPP_NORMAL, 0), - ] - ) - ], - match=ofpp.OFPMatch(in_port=666, vlan_vid=ofp.OFPVID_NONE), - priority=3) - sendmsg.assert_has_calls([mock.call(expected_msg)]) - - def test__reclaim_local_vlan_outbound_flat(self): - lvm = mock.Mock() - lvm.network_type = p_const.TYPE_FLAT - lvm.segmentation_id = 555 - lvm.vlan = 444 - lvm.physical_network = 'phys-net1' - with mock.patch.object(self.agent, 'ryu_send_msg') as sendmsg: - self.agent._reclaim_local_vlan_outbound(lvm) - - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - expected_msg = ofpp.OFPFlowMod( - self.agent.phys_brs['phys-net1'].datapath, - command=ofp.OFPFC_DELETE, - match=ofpp.OFPMatch( - in_port=777, - vlan_vid=444 | ofp.OFPVID_PRESENT - ), - out_group=ofp.OFPG_ANY, - out_port=ofp.OFPP_ANY, - table_id=ofp.OFPTT_ALL) - sendmsg.assert_has_calls([mock.call(expected_msg)]) - - def test__reclaim_local_vlan_inbound_flat(self): - lvm = mock.Mock() - lvm.network_type = p_const.TYPE_FLAT - lvm.segmentation_id = 555 - lvm.vlan = 444 - lvm.physical_network = 'phys-net1' - with mock.patch.object(self.agent, 'ryu_send_msg') as sendmsg: - self.agent._reclaim_local_vlan_inbound(lvm) - - ofp = importutils.import_module('ryu.ofproto.ofproto_v1_3') - ofpp = importutils.import_module('ryu.ofproto.ofproto_v1_3_parser') - expected_msg = ofpp.OFPFlowMod( - self.agent.int_br.datapath, - command=ofp.OFPFC_DELETE, - match=ofpp.OFPMatch( - in_port=666, - vlan_vid=ofp.OFPVID_NONE - ), - out_group=ofp.OFPG_ANY, - out_port=ofp.OFPP_ANY, - table_id=ofp.OFPTT_ALL) - sendmsg.assert_has_calls([mock.call(expected_msg)]) - - -class AncillaryBridgesTest(OFAAgentTestCase): - - def setUp(self): - super(AncillaryBridgesTest, self).setUp() - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - # Avoid rpc initialization for unit tests - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - cfg.CONF.set_override('report_interval', 0, 'AGENT') - self.kwargs = self.mod_agent.create_agent_config_map(cfg.CONF) - - def _test_ancillary_bridges(self, bridges, ancillary): - device_ids = ancillary[:] - - def pullup_side_effect(self, *args): - result = device_ids.pop(0) - return result - - with contextlib.nested( - mock.patch.object(self.mod_agent.OFANeutronAgent, - 'setup_integration_br', - return_value=mock.Mock()), - mock.patch('neutron.agent.linux.utils.get_interface_mac', - return_value='00:00:00:00:00:01'), - mock.patch.object(self.mod_agent.OVSBridge, - 'get_local_port_mac', - return_value='00:00:00:00:00:01'), - mock.patch('neutron.agent.linux.ovs_lib.get_bridges', - return_value=bridges), - mock.patch( - 'neutron.agent.linux.ovs_lib.get_bridge_external_bridge_id', - side_effect=pullup_side_effect)): - self.agent = self.mod_agent.OFANeutronAgent( - self.ryuapp, **self.kwargs) - self.assertEqual(len(ancillary), len(self.agent.ancillary_brs)) - if ancillary: - bridges = [br.br_name for br in self.agent.ancillary_brs] - for br in ancillary: - self.assertIn(br, bridges) - - def test_ancillary_bridges_single(self): - bridges = ['br-int', 'br-ex'] - self._test_ancillary_bridges(bridges, ['br-ex']) - - def test_ancillary_bridges_none(self): - bridges = ['br-int'] - self._test_ancillary_bridges(bridges, []) - - def test_ancillary_bridges_multiple(self): - bridges = ['br-int', 'br-ex1', 'br-ex2'] - self._test_ancillary_bridges(bridges, ['br-ex1', 'br-ex2']) diff --git a/neutron/tests/unit/oneconvergence/__init__.py b/neutron/tests/unit/oneconvergence/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/oneconvergence/test_nvsd_agent.py b/neutron/tests/unit/oneconvergence/test_nvsd_agent.py deleted file mode 100644 index f04d2fecb..000000000 --- a/neutron/tests/unit/oneconvergence/test_nvsd_agent.py +++ /dev/null @@ -1,177 +0,0 @@ -# Copyright 2014 OneConvergence, Inc. All Rights Reserved. -# -# 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. -# -# @author: Kedar Kulkarni, One Convergence, Inc. - -import contextlib -import time - -import mock -from oslo.config import cfg -import testtools - -from neutron.agent.linux import ovs_lib -from neutron.extensions import securitygroup as ext_sg -from neutron.plugins.oneconvergence.agent import nvsd_neutron_agent -from neutron.tests import base - -DAEMON_LOOP_COUNT = 5 - - -class TestOneConvergenceAgentBase(base.BaseTestCase): - - def setUp(self): - super(TestOneConvergenceAgentBase, self).setUp() - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - with contextlib.nested( - mock.patch('neutron.openstack.common.loopingcall.' - 'FixedIntervalLoopingCall'), - ) as (loopingcall): - kwargs = {'integ_br': 'integration_bridge', - 'root_helper': 'dummy_wrapper', - 'polling_interval': 5} - context = mock.Mock() - self.agent = nvsd_neutron_agent.NVSDNeutronAgent(**kwargs) - self.sg_agent = nvsd_neutron_agent.SecurityGroupAgentRpc( - context, 'dummy_wrapper') - self.callback_nvsd = nvsd_neutron_agent.NVSDAgentRpcCallback( - context, self.agent, self.sg_agent) - self.loopingcall = loopingcall - - -class TestOneConvergenceAgentCallback(TestOneConvergenceAgentBase): - - def test_port_update(self): - with contextlib.nested( - mock.patch.object(ovs_lib.OVSBridge, 'get_vif_port_by_id'), - mock.patch.object(self.sg_agent, 'refresh_firewall') - ) as (get_vif_port_by_id, refresh_firewall): - context = mock.Mock() - vifport = ovs_lib.VifPort('port1', '1', 'id-1', 'mac-1', - self.agent.int_br) - - # The OVS port does not exist. - get_vif_port_by_id.return_value = None - port = {'id': 'update-port-1'} - self.callback_nvsd.port_update(context, port=port) - self.assertEqual(get_vif_port_by_id.call_count, 1) - self.assertFalse(refresh_firewall.call_count) - - # The OVS port exists but no security group is associated. - get_vif_port_by_id.return_value = vifport - port = {'id': 'update-port-1'} - self.callback_nvsd.port_update(context, port=port) - self.assertEqual(get_vif_port_by_id.call_count, 2) - self.assertFalse(refresh_firewall.call_count) - - # The OVS port exists but a security group is associated. - get_vif_port_by_id.return_value = vifport - port = {'id': 'update-port-1', - ext_sg.SECURITYGROUPS: ['default']} - self.callback_nvsd.port_update(context, port=port) - self.assertEqual(get_vif_port_by_id.call_count, 3) - self.assertEqual(refresh_firewall.call_count, 1) - - get_vif_port_by_id.return_value = None - port = {'id': 'update-port-1', - ext_sg.SECURITYGROUPS: ['default']} - self.callback_nvsd.port_update(context, port=port) - self.assertEqual(get_vif_port_by_id.call_count, 4) - self.assertEqual(refresh_firewall.call_count, 1) - - -class TestNVSDAgent(TestOneConvergenceAgentBase): - - def _setup_mock(self): - self.get_vif_ports = mock.patch.object( - ovs_lib.OVSBridge, 'get_vif_port_set', - return_value=set(['id-1', 'id-2'])).start() - self.prepare_devices_filter = mock.patch.object( - self.agent.sg_agent, 'prepare_devices_filter').start() - self.remove_devices_filter = mock.patch.object( - self.agent.sg_agent, 'remove_devices_filter').start() - - def test_daemon_loop(self): - - def state_check(index): - self.assertEqual(len(self.vif_ports_scenario[index]), - len(self.agent.ports)) - - # Fake time.sleep to stop the infinite loop in daemon_loop() - self.sleep_count = 0 - - def sleep_mock(*args, **kwargs): - state_check(self.sleep_count) - self.sleep_count += 1 - if self.sleep_count >= DAEMON_LOOP_COUNT: - raise RuntimeError() - - self.vif_ports_scenario = [set(), set(), set(), set(['id-1', 'id-2']), - set(['id-2', 'id-3'])] - - # Ensure vif_ports_scenario is longer than DAEMON_LOOP_COUNT - if len(self.vif_ports_scenario) < DAEMON_LOOP_COUNT: - self.vif_ports_scenario.extend( - [] for _i in xrange(DAEMON_LOOP_COUNT - - len(self.vif_ports_scenario))) - - with contextlib.nested( - mock.patch.object(time, 'sleep', side_effect=sleep_mock), - mock.patch.object(ovs_lib.OVSBridge, 'get_vif_port_set'), - mock.patch.object(self.agent.sg_agent, 'prepare_devices_filter'), - mock.patch.object(self.agent.sg_agent, 'remove_devices_filter') - ) as (sleep, get_vif_port_set, prepare_devices_filter, - remove_devices_filter): - get_vif_port_set.side_effect = self.vif_ports_scenario - - with testtools.ExpectedException(RuntimeError): - self.agent.daemon_loop() - self.assertEqual(sleep.call_count, DAEMON_LOOP_COUNT) - - expected = [mock.call(set(['id-1', 'id-2'])), - mock.call(set(['id-3']))] - - self.assertEqual(prepare_devices_filter.call_count, 2) - prepare_devices_filter.assert_has_calls(expected) - - expected = [mock.call(set([])), mock.call(set(['id-1']))] - - self.assertEqual(remove_devices_filter.call_count, 2) - remove_devices_filter.assert_has_calls(expected) - - sleep.assert_called_with(self.agent.polling_interval) - - -class TestOneConvergenceAgentMain(base.BaseTestCase): - def test_main(self): - with contextlib.nested( - mock.patch.object(nvsd_neutron_agent, 'NVSDNeutronAgent'), - mock.patch.object(nvsd_neutron_agent, 'common_config'), - mock.patch.object(nvsd_neutron_agent, 'config') - ) as (agent, common_config, config): - config.AGENT.integration_bridge = 'br-int-dummy' - config.AGENT.root_helper = 'root-helper' - config.AGENT.polling_interval = 5 - - nvsd_neutron_agent.main() - - self.assertTrue(common_config.setup_logging.called) - agent.assert_has_calls([ - mock.call('br-int-dummy', 'root-helper', 5), - mock.call().daemon_loop() - ]) diff --git a/neutron/tests/unit/oneconvergence/test_nvsd_plugin.py b/neutron/tests/unit/oneconvergence/test_nvsd_plugin.py deleted file mode 100644 index 564b8c56a..000000000 --- a/neutron/tests/unit/oneconvergence/test_nvsd_plugin.py +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright 2014 OneConvergence, Inc. All Rights Reserved. -# -# 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. -# - -"""Test Library for OneConvergencePlugin.""" - -import contextlib -import uuid - -import mock -from oslo.config import cfg - -from neutron import context -from neutron.extensions import portbindings -from neutron import manager -from neutron.plugins.oneconvergence import plugin as nvsd_plugin -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_l3_plugin - -PLUGIN_NAME = 'neutron.plugins.oneconvergence.plugin.OneConvergencePluginV2' - - -class OneConvergencePluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self): - def mocked_oneconvergence_init(self): - def side_effect(*args, **kwargs): - return {'id': str(uuid.uuid4())} - - self.nvsdlib = mock.Mock() - self.nvsdlib.create_network.side_effect = side_effect - - with mock.patch.object(nvsd_plugin.OneConvergencePluginV2, - 'oneconvergence_init', - new=mocked_oneconvergence_init): - super(OneConvergencePluginV2TestCase, - self).setUp(self._plugin_name) - - -class TestOneConvergencePluginNetworksV2(test_plugin.TestNetworksV2, - OneConvergencePluginV2TestCase): - pass - - -class TestOneConvergencePluginSubnetsV2(test_plugin.TestSubnetsV2, - OneConvergencePluginV2TestCase): - def test_update_subnet_inconsistent_ipv6_gatewayv4(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_create_subnet_with_v6_allocation_pool(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_update_subnet_inconsistent_ipv6_hostroute_dst_v4(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_update_subnet_inconsistent_ipv6_hostroute_np_v4(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_create_subnet_ipv6_attributes(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_create_subnet_ipv6_single_attribute_set(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_update_subnet_ipv6_attributes(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_update_subnet_ipv6_inconsistent_enable_dhcp(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_update_subnet_ipv6_inconsistent_ra_attribute(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_update_subnet_ipv6_inconsistent_address_attribute(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - -class TestOneConvergencePluginPortsV2(test_plugin.TestPortsV2, - test_bindings.PortBindingsTestCase, - OneConvergencePluginV2TestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - - def test_requested_subnet_id_v4_and_v6(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_port_vif_details(self): - plugin = manager.NeutronManager.get_plugin() - with self.port(name='name') as port1: - ctx = context.get_admin_context() - port = plugin.get_port(ctx, port1['port']['id']) - self.assertEqual(port['binding:vif_type'], - portbindings.VIF_TYPE_OVS) - - def test_ports_vif_details(self): - cfg.CONF.set_default('allow_overlapping_ips', True) - plugin = manager.NeutronManager.get_plugin() - with contextlib.nested(self.port(), self.port()) as (port1, port2): - ctx = context.get_admin_context() - ports = plugin.get_ports(ctx) - self.assertEqual(len(ports), 2) - for port in ports: - self.assertEqual(port['binding:vif_type'], - portbindings.VIF_TYPE_OVS) - - def test_ip_allocation_for_ipv6_subnet_slaac_adddress_mode(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - -class TestOneConvergenceBasicGet(test_plugin.TestBasicGet, - OneConvergencePluginV2TestCase): - pass - - -class TestOneConvergenceV2HTTPResponse(test_plugin.TestV2HTTPResponse, - OneConvergencePluginV2TestCase): - pass - - -class TestOneConvergenceL3NatTestCase(test_l3_plugin.L3NatDBIntTestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self): - def mocked_oneconvergence_init(self): - def side_effect(*args, **kwargs): - return {'id': str(uuid.uuid4())} - - self.nvsdlib = mock.Mock() - self.nvsdlib.create_network.side_effect = side_effect - - ext_mgr = test_l3_plugin.L3TestExtensionManager() - - with mock.patch.object(nvsd_plugin.OneConvergencePluginV2, - 'oneconvergence_init', - new=mocked_oneconvergence_init): - super(TestOneConvergenceL3NatTestCase, - self).setUp(plugin=self._plugin_name, ext_mgr=ext_mgr) - - def test_floatingip_with_invalid_create_port(self): - self._test_floatingip_with_invalid_create_port(self._plugin_name) diff --git a/neutron/tests/unit/oneconvergence/test_nvsdlib.py b/neutron/tests/unit/oneconvergence/test_nvsdlib.py deleted file mode 100644 index 5ee80ada6..000000000 --- a/neutron/tests/unit/oneconvergence/test_nvsdlib.py +++ /dev/null @@ -1,261 +0,0 @@ -# Copyright 2014 OneConvergence, Inc. All Rights Reserved. -# -# 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 neutron.openstack.common import jsonutils as json -from neutron.plugins.oneconvergence.lib import nvsdlib -from neutron.tests import base - -NETWORKS_URI = "/pluginhandler/ocplugin/tenant/%s/lnetwork/" -NETWORK_URI = NETWORKS_URI + "%s" -GET_ALL_NETWORKS = "/pluginhandler/ocplugin/tenant/getallnetworks" - -SUBNETS_URI = NETWORK_URI + "/lsubnet/" -SUBNET_URI = SUBNETS_URI + "%s" -GET_ALL_SUBNETS = "/pluginhandler/ocplugin/tenant/getallsubnets" - -PORTS_URI = NETWORK_URI + "/lport/" -PORT_URI = PORTS_URI + "%s" - -EXT_URI = "/pluginhandler/ocplugin/ext/tenant/%s" -FLOATING_IPS_URI = EXT_URI + "/floatingip/" -FLOATING_IP_URI = FLOATING_IPS_URI + "%s" - -ROUTERS_URI = EXT_URI + "/lrouter/" -ROUTER_URI = ROUTERS_URI + "%s" - -TEST_NET = 'test-network' -TEST_SUBNET = 'test-subnet' -TEST_PORT = 'test-port' -TEST_FIP = 'test-floatingip' -TEST_ROUTER = 'test-router' -TEST_TENANT = 'test-tenant' - - -class TestNVSDApi(base.BaseTestCase): - - def setUp(self): - super(TestNVSDApi, self).setUp() - self.nvsdlib = nvsdlib.NVSDApi() - - def test_create_network(self): - network_obj = { - "name": 'test-net', - "tenant_id": TEST_TENANT, - "shared": False, - "admin_state_up": True, - "router:external": False - } - resp = mock.Mock() - resp.json.return_value = {'id': 'uuid'} - with mock.patch.object(self.nvsdlib, 'send_request', - return_value=resp) as send_request: - uri = NETWORKS_URI % TEST_TENANT - net = self.nvsdlib.create_network(network_obj) - send_request.assert_called_once_with("POST", uri, - body=json.dumps(network_obj), - resource='network', - tenant_id=TEST_TENANT) - self.assertEqual(net, {'id': 'uuid'}) - - def test_update_network(self): - network = {'id': TEST_NET, - 'tenant_id': TEST_TENANT} - update_network = {'name': 'new_name'} - uri = NETWORK_URI % (TEST_TENANT, TEST_NET) - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.update_network(network, update_network) - send_request.assert_called_once_with( - "PUT", uri, body=json.dumps(update_network), - resource='network', tenant_id=TEST_TENANT, - resource_id=TEST_NET) - - def test_delete_network(self): - network = {'id': TEST_NET, - 'tenant_id': TEST_TENANT} - - uri = NETWORK_URI % (TEST_TENANT, TEST_NET) - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - with mock.patch.object(self.nvsdlib, '_get_ports'): - self.nvsdlib.delete_network(network) - send_request.assert_called_once_with( - "DELETE", uri, resource='network', - tenant_id=TEST_TENANT, resource_id=TEST_NET) - - def test_create_port(self): - path = PORTS_URI % (TEST_TENANT, TEST_NET) - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - fixed_ips = [{'ip_address': '10.0.0.2', - 'subnet_id': TEST_SUBNET}] - - lport = { - "id": TEST_PORT, - "name": 'test', - "device_id": "device_id", - "device_owner": "device_owner", - "mac_address": "mac_address", - "fixed_ips": fixed_ips, - "admin_state_up": True, - "network_id": TEST_NET, - "status": 'ACTIVE' - } - self.nvsdlib.create_port(TEST_TENANT, lport) - expected = {"id": TEST_PORT, "name": 'test', - "device_id": "device_id", - "device_owner": "device_owner", - "mac_address": "mac_address", - "ip_address": '10.0.0.2', - "subnet_id": TEST_SUBNET, - "admin_state_up": True, - "network_id": TEST_NET, - "status": 'ACTIVE'} - send_request.assert_called_once_with("POST", path, - body=json.dumps(expected), - resource='port', - tenant_id=TEST_TENANT) - - def test_update_port(self): - port = {'id': TEST_PORT, - 'network_id': TEST_NET} - - port_update = {'name': 'new-name'} - uri = PORT_URI % (TEST_TENANT, TEST_NET, TEST_PORT) - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.update_port(TEST_TENANT, port, port_update) - send_request.assert_called_once_with("PUT", uri, - body=json.dumps(port_update), - resource='port', - resource_id='test-port', - tenant_id=TEST_TENANT) - - def test_delete_port(self): - port = {'network_id': TEST_NET, - 'tenant_id': TEST_TENANT} - uri = PORT_URI % (TEST_TENANT, TEST_NET, TEST_PORT) - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.delete_port(TEST_PORT, port) - send_request.assert_called_once_with("DELETE", uri, - resource='port', - tenant_id=TEST_TENANT, - resource_id=TEST_PORT) - - def test_create_subnet(self): - subnet = {'id': TEST_SUBNET, - 'tenant_id': TEST_TENANT, - 'network_id': TEST_NET} - uri = SUBNETS_URI % (TEST_TENANT, TEST_NET) - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.create_subnet(subnet) - send_request.assert_called_once_with("POST", uri, - body=json.dumps(subnet), - resource='subnet', - tenant_id=TEST_TENANT) - - def test_update_subnet(self): - subnet = {'id': TEST_SUBNET, - 'tenant_id': TEST_TENANT, - 'network_id': TEST_NET} - subnet_update = {'name': 'new-name'} - uri = SUBNET_URI % (TEST_TENANT, TEST_NET, TEST_SUBNET) - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.update_subnet(subnet, subnet_update) - send_request.assert_called_once_with( - "PUT", uri, body=json.dumps(subnet_update), resource='subnet', - tenant_id=TEST_TENANT, resource_id=TEST_SUBNET) - - def test_delete_subnet(self): - subnet = {'id': TEST_SUBNET, - 'tenant_id': TEST_TENANT, - 'network_id': TEST_NET} - uri = SUBNET_URI % (TEST_TENANT, TEST_NET, TEST_SUBNET) - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.delete_subnet(subnet) - send_request.assert_called_once_with("DELETE", uri, - resource='subnet', - tenant_id=TEST_TENANT, - resource_id=TEST_SUBNET) - - def test_create_floatingip(self): - floatingip = {'id': TEST_FIP, - 'tenant_id': TEST_TENANT} - uri = FLOATING_IPS_URI % TEST_TENANT - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.create_floatingip(floatingip) - send_request.assert_called_once_with("POST", uri, - body=json.dumps(floatingip), - resource='floating_ip', - tenant_id=TEST_TENANT) - - def test_update_floatingip(self): - floatingip = {'id': TEST_FIP, - 'tenant_id': TEST_TENANT} - uri = FLOATING_IP_URI % (TEST_TENANT, TEST_FIP) - - floatingip_update = {'floatingip': {'router_id': TEST_ROUTER}} - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.update_floatingip(floatingip, floatingip_update) - send_request.assert_called_once_with( - "PUT", uri, body=json.dumps(floatingip_update['floatingip']), - resource='floating_ip', tenant_id=TEST_TENANT, - resource_id=TEST_FIP) - - def test_delete_floatingip(self): - floatingip = {'id': TEST_FIP, - 'tenant_id': TEST_TENANT} - uri = FLOATING_IP_URI % (TEST_TENANT, TEST_FIP) - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.delete_floatingip(floatingip) - send_request.assert_called_once_with( - "DELETE", uri, resource='floating_ip', tenant_id=TEST_TENANT, - resource_id=TEST_FIP) - - def test_create_router(self): - router = {'id': TEST_ROUTER, 'tenant_id': TEST_TENANT} - uri = ROUTERS_URI % TEST_TENANT - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.create_router(router) - send_request.assert_called_once_with( - "POST", uri, body=json.dumps(router), resource='router', - tenant_id=TEST_TENANT) - - def test_update_router(self): - router = {'id': TEST_ROUTER, 'tenant_id': TEST_TENANT} - uri = ROUTER_URI % (TEST_TENANT, TEST_ROUTER) - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.update_router(router) - send_request.assert_called_once_with( - "PUT", uri, body=json.dumps(router), - resource='router', tenant_id=TEST_TENANT, - resource_id=TEST_ROUTER) - - def test_delete_router(self): - uri = ROUTER_URI % (TEST_TENANT, TEST_ROUTER) - - with mock.patch.object(self.nvsdlib, 'send_request') as send_request: - self.nvsdlib.delete_router(TEST_TENANT, TEST_ROUTER) - send_request.assert_called_once_with( - "DELETE", uri, resource='router', - tenant_id=TEST_TENANT, resource_id=TEST_ROUTER) diff --git a/neutron/tests/unit/oneconvergence/test_plugin_helper.py b/neutron/tests/unit/oneconvergence/test_plugin_helper.py deleted file mode 100644 index 21031a79c..000000000 --- a/neutron/tests/unit/oneconvergence/test_plugin_helper.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2014 OneConvergence, Inc. All Rights Reserved. -# -# 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. -# -# @author: Kedar Kulkarni, One Convergence, Inc. -import mock -import requests - -from neutron.openstack.common import jsonutils as json -from neutron.plugins.oneconvergence.lib import config # noqa -from neutron.plugins.oneconvergence.lib import plugin_helper as client -from neutron.tests import base - - -class TestPluginHelper(base.BaseTestCase): - def setUp(self): - super(TestPluginHelper, self).setUp() - self.nvsdcontroller = client.NVSDController() - - def get_response(self, *args, **kwargs): - response = mock.Mock() - response.status_code = requests.codes.ok - response.content = json.dumps({'session_uuid': 'new_auth_token'}) - return response - - def test_login(self): - login_url = ('http://127.0.0.1:8082/pluginhandler/ocplugin/' - 'authmgmt/login') - headers = {'Content-Type': 'application/json'} - data = json.dumps({"user_name": "ocplugin", "passwd": "oc123"}) - timeout = 30.0 - - with mock.patch.object(self.nvsdcontroller, 'do_request', - side_effect=self.get_response) as do_request: - self.nvsdcontroller.login() - do_request.assert_called_once_with('POST', url=login_url, - headers=headers, data=data, - timeout=timeout) - - def test_request(self): - with mock.patch.object(self.nvsdcontroller, 'do_request', - side_effect=self.get_response) as do_request: - self.nvsdcontroller.login() - self.nvsdcontroller.request("POST", "/some_url") - self.assertEqual(do_request.call_count, 2) - do_request.assert_called_with( - 'POST', - url='http://127.0.0.1:8082/some_url?authToken=new_auth_token', - headers={'Content-Type': 'application/json'}, data='', - timeout=30.0) diff --git a/neutron/tests/unit/oneconvergence/test_security_group.py b/neutron/tests/unit/oneconvergence/test_security_group.py deleted file mode 100644 index af08132c5..000000000 --- a/neutron/tests/unit/oneconvergence/test_security_group.py +++ /dev/null @@ -1,157 +0,0 @@ -# Copyright 2014 OneConvergence, Inc. All Rights Reserved. -# -# 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. -# -# @author: Kedar Kulkarni, One Convergence, Inc. - -import uuid - -import mock - -from neutron.api.v2 import attributes -from neutron.extensions import securitygroup as ext_sg -from neutron import manager -from neutron.plugins.oneconvergence import plugin as nvsd_plugin -from neutron.tests.unit import test_extension_security_group as test_sg -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - -PLUGIN_NAME = ('neutron.plugins.oneconvergence.' - 'plugin.OneConvergencePluginV2') -AGENTNOTIFIER = ('neutron.plugins.oneconvergence.' - 'plugin.NVSDPluginV2AgentNotifierApi') -DUMMY_NVSD_LIB = ('neutron.tests.unit.oneconvergence.dummynvsdlib.NVSDApi') - - -class OneConvergenceSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self): - def mocked_oneconvergence_init(self): - def side_effect(*args, **kwargs): - return {'id': str(uuid.uuid4())} - - self.nvsdlib = mock.Mock() - self.nvsdlib.create_network.side_effect = side_effect - - test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER) - notifier_cls = mock.patch(AGENTNOTIFIER).start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - self._attribute_map_bk_ = {} - for item in attributes.RESOURCE_ATTRIBUTE_MAP: - self._attribute_map_bk_[item] = (attributes. - RESOURCE_ATTRIBUTE_MAP[item]. - copy()) - with mock.patch.object(nvsd_plugin.OneConvergencePluginV2, - 'oneconvergence_init', - new=mocked_oneconvergence_init): - super(OneConvergenceSecurityGroupsTestCase, - self).setUp(PLUGIN_NAME) - - def tearDown(self): - super(OneConvergenceSecurityGroupsTestCase, self).tearDown() - attributes.RESOURCE_ATTRIBUTE_MAP = self._attribute_map_bk_ - - -class TestOneConvergenceSGServerRpcCallBack( - OneConvergenceSecurityGroupsTestCase, - test_sg_rpc.SGServerRpcCallBackMixinTestCase): - def test_security_group_rules_for_devices_ipv6_egress(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_rules_for_devices_ipv6_ingress(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_rules_for_devices_ipv6_source_group(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_ra_rules_for_devices_ipv6_gateway_global(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_ra_rules_for_devices_ipv6_gateway_lla(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_ra_rules_for_devices_ipv6_no_gateway_port(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_rule_for_device_ipv6_multi_router_interfaces(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - -class TestOneConvergenceSGServerRpcCallBackXML( - OneConvergenceSecurityGroupsTestCase, - test_sg_rpc.SGServerRpcCallBackMixinTestCaseXML): - def test_security_group_rules_for_devices_ipv6_egress(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_rules_for_devices_ipv6_ingress(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_rules_for_devices_ipv6_source_group(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_ra_rules_for_devices_ipv6_gateway_global(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_ra_rules_for_devices_ipv6_gateway_lla(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_ra_rules_for_devices_ipv6_no_gateway_port(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - def test_security_group_rule_for_device_ipv6_multi_router_interfaces(self): - self.skipTest("NVSD Plugin does not support IPV6.") - - -class TestOneConvergenceSecurityGroups(OneConvergenceSecurityGroupsTestCase, - test_sg.TestSecurityGroups, - test_sg_rpc.SGNotificationTestMixin): - - def test_security_group_get_port_from_device(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - security_group_id = sg['security_group']['id'] - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - fixed_ips = port['port']['fixed_ips'] - data = {'port': {'fixed_ips': fixed_ips, - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: - [security_group_id]}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - port_id = res['port']['id'] - plugin = manager.NeutronManager.get_plugin() - callbacks = plugin.endpoints[0] - port_dict = callbacks.get_port_from_device(port_id) - self.assertEqual(port_id, port_dict['id']) - self.assertEqual([security_group_id], - port_dict[ext_sg.SECURITYGROUPS]) - self.assertEqual([], port_dict['security_group_rules']) - self.assertEqual([fixed_ips[0]['ip_address']], - port_dict['fixed_ips']) - self._delete('ports', port_id) - - def test_security_group_get_port_from_device_with_no_port(self): - - plugin = manager.NeutronManager.get_plugin() - port_dict = plugin.endpoints[0].get_port_from_device('bad_device_id') - self.assertIsNone(port_dict) - - -class TestOneConvergenceSecurityGroupsXML(TestOneConvergenceSecurityGroups): - fmt = 'xml' diff --git a/neutron/tests/unit/openvswitch/__init__.py b/neutron/tests/unit/openvswitch/__init__.py deleted file mode 100644 index 7e503debd..000000000 --- a/neutron/tests/unit/openvswitch/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/openvswitch/test_agent_scheduler.py b/neutron/tests/unit/openvswitch/test_agent_scheduler.py deleted file mode 100644 index 04ef593b5..000000000 --- a/neutron/tests/unit/openvswitch/test_agent_scheduler.py +++ /dev/null @@ -1,1245 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 contextlib -import copy - -import mock -from oslo.config import cfg -from webob import exc - -from neutron.api import extensions -from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api -from neutron.api.v2 import attributes -from neutron.common import constants -from neutron import context -from neutron.db import agents_db -from neutron.db import dhcp_rpc_base -from neutron.db import l3_rpc_base -from neutron.extensions import agent -from neutron.extensions import dhcpagentscheduler -from neutron.extensions import l3agentscheduler -from neutron import manager -from neutron.openstack.common import timeutils -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants as service_constants -from neutron.tests.unit import test_agent_ext_plugin -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_extensions -from neutron.tests.unit import test_l3_plugin -from neutron.tests.unit import testlib_api -from neutron import wsgi - -L3_HOSTA = 'hosta' -DHCP_HOSTA = 'hosta' -L3_HOSTB = 'hostb' -DHCP_HOSTC = 'hostc' - - -class AgentSchedulerTestMixIn(object): - - def _request_list(self, path, admin_context=True, - expected_code=exc.HTTPOk.code): - req = self._path_req(path, admin_context=admin_context) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, expected_code) - return self.deserialize(self.fmt, res) - - def _path_req(self, path, method='GET', data=None, - query_string=None, - admin_context=True): - content_type = 'application/%s' % self.fmt - body = None - if data is not None: # empty dict is valid - body = wsgi.Serializer().serialize(data, content_type) - if admin_context: - return testlib_api.create_request( - path, body, content_type, method, query_string=query_string) - else: - return testlib_api.create_request( - path, body, content_type, method, query_string=query_string, - context=context.Context('', 'tenant_id')) - - def _path_create_request(self, path, data, admin_context=True): - return self._path_req(path, method='POST', data=data, - admin_context=admin_context) - - def _path_show_request(self, path, admin_context=True): - return self._path_req(path, admin_context=admin_context) - - def _path_delete_request(self, path, admin_context=True): - return self._path_req(path, method='DELETE', - admin_context=admin_context) - - def _path_update_request(self, path, data, admin_context=True): - return self._path_req(path, method='PUT', data=data, - admin_context=admin_context) - - def _list_routers_hosted_by_l3_agent(self, agent_id, - expected_code=exc.HTTPOk.code, - admin_context=True): - path = "/agents/%s/%s.%s" % (agent_id, - l3agentscheduler.L3_ROUTERS, - self.fmt) - return self._request_list(path, expected_code=expected_code, - admin_context=admin_context) - - def _list_networks_hosted_by_dhcp_agent(self, agent_id, - expected_code=exc.HTTPOk.code, - admin_context=True): - path = "/agents/%s/%s.%s" % (agent_id, - dhcpagentscheduler.DHCP_NETS, - self.fmt) - return self._request_list(path, expected_code=expected_code, - admin_context=admin_context) - - def _list_l3_agents_hosting_router(self, router_id, - expected_code=exc.HTTPOk.code, - admin_context=True): - path = "/routers/%s/%s.%s" % (router_id, - l3agentscheduler.L3_AGENTS, - self.fmt) - return self._request_list(path, expected_code=expected_code, - admin_context=admin_context) - - def _list_dhcp_agents_hosting_network(self, network_id, - expected_code=exc.HTTPOk.code, - admin_context=True): - path = "/networks/%s/%s.%s" % (network_id, - dhcpagentscheduler.DHCP_AGENTS, - self.fmt) - return self._request_list(path, expected_code=expected_code, - admin_context=admin_context) - - def _add_router_to_l3_agent(self, id, router_id, - expected_code=exc.HTTPCreated.code, - admin_context=True): - path = "/agents/%s/%s.%s" % (id, - l3agentscheduler.L3_ROUTERS, - self.fmt) - req = self._path_create_request(path, - {'router_id': router_id}, - admin_context=admin_context) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, expected_code) - - def _add_network_to_dhcp_agent(self, id, network_id, - expected_code=exc.HTTPCreated.code, - admin_context=True): - path = "/agents/%s/%s.%s" % (id, - dhcpagentscheduler.DHCP_NETS, - self.fmt) - req = self._path_create_request(path, - {'network_id': network_id}, - admin_context=admin_context) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, expected_code) - - def _remove_network_from_dhcp_agent(self, id, network_id, - expected_code=exc.HTTPNoContent.code, - admin_context=True): - path = "/agents/%s/%s/%s.%s" % (id, - dhcpagentscheduler.DHCP_NETS, - network_id, - self.fmt) - req = self._path_delete_request(path, - admin_context=admin_context) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, expected_code) - - def _remove_router_from_l3_agent(self, id, router_id, - expected_code=exc.HTTPNoContent.code, - admin_context=True): - path = "/agents/%s/%s/%s.%s" % (id, - l3agentscheduler.L3_ROUTERS, - router_id, - self.fmt) - req = self._path_delete_request(path, admin_context=admin_context) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, expected_code) - - def _register_one_agent_state(self, agent_state): - callback = agents_db.AgentExtRpcCallback() - callback.report_state(self.adminContext, - agent_state={'agent_state': agent_state}, - time=timeutils.strtime()) - - def _disable_agent(self, agent_id, admin_state_up=False): - new_agent = {} - new_agent['agent'] = {} - new_agent['agent']['admin_state_up'] = admin_state_up - self._update('agents', agent_id, new_agent) - - def _get_agent_id(self, agent_type, host): - agents = self._list_agents() - for agent_data in agents['agents']: - if (agent_data['agent_type'] == agent_type and - agent_data['host'] == host): - return agent_data['id'] - - -class OvsAgentSchedulerTestCaseBase(test_l3_plugin.L3NatTestCaseMixin, - test_agent_ext_plugin.AgentDBTestMixIn, - AgentSchedulerTestMixIn, - test_plugin.NeutronDbPluginV2TestCase): - fmt = 'json' - plugin_str = ('neutron.plugins.openvswitch.' - 'ovs_neutron_plugin.OVSNeutronPluginV2') - l3_plugin = None - - def setUp(self): - # Save the global RESOURCE_ATTRIBUTE_MAP before loading plugin - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - if self.l3_plugin: - service_plugins = {'l3_plugin_name': self.l3_plugin} - else: - service_plugins = None - super(OvsAgentSchedulerTestCaseBase, self).setUp( - self.plugin_str, service_plugins=service_plugins) - ext_mgr = extensions.PluginAwareExtensionManager.get_instance() - self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr) - self.adminContext = context.get_admin_context() - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - agent.RESOURCE_ATTRIBUTE_MAP) - self.addCleanup(self.restore_attribute_map) - self.l3agentscheduler_dbMinxin = ( - manager.NeutronManager.get_service_plugins().get( - service_constants.L3_ROUTER_NAT)) - - def restore_attribute_map(self): - # Restore the original RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - - -class OvsAgentSchedulerTestCase(OvsAgentSchedulerTestCaseBase): - - def test_report_states(self): - self._register_agent_states() - agents = self._list_agents() - self.assertEqual(4, len(agents['agents'])) - - def test_network_scheduling_on_network_creation(self): - self._register_agent_states() - with self.network() as net: - dhcp_agents = self._list_dhcp_agents_hosting_network( - net['network']['id']) - self.assertEqual(0, len(dhcp_agents['agents'])) - - def test_network_auto_schedule_with_disabled(self): - cfg.CONF.set_override('allow_overlapping_ips', True) - with contextlib.nested(self.subnet(), - self.subnet()): - dhcp_rpc = dhcp_rpc_base.DhcpRpcCallbackMixin() - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - hostc_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTC) - self._disable_agent(hosta_id) - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTA) - # second agent will host all the networks since first is disabled. - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTC) - networks = self._list_networks_hosted_by_dhcp_agent(hostc_id) - num_hostc_nets = len(networks['networks']) - networks = self._list_networks_hosted_by_dhcp_agent(hosta_id) - num_hosta_nets = len(networks['networks']) - self.assertEqual(0, num_hosta_nets) - self.assertEqual(2, num_hostc_nets) - - def test_network_auto_schedule_with_no_dhcp(self): - cfg.CONF.set_override('allow_overlapping_ips', True) - with contextlib.nested(self.subnet(enable_dhcp=False), - self.subnet(enable_dhcp=False)): - dhcp_rpc = dhcp_rpc_base.DhcpRpcCallbackMixin() - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - hostc_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTC) - self._disable_agent(hosta_id) - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTA) - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTC) - networks = self._list_networks_hosted_by_dhcp_agent(hostc_id) - num_hostc_nets = len(networks['networks']) - networks = self._list_networks_hosted_by_dhcp_agent(hosta_id) - num_hosta_nets = len(networks['networks']) - self.assertEqual(0, num_hosta_nets) - self.assertEqual(0, num_hostc_nets) - - def test_network_auto_schedule_with_multiple_agents(self): - cfg.CONF.set_override('dhcp_agents_per_network', 2) - cfg.CONF.set_override('allow_overlapping_ips', True) - with contextlib.nested(self.subnet(), - self.subnet()): - dhcp_rpc = dhcp_rpc_base.DhcpRpcCallbackMixin() - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - hostc_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTC) - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTA) - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTC) - networks = self._list_networks_hosted_by_dhcp_agent(hostc_id) - num_hostc_nets = len(networks['networks']) - networks = self._list_networks_hosted_by_dhcp_agent(hosta_id) - num_hosta_nets = len(networks['networks']) - self.assertEqual(2, num_hosta_nets) - self.assertEqual(2, num_hostc_nets) - - def test_network_auto_schedule_restart_dhcp_agent(self): - cfg.CONF.set_override('dhcp_agents_per_network', 2) - with self.subnet() as sub1: - dhcp_rpc = dhcp_rpc_base.DhcpRpcCallbackMixin() - self._register_agent_states() - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTA) - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTA) - dhcp_agents = self._list_dhcp_agents_hosting_network( - sub1['subnet']['network_id']) - self.assertEqual(1, len(dhcp_agents['agents'])) - - def test_network_auto_schedule_with_hosted(self): - # one agent hosts all the networks, other hosts none - cfg.CONF.set_override('allow_overlapping_ips', True) - with contextlib.nested(self.subnet(), - self.subnet()) as (sub1, sub2): - dhcp_rpc = dhcp_rpc_base.DhcpRpcCallbackMixin() - self._register_agent_states() - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTA) - # second agent will not host the network since first has got it. - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTC) - dhcp_agents = self._list_dhcp_agents_hosting_network( - sub1['subnet']['network_id']) - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - hostc_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTC) - hosta_nets = self._list_networks_hosted_by_dhcp_agent(hosta_id) - num_hosta_nets = len(hosta_nets['networks']) - hostc_nets = self._list_networks_hosted_by_dhcp_agent(hostc_id) - num_hostc_nets = len(hostc_nets['networks']) - - self.assertEqual(2, num_hosta_nets) - self.assertEqual(0, num_hostc_nets) - self.assertEqual(1, len(dhcp_agents['agents'])) - self.assertEqual(DHCP_HOSTA, dhcp_agents['agents'][0]['host']) - - def test_network_auto_schedule_with_hosted_2(self): - # one agent hosts one network - dhcp_rpc = dhcp_rpc_base.DhcpRpcCallbackMixin() - dhcp_hosta = { - 'binary': 'neutron-dhcp-agent', - 'host': DHCP_HOSTA, - 'topic': 'DHCP_AGENT', - 'configurations': {'dhcp_driver': 'dhcp_driver', - 'use_namespaces': True, - }, - 'agent_type': constants.AGENT_TYPE_DHCP} - dhcp_hostc = copy.deepcopy(dhcp_hosta) - dhcp_hostc['host'] = DHCP_HOSTC - cfg.CONF.set_override('allow_overlapping_ips', True) - with self.subnet() as sub1: - self._register_one_agent_state(dhcp_hosta) - dhcp_rpc.get_active_networks(self.adminContext, host=DHCP_HOSTA) - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - self._disable_agent(hosta_id, admin_state_up=False) - with self.subnet() as sub2: - self._register_one_agent_state(dhcp_hostc) - dhcp_rpc.get_active_networks(self.adminContext, - host=DHCP_HOSTC) - dhcp_agents_1 = self._list_dhcp_agents_hosting_network( - sub1['subnet']['network_id']) - dhcp_agents_2 = self._list_dhcp_agents_hosting_network( - sub2['subnet']['network_id']) - hosta_nets = self._list_networks_hosted_by_dhcp_agent(hosta_id) - num_hosta_nets = len(hosta_nets['networks']) - hostc_id = self._get_agent_id( - constants.AGENT_TYPE_DHCP, - DHCP_HOSTC) - hostc_nets = self._list_networks_hosted_by_dhcp_agent(hostc_id) - num_hostc_nets = len(hostc_nets['networks']) - - self.assertEqual(1, num_hosta_nets) - self.assertEqual(1, num_hostc_nets) - self.assertEqual(1, len(dhcp_agents_1['agents'])) - self.assertEqual(1, len(dhcp_agents_2['agents'])) - self.assertEqual(DHCP_HOSTA, dhcp_agents_1['agents'][0]['host']) - self.assertEqual(DHCP_HOSTC, dhcp_agents_2['agents'][0]['host']) - - def test_network_scheduling_on_port_creation(self): - with self.subnet() as subnet: - dhcp_agents = self._list_dhcp_agents_hosting_network( - subnet['subnet']['network_id']) - result0 = len(dhcp_agents['agents']) - self._register_agent_states() - with self.port(subnet=subnet, - device_owner="compute:test:" + DHCP_HOSTA) as port: - dhcp_agents = self._list_dhcp_agents_hosting_network( - port['port']['network_id']) - result1 = len(dhcp_agents['agents']) - self.assertEqual(0, result0) - self.assertEqual(1, result1) - - def test_network_ha_scheduling_on_port_creation(self): - cfg.CONF.set_override('dhcp_agents_per_network', 2) - with self.subnet() as subnet: - dhcp_agents = self._list_dhcp_agents_hosting_network( - subnet['subnet']['network_id']) - result0 = len(dhcp_agents['agents']) - self._register_agent_states() - with self.port(subnet=subnet, - device_owner="compute:test:" + DHCP_HOSTA) as port: - dhcp_agents = self._list_dhcp_agents_hosting_network( - port['port']['network_id']) - result1 = len(dhcp_agents['agents']) - self.assertEqual(0, result0) - self.assertEqual(2, result1) - - def test_network_ha_scheduling_on_port_creation_with_new_agent(self): - cfg.CONF.set_override('dhcp_agents_per_network', 3) - with self.subnet() as subnet: - dhcp_agents = self._list_dhcp_agents_hosting_network( - subnet['subnet']['network_id']) - result0 = len(dhcp_agents['agents']) - self._register_agent_states() - with self.port(subnet=subnet, - device_owner="compute:test:" + DHCP_HOSTA) as port: - dhcp_agents = self._list_dhcp_agents_hosting_network( - port['port']['network_id']) - result1 = len(dhcp_agents['agents']) - self._register_one_dhcp_agent() - with self.port(subnet=subnet, - device_owner="compute:test:" + DHCP_HOSTA) as port: - dhcp_agents = self._list_dhcp_agents_hosting_network( - port['port']['network_id']) - result2 = len(dhcp_agents['agents']) - self.assertEqual(0, result0) - self.assertEqual(2, result1) - self.assertEqual(3, result2) - - def test_network_scheduler_with_disabled_agent(self): - dhcp_hosta = { - 'binary': 'neutron-dhcp-agent', - 'host': DHCP_HOSTA, - 'topic': 'DHCP_AGENT', - 'configurations': {'dhcp_driver': 'dhcp_driver', - 'use_namespaces': True, - }, - 'agent_type': constants.AGENT_TYPE_DHCP} - self._register_one_agent_state(dhcp_hosta) - with self.port() as port1: - dhcp_agents = self._list_dhcp_agents_hosting_network( - port1['port']['network_id']) - self.assertEqual(1, len(dhcp_agents['agents'])) - agents = self._list_agents() - self._disable_agent(agents['agents'][0]['id']) - with self.port() as port2: - dhcp_agents = self._list_dhcp_agents_hosting_network( - port2['port']['network_id']) - self.assertEqual(0, len(dhcp_agents['agents'])) - - def test_network_scheduler_with_down_agent(self): - dhcp_hosta = { - 'binary': 'neutron-dhcp-agent', - 'host': DHCP_HOSTA, - 'topic': 'DHCP_AGENT', - 'configurations': {'dhcp_driver': 'dhcp_driver', - 'use_namespaces': True, - }, - 'agent_type': constants.AGENT_TYPE_DHCP} - self._register_one_agent_state(dhcp_hosta) - is_agent_down_str = 'neutron.db.agents_db.AgentDbMixin.is_agent_down' - with mock.patch(is_agent_down_str) as mock_is_agent_down: - mock_is_agent_down.return_value = False - with self.port() as port: - dhcp_agents = self._list_dhcp_agents_hosting_network( - port['port']['network_id']) - self.assertEqual(1, len(dhcp_agents['agents'])) - with mock.patch(is_agent_down_str) as mock_is_agent_down: - mock_is_agent_down.return_value = True - with self.port() as port: - dhcp_agents = self._list_dhcp_agents_hosting_network( - port['port']['network_id']) - self.assertEqual(0, len(dhcp_agents['agents'])) - - def test_network_scheduler_with_hosted_network(self): - plugin = manager.NeutronManager.get_plugin() - dhcp_hosta = { - 'binary': 'neutron-dhcp-agent', - 'host': DHCP_HOSTA, - 'topic': 'DHCP_AGENT', - 'configurations': {'dhcp_driver': 'dhcp_driver', - 'use_namespaces': True, - }, - 'agent_type': constants.AGENT_TYPE_DHCP} - self._register_one_agent_state(dhcp_hosta) - with self.port() as port1: - dhcp_agents = self._list_dhcp_agents_hosting_network( - port1['port']['network_id']) - self.assertEqual(1, len(dhcp_agents['agents'])) - with mock.patch.object(plugin, - 'get_dhcp_agents_hosting_networks', - autospec=True) as mock_hosting_agents: - - mock_hosting_agents.return_value = plugin.get_agents_db( - self.adminContext) - with self.network('test', do_delete=False) as net1: - pass - with self.subnet(network=net1, - cidr='10.0.1.0/24', - do_delete=False) as subnet1: - pass - with self.port(subnet=subnet1, no_delete=True) as port2: - pass - dhcp_agents = self._list_dhcp_agents_hosting_network( - port2['port']['network_id']) - self.assertEqual(0, len(dhcp_agents['agents'])) - - def test_network_policy(self): - with self.network() as net1: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - self._list_networks_hosted_by_dhcp_agent( - hosta_id, expected_code=exc.HTTPForbidden.code, - admin_context=False) - self._add_network_to_dhcp_agent( - hosta_id, net1['network']['id'], - expected_code=exc.HTTPForbidden.code, - admin_context=False) - self._add_network_to_dhcp_agent(hosta_id, - net1['network']['id']) - self._remove_network_from_dhcp_agent( - hosta_id, net1['network']['id'], - expected_code=exc.HTTPForbidden.code, - admin_context=False) - self._list_dhcp_agents_hosting_network( - net1['network']['id'], - expected_code=exc.HTTPForbidden.code, - admin_context=False) - - def test_network_add_to_dhcp_agent(self): - with self.network() as net1: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - num_before_add = len( - self._list_networks_hosted_by_dhcp_agent( - hosta_id)['networks']) - self._add_network_to_dhcp_agent(hosta_id, - net1['network']['id']) - num_after_add = len( - self._list_networks_hosted_by_dhcp_agent( - hosta_id)['networks']) - self.assertEqual(0, num_before_add) - self.assertEqual(1, num_after_add) - - def test_network_remove_from_dhcp_agent(self): - dhcp_hosta = { - 'binary': 'neutron-dhcp-agent', - 'host': DHCP_HOSTA, - 'topic': 'DHCP_AGENT', - 'configurations': {'dhcp_driver': 'dhcp_driver', - 'use_namespaces': True, - }, - 'agent_type': constants.AGENT_TYPE_DHCP} - self._register_one_agent_state(dhcp_hosta) - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - with self.port() as port1: - num_before_remove = len( - self._list_networks_hosted_by_dhcp_agent( - hosta_id)['networks']) - self._remove_network_from_dhcp_agent(hosta_id, - port1['port']['network_id']) - num_after_remove = len( - self._list_networks_hosted_by_dhcp_agent( - hosta_id)['networks']) - self.assertEqual(1, num_before_remove) - self.assertEqual(0, num_after_remove) - - def test_list_active_networks_on_not_registered_yet_dhcp_agent(self): - plugin = manager.NeutronManager.get_plugin() - nets = plugin.list_active_networks_on_active_dhcp_agent( - self.adminContext, host=DHCP_HOSTA) - self.assertEqual([], nets) - - def test_reserved_port_after_network_remove_from_dhcp_agent(self): - dhcp_hosta = { - 'binary': 'neutron-dhcp-agent', - 'host': DHCP_HOSTA, - 'topic': 'DHCP_AGENT', - 'configurations': {'dhcp_driver': 'dhcp_driver', - 'use_namespaces': True, - }, - 'agent_type': constants.AGENT_TYPE_DHCP} - self._register_one_agent_state(dhcp_hosta) - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - with self.port(device_owner=constants.DEVICE_OWNER_DHCP, - host=DHCP_HOSTA) as port1: - self._remove_network_from_dhcp_agent(hosta_id, - port1['port']['network_id']) - port_res = self._list_ports( - 'json', - 200, - network_id=port1['port']['network_id']) - port_list = self.deserialize('json', port_res) - self.assertEqual(port_list['ports'][0]['device_id'], - constants.DEVICE_ID_RESERVED_DHCP_PORT) - - def test_router_auto_schedule_with_invalid_router(self): - with self.router() as router: - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_agent_states() - # deleted router - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA, - router_ids=[router['router']['id']]) - self.assertFalse(ret_a) - # non-existent router - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA, - router_ids=[uuidutils.generate_uuid()]) - self.assertFalse(ret_a) - - def test_router_auto_schedule_with_hosted(self): - with self.router() as router: - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_agent_states() - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - ret_b = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTB) - l3_agents = self._list_l3_agents_hosting_router( - router['router']['id']) - self.assertEqual(1, len(ret_a)) - self.assertIn(router['router']['id'], [r['id'] for r in ret_a]) - self.assertFalse(len(ret_b)) - self.assertEqual(1, len(l3_agents['agents'])) - self.assertEqual(L3_HOSTA, l3_agents['agents'][0]['host']) - - def test_router_auto_schedule_restart_l3_agent(self): - with self.router(): - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_agent_states() - l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - - def test_router_auto_schedule_with_hosted_2(self): - # one agent hosts one router - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - l3_hosta = { - 'binary': 'neutron-l3-agent', - 'host': L3_HOSTA, - 'topic': 'L3_AGENT', - 'configurations': {'use_namespaces': True, - 'router_id': None, - 'handle_internal_only_routers': - True, - 'gateway_external_network_id': - None, - 'interface_driver': 'interface_driver', - }, - 'agent_type': constants.AGENT_TYPE_L3} - l3_hostb = copy.deepcopy(l3_hosta) - l3_hostb['host'] = L3_HOSTB - with self.router() as router1: - self._register_one_agent_state(l3_hosta) - l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - self._disable_agent(hosta_id, admin_state_up=False) - with self.router() as router2: - self._register_one_agent_state(l3_hostb) - l3_rpc.sync_routers(self.adminContext, host=L3_HOSTB) - l3_agents_1 = self._list_l3_agents_hosting_router( - router1['router']['id']) - l3_agents_2 = self._list_l3_agents_hosting_router( - router2['router']['id']) - hosta_routers = self._list_routers_hosted_by_l3_agent(hosta_id) - num_hosta_routers = len(hosta_routers['routers']) - hostb_id = self._get_agent_id( - constants.AGENT_TYPE_L3, - L3_HOSTB) - hostb_routers = self._list_routers_hosted_by_l3_agent(hostb_id) - num_hostc_routers = len(hostb_routers['routers']) - - self.assertEqual(1, num_hosta_routers) - self.assertEqual(1, num_hostc_routers) - self.assertEqual(1, len(l3_agents_1['agents'])) - self.assertEqual(1, len(l3_agents_2['agents'])) - self.assertEqual(L3_HOSTA, l3_agents_1['agents'][0]['host']) - self.assertEqual(L3_HOSTB, l3_agents_2['agents'][0]['host']) - - def test_router_auto_schedule_with_disabled(self): - with contextlib.nested(self.router(), - self.router()): - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - hostb_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTB) - self._disable_agent(hosta_id) - # first agent will not host router since it is disabled - l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - # second agent will host all the routers since first is disabled. - l3_rpc.sync_routers(self.adminContext, host=L3_HOSTB) - hostb_routers = self._list_routers_hosted_by_l3_agent(hostb_id) - num_hostb_routers = len(hostb_routers['routers']) - hosta_routers = self._list_routers_hosted_by_l3_agent(hosta_id) - num_hosta_routers = len(hosta_routers['routers']) - self.assertEqual(2, num_hostb_routers) - self.assertEqual(0, num_hosta_routers) - - def test_router_auto_schedule_with_candidates(self): - l3_hosta = { - 'binary': 'neutron-l3-agent', - 'host': L3_HOSTA, - 'topic': 'L3_AGENT', - 'configurations': {'use_namespaces': False, - 'router_id': None, - 'handle_internal_only_routers': - True, - 'gateway_external_network_id': - None, - 'interface_driver': 'interface_driver', - }, - 'agent_type': constants.AGENT_TYPE_L3} - with contextlib.nested(self.router(), - self.router()) as (router1, router2): - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - l3_hosta['configurations']['router_id'] = router1['router']['id'] - self._register_one_agent_state(l3_hosta) - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - hosta_routers = self._list_routers_hosted_by_l3_agent(hosta_id) - num_hosta_routers = len(hosta_routers['routers']) - l3_agents_1 = self._list_l3_agents_hosting_router( - router1['router']['id']) - l3_agents_2 = self._list_l3_agents_hosting_router( - router2['router']['id']) - # L3 agent will host only the compatible router. - self.assertEqual(1, num_hosta_routers) - self.assertEqual(1, len(l3_agents_1['agents'])) - self.assertEqual(0, len(l3_agents_2['agents'])) - - def test_rpc_sync_routers(self): - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_agent_states() - - # No routers - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - self.assertEqual(0, len(ret_a)) - - with contextlib.nested(self.router(), - self.router(), - self.router()) as routers: - router_ids = [r['router']['id'] for r in routers] - - # Get all routers - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA) - self.assertEqual(3, len(ret_a)) - self.assertEqual(set(router_ids), set([r['id'] for r in ret_a])) - - # Get all routers (router_ids=None) - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA, - router_ids=None) - self.assertEqual(3, len(ret_a)) - self.assertEqual(set(router_ids), set([r['id'] for r in ret_a])) - - # Get router2 only - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA, - router_ids=[router_ids[1]]) - self.assertEqual(1, len(ret_a)) - self.assertIn(router_ids[1], [r['id'] for r in ret_a]) - - # Get router1 and router3 - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA, - router_ids=[router_ids[0], - router_ids[2]]) - self.assertEqual(2, len(ret_a)) - self.assertIn(router_ids[0], [r['id'] for r in ret_a]) - self.assertIn(router_ids[2], [r['id'] for r in ret_a]) - - def test_router_auto_schedule_for_specified_routers(self): - - def _sync_router_with_ids(router_ids, exp_synced, exp_hosted, host_id): - ret_a = l3_rpc.sync_routers(self.adminContext, host=L3_HOSTA, - router_ids=router_ids) - self.assertEqual(exp_synced, len(ret_a)) - for r in router_ids: - self.assertIn(r, [r['id'] for r in ret_a]) - host_routers = self._list_routers_hosted_by_l3_agent(host_id) - num_host_routers = len(host_routers['routers']) - self.assertEqual(exp_hosted, num_host_routers) - - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, L3_HOSTA) - - with contextlib.nested(self.router(), self.router(), - self.router(), self.router()) as routers: - router_ids = [r['router']['id'] for r in routers] - # Sync router1 (router1 is scheduled) - _sync_router_with_ids([router_ids[0]], 1, 1, hosta_id) - # Sync router1 only (no router is scheduled) - _sync_router_with_ids([router_ids[0]], 1, 1, hosta_id) - # Schedule router2 - _sync_router_with_ids([router_ids[1]], 1, 2, hosta_id) - # Sync router2 and router4 (router4 is scheduled) - _sync_router_with_ids([router_ids[1], router_ids[3]], - 2, 3, hosta_id) - # Sync all routers (router3 is scheduled) - _sync_router_with_ids(router_ids, 4, 4, hosta_id) - - def test_router_schedule_with_candidates(self): - l3_hosta = { - 'binary': 'neutron-l3-agent', - 'host': L3_HOSTA, - 'topic': 'L3_AGENT', - 'configurations': {'use_namespaces': False, - 'router_id': None, - 'handle_internal_only_routers': - True, - 'gateway_external_network_id': - None, - 'interface_driver': 'interface_driver', - }, - 'agent_type': constants.AGENT_TYPE_L3} - with contextlib.nested(self.router(), - self.router(), - self.subnet(), - self.subnet(cidr='10.0.3.0/24')) as (router1, - router2, - subnet1, - subnet2): - l3_hosta['configurations']['router_id'] = router1['router']['id'] - self._register_one_agent_state(l3_hosta) - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - self._router_interface_action('add', - router1['router']['id'], - subnet1['subnet']['id'], - None) - self._router_interface_action('add', - router2['router']['id'], - subnet2['subnet']['id'], - None) - hosta_routers = self._list_routers_hosted_by_l3_agent(hosta_id) - num_hosta_routers = len(hosta_routers['routers']) - l3_agents_1 = self._list_l3_agents_hosting_router( - router1['router']['id']) - l3_agents_2 = self._list_l3_agents_hosting_router( - router2['router']['id']) - # safe cleanup - self._router_interface_action('remove', - router1['router']['id'], - subnet1['subnet']['id'], - None) - self._router_interface_action('remove', - router2['router']['id'], - subnet2['subnet']['id'], - None) - - # L3 agent will host only the compatible router. - self.assertEqual(1, num_hosta_routers) - self.assertEqual(1, len(l3_agents_1['agents'])) - self.assertEqual(0, len(l3_agents_2['agents'])) - - def test_router_without_l3_agents(self): - with self.subnet() as s: - self._set_net_external(s['subnet']['network_id']) - data = {'router': {'tenant_id': uuidutils.generate_uuid()}} - data['router']['name'] = 'router1' - data['router']['external_gateway_info'] = { - 'network_id': s['subnet']['network_id']} - router_req = self.new_create_request('routers', data, self.fmt) - res = router_req.get_response(self.ext_api) - router = self.deserialize(self.fmt, res) - l3agents = ( - self.l3agentscheduler_dbMinxin.get_l3_agents_hosting_routers( - self.adminContext, [router['router']['id']])) - self._delete('routers', router['router']['id']) - self.assertEqual(0, len(l3agents)) - - def test_router_sync_data(self): - with contextlib.nested( - self.subnet(), - self.subnet(cidr='10.0.2.0/24'), - self.subnet(cidr='10.0.3.0/24') - ) as (s1, s2, s3): - self._register_agent_states() - self._set_net_external(s1['subnet']['network_id']) - data = {'router': {'tenant_id': uuidutils.generate_uuid()}} - data['router']['name'] = 'router1' - data['router']['external_gateway_info'] = { - 'network_id': s1['subnet']['network_id']} - router_req = self.new_create_request('routers', data, self.fmt) - res = router_req.get_response(self.ext_api) - router = self.deserialize(self.fmt, res) - self._router_interface_action('add', - router['router']['id'], - s2['subnet']['id'], - None) - self._router_interface_action('add', - router['router']['id'], - s3['subnet']['id'], - None) - l3agents = self._list_l3_agents_hosting_router( - router['router']['id']) - self.assertEqual(1, len(l3agents['agents'])) - agents = self._list_agents() - another_l3_agent_id = None - another_l3_agent_host = None - default = l3agents['agents'][0]['id'] - for com in agents['agents']: - if (com['id'] != default and - com['agent_type'] == constants.AGENT_TYPE_L3): - another_l3_agent_id = com['id'] - another_l3_agent_host = com['host'] - break - self.assertIsNotNone(another_l3_agent_id) - self._add_router_to_l3_agent(another_l3_agent_id, - router['router']['id'], - expected_code=exc.HTTPConflict.code) - self._remove_router_from_l3_agent(default, - router['router']['id']) - self._add_router_to_l3_agent(another_l3_agent_id, - router['router']['id']) - l3agents = self._list_l3_agents_hosting_router( - router['router']['id']) - self.assertEqual(another_l3_agent_host, - l3agents['agents'][0]['host']) - self._remove_router_from_l3_agent(another_l3_agent_id, - router['router']['id']) - self._router_interface_action('remove', - router['router']['id'], - s2['subnet']['id'], - None) - l3agents = self._list_l3_agents_hosting_router( - router['router']['id']) - self.assertEqual(1, - len(l3agents['agents'])) - self._router_interface_action('remove', - router['router']['id'], - s3['subnet']['id'], - None) - self._delete('routers', router['router']['id']) - - def test_router_add_to_l3_agent(self): - with self.router() as router1: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - num_before_add = len( - self._list_routers_hosted_by_l3_agent( - hosta_id)['routers']) - self._add_router_to_l3_agent(hosta_id, - router1['router']['id']) - hostb_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTB) - self._add_router_to_l3_agent(hostb_id, - router1['router']['id'], - expected_code=exc.HTTPConflict.code) - num_after_add = len( - self._list_routers_hosted_by_l3_agent( - hosta_id)['routers']) - self.assertEqual(0, num_before_add) - self.assertEqual(1, num_after_add) - - def test_router_add_to_l3_agent_two_times(self): - with self.router() as router1: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - self._add_router_to_l3_agent(hosta_id, - router1['router']['id']) - self._add_router_to_l3_agent(hosta_id, - router1['router']['id'], - expected_code=exc.HTTPConflict.code) - - def test_router_add_to_two_l3_agents(self): - with self.router() as router1: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - hostb_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTB) - self._add_router_to_l3_agent(hosta_id, - router1['router']['id']) - self._add_router_to_l3_agent(hostb_id, - router1['router']['id'], - expected_code=exc.HTTPConflict.code) - - def test_router_policy(self): - with self.router() as router1: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - self._list_routers_hosted_by_l3_agent( - hosta_id, expected_code=exc.HTTPForbidden.code, - admin_context=False) - self._add_router_to_l3_agent( - hosta_id, router1['router']['id'], - expected_code=exc.HTTPForbidden.code, - admin_context=False) - self._add_router_to_l3_agent( - hosta_id, router1['router']['id']) - self._remove_router_from_l3_agent( - hosta_id, router1['router']['id'], - expected_code=exc.HTTPForbidden.code, - admin_context=False) - self._list_l3_agents_hosting_router( - router1['router']['id'], - expected_code=exc.HTTPForbidden.code, - admin_context=False) - - -class OvsDhcpAgentNotifierTestCase(test_l3_plugin.L3NatTestCaseMixin, - test_agent_ext_plugin.AgentDBTestMixIn, - AgentSchedulerTestMixIn, - test_plugin.NeutronDbPluginV2TestCase): - plugin_str = ('neutron.plugins.openvswitch.' - 'ovs_neutron_plugin.OVSNeutronPluginV2') - - def setUp(self): - # Save the global RESOURCE_ATTRIBUTE_MAP before loading plugin - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - super(OvsDhcpAgentNotifierTestCase, self).setUp(self.plugin_str) - # the notifier is used to get access to make_msg() method only - self.dhcp_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI() - self.dhcp_notifier_cast = mock.patch( - 'neutron.api.rpc.agentnotifiers.dhcp_rpc_agent_api.' - 'DhcpAgentNotifyAPI.cast').start() - ext_mgr = extensions.PluginAwareExtensionManager.get_instance() - self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr) - self.adminContext = context.get_admin_context() - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - agent.RESOURCE_ATTRIBUTE_MAP) - self.addCleanup(self.restore_attribute_map) - - def restore_attribute_map(self): - # Restore the original RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - - def test_network_add_to_dhcp_agent_notification(self): - with self.network() as net1: - network_id = net1['network']['id'] - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - self._add_network_to_dhcp_agent(hosta_id, - network_id) - self.dhcp_notifier_cast.assert_called_with( - mock.ANY, - self.dhcp_notifier.make_msg( - 'network_create_end', - payload={'network': {'id': network_id}}), - topic='dhcp_agent.' + DHCP_HOSTA) - - def test_network_remove_from_dhcp_agent_notification(self): - with self.network(do_delete=False) as net1: - network_id = net1['network']['id'] - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - self._add_network_to_dhcp_agent(hosta_id, - network_id) - - self._remove_network_from_dhcp_agent(hosta_id, - network_id) - self.dhcp_notifier_cast.assert_called_with( - mock.ANY, - self.dhcp_notifier.make_msg( - 'network_delete_end', - payload={'network_id': network_id}), - topic='dhcp_agent.' + DHCP_HOSTA) - - def test_agent_updated_dhcp_agent_notification(self): - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_DHCP, - DHCP_HOSTA) - self._disable_agent(hosta_id, admin_state_up=False) - - self.dhcp_notifier_cast.assert_called_with( - mock.ANY, self.dhcp_notifier.make_msg( - 'agent_updated', - payload={'admin_state_up': False}), - topic='dhcp_agent.' + DHCP_HOSTA) - - def _network_port_create( - self, hosts, gateway=attributes.ATTR_NOT_SPECIFIED, owner=None): - for host in hosts: - self._register_one_agent_state( - {'binary': 'neutron-dhcp-agent', - 'host': host, - 'topic': 'dhcp_agent', - 'configurations': {'dhcp_driver': 'dhcp_driver', - 'use_namespaces': True, }, - 'agent_type': constants.AGENT_TYPE_DHCP}) - with self.network(do_delete=False) as net1: - with self.subnet(network=net1, - gateway_ip=gateway, - do_delete=False) as subnet1: - if owner: - with self.port(subnet=subnet1, - no_delete=True, - device_owner=owner) as port: - return [net1, subnet1, port] - else: - with self.port(subnet=subnet1, - no_delete=True) as port: - return [net1, subnet1, port] - - def _notification_mocks(self, hosts, net, subnet, port): - host_calls = {} - for host in hosts: - expected_calls = [ - mock.call( - mock.ANY, - self.dhcp_notifier.make_msg( - 'network_create_end', - payload={'network': {'id': net['network']['id']}}), - topic='dhcp_agent.' + host), - mock.call( - mock.ANY, - self.dhcp_notifier.make_msg( - 'port_create_end', - payload={'port': port['port']}), - topic='dhcp_agent.' + host)] - host_calls[host] = expected_calls - return host_calls - - def test_network_port_create_notification(self): - hosts = [DHCP_HOSTA] - net, subnet, port = self._network_port_create(hosts) - expected_calls = self._notification_mocks(hosts, net, subnet, port) - self.assertEqual( - expected_calls[DHCP_HOSTA], self.dhcp_notifier_cast.call_args_list) - - def test_network_ha_port_create_notification(self): - cfg.CONF.set_override('dhcp_agents_per_network', 2) - hosts = [DHCP_HOSTA, DHCP_HOSTC] - net, subnet, port = self._network_port_create(hosts) - expected_calls = self._notification_mocks(hosts, net, subnet, port) - for expected in expected_calls[DHCP_HOSTA]: - self.assertIn(expected, self.dhcp_notifier_cast.call_args_list) - for expected in expected_calls[DHCP_HOSTC]: - self.assertIn(expected, self.dhcp_notifier_cast.call_args_list) - - -class OvsL3AgentNotifierTestCase(test_l3_plugin.L3NatTestCaseMixin, - test_agent_ext_plugin.AgentDBTestMixIn, - AgentSchedulerTestMixIn, - test_plugin.NeutronDbPluginV2TestCase): - plugin_str = ('neutron.plugins.openvswitch.' - 'ovs_neutron_plugin.OVSNeutronPluginV2') - l3_plugin = None - - def setUp(self): - self.dhcp_notifier_cls_p = mock.patch( - 'neutron.api.rpc.agentnotifiers.dhcp_rpc_agent_api.' - 'DhcpAgentNotifyAPI') - self.dhcp_notifier = mock.Mock(name='dhcp_notifier') - self.dhcp_notifier_cls = self.dhcp_notifier_cls_p.start() - self.dhcp_notifier_cls.return_value = self.dhcp_notifier - # Save the global RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - if self.l3_plugin: - service_plugins = {'l3_plugin_name': self.l3_plugin} - else: - service_plugins = None - super(OvsL3AgentNotifierTestCase, self).setUp( - self.plugin_str, service_plugins=service_plugins) - ext_mgr = extensions.PluginAwareExtensionManager.get_instance() - self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr) - self.adminContext = context.get_admin_context() - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - agent.RESOURCE_ATTRIBUTE_MAP) - self.addCleanup(self.restore_attribute_map) - - def restore_attribute_map(self): - # Restore the original RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - - def test_router_add_to_l3_agent_notification(self): - plugin = manager.NeutronManager.get_plugin() - l3_notifier = plugin.agent_notifiers[constants.AGENT_TYPE_L3] - with mock.patch.object(l3_notifier, 'cast') as mock_l3: - with self.router() as router1: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - self._add_router_to_l3_agent(hosta_id, - router1['router']['id']) - routers = [router1['router']['id']] - mock_l3.assert_called_with( - mock.ANY, - l3_notifier.make_msg( - 'router_added_to_agent', - payload=routers), - topic='l3_agent.hosta') - - def test_router_remove_from_l3_agent_notification(self): - plugin = manager.NeutronManager.get_plugin() - l3_notifier = plugin.agent_notifiers[constants.AGENT_TYPE_L3] - with mock.patch.object(l3_notifier, 'cast') as mock_l3: - with self.router() as router1: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - self._add_router_to_l3_agent(hosta_id, - router1['router']['id']) - self._remove_router_from_l3_agent(hosta_id, - router1['router']['id']) - mock_l3.assert_called_with( - mock.ANY, l3_notifier.make_msg( - 'router_removed_from_agent', - payload={'router_id': router1['router']['id']}), - topic='l3_agent.hosta') - - def test_agent_updated_l3_agent_notification(self): - plugin = manager.NeutronManager.get_plugin() - l3_notifier = plugin.agent_notifiers[constants.AGENT_TYPE_L3] - with mock.patch.object(l3_notifier, 'cast') as mock_l3: - self._register_agent_states() - hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, - L3_HOSTA) - self._disable_agent(hosta_id, admin_state_up=False) - mock_l3.assert_called_with( - mock.ANY, l3_notifier.make_msg( - 'agent_updated', payload={'admin_state_up': False}), - topic='l3_agent.hosta') - - -class OvsAgentSchedulerTestCaseXML(OvsAgentSchedulerTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/openvswitch/test_openvswitch_plugin.py b/neutron/tests/unit/openvswitch/test_openvswitch_plugin.py deleted file mode 100644 index 234a8feb8..000000000 --- a/neutron/tests/unit/openvswitch/test_openvswitch_plugin.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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. - -from oslo.config import cfg - -from neutron.extensions import portbindings -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_extension_allowedaddresspairs as test_pair -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - - -class OpenvswitchPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - - _plugin_name = ('neutron.plugins.openvswitch.' - 'ovs_neutron_plugin.OVSNeutronPluginV2') - - def setUp(self): - super(OpenvswitchPluginV2TestCase, self).setUp(self._plugin_name) - self.port_create_status = 'DOWN' - - -class TestOpenvswitchBasicGet(test_plugin.TestBasicGet, - OpenvswitchPluginV2TestCase): - pass - - -class TestOpenvswitchV2HTTPResponse(test_plugin.TestV2HTTPResponse, - OpenvswitchPluginV2TestCase): - pass - - -class TestOpenvswitchPortsV2(test_plugin.TestPortsV2, - OpenvswitchPluginV2TestCase): - - def test_update_port_status_build(self): - with self.port() as port: - self.assertEqual(port['port']['status'], 'DOWN') - self.assertEqual(self.port_create_status, 'DOWN') - - -class TestOpenvswitchNetworksV2(test_plugin.TestNetworksV2, - OpenvswitchPluginV2TestCase): - pass - - -class TestOpenvswitchPortBinding(OpenvswitchPluginV2TestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - HAS_PORT_FILTER = True - ENABLE_SG = True - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_HYBRID_DRIVER - - def setUp(self, firewall_driver=None): - test_sg_rpc.set_firewall_driver(self.FIREWALL_DRIVER) - cfg.CONF.set_override( - 'enable_security_group', self.ENABLE_SG, - group='SECURITYGROUP') - super(TestOpenvswitchPortBinding, self).setUp() - - -class TestOpenvswitchPortBindingNoSG(TestOpenvswitchPortBinding): - HAS_PORT_FILTER = False - ENABLE_SG = False - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER - - -class TestOpenvswitchPortBindingHost( - OpenvswitchPluginV2TestCase, - test_bindings.PortBindingsHostTestCaseMixin): - pass - - -class TestOpenvswitchAllowedAddressPairs(OpenvswitchPluginV2TestCase, - test_pair.TestAllowedAddressPairs): - pass diff --git a/neutron/tests/unit/openvswitch/test_ovs_db.py b/neutron/tests/unit/openvswitch/test_ovs_db.py deleted file mode 100644 index 528f894a6..000000000 --- a/neutron/tests/unit/openvswitch/test_ovs_db.py +++ /dev/null @@ -1,322 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 oslo.config import cfg -from six import moves -import testtools -from testtools import matchers - -from neutron.common import exceptions as n_exc -from neutron.db import api as db -from neutron.openstack.common.db import exception as db_exc -from neutron.openstack.common.db.sqlalchemy import session -from neutron.plugins.openvswitch import ovs_db_v2 -from neutron.plugins.openvswitch import ovs_models_v2 as ovs_models -from neutron.tests import base -from neutron.tests.unit import test_db_plugin as test_plugin - -PHYS_NET = 'physnet1' -PHYS_NET_2 = 'physnet2' -VLAN_MIN = 10 -VLAN_MAX = 19 -VLAN_RANGES = {PHYS_NET: [(VLAN_MIN, VLAN_MAX)]} -UPDATED_VLAN_RANGES = {PHYS_NET: [(VLAN_MIN + 5, VLAN_MAX + 5)], - PHYS_NET_2: [(VLAN_MIN + 20, VLAN_MAX + 20)]} -TUN_MIN = 100 -TUN_MAX = 109 -TUNNEL_RANGES = [(TUN_MIN, TUN_MAX)] -UPDATED_TUNNEL_RANGES = [(TUN_MIN + 5, TUN_MAX + 5)] - -PLUGIN_NAME = ('neutron.plugins.openvswitch.' - 'ovs_neutron_plugin.OVSNeutronPluginV2') - - -class VlanAllocationsTest(base.BaseTestCase): - def setUp(self): - super(VlanAllocationsTest, self).setUp() - db.configure_db() - ovs_db_v2.sync_vlan_allocations(VLAN_RANGES) - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_sync_vlan_allocations(self): - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MIN - 1)) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MIN + 1).allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MAX - 1).allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MAX).allocated) - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MAX + 1)) - - ovs_db_v2.sync_vlan_allocations(UPDATED_VLAN_RANGES) - - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MIN + 5 - 1)) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MIN + 5). - allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MIN + 5 + 1). - allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MAX + 5 - 1). - allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MAX + 5). - allocated) - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MAX + 5 + 1)) - - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET_2, - VLAN_MIN + 20 - 1)) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET_2, - VLAN_MIN + 20). - allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET_2, - VLAN_MIN + 20 + 1). - allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET_2, - VLAN_MAX + 20 - 1). - allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET_2, - VLAN_MAX + 20). - allocated) - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET_2, - VLAN_MAX + 20 + 1)) - - ovs_db_v2.sync_vlan_allocations(VLAN_RANGES) - - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MIN - 1)) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MIN + 1).allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MAX - 1).allocated) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MAX).allocated) - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET, - VLAN_MAX + 1)) - - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET_2, - VLAN_MIN + 20)) - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET_2, - VLAN_MAX + 20)) - - def test_vlan_pool(self): - vlan_ids = set() - for x in moves.xrange(VLAN_MIN, VLAN_MAX + 1): - physical_network, vlan_id = ovs_db_v2.reserve_vlan(self.session) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - with testtools.ExpectedException(n_exc.NoNetworkAvailable): - physical_network, vlan_id = ovs_db_v2.reserve_vlan(self.session) - - ovs_db_v2.release_vlan(self.session, PHYS_NET, vlan_ids.pop(), - VLAN_RANGES) - physical_network, vlan_id = ovs_db_v2.reserve_vlan(self.session) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - for vlan_id in vlan_ids: - ovs_db_v2.release_vlan(self.session, PHYS_NET, vlan_id, - VLAN_RANGES) - - def test_specific_vlan_inside_pool(self): - vlan_id = VLAN_MIN + 5 - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - vlan_id).allocated) - ovs_db_v2.reserve_specific_vlan(self.session, PHYS_NET, vlan_id) - self.assertTrue(ovs_db_v2.get_vlan_allocation(PHYS_NET, - vlan_id).allocated) - - with testtools.ExpectedException(n_exc.VlanIdInUse): - ovs_db_v2.reserve_specific_vlan(self.session, PHYS_NET, vlan_id) - - ovs_db_v2.release_vlan(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - self.assertFalse(ovs_db_v2.get_vlan_allocation(PHYS_NET, - vlan_id).allocated) - - def test_specific_vlan_outside_pool(self): - vlan_id = VLAN_MAX + 5 - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET, vlan_id)) - ovs_db_v2.reserve_specific_vlan(self.session, PHYS_NET, vlan_id) - self.assertTrue(ovs_db_v2.get_vlan_allocation(PHYS_NET, - vlan_id).allocated) - - with testtools.ExpectedException(n_exc.VlanIdInUse): - ovs_db_v2.reserve_specific_vlan(self.session, PHYS_NET, vlan_id) - - ovs_db_v2.release_vlan(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - self.assertIsNone(ovs_db_v2.get_vlan_allocation(PHYS_NET, vlan_id)) - - def test_sync_with_allocated_false(self): - vlan_ids = set() - for x in moves.xrange(VLAN_MIN, VLAN_MAX + 1): - physical_network, vlan_id = ovs_db_v2.reserve_vlan(self.session) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - ovs_db_v2.release_vlan(self.session, PHYS_NET, vlan_ids.pop(), - VLAN_RANGES) - ovs_db_v2.sync_vlan_allocations({}) - - -class TunnelAllocationsTest(base.BaseTestCase): - def setUp(self): - super(TunnelAllocationsTest, self).setUp() - db.configure_db() - ovs_db_v2.sync_tunnel_allocations(TUNNEL_RANGES) - self.session = db.get_session() - self.addCleanup(db.clear_db) - - def test_sync_tunnel_allocations(self): - self.assertIsNone(ovs_db_v2.get_tunnel_allocation(TUN_MIN - 1)) - self.assertFalse(ovs_db_v2.get_tunnel_allocation(TUN_MIN).allocated) - self.assertFalse(ovs_db_v2.get_tunnel_allocation(TUN_MIN + 1). - allocated) - self.assertFalse(ovs_db_v2.get_tunnel_allocation(TUN_MAX - 1). - allocated) - self.assertFalse(ovs_db_v2.get_tunnel_allocation(TUN_MAX).allocated) - self.assertIsNone(ovs_db_v2.get_tunnel_allocation(TUN_MAX + 1)) - - ovs_db_v2.sync_tunnel_allocations(UPDATED_TUNNEL_RANGES) - - self.assertIsNone(ovs_db_v2.get_tunnel_allocation(TUN_MIN + 5 - 1)) - self.assertFalse(ovs_db_v2.get_tunnel_allocation(TUN_MIN + 5). - allocated) - self.assertFalse(ovs_db_v2.get_tunnel_allocation(TUN_MIN + 5 + 1). - allocated) - self.assertFalse(ovs_db_v2.get_tunnel_allocation(TUN_MAX + 5 - 1). - allocated) - self.assertFalse(ovs_db_v2.get_tunnel_allocation(TUN_MAX + 5). - allocated) - self.assertIsNone(ovs_db_v2.get_tunnel_allocation(TUN_MAX + 5 + 1)) - - def test_tunnel_pool(self): - tunnel_ids = set() - for x in moves.xrange(TUN_MIN, TUN_MAX + 1): - tunnel_id = ovs_db_v2.reserve_tunnel(self.session) - self.assertThat(tunnel_id, matchers.GreaterThan(TUN_MIN - 1)) - self.assertThat(tunnel_id, matchers.LessThan(TUN_MAX + 1)) - tunnel_ids.add(tunnel_id) - - with testtools.ExpectedException(n_exc.NoNetworkAvailable): - tunnel_id = ovs_db_v2.reserve_tunnel(self.session) - - ovs_db_v2.release_tunnel(self.session, tunnel_ids.pop(), TUNNEL_RANGES) - tunnel_id = ovs_db_v2.reserve_tunnel(self.session) - self.assertThat(tunnel_id, matchers.GreaterThan(TUN_MIN - 1)) - self.assertThat(tunnel_id, matchers.LessThan(TUN_MAX + 1)) - tunnel_ids.add(tunnel_id) - - for tunnel_id in tunnel_ids: - ovs_db_v2.release_tunnel(self.session, tunnel_id, TUNNEL_RANGES) - - def test_add_tunnel_endpoints(self): - tun_1 = ovs_db_v2.add_tunnel_endpoint('192.168.0.1') - tun_2 = ovs_db_v2.add_tunnel_endpoint('192.168.0.2') - self.assertEqual(1, tun_1.id) - self.assertEqual('192.168.0.1', tun_1.ip_address) - self.assertEqual(2, tun_2.id) - self.assertEqual('192.168.0.2', tun_2.ip_address) - - def test_specific_tunnel_inside_pool(self): - tunnel_id = TUN_MIN + 5 - self.assertFalse(ovs_db_v2.get_tunnel_allocation(tunnel_id).allocated) - ovs_db_v2.reserve_specific_tunnel(self.session, tunnel_id) - self.assertTrue(ovs_db_v2.get_tunnel_allocation(tunnel_id).allocated) - - with testtools.ExpectedException(n_exc.TunnelIdInUse): - ovs_db_v2.reserve_specific_tunnel(self.session, tunnel_id) - - ovs_db_v2.release_tunnel(self.session, tunnel_id, TUNNEL_RANGES) - self.assertFalse(ovs_db_v2.get_tunnel_allocation(tunnel_id).allocated) - - def test_specific_tunnel_outside_pool(self): - tunnel_id = TUN_MAX + 5 - self.assertIsNone(ovs_db_v2.get_tunnel_allocation(tunnel_id)) - ovs_db_v2.reserve_specific_tunnel(self.session, tunnel_id) - self.assertTrue(ovs_db_v2.get_tunnel_allocation(tunnel_id).allocated) - - with testtools.ExpectedException(n_exc.TunnelIdInUse): - ovs_db_v2.reserve_specific_tunnel(self.session, tunnel_id) - - ovs_db_v2.release_tunnel(self.session, tunnel_id, TUNNEL_RANGES) - self.assertIsNone(ovs_db_v2.get_tunnel_allocation(tunnel_id)) - - def test_add_tunnel_endpoint_create_new_endpoint(self): - addr = '10.0.0.1' - ovs_db_v2.add_tunnel_endpoint(addr) - self.assertIsNotNone(self.session.query(ovs_models.TunnelEndpoint). - filter_by(ip_address=addr).first()) - - def test_add_tunnel_endpoint_retrieve_an_existing_endpoint(self): - addr = '10.0.0.1' - self.session.add(ovs_models.TunnelEndpoint(ip_address=addr, id=1)) - self.session.flush() - - tunnel = ovs_db_v2.add_tunnel_endpoint(addr) - self.assertEqual(tunnel.id, 1) - self.assertEqual(tunnel.ip_address, addr) - - def test_add_tunnel_endpoint_handle_duplicate_error(self): - with mock.patch.object(session.Session, 'query') as query_mock: - error = db_exc.DBDuplicateEntry(['id']) - query_mock.side_effect = error - - with testtools.ExpectedException(n_exc.NeutronException): - ovs_db_v2.add_tunnel_endpoint('10.0.0.1', 5) - self.assertEqual(query_mock.call_count, 5) - - -class NetworkBindingsTest(test_plugin.NeutronDbPluginV2TestCase): - def setUp(self): - cfg.CONF.set_override('network_vlan_ranges', ['physnet1:1000:2999'], - group='OVS') - super(NetworkBindingsTest, self).setUp(plugin=PLUGIN_NAME) - db.configure_db() - self.session = db.get_session() - - def test_add_network_binding(self): - params = {'provider:network_type': 'vlan', - 'provider:physical_network': PHYS_NET, - 'provider:segmentation_id': 1234} - params['arg_list'] = tuple(params.keys()) - with self.network(**params) as network: - TEST_NETWORK_ID = network['network']['id'] - binding = ovs_db_v2.get_network_binding(self.session, - TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, 'vlan') - self.assertEqual(binding.physical_network, PHYS_NET) - self.assertEqual(binding.segmentation_id, 1234) diff --git a/neutron/tests/unit/openvswitch/test_ovs_defaults.py b/neutron/tests/unit/openvswitch/test_ovs_defaults.py deleted file mode 100644 index 0d5c00f73..000000000 --- a/neutron/tests/unit/openvswitch/test_ovs_defaults.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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. - -from oslo.config import cfg - -from neutron.plugins.openvswitch.common import config # noqa -from neutron.tests import base - - -class ConfigurationTest(base.BaseTestCase): - - def test_defaults(self): - self.assertEqual('br-int', cfg.CONF.OVS.integration_bridge) - self.assertFalse(cfg.CONF.OVS.enable_tunneling) - self.assertEqual('br-tun', cfg.CONF.OVS.tunnel_bridge) - self.assertEqual(2, cfg.CONF.AGENT.polling_interval) - self.assertEqual('sudo', cfg.CONF.AGENT.root_helper) - self.assertEqual('local', cfg.CONF.OVS.tenant_network_type) - self.assertEqual(0, len(cfg.CONF.OVS.bridge_mappings)) - self.assertEqual(0, len(cfg.CONF.OVS.network_vlan_ranges)) - self.assertEqual(0, len(cfg.CONF.OVS.tunnel_id_ranges)) - self.assertFalse(cfg.CONF.AGENT.l2_population) - self.assertFalse(cfg.CONF.AGENT.arp_responder) diff --git a/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py b/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py deleted file mode 100644 index b1d2371b3..000000000 --- a/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py +++ /dev/null @@ -1,954 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 contextlib -import sys - -import mock -import netaddr -from oslo.config import cfg -import testtools - -from neutron.agent.linux import async_process -from neutron.agent.linux import ip_lib -from neutron.agent.linux import ovs_lib -from neutron.agent.linux import utils -from neutron.common import constants as n_const -from neutron.openstack.common import log -from neutron.plugins.common import constants as p_const -from neutron.plugins.openvswitch.agent import ovs_neutron_agent -from neutron.plugins.openvswitch.common import constants -from neutron.tests import base - - -NOTIFIER = ('neutron.plugins.openvswitch.' - 'ovs_neutron_plugin.AgentNotifierApi') -OVS_LINUX_KERN_VERS_WITHOUT_VXLAN = "3.12.0" - -FAKE_MAC = '00:11:22:33:44:55' -FAKE_IP1 = '10.0.0.1' -FAKE_IP2 = '10.0.0.2' - - -class CreateAgentConfigMap(base.BaseTestCase): - - def test_create_agent_config_map_succeeds(self): - self.assertTrue(ovs_neutron_agent.create_agent_config_map(cfg.CONF)) - - def test_create_agent_config_map_fails_for_invalid_tunnel_config(self): - # An ip address is required for tunneling but there is no default, - # verify this for both gre and vxlan tunnels. - cfg.CONF.set_override('tunnel_types', [p_const.TYPE_GRE], - group='AGENT') - with testtools.ExpectedException(ValueError): - ovs_neutron_agent.create_agent_config_map(cfg.CONF) - cfg.CONF.set_override('tunnel_types', [p_const.TYPE_VXLAN], - group='AGENT') - with testtools.ExpectedException(ValueError): - ovs_neutron_agent.create_agent_config_map(cfg.CONF) - - def test_create_agent_config_map_enable_tunneling(self): - # Verify setting only enable_tunneling will default tunnel_type to GRE - cfg.CONF.set_override('tunnel_types', None, group='AGENT') - cfg.CONF.set_override('enable_tunneling', True, group='OVS') - cfg.CONF.set_override('local_ip', '10.10.10.10', group='OVS') - cfgmap = ovs_neutron_agent.create_agent_config_map(cfg.CONF) - self.assertEqual(cfgmap['tunnel_types'], [p_const.TYPE_GRE]) - - def test_create_agent_config_map_fails_no_local_ip(self): - # An ip address is required for tunneling but there is no default - cfg.CONF.set_override('enable_tunneling', True, group='OVS') - with testtools.ExpectedException(ValueError): - ovs_neutron_agent.create_agent_config_map(cfg.CONF) - - def test_create_agent_config_map_fails_for_invalid_tunnel_type(self): - cfg.CONF.set_override('tunnel_types', ['foobar'], group='AGENT') - with testtools.ExpectedException(ValueError): - ovs_neutron_agent.create_agent_config_map(cfg.CONF) - - def test_create_agent_config_map_multiple_tunnel_types(self): - cfg.CONF.set_override('local_ip', '10.10.10.10', group='OVS') - cfg.CONF.set_override('tunnel_types', [p_const.TYPE_GRE, - p_const.TYPE_VXLAN], group='AGENT') - cfgmap = ovs_neutron_agent.create_agent_config_map(cfg.CONF) - self.assertEqual(cfgmap['tunnel_types'], - [p_const.TYPE_GRE, p_const.TYPE_VXLAN]) - - -class TestOvsNeutronAgent(base.BaseTestCase): - - def setUp(self): - super(TestOvsNeutronAgent, self).setUp() - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - # Avoid rpc initialization for unit tests - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - kwargs = ovs_neutron_agent.create_agent_config_map(cfg.CONF) - - class MockFixedIntervalLoopingCall(object): - def __init__(self, f): - self.f = f - - def start(self, interval=0): - self.f() - - with contextlib.nested( - mock.patch('neutron.plugins.openvswitch.agent.ovs_neutron_agent.' - 'OVSNeutronAgent.setup_integration_br', - return_value=mock.Mock()), - mock.patch('neutron.plugins.openvswitch.agent.ovs_neutron_agent.' - 'OVSNeutronAgent.setup_ancillary_bridges', - return_value=[]), - mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.' - 'set_secure_mode'), - mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.' - 'get_local_port_mac', - return_value='00:00:00:00:00:01'), - mock.patch('neutron.agent.linux.utils.get_interface_mac', - return_value='00:00:00:00:00:01'), - mock.patch('neutron.openstack.common.loopingcall.' - 'FixedIntervalLoopingCall', - new=MockFixedIntervalLoopingCall), - mock.patch('neutron.plugins.openvswitch.agent.ovs_neutron_agent.' - 'OVSNeutronAgent._check_arp_responder_support', - return_value=True)): - self.agent = ovs_neutron_agent.OVSNeutronAgent(**kwargs) - self.agent.tun_br = mock.Mock() - self.agent.sg_agent = mock.Mock() - - def _mock_port_bound(self, ofport=None, new_local_vlan=None, - old_local_vlan=None): - port = mock.Mock() - port.ofport = ofport - net_uuid = 'my-net-uuid' - if old_local_vlan is not None: - self.agent.local_vlan_map[net_uuid] = ( - ovs_neutron_agent.LocalVLANMapping( - old_local_vlan, None, None, None)) - with contextlib.nested( - mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.' - 'set_db_attribute', return_value=True), - mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.' - 'db_get_val', return_value=str(old_local_vlan)), - mock.patch.object(self.agent.int_br, 'delete_flows') - ) as (set_ovs_db_func, get_ovs_db_func, delete_flows_func): - self.agent.port_bound(port, net_uuid, 'local', None, None, False) - get_ovs_db_func.assert_called_once_with("Port", mock.ANY, "tag") - if new_local_vlan != old_local_vlan: - set_ovs_db_func.assert_called_once_with( - "Port", mock.ANY, "tag", str(new_local_vlan)) - if ofport != -1: - delete_flows_func.assert_called_once_with(in_port=port.ofport) - else: - self.assertFalse(delete_flows_func.called) - else: - self.assertFalse(set_ovs_db_func.called) - self.assertFalse(delete_flows_func.called) - - def test_port_bound_deletes_flows_for_valid_ofport(self): - self._mock_port_bound(ofport=1, new_local_vlan=1) - - def test_port_bound_ignores_flows_for_invalid_ofport(self): - self._mock_port_bound(ofport=-1, new_local_vlan=1) - - def test_port_bound_does_not_rewire_if_already_bound(self): - self._mock_port_bound(ofport=-1, new_local_vlan=1, old_local_vlan=1) - - def _test_port_dead(self, cur_tag=None): - port = mock.Mock() - port.ofport = 1 - with contextlib.nested( - mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.' - 'set_db_attribute', return_value=True), - mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.' - 'db_get_val', return_value=cur_tag), - mock.patch.object(self.agent.int_br, 'add_flow') - ) as (set_ovs_db_func, get_ovs_db_func, add_flow_func): - self.agent.port_dead(port) - get_ovs_db_func.assert_called_once_with("Port", mock.ANY, "tag") - if cur_tag == ovs_neutron_agent.DEAD_VLAN_TAG: - self.assertFalse(set_ovs_db_func.called) - self.assertFalse(add_flow_func.called) - else: - set_ovs_db_func.assert_called_once_with( - "Port", mock.ANY, "tag", str(ovs_neutron_agent.DEAD_VLAN_TAG)) - add_flow_func.assert_called_once_with( - priority=2, in_port=port.ofport, actions="drop") - - def test_port_dead(self): - self._test_port_dead() - - def test_port_dead_with_port_already_dead(self): - self._test_port_dead(ovs_neutron_agent.DEAD_VLAN_TAG) - - def mock_scan_ports(self, vif_port_set=None, registered_ports=None, - updated_ports=None, port_tags_dict=None): - if port_tags_dict is None: # Because empty dicts evaluate as False. - port_tags_dict = {} - with contextlib.nested( - mock.patch.object(self.agent.int_br, 'get_vif_port_set', - return_value=vif_port_set), - mock.patch.object(self.agent.int_br, 'get_port_tag_dict', - return_value=port_tags_dict) - ): - return self.agent.scan_ports(registered_ports, updated_ports) - - def test_scan_ports_returns_current_only_for_unchanged_ports(self): - vif_port_set = set([1, 3]) - registered_ports = set([1, 3]) - expected = {'current': vif_port_set} - actual = self.mock_scan_ports(vif_port_set, registered_ports) - self.assertEqual(expected, actual) - - def test_scan_ports_returns_port_changes(self): - vif_port_set = set([1, 3]) - registered_ports = set([1, 2]) - expected = dict(current=vif_port_set, added=set([3]), removed=set([2])) - actual = self.mock_scan_ports(vif_port_set, registered_ports) - self.assertEqual(expected, actual) - - def _test_scan_ports_with_updated_ports(self, updated_ports): - vif_port_set = set([1, 3, 4]) - registered_ports = set([1, 2, 4]) - expected = dict(current=vif_port_set, added=set([3]), - removed=set([2]), updated=set([4])) - actual = self.mock_scan_ports(vif_port_set, registered_ports, - updated_ports) - self.assertEqual(expected, actual) - - def test_scan_ports_finds_known_updated_ports(self): - self._test_scan_ports_with_updated_ports(set([4])) - - def test_scan_ports_ignores_unknown_updated_ports(self): - # the port '5' was not seen on current ports. Hence it has either - # never been wired or already removed and should be ignored - self._test_scan_ports_with_updated_ports(set([4, 5])) - - def test_scan_ports_ignores_updated_port_if_removed(self): - vif_port_set = set([1, 3]) - registered_ports = set([1, 2]) - updated_ports = set([1, 2]) - expected = dict(current=vif_port_set, added=set([3]), - removed=set([2]), updated=set([1])) - actual = self.mock_scan_ports(vif_port_set, registered_ports, - updated_ports) - self.assertEqual(expected, actual) - - def test_scan_ports_no_vif_changes_returns_updated_port_only(self): - vif_port_set = set([1, 2, 3]) - registered_ports = set([1, 2, 3]) - updated_ports = set([2]) - expected = dict(current=vif_port_set, updated=set([2])) - actual = self.mock_scan_ports(vif_port_set, registered_ports, - updated_ports) - self.assertEqual(expected, actual) - - def test_update_ports_returns_changed_vlan(self): - br = ovs_lib.OVSBridge('br-int', 'sudo') - mac = "ca:fe:de:ad:be:ef" - port = ovs_lib.VifPort(1, 1, 1, mac, br) - lvm = ovs_neutron_agent.LocalVLANMapping( - 1, '1', None, 1, {port.vif_id: port}) - local_vlan_map = {'1': lvm} - vif_port_set = set([1, 3]) - registered_ports = set([1, 2]) - port_tags_dict = {1: []} - expected = dict( - added=set([3]), current=vif_port_set, - removed=set([2]), updated=set([1]) - ) - with mock.patch.dict(self.agent.local_vlan_map, local_vlan_map): - actual = self.mock_scan_ports( - vif_port_set, registered_ports, port_tags_dict=port_tags_dict) - self.assertEqual(expected, actual) - - def test_treat_devices_added_returns_true_for_missing_device(self): - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'get_device_details', - side_effect=Exception()), - mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', - return_value=mock.Mock())): - self.assertTrue(self.agent.treat_devices_added_or_updated([{}], - False)) - - def _mock_treat_devices_added_updated(self, details, port, func_name): - """Mock treat devices added or updated. - - :param details: the details to return for the device - :param port: the port that get_vif_port_by_id should return - :param func_name: the function that should be called - :returns: whether the named function was called - """ - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'get_device_details', - return_value=details), - mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', - return_value=port), - mock.patch.object(self.agent.plugin_rpc, 'update_device_up'), - mock.patch.object(self.agent.plugin_rpc, 'update_device_down'), - mock.patch.object(self.agent, func_name) - ) as (get_dev_fn, get_vif_func, upd_dev_up, upd_dev_down, func): - self.assertFalse(self.agent.treat_devices_added_or_updated([{}], - False)) - return func.called - - def test_treat_devices_added_updated_ignores_invalid_ofport(self): - port = mock.Mock() - port.ofport = -1 - self.assertFalse(self._mock_treat_devices_added_updated( - mock.MagicMock(), port, 'port_dead')) - - def test_treat_devices_added_updated_marks_unknown_port_as_dead(self): - port = mock.Mock() - port.ofport = 1 - self.assertTrue(self._mock_treat_devices_added_updated( - mock.MagicMock(), port, 'port_dead')) - - def test_treat_devices_added_does_not_process_missing_port(self): - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'get_device_details'), - mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', - return_value=None) - ) as (get_dev_fn, get_vif_func): - self.assertFalse(get_dev_fn.called) - - def test_treat_devices_added__updated_updates_known_port(self): - details = mock.MagicMock() - details.__contains__.side_effect = lambda x: True - self.assertTrue(self._mock_treat_devices_added_updated( - details, mock.Mock(), 'treat_vif_port')) - - def test_treat_devices_added_updated_put_port_down(self): - fake_details_dict = {'admin_state_up': False, - 'port_id': 'xxx', - 'device': 'xxx', - 'network_id': 'yyy', - 'physical_network': 'foo', - 'segmentation_id': 'bar', - 'network_type': 'baz'} - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'get_device_details', - return_value=fake_details_dict), - mock.patch.object(self.agent.int_br, 'get_vif_port_by_id', - return_value=mock.MagicMock()), - mock.patch.object(self.agent.plugin_rpc, 'update_device_up'), - mock.patch.object(self.agent.plugin_rpc, 'update_device_down'), - mock.patch.object(self.agent, 'treat_vif_port') - ) as (get_dev_fn, get_vif_func, upd_dev_up, - upd_dev_down, treat_vif_port): - self.assertFalse(self.agent.treat_devices_added_or_updated([{}], - False)) - self.assertTrue(treat_vif_port.called) - self.assertTrue(upd_dev_down.called) - - def test_treat_devices_removed_returns_true_for_missing_device(self): - with mock.patch.object(self.agent.plugin_rpc, 'update_device_down', - side_effect=Exception()): - self.assertTrue(self.agent.treat_devices_removed([{}])) - - def _mock_treat_devices_removed(self, port_exists): - details = dict(exists=port_exists) - with mock.patch.object(self.agent.plugin_rpc, 'update_device_down', - return_value=details): - with mock.patch.object(self.agent, 'port_unbound') as port_unbound: - self.assertFalse(self.agent.treat_devices_removed([{}])) - self.assertTrue(port_unbound.called) - - def test_treat_devices_removed_unbinds_port(self): - self._mock_treat_devices_removed(True) - - def test_treat_devices_removed_ignores_missing_port(self): - self._mock_treat_devices_removed(False) - - def _test_process_network_ports(self, port_info): - with contextlib.nested( - mock.patch.object(self.agent.sg_agent, "setup_port_filters"), - mock.patch.object(self.agent, "treat_devices_added_or_updated", - return_value=False), - mock.patch.object(self.agent, "treat_devices_removed", - return_value=False) - ) as (setup_port_filters, device_added_updated, device_removed): - self.assertFalse(self.agent.process_network_ports(port_info, - False)) - setup_port_filters.assert_called_once_with( - port_info['added'], port_info.get('updated', set())) - device_added_updated.assert_called_once_with( - port_info['added'] | port_info.get('updated', set()), False) - device_removed.assert_called_once_with(port_info['removed']) - - def test_process_network_ports(self): - self._test_process_network_ports( - {'current': set(['tap0']), - 'removed': set(['eth0']), - 'added': set(['eth1'])}) - - def test_process_network_port_with_updated_ports(self): - self._test_process_network_ports( - {'current': set(['tap0', 'tap1']), - 'updated': set(['tap1', 'eth1']), - 'removed': set(['eth0']), - 'added': set(['eth1'])}) - - def test_report_state(self): - with mock.patch.object(self.agent.state_rpc, - "report_state") as report_st: - self.agent.int_br_device_count = 5 - self.agent._report_state() - report_st.assert_called_with(self.agent.context, - self.agent.agent_state) - self.assertNotIn("start_flag", self.agent.agent_state) - self.assertEqual( - self.agent.agent_state["configurations"]["devices"], - self.agent.int_br_device_count - ) - - def test_network_delete(self): - with contextlib.nested( - mock.patch.object(self.agent, "reclaim_local_vlan"), - mock.patch.object(self.agent.tun_br, "cleanup_tunnel_port") - ) as (recl_fn, clean_tun_fn): - self.agent.network_delete("unused_context", - network_id="123") - self.assertFalse(recl_fn.called) - self.agent.local_vlan_map["123"] = "LVM object" - self.agent.network_delete("unused_context", - network_id="123") - self.assertFalse(clean_tun_fn.called) - recl_fn.assert_called_with("123") - - def test_port_update(self): - port = {"id": "123", - "network_id": "124", - "admin_state_up": False} - self.agent.port_update("unused_context", - port=port, - network_type="vlan", - segmentation_id="1", - physical_network="physnet") - self.assertEqual(set(['123']), self.agent.updated_ports) - - def test_setup_physical_bridges(self): - with contextlib.nested( - mock.patch.object(ip_lib, "device_exists"), - mock.patch.object(sys, "exit"), - mock.patch.object(utils, "execute"), - mock.patch.object(ovs_lib.OVSBridge, "remove_all_flows"), - mock.patch.object(ovs_lib.OVSBridge, "add_flow"), - mock.patch.object(ovs_lib.OVSBridge, "add_port"), - mock.patch.object(ovs_lib.OVSBridge, "delete_port"), - mock.patch.object(self.agent.int_br, "add_port"), - mock.patch.object(self.agent.int_br, "delete_port"), - mock.patch.object(ip_lib.IPWrapper, "add_veth"), - mock.patch.object(ip_lib.IpLinkCommand, "delete"), - mock.patch.object(ip_lib.IpLinkCommand, "set_up"), - mock.patch.object(ip_lib.IpLinkCommand, "set_mtu") - ) as (devex_fn, sysexit_fn, utilsexec_fn, remflows_fn, ovs_addfl_fn, - ovs_addport_fn, ovs_delport_fn, br_addport_fn, - br_delport_fn, addveth_fn, linkdel_fn, linkset_fn, linkmtu_fn): - devex_fn.return_value = True - parent = mock.MagicMock() - parent.attach_mock(utilsexec_fn, 'utils_execute') - parent.attach_mock(linkdel_fn, 'link_delete') - parent.attach_mock(addveth_fn, 'add_veth') - addveth_fn.return_value = (ip_lib.IPDevice("int-br-eth1"), - ip_lib.IPDevice("phy-br-eth1")) - ovs_addport_fn.return_value = "int_ofport" - br_addport_fn.return_value = "phys_veth" - self.agent.setup_physical_bridges({"physnet1": "br-eth"}) - expected_calls = [mock.call.link_delete(), - mock.call.utils_execute(['/sbin/udevadm', - 'settle', - '--timeout=10']), - mock.call.add_veth('int-br-eth', - 'phy-br-eth')] - parent.assert_has_calls(expected_calls, any_order=False) - self.assertEqual(self.agent.int_ofports["physnet1"], - "phys_veth") - self.assertEqual(self.agent.phys_ofports["physnet1"], - "int_ofport") - - def test_get_veth_name(self): - bridge1 = "A_REALLY_LONG_BRIDGE_NAME1" - bridge2 = "A_REALLY_LONG_BRIDGE_NAME2" - self.assertEqual(len(self.agent.get_veth_name('int-', bridge1)), - ip_lib.VETH_MAX_NAME_LENGTH) - self.assertEqual(len(self.agent.get_veth_name('int-', bridge2)), - ip_lib.VETH_MAX_NAME_LENGTH) - self.assertNotEqual(self.agent.get_veth_name('int-', bridge1), - self.agent.get_veth_name('int-', bridge2)) - - def test_port_unbound(self): - with mock.patch.object(self.agent, "reclaim_local_vlan") as reclvl_fn: - self.agent.enable_tunneling = True - lvm = mock.Mock() - lvm.network_type = "gre" - lvm.vif_ports = {"vif1": mock.Mock()} - self.agent.local_vlan_map["netuid12345"] = lvm - self.agent.port_unbound("vif1", "netuid12345") - self.assertTrue(reclvl_fn.called) - reclvl_fn.called = False - - lvm.vif_ports = {} - self.agent.port_unbound("vif1", "netuid12345") - self.assertEqual(reclvl_fn.call_count, 2) - - lvm.vif_ports = {"vif1": mock.Mock()} - self.agent.port_unbound("vif3", "netuid12345") - self.assertEqual(reclvl_fn.call_count, 2) - - def _prepare_l2_pop_ofports(self): - lvm1 = mock.Mock() - lvm1.network_type = 'gre' - lvm1.vlan = 'vlan1' - lvm1.segmentation_id = 'seg1' - lvm1.tun_ofports = set(['1']) - lvm2 = mock.Mock() - lvm2.network_type = 'gre' - lvm2.vlan = 'vlan2' - lvm2.segmentation_id = 'seg2' - lvm2.tun_ofports = set(['1', '2']) - self.agent.local_vlan_map = {'net1': lvm1, 'net2': lvm2} - self.agent.tun_br_ofports = {'gre': - {'1.1.1.1': '1', '2.2.2.2': '2'}} - self.agent.arp_responder_enabled = True - - def test_fdb_ignore_network(self): - self._prepare_l2_pop_ofports() - fdb_entry = {'net3': {}} - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'add_flow'), - mock.patch.object(self.agent.tun_br, 'delete_flows'), - mock.patch.object(self.agent, 'setup_tunnel_port'), - mock.patch.object(self.agent, 'cleanup_tunnel_port') - ) as (add_flow_fn, del_flow_fn, add_tun_fn, clean_tun_fn): - self.agent.fdb_add(None, fdb_entry) - self.assertFalse(add_flow_fn.called) - self.assertFalse(add_tun_fn.called) - self.agent.fdb_remove(None, fdb_entry) - self.assertFalse(del_flow_fn.called) - self.assertFalse(clean_tun_fn.called) - - def test_fdb_ignore_self(self): - self._prepare_l2_pop_ofports() - self.agent.local_ip = 'agent_ip' - fdb_entry = {'net2': - {'network_type': 'gre', - 'segment_id': 'tun2', - 'ports': - {'agent_ip': - [[FAKE_MAC, FAKE_IP1], - n_const.FLOODING_ENTRY]}}} - with mock.patch.object(self.agent.tun_br, - "defer_apply_on") as defer_fn: - self.agent.fdb_add(None, fdb_entry) - self.assertFalse(defer_fn.called) - - self.agent.fdb_remove(None, fdb_entry) - self.assertFalse(defer_fn.called) - - def test_fdb_add_flows(self): - self._prepare_l2_pop_ofports() - fdb_entry = {'net1': - {'network_type': 'gre', - 'segment_id': 'tun1', - 'ports': - {'2.2.2.2': - [[FAKE_MAC, FAKE_IP1], - n_const.FLOODING_ENTRY]}}} - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'add_flow'), - mock.patch.object(self.agent.tun_br, 'mod_flow'), - mock.patch.object(self.agent, 'setup_tunnel_port'), - ) as (add_flow_fn, mod_flow_fn, add_tun_fn): - self.agent.fdb_add(None, fdb_entry) - self.assertFalse(add_tun_fn.called) - actions = ('move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],' - 'mod_dl_src:%(mac)s,' - 'load:0x2->NXM_OF_ARP_OP[],' - 'move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],' - 'move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],' - 'load:%(mac)#x->NXM_NX_ARP_SHA[],' - 'load:%(ip)#x->NXM_OF_ARP_SPA[],' - 'in_port' % - {'mac': netaddr.EUI(FAKE_MAC, dialect=netaddr.mac_unix), - 'ip': netaddr.IPAddress(FAKE_IP1)}) - add_flow_fn.assert_has_calls([ - mock.call(table=constants.ARP_RESPONDER, - priority=1, - proto='arp', - dl_vlan='vlan1', - nw_dst=FAKE_IP1, - actions=actions), - mock.call(table=constants.UCAST_TO_TUN, - priority=2, - dl_vlan='vlan1', - dl_dst=FAKE_MAC, - actions='strip_vlan,' - 'set_tunnel:seg1,output:2') - ]) - mod_flow_fn.assert_called_with(table=constants.FLOOD_TO_TUN, - dl_vlan='vlan1', - actions='strip_vlan,' - 'set_tunnel:seg1,output:1,2') - - def test_fdb_del_flows(self): - self._prepare_l2_pop_ofports() - fdb_entry = {'net2': - {'network_type': 'gre', - 'segment_id': 'tun2', - 'ports': - {'2.2.2.2': - [[FAKE_MAC, FAKE_IP1], - n_const.FLOODING_ENTRY]}}} - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'mod_flow'), - mock.patch.object(self.agent.tun_br, 'delete_flows'), - ) as (mod_flow_fn, del_flow_fn): - self.agent.fdb_remove(None, fdb_entry) - mod_flow_fn.assert_called_with(table=constants.FLOOD_TO_TUN, - dl_vlan='vlan2', - actions='strip_vlan,' - 'set_tunnel:seg2,output:1') - expected = [mock.call(table=constants.ARP_RESPONDER, - proto='arp', - dl_vlan='vlan2', - nw_dst=FAKE_IP1), - mock.call(table=constants.UCAST_TO_TUN, - dl_vlan='vlan2', - dl_dst=FAKE_MAC), - mock.call(in_port='2')] - del_flow_fn.assert_has_calls(expected) - - def test_fdb_add_port(self): - self._prepare_l2_pop_ofports() - fdb_entry = {'net1': - {'network_type': 'gre', - 'segment_id': 'tun1', - 'ports': {'1.1.1.1': [[FAKE_MAC, FAKE_IP1]]}}} - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'add_flow'), - mock.patch.object(self.agent.tun_br, 'mod_flow'), - mock.patch.object(self.agent, 'setup_tunnel_port') - ) as (add_flow_fn, mod_flow_fn, add_tun_fn): - self.agent.fdb_add(None, fdb_entry) - self.assertFalse(add_tun_fn.called) - fdb_entry['net1']['ports']['10.10.10.10'] = [[FAKE_MAC, FAKE_IP1]] - self.agent.fdb_add(None, fdb_entry) - add_tun_fn.assert_called_with('gre-0a0a0a0a', '10.10.10.10', 'gre') - - def test_fdb_del_port(self): - self._prepare_l2_pop_ofports() - fdb_entry = {'net2': - {'network_type': 'gre', - 'segment_id': 'tun2', - 'ports': {'2.2.2.2': [n_const.FLOODING_ENTRY]}}} - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'delete_flows'), - mock.patch.object(self.agent.tun_br, 'delete_port') - ) as (del_flow_fn, del_port_fn): - self.agent.fdb_remove(None, fdb_entry) - del_port_fn.assert_called_once_with('gre-02020202') - - def test_fdb_update_chg_ip(self): - self._prepare_l2_pop_ofports() - fdb_entries = {'chg_ip': - {'net1': - {'agent_ip': - {'before': [[FAKE_MAC, FAKE_IP1]], - 'after': [[FAKE_MAC, FAKE_IP2]]}}}} - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'add_flow'), - mock.patch.object(self.agent.tun_br, 'delete_flows') - ) as (add_flow_fn, del_flow_fn): - self.agent.fdb_update(None, fdb_entries) - actions = ('move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],' - 'mod_dl_src:%(mac)s,' - 'load:0x2->NXM_OF_ARP_OP[],' - 'move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],' - 'move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],' - 'load:%(mac)#x->NXM_NX_ARP_SHA[],' - 'load:%(ip)#x->NXM_OF_ARP_SPA[],' - 'in_port' % - {'mac': netaddr.EUI(FAKE_MAC, dialect=netaddr.mac_unix), - 'ip': netaddr.IPAddress(FAKE_IP2)}) - add_flow_fn.assert_called_once_with(table=constants.ARP_RESPONDER, - priority=1, - proto='arp', - dl_vlan='vlan1', - nw_dst=FAKE_IP2, - actions=actions) - del_flow_fn.assert_called_once_with(table=constants.ARP_RESPONDER, - proto='arp', - dl_vlan='vlan1', - nw_dst=FAKE_IP1) - - def test_recl_lv_port_to_preserve(self): - self._prepare_l2_pop_ofports() - self.agent.l2_pop = True - self.agent.enable_tunneling = True - with mock.patch.object( - self.agent.tun_br, 'cleanup_tunnel_port' - ) as clean_tun_fn: - self.agent.reclaim_local_vlan('net1') - self.assertFalse(clean_tun_fn.called) - - def test_recl_lv_port_to_remove(self): - self._prepare_l2_pop_ofports() - self.agent.l2_pop = True - self.agent.enable_tunneling = True - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'delete_port'), - mock.patch.object(self.agent.tun_br, 'delete_flows') - ) as (del_port_fn, del_flow_fn): - self.agent.reclaim_local_vlan('net2') - del_port_fn.assert_called_once_with('gre-02020202') - - def test_daemon_loop_uses_polling_manager(self): - with mock.patch( - 'neutron.agent.linux.polling.get_polling_manager') as mock_get_pm: - with mock.patch.object(self.agent, 'rpc_loop') as mock_loop: - self.agent.daemon_loop() - mock_get_pm.assert_called_with(True, 'sudo', - constants.DEFAULT_OVSDBMON_RESPAWN) - mock_loop.assert_called_once_with(polling_manager=mock.ANY) - - def test_setup_tunnel_port_error_negative(self): - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'add_tunnel_port', - return_value='-1'), - mock.patch.object(ovs_neutron_agent.LOG, 'error') - ) as (add_tunnel_port_fn, log_error_fn): - ofport = self.agent.setup_tunnel_port( - 'gre-1', 'remote_ip', p_const.TYPE_GRE) - add_tunnel_port_fn.assert_called_once_with( - 'gre-1', 'remote_ip', self.agent.local_ip, p_const.TYPE_GRE, - self.agent.vxlan_udp_port, self.agent.dont_fragment) - log_error_fn.assert_called_once_with( - _("Failed to set-up %(type)s tunnel port to %(ip)s"), - {'type': p_const.TYPE_GRE, 'ip': 'remote_ip'}) - self.assertEqual(ofport, 0) - - def test_setup_tunnel_port_error_not_int(self): - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'add_tunnel_port', - return_value=None), - mock.patch.object(ovs_neutron_agent.LOG, 'exception'), - mock.patch.object(ovs_neutron_agent.LOG, 'error') - ) as (add_tunnel_port_fn, log_exc_fn, log_error_fn): - ofport = self.agent.setup_tunnel_port( - 'gre-1', 'remote_ip', p_const.TYPE_GRE) - add_tunnel_port_fn.assert_called_once_with( - 'gre-1', 'remote_ip', self.agent.local_ip, p_const.TYPE_GRE, - self.agent.vxlan_udp_port, self.agent.dont_fragment) - log_exc_fn.assert_called_once_with( - _("ofport should have a value that can be " - "interpreted as an integer")) - log_error_fn.assert_called_once_with( - _("Failed to set-up %(type)s tunnel port to %(ip)s"), - {'type': p_const.TYPE_GRE, 'ip': 'remote_ip'}) - self.assertEqual(ofport, 0) - - def test_setup_tunnel_port_error_negative_df_disabled(self): - with contextlib.nested( - mock.patch.object(self.agent.tun_br, 'add_tunnel_port', - return_value='-1'), - mock.patch.object(ovs_neutron_agent.LOG, 'error') - ) as (add_tunnel_port_fn, log_error_fn): - self.agent.dont_fragment = False - ofport = self.agent.setup_tunnel_port( - 'gre-1', 'remote_ip', p_const.TYPE_GRE) - add_tunnel_port_fn.assert_called_once_with( - 'gre-1', 'remote_ip', self.agent.local_ip, p_const.TYPE_GRE, - self.agent.vxlan_udp_port, self.agent.dont_fragment) - log_error_fn.assert_called_once_with( - _("Failed to set-up %(type)s tunnel port to %(ip)s"), - {'type': p_const.TYPE_GRE, 'ip': 'remote_ip'}) - self.assertEqual(ofport, 0) - - def test_tunnel_sync_with_ovs_plugin(self): - fake_tunnel_details = {'tunnels': [{'id': '42', - 'ip_address': '100.101.102.103'}]} - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'tunnel_sync', - return_value=fake_tunnel_details), - mock.patch.object(self.agent, 'setup_tunnel_port') - ) as (tunnel_sync_rpc_fn, setup_tunnel_port_fn): - self.agent.tunnel_types = ['gre'] - self.agent.tunnel_sync() - expected_calls = [mock.call('gre-42', '100.101.102.103', 'gre')] - setup_tunnel_port_fn.assert_has_calls(expected_calls) - - def test_tunnel_sync_with_ml2_plugin(self): - fake_tunnel_details = {'tunnels': [{'ip_address': '100.101.31.15'}]} - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'tunnel_sync', - return_value=fake_tunnel_details), - mock.patch.object(self.agent, 'setup_tunnel_port') - ) as (tunnel_sync_rpc_fn, setup_tunnel_port_fn): - self.agent.tunnel_types = ['vxlan'] - self.agent.tunnel_sync() - expected_calls = [mock.call('vxlan-64651f0f', - '100.101.31.15', 'vxlan')] - setup_tunnel_port_fn.assert_has_calls(expected_calls) - - def test_tunnel_sync_invalid_ip_address(self): - fake_tunnel_details = {'tunnels': [{'ip_address': '300.300.300.300'}, - {'ip_address': '100.100.100.100'}]} - with contextlib.nested( - mock.patch.object(self.agent.plugin_rpc, 'tunnel_sync', - return_value=fake_tunnel_details), - mock.patch.object(self.agent, 'setup_tunnel_port') - ) as (tunnel_sync_rpc_fn, setup_tunnel_port_fn): - self.agent.tunnel_types = ['vxlan'] - self.agent.tunnel_sync() - setup_tunnel_port_fn.assert_called_once_with('vxlan-64646464', - '100.100.100.100', - 'vxlan') - - def test_tunnel_update(self): - kwargs = {'tunnel_ip': '10.10.10.10', - 'tunnel_type': 'gre'} - self.agent.setup_tunnel_port = mock.Mock() - self.agent.enable_tunneling = True - self.agent.tunnel_types = ['gre'] - self.agent.l2_pop = False - self.agent.tunnel_update(context=None, **kwargs) - expected_calls = [mock.call('gre-0a0a0a0a', '10.10.10.10', 'gre')] - self.agent.setup_tunnel_port.assert_has_calls(expected_calls) - - def test_ovs_restart(self): - reply2 = {'current': set(['tap0']), - 'added': set(['tap2']), - 'removed': set([])} - - reply3 = {'current': set(['tap2']), - 'added': set([]), - 'removed': set(['tap0'])} - - with contextlib.nested( - mock.patch.object(async_process.AsyncProcess, "_spawn"), - mock.patch.object(log.ContextAdapter, 'exception'), - mock.patch.object(ovs_neutron_agent.OVSNeutronAgent, - 'scan_ports'), - mock.patch.object(ovs_neutron_agent.OVSNeutronAgent, - 'process_network_ports'), - mock.patch.object(ovs_neutron_agent.OVSNeutronAgent, - 'check_ovs_restart'), - mock.patch.object(ovs_neutron_agent.OVSNeutronAgent, - 'setup_integration_br'), - mock.patch.object(ovs_neutron_agent.OVSNeutronAgent, - 'setup_physical_bridges') - ) as (spawn_fn, log_exception, scan_ports, process_network_ports, - check_ovs_restart, setup_int_br, setup_phys_br): - log_exception.side_effect = Exception( - 'Fake exception to get out of the loop') - scan_ports.side_effect = [reply2, reply3] - process_network_ports.side_effect = [ - False, Exception('Fake exception to get out of the loop')] - check_ovs_restart.side_effect = [False, True] - - # This will exit after the second loop - try: - self.agent.daemon_loop() - except Exception: - pass - - scan_ports.assert_has_calls([ - mock.call(set(), set()), - mock.call(set(), set()) - ]) - process_network_ports.assert_has_calls([ - mock.call({'current': set(['tap0']), - 'removed': set([]), - 'added': set(['tap2'])}, False), - mock.call({'current': set(['tap2']), - 'removed': set(['tap0']), - 'added': set([])}, True) - ]) - - # Verify the second time through the loop we triggered an - # OVS restart and re-setup the bridges - setup_int_br.assert_has_calls([mock.call()]) - setup_phys_br.assert_has_calls([mock.call({})]) - - -class AncillaryBridgesTest(base.BaseTestCase): - - def setUp(self): - super(AncillaryBridgesTest, self).setUp() - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - # Avoid rpc initialization for unit tests - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - cfg.CONF.set_override('report_interval', 0, 'AGENT') - self.kwargs = ovs_neutron_agent.create_agent_config_map(cfg.CONF) - - def _test_ancillary_bridges(self, bridges, ancillary): - device_ids = ancillary[:] - - def pullup_side_effect(self, *args): - result = device_ids.pop(0) - return result - - with contextlib.nested( - mock.patch('neutron.plugins.openvswitch.agent.ovs_neutron_agent.' - 'OVSNeutronAgent.setup_integration_br', - return_value=mock.Mock()), - mock.patch('neutron.agent.linux.utils.get_interface_mac', - return_value='00:00:00:00:00:01'), - mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.' - 'get_local_port_mac', - return_value='00:00:00:00:00:01'), - mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.' - 'set_secure_mode'), - mock.patch('neutron.agent.linux.ovs_lib.get_bridges', - return_value=bridges), - mock.patch( - 'neutron.agent.linux.ovs_lib.get_bridge_external_bridge_id', - side_effect=pullup_side_effect), - mock.patch('neutron.plugins.openvswitch.agent.ovs_neutron_agent.' - 'OVSNeutronAgent._check_arp_responder_support', - return_value=True)): - self.agent = ovs_neutron_agent.OVSNeutronAgent(**self.kwargs) - self.assertEqual(len(ancillary), len(self.agent.ancillary_brs)) - if ancillary: - bridges = [br.br_name for br in self.agent.ancillary_brs] - for br in ancillary: - self.assertIn(br, bridges) - - def test_ancillary_bridges_single(self): - bridges = ['br-int', 'br-ex'] - self._test_ancillary_bridges(bridges, ['br-ex']) - - def test_ancillary_bridges_none(self): - bridges = ['br-int'] - self._test_ancillary_bridges(bridges, []) - - def test_ancillary_bridges_multiple(self): - bridges = ['br-int', 'br-ex1', 'br-ex2'] - self._test_ancillary_bridges(bridges, ['br-ex1', 'br-ex2']) diff --git a/neutron/tests/unit/openvswitch/test_ovs_rpcapi.py b/neutron/tests/unit/openvswitch/test_ovs_rpcapi.py deleted file mode 100644 index e8f75b9f4..000000000 --- a/neutron/tests/unit/openvswitch/test_ovs_rpcapi.py +++ /dev/null @@ -1,123 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012, Red Hat, Inc. -# -# 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. - -""" -Unit Tests for openvswitch rpc -""" - -import fixtures - -from neutron.agent import rpc as agent_rpc -from neutron.common import topics -from neutron.openstack.common import context -from neutron.plugins.openvswitch.common import constants -from neutron.plugins.openvswitch import ovs_neutron_plugin as povs -from neutron.tests import base - - -class rpcApiTestCase(base.BaseTestCase): - - def _test_ovs_api(self, rpcapi, topic, method, rpc_method, **kwargs): - ctxt = context.RequestContext('fake_user', 'fake_project') - expected_retval = 'foo' if method == 'call' else None - expected_msg = rpcapi.make_msg(method, **kwargs) - if rpc_method == 'cast' and method == 'run_instance': - kwargs['call'] = False - - self.fake_args = None - self.fake_kwargs = None - - def _fake_rpc_method(*args, **kwargs): - self.fake_args = args - self.fake_kwargs = kwargs - if expected_retval: - return expected_retval - - self.useFixture(fixtures.MonkeyPatch( - 'neutron.common.rpc_compat.RpcProxy.' + rpc_method, - _fake_rpc_method)) - - retval = getattr(rpcapi, method)(ctxt, **kwargs) - - self.assertEqual(retval, expected_retval) - expected_args = [ctxt, expected_msg] - expected_kwargs = {'topic': topic} - - # skip the first argument which is 'self' - for arg, expected_arg in zip(self.fake_args[1:], expected_args): - self.assertEqual(arg, expected_arg) - self.assertEqual(expected_kwargs, self.fake_kwargs) - - def test_delete_network(self): - rpcapi = povs.AgentNotifierApi(topics.AGENT) - self._test_ovs_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.NETWORK, - topics.DELETE), - 'network_delete', rpc_method='fanout_cast', - network_id='fake_request_spec') - - def test_port_update(self): - rpcapi = povs.AgentNotifierApi(topics.AGENT) - self._test_ovs_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - port='fake_port', - network_type='fake_network_type', - segmentation_id='fake_segmentation_id', - physical_network='fake_physical_network') - - def test_tunnel_update(self): - rpcapi = povs.AgentNotifierApi(topics.AGENT) - self._test_ovs_api(rpcapi, - topics.get_topic_name(topics.AGENT, - constants.TUNNEL, - topics.UPDATE), - 'tunnel_update', rpc_method='fanout_cast', - tunnel_ip='fake_ip', tunnel_id='fake_id', - tunnel_type=None) - - def test_device_details(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_ovs_api(rpcapi, topics.PLUGIN, - 'get_device_details', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id') - - def test_update_device_down(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_ovs_api(rpcapi, topics.PLUGIN, - 'update_device_down', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') - - def test_tunnel_sync(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_ovs_api(rpcapi, topics.PLUGIN, - 'tunnel_sync', rpc_method='call', - tunnel_ip='fake_tunnel_ip', - tunnel_type=None) - - def test_update_device_up(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_ovs_api(rpcapi, topics.PLUGIN, - 'update_device_up', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') diff --git a/neutron/tests/unit/openvswitch/test_ovs_security_group.py b/neutron/tests/unit/openvswitch/test_ovs_security_group.py deleted file mode 100644 index 50e2caf27..000000000 --- a/neutron/tests/unit/openvswitch/test_ovs_security_group.py +++ /dev/null @@ -1,104 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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 neutron.api.v2 import attributes -from neutron.extensions import securitygroup as ext_sg -from neutron import manager -from neutron.tests.unit import test_extension_security_group as test_sg -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - -PLUGIN_NAME = ('neutron.plugins.openvswitch.' - 'ovs_neutron_plugin.OVSNeutronPluginV2') -NOTIFIER = ('neutron.plugins.openvswitch.' - 'ovs_neutron_plugin.AgentNotifierApi') - - -class OpenvswitchSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self, plugin=None): - test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER) - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - self._attribute_map_bk_ = {} - for item in attributes.RESOURCE_ATTRIBUTE_MAP: - self._attribute_map_bk_[item] = (attributes. - RESOURCE_ATTRIBUTE_MAP[item]. - copy()) - super(OpenvswitchSecurityGroupsTestCase, self).setUp(PLUGIN_NAME) - - def tearDown(self): - super(OpenvswitchSecurityGroupsTestCase, self).tearDown() - attributes.RESOURCE_ATTRIBUTE_MAP = self._attribute_map_bk_ - - -class TestOpenvswitchSGServerRpcCallBack( - OpenvswitchSecurityGroupsTestCase, - test_sg_rpc.SGServerRpcCallBackMixinTestCase): - pass - - -class TestOpenvswitchSGServerRpcCallBackXML( - OpenvswitchSecurityGroupsTestCase, - test_sg_rpc.SGServerRpcCallBackMixinTestCaseXML): - pass - - -class TestOpenvswitchSecurityGroups(OpenvswitchSecurityGroupsTestCase, - test_sg.TestSecurityGroups, - test_sg_rpc.SGNotificationTestMixin): - def test_security_group_get_port_from_device(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - security_group_id = sg['security_group']['id'] - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - fixed_ips = port['port']['fixed_ips'] - data = {'port': {'fixed_ips': fixed_ips, - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: - [security_group_id]}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - port_id = res['port']['id'] - plugin = manager.NeutronManager.get_plugin() - callbacks = plugin.endpoints[0] - port_dict = callbacks.get_port_from_device(port_id) - self.assertEqual(port_id, port_dict['id']) - self.assertEqual([security_group_id], - port_dict[ext_sg.SECURITYGROUPS]) - self.assertEqual([], port_dict['security_group_rules']) - self.assertEqual([fixed_ips[0]['ip_address']], - port_dict['fixed_ips']) - self._delete('ports', port_id) - - def test_security_group_get_port_from_device_with_no_port(self): - plugin = manager.NeutronManager.get_plugin() - port_dict = plugin.endpoints[0].get_port_from_device('bad_device_id') - self.assertIsNone(port_dict) - - -class TestOpenvswitchSecurityGroupsXML(TestOpenvswitchSecurityGroups): - fmt = 'xml' diff --git a/neutron/tests/unit/openvswitch/test_ovs_tunnel.py b/neutron/tests/unit/openvswitch/test_ovs_tunnel.py deleted file mode 100644 index 642659037..000000000 --- a/neutron/tests/unit/openvswitch/test_ovs_tunnel.py +++ /dev/null @@ -1,603 +0,0 @@ -# Copyright 2012 VMware, Inc. -# All Rights Reserved. -# -# 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 contextlib - -import mock -from oslo.config import cfg - -from neutron.agent.linux import ip_lib -from neutron.agent.linux import ovs_lib -from neutron.openstack.common import log -from neutron.plugins.common import constants as p_const -from neutron.plugins.openvswitch.agent import ovs_neutron_agent -from neutron.plugins.openvswitch.common import constants -from neutron.tests import base - - -# Useful global dummy variables. -NET_UUID = '3faeebfe-5d37-11e1-a64b-000c29d5f0a7' -LS_ID = 42 -LV_ID = 42 -LV_IDS = [42, 43] -VIF_ID = '404deaec-5d37-11e1-a64b-000c29d5f0a8' -VIF_MAC = '3c:09:24:1e:78:23' -OFPORT_NUM = 1 -VIF_PORT = ovs_lib.VifPort('port', OFPORT_NUM, - VIF_ID, VIF_MAC, 'switch') -VIF_PORTS = {VIF_ID: VIF_PORT} -LVM = ovs_neutron_agent.LocalVLANMapping(LV_ID, 'gre', None, LS_ID, VIF_PORTS) -LVM_FLAT = ovs_neutron_agent.LocalVLANMapping( - LV_ID, 'flat', 'net1', LS_ID, VIF_PORTS) -LVM_VLAN = ovs_neutron_agent.LocalVLANMapping( - LV_ID, 'vlan', 'net1', LS_ID, VIF_PORTS) - -TUN_OFPORTS = {p_const.TYPE_GRE: {'ip1': '11', 'ip2': '12'}} - -BCAST_MAC = "01:00:00:00:00:00/01:00:00:00:00:00" -UCAST_MAC = "00:00:00:00:00:00/01:00:00:00:00:00" - - -class DummyPort: - def __init__(self, interface_id): - self.interface_id = interface_id - - -class DummyVlanBinding: - def __init__(self, network_id, vlan_id): - self.network_id = network_id - self.vlan_id = vlan_id - - -class TunnelTest(base.BaseTestCase): - - def setUp(self): - super(TunnelTest, self).setUp() - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - cfg.CONF.set_override('rpc_backend', - 'neutron.openstack.common.rpc.impl_fake') - cfg.CONF.set_override('report_interval', 0, 'AGENT') - - check_arp_responder_str = ('neutron.plugins.openvswitch.agent.' - 'ovs_neutron_agent.OVSNeutronAgent.' - '_check_arp_responder_support') - self.mock_check_arp_resp = mock.patch(check_arp_responder_str).start() - self.mock_check_arp_resp.return_value = True - - self.INT_BRIDGE = 'integration_bridge' - self.TUN_BRIDGE = 'tunnel_bridge' - self.MAP_TUN_BRIDGE = 'tun_br_map' - self.NET_MAPPING = {'net1': self.MAP_TUN_BRIDGE} - self.INT_OFPORT = 11111 - self.TUN_OFPORT = 22222 - self.MAP_TUN_OFPORT = 33333 - self.VETH_MTU = None - self.inta = mock.Mock() - self.intb = mock.Mock() - - self.ovs_bridges = {self.INT_BRIDGE: mock.Mock(), - self.TUN_BRIDGE: mock.Mock(), - self.MAP_TUN_BRIDGE: mock.Mock(), - } - - self.mock_bridge = mock.patch.object(ovs_lib, 'OVSBridge').start() - self.mock_bridge.side_effect = (lambda br_name, root_helper: - self.ovs_bridges[br_name]) - self.mock_bridge_expected = [ - mock.call(self.INT_BRIDGE, 'sudo'), - mock.call(self.MAP_TUN_BRIDGE, 'sudo'), - mock.call(self.TUN_BRIDGE, 'sudo'), - ] - - self.mock_int_bridge = self.ovs_bridges[self.INT_BRIDGE] - self.mock_int_bridge.get_local_port_mac.return_value = '000000000001' - self.mock_int_bridge_expected = [ - mock.call.set_secure_mode(), - mock.call.get_local_port_mac(), - mock.call.delete_port('patch-tun'), - mock.call.remove_all_flows(), - mock.call.add_flow(priority=1, actions='normal'), - mock.call.add_flow(priority=0, table=constants.CANARY_TABLE, - actions='drop') - ] - - self.mock_map_tun_bridge = self.ovs_bridges[self.MAP_TUN_BRIDGE] - self.mock_map_tun_bridge.br_name = self.MAP_TUN_BRIDGE - self.mock_map_tun_bridge.add_port.return_value = None - self.mock_map_tun_bridge_expected = [ - mock.call.remove_all_flows(), - mock.call.add_flow(priority=1, actions='normal'), - mock.call.delete_port('phy-%s' % self.MAP_TUN_BRIDGE), - mock.call.add_port(self.intb), - ] - self.mock_int_bridge.add_port.return_value = None - self.mock_int_bridge_expected += [ - mock.call.delete_port('int-%s' % self.MAP_TUN_BRIDGE), - mock.call.add_port(self.inta) - ] - self.inta_expected = [mock.call.link.set_up()] - self.intb_expected = [mock.call.link.set_up()] - - self.mock_int_bridge_expected += [ - mock.call.add_flow(priority=2, in_port=None, actions='drop') - ] - self.mock_map_tun_bridge_expected += [ - mock.call.add_flow(priority=2, in_port=None, actions='drop') - ] - - self.mock_tun_bridge = self.ovs_bridges[self.TUN_BRIDGE] - self.mock_tun_bridge_expected = [ - mock.call.reset_bridge(), - mock.call.add_patch_port('patch-int', 'patch-tun'), - ] - self.mock_int_bridge_expected += [ - mock.call.add_patch_port('patch-tun', 'patch-int') - ] - self.mock_int_bridge.add_patch_port.return_value = self.TUN_OFPORT - self.mock_tun_bridge.add_patch_port.return_value = self.INT_OFPORT - - self.mock_tun_bridge_expected += [ - mock.call.remove_all_flows(), - mock.call.add_flow(priority=1, - in_port=self.INT_OFPORT, - actions="resubmit(,%s)" % - constants.PATCH_LV_TO_TUN), - mock.call.add_flow(priority=0, actions="drop"), - mock.call.add_flow(priority=0, table=constants.PATCH_LV_TO_TUN, - dl_dst=UCAST_MAC, - actions="resubmit(,%s)" % - constants.UCAST_TO_TUN), - mock.call.add_flow(priority=0, table=constants.PATCH_LV_TO_TUN, - dl_dst=BCAST_MAC, - actions="resubmit(,%s)" % - constants.FLOOD_TO_TUN), - ] - for tunnel_type in constants.TUNNEL_NETWORK_TYPES: - self.mock_tun_bridge_expected.append( - mock.call.add_flow( - table=constants.TUN_TABLE[tunnel_type], - priority=0, - actions="drop")) - learned_flow = ("table=%s," - "priority=1," - "hard_timeout=300," - "NXM_OF_VLAN_TCI[0..11]," - "NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]," - "load:0->NXM_OF_VLAN_TCI[]," - "load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[]," - "output:NXM_OF_IN_PORT[]" % - constants.UCAST_TO_TUN) - self.mock_tun_bridge_expected += [ - mock.call.add_flow(table=constants.LEARN_FROM_TUN, - priority=1, - actions="learn(%s),output:%s" % - (learned_flow, self.INT_OFPORT)), - mock.call.add_flow(table=constants.UCAST_TO_TUN, - priority=0, - actions="resubmit(,%s)" % - constants.FLOOD_TO_TUN), - mock.call.add_flow(table=constants.FLOOD_TO_TUN, - priority=0, - actions="drop") - ] - - self.device_exists = mock.patch.object(ip_lib, 'device_exists').start() - self.device_exists.return_value = True - self.device_exists_expected = [ - mock.call(self.MAP_TUN_BRIDGE, 'sudo'), - mock.call('int-%s' % self.MAP_TUN_BRIDGE, 'sudo'), - ] - - self.ipdevice = mock.patch.object(ip_lib, 'IPDevice').start() - self.ipdevice_expected = [ - mock.call('int-%s' % self.MAP_TUN_BRIDGE, 'sudo'), - mock.call().link.delete() - ] - self.ipwrapper = mock.patch.object(ip_lib, 'IPWrapper').start() - add_veth = self.ipwrapper.return_value.add_veth - add_veth.return_value = [self.inta, self.intb] - self.ipwrapper_expected = [ - mock.call('sudo'), - mock.call().add_veth('int-%s' % self.MAP_TUN_BRIDGE, - 'phy-%s' % self.MAP_TUN_BRIDGE) - ] - - self.get_bridges = mock.patch.object(ovs_lib, 'get_bridges').start() - self.get_bridges.return_value = [self.INT_BRIDGE, - self.TUN_BRIDGE, - self.MAP_TUN_BRIDGE] - self.get_bridges_expected = [ - mock.call('sudo') - ] - self.execute = mock.patch('neutron.agent.linux.utils.execute').start() - self.execute_expected = [mock.call(['/sbin/udevadm', 'settle', - '--timeout=10'])] - - def _verify_mock_call(self, mock_obj, expected): - mock_obj.assert_has_calls(expected) - self.assertEqual(len(mock_obj.mock_calls), len(expected)) - - def _verify_mock_calls(self): - self._verify_mock_call(self.mock_bridge, self.mock_bridge_expected) - self._verify_mock_call(self.mock_int_bridge, - self.mock_int_bridge_expected) - self._verify_mock_call(self.mock_map_tun_bridge, - self.mock_map_tun_bridge_expected) - self._verify_mock_call(self.mock_tun_bridge, - self.mock_tun_bridge_expected) - self._verify_mock_call(self.device_exists, self.device_exists_expected) - self._verify_mock_call(self.ipdevice, self.ipdevice_expected) - self._verify_mock_call(self.ipwrapper, self.ipwrapper_expected) - self._verify_mock_call(self.get_bridges, self.get_bridges_expected) - self._verify_mock_call(self.inta, self.inta_expected) - self._verify_mock_call(self.intb, self.intb_expected) - self._verify_mock_call(self.execute, self.execute_expected) - - def test_construct(self): - ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - self._verify_mock_calls() - - # TODO(ethuleau): Initially, local ARP responder is be dependent to the - # ML2 l2 population mechanism driver. - # The next two tests use l2_pop flag to test ARP responder - def test_construct_with_arp_responder(self): - ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU, l2_population=True, - arp_responder=True) - self.mock_tun_bridge_expected.insert( - 5, mock.call.add_flow(table=constants.PATCH_LV_TO_TUN, - priority=1, - proto="arp", - dl_dst="ff:ff:ff:ff:ff:ff", - actions="resubmit(,%s)" % - constants.ARP_RESPONDER) - ) - self.mock_tun_bridge_expected.insert( - 12, mock.call.add_flow(table=constants.ARP_RESPONDER, - priority=0, - actions="resubmit(,%s)" % - constants.FLOOD_TO_TUN) - ) - self._verify_mock_calls() - - def test_construct_without_arp_responder(self): - ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU, l2_population=False, - arp_responder=True) - self._verify_mock_calls() - - def test_construct_vxlan(self): - ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', - self.NET_MAPPING, - 'sudo', 2, ['vxlan'], - self.VETH_MTU) - self._verify_mock_calls() - - def test_provision_local_vlan(self): - ofports = ','.join(TUN_OFPORTS[p_const.TYPE_GRE].values()) - self.mock_tun_bridge_expected += [ - mock.call.mod_flow(table=constants.FLOOD_TO_TUN, - dl_vlan=LV_ID, - actions="strip_vlan," - "set_tunnel:%s,output:%s" % - (LS_ID, ofports)), - mock.call.add_flow(table=constants.TUN_TABLE['gre'], - priority=1, - tun_id=LS_ID, - actions="mod_vlan_vid:%s,resubmit(,%s)" % - (LV_ID, constants.LEARN_FROM_TUN)), - ] - - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.available_local_vlans = set([LV_ID]) - a.tun_br_ofports = TUN_OFPORTS - a.provision_local_vlan(NET_UUID, p_const.TYPE_GRE, None, LS_ID) - self._verify_mock_calls() - - def test_provision_local_vlan_flat(self): - action_string = 'strip_vlan,normal' - self.mock_map_tun_bridge_expected.append( - mock.call.add_flow(priority=4, in_port=self.MAP_TUN_OFPORT, - dl_vlan=LV_ID, actions=action_string)) - - action_string = 'mod_vlan_vid:%s,normal' % LV_ID - self.mock_int_bridge_expected.append( - mock.call.add_flow(priority=3, in_port=self.INT_OFPORT, - dl_vlan=65535, actions=action_string)) - - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.available_local_vlans = set([LV_ID]) - a.phys_brs['net1'] = self.mock_map_tun_bridge - a.phys_ofports['net1'] = self.MAP_TUN_OFPORT - a.int_ofports['net1'] = self.INT_OFPORT - a.provision_local_vlan(NET_UUID, p_const.TYPE_FLAT, 'net1', LS_ID) - self._verify_mock_calls() - - def test_provision_local_vlan_flat_fail(self): - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.provision_local_vlan(NET_UUID, p_const.TYPE_FLAT, 'net2', LS_ID) - self._verify_mock_calls() - - def test_provision_local_vlan_vlan(self): - action_string = 'mod_vlan_vid:%s,normal' % LS_ID - self.mock_map_tun_bridge_expected.append( - mock.call.add_flow(priority=4, in_port=self.MAP_TUN_OFPORT, - dl_vlan=LV_ID, actions=action_string)) - - action_string = 'mod_vlan_vid:%s,normal' % LS_ID - self.mock_int_bridge_expected.append( - mock.call.add_flow(priority=3, in_port=self.INT_OFPORT, - dl_vlan=LV_ID, actions=action_string)) - - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.available_local_vlans = set([LV_ID]) - a.phys_brs['net1'] = self.mock_map_tun_bridge - a.phys_ofports['net1'] = self.MAP_TUN_OFPORT - a.int_ofports['net1'] = self.INT_OFPORT - a.provision_local_vlan(NET_UUID, p_const.TYPE_VLAN, 'net1', LS_ID) - self._verify_mock_calls() - - def test_provision_local_vlan_vlan_fail(self): - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.provision_local_vlan(NET_UUID, p_const.TYPE_VLAN, 'net2', LS_ID) - self._verify_mock_calls() - - def test_reclaim_local_vlan(self): - self.mock_tun_bridge_expected += [ - mock.call.delete_flows( - table=constants.TUN_TABLE['gre'], tun_id=LS_ID), - mock.call.delete_flows(dl_vlan=LVM.vlan) - ] - - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.available_local_vlans = set() - a.local_vlan_map[NET_UUID] = LVM - a.reclaim_local_vlan(NET_UUID) - self.assertIn(LVM.vlan, a.available_local_vlans) - self._verify_mock_calls() - - def test_reclaim_local_vlan_flat(self): - self.mock_map_tun_bridge_expected.append( - mock.call.delete_flows( - in_port=self.MAP_TUN_OFPORT, dl_vlan=LVM_FLAT.vlan)) - self.mock_int_bridge_expected.append( - mock.call.delete_flows( - dl_vlan=65535, in_port=self.INT_OFPORT)) - - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.phys_brs['net1'] = self.mock_map_tun_bridge - a.phys_ofports['net1'] = self.MAP_TUN_OFPORT - a.int_ofports['net1'] = self.INT_OFPORT - - a.available_local_vlans = set() - a.local_vlan_map[NET_UUID] = LVM_FLAT - a.reclaim_local_vlan(NET_UUID) - self.assertIn(LVM_FLAT.vlan, a.available_local_vlans) - self._verify_mock_calls() - - def test_reclaim_local_vlan_vlan(self): - self.mock_map_tun_bridge_expected.append( - mock.call.delete_flows( - in_port=self.MAP_TUN_OFPORT, dl_vlan=LVM_VLAN.vlan)) - self.mock_int_bridge_expected.append( - mock.call.delete_flows( - dl_vlan=LV_ID, in_port=self.INT_OFPORT)) - - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.phys_brs['net1'] = self.mock_map_tun_bridge - a.phys_ofports['net1'] = self.MAP_TUN_OFPORT - a.int_ofports['net1'] = self.INT_OFPORT - - a.available_local_vlans = set() - a.local_vlan_map[NET_UUID] = LVM_VLAN - a.reclaim_local_vlan(NET_UUID) - self.assertIn(LVM_VLAN.vlan, a.available_local_vlans) - self._verify_mock_calls() - - def test_port_bound(self): - self.mock_int_bridge_expected += [ - mock.call.db_get_val('Port', VIF_PORT.port_name, 'tag'), - mock.call.set_db_attribute('Port', VIF_PORT.port_name, - 'tag', str(LVM.vlan)), - mock.call.delete_flows(in_port=VIF_PORT.ofport) - ] - - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.local_vlan_map[NET_UUID] = LVM - a.port_bound(VIF_PORT, NET_UUID, 'gre', None, LS_ID, False) - self._verify_mock_calls() - - def test_port_unbound(self): - with mock.patch.object(ovs_neutron_agent.OVSNeutronAgent, - 'reclaim_local_vlan') as reclaim_local_vlan: - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.local_vlan_map[NET_UUID] = LVM - a.port_unbound(VIF_ID, NET_UUID) - - reclaim_local_vlan.assert_called_once_with(NET_UUID) - self._verify_mock_calls() - - def test_port_dead(self): - self.mock_int_bridge_expected += [ - mock.call.db_get_val('Port', VIF_PORT.port_name, 'tag'), - mock.call.set_db_attribute( - 'Port', VIF_PORT.port_name, - 'tag', ovs_neutron_agent.DEAD_VLAN_TAG), - mock.call.add_flow(priority=2, in_port=VIF_PORT.ofport, - actions='drop') - ] - - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.available_local_vlans = set([LV_ID]) - a.local_vlan_map[NET_UUID] = LVM - a.port_dead(VIF_PORT) - self._verify_mock_calls() - - def test_tunnel_update(self): - tunnel_port = '9999' - self.mock_tun_bridge.add_tunnel_port.return_value = tunnel_port - self.mock_tun_bridge_expected += [ - mock.call.add_tunnel_port('gre-1', '10.0.10.1', '10.0.0.1', - 'gre', 4789, True), - mock.call.add_flow(priority=1, in_port=tunnel_port, - actions='resubmit(,2)') - ] - - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.tunnel_update( - mock.sentinel.ctx, tunnel_id='1', tunnel_ip='10.0.10.1', - tunnel_type=p_const.TYPE_GRE) - self._verify_mock_calls() - - def test_tunnel_update_self(self): - a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - a.tunnel_update( - mock.sentinel.ctx, tunnel_id='1', tunnel_ip='10.0.0.1') - self._verify_mock_calls() - - def test_daemon_loop(self): - reply2 = {'current': set(['tap0']), - 'added': set(['tap2']), - 'removed': set([])} - - reply3 = {'current': set(['tap2']), - 'added': set([]), - 'removed': set(['tap0'])} - - self.mock_int_bridge_expected += [ - mock.call.dump_flows_for_table(constants.CANARY_TABLE), - mock.call.dump_flows_for_table(constants.CANARY_TABLE) - ] - - with contextlib.nested( - mock.patch.object(log.ContextAdapter, 'exception'), - mock.patch.object(ovs_neutron_agent.OVSNeutronAgent, - 'scan_ports'), - mock.patch.object(ovs_neutron_agent.OVSNeutronAgent, - 'process_network_ports') - ) as (log_exception, scan_ports, process_network_ports): - log_exception.side_effect = Exception( - 'Fake exception to get out of the loop') - scan_ports.side_effect = [reply2, reply3] - process_network_ports.side_effect = [ - False, Exception('Fake exception to get out of the loop')] - - q_agent = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, - self.TUN_BRIDGE, - '10.0.0.1', - self.NET_MAPPING, - 'sudo', 2, ['gre'], - self.VETH_MTU) - - # Hack to test loop - # We start method and expect it will raise after 2nd loop - # If something goes wrong, assert_has_calls below will catch it - try: - q_agent.daemon_loop() - except Exception: - pass - - # FIXME(salv-orlando): There should not be assertions on log messages - log_exception.assert_called_once_with( - "Error while processing VIF ports") - scan_ports.assert_has_calls([ - mock.call(set(), set()), - mock.call(set(['tap0']), set()) - ]) - process_network_ports.assert_has_calls([ - mock.call({'current': set(['tap0']), - 'removed': set([]), - 'added': set(['tap2'])}, False), - mock.call({'current': set(['tap2']), - 'removed': set(['tap0']), - 'added': set([])}, False) - ]) - self._verify_mock_calls() - - -class TunnelTestWithMTU(TunnelTest): - - def setUp(self): - super(TunnelTestWithMTU, self).setUp() - self.VETH_MTU = 1500 - self.inta_expected.append(mock.call.link.set_mtu(self.VETH_MTU)) - self.intb_expected.append(mock.call.link.set_mtu(self.VETH_MTU)) diff --git a/neutron/tests/unit/plumgrid/__init__.py b/neutron/tests/unit/plumgrid/__init__.py deleted file mode 100644 index 39e9b8d13..000000000 --- a/neutron/tests/unit/plumgrid/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 PLUMgrid, Inc. All Rights Reserved. -# -# 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. -# -# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc. diff --git a/neutron/tests/unit/plumgrid/test_plumgrid_plugin.py b/neutron/tests/unit/plumgrid/test_plumgrid_plugin.py deleted file mode 100644 index 92fa937c5..000000000 --- a/neutron/tests/unit/plumgrid/test_plumgrid_plugin.py +++ /dev/null @@ -1,171 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2013 PLUMgrid, Inc. All Rights Reserved. -# -# 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. -# -# @author: Edgar Magana, emagana@plumgrid.com, PLUMgrid, Inc. - -""" -Test cases for Neutron PLUMgrid Plug-in -""" - -import mock - -from neutron.extensions import portbindings -from neutron.extensions import providernet as provider -from neutron import manager -from neutron.openstack.common import importutils -from neutron.plugins.plumgrid.plumgrid_plugin import plumgrid_plugin -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit import test_db_plugin as test_plugin - - -PLUM_DRIVER = ('neutron.plugins.plumgrid.drivers.fake_plumlib.Plumlib') -FAKE_DIRECTOR = '1.1.1.1' -FAKE_PORT = '1234' -FAKE_USERNAME = 'fake_admin' -FAKE_PASSWORD = 'fake_password' -FAKE_TIMEOUT = '0' - - -class PLUMgridPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - _plugin_name = ('neutron.plugins.plumgrid.plumgrid_plugin.' - 'plumgrid_plugin.NeutronPluginPLUMgridV2') - - def setUp(self): - def mocked_plumlib_init(self): - director_plumgrid = FAKE_DIRECTOR - director_port = FAKE_PORT - director_username = FAKE_USERNAME - director_password = FAKE_PASSWORD - timeout = FAKE_TIMEOUT - self._plumlib = importutils.import_object(PLUM_DRIVER) - self._plumlib.director_conn(director_plumgrid, - director_port, timeout, - director_username, - director_password) - - with mock.patch.object(plumgrid_plugin.NeutronPluginPLUMgridV2, - 'plumgrid_init', new=mocked_plumlib_init): - super(PLUMgridPluginV2TestCase, self).setUp(self._plugin_name) - - def tearDown(self): - super(PLUMgridPluginV2TestCase, self).tearDown() - - -class TestPlumgridPluginNetworksV2(test_plugin.TestNetworksV2, - PLUMgridPluginV2TestCase): - pass - - -class TestPlumgridV2HTTPResponse(test_plugin.TestV2HTTPResponse, - PLUMgridPluginV2TestCase): - pass - - -class TestPlumgridPluginPortsV2(test_plugin.TestPortsV2, - PLUMgridPluginV2TestCase): - def test_range_allocation(self): - self.skipTest("Plugin does not support Neutron allocation process") - - -class TestPlumgridPluginSubnetsV2(test_plugin.TestSubnetsV2, - PLUMgridPluginV2TestCase): - _unsupported = ( - 'test_create_subnet_default_gw_conflict_allocation_pool_returns_409', - 'test_create_subnet_defaults', 'test_create_subnet_gw_values', - 'test_update_subnet_gateway_in_allocation_pool_returns_409', - 'test_update_subnet_allocation_pools', - 'test_update_subnet_allocation_pools_invalid_pool_for_cidr') - - def setUp(self): - if self._testMethodName in self._unsupported: - self.skipTest("Plugin does not support Neutron allocation process") - super(TestPlumgridPluginSubnetsV2, self).setUp() - - -class TestPlumgridPluginPortBinding(PLUMgridPluginV2TestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = portbindings.VIF_TYPE_IOVISOR - - def setUp(self): - super(TestPlumgridPluginPortBinding, self).setUp() - - -class TestPlumgridNetworkAdminState(PLUMgridPluginV2TestCase): - def test_network_admin_state(self): - name = 'network_test' - admin_status_up = False - tenant_id = 'tenant_test' - network = {'network': {'name': name, - 'admin_state_up': admin_status_up, - 'tenant_id': tenant_id}} - plugin = manager.NeutronManager.get_plugin() - self.assertEqual(plugin._network_admin_state(network), network) - - -class TestPlumgridAllocationPool(PLUMgridPluginV2TestCase): - def test_allocate_pools_for_subnet(self): - cidr = '10.0.0.0/24' - gateway_ip = '10.0.0.254' - subnet = {'gateway_ip': gateway_ip, - 'cidr': cidr, - 'ip_version': 4} - allocation_pool = [{"start": '10.0.0.2', - "end": '10.0.0.253'}] - context = None - plugin = manager.NeutronManager.get_plugin() - pool = plugin._allocate_pools_for_subnet(context, subnet) - self.assertEqual(allocation_pool, pool) - - -class TestPlumgridProvidernet(PLUMgridPluginV2TestCase): - - def test_create_provider_network(self): - tenant_id = 'admin' - data = {'network': {'name': 'net1', - 'admin_state_up': True, - 'tenant_id': tenant_id, - provider.NETWORK_TYPE: 'vlan', - provider.SEGMENTATION_ID: 3333, - provider.PHYSICAL_NETWORK: 'phy3333'}} - - network_req = self.new_create_request('networks', data, self.fmt) - net = self.deserialize(self.fmt, network_req.get_response(self.api)) - plumlib = importutils.import_object(PLUM_DRIVER) - plumlib.create_network(tenant_id, net, data) - self.assertEqual(net['network'][provider.NETWORK_TYPE], 'vlan') - self.assertEqual(net['network'][provider.SEGMENTATION_ID], 3333) - self.assertEqual(net['network'][provider.PHYSICAL_NETWORK], 'phy3333') - - -class TestDisassociateFloatingIP(PLUMgridPluginV2TestCase): - - def test_disassociate_floating_ip(self): - port_id = "abcdefgh" - tenant_id = "94eb42de4e331" - fip_net_id = "b843d18245678" - fip_addr = "10.0.3.44" - fip_id = "e623679734051" - fip = {"router_id": "94eb42de4e331", - "tenant_id": tenant_id, - "floating_network_id": fip_net_id, - "fixed_ip_address": "192.168.8.2", - "floating_ip_address": fip_addr, - "port_id": port_id, - "id": fip_id} - plumlib = importutils.import_object(PLUM_DRIVER) - fip_res = plumlib.disassociate_floatingips(fip, port_id) - self.assertEqual(fip_res["id"], fip_id) - self.assertEqual(fip_res["floating_ip_address"], fip_addr) - self.assertEqual(fip_res["floating_network_id"], fip_net_id) diff --git a/neutron/tests/unit/ryu/__init__.py b/neutron/tests/unit/ryu/__init__.py deleted file mode 100644 index 7e503debd..000000000 --- a/neutron/tests/unit/ryu/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/ryu/fake_ryu.py b/neutron/tests/unit/ryu/fake_ryu.py deleted file mode 100644 index 994748f80..000000000 --- a/neutron/tests/unit/ryu/fake_ryu.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 - - -def patch_fake_ryu_client(): - ryu_mod = mock.Mock() - ryu_app_mod = ryu_mod.app - ryu_app_client = ryu_app_mod.client - conf_switch_key = ryu_app_mod.conf_switch_key - conf_switch_key.OVSDB_ADDR = 'ovsdb_addr' - conf_switch_key.OVS_TUNNEL_ADDR = 'ovs_tunnel_addr' - rest_nw_id = ryu_app_mod.rest_nw_id - rest_nw_id.NW_ID_EXTERNAL = '__NW_ID_EXTERNAL__' - rest_nw_id.NW_ID_RESERVED = '__NW_ID_RESERVED__' - rest_nw_id.NW_ID_VPORT_GRE = '__NW_ID_VPORT_GRE__' - rest_nw_id.NW_ID_UNKNOWN = '__NW_ID_UNKNOWN__' - rest_nw_id.RESERVED_NETWORK_IDS = [ - rest_nw_id.NW_ID_EXTERNAL, - rest_nw_id.NW_ID_RESERVED, - rest_nw_id.NW_ID_VPORT_GRE, - rest_nw_id.NW_ID_UNKNOWN, - ] - return mock.patch.dict('sys.modules', - {'ryu': ryu_mod, - 'ryu.app': ryu_app_mod, - 'ryu.app.client': ryu_app_client, - 'ryu.app.conf_switch_key': conf_switch_key, - 'ryu.app.rest_nw_id': rest_nw_id}) diff --git a/neutron/tests/unit/ryu/test_defaults.py b/neutron/tests/unit/ryu/test_defaults.py deleted file mode 100644 index 8e840f48a..000000000 --- a/neutron/tests/unit/ryu/test_defaults.py +++ /dev/null @@ -1,33 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012 Isaku Yamahata -# All Rights Reserved. -# -# 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. - -from oslo.config import cfg - -from neutron.plugins.ryu.common import config # noqa -from neutron.tests import base - - -class ConfigurationTest(base.BaseTestCase): - """Configuration file Tests.""" - def test_defaults(self): - self.assertEqual('br-int', cfg.CONF.OVS.integration_bridge) - self.assertEqual(2, cfg.CONF.AGENT.polling_interval) - self.assertEqual('sudo', cfg.CONF.AGENT.root_helper) - self.assertEqual('127.0.0.1:8080', cfg.CONF.OVS.openflow_rest_api) - self.assertEqual(1, cfg.CONF.OVS.tunnel_key_min) - self.assertEqual(0xffffff, cfg.CONF.OVS.tunnel_key_max) - self.assertEqual(6634, cfg.CONF.OVS.ovsdb_port) diff --git a/neutron/tests/unit/ryu/test_ryu_agent.py b/neutron/tests/unit/ryu/test_ryu_agent.py deleted file mode 100644 index 756b39d04..000000000 --- a/neutron/tests/unit/ryu/test_ryu_agent.py +++ /dev/null @@ -1,651 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 contextlib -import httplib - -import mock - -from neutron.openstack.common import importutils -from neutron.tests import base -from neutron.tests.unit.ryu import fake_ryu - - -class RyuAgentTestCase(base.BaseTestCase): - - _AGENT_NAME = 'neutron.plugins.ryu.agent.ryu_neutron_agent' - - def setUp(self): - super(RyuAgentTestCase, self).setUp() - self.fake_ryu = fake_ryu.patch_fake_ryu_client().start() - self.mod_agent = importutils.import_module(self._AGENT_NAME) - - -class TestOVSNeutronOFPRyuAgent(RyuAgentTestCase): - def setUp(self): - super(TestOVSNeutronOFPRyuAgent, self).setUp() - self.plugin_api = mock.patch( - self._AGENT_NAME + '.RyuPluginApi').start() - self.ovsbridge = mock.patch( - self._AGENT_NAME + '.OVSBridge').start() - self.vifportset = mock.patch( - self._AGENT_NAME + '.VifPortSet').start() - self.q_ctx = mock.patch( - self._AGENT_NAME + '.q_context').start() - self.agent_rpc = mock.patch( - self._AGENT_NAME + '.agent_rpc.create_consumers').start() - self.sg_rpc = mock.patch( - self._AGENT_NAME + '.sg_rpc').start() - self.sg_agent = mock.patch( - self._AGENT_NAME + '.RyuSecurityGroupAgent').start() - - def mock_rest_addr(self, rest_addr): - integ_br = 'integ_br' - tunnel_ip = '192.168.0.1' - ovsdb_ip = '172.16.0.1' - ovsdb_port = 16634 - interval = 2 - root_helper = 'helper' - - self.mod_agent.OVSBridge.return_value.datapath_id = '1234' - - mock_context = mock.Mock(return_value='abc') - self.q_ctx.get_admin_context_without_session = mock_context - - mock_rest_addr = mock.Mock(return_value=rest_addr) - self.plugin_api.return_value.get_ofp_rest_api_addr = mock_rest_addr - - # Instantiate OVSNeutronOFPRyuAgent - return self.mod_agent.OVSNeutronOFPRyuAgent( - integ_br, tunnel_ip, ovsdb_ip, ovsdb_port, interval, root_helper) - - def test_valid_rest_addr(self): - self.mock_rest_addr('192.168.0.1:8080') - - # OVSBridge - self.ovsbridge.assert_has_calls([ - mock.call('integ_br', 'helper'), - mock.call().find_datapath_id() - ]) - - # RyuPluginRpc - self.plugin_api.assert_has_calls([ - mock.call('q-plugin'), - mock.call().get_ofp_rest_api_addr('abc') - ]) - - # Agent RPC - self.agent_rpc.assert_has_calls([ - mock.call(mock.ANY, 'q-agent-notifier', mock.ANY) - ]) - - # OFPClient - self.mod_agent.client.OFPClient.assert_has_calls([ - mock.call('192.168.0.1:8080') - ]) - - # VifPortSet - self.vifportset.assert_has_calls([ - mock.call( - self.ovsbridge.return_value, - self.mod_agent.client.OFPClient.return_value), - mock.call().setup() - ]) - - # SwitchConfClient - self.mod_agent.client.SwitchConfClient.assert_has_calls([ - mock.call('192.168.0.1:8080'), - mock.call().set_key('1234', 'ovs_tunnel_addr', '192.168.0.1'), - mock.call().set_key('1234', 'ovsdb_addr', - 'tcp:%s:%d' % ('172.16.0.1', 16634)) - ]) - - # OVSBridge - self.ovsbridge.return_value.set_manager.assert_has_calls([ - mock.call('ptcp:%d' % 16634) - ]) - - def test_invalid_rest_addr(self): - self.assertRaises(self.mod_agent.n_exc.Invalid, - self.mock_rest_addr, ('')) - - def mock_port_update(self, **kwargs): - agent = self.mock_rest_addr('192.168.0.1:8080') - agent.port_update(mock.Mock(), **kwargs) - - def test_port_update(self, **kwargs): - port = {'id': 1, 'security_groups': 'default'} - - with mock.patch.object(self.ovsbridge.return_value, - 'get_vif_port_by_id', - return_value=1) as get_vif: - self.mock_port_update(port=port) - - get_vif.assert_called_once_with(1) - self.sg_agent.assert_has_calls([ - mock.call().refresh_firewall() - ]) - - def test_port_update_not_vifport(self, **kwargs): - port = {'id': 1, 'security_groups': 'default'} - - with mock.patch.object(self.ovsbridge.return_value, - 'get_vif_port_by_id', - return_value=0) as get_vif: - self.mock_port_update(port=port) - - get_vif.assert_called_once_with(1) - self.assertFalse(self.sg_agent.return_value.refresh_firewall.called) - - def test_port_update_without_secgroup(self, **kwargs): - port = {'id': 1} - - with mock.patch.object(self.ovsbridge.return_value, - 'get_vif_port_by_id', - return_value=1) as get_vif: - self.mock_port_update(port=port) - - get_vif.assert_called_once_with(1) - self.assertFalse(self.sg_agent.return_value.refresh_firewall.called) - - def mock_update_ports(self, vif_port_set=None, registered_ports=None): - with mock.patch.object(self.ovsbridge.return_value, - 'get_vif_port_set', - return_value=vif_port_set): - agent = self.mock_rest_addr('192.168.0.1:8080') - return agent._update_ports(registered_ports) - - def test_update_ports_unchanged(self): - self.assertIsNone(self.mock_update_ports()) - - def test_update_ports_changed(self): - vif_port_set = set([1, 3]) - registered_ports = set([1, 2]) - expected = dict(current=vif_port_set, - added=set([3]), - removed=set([2])) - - actual = self.mock_update_ports(vif_port_set, registered_ports) - - self.assertEqual(expected, actual) - - def mock_process_devices_filter(self, port_info): - agent = self.mock_rest_addr('192.168.0.1:8080') - agent._process_devices_filter(port_info) - - def test_process_devices_filter_add(self): - port_info = {'added': 1} - - self.mock_process_devices_filter(port_info) - - self.sg_agent.assert_has_calls([ - mock.call().prepare_devices_filter(1) - ]) - - def test_process_devices_filter_remove(self): - port_info = {'removed': 2} - - self.mock_process_devices_filter(port_info) - - self.sg_agent.assert_has_calls([ - mock.call().remove_devices_filter(2) - ]) - - def test_process_devices_filter_both(self): - port_info = {'added': 1, 'removed': 2} - - self.mock_process_devices_filter(port_info) - - self.sg_agent.assert_has_calls([ - mock.call().prepare_devices_filter(1), - mock.call().remove_devices_filter(2) - ]) - - def test_process_devices_filter_none(self): - port_info = {} - - self.mock_process_devices_filter(port_info) - - self.assertFalse( - self.sg_agent.return_value.prepare_devices_filter.called) - self.assertFalse( - self.sg_agent.return_value.remove_devices_filter.called) - - -class TestRyuPluginApi(RyuAgentTestCase): - def test_get_ofp_rest_api_addr(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.RyuPluginApi.make_msg', - return_value='msg'), - mock.patch(self._AGENT_NAME + '.RyuPluginApi.call', - return_value='10.0.0.1') - ) as (mock_msg, mock_call): - api = self.mod_agent.RyuPluginApi('topics') - addr = api.get_ofp_rest_api_addr('context') - - self.assertEqual(addr, '10.0.0.1') - mock_msg.assert_has_calls([ - mock.call('get_ofp_rest_api') - ]) - mock_call.assert_has_calls([ - mock.call('context', 'msg', topic='topics') - ]) - - -class TestVifPortSet(RyuAgentTestCase): - def test_setup(self): - attrs = {'switch.datapath_id': 'dp1', 'ofport': 'p1'} - p1 = mock.Mock(**attrs) - attrs = {'switch.datapath_id': 'dp2', 'ofport': 'p2'} - p2 = mock.Mock(**attrs) - attrs = {'get_external_ports.return_value': [p1, p2]} - int_br = mock.Mock(**attrs) - with mock.patch(self._AGENT_NAME + '.client.OFPClient') as client: - api = client() - vif = self.mod_agent.VifPortSet(int_br, api) - vif.setup() - - client.assert_has_calls([ - mock.call().update_port('__NW_ID_EXTERNAL__', 'dp1', 'p1'), - mock.call().update_port('__NW_ID_EXTERNAL__', 'dp2', 'p2') - ]) - - def test_setup_empty(self): - attrs = {'get_external_ports.return_value': []} - int_br = mock.Mock(**attrs) - api = mock.Mock() - - vif = self.mod_agent.VifPortSet(int_br, api) - vif.setup() - - self.assertEqual(api.update_port.call_count, 0) - - -class TestOVSBridge(RyuAgentTestCase): - def setUp(self): - super(TestOVSBridge, self).setUp() - self.lib_ovs = mock.patch( - 'neutron.agent.linux.ovs_lib.OVSBridge').start() - - def test_find_datapath_id(self): - with mock.patch(self._AGENT_NAME + '.OVSBridge.get_datapath_id', - return_value='1234') as mock_get_dpid: - br = self.mod_agent.OVSBridge('br_name', 'helper') - br.find_datapath_id() - - mock_get_dpid.assert_has_calls([ - mock.call() - ]) - self.assertEqual(br.datapath_id, '1234') - - def test_set_manager(self): - with mock.patch( - self._AGENT_NAME + '.OVSBridge.run_vsctl') as mock_vsctl: - br = self.mod_agent.OVSBridge('br_name', 'helper') - br.set_manager('target') - - mock_vsctl.assert_has_calls([ - mock.call(['set-manager', 'target']) - ]) - - def test_get_ofport(self): - with mock.patch( - self._AGENT_NAME + '.OVSBridge.db_get_val', - return_value=1) as mock_db: - br = self.mod_agent.OVSBridge('br_name', 'helper') - ofport = br.get_ofport('name') - - mock_db.assert_has_calls([ - mock.call('Interface', 'name', 'ofport') - ]) - self.assertEqual(ofport, 1) - - def test_get_ports(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.OVSBridge.get_port_name_list', - return_value=['p1', 'p2']), - mock.patch(self._AGENT_NAME + '.OVSBridge.get_ofport', - return_value=1) - ) as (mock_name, mock_ofport): - get_port = mock.Mock(side_effect=['port1', 'port2']) - br = self.mod_agent.OVSBridge('br_name', 'helper') - ports = br._get_ports(get_port) - - mock_name.assert_has_calls([ - mock.call() - ]) - mock_ofport.assert_has_calls([ - mock.call('p1'), - mock.call('p2') - ]) - get_port.assert_has_calls([ - mock.call('p1'), - mock.call('p2') - ]) - self.assertEqual(len(ports), 2) - self.assertEqual(ports, ['port1', 'port2']) - - def test_get_ports_empty(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.OVSBridge.get_port_name_list', - return_value=[]), - mock.patch(self._AGENT_NAME + '.OVSBridge.get_ofport', - return_value=1) - ) as (mock_name, mock_ofport): - get_port = mock.Mock(side_effect=['port1', 'port2']) - br = self.mod_agent.OVSBridge('br_name', 'helper') - ports = br._get_ports(get_port) - - mock_name.assert_has_calls([ - mock.call() - ]) - self.assertEqual(mock_ofport.call_count, 0) - self.assertEqual(get_port.call_count, 0) - self.assertEqual(len(ports), 0) - - def test_get_ports_invalid_ofport(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.OVSBridge.get_port_name_list', - return_value=['p1', 'p2']), - mock.patch(self._AGENT_NAME + '.OVSBridge.get_ofport', - side_effect=[-1, 1]) - ) as (mock_name, mock_ofport): - get_port = mock.Mock(side_effect=['port1', 'port2']) - br = self.mod_agent.OVSBridge('br_name', 'helper') - ports = br._get_ports(get_port) - - mock_name.assert_has_calls([ - mock.call() - ]) - mock_ofport.assert_has_calls([ - mock.call('p1'), - mock.call('p2') - ]) - get_port.assert_has_calls([ - mock.call('p2') - ]) - self.assertEqual(len(ports), 1) - self.assertEqual(ports, ['port1']) - - def test_get_ports_invalid_port(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.OVSBridge.get_port_name_list', - return_value=['p1', 'p2']), - mock.patch(self._AGENT_NAME + '.OVSBridge.get_ofport', - side_effect=[1, 2]) - ) as (mock_name, mock_ofport): - get_port = mock.Mock(side_effect=[None, 'port2']) - br = self.mod_agent.OVSBridge('br_name', 'helper') - ports = br._get_ports(get_port) - - mock_name.assert_has_calls([ - mock.call() - ]) - mock_ofport.assert_has_calls([ - mock.call('p1'), - mock.call('p2') - ]) - get_port.assert_has_calls([ - mock.call('p1'), - mock.call('p2') - ]) - self.assertEqual(len(ports), 1) - self.assertEqual(ports, ['port2']) - - def test_get_external_port(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.OVSBridge.db_get_map', - side_effect=[None, {'opts': 'opts_val'}]), - mock.patch(self._AGENT_NAME + '.OVSBridge.get_ofport', - return_value=1), - mock.patch('neutron.agent.linux.ovs_lib.VifPort') - ) as (mock_db, mock_ofport, mock_vif): - br = self.mod_agent.OVSBridge('br_name', 'helper') - vifport = br._get_external_port('iface') - - mock_db.assert_has_calls([ - mock.call('Interface', 'iface', 'external_ids'), - mock.call('Interface', 'iface', 'options'), - ]) - mock_ofport.assert_has_calls([ - mock.call('iface') - ]) - mock_vif.assert_has_calls([ - mock.call('iface', 1, None, None, br) - ]) - self.assertEqual(vifport, mock_vif.return_value) - - def test_get_external_port_vmport(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.OVSBridge.db_get_map', - side_effect=[{'extids': 'extid_val'}, - {'opts': 'opts_val'}]), - mock.patch(self._AGENT_NAME + '.OVSBridge.get_ofport', - return_value=1), - mock.patch('neutron.agent.linux.ovs_lib.VifPort') - ) as (mock_db, mock_ofport, mock_vif): - br = self.mod_agent.OVSBridge('br_name', 'helper') - vifport = br._get_external_port('iface') - - mock_db.assert_has_calls([ - mock.call('Interface', 'iface', 'external_ids'), - ]) - self.assertEqual(mock_ofport.call_count, 0) - self.assertEqual(mock_vif.call_count, 0) - self.assertIsNone(vifport) - - def test_get_external_port_tunnel(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.OVSBridge.db_get_map', - side_effect=[None, {'remote_ip': '0.0.0.0'}]), - mock.patch(self._AGENT_NAME + '.OVSBridge.get_ofport', - return_value=1), - mock.patch('neutron.agent.linux.ovs_lib.VifPort') - ) as (mock_db, mock_ofport, mock_vif): - br = self.mod_agent.OVSBridge('br_name', 'helper') - vifport = br._get_external_port('iface') - - mock_db.assert_has_calls([ - mock.call('Interface', 'iface', 'external_ids'), - mock.call('Interface', 'iface', 'options'), - ]) - self.assertEqual(mock_ofport.call_count, 0) - self.assertEqual(mock_vif.call_count, 0) - self.assertIsNone(vifport) - - def test_get_external_ports(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.OVSBridge._get_external_port'), - mock.patch(self._AGENT_NAME + '.OVSBridge._get_ports') - ) as (mock_extport, mock_port): - br = self.mod_agent.OVSBridge('br_name', 'helper') - br.get_external_ports() - - mock_port.assert_has_calls([ - mock.call(mock_extport) - ]) - - -class TestRyuNeutronAgent(RyuAgentTestCase): - def test_get_my_ip(self): - sock_attrs = { - 'return_value.getsockname.return_value': ['1.2.3.4', '']} - with mock.patch('socket.socket', **sock_attrs): - addr = self.mod_agent._get_my_ip() - - self.assertEqual(addr, '1.2.3.4') - - def test_get_ip_from_nic(self): - mock_device = mock.Mock() - mock_device.addr.list = mock.Mock( - return_value=[{'ip_version': 6, 'cidr': '::ffff:1.2.3.4'}, - {'ip_version': 4, 'cidr': '1.2.3.4/8'}]) - mock_ip_wrapper = mock.Mock() - mock_ip_wrapper.device = mock.Mock(return_value=mock_device) - with mock.patch(self._AGENT_NAME + '.ip_lib.IPWrapper', - return_value=mock_ip_wrapper): - addr = self.mod_agent._get_ip_from_nic('eth0') - - self.assertEqual(addr, '1.2.3.4') - - def test_get_ip_from_nic_empty(self): - mock_device = mock.Mock() - mock_device.addr.list = mock.Mock(return_value=[]) - mock_ip_wrapper = mock.Mock() - mock_ip_wrapper.device = mock.Mock(return_value=mock_device) - with mock.patch(self._AGENT_NAME + '.ip_lib.IPWrapper', - return_value=mock_ip_wrapper): - addr = self.mod_agent._get_ip_from_nic('eth0') - - self.assertIsNone(addr) - - def test_get_ip_ip(self): - cfg_attrs = {'CONF.OVS.cfg_ip': '1.2.3.4', - 'CONF.OVS.cfg_iface': 'eth0'} - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.cfg', **cfg_attrs), - mock.patch(self._AGENT_NAME + '._get_ip_from_nic', - return_value='10.0.0.1'), - mock.patch(self._AGENT_NAME + '._get_my_ip', - return_value='172.16.0.1') - ) as (_cfg, mock_nicip, mock_myip): - ip = self.mod_agent._get_ip('cfg_ip', 'cfg_iface') - - self.assertEqual(mock_nicip.call_count, 0) - self.assertEqual(mock_myip.call_count, 0) - self.assertEqual(ip, '1.2.3.4') - - def test_get_ip_nic(self): - cfg_attrs = {'CONF.OVS.cfg_ip': None, - 'CONF.OVS.cfg_iface': 'eth0'} - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.cfg', **cfg_attrs), - mock.patch(self._AGENT_NAME + '._get_ip_from_nic', - return_value='10.0.0.1'), - mock.patch(self._AGENT_NAME + '._get_my_ip', - return_value='172.16.0.1') - ) as (_cfg, mock_nicip, mock_myip): - ip = self.mod_agent._get_ip('cfg_ip', 'cfg_iface') - - mock_nicip.assert_has_calls([ - mock.call('eth0') - ]) - self.assertEqual(mock_myip.call_count, 0) - self.assertEqual(ip, '10.0.0.1') - - def test_get_ip_myip(self): - cfg_attrs = {'CONF.OVS.cfg_ip': None, - 'CONF.OVS.cfg_iface': None} - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.cfg', **cfg_attrs), - mock.patch(self._AGENT_NAME + '._get_ip_from_nic', - return_value='10.0.0.1'), - mock.patch(self._AGENT_NAME + '._get_my_ip', - return_value='172.16.0.1') - ) as (_cfg, mock_nicip, mock_myip): - ip = self.mod_agent._get_ip('cfg_ip', 'cfg_iface') - - self.assertEqual(mock_nicip.call_count, 0) - mock_myip.assert_has_calls([ - mock.call() - ]) - self.assertEqual(ip, '172.16.0.1') - - def test_get_ip_nic_myip(self): - cfg_attrs = {'CONF.OVS.cfg_ip': None, - 'CONF.OVS.cfg_iface': 'eth0'} - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.cfg', **cfg_attrs), - mock.patch(self._AGENT_NAME + '._get_ip_from_nic', - return_value=None), - mock.patch(self._AGENT_NAME + '._get_my_ip', - return_value='172.16.0.1') - ) as (_cfg, mock_nicip, mock_myip): - ip = self.mod_agent._get_ip('cfg_ip', 'cfg_iface') - - mock_nicip.assert_has_calls([ - mock.call('eth0') - ]) - mock_myip.assert_has_calls([ - mock.call() - ]) - self.assertEqual(ip, '172.16.0.1') - - def test_get_tunnel_ip(self): - with mock.patch(self._AGENT_NAME + '._get_ip', - return_value='1.2.3.4') as mock_getip: - ip = self.mod_agent._get_tunnel_ip() - - mock_getip.assert_has_calls([ - mock.call('tunnel_ip', 'tunnel_interface') - ]) - self.assertEqual(ip, '1.2.3.4') - - def test_get_ovsdb_ip(self): - with mock.patch(self._AGENT_NAME + '._get_ip', - return_value='1.2.3.4') as mock_getip: - ip = self.mod_agent._get_ovsdb_ip() - - mock_getip.assert_has_calls([ - mock.call('ovsdb_ip', 'ovsdb_interface') - ]) - self.assertEqual(ip, '1.2.3.4') - - def mock_main(self): - cfg_attrs = {'CONF.OVS.integration_bridge': 'integ_br', - 'CONF.OVS.ovsdb_port': 16634, - 'CONF.AGENT.polling_interval': 2, - 'CONF.AGENT.root_helper': 'helper'} - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.cfg', **cfg_attrs), - mock.patch(self._AGENT_NAME + '.common_config'), - mock.patch(self._AGENT_NAME + '._get_tunnel_ip', - return_value='10.0.0.1'), - mock.patch(self._AGENT_NAME + '._get_ovsdb_ip', - return_value='172.16.0.1'), - ) as (mock_conf, mock_common_conf, _tun, _ovsdb): - self.mod_agent.main() - - mock_common_conf.assert_has_calls([ - mock.call(mock_conf) - ]) - - def test_main(self): - agent_attrs = {'daemon_loop.side_effect': SystemExit(0)} - with mock.patch(self._AGENT_NAME + '.OVSNeutronOFPRyuAgent', - **agent_attrs) as mock_agent: - self.assertRaises(SystemExit, self.mock_main) - - mock_agent.assert_has_calls([ - mock.call('integ_br', '10.0.0.1', '172.16.0.1', 16634, 2, - 'helper'), - mock.call().daemon_loop() - ]) - - def test_main_raise(self): - with contextlib.nested( - mock.patch(self._AGENT_NAME + '.OVSNeutronOFPRyuAgent', - side_effect=httplib.HTTPException('boom')), - mock.patch('sys.exit', side_effect=SystemExit(0)) - ) as (mock_agent, mock_exit): - self.assertRaises(SystemExit, self.mock_main) - - mock_agent.assert_has_calls([ - mock.call('integ_br', '10.0.0.1', '172.16.0.1', 16634, 2, - 'helper') - ]) - mock_exit.assert_has_calls([ - mock.call(1) - ]) diff --git a/neutron/tests/unit/ryu/test_ryu_db.py b/neutron/tests/unit/ryu/test_ryu_db.py deleted file mode 100644 index 3dd49fcc8..000000000 --- a/neutron/tests/unit/ryu/test_ryu_db.py +++ /dev/null @@ -1,57 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012 Isaku Yamahata -# All Rights Reserved. -# -# 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 contextlib -import operator - -from neutron.db import api as db -from neutron.plugins.ryu.common import config # noqa -from neutron.plugins.ryu.db import api_v2 as db_api_v2 -from neutron.plugins.ryu.db import models_v2 as ryu_models_v2 # noqa -from neutron.tests.unit import test_db_plugin as test_plugin - - -class RyuDBTest(test_plugin.NeutronDbPluginV2TestCase): - @staticmethod - def _tunnel_key_sort(key_list): - key_list.sort(key=operator.attrgetter('tunnel_key')) - return [(key.network_id, key.tunnel_key) for key in key_list] - - def test_key_allocation(self): - tunnel_key = db_api_v2.TunnelKey() - session = db.get_session() - with contextlib.nested(self.network('network-0'), - self.network('network-1') - ) as (network_0, network_1): - network_id0 = network_0['network']['id'] - key0 = tunnel_key.allocate(session, network_id0) - network_id1 = network_1['network']['id'] - key1 = tunnel_key.allocate(session, network_id1) - key_list = tunnel_key.all_list() - self.assertEqual(len(key_list), 2) - - expected_list = [(network_id0, key0), (network_id1, key1)] - self.assertEqual(self._tunnel_key_sort(key_list), - expected_list) - - tunnel_key.delete(session, network_id0) - key_list = tunnel_key.all_list() - self.assertEqual(self._tunnel_key_sort(key_list), - [(network_id1, key1)]) - - tunnel_key.delete(session, network_id1) - self.assertEqual(tunnel_key.all_list(), []) diff --git a/neutron/tests/unit/ryu/test_ryu_plugin.py b/neutron/tests/unit/ryu/test_ryu_plugin.py deleted file mode 100644 index e0dfe283e..000000000 --- a/neutron/tests/unit/ryu/test_ryu_plugin.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 neutron import manager -from neutron.plugins.ryu.db import models_v2 as ryu_models_v2 # noqa -from neutron.tests.unit.ryu import fake_ryu -from neutron.tests.unit import test_db_plugin as test_plugin - - -class RyuPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - - _plugin_name = 'neutron.plugins.ryu.ryu_neutron_plugin.RyuNeutronPluginV2' - - def setUp(self): - self.ryu_patcher = fake_ryu.patch_fake_ryu_client() - self.ryu_patcher.start() - super(RyuPluginV2TestCase, self).setUp(self._plugin_name) - self.addCleanup(self.ryu_patcher.stop) - plugin = manager.NeutronManager.get_plugin() - plugin.notifier = mock.Mock() - - -class TestRyuBasicGet(test_plugin.TestBasicGet, RyuPluginV2TestCase): - pass - - -class TestRyuV2HTTPResponse(test_plugin.TestV2HTTPResponse, - RyuPluginV2TestCase): - pass - - -class TestRyuPortsV2(test_plugin.TestPortsV2, RyuPluginV2TestCase): - pass - - -class TestRyuNetworksV2(test_plugin.TestNetworksV2, RyuPluginV2TestCase): - pass diff --git a/neutron/tests/unit/ryu/test_ryu_security_group.py b/neutron/tests/unit/ryu/test_ryu_security_group.py deleted file mode 100644 index a023136ef..000000000 --- a/neutron/tests/unit/ryu/test_ryu_security_group.py +++ /dev/null @@ -1,92 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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 contextlib - -import mock - -from neutron.api.v2 import attributes -from neutron.extensions import securitygroup as ext_sg -from neutron import manager -from neutron.tests.unit.ryu import fake_ryu -from neutron.tests.unit import test_extension_security_group as test_sg -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - -PLUGIN_NAME = ('neutron.plugins.ryu.' - 'ryu_neutron_plugin.RyuNeutronPluginV2') -NOTIFIER = ('neutron.plugins.ryu.' - 'ryu_neutron_plugin.AgentNotifierApi') - - -class RyuSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self, plugin=None): - test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER) - self.fake_ryu = fake_ryu.patch_fake_ryu_client().start() - self.notifier = mock.patch(NOTIFIER).start().return_value - self._attribute_map_bk_ = {} - for item in attributes.RESOURCE_ATTRIBUTE_MAP: - self._attribute_map_bk_[item] = (attributes. - RESOURCE_ATTRIBUTE_MAP[item]. - copy()) - super(RyuSecurityGroupsTestCase, self).setUp(PLUGIN_NAME) - - def tearDown(self): - super(RyuSecurityGroupsTestCase, self).tearDown() - attributes.RESOURCE_ATTRIBUTE_MAP = self._attribute_map_bk_ - - -class TestRyuSecurityGroups(RyuSecurityGroupsTestCase, - test_sg.TestSecurityGroups, - test_sg_rpc.SGNotificationTestMixin): - def test_security_group_get_port_from_device(self): - with contextlib.nested(self.network(), - self.security_group()) as (n, sg): - with self.subnet(n): - security_group_id = sg['security_group']['id'] - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - fixed_ips = port['port']['fixed_ips'] - data = {'port': {'fixed_ips': fixed_ips, - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: - [security_group_id]}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - port_id = res['port']['id'] - plugin = manager.NeutronManager.get_plugin() - port_dict = plugin.endpoints[0].get_port_from_device(port_id) - self.assertEqual(port_id, port_dict['id']) - self.assertEqual([security_group_id], - port_dict[ext_sg.SECURITYGROUPS]) - self.assertEqual([], port_dict['security_group_rules']) - self.assertEqual([fixed_ips[0]['ip_address']], - port_dict['fixed_ips']) - self._delete('ports', port_id) - - def test_security_group_get_port_from_device_with_no_port(self): - plugin = manager.NeutronManager.get_plugin() - port_dict = plugin.endpoints[0].get_port_from_device('bad_device_id') - self.assertIsNone(port_dict) - - -class TestRyuSecurityGroupsXML(TestRyuSecurityGroups): - fmt = 'xml' diff --git a/neutron/tests/unit/services/firewall/__init__.py b/neutron/tests/unit/services/firewall/__init__.py deleted file mode 100644 index cae279d0a..000000000 --- a/neutron/tests/unit/services/firewall/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack Foundation -# -# 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. diff --git a/neutron/tests/unit/services/firewall/agents/__init__.py b/neutron/tests/unit/services/firewall/agents/__init__.py deleted file mode 100644 index cae279d0a..000000000 --- a/neutron/tests/unit/services/firewall/agents/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack Foundation -# -# 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. diff --git a/neutron/tests/unit/services/firewall/agents/l3reference/__init__.py b/neutron/tests/unit/services/firewall/agents/l3reference/__init__.py deleted file mode 100644 index cae279d0a..000000000 --- a/neutron/tests/unit/services/firewall/agents/l3reference/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack Foundation -# -# 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. diff --git a/neutron/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py b/neutron/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py deleted file mode 100644 index 7daffce19..000000000 --- a/neutron/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py +++ /dev/null @@ -1,391 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# 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. -# -# @author: Sumit Naiksatam, sumitnaiksatam@gmail.com, Big Switch Networks, Inc. -# @author: Sridar Kandaswamy, skandasw@cisco.com, Cisco Systems, Inc. -# @author: Dan Florea, dflorea@cisco.com, Cisco Systems, Inc. - -import contextlib -import uuid - -import mock -from oslo.config import cfg - -from neutron.agent.common import config as agent_config -from neutron.agent import l3_agent -from neutron.agent.linux import ip_lib -from neutron.common import config as base_config -from neutron import context -from neutron.plugins.common import constants -from neutron.services.firewall.agents.l3reference import firewall_l3_agent -from neutron.tests import base -from neutron.tests.unit.services.firewall.agents import test_firewall_agent_api - - -class FWaasHelper(object): - def __init__(self, host): - pass - - -class FWaasAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, FWaasHelper): - def __init__(self, conf=None): - super(FWaasAgent, self).__init__(conf) - - -class TestFwaasL3AgentRpcCallback(base.BaseTestCase): - def setUp(self): - super(TestFwaasL3AgentRpcCallback, self).setUp() - - self.conf = cfg.ConfigOpts() - self.conf.register_opts(base_config.core_opts) - self.conf.register_opts(l3_agent.L3NATAgent.OPTS) - agent_config.register_use_namespaces_opts_helper(self.conf) - agent_config.register_root_helper(self.conf) - self.conf.root_helper = 'sudo' - self.api = FWaasAgent(self.conf) - self.api.fwaas_driver = test_firewall_agent_api.NoopFwaasDriver() - - def test_create_firewall(self): - fake_firewall = {'id': 0} - with mock.patch.object( - self.api, - '_invoke_driver_for_plugin_api' - ) as mock_driver: - self.assertEqual( - self.api.create_firewall( - mock.sentinel.context, - fake_firewall, - 'host'), - mock_driver.return_value) - - def test_update_firewall(self): - fake_firewall = {'id': 0} - with mock.patch.object( - self.api, - '_invoke_driver_for_plugin_api' - ) as mock_driver: - self.assertEqual( - self.api.update_firewall( - mock.sentinel.context, - fake_firewall, - 'host'), - mock_driver.return_value) - - def test_delete_firewall(self): - fake_firewall = {'id': 0} - with mock.patch.object( - self.api, - '_invoke_driver_for_plugin_api' - ) as mock_driver: - self.assertEqual( - self.api.delete_firewall( - mock.sentinel.context, - fake_firewall, - 'host'), - mock_driver.return_value) - - def test_invoke_driver_for_plugin_api(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': True} - self.api.plugin_rpc = mock.Mock() - with contextlib.nested( - mock.patch.object(self.api.plugin_rpc, 'get_routers'), - mock.patch.object(self.api, '_get_router_info_list_for_tenant'), - mock.patch.object(self.api.fwaas_driver, 'create_firewall'), - mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status') - ) as ( - mock_get_routers, - mock_get_router_info_list_for_tenant, - mock_driver_create_firewall, - mock_set_firewall_status): - - mock_driver_create_firewall.return_value = True - self.api.create_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_get_routers.assert_called_once_with( - mock.sentinel.context) - - mock_get_router_info_list_for_tenant.assert_called_once_with( - mock_get_routers.return_value, fake_firewall['tenant_id']) - - mock_set_firewall_status.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id'], - 'ACTIVE') - - def test_invoke_driver_for_plugin_api_admin_state_down(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': False} - self.api.plugin_rpc = mock.Mock() - with contextlib.nested( - mock.patch.object(self.api.plugin_rpc, 'get_routers'), - mock.patch.object(self.api, '_get_router_info_list_for_tenant'), - mock.patch.object(self.api.fwaas_driver, 'update_firewall'), - mock.patch.object(self.api.fwplugin_rpc, - 'get_firewalls_for_tenant'), - mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status') - ) as ( - mock_get_routers, - mock_get_router_info_list_for_tenant, - mock_driver_update_firewall, - mock_get_firewalls_for_tenant, - mock_set_firewall_status): - - mock_driver_update_firewall.return_value = True - self.api.update_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_get_routers.assert_called_once_with( - mock.sentinel.context) - - mock_get_router_info_list_for_tenant.assert_called_once_with( - mock_get_routers.return_value, fake_firewall['tenant_id']) - - mock_set_firewall_status.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id'], - 'DOWN') - - def test_invoke_driver_for_plugin_api_delete(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': True} - self.api.plugin_rpc = mock.Mock() - with contextlib.nested( - mock.patch.object(self.api.plugin_rpc, 'get_routers'), - mock.patch.object(self.api, '_get_router_info_list_for_tenant'), - mock.patch.object(self.api.fwaas_driver, 'delete_firewall'), - mock.patch.object(self.api.fwplugin_rpc, 'firewall_deleted') - ) as ( - mock_get_routers, - mock_get_router_info_list_for_tenant, - mock_driver_delete_firewall, - mock_firewall_deleted): - - mock_driver_delete_firewall.return_value = True - self.api.delete_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_get_routers.assert_called_once_with( - mock.sentinel.context) - - mock_get_router_info_list_for_tenant.assert_called_once_with( - mock_get_routers.return_value, fake_firewall['tenant_id']) - - mock_firewall_deleted.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id']) - - def test_delete_firewall_no_router(self): - fake_firewall = {'id': 0, 'tenant_id': 1} - self.api.plugin_rpc = mock.Mock() - with contextlib.nested( - mock.patch.object(self.api.plugin_rpc, 'get_routers'), - mock.patch.object(self.api, '_get_router_info_list_for_tenant'), - mock.patch.object(self.api.fwplugin_rpc, 'firewall_deleted') - ) as ( - mock_get_routers, - mock_get_router_info_list_for_tenant, - mock_firewall_deleted): - - mock_get_router_info_list_for_tenant.return_value = [] - self.api.delete_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_get_routers.assert_called_once_with( - mock.sentinel.context) - - mock_get_router_info_list_for_tenant.assert_called_once_with( - mock_get_routers.return_value, fake_firewall['tenant_id']) - - mock_firewall_deleted.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id']) - - def test_process_router_add_fw_update(self): - fake_firewall_list = [{'id': 0, 'tenant_id': 1, - 'status': constants.PENDING_UPDATE, - 'admin_state_up': True}] - fake_router = {'id': 1111, 'tenant_id': 2} - self.api.plugin_rpc = mock.Mock() - ri = mock.Mock() - ri.router = fake_router - routers = [ri.router] - with contextlib.nested( - mock.patch.object(self.api.plugin_rpc, 'get_routers'), - mock.patch.object(self.api, '_get_router_info_list_for_tenant'), - mock.patch.object(self.api.fwaas_driver, 'update_firewall'), - mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status'), - mock.patch.object(self.api.fwplugin_rpc, - 'get_firewalls_for_tenant'), - mock.patch.object(context, 'Context') - ) as ( - mock_get_routers, - mock_get_router_info_list_for_tenant, - mock_driver_update_firewall, - mock_set_firewall_status, - mock_get_firewalls_for_tenant, - mock_Context): - - mock_driver_update_firewall.return_value = True - ctx = mock.sentinel.context - mock_Context.return_value = ctx - mock_get_router_info_list_for_tenant.return_value = routers - mock_get_firewalls_for_tenant.return_value = fake_firewall_list - - self.api._process_router_add(ri) - mock_get_router_info_list_for_tenant.assert_called_with( - routers, - ri.router['tenant_id']) - mock_get_firewalls_for_tenant.assert_called_once_with(ctx) - mock_driver_update_firewall.assert_called_once_with( - routers, - fake_firewall_list[0]) - - mock_set_firewall_status.assert_called_once_with( - ctx, - fake_firewall_list[0]['id'], - constants.ACTIVE) - - def test_process_router_add_fw_delete(self): - fake_firewall_list = [{'id': 0, 'tenant_id': 1, - 'status': constants.PENDING_DELETE}] - fake_router = {'id': 1111, 'tenant_id': 2} - self.api.plugin_rpc = mock.Mock() - ri = mock.Mock() - ri.router = fake_router - routers = [ri.router] - with contextlib.nested( - mock.patch.object(self.api.plugin_rpc, 'get_routers'), - mock.patch.object(self.api, '_get_router_info_list_for_tenant'), - mock.patch.object(self.api.fwaas_driver, 'delete_firewall'), - mock.patch.object(self.api.fwplugin_rpc, 'firewall_deleted'), - mock.patch.object(self.api.fwplugin_rpc, - 'get_firewalls_for_tenant'), - mock.patch.object(context, 'Context') - ) as ( - mock_get_routers, - mock_get_router_info_list_for_tenant, - mock_driver_delete_firewall, - mock_firewall_deleted, - mock_get_firewalls_for_tenant, - mock_Context): - - mock_driver_delete_firewall.return_value = True - ctx = mock.sentinel.context - mock_Context.return_value = ctx - mock_get_router_info_list_for_tenant.return_value = routers - mock_get_firewalls_for_tenant.return_value = fake_firewall_list - - self.api._process_router_add(ri) - mock_get_router_info_list_for_tenant.assert_called_with( - routers, - ri.router['tenant_id']) - mock_get_firewalls_for_tenant.assert_called_once_with(ctx) - mock_driver_delete_firewall.assert_called_once_with( - routers, - fake_firewall_list[0]) - - mock_firewall_deleted.assert_called_once_with( - ctx, - fake_firewall_list[0]['id']) - - def _prepare_router_data(self, use_namespaces): - router = {'id': str(uuid.uuid4()), 'tenant_id': str(uuid.uuid4())} - return l3_agent.RouterInfo(router['id'], self.conf.root_helper, - use_namespaces, router=router) - - def _get_router_info_list_with_namespace_helper(self, - router_use_namespaces): - self.conf.set_override('use_namespaces', True) - ri = self._prepare_router_data( - use_namespaces=router_use_namespaces) - routers = [ri.router] - self.api.router_info = {ri.router_id: ri} - with mock.patch.object(ip_lib.IPWrapper, - 'get_namespaces') as mock_get_namespaces: - mock_get_namespaces.return_value = ri.ns_name - router_info_list = self.api._get_router_info_list_for_tenant( - routers, - ri.router['tenant_id']) - self.assertEqual([ri], router_info_list) - mock_get_namespaces.assert_called_once_with( - self.conf.root_helper) - - def _get_router_info_list_without_namespace_helper(self, - router_use_namespaces): - self.conf.set_override('use_namespaces', False) - ri = self._prepare_router_data( - use_namespaces=router_use_namespaces) - routers = [ri.router] - self.api.router_info = {ri.router_id: ri} - router_info_list = self.api._get_router_info_list_for_tenant( - routers, - ri.router['tenant_id']) - if router_use_namespaces: - self.assertFalse(router_info_list) - else: - self.assertEqual([ri], router_info_list) - - def test_get_router_info_list_for_tenant_for_namespaces_enabled(self): - self._get_router_info_list_with_namespace_helper( - router_use_namespaces=True) - - def test_get_router_info_list_for_tenant_for_namespaces_disabled(self): - self._get_router_info_list_without_namespace_helper( - router_use_namespaces=False) - - def test_get_router_info_list_tenant_with_namespace_router_without(self): - self._get_router_info_list_with_namespace_helper( - router_use_namespaces=False) - - def test_get_router_info_list_tenant_without_namespace_router_with(self): - self._get_router_info_list_without_namespace_helper( - router_use_namespaces=True) - - def _get_router_info_list_router_without_router_info_helper(self, - rtr_with_ri): - self.conf.set_override('use_namespaces', True) - # ri.router with associated router_info (ri) - # rtr2 has no router_info - ri = self._prepare_router_data(use_namespaces=True) - rtr2 = {'id': str(uuid.uuid4()), 'tenant_id': ri.router['tenant_id']} - routers = [rtr2] - self.api.router_info = {} - ri_expected = [] - if rtr_with_ri: - self.api.router_info[ri.router_id] = ri - routers.append(ri.router) - ri_expected.append(ri) - with mock.patch.object(ip_lib.IPWrapper, - 'get_namespaces') as mock_get_namespaces: - mock_get_namespaces.return_value = ri.ns_name - router_info_list = self.api._get_router_info_list_for_tenant( - routers, - ri.router['tenant_id']) - self.assertEqual(ri_expected, router_info_list) - - def test_get_router_info_list_router_without_router_info(self): - self._get_router_info_list_router_without_router_info_helper( - rtr_with_ri=False) - - def test_get_router_info_list_two_routers_one_without_router_info(self): - self._get_router_info_list_router_without_router_info_helper( - rtr_with_ri=True) diff --git a/neutron/tests/unit/services/firewall/agents/test_firewall_agent_api.py b/neutron/tests/unit/services/firewall/agents/test_firewall_agent_api.py deleted file mode 100644 index 3b76c5af3..000000000 --- a/neutron/tests/unit/services/firewall/agents/test_firewall_agent_api.py +++ /dev/null @@ -1,105 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. -# -# @author: Sumit Naiksatam, sumitnaiksatam@gmail.com, Big Switch Networks, Inc. -# @author: Sridar Kandaswamy, skandasw@cisco.com, Cisco Systems, Inc. -# @author: Dan Florea, dflorea@cisco.com, Cisco Systems, Inc. - -import contextlib -import mock - -from neutron.services.firewall.agents import firewall_agent_api as api -from neutron.services.firewall.drivers import fwaas_base as base_driver -from neutron.tests import base - - -class NoopFwaasDriver(base_driver.FwaasDriverBase): - """Noop Fwaas Driver. - - Firewall driver which does nothing. - This driver is for disabling Fwaas functionality. - """ - - def create_firewall(self, apply_list, firewall): - pass - - def delete_firewall(self, apply_list, firewall): - pass - - def update_firewall(self, apply_list, firewall): - pass - - def apply_default_policy(self, apply_list, firewall): - pass - - -class TestFWaaSAgentApi(base.BaseTestCase): - def setUp(self): - super(TestFWaaSAgentApi, self).setUp() - - self.api = api.FWaaSPluginApiMixin( - 'topic', - 'host') - - def test_init(self): - self.assertEqual(self.api.host, 'host') - - def test_set_firewall_status(self): - with contextlib.nested( - mock.patch.object(self.api, 'make_msg'), - mock.patch.object(self.api, 'call') - ) as (mock_make_msg, mock_call): - - self.assertEqual( - self.api.set_firewall_status( - mock.sentinel.context, - 'firewall_id', - 'status'), - mock_call.return_value) - - mock_make_msg.assert_called_once_with( - 'set_firewall_status', - host='host', - firewall_id='firewall_id', - status='status') - - mock_call.assert_called_once_with( - mock.sentinel.context, - mock_make_msg.return_value, - topic='topic') - - def test_firewall_deleted(self): - with contextlib.nested( - mock.patch.object(self.api, 'make_msg'), - mock.patch.object(self.api, 'call') - ) as (mock_make_msg, mock_call): - - self.assertEqual( - self.api.firewall_deleted( - mock.sentinel.context, - 'firewall_id'), - mock_call.return_value) - - mock_make_msg.assert_called_once_with( - 'firewall_deleted', - host='host', - firewall_id='firewall_id') - - mock_call.assert_called_once_with( - mock.sentinel.context, - mock_make_msg.return_value, - topic='topic') diff --git a/neutron/tests/unit/services/firewall/agents/varmour/__init__.py b/neutron/tests/unit/services/firewall/agents/varmour/__init__.py deleted file mode 100755 index 5e8da711f..000000000 --- a/neutron/tests/unit/services/firewall/agents/varmour/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack Foundation. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/services/firewall/agents/varmour/test_varmour_router.py b/neutron/tests/unit/services/firewall/agents/varmour/test_varmour_router.py deleted file mode 100644 index 6a08e34b2..000000000 --- a/neutron/tests/unit/services/firewall/agents/varmour/test_varmour_router.py +++ /dev/null @@ -1,322 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 vArmour Networks Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Gary Duan, vArmour Networks Inc. -# - - -import mock -from oslo.config import cfg - -from neutron.agent.common import config as agent_config -from neutron.agent import l3_agent -from neutron.agent.linux import interface -from neutron.common import config as base_config -from neutron.common import constants as l3_constants -from neutron.openstack.common import uuidutils -from neutron.services.firewall.agents.varmour import varmour_router -from neutron.services.firewall.agents.varmour import varmour_utils -from neutron.tests import base - -_uuid = uuidutils.generate_uuid -HOSTNAME = 'myhost' -FAKE_DIRECTOR = '1.1.1.1' - - -class TestVarmourRouter(base.BaseTestCase): - - def setUp(self): - super(TestVarmourRouter, self).setUp() - self.conf = cfg.ConfigOpts() - self.conf.register_opts(base_config.core_opts) - self.conf.register_opts(varmour_router.vArmourL3NATAgent.OPTS) - agent_config.register_interface_driver_opts_helper(self.conf) - agent_config.register_use_namespaces_opts_helper(self.conf) - agent_config.register_root_helper(self.conf) - self.conf.register_opts(interface.OPTS) - self.conf.set_override('interface_driver', - 'neutron.agent.linux.interface.NullDriver') - self.conf.root_helper = 'sudo' - - self.device_exists_p = mock.patch( - 'neutron.agent.linux.ip_lib.device_exists') - self.device_exists = self.device_exists_p.start() - - self.utils_exec_p = mock.patch( - 'neutron.agent.linux.utils.execute') - self.utils_exec = self.utils_exec_p.start() - - self.external_process_p = mock.patch( - 'neutron.agent.linux.external_process.ProcessManager') - self.external_process = self.external_process_p.start() - - self.dvr_cls_p = mock.patch('neutron.agent.linux.interface.NullDriver') - driver_cls = self.dvr_cls_p.start() - self.mock_driver = mock.MagicMock() - self.mock_driver.DEV_NAME_LEN = ( - interface.LinuxInterfaceDriver.DEV_NAME_LEN) - driver_cls.return_value = self.mock_driver - - self.ip_cls_p = mock.patch('neutron.agent.linux.ip_lib.IPWrapper') - ip_cls = self.ip_cls_p.start() - self.mock_ip = mock.MagicMock() - ip_cls.return_value = self.mock_ip - - self.looping_call_p = mock.patch( - 'neutron.openstack.common.loopingcall.FixedIntervalLoopingCall') - self.looping_call_p.start() - - def _create_router(self): - router = varmour_router.vArmourL3NATAgent(HOSTNAME, self.conf) - router.rest.server = FAKE_DIRECTOR - router.rest.user = 'varmour' - router.rest.passwd = 'varmour' - return router - - def _del_all_internal_ports(self, router): - router[l3_constants.INTERFACE_KEY] = [] - - def _del_internal_ports(self, router, port_idx): - del router[l3_constants.INTERFACE_KEY][port_idx] - - def _add_internal_ports(self, router, port_count=1): - self._del_all_internal_ports(router) - for i in range(port_count): - port = {'id': _uuid(), - 'network_id': _uuid(), - 'admin_state_up': True, - 'fixed_ips': [{'ip_address': '10.0.%s.4' % i, - 'subnet_id': _uuid()}], - 'mac_address': 'ca:fe:de:ad:be:ef', - 'subnet': {'cidr': '10.0.%s.0/24' % i, - 'gateway_ip': '10.0.%s.1' % i}} - router[l3_constants.INTERFACE_KEY].append(port) - - def _del_all_floating_ips(self, router): - router[l3_constants.FLOATINGIP_KEY] = [] - - def _del_floating_ips(self, router, port_idx): - del router[l3_constants.FLOATINGIP_KEY][port_idx] - - def _add_floating_ips(self, router, port_count=1): - self._del_all_floating_ips(router) - for i in range(port_count): - fip = {'id': _uuid(), - 'port_id': router['gw_port']['id'], - 'floating_ip_address': '172.24.4.%s' % (100 + i), - 'fixed_ip_address': '10.0.0.%s' % (100 + i)} - router[l3_constants.FLOATINGIP_KEY].append(fip) - - def _prepare_router_data(self, enable_snat=None): - router_id = _uuid() - ex_gw_port = {'id': _uuid(), - 'network_id': _uuid(), - 'fixed_ips': [{'ip_address': '172.24.4.2', - 'subnet_id': _uuid()}], - 'subnet': {'cidr': '172.24.4.0/24', - 'gateway_ip': '172.24.4.1'}, - 'ip_cidr': '172.24.4.226/28'} - int_ports = [] - - router = { - 'id': router_id, - l3_constants.INTERFACE_KEY: int_ports, - 'routes': [], - 'gw_port': ex_gw_port} - if enable_snat is not None: - router['enable_snat'] = enable_snat - - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - return ri - - def test_agent_add_internal_network(self): - router = self._create_router() - try: - router.rest.auth() - except Exception: - # skip the test, firewall is not deployed - return - - ri = self._prepare_router_data(enable_snat=True) - router._router_added(ri.router['id'], ri.router) - - url = varmour_utils.REST_URL_CONF_NAT_RULE - prefix = varmour_utils.get_snat_rule_name(ri) - - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - self._add_internal_ports(ri.router, port_count=1) - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 1, 'prefix %s' % prefix) - - router._router_removed(ri.router['id']) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - def test_agent_remove_internal_network(self): - router = self._create_router() - try: - router.rest.auth() - except Exception: - # skip the test, firewall is not deployed - return - - ri = self._prepare_router_data(enable_snat=True) - router._router_added(ri.router['id'], ri.router) - - url = varmour_utils.REST_URL_CONF_NAT_RULE - prefix = varmour_utils.get_snat_rule_name(ri) - - self._add_internal_ports(ri.router, port_count=2) - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 2, 'prefix %s' % prefix) - - self._del_internal_ports(ri.router, 0) - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 1, 'prefix %s' % prefix) - - self._del_all_internal_ports(ri.router) - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - router._router_removed(ri.router['id']) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - def test_agent_add_floating_ips(self): - router = self._create_router() - try: - router.rest.auth() - except Exception: - # skip the test, firewall is not deployed - return - - ri = self._prepare_router_data(enable_snat=True) - self._add_internal_ports(ri.router, port_count=1) - router._router_added(ri.router['id'], ri.router) - - url = varmour_utils.REST_URL_CONF_NAT_RULE - prefix = varmour_utils.get_dnat_rule_name(ri) - - self._add_floating_ips(ri.router, port_count=1) - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 1, 'prefix %s' % prefix) - - self._add_floating_ips(ri.router, port_count=2) - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 2, 'prefix %s' % prefix) - - router._router_removed(ri.router['id']) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - def test_agent_remove_floating_ips(self): - router = self._create_router() - try: - router.rest.auth() - except Exception: - # skip the test, firewall is not deployed - return - - ri = self._prepare_router_data(enable_snat=True) - self._add_internal_ports(ri.router, port_count=1) - self._add_floating_ips(ri.router, port_count=2) - router._router_added(ri.router['id'], ri.router) - - url = varmour_utils.REST_URL_CONF_NAT_RULE - prefix = varmour_utils.get_dnat_rule_name(ri) - - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 2, 'prefix %s' % prefix) - - self._del_floating_ips(ri.router, 0) - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 1, 'prefix %s' % prefix) - - self._del_all_floating_ips(ri.router) - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - router._router_removed(ri.router['id']) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - def test_agent_external_gateway(self): - router = self._create_router() - try: - router.rest.auth() - except Exception: - # skip the test, firewall is not deployed - return - - ri = self._prepare_router_data(enable_snat=True) - router._router_added(ri.router['id'], ri.router) - - url = varmour_utils.REST_URL_CONF_ZONE - prefix = varmour_utils.get_untrusted_zone_name(ri) - - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 1, 'prefix %s' % prefix) - - del ri.router['gw_port'] - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 1, 'prefix %s' % prefix) - - router._router_removed(ri.router['id']) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - def test_agent_snat_enable(self): - router = self._create_router() - try: - router.rest.auth() - except Exception: - # skip the test, firewall is not deployed - return - - ri = self._prepare_router_data(enable_snat=True) - router._router_added(ri.router['id'], ri.router) - - url = varmour_utils.REST_URL_CONF_NAT_RULE - prefix = varmour_utils.get_snat_rule_name(ri) - - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - ri.router['enable_snat'] = False - router.process_router(ri) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) - - router._router_removed(ri.router['id']) - n = router.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0, 'prefix %s' % prefix) diff --git a/neutron/tests/unit/services/firewall/drivers/__init__.py b/neutron/tests/unit/services/firewall/drivers/__init__.py deleted file mode 100644 index cae279d0a..000000000 --- a/neutron/tests/unit/services/firewall/drivers/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack Foundation -# -# 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. diff --git a/neutron/tests/unit/services/firewall/drivers/linux/__init__.py b/neutron/tests/unit/services/firewall/drivers/linux/__init__.py deleted file mode 100644 index cae279d0a..000000000 --- a/neutron/tests/unit/services/firewall/drivers/linux/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack Foundation -# -# 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. diff --git a/neutron/tests/unit/services/firewall/drivers/linux/test_iptables_fwaas.py b/neutron/tests/unit/services/firewall/drivers/linux/test_iptables_fwaas.py deleted file mode 100644 index 4bcef20e6..000000000 --- a/neutron/tests/unit/services/firewall/drivers/linux/test_iptables_fwaas.py +++ /dev/null @@ -1,218 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 Dell Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Rajesh Mohan, Rajesh_Mohan3@Dell.com, DELL Inc. - -import mock -from oslo.config import cfg - -from neutron.agent.common import config as a_cfg -import neutron.services.firewall.drivers.linux.iptables_fwaas as fwaas -from neutron.tests import base -from neutron.tests.unit import test_api_v2 - - -_uuid = test_api_v2._uuid -FAKE_SRC_PREFIX = '10.0.0.0/24' -FAKE_DST_PREFIX = '20.0.0.0/24' -FAKE_PROTOCOL = 'tcp' -FAKE_SRC_PORT = 5000 -FAKE_DST_PORT = 22 -FAKE_FW_ID = 'fake-fw-uuid' - - -class IptablesFwaasTestCase(base.BaseTestCase): - def setUp(self): - super(IptablesFwaasTestCase, self).setUp() - cfg.CONF.register_opts(a_cfg.ROOT_HELPER_OPTS, 'AGENT') - self.utils_exec_p = mock.patch( - 'neutron.agent.linux.utils.execute') - self.utils_exec = self.utils_exec_p.start() - self.iptables_cls_p = mock.patch( - 'neutron.agent.linux.iptables_manager.IptablesManager') - self.iptables_cls_p.start() - self.firewall = fwaas.IptablesFwaasDriver() - - def _fake_rules_v4(self, fwid, apply_list): - rule_list = [] - rule1 = {'enabled': True, - 'action': 'allow', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '80', - 'source_ip_address': '10.24.4.2'} - rule2 = {'enabled': True, - 'action': 'deny', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '22'} - ingress_chain = ('iv4%s' % fwid)[:11] - egress_chain = ('ov4%s' % fwid)[:11] - for router_info_inst in apply_list: - v4filter_inst = router_info_inst.iptables_manager.ipv4['filter'] - v4filter_inst.chains.append(ingress_chain) - v4filter_inst.chains.append(egress_chain) - rule_list.append(rule1) - rule_list.append(rule2) - return rule_list - - def _fake_firewall_no_rule(self): - rule_list = [] - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': True, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': rule_list} - return fw_inst - - def _fake_firewall(self, rule_list): - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': True, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': rule_list} - return fw_inst - - def _fake_firewall_with_admin_down(self, rule_list): - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': False, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': rule_list} - return fw_inst - - def _fake_apply_list(self, router_count=1): - apply_list = [] - while router_count > 0: - iptables_inst = mock.Mock() - v4filter_inst = mock.Mock() - v6filter_inst = mock.Mock() - v4filter_inst.chains = [] - v6filter_inst.chains = [] - iptables_inst.ipv4 = {'filter': v4filter_inst} - iptables_inst.ipv6 = {'filter': v6filter_inst} - router_info_inst = mock.Mock() - router_info_inst.iptables_manager = iptables_inst - apply_list.append(router_info_inst) - router_count -= 1 - return apply_list - - def _setup_firewall_with_rules(self, func, router_count=1): - apply_list = self._fake_apply_list(router_count=router_count) - rule_list = self._fake_rules_v4(FAKE_FW_ID, apply_list) - firewall = self._fake_firewall(rule_list) - func(apply_list, firewall) - invalid_rule = '-m state --state INVALID -j DROP' - est_rule = '-m state --state ESTABLISHED,RELATED -j ACCEPT' - rule1 = '-p tcp --dport 80 -s 10.24.4.2 -j ACCEPT' - rule2 = '-p tcp --dport 22 -j DROP' - ingress_chain = 'iv4%s' % firewall['id'] - egress_chain = 'ov4%s' % firewall['id'] - bname = fwaas.iptables_manager.binary_name - ipt_mgr_ichain = '%s-%s' % (bname, ingress_chain[:11]) - ipt_mgr_echain = '%s-%s' % (bname, egress_chain[:11]) - for router_info_inst in apply_list: - v4filter_inst = router_info_inst.iptables_manager.ipv4['filter'] - calls = [mock.call.ensure_remove_chain('iv4fake-fw-uuid'), - mock.call.ensure_remove_chain('ov4fake-fw-uuid'), - mock.call.ensure_remove_chain('fwaas-default-policy'), - mock.call.add_chain('fwaas-default-policy'), - mock.call.add_rule('fwaas-default-policy', '-j DROP'), - mock.call.add_chain(ingress_chain), - mock.call.add_rule(ingress_chain, invalid_rule), - mock.call.add_rule(ingress_chain, est_rule), - mock.call.add_chain(egress_chain), - mock.call.add_rule(egress_chain, invalid_rule), - mock.call.add_rule(egress_chain, est_rule), - mock.call.add_rule(ingress_chain, rule1), - mock.call.add_rule(egress_chain, rule1), - mock.call.add_rule(ingress_chain, rule2), - mock.call.add_rule(egress_chain, rule2), - mock.call.add_rule('FORWARD', - '-o qr-+ -j %s' % ipt_mgr_ichain), - mock.call.add_rule('FORWARD', - '-i qr-+ -j %s' % ipt_mgr_echain), - mock.call.add_rule('FORWARD', - '-o qr-+ -j %s-fwaas-defau' % bname), - mock.call.add_rule('FORWARD', - '-i qr-+ -j %s-fwaas-defau' % bname)] - v4filter_inst.assert_has_calls(calls) - - def test_create_firewall_no_rules(self): - apply_list = self._fake_apply_list() - firewall = self._fake_firewall_no_rule() - self.firewall.create_firewall(apply_list, firewall) - invalid_rule = '-m state --state INVALID -j DROP' - est_rule = '-m state --state ESTABLISHED,RELATED -j ACCEPT' - bname = fwaas.iptables_manager.binary_name - - for ip_version in (4, 6): - ingress_chain = ('iv%s%s' % (ip_version, firewall['id'])) - egress_chain = ('ov%s%s' % (ip_version, firewall['id'])) - calls = [mock.call.ensure_remove_chain( - 'iv%sfake-fw-uuid' % ip_version), - mock.call.ensure_remove_chain( - 'ov%sfake-fw-uuid' % ip_version), - mock.call.ensure_remove_chain('fwaas-default-policy'), - mock.call.add_chain('fwaas-default-policy'), - mock.call.add_rule('fwaas-default-policy', '-j DROP'), - mock.call.add_chain(ingress_chain), - mock.call.add_rule(ingress_chain, invalid_rule), - mock.call.add_rule(ingress_chain, est_rule), - mock.call.add_chain(egress_chain), - mock.call.add_rule(egress_chain, invalid_rule), - mock.call.add_rule(egress_chain, est_rule), - mock.call.add_rule('FORWARD', - '-o qr-+ -j %s-fwaas-defau' % bname), - mock.call.add_rule('FORWARD', - '-i qr-+ -j %s-fwaas-defau' % bname)] - if ip_version == 4: - v4filter_inst = apply_list[0].iptables_manager.ipv4['filter'] - v4filter_inst.assert_has_calls(calls) - else: - v6filter_inst = apply_list[0].iptables_manager.ipv6['filter'] - v6filter_inst.assert_has_calls(calls) - - def test_create_firewall_with_rules(self): - self._setup_firewall_with_rules(self.firewall.create_firewall) - - def test_create_firewall_with_rules_two_routers(self): - self._setup_firewall_with_rules(self.firewall.create_firewall, - router_count=2) - - def test_update_firewall_with_rules(self): - self._setup_firewall_with_rules(self.firewall.update_firewall) - - def test_delete_firewall(self): - apply_list = self._fake_apply_list() - firewall = self._fake_firewall_no_rule() - self.firewall.delete_firewall(apply_list, firewall) - ingress_chain = 'iv4%s' % firewall['id'] - egress_chain = 'ov4%s' % firewall['id'] - calls = [mock.call.ensure_remove_chain(ingress_chain), - mock.call.ensure_remove_chain(egress_chain), - mock.call.ensure_remove_chain('fwaas-default-policy')] - apply_list[0].iptables_manager.ipv4['filter'].assert_has_calls(calls) - - def test_create_firewall_with_admin_down(self): - apply_list = self._fake_apply_list() - rule_list = self._fake_rules_v4(FAKE_FW_ID, apply_list) - firewall = self._fake_firewall_with_admin_down(rule_list) - self.firewall.create_firewall(apply_list, firewall) - calls = [mock.call.ensure_remove_chain('iv4fake-fw-uuid'), - mock.call.ensure_remove_chain('ov4fake-fw-uuid'), - mock.call.ensure_remove_chain('fwaas-default-policy'), - mock.call.add_chain('fwaas-default-policy'), - mock.call.add_rule('fwaas-default-policy', '-j DROP')] - apply_list[0].iptables_manager.ipv4['filter'].assert_has_calls(calls) diff --git a/neutron/tests/unit/services/firewall/drivers/varmour/__init__.py b/neutron/tests/unit/services/firewall/drivers/varmour/__init__.py deleted file mode 100755 index 5e8da711f..000000000 --- a/neutron/tests/unit/services/firewall/drivers/varmour/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack Foundation. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/services/firewall/drivers/varmour/test_varmour_fwaas.py b/neutron/tests/unit/services/firewall/drivers/varmour/test_varmour_fwaas.py deleted file mode 100644 index c65af6bc5..000000000 --- a/neutron/tests/unit/services/firewall/drivers/varmour/test_varmour_fwaas.py +++ /dev/null @@ -1,290 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 vArmour Networks Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Gary Duan, vArmour Networks Inc. -# - - -import mock -from oslo.config import cfg - -from neutron.agent.common import config as agent_config -from neutron.agent import l3_agent -from neutron.agent.linux import interface -from neutron.common import config as base_config -from neutron.common import constants as l3_constants -from neutron.openstack.common import uuidutils -from neutron.services.firewall.agents.varmour import varmour_router -from neutron.services.firewall.agents.varmour import varmour_utils -from neutron.services.firewall.drivers.varmour import varmour_fwaas -from neutron.tests import base - -_uuid = uuidutils.generate_uuid -HOSTNAME = 'myhost' -FAKE_DIRECTOR = '1.1.1.1' - - -class TestBasicRouterOperations(base.BaseTestCase): - - def setUp(self): - super(TestBasicRouterOperations, self).setUp() - self.conf = cfg.ConfigOpts() - self.conf.register_opts(base_config.core_opts) - self.conf.register_opts(varmour_router.vArmourL3NATAgent.OPTS) - agent_config.register_interface_driver_opts_helper(self.conf) - agent_config.register_use_namespaces_opts_helper(self.conf) - agent_config.register_root_helper(self.conf) - self.conf.register_opts(interface.OPTS) - self.conf.set_override('interface_driver', - 'neutron.agent.linux.interface.NullDriver') - self.conf.root_helper = 'sudo' - - self.device_exists_p = mock.patch( - 'neutron.agent.linux.ip_lib.device_exists') - self.device_exists = self.device_exists_p.start() - - self.utils_exec_p = mock.patch( - 'neutron.agent.linux.utils.execute') - self.utils_exec = self.utils_exec_p.start() - - self.external_process_p = mock.patch( - 'neutron.agent.linux.external_process.ProcessManager') - self.external_process = self.external_process_p.start() - - self.dvr_cls_p = mock.patch('neutron.agent.linux.interface.NullDriver') - driver_cls = self.dvr_cls_p.start() - self.mock_driver = mock.MagicMock() - self.mock_driver.DEV_NAME_LEN = ( - interface.LinuxInterfaceDriver.DEV_NAME_LEN) - driver_cls.return_value = self.mock_driver - - self.ip_cls_p = mock.patch('neutron.agent.linux.ip_lib.IPWrapper') - ip_cls = self.ip_cls_p.start() - self.mock_ip = mock.MagicMock() - ip_cls.return_value = self.mock_ip - - self.looping_call_p = mock.patch( - 'neutron.openstack.common.loopingcall.FixedIntervalLoopingCall') - self.looping_call_p.start() - - def _create_router(self): - router = varmour_router.vArmourL3NATAgent(HOSTNAME, self.conf) - router.rest.server = FAKE_DIRECTOR - router.rest.user = 'varmour' - router.rest.passwd = 'varmour' - return router - - def _create_fwaas(self): - fwaas = varmour_fwaas.vArmourFwaasDriver() - fwaas.rest.server = FAKE_DIRECTOR - fwaas.rest.user = 'varmour' - fwaas.rest.passwd = 'varmour' - return fwaas - - def _del_all_internal_ports(self, router): - router[l3_constants.INTERFACE_KEY] = [] - - def _del_internal_ports(self, router, port_idx): - del router[l3_constants.INTERFACE_KEY][port_idx] - - def _add_internal_ports(self, router, port_count=1): - self._del_all_internal_ports(router) - for i in range(port_count): - port = {'id': _uuid(), - 'network_id': _uuid(), - 'admin_state_up': True, - 'fixed_ips': [{'ip_address': '10.0.%s.4' % i, - 'subnet_id': _uuid()}], - 'mac_address': 'ca:fe:de:ad:be:ef', - 'subnet': {'cidr': '10.0.%s.0/24' % i, - 'gateway_ip': '10.0.%s.1' % i}} - router[l3_constants.INTERFACE_KEY].append(port) - - def _del_all_floating_ips(self, router): - router[l3_constants.FLOATINGIP_KEY] = [] - - def _del_floating_ips(self, router, port_idx): - del router[l3_constants.FLOATINGIP_KEY][port_idx] - - def _add_floating_ips(self, router, port_count=1): - self._del_all_floating_ips(router) - for i in range(port_count): - fip = {'id': _uuid(), - 'port_id': router['gw_port']['id'], - 'floating_ip_address': '172.24.4.%s' % (100 + i), - 'fixed_ip_address': '10.0.0.%s' % (100 + i)} - router[l3_constants.FLOATINGIP_KEY].append(fip) - - def _prepare_router_data(self, enable_snat=None): - router_id = _uuid() - ex_gw_port = {'id': _uuid(), - 'network_id': _uuid(), - 'fixed_ips': [{'ip_address': '172.24.4.2', - 'subnet_id': _uuid()}], - 'subnet': {'cidr': '172.24.4.0/24', - 'gateway_ip': '172.24.4.1'}, - 'ip_cidr': '172.24.4.226/28'} - int_ports = [] - - router = { - 'id': router_id, - l3_constants.INTERFACE_KEY: int_ports, - 'routes': [], - 'gw_port': ex_gw_port} - if enable_snat is not None: - router['enable_snat'] = enable_snat - - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - return ri - - def _add_firewall_rules(self, fw, rule_count=1): - rules = [] - for i in range(rule_count): - rule = {'id': _uuid(), - 'enabled': True, - 'action': 'deny' if (i % 2 == 0) else 'allow', - 'ip_version': 4, - 'protocol': 'tcp', - 'source_ip_address': '10.0.0.%s/24' % (100 + i), - 'destination_port': '%s' % (100 + i)} - rules.append(rule) - fw['firewall_rule_list'] = rules - - def _prepare_firewall_data(self): - fw = {'id': _uuid(), - 'admin_state_up': True, - 'firewall_rule_list': []} - return fw - - def test_firewall_without_rule(self): - router = self._create_router() - fwaas = self._create_fwaas() - try: - router.rest.auth() - except Exception: - # skip the test, firewall is not deployed - return - - ri = self._prepare_router_data(enable_snat=True) - self._add_internal_ports(ri.router, port_count=1) - self._add_floating_ips(ri.router, port_count=1) - router._router_added(ri.router['id'], ri.router) - - rl = [ri] - - fw = self._prepare_firewall_data() - fwaas.create_firewall(rl, fw) - - url = varmour_utils.REST_URL_CONF_POLICY - prefix = varmour_utils.get_firewall_object_prefix(ri, fw) - - n = fwaas.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0) - - fwaas.delete_firewall(rl, fw) - n = fwaas.rest.count_cfg_objs(url, prefix) - self.assertEqual(n, 0) - - router._router_removed(ri.router['id']) - - def test_firewall_with_rules(self): - router = self._create_router() - fwaas = self._create_fwaas() - try: - router.rest.auth() - except Exception: - # skip the test, firewall is not deployed - return - - ri = self._prepare_router_data(enable_snat=True) - self._add_internal_ports(ri.router, port_count=1) - self._add_floating_ips(ri.router, port_count=1) - router._router_added(ri.router['id'], ri.router) - - rl = [ri] - - fw = self._prepare_firewall_data() - self._add_firewall_rules(fw, 2) - fwaas.create_firewall(rl, fw) - - prefix = varmour_utils.get_firewall_object_prefix(ri, fw) - pol_url = varmour_utils.REST_URL_CONF_POLICY - serv_url = varmour_utils.REST_URL_CONF_SERVICE - addr_url = varmour_utils.REST_URL_CONF_ADDR - - # 3x number of policies - n = fwaas.rest.count_cfg_objs(pol_url, prefix) - self.assertEqual(n, 6) - n = fwaas.rest.count_cfg_objs(addr_url, prefix) - self.assertEqual(n, 2) - n = fwaas.rest.count_cfg_objs(serv_url, prefix) - self.assertEqual(n, 2) - - fwaas.delete_firewall(rl, fw) - n = fwaas.rest.count_cfg_objs(pol_url, prefix) - self.assertEqual(n, 0) - - router._router_removed(ri.router['id']) - - def test_firewall_add_remove_rules(self): - router = self._create_router() - fwaas = self._create_fwaas() - try: - router.rest.auth() - except Exception: - # skip the test, firewall is not deployed - return - - ri = self._prepare_router_data(enable_snat=True) - self._add_internal_ports(ri.router, port_count=1) - self._add_floating_ips(ri.router, port_count=1) - router._router_added(ri.router['id'], ri.router) - - rl = [ri] - - fw = self._prepare_firewall_data() - self._add_firewall_rules(fw, 2) - fwaas.create_firewall(rl, fw) - - prefix = varmour_utils.get_firewall_object_prefix(ri, fw) - pol_url = varmour_utils.REST_URL_CONF_POLICY - serv_url = varmour_utils.REST_URL_CONF_SERVICE - addr_url = varmour_utils.REST_URL_CONF_ADDR - - # 3x number of policies - n = fwaas.rest.count_cfg_objs(pol_url, prefix) - self.assertEqual(n, 6) - n = fwaas.rest.count_cfg_objs(addr_url, prefix) - self.assertEqual(n, 2) - n = fwaas.rest.count_cfg_objs(serv_url, prefix) - self.assertEqual(n, 2) - - self._add_firewall_rules(fw, 1) - fwaas.create_firewall(rl, fw) - n = fwaas.rest.count_cfg_objs(pol_url, prefix) - self.assertEqual(n, 3) - n = fwaas.rest.count_cfg_objs(addr_url, prefix) - self.assertEqual(n, 1) - n = fwaas.rest.count_cfg_objs(serv_url, prefix) - self.assertEqual(n, 1) - - fwaas.delete_firewall(rl, fw) - n = fwaas.rest.count_cfg_objs(pol_url, prefix) - self.assertEqual(n, 0) - - router._router_removed(ri.router['id']) diff --git a/neutron/tests/unit/services/firewall/test_fwaas_plugin.py b/neutron/tests/unit/services/firewall/test_fwaas_plugin.py deleted file mode 100644 index 2430d69c6..000000000 --- a/neutron/tests/unit/services/firewall/test_fwaas_plugin.py +++ /dev/null @@ -1,401 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 Big Switch Networks, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Sumit Naiksatam, sumitnaiksatam@gmail.com, Big Switch Networks, Inc. - - -import contextlib - -import mock -from webob import exc - -from neutron import context -from neutron.extensions import firewall -from neutron.plugins.common import constants as const -from neutron.services.firewall import fwaas_plugin -from neutron.tests import base -from neutron.tests.unit.db.firewall import test_db_firewall - - -FW_PLUGIN_KLASS = ( - "neutron.services.firewall.fwaas_plugin.FirewallPlugin" -) - - -class TestFirewallCallbacks(test_db_firewall.FirewallPluginDbTestCase): - - def setUp(self): - super(TestFirewallCallbacks, - self).setUp(fw_plugin=FW_PLUGIN_KLASS) - self.callbacks = self.plugin.endpoints[0] - - def test_set_firewall_status(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP) as fw: - fw_id = fw['firewall']['id'] - res = self.callbacks.set_firewall_status(ctx, fw_id, - const.ACTIVE, - host='dummy') - fw_db = self.plugin.get_firewall(ctx, fw_id) - self.assertEqual(fw_db['status'], const.ACTIVE) - self.assertTrue(res) - res = self.callbacks.set_firewall_status(ctx, fw_id, - const.ERROR) - fw_db = self.plugin.get_firewall(ctx, fw_id) - self.assertEqual(fw_db['status'], const.ERROR) - self.assertFalse(res) - - def test_set_firewall_status_pending_delete(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP) as fw: - fw_id = fw['firewall']['id'] - fw_db = self.plugin._get_firewall(ctx, fw_id) - fw_db['status'] = const.PENDING_DELETE - ctx.session.flush() - res = self.callbacks.set_firewall_status(ctx, fw_id, - const.ACTIVE, - host='dummy') - fw_db = self.plugin.get_firewall(ctx, fw_id) - self.assertEqual(fw_db['status'], const.PENDING_DELETE) - self.assertFalse(res) - - def test_firewall_deleted(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - no_delete=True) as fw: - fw_id = fw['firewall']['id'] - with ctx.session.begin(subtransactions=True): - fw_db = self.plugin._get_firewall(ctx, fw_id) - fw_db['status'] = const.PENDING_DELETE - ctx.session.flush() - res = self.callbacks.firewall_deleted(ctx, fw_id, - host='dummy') - self.assertTrue(res) - self.assertRaises(firewall.FirewallNotFound, - self.plugin.get_firewall, - ctx, fw_id) - - def test_firewall_deleted_error(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - ) as fw: - fw_id = fw['firewall']['id'] - res = self.callbacks.firewall_deleted(ctx, fw_id, - host='dummy') - self.assertFalse(res) - fw_db = self.plugin._get_firewall(ctx, fw_id) - self.assertEqual(fw_db['status'], const.ERROR) - - def test_get_firewall_for_tenant(self): - tenant_id = 'test-tenant' - ctx = context.Context('', tenant_id) - with contextlib.nested(self.firewall_rule(name='fwr1', - tenant_id=tenant_id), - self.firewall_rule(name='fwr2', - tenant_id=tenant_id), - self.firewall_rule(name='fwr3', - tenant_id=tenant_id) - ) as fr: - with self.firewall_policy(tenant_id=tenant_id) as fwp: - fwp_id = fwp['firewall_policy']['id'] - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - res = req.get_response(self.ext_api) - attrs = self._get_test_firewall_attrs() - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, - tenant_id=tenant_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP) as fw: - fw_id = fw['firewall']['id'] - res = self.callbacks.get_firewalls_for_tenant(ctx, - host='dummy') - fw_rules = ( - self.plugin._make_firewall_dict_with_rules(ctx, - fw_id) - ) - self.assertEqual(res[0], fw_rules) - self._compare_firewall_rule_lists( - fwp_id, fr, res[0]['firewall_rule_list']) - - def test_get_firewall_for_tenant_without_rules(self): - tenant_id = 'test-tenant' - ctx = context.Context('', tenant_id) - with self.firewall_policy(tenant_id=tenant_id) as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs = self._get_test_firewall_attrs() - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, tenant_id=tenant_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP - ) as fw: - fw_list = [fw['firewall']] - f = self.callbacks.get_firewalls_for_tenant_without_rules - res = f(ctx, host='dummy') - for fw in res: - del fw['shared'] - self.assertEqual(res, fw_list) - - -class TestFirewallAgentApi(base.BaseTestCase): - def setUp(self): - super(TestFirewallAgentApi, self).setUp() - - self.api = fwaas_plugin.FirewallAgentApi('topic', 'host') - self.mock_fanoutcast = mock.patch.object(self.api, - 'fanout_cast').start() - self.mock_msg = mock.patch.object(self.api, 'make_msg').start() - - def test_init(self): - self.assertEqual(self.api.topic, 'topic') - self.assertEqual(self.api.host, 'host') - - def _call_test_helper(self, method_name): - rv = getattr(self.api, method_name)(mock.sentinel.context, 'test') - self.assertEqual(rv, self.mock_fanoutcast.return_value) - self.mock_fanoutcast.assert_called_once_with( - mock.sentinel.context, - self.mock_msg.return_value, - topic='topic' - ) - - self.mock_msg.assert_called_once_with( - method_name, - firewall='test', - host='host' - ) - - def test_create_firewall(self): - self._call_test_helper('create_firewall') - - def test_update_firewall(self): - self._call_test_helper('update_firewall') - - def test_delete_firewall(self): - self._call_test_helper('delete_firewall') - - -class TestFirewallPluginBase(test_db_firewall.TestFirewallDBPlugin): - - def setUp(self): - super(TestFirewallPluginBase, self).setUp(fw_plugin=FW_PLUGIN_KLASS) - self.callbacks = self.plugin.endpoints[0] - - def test_create_second_firewall_not_permitted(self): - with self.firewall(): - res = self._create_firewall( - None, 'firewall2', description='test', - firewall_policy_id=None, admin_state_up=True) - self.assertEqual(res.status_int, exc.HTTPConflict.code) - - def test_create_firewall_admin_not_affected_by_other_tenant(self): - # Create fw with admin after creating fw with other tenant - with self.firewall(tenant_id='other-tenant') as fw1: - with self.firewall() as fw2: - self.assertEqual('other-tenant', fw1['firewall']['tenant_id']) - self.assertEqual(self._tenant_id, fw2['firewall']['tenant_id']) - - def test_update_firewall(self): - ctx = context.get_admin_context() - name = "new_firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP) as firewall: - fw_id = firewall['firewall']['id'] - res = self.callbacks.set_firewall_status(ctx, fw_id, - const.ACTIVE) - data = {'firewall': {'name': name}} - req = self.new_update_request('firewalls', data, fw_id) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs = self._replace_firewall_status(attrs, - const.PENDING_CREATE, - const.PENDING_UPDATE) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall'][k], v) - - def test_update_firewall_fails_when_firewall_pending(self): - name = "new_firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP) as firewall: - fw_id = firewall['firewall']['id'] - data = {'firewall': {'name': name}} - req = self.new_update_request('firewalls', data, fw_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, exc.HTTPConflict.code) - - def test_update_firewall_shared_fails_for_non_admin(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP, - tenant_id='noadmin') as firewall: - fw_id = firewall['firewall']['id'] - self.callbacks.set_firewall_status(ctx, fw_id, - const.ACTIVE) - data = {'firewall': {'shared': True}} - req = self.new_update_request( - 'firewalls', data, fw_id, - context=context.Context('', 'noadmin')) - res = req.get_response(self.ext_api) - # returns 404 due to security reasons - self.assertEqual(res.status_int, exc.HTTPNotFound.code) - - def test_update_firewall_policy_fails_when_firewall_pending(self): - name = "new_firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP): - data = {'firewall_policy': {'name': name}} - req = self.new_update_request('firewall_policies', - data, fwp_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, exc.HTTPConflict.code) - - def test_update_firewall_rule_fails_when_firewall_pending(self): - with self.firewall_rule(name='fwr1') as fr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - fr_id = fr['firewall_rule']['id'] - fw_rule_ids = [fr_id] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP): - data = {'firewall_rule': {'protocol': 'udp'}} - req = self.new_update_request('firewall_rules', - data, fr_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, exc.HTTPConflict.code) - - def test_delete_firewall(self): - ctx = context.get_admin_context() - attrs = self._get_test_firewall_attrs() - # stop the AgentRPC patch for this one to test pending states - self.agentapi_delf_p.stop() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP) as firewall: - fw_id = firewall['firewall']['id'] - attrs = self._replace_firewall_status(attrs, - const.PENDING_CREATE, - const.PENDING_DELETE) - req = self.new_delete_request('firewalls', fw_id) - req.get_response(self.ext_api) - fw_db = self.plugin._get_firewall(ctx, fw_id) - for k, v in attrs.iteritems(): - self.assertEqual(fw_db[k], v) - # cleanup the pending firewall - self.plugin.endpoints[0].firewall_deleted(ctx, fw_id) - - def test_delete_firewall_after_agent_delete(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - no_delete=True) as fw: - fw_id = fw['firewall']['id'] - req = self.new_delete_request('firewalls', fw_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, exc.HTTPNoContent.code) - self.assertRaises(firewall.FirewallNotFound, - self.plugin.get_firewall, - ctx, fw_id) - - def test_make_firewall_dict_with_in_place_rules(self): - ctx = context.get_admin_context() - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as fr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - attrs = self._get_test_firewall_attrs() - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP) as fw: - fw_id = fw['firewall']['id'] - fw_rules = ( - self.plugin._make_firewall_dict_with_rules(ctx, - fw_id) - ) - self.assertEqual(fw_rules['id'], fw_id) - self._compare_firewall_rule_lists( - fwp_id, fr, fw_rules['firewall_rule_list']) - - def test_make_firewall_dict_with_in_place_rules_no_policy(self): - ctx = context.get_admin_context() - with self.firewall() as fw: - fw_id = fw['firewall']['id'] - fw_rules = self.plugin._make_firewall_dict_with_rules(ctx, fw_id) - self.assertEqual(fw_rules['firewall_rule_list'], []) - - def test_list_firewalls(self): - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name='fw1', firewall_policy_id=fwp_id, - description='fw') as fwalls: - self._test_list_resources('firewall', [fwalls], - query_params='description=fw') diff --git a/neutron/tests/unit/services/l3_router/__init__.py b/neutron/tests/unit/services/l3_router/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/services/l3_router/test_l3_apic_plugin.py b/neutron/tests/unit/services/l3_router/test_l3_apic_plugin.py deleted file mode 100644 index 6bc33ef28..000000000 --- a/neutron/tests/unit/services/l3_router/test_l3_apic_plugin.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright (c) 2014 Cisco Systems -# All Rights Reserved. -# -# 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. -# -# @author: Arvind Somya (asomya@cisco.com), Cisco Systems - -import mock - -from neutron.services.l3_router import l3_apic -from neutron.tests import base - -TENANT = 'tenant1' -TENANT_CONTRACT = 'abcd' -ROUTER = 'router1' -SUBNET = 'subnet1' -NETWORK = 'network1' -NETWORK_NAME = 'one_network' -NETWORK_EPG = 'one_network-epg' -TEST_SEGMENT1 = 'test-segment1' -SUBNET_GATEWAY = '10.3.2.1' -SUBNET_CIDR = '10.3.1.0/24' -SUBNET_NETMASK = '24' - - -class FakeContext(object): - def __init__(self): - self.tenant_id = None - - -class FakeContract(object): - def __init__(self): - self.contract_id = '123' - - -class FakeEpg(object): - def __init__(self): - self.epg_id = 'abcd_epg' - - -class FakePort(object): - def __init__(self): - self.id = 'Fake_port_id' - self.network_id = NETWORK - self.subnet_id = SUBNET - - -class TestCiscoApicL3Plugin(base.BaseTestCase): - - def setUp(self): - super(TestCiscoApicL3Plugin, self).setUp() - mock.patch('neutron.plugins.ml2.drivers.cisco.apic.apic_manager.' - 'APICManager').start() - self.plugin = l3_apic.ApicL3ServicePlugin() - self.context = FakeContext() - self.context.tenant_id = TENANT - self.interface_info = {'subnet_id': SUBNET, 'network_id': NETWORK, - 'name': NETWORK_NAME} - - self.contract = FakeContract() - self.plugin.manager.create_tenant_contract = mock.Mock() - ctmk = mock.PropertyMock(return_value=self.contract.contract_id) - type(self.plugin.manager.create_tenant_contract).contract_id = ctmk - self.epg = FakeEpg() - self.plugin.manager.ensure_epg_created_for_network = mock.Mock() - epmk = mock.PropertyMock(return_value=self.epg.epg_id) - type(self.plugin.manager.ensure_epg_created_for_network).epg_id = epmk - - self.plugin.manager.db.get_provider_contract = mock.Mock( - return_value=None) - self.plugin.manager.set_contract_for_epg = mock.Mock( - return_value=True) - - self.plugin.get_subnet = mock.Mock(return_value=self.interface_info) - self.plugin.get_network = mock.Mock(return_value=self.interface_info) - mock.patch('neutron.db.l3_gwmode_db.L3_NAT_db_mixin.' - '_core_plugin').start() - mock.patch('neutron.db.l3_gwmode_db.L3_NAT_db_mixin.' - 'add_router_interface').start() - mock.patch('neutron.db.l3_gwmode_db.L3_NAT_db_mixin.' - 'remove_router_interface').start() - mock.patch('neutron.openstack.common.excutils.' - 'save_and_reraise_exception').start() - - def test_add_router_interface(self): - mgr = self.plugin.manager - self.plugin.add_router_interface(self.context, ROUTER, - self.interface_info) - mgr.create_tenant_contract.assert_called_once_with(TENANT) - mgr.create_tenant_contract.assertEqual(TENANT_CONTRACT) - mgr.ensure_epg_created_for_network.assert_called_once_with( - TENANT, NETWORK, NETWORK_NAME) - mgr.ensure_epg_created_for_network.assertEqual(NETWORK_EPG) - mgr.db.get_provider_contract.assert_called_once() - mgr.db.get_provider_contract.assertEqual(None) - mgr.set_contract_for_epg.assert_called_once() - - def test_remove_router_interface(self): - mgr = self.plugin.manager - self.plugin.remove_router_interface(self.context, ROUTER, - self.interface_info) - mgr.create_tenant_contract.assert_called_once_with(TENANT) - mgr.ensure_epg_created_for_network.assert_called_once_with( - TENANT, NETWORK, NETWORK_NAME) - mgr.ensure_epg_created_for_network.assertEqual(NETWORK_EPG) - mgr.delete_contract_for_epg.assert_called_once() - - def test_add_router_interface_fail_contract_delete(self): - mgr = self.plugin.manager - with mock.patch('neutron.db.l3_gwmode_db.L3_NAT_db_mixin.' - 'add_router_interface', - side_effect=KeyError()): - self.plugin.add_router_interface(self.context, ROUTER, - self.interface_info) - mgr.delete_contract_for_epg.assert_called_once() - - def test_delete_router_interface_fail_contract_create(self): - mgr = self.plugin.manager - with mock.patch('neutron.db.l3_gwmode_db.L3_NAT_db_mixin.' - 'remove_router_interface', - side_effect=KeyError()): - self.plugin.remove_router_interface(self.context, ROUTER, - self.interface_info) - mgr.set_contract_for_epg.assert_called_once() diff --git a/neutron/tests/unit/services/loadbalancer/__init__.py b/neutron/tests/unit/services/loadbalancer/__init__.py deleted file mode 100644 index ce18bf6d6..000000000 --- a/neutron/tests/unit/services/loadbalancer/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost diff --git a/neutron/tests/unit/services/loadbalancer/agent/__init__.py b/neutron/tests/unit/services/loadbalancer/agent/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/services/loadbalancer/agent/test_agent.py b/neutron/tests/unit/services/loadbalancer/agent/test_agent.py deleted file mode 100644 index 955d6e1a8..000000000 --- a/neutron/tests/unit/services/loadbalancer/agent/test_agent.py +++ /dev/null @@ -1,51 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost - -import contextlib -import mock -from oslo.config import cfg - -from neutron.services.loadbalancer.agent import agent -from neutron.tests import base - - -class TestLbaasService(base.BaseTestCase): - def test_start(self): - with mock.patch.object( - agent.rpc_compat.Service, 'start' - ) as mock_start: - - mgr = mock.Mock() - cfg.CONF.periodic_interval = mock.Mock(return_value=10) - agent_service = agent.LbaasAgentService('host', 'topic', mgr) - agent_service.start() - - self.assertTrue(mock_start.called) - - def test_main(self): - logging_str = 'neutron.agent.common.config.setup_logging' - with contextlib.nested( - mock.patch(logging_str), - mock.patch.object(agent.service, 'launch'), - mock.patch('sys.argv'), - mock.patch.object(agent.manager, 'LbaasAgentManager'), - mock.patch.object(cfg.CONF, 'register_opts') - ) as (mock_logging, mock_launch, sys_argv, mgr_cls, ro): - agent.main() - - mock_launch.assert_called_once_with(mock.ANY) diff --git a/neutron/tests/unit/services/loadbalancer/agent/test_agent_manager.py b/neutron/tests/unit/services/loadbalancer/agent/test_agent_manager.py deleted file mode 100644 index 6a593b367..000000000 --- a/neutron/tests/unit/services/loadbalancer/agent/test_agent_manager.py +++ /dev/null @@ -1,371 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost - -import contextlib - -import mock - -from neutron.plugins.common import constants -from neutron.services.loadbalancer.agent import agent_manager as manager -from neutron.tests import base - - -class TestManager(base.BaseTestCase): - def setUp(self): - super(TestManager, self).setUp() - - mock_conf = mock.Mock() - mock_conf.device_driver = ['devdriver'] - - self.mock_importer = mock.patch.object(manager, 'importutils').start() - - rpc_mock_cls = mock.patch( - 'neutron.services.loadbalancer.agent.agent_api.LbaasAgentApi' - ).start() - - # disable setting up periodic state reporting - mock_conf.AGENT.report_interval = 0 - - self.mgr = manager.LbaasAgentManager(mock_conf) - self.rpc_mock = rpc_mock_cls.return_value - self.log = mock.patch.object(manager, 'LOG').start() - self.driver_mock = mock.Mock() - self.mgr.device_drivers = {'devdriver': self.driver_mock} - self.mgr.instance_mapping = {'1': 'devdriver', '2': 'devdriver'} - self.mgr.needs_resync = False - - def test_initialize_service_hook(self): - with mock.patch.object(self.mgr, 'sync_state') as sync: - self.mgr.initialize_service_hook(mock.Mock()) - sync.assert_called_once_with() - - def test_periodic_resync_needs_sync(self): - with mock.patch.object(self.mgr, 'sync_state') as sync: - self.mgr.needs_resync = True - self.mgr.periodic_resync(mock.Mock()) - sync.assert_called_once_with() - - def test_periodic_resync_no_sync(self): - with mock.patch.object(self.mgr, 'sync_state') as sync: - self.mgr.needs_resync = False - self.mgr.periodic_resync(mock.Mock()) - self.assertFalse(sync.called) - - def test_collect_stats(self): - self.mgr.collect_stats(mock.Mock()) - self.rpc_mock.update_pool_stats.assert_has_calls([ - mock.call('1', mock.ANY), - mock.call('2', mock.ANY) - ]) - - def test_collect_stats_exception(self): - self.driver_mock.get_stats.side_effect = Exception - - self.mgr.collect_stats(mock.Mock()) - - self.assertFalse(self.rpc_mock.called) - self.assertTrue(self.mgr.needs_resync) - self.assertTrue(self.log.exception.called) - - def _sync_state_helper(self, ready, reloaded, destroyed): - with contextlib.nested( - mock.patch.object(self.mgr, '_reload_pool'), - mock.patch.object(self.mgr, '_destroy_pool') - ) as (reload, destroy): - - self.rpc_mock.get_ready_devices.return_value = ready - - self.mgr.sync_state() - - self.assertEqual(len(reloaded), len(reload.mock_calls)) - self.assertEqual(len(destroyed), len(destroy.mock_calls)) - - reload.assert_has_calls([mock.call(i) for i in reloaded]) - destroy.assert_has_calls([mock.call(i) for i in destroyed]) - self.assertFalse(self.mgr.needs_resync) - - def test_sync_state_all_known(self): - self._sync_state_helper(['1', '2'], ['1', '2'], []) - - def test_sync_state_all_unknown(self): - self.mgr.instance_mapping = {} - self._sync_state_helper(['1', '2'], ['1', '2'], []) - - def test_sync_state_destroy_all(self): - self._sync_state_helper([], [], ['1', '2']) - - def test_sync_state_both(self): - self.mgr.instance_mapping = {'1': 'devdriver'} - self._sync_state_helper(['2'], ['2'], ['1']) - - def test_sync_state_exception(self): - self.rpc_mock.get_ready_devices.side_effect = Exception - - self.mgr.sync_state() - - self.assertTrue(self.log.exception.called) - self.assertTrue(self.mgr.needs_resync) - - def test_reload_pool(self): - config = {'driver': 'devdriver'} - self.rpc_mock.get_logical_device.return_value = config - pool_id = 'new_id' - self.assertNotIn(pool_id, self.mgr.instance_mapping) - - self.mgr._reload_pool(pool_id) - - self.driver_mock.deploy_instance.assert_called_once_with(config) - self.assertIn(pool_id, self.mgr.instance_mapping) - self.rpc_mock.pool_deployed.assert_called_once_with(pool_id) - - def test_reload_pool_driver_not_found(self): - config = {'driver': 'unknown_driver'} - self.rpc_mock.get_logical_device.return_value = config - pool_id = 'new_id' - self.assertNotIn(pool_id, self.mgr.instance_mapping) - - self.mgr._reload_pool(pool_id) - - self.assertTrue(self.log.error.called) - self.assertFalse(self.driver_mock.deploy_instance.called) - self.assertNotIn(pool_id, self.mgr.instance_mapping) - self.assertFalse(self.rpc_mock.pool_deployed.called) - - def test_reload_pool_exception_on_driver(self): - config = {'driver': 'devdriver'} - self.rpc_mock.get_logical_device.return_value = config - self.driver_mock.deploy_instance.side_effect = Exception - pool_id = 'new_id' - self.assertNotIn(pool_id, self.mgr.instance_mapping) - - self.mgr._reload_pool(pool_id) - - self.driver_mock.deploy_instance.assert_called_once_with(config) - self.assertNotIn(pool_id, self.mgr.instance_mapping) - self.assertFalse(self.rpc_mock.pool_deployed.called) - self.assertTrue(self.log.exception.called) - self.assertTrue(self.mgr.needs_resync) - - def test_destroy_pool(self): - pool_id = '1' - self.assertIn(pool_id, self.mgr.instance_mapping) - - self.mgr._destroy_pool(pool_id) - - self.driver_mock.undeploy_instance.assert_called_once_with(pool_id) - self.assertNotIn(pool_id, self.mgr.instance_mapping) - self.rpc_mock.pool_destroyed.assert_called_once_with(pool_id) - self.assertFalse(self.mgr.needs_resync) - - def test_destroy_pool_exception_on_driver(self): - pool_id = '1' - self.assertIn(pool_id, self.mgr.instance_mapping) - self.driver_mock.undeploy_instance.side_effect = Exception - - self.mgr._destroy_pool(pool_id) - - self.driver_mock.undeploy_instance.assert_called_once_with(pool_id) - self.assertIn(pool_id, self.mgr.instance_mapping) - self.assertFalse(self.rpc_mock.pool_destroyed.called) - self.assertTrue(self.log.exception.called) - self.assertTrue(self.mgr.needs_resync) - - def test_get_driver_unknown_device(self): - self.assertRaises(manager.DeviceNotFoundOnAgent, - self.mgr._get_driver, 'unknown') - - def test_remove_orphans(self): - self.mgr.remove_orphans() - self.driver_mock.remove_orphans.assert_called_once_with(['1', '2']) - - def test_create_vip(self): - vip = {'id': 'id1', 'pool_id': '1'} - self.mgr.create_vip(mock.Mock(), vip) - self.driver_mock.create_vip.assert_called_once_with(vip) - self.rpc_mock.update_status.assert_called_once_with('vip', vip['id'], - constants.ACTIVE) - - def test_create_vip_failed(self): - vip = {'id': 'id1', 'pool_id': '1'} - self.driver_mock.create_vip.side_effect = Exception - self.mgr.create_vip(mock.Mock(), vip) - self.driver_mock.create_vip.assert_called_once_with(vip) - self.rpc_mock.update_status.assert_called_once_with('vip', vip['id'], - constants.ERROR) - - def test_update_vip(self): - old_vip = {'id': 'id1'} - vip = {'id': 'id1', 'pool_id': '1'} - self.mgr.update_vip(mock.Mock(), old_vip, vip) - self.driver_mock.update_vip.assert_called_once_with(old_vip, vip) - self.rpc_mock.update_status.assert_called_once_with('vip', vip['id'], - constants.ACTIVE) - - def test_update_vip_failed(self): - old_vip = {'id': 'id1'} - vip = {'id': 'id1', 'pool_id': '1'} - self.driver_mock.update_vip.side_effect = Exception - self.mgr.update_vip(mock.Mock(), old_vip, vip) - self.driver_mock.update_vip.assert_called_once_with(old_vip, vip) - self.rpc_mock.update_status.assert_called_once_with('vip', vip['id'], - constants.ERROR) - - def test_delete_vip(self): - vip = {'id': 'id1', 'pool_id': '1'} - self.mgr.delete_vip(mock.Mock(), vip) - self.driver_mock.delete_vip.assert_called_once_with(vip) - - def test_create_pool(self): - pool = {'id': 'id1'} - self.assertNotIn(pool['id'], self.mgr.instance_mapping) - self.mgr.create_pool(mock.Mock(), pool, 'devdriver') - self.driver_mock.create_pool.assert_called_once_with(pool) - self.rpc_mock.update_status.assert_called_once_with('pool', pool['id'], - constants.ACTIVE) - self.assertIn(pool['id'], self.mgr.instance_mapping) - - def test_create_pool_failed(self): - pool = {'id': 'id1'} - self.assertNotIn(pool['id'], self.mgr.instance_mapping) - self.driver_mock.create_pool.side_effect = Exception - self.mgr.create_pool(mock.Mock(), pool, 'devdriver') - self.driver_mock.create_pool.assert_called_once_with(pool) - self.rpc_mock.update_status.assert_called_once_with('pool', pool['id'], - constants.ERROR) - self.assertNotIn(pool['id'], self.mgr.instance_mapping) - - def test_update_pool(self): - old_pool = {'id': '1'} - pool = {'id': '1'} - self.mgr.update_pool(mock.Mock(), old_pool, pool) - self.driver_mock.update_pool.assert_called_once_with(old_pool, pool) - self.rpc_mock.update_status.assert_called_once_with('pool', pool['id'], - constants.ACTIVE) - - def test_update_pool_failed(self): - old_pool = {'id': '1'} - pool = {'id': '1'} - self.driver_mock.update_pool.side_effect = Exception - self.mgr.update_pool(mock.Mock(), old_pool, pool) - self.driver_mock.update_pool.assert_called_once_with(old_pool, pool) - self.rpc_mock.update_status.assert_called_once_with('pool', pool['id'], - constants.ERROR) - - def test_delete_pool(self): - pool = {'id': '1'} - self.assertIn(pool['id'], self.mgr.instance_mapping) - self.mgr.delete_pool(mock.Mock(), pool) - self.driver_mock.delete_pool.assert_called_once_with(pool) - self.assertNotIn(pool['id'], self.mgr.instance_mapping) - - def test_create_member(self): - member = {'id': 'id1', 'pool_id': '1'} - self.mgr.create_member(mock.Mock(), member) - self.driver_mock.create_member.assert_called_once_with(member) - self.rpc_mock.update_status.assert_called_once_with('member', - member['id'], - constants.ACTIVE) - - def test_create_member_failed(self): - member = {'id': 'id1', 'pool_id': '1'} - self.driver_mock.create_member.side_effect = Exception - self.mgr.create_member(mock.Mock(), member) - self.driver_mock.create_member.assert_called_once_with(member) - self.rpc_mock.update_status.assert_called_once_with('member', - member['id'], - constants.ERROR) - - def test_update_member(self): - old_member = {'id': 'id1'} - member = {'id': 'id1', 'pool_id': '1'} - self.mgr.update_member(mock.Mock(), old_member, member) - self.driver_mock.update_member.assert_called_once_with(old_member, - member) - self.rpc_mock.update_status.assert_called_once_with('member', - member['id'], - constants.ACTIVE) - - def test_update_member_failed(self): - old_member = {'id': 'id1'} - member = {'id': 'id1', 'pool_id': '1'} - self.driver_mock.update_member.side_effect = Exception - self.mgr.update_member(mock.Mock(), old_member, member) - self.driver_mock.update_member.assert_called_once_with(old_member, - member) - self.rpc_mock.update_status.assert_called_once_with('member', - member['id'], - constants.ERROR) - - def test_delete_member(self): - member = {'id': 'id1', 'pool_id': '1'} - self.mgr.delete_member(mock.Mock(), member) - self.driver_mock.delete_member.assert_called_once_with(member) - - def test_create_monitor(self): - monitor = {'id': 'id1'} - assoc_id = {'monitor_id': monitor['id'], 'pool_id': '1'} - self.mgr.create_pool_health_monitor(mock.Mock(), monitor, '1') - self.driver_mock.create_pool_health_monitor.assert_called_once_with( - monitor, '1') - self.rpc_mock.update_status.assert_called_once_with('health_monitor', - assoc_id, - constants.ACTIVE) - - def test_create_monitor_failed(self): - monitor = {'id': 'id1'} - assoc_id = {'monitor_id': monitor['id'], 'pool_id': '1'} - self.driver_mock.create_pool_health_monitor.side_effect = Exception - self.mgr.create_pool_health_monitor(mock.Mock(), monitor, '1') - self.driver_mock.create_pool_health_monitor.assert_called_once_with( - monitor, '1') - self.rpc_mock.update_status.assert_called_once_with('health_monitor', - assoc_id, - constants.ERROR) - - def test_update_monitor(self): - monitor = {'id': 'id1'} - assoc_id = {'monitor_id': monitor['id'], 'pool_id': '1'} - self.mgr.update_pool_health_monitor(mock.Mock(), monitor, monitor, '1') - self.driver_mock.update_pool_health_monitor.assert_called_once_with( - monitor, monitor, '1') - self.rpc_mock.update_status.assert_called_once_with('health_monitor', - assoc_id, - constants.ACTIVE) - - def test_update_monitor_failed(self): - monitor = {'id': 'id1'} - assoc_id = {'monitor_id': monitor['id'], 'pool_id': '1'} - self.driver_mock.update_pool_health_monitor.side_effect = Exception - self.mgr.update_pool_health_monitor(mock.Mock(), monitor, monitor, '1') - self.driver_mock.update_pool_health_monitor.assert_called_once_with( - monitor, monitor, '1') - self.rpc_mock.update_status.assert_called_once_with('health_monitor', - assoc_id, - constants.ERROR) - - def test_delete_monitor(self): - monitor = {'id': 'id1'} - self.mgr.delete_pool_health_monitor(mock.Mock(), monitor, '1') - self.driver_mock.delete_pool_health_monitor.assert_called_once_with( - monitor, '1') - - def test_agent_disabled(self): - payload = {'admin_state_up': False} - self.mgr.agent_updated(mock.Mock(), payload) - self.driver_mock.undeploy_instance.assert_has_calls( - [mock.call('1'), mock.call('2')]) diff --git a/neutron/tests/unit/services/loadbalancer/agent/test_api.py b/neutron/tests/unit/services/loadbalancer/agent/test_api.py deleted file mode 100644 index 94513ee9d..000000000 --- a/neutron/tests/unit/services/loadbalancer/agent/test_api.py +++ /dev/null @@ -1,166 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost - -import mock - -from neutron.services.loadbalancer.agent import agent_api as api -from neutron.tests import base - - -class TestApiCache(base.BaseTestCase): - def setUp(self): - super(TestApiCache, self).setUp() - - self.api = api.LbaasAgentApi('topic', mock.sentinel.context, 'host') - self.make_msg = mock.patch.object(self.api, 'make_msg').start() - self.mock_call = mock.patch.object(self.api, 'call').start() - - def test_init(self): - self.assertEqual(self.api.host, 'host') - self.assertEqual(self.api.context, mock.sentinel.context) - - def test_get_ready_devices(self): - self.assertEqual( - self.api.get_ready_devices(), - self.mock_call.return_value - ) - - self.make_msg.assert_called_once_with('get_ready_devices', host='host') - self.mock_call.assert_called_once_with( - mock.sentinel.context, - self.make_msg.return_value, - topic='topic' - ) - - def test_get_logical_device(self): - self.assertEqual( - self.api.get_logical_device('pool_id'), - self.mock_call.return_value - ) - - self.make_msg.assert_called_once_with( - 'get_logical_device', - pool_id='pool_id') - - self.mock_call.assert_called_once_with( - mock.sentinel.context, - self.make_msg.return_value, - topic='topic' - ) - - def test_pool_destroyed(self): - self.assertEqual( - self.api.pool_destroyed('pool_id'), - self.mock_call.return_value - ) - - self.make_msg.assert_called_once_with( - 'pool_destroyed', - pool_id='pool_id') - - self.mock_call.assert_called_once_with( - mock.sentinel.context, - self.make_msg.return_value, - topic='topic' - ) - - def test_pool_deployed(self): - self.assertEqual( - self.api.pool_deployed('pool_id'), - self.mock_call.return_value - ) - - self.make_msg.assert_called_once_with( - 'pool_deployed', - pool_id='pool_id') - - self.mock_call.assert_called_once_with( - mock.sentinel.context, - self.make_msg.return_value, - topic='topic' - ) - - def test_update_status(self): - self.assertEqual( - self.api.update_status('pool', 'pool_id', 'ACTIVE'), - self.mock_call.return_value - ) - - self.make_msg.assert_called_once_with( - 'update_status', - obj_type='pool', - obj_id='pool_id', - status='ACTIVE') - - self.mock_call.assert_called_once_with( - mock.sentinel.context, - self.make_msg.return_value, - topic='topic' - ) - - def test_plug_vip_port(self): - self.assertEqual( - self.api.plug_vip_port('port_id'), - self.mock_call.return_value - ) - - self.make_msg.assert_called_once_with( - 'plug_vip_port', - port_id='port_id', - host='host') - - self.mock_call.assert_called_once_with( - mock.sentinel.context, - self.make_msg.return_value, - topic='topic' - ) - - def test_unplug_vip_port(self): - self.assertEqual( - self.api.unplug_vip_port('port_id'), - self.mock_call.return_value - ) - - self.make_msg.assert_called_once_with( - 'unplug_vip_port', - port_id='port_id', - host='host') - - self.mock_call.assert_called_once_with( - mock.sentinel.context, - self.make_msg.return_value, - topic='topic' - ) - - def test_update_pool_stats(self): - self.assertEqual( - self.api.update_pool_stats('pool_id', {'stat': 'stat'}), - self.mock_call.return_value - ) - - self.make_msg.assert_called_once_with( - 'update_pool_stats', - pool_id='pool_id', - stats={'stat': 'stat'}, - host='host') - - self.mock_call.assert_called_once_with( - mock.sentinel.context, - self.make_msg.return_value, - topic='topic' - ) diff --git a/neutron/tests/unit/services/loadbalancer/drivers/__init__.py b/neutron/tests/unit/services/loadbalancer/drivers/__init__.py deleted file mode 100644 index ce18bf6d6..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost diff --git a/neutron/tests/unit/services/loadbalancer/drivers/embrane/__init__.py b/neutron/tests/unit/services/loadbalancer/drivers/embrane/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/services/loadbalancer/drivers/embrane/test_embrane_defaults.py b/neutron/tests/unit/services/loadbalancer/drivers/embrane/test_embrane_defaults.py deleted file mode 100644 index cffb2ae37..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/embrane/test_embrane_defaults.py +++ /dev/null @@ -1,30 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Embrane, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Ivar Lazzaro, Embrane, Inc. - -from oslo.config import cfg - -from neutron.services.loadbalancer.drivers.embrane import config # noqa -from neutron.tests import base - - -class ConfigurationTest(base.BaseTestCase): - - def test_defaults(self): - self.assertEqual('small', cfg.CONF.heleoslb.lb_flavor) - self.assertEqual(60, cfg.CONF.heleoslb.sync_interval) diff --git a/neutron/tests/unit/services/loadbalancer/drivers/embrane/test_plugin_driver.py b/neutron/tests/unit/services/loadbalancer/drivers/embrane/test_plugin_driver.py deleted file mode 100644 index 56a02a208..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/embrane/test_plugin_driver.py +++ /dev/null @@ -1,93 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Embrane, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Ivar Lazzaro, Embrane, Inc. ivar@embrane.com - -import sys - -import mock -from oslo.config import cfg - -from neutron import context -from neutron.openstack.common.db import exception as n_exc -from neutron.tests.unit.db.loadbalancer import test_db_loadbalancer - -HELEOSAPIMOCK = mock.Mock() -sys.modules["heleosapi"] = HELEOSAPIMOCK -from neutron.services.loadbalancer.drivers.embrane import config # noqa -from neutron.services.loadbalancer.drivers.embrane import constants as h_con -from neutron.services.loadbalancer.drivers.embrane import db as h_db -# Stop the mock from persisting indefinitely in the global modules space -del sys.modules["heleosapi"] - -EMBRANE_PROVIDER = ('LOADBALANCER:lbaas:neutron.services.' - 'loadbalancer.drivers.embrane.driver.' - 'EmbraneLbaas:default') - - -class TestLoadBalancerPluginBase( - test_db_loadbalancer.LoadBalancerPluginDbTestCase): - - def setUp(self): - cfg.CONF.set_override('admin_password', "admin123", 'heleoslb') - cfg.CONF.set_override('sync_interval', 0, 'heleoslb') - mock.patch.dict(sys.modules, {'heleosapi': HELEOSAPIMOCK}).start() - super(TestLoadBalancerPluginBase, self).setUp( - lbaas_provider=EMBRANE_PROVIDER) - self.driver = self.plugin.drivers['lbaas'] - # prevent module mock from saving calls between tests - self.addCleanup(HELEOSAPIMOCK.reset_mock) - - -class TestLoadBalancerPlugin(test_db_loadbalancer.TestLoadBalancer, - TestLoadBalancerPluginBase): - - def test_create_vip_with_session_persistence_with_app_cookie(self): - self.skip("App cookie persistence not supported.") - - def test_pool_port(self): - with self.port(no_delete=True) as port: - with self.pool() as pool: - h_db.add_pool_port(context.get_admin_context(), - pool['pool']['id'], port['port']['id']) - pool_port = h_db.get_pool_port(context.get_admin_context(), - pool['pool']['id']) - self.assertIsNotNone(pool_port) - pool_port = h_db.get_pool_port(context.get_admin_context(), - pool['pool']['id']) - self.assertIsNone(pool_port) - - def test_create_pool_port_no_port(self): - with self.pool() as pool: - self.assertRaises(n_exc.DBError, - h_db.add_pool_port, - context.get_admin_context(), - pool['pool']['id'], None) - - def test_lb_operations_handlers(self): - h = self.driver._dispatcher.handlers - self.assertIsNotNone(h[h_con.Events.ADD_OR_UPDATE_MEMBER]) - self.assertIsNotNone(h[h_con.Events.CREATE_VIP]) - self.assertIsNotNone(h[h_con.Events.DELETE_MEMBER]) - self.assertIsNotNone(h[h_con.Events.DELETE_VIP]) - self.assertIsNotNone(h[h_con.Events.POLL_GRAPH]) - self.assertIsNotNone(h[h_con.Events.REMOVE_MEMBER]) - self.assertIsNotNone(h[h_con.Events.UPDATE_POOL]) - self.assertIsNotNone(h[h_con.Events.UPDATE_VIP]) - self.assertIsNotNone(h[h_con.Events.UPDATE_POOL_HM]) - self.assertIsNotNone(h[h_con.Events.DELETE_POOL_HM]) - self.assertIsNotNone(h[h_con.Events.ADD_POOL_HM]) diff --git a/neutron/tests/unit/services/loadbalancer/drivers/haproxy/__init__.py b/neutron/tests/unit/services/loadbalancer/drivers/haproxy/__init__.py deleted file mode 100644 index ce18bf6d6..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/haproxy/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost diff --git a/neutron/tests/unit/services/loadbalancer/drivers/haproxy/test_cfg.py b/neutron/tests/unit/services/loadbalancer/drivers/haproxy/test_cfg.py deleted file mode 100644 index a35e15936..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/haproxy/test_cfg.py +++ /dev/null @@ -1,228 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 Mirantis, Inc. -# All Rights Reserved. -# -# 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. -# -# @author: Oleg Bondarev (obondarev@mirantis.com) - -import contextlib - -import mock - -from neutron.services.loadbalancer.drivers.haproxy import cfg -from neutron.tests import base - - -class TestHaproxyCfg(base.BaseTestCase): - def test_save_config(self): - with contextlib.nested( - mock.patch('neutron.services.loadbalancer.' - 'drivers.haproxy.cfg._build_global'), - mock.patch('neutron.services.loadbalancer.' - 'drivers.haproxy.cfg._build_defaults'), - mock.patch('neutron.services.loadbalancer.' - 'drivers.haproxy.cfg._build_frontend'), - mock.patch('neutron.services.loadbalancer.' - 'drivers.haproxy.cfg._build_backend'), - mock.patch('neutron.agent.linux.utils.replace_file') - ) as (b_g, b_d, b_f, b_b, replace): - test_config = ['globals', 'defaults', 'frontend', 'backend'] - b_g.return_value = [test_config[0]] - b_d.return_value = [test_config[1]] - b_f.return_value = [test_config[2]] - b_b.return_value = [test_config[3]] - - cfg.save_config('test_path', mock.Mock()) - replace.assert_called_once_with('test_path', - '\n'.join(test_config)) - - def test_build_global(self): - expected_opts = ['global', - '\tdaemon', - '\tuser nobody', - '\tgroup test_group', - '\tlog /dev/log local0', - '\tlog /dev/log local1 notice', - '\tstats socket test_path mode 0666 level user'] - opts = cfg._build_global(mock.Mock(), 'test_path', 'test_group') - self.assertEqual(expected_opts, list(opts)) - - def test_build_defaults(self): - expected_opts = ['defaults', - '\tlog global', - '\tretries 3', - '\toption redispatch', - '\ttimeout connect 5000', - '\ttimeout client 50000', - '\ttimeout server 50000'] - opts = cfg._build_defaults(mock.Mock()) - self.assertEqual(expected_opts, list(opts)) - - def test_build_frontend(self): - test_config = {'vip': {'id': 'vip_id', - 'protocol': 'HTTP', - 'port': {'fixed_ips': [ - {'ip_address': '10.0.0.2'}] - }, - 'protocol_port': 80, - 'connection_limit': 2000, - }, - 'pool': {'id': 'pool_id'}} - expected_opts = ['frontend vip_id', - '\toption tcplog', - '\tbind 10.0.0.2:80', - '\tmode http', - '\tdefault_backend pool_id', - '\tmaxconn 2000', - '\toption forwardfor'] - opts = cfg._build_frontend(test_config) - self.assertEqual(expected_opts, list(opts)) - - test_config['vip']['connection_limit'] = -1 - expected_opts.remove('\tmaxconn 2000') - opts = cfg._build_frontend(test_config) - self.assertEqual(expected_opts, list(opts)) - - def test_build_backend(self): - test_config = {'pool': {'id': 'pool_id', - 'protocol': 'HTTP', - 'lb_method': 'ROUND_ROBIN'}, - 'members': [{'status': 'ACTIVE', - 'admin_state_up': True, - 'id': 'member1_id', - 'address': '10.0.0.3', - 'protocol_port': 80, - 'weight': 1}, - {'status': 'INACTIVE', - 'admin_state_up': True, - 'id': 'member2_id', - 'address': '10.0.0.4', - 'protocol_port': 80, - 'weight': 1}, - {'status': 'PENDING_CREATE', - 'admin_state_up': True, - 'id': 'member3_id', - 'address': '10.0.0.5', - 'protocol_port': 80, - 'weight': 1}], - 'healthmonitors': [{'admin_state_up': True, - 'delay': 3, - 'max_retries': 4, - 'timeout': 2, - 'type': 'TCP'}], - 'vip': {'session_persistence': {'type': 'HTTP_COOKIE'}}} - expected_opts = ['backend pool_id', - '\tmode http', - '\tbalance roundrobin', - '\toption forwardfor', - '\ttimeout check 2s', - '\tcookie SRV insert indirect nocache', - '\tserver member1_id 10.0.0.3:80 weight 1 ' - 'check inter 3s fall 4 cookie 0', - '\tserver member2_id 10.0.0.4:80 weight 1 ' - 'check inter 3s fall 4 cookie 1', - '\tserver member3_id 10.0.0.5:80 weight 1 ' - 'check inter 3s fall 4 cookie 2'] - opts = cfg._build_backend(test_config) - self.assertEqual(expected_opts, list(opts)) - - def test_get_server_health_option(self): - test_config = {'healthmonitors': [{'admin_state_up': False, - 'delay': 3, - 'max_retries': 4, - 'timeout': 2, - 'type': 'TCP', - 'http_method': 'GET', - 'url_path': '/', - 'expected_codes': '200'}]} - self.assertEqual(('', []), cfg._get_server_health_option(test_config)) - - self.assertEqual(('', []), cfg._get_server_health_option(test_config)) - - test_config['healthmonitors'][0]['admin_state_up'] = True - expected = (' check inter 3s fall 4', ['timeout check 2s']) - self.assertEqual(expected, cfg._get_server_health_option(test_config)) - - test_config['healthmonitors'][0]['type'] = 'HTTPS' - expected = (' check inter 3s fall 4', - ['timeout check 2s', - 'option httpchk GET /', - 'http-check expect rstatus 200', - 'option ssl-hello-chk']) - self.assertEqual(expected, cfg._get_server_health_option(test_config)) - - def test_has_http_cookie_persistence(self): - config = {'vip': {'session_persistence': {'type': 'HTTP_COOKIE'}}} - self.assertTrue(cfg._has_http_cookie_persistence(config)) - - config = {'vip': {'session_persistence': {'type': 'SOURCE_IP'}}} - self.assertFalse(cfg._has_http_cookie_persistence(config)) - - config = {'vip': {'session_persistence': {}}} - self.assertFalse(cfg._has_http_cookie_persistence(config)) - - def test_get_session_persistence(self): - config = {'vip': {'session_persistence': {'type': 'SOURCE_IP'}}} - self.assertEqual(cfg._get_session_persistence(config), - ['stick-table type ip size 10k', 'stick on src']) - - config = {'vip': {'session_persistence': {'type': 'HTTP_COOKIE'}}, - 'members': []} - self.assertEqual([], cfg._get_session_persistence(config)) - - config = {'vip': {'session_persistence': {'type': 'HTTP_COOKIE'}}} - self.assertEqual([], cfg._get_session_persistence(config)) - - config = {'vip': {'session_persistence': {'type': 'HTTP_COOKIE'}}, - 'members': [{'id': 'member1_id'}]} - self.assertEqual(cfg._get_session_persistence(config), - ['cookie SRV insert indirect nocache']) - - config = {'vip': {'session_persistence': {'type': 'APP_COOKIE', - 'cookie_name': 'test'}}} - self.assertEqual(cfg._get_session_persistence(config), - ['appsession test len 56 timeout 3h']) - - config = {'vip': {'session_persistence': {'type': 'APP_COOKIE'}}} - self.assertEqual(cfg._get_session_persistence(config), []) - - config = {'vip': {'session_persistence': {'type': 'UNSUPPORTED'}}} - self.assertEqual(cfg._get_session_persistence(config), []) - - def test_expand_expected_codes(self): - exp_codes = '' - self.assertEqual(cfg._expand_expected_codes(exp_codes), set([])) - exp_codes = '200' - self.assertEqual(cfg._expand_expected_codes(exp_codes), set(['200'])) - exp_codes = '200, 201' - self.assertEqual(cfg._expand_expected_codes(exp_codes), - set(['200', '201'])) - exp_codes = '200, 201,202' - self.assertEqual(cfg._expand_expected_codes(exp_codes), - set(['200', '201', '202'])) - exp_codes = '200-202' - self.assertEqual(cfg._expand_expected_codes(exp_codes), - set(['200', '201', '202'])) - exp_codes = '200-202, 205' - self.assertEqual(cfg._expand_expected_codes(exp_codes), - set(['200', '201', '202', '205'])) - exp_codes = '200, 201-203' - self.assertEqual(cfg._expand_expected_codes(exp_codes), - set(['200', '201', '202', '203'])) - exp_codes = '200, 201-203, 205' - self.assertEqual(cfg._expand_expected_codes(exp_codes), - set(['200', '201', '202', '203', '205'])) - exp_codes = '201-200, 205' - self.assertEqual(cfg._expand_expected_codes(exp_codes), set(['205'])) diff --git a/neutron/tests/unit/services/loadbalancer/drivers/haproxy/test_namespace_driver.py b/neutron/tests/unit/services/loadbalancer/drivers/haproxy/test_namespace_driver.py deleted file mode 100644 index 450727bc2..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/haproxy/test_namespace_driver.py +++ /dev/null @@ -1,550 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost - -import contextlib - -import mock - -from neutron.common import exceptions -from neutron.services.loadbalancer.drivers.haproxy import namespace_driver -from neutron.tests import base - - -class TestHaproxyNSDriver(base.BaseTestCase): - def setUp(self): - super(TestHaproxyNSDriver, self).setUp() - - conf = mock.Mock() - conf.haproxy.loadbalancer_state_path = '/the/path' - conf.interface_driver = 'intdriver' - conf.haproxy.user_group = 'test_group' - conf.haproxy.send_gratuitous_arp = 3 - conf.AGENT.root_helper = 'sudo_test' - self.conf = conf - self.mock_importer = mock.patch.object(namespace_driver, - 'importutils').start() - - self.rpc_mock = mock.Mock() - self.driver = namespace_driver.HaproxyNSDriver( - conf, - self.rpc_mock - ) - self.vif_driver = mock.Mock() - self.driver.vif_driver = self.vif_driver - - self.fake_config = { - 'pool': {'id': 'pool_id', 'status': 'ACTIVE', - 'admin_state_up': True}, - 'vip': {'id': 'vip_id', 'port': {'id': 'port_id'}, - 'status': 'ACTIVE', 'admin_state_up': True} - } - - def test_get_name(self): - self.assertEqual(self.driver.get_name(), namespace_driver.DRIVER_NAME) - - def test_create(self): - with mock.patch.object(self.driver, '_plug') as plug: - with mock.patch.object(self.driver, '_spawn') as spawn: - self.driver.create(self.fake_config) - - plug.assert_called_once_with( - 'qlbaas-pool_id', {'id': 'port_id'} - ) - spawn.assert_called_once_with(self.fake_config) - - def test_update(self): - with contextlib.nested( - mock.patch.object(self.driver, '_get_state_file_path'), - mock.patch.object(self.driver, '_spawn'), - mock.patch('__builtin__.open') - ) as (gsp, spawn, mock_open): - mock_open.return_value = ['5'] - - self.driver.update(self.fake_config) - - mock_open.assert_called_once_with(gsp.return_value, 'r') - spawn.assert_called_once_with(self.fake_config, ['-sf', '5']) - - def test_spawn(self): - with contextlib.nested( - mock.patch.object(namespace_driver.hacfg, 'save_config'), - mock.patch.object(self.driver, '_get_state_file_path'), - mock.patch('neutron.agent.linux.ip_lib.IPWrapper') - ) as (mock_save, gsp, ip_wrap): - gsp.side_effect = lambda x, y: y - - self.driver._spawn(self.fake_config) - - mock_save.assert_called_once_with('conf', self.fake_config, - 'sock', 'test_group') - cmd = ['haproxy', '-f', 'conf', '-p', 'pid'] - ip_wrap.assert_has_calls([ - mock.call('sudo_test', 'qlbaas-pool_id'), - mock.call().netns.execute(cmd) - ]) - - def test_undeploy_instance(self): - with contextlib.nested( - mock.patch.object(self.driver, '_get_state_file_path'), - mock.patch.object(namespace_driver, 'kill_pids_in_file'), - mock.patch.object(self.driver, '_unplug'), - mock.patch('neutron.agent.linux.ip_lib.IPWrapper'), - mock.patch('os.path.isdir'), - mock.patch('shutil.rmtree') - ) as (gsp, kill, unplug, ip_wrap, isdir, rmtree): - gsp.side_effect = lambda x, y: '/pool/' + y - - self.driver.pool_to_port_id['pool_id'] = 'port_id' - isdir.return_value = True - - self.driver.undeploy_instance('pool_id') - - kill.assert_called_once_with('sudo_test', '/pool/pid') - unplug.assert_called_once_with('qlbaas-pool_id', 'port_id') - isdir.assert_called_once_with('/pool') - rmtree.assert_called_once_with('/pool') - ip_wrap.assert_has_calls([ - mock.call('sudo_test', 'qlbaas-pool_id'), - mock.call().garbage_collect_namespace() - ]) - - def test_undeploy_instance_with_ns_cleanup(self): - with contextlib.nested( - mock.patch.object(self.driver, '_get_state_file_path'), - mock.patch.object(self.driver, 'vif_driver'), - mock.patch.object(namespace_driver, 'kill_pids_in_file'), - mock.patch('neutron.agent.linux.ip_lib.IPWrapper'), - mock.patch('os.path.isdir'), - mock.patch('shutil.rmtree') - ) as (gsp, vif, kill, ip_wrap, isdir, rmtree): - device = mock.Mock() - device_name = 'port_device' - device.name = device_name - ip_wrap.return_value.get_devices.return_value = [device] - - self.driver.undeploy_instance('pool_id', cleanup_namespace=True) - vif.unplug.assert_called_once_with(device_name, - namespace='qlbaas-pool_id') - - def test_remove_orphans(self): - with contextlib.nested( - mock.patch.object(self.driver, 'exists'), - mock.patch.object(self.driver, 'undeploy_instance'), - mock.patch('os.listdir'), - mock.patch('os.path.exists') - ) as (exists, undeploy, listdir, path_exists): - known = ['known1', 'known2'] - unknown = ['unknown1', 'unknown2'] - listdir.return_value = known + unknown - exists.side_effect = lambda x: x == 'unknown2' - - self.driver.remove_orphans(known) - - undeploy.assert_called_once_with('unknown2', - cleanup_namespace=True) - - def test_exists(self): - with contextlib.nested( - mock.patch.object(self.driver, '_get_state_file_path'), - mock.patch('neutron.agent.linux.ip_lib.IPWrapper'), - mock.patch('socket.socket'), - mock.patch('os.path.exists'), - ) as (gsp, ip_wrap, socket, path_exists): - gsp.side_effect = lambda x, y: '/pool/' + y - - ip_wrap.return_value.netns.exists.return_value = True - path_exists.return_value = True - - self.driver.exists('pool_id') - - ip_wrap.assert_has_calls([ - mock.call('sudo_test'), - mock.call().netns.exists('qlbaas-pool_id') - ]) - - self.assertTrue(self.driver.exists('pool_id')) - - def test_get_stats(self): - raw_stats = ('# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,' - 'dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,' - 'act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,' - 'sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,' - 'check_status,check_code,check_duration,hrsp_1xx,' - 'hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,' - 'req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,\n' - '8e271901-69ed-403e-a59b-f53cf77ef208,BACKEND,1,2,3,4,0,' - '10,7764,2365,0,0,,0,0,0,0,UP,1,1,0,,0,103780,0,,1,2,0,,0' - ',,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0,\n\n' - 'a557019b-dc07-4688-9af4-f5cf02bb6d4b,' - '32a6c2a3-420a-44c3-955d-86bd2fc6871e,0,0,0,1,,7,1120,' - '224,,0,,0,0,0,0,UP,1,1,0,0,1,2623,303,,1,2,1,,7,,2,0,,' - '1,L7OK,200,98,0,7,0,0,0,0,0,,,,0,0,\n' - 'a557019b-dc07-4688-9af4-f5cf02bb6d4b,' - 'd9aea044-8867-4e80-9875-16fb808fa0f9,0,0,0,2,,12,0,0,,' - '0,,0,0,8,4,DOWN,1,1,0,9,2,308,675,,1,2,2,,4,,2,0,,2,' - 'L4CON,,2999,0,0,0,0,0,0,0,,,,0,0,\n') - raw_stats_empty = ('# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,' - 'bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,' - 'status,weight,act,bck,chkfail,chkdown,lastchg,' - 'downtime,qlimit,pid,iid,sid,throttle,lbtot,' - 'tracked,type,rate,rate_lim,rate_max,check_status,' - 'check_code,check_duration,hrsp_1xx,hrsp_2xx,' - 'hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,' - 'req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,' - '\n') - with contextlib.nested( - mock.patch.object(self.driver, '_get_state_file_path'), - mock.patch('socket.socket'), - mock.patch('os.path.exists'), - ) as (gsp, socket, path_exists): - gsp.side_effect = lambda x, y: '/pool/' + y - path_exists.return_value = True - socket.return_value = socket - socket.recv.return_value = raw_stats - - exp_stats = {'connection_errors': '0', - 'active_connections': '3', - 'current_sessions': '3', - 'bytes_in': '7764', - 'max_connections': '4', - 'max_sessions': '4', - 'bytes_out': '2365', - 'response_errors': '0', - 'total_sessions': '10', - 'total_connections': '10', - 'members': { - '32a6c2a3-420a-44c3-955d-86bd2fc6871e': { - 'status': 'ACTIVE', - 'health': 'L7OK', - 'failed_checks': '0' - }, - 'd9aea044-8867-4e80-9875-16fb808fa0f9': { - 'status': 'INACTIVE', - 'health': 'L4CON', - 'failed_checks': '9' - } - } - } - stats = self.driver.get_stats('pool_id') - self.assertEqual(exp_stats, stats) - - socket.recv.return_value = raw_stats_empty - self.assertEqual({'members': {}}, self.driver.get_stats('pool_id')) - - path_exists.return_value = False - socket.reset_mock() - self.assertEqual({}, self.driver.get_stats('pool_id')) - self.assertFalse(socket.called) - - def test_plug(self): - test_port = {'id': 'port_id', - 'network_id': 'net_id', - 'mac_address': 'mac_addr', - 'fixed_ips': [{'ip_address': '10.0.0.2', - 'subnet': {'cidr': '10.0.0.0/24', - 'gateway_ip': '10.0.0.1'}}]} - with contextlib.nested( - mock.patch('neutron.agent.linux.ip_lib.device_exists'), - mock.patch('netaddr.IPNetwork'), - mock.patch('neutron.agent.linux.ip_lib.IPWrapper'), - ) as (dev_exists, ip_net, ip_wrap): - self.vif_driver.get_device_name.return_value = 'test_interface' - dev_exists.return_value = False - ip_net.return_value = ip_net - ip_net.prefixlen = 24 - - self.driver._plug('test_ns', test_port) - self.rpc_mock.plug_vip_port.assert_called_once_with( - test_port['id']) - self.assertTrue(dev_exists.called) - self.vif_driver.plug.assert_called_once_with('net_id', 'port_id', - 'test_interface', - 'mac_addr', - namespace='test_ns') - self.vif_driver.init_l3.assert_called_once_with('test_interface', - ['10.0.0.2/24'], - namespace= - 'test_ns') - cmd = ['route', 'add', 'default', 'gw', '10.0.0.1'] - cmd_arping = ['arping', '-U', '-I', - 'test_interface', '-c', - self.conf.haproxy.send_gratuitous_arp, '10.0.0.2'] - ip_wrap.assert_has_calls([ - mock.call('sudo_test', namespace='test_ns'), - mock.call().netns.execute(cmd, check_exit_code=False), - mock.call().netns.execute(cmd_arping, check_exit_code=False), - ]) - - dev_exists.return_value = True - self.assertRaises(exceptions.PreexistingDeviceFailure, - self.driver._plug, 'test_ns', test_port, False) - - def test_plug_not_send_gratuitous_arp(self): - self.conf.haproxy.send_gratuitous_arp = 0 - test_port = {'id': 'port_id', - 'network_id': 'net_id', - 'mac_address': 'mac_addr', - 'fixed_ips': [{'ip_address': '10.0.0.2', - 'subnet': {'cidr': '10.0.0.0/24', - 'gateway_ip': '10.0.0.1'}}]} - with contextlib.nested( - mock.patch('neutron.agent.linux.ip_lib.device_exists'), - mock.patch('netaddr.IPNetwork'), - mock.patch('neutron.agent.linux.ip_lib.IPWrapper'), - ) as (dev_exists, ip_net, ip_wrap): - self.vif_driver.get_device_name.return_value = 'test_interface' - dev_exists.return_value = False - ip_net.return_value = ip_net - ip_net.prefixlen = 24 - - self.driver._plug('test_ns', test_port) - cmd = ['route', 'add', 'default', 'gw', '10.0.0.1'] - expected = [ - mock.call('sudo_test', namespace='test_ns'), - mock.call().netns.execute(cmd, check_exit_code=False)] - self.assertEqual(expected, ip_wrap.mock_calls) - - def test_plug_no_gw(self): - test_port = {'id': 'port_id', - 'network_id': 'net_id', - 'mac_address': 'mac_addr', - 'fixed_ips': [{'ip_address': '10.0.0.2', - 'subnet': {'cidr': '10.0.0.0/24'}}]} - with contextlib.nested( - mock.patch('neutron.agent.linux.ip_lib.device_exists'), - mock.patch('netaddr.IPNetwork'), - mock.patch('neutron.agent.linux.ip_lib.IPWrapper'), - ) as (dev_exists, ip_net, ip_wrap): - self.vif_driver.get_device_name.return_value = 'test_interface' - dev_exists.return_value = False - ip_net.return_value = ip_net - ip_net.prefixlen = 24 - - self.driver._plug('test_ns', test_port) - self.rpc_mock.plug_vip_port.assert_called_once_with( - test_port['id']) - self.assertTrue(dev_exists.called) - self.vif_driver.plug.assert_called_once_with('net_id', 'port_id', - 'test_interface', - 'mac_addr', - namespace='test_ns') - self.vif_driver.init_l3.assert_called_once_with('test_interface', - ['10.0.0.2/24'], - namespace= - 'test_ns') - self.assertFalse(ip_wrap.called) - dev_exists.return_value = True - self.assertRaises(exceptions.PreexistingDeviceFailure, - self.driver._plug, 'test_ns', test_port, False) - - def test_plug_gw_in_host_routes(self): - test_port = {'id': 'port_id', - 'network_id': 'net_id', - 'mac_address': 'mac_addr', - 'fixed_ips': [{'ip_address': '10.0.0.2', - 'subnet': {'cidr': '10.0.0.0/24', - 'host_routes': - [{'destination': '0.0.0.0/0', - 'nexthop': '10.0.0.1'}]}}]} - with contextlib.nested( - mock.patch('neutron.agent.linux.ip_lib.device_exists'), - mock.patch('netaddr.IPNetwork'), - mock.patch('neutron.agent.linux.ip_lib.IPWrapper'), - ) as (dev_exists, ip_net, ip_wrap): - self.vif_driver.get_device_name.return_value = 'test_interface' - dev_exists.return_value = False - ip_net.return_value = ip_net - ip_net.prefixlen = 24 - - self.driver._plug('test_ns', test_port) - self.rpc_mock.plug_vip_port.assert_called_once_with( - test_port['id']) - self.assertTrue(dev_exists.called) - self.vif_driver.plug.assert_called_once_with('net_id', 'port_id', - 'test_interface', - 'mac_addr', - namespace='test_ns') - self.vif_driver.init_l3.assert_called_once_with('test_interface', - ['10.0.0.2/24'], - namespace= - 'test_ns') - cmd = ['route', 'add', 'default', 'gw', '10.0.0.1'] - ip_wrap.assert_has_calls([ - mock.call('sudo_test', namespace='test_ns'), - mock.call().netns.execute(cmd, check_exit_code=False), - ]) - - def test_unplug(self): - self.vif_driver.get_device_name.return_value = 'test_interface' - - self.driver._unplug('test_ns', 'port_id') - self.rpc_mock.unplug_vip_port.assert_called_once_with('port_id') - self.vif_driver.unplug('test_interface', namespace='test_ns') - - def test_kill_pids_in_file(self): - with contextlib.nested( - mock.patch('os.path.exists'), - mock.patch('__builtin__.open'), - mock.patch('neutron.agent.linux.utils.execute'), - mock.patch.object(namespace_driver.LOG, 'exception'), - ) as (path_exists, mock_open, mock_execute, mock_log): - file_mock = mock.MagicMock() - mock_open.return_value = file_mock - file_mock.__enter__.return_value = file_mock - file_mock.__iter__.return_value = iter(['123']) - - path_exists.return_value = False - namespace_driver.kill_pids_in_file('sudo_test', 'test_path') - path_exists.assert_called_once_with('test_path') - self.assertFalse(mock_open.called) - self.assertFalse(mock_execute.called) - - path_exists.return_value = True - mock_execute.side_effect = RuntimeError - namespace_driver.kill_pids_in_file('sudo_test', 'test_path') - self.assertTrue(mock_log.called) - mock_execute.assert_called_once_with( - ['kill', '-9', '123'], 'sudo_test') - - def test_get_state_file_path(self): - with mock.patch('os.makedirs') as mkdir: - path = self.driver._get_state_file_path('pool_id', 'conf') - self.assertEqual('/the/path/pool_id/conf', path) - mkdir.assert_called_once_with('/the/path/pool_id', 0o755) - - def test_deploy_instance(self): - with mock.patch.object(self.driver, 'exists') as exists: - with mock.patch.object(self.driver, 'update') as update: - self.driver.deploy_instance(self.fake_config) - exists.assert_called_once_with(self.fake_config['pool']['id']) - update.assert_called_once_with(self.fake_config) - - def test_deploy_instance_non_existing(self): - with mock.patch.object(self.driver, 'exists') as exists: - with mock.patch.object(self.driver, 'create') as create: - exists.return_value = False - self.driver.deploy_instance(self.fake_config) - exists.assert_called_once_with(self.fake_config['pool']['id']) - create.assert_called_once_with(self.fake_config) - - def test_deploy_instance_vip_status_non_active(self): - with mock.patch.object(self.driver, 'exists') as exists: - self.fake_config['vip']['status'] = 'NON_ACTIVE' - self.driver.deploy_instance(self.fake_config) - self.assertFalse(exists.called) - - def test_deploy_instance_vip_admin_state_down(self): - with mock.patch.object(self.driver, 'exists') as exists: - self.fake_config['vip']['admin_state_up'] = False - self.driver.deploy_instance(self.fake_config) - self.assertFalse(exists.called) - - def test_deploy_instance_no_vip(self): - with mock.patch.object(self.driver, 'exists') as exists: - del self.fake_config['vip'] - self.driver.deploy_instance(self.fake_config) - self.assertFalse(exists.called) - - def test_deploy_instance_pool_status_non_active(self): - with mock.patch.object(self.driver, 'exists') as exists: - self.fake_config['pool']['status'] = 'NON_ACTIVE' - self.driver.deploy_instance(self.fake_config) - self.assertFalse(exists.called) - - def test_deploy_instance_pool_admin_state_down(self): - with mock.patch.object(self.driver, 'exists') as exists: - self.fake_config['pool']['admin_state_up'] = False - self.driver.deploy_instance(self.fake_config) - self.assertFalse(exists.called) - - def test_refresh_device(self): - with mock.patch.object(self.driver, 'deploy_instance') as deploy: - pool_id = 'pool_id1' - self.driver._refresh_device(pool_id) - self.rpc_mock.get_logical_device.assert_called_once_with(pool_id) - deploy.assert_called_once_with( - self.rpc_mock.get_logical_device.return_value) - - def test_create_vip(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.create_vip({'pool_id': '1'}) - refresh.assert_called_once_with('1') - - def test_update_vip(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.update_vip({}, {'pool_id': '1'}) - refresh.assert_called_once_with('1') - - def test_delete_vip(self): - with mock.patch.object(self.driver, 'undeploy_instance') as undeploy: - self.driver.delete_vip({'pool_id': '1'}) - undeploy.assert_called_once_with('1') - - def test_create_pool(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.create_pool({'id': '1'}) - self.assertFalse(refresh.called) - - def test_update_pool(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.update_pool({}, {'id': '1'}) - refresh.assert_called_once_with('1') - - def test_delete_pool_existing(self): - with mock.patch.object(self.driver, 'undeploy_instance') as undeploy: - with mock.patch.object(self.driver, 'exists') as exists: - exists.return_value = True - self.driver.delete_pool({'id': '1'}) - undeploy.assert_called_once_with('1') - - def test_delete_pool_non_existing(self): - with mock.patch.object(self.driver, 'undeploy_instance') as undeploy: - with mock.patch.object(self.driver, 'exists') as exists: - exists.return_value = False - self.driver.delete_pool({'id': '1'}) - self.assertFalse(undeploy.called) - - def test_create_member(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.create_member({'pool_id': '1'}) - refresh.assert_called_once_with('1') - - def test_update_member(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.update_member({}, {'pool_id': '1'}) - refresh.assert_called_once_with('1') - - def test_delete_member(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.delete_member({'pool_id': '1'}) - refresh.assert_called_once_with('1') - - def test_create_pool_health_monitor(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.create_pool_health_monitor('', '1') - refresh.assert_called_once_with('1') - - def test_update_pool_health_monitor(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.update_pool_health_monitor('', '', '1') - refresh.assert_called_once_with('1') - - def test_delete_pool_health_monitor(self): - with mock.patch.object(self.driver, '_refresh_device') as refresh: - self.driver.delete_pool_health_monitor('', '1') - refresh.assert_called_once_with('1') diff --git a/neutron/tests/unit/services/loadbalancer/drivers/netscaler/__init__.py b/neutron/tests/unit/services/loadbalancer/drivers/netscaler/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/services/loadbalancer/drivers/netscaler/test_ncc_client.py b/neutron/tests/unit/services/loadbalancer/drivers/netscaler/test_ncc_client.py deleted file mode 100644 index 6585e60e4..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/netscaler/test_ncc_client.py +++ /dev/null @@ -1,204 +0,0 @@ -# Copyright 2014 Citrix Systems -# -# 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 -import requests - -from neutron.services.loadbalancer.drivers.netscaler import ncc_client -from neutron.services.loadbalancer.drivers.netscaler import netscaler_driver -from neutron.tests.unit import testlib_api - -NCC_CLIENT_CLASS = ('neutron.services.loadbalancer.drivers' - '.netscaler.ncc_client.NSClient') - -TESTURI_SCHEME = 'http' -TESTURI_HOSTNAME = '1.1.1.1' -TESTURI_PORT = 4433 -TESTURI_PATH = '/ncc_service/1.0' -TESTURI = '%s://%s:%s%s' % (TESTURI_SCHEME, TESTURI_HOSTNAME, - TESTURI_PORT, TESTURI_PATH) -TEST_USERNAME = 'user211' -TEST_PASSWORD = '@30xHl5cT' -TEST_TENANT_ID = '9c5245a2-0432-9d4c-4829-9bd7028603a1' -TESTVIP_ID = '52ab5d71-6bb2-457f-8414-22a4ba55efec' - - -class TestNSClient(testlib_api.WebTestCase): - - """A Unit test for the NetScaler NCC client module.""" - - def setUp(self): - self.log = mock.patch.object(ncc_client, 'LOG').start() - super(TestNSClient, self).setUp() - # mock the requests.request function call - self.request_method_mock = mock.Mock() - requests.request = self.request_method_mock - self.testclient = self._get_nsclient() - - def test_instantiate_nsclient_with_empty_uri(self): - """Asserts that a call with empty URI will raise an exception.""" - self.assertRaises(ncc_client.NCCException, ncc_client.NSClient, - '', TEST_USERNAME, TEST_PASSWORD) - - def test_create_resource_with_no_connection(self): - """Asserts that a call with no connection will raise an exception.""" - # mock a connection object that fails to establish a connection - self.request_method_mock.side_effect = ( - requests.exceptions.ConnectionError()) - resource_path = netscaler_driver.VIPS_RESOURCE - resource_name = netscaler_driver.VIP_RESOURCE - resource_body = self._get_testvip_httpbody_for_create() - # call method under test: create_resource() and assert that - # it raises an exception - self.assertRaises(ncc_client.NCCException, - self.testclient.create_resource, - TEST_TENANT_ID, resource_path, - resource_name, resource_body) - - def test_create_resource_with_error(self): - """Asserts that a failed create call raises an exception.""" - # create a mock object to represent a valid http response - # with a failure status code. - fake_response = requests.Response() - fake_response.status_code = requests.codes.unauthorized - fake_response.headers = [] - requests.request.return_value = fake_response - resource_path = netscaler_driver.VIPS_RESOURCE - resource_name = netscaler_driver.VIP_RESOURCE - resource_body = self._get_testvip_httpbody_for_create() - # call method under test: create_resource - # and assert that it raises the expected exception. - self.assertRaises(ncc_client.NCCException, - self.testclient.create_resource, - TEST_TENANT_ID, resource_path, - resource_name, resource_body) - - def test_create_resource(self): - """Asserts that a correct call will succeed.""" - # obtain the mock object that corresponds to the call of request() - fake_response = requests.Response() - fake_response.status_code = requests.codes.created - fake_response.headers = [] - self.request_method_mock.return_value = fake_response - resource_path = netscaler_driver.VIPS_RESOURCE - resource_name = netscaler_driver.VIP_RESOURCE - resource_body = self._get_testvip_httpbody_for_create() - # call method under test: create_resource() - self.testclient.create_resource(TEST_TENANT_ID, resource_path, - resource_name, resource_body) - # assert that request() was called - # with the expected params. - resource_url = "%s/%s" % (self.testclient.service_uri, resource_path) - self.request_method_mock.assert_called_once_with( - 'POST', - url=resource_url, - headers=mock.ANY, - data=mock.ANY) - - def test_update_resource_with_error(self): - """Asserts that a failed update call raises an exception.""" - # create a valid http response with a failure status code. - fake_response = requests.Response() - fake_response.status_code = requests.codes.unauthorized - fake_response.headers = [] - # obtain the mock object that corresponds to the call of request() - self.request_method_mock.return_value = fake_response - resource_path = "%s/%s" % (netscaler_driver.VIPS_RESOURCE, - TESTVIP_ID) - resource_name = netscaler_driver.VIP_RESOURCE - resource_body = self._get_testvip_httpbody_for_update() - # call method under test: update_resource() and - # assert that it raises the expected exception. - self.assertRaises(ncc_client.NCCException, - self.testclient.update_resource, - TEST_TENANT_ID, resource_path, - resource_name, resource_body) - - def test_update_resource(self): - """Asserts that a correct update call will succeed.""" - # create a valid http response with a successful status code. - fake_response = requests.Response() - fake_response.status_code = requests.codes.ok - fake_response.headers = [] - # obtain the mock object that corresponds to the call of request() - self.request_method_mock.return_value = fake_response - resource_path = "%s/%s" % (netscaler_driver.VIPS_RESOURCE, - TESTVIP_ID) - resource_name = netscaler_driver.VIP_RESOURCE - resource_body = self._get_testvip_httpbody_for_update() - # call method under test: update_resource. - self.testclient.update_resource(TEST_TENANT_ID, resource_path, - resource_name, resource_body) - resource_url = "%s/%s" % (self.testclient.service_uri, resource_path) - # assert that requests.request() was called with the - # expected params. - self.request_method_mock.assert_called_once_with( - 'PUT', - url=resource_url, - headers=mock.ANY, - data=mock.ANY) - - def test_delete_resource_with_error(self): - """Asserts that a failed delete call raises an exception.""" - # create a valid http response with a failure status code. - fake_response = requests.Response() - fake_response.status_code = requests.codes.unauthorized - fake_response.headers = [] - resource_path = "%s/%s" % (netscaler_driver.VIPS_RESOURCE, - TESTVIP_ID) - # call method under test: create_resource - self.assertRaises(ncc_client.NCCException, - self.testclient.remove_resource, - TEST_TENANT_ID, resource_path) - - def test_delete_resource(self): - """Asserts that a correct delete call will succeed.""" - # create a valid http response with a failure status code. - fake_response = requests.Response() - fake_response.status_code = requests.codes.ok - fake_response.headers = [] - # obtain the mock object that corresponds to the call of request() - self.request_method_mock.return_value = fake_response - resource_path = "%s/%s" % (netscaler_driver.VIPS_RESOURCE, - TESTVIP_ID) - resource_url = "%s/%s" % (self.testclient.service_uri, resource_path) - # call method under test: create_resource - self.testclient.remove_resource(TEST_TENANT_ID, resource_path) - # assert that httplib.HTTPConnection request() was called with the - # expected params - self.request_method_mock.assert_called_once_with( - 'DELETE', - url=resource_url, - headers=mock.ANY, - data=mock.ANY) - - def _get_nsclient(self): - return ncc_client.NSClient(TESTURI, TEST_USERNAME, TEST_PASSWORD) - - def _get_testvip_httpbody_for_create(self): - body = { - 'name': 'vip1', - 'address': '10.0.0.3', - 'pool_id': 'da477c13-24cd-4c9f-8c19-757a61ef3b9d', - 'protocol': 'HTTP', - 'protocol_port': 80, - 'admin_state_up': True, - } - return body - - def _get_testvip_httpbody_for_update(self): - body = {} - body['name'] = 'updated vip1' - body['admin_state_up'] = False - return body diff --git a/neutron/tests/unit/services/loadbalancer/drivers/netscaler/test_netscaler_driver.py b/neutron/tests/unit/services/loadbalancer/drivers/netscaler/test_netscaler_driver.py deleted file mode 100644 index e10c1a3d7..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/netscaler/test_netscaler_driver.py +++ /dev/null @@ -1,802 +0,0 @@ -# Copyright 2014 Citrix Systems -# -# 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 contextlib - -import mock - -from neutron.common import exceptions -from neutron import context -from neutron.db.loadbalancer import loadbalancer_db -from neutron import manager -from neutron.plugins.common import constants -from neutron.services.loadbalancer.drivers.netscaler import ncc_client -from neutron.services.loadbalancer.drivers.netscaler import netscaler_driver -from neutron.tests.unit.db.loadbalancer import test_db_loadbalancer - - -LBAAS_DRIVER_CLASS = ('neutron.services.loadbalancer.drivers' - '.netscaler.netscaler_driver' - '.NetScalerPluginDriver') - -NCC_CLIENT_CLASS = ('neutron.services.loadbalancer.drivers' - '.netscaler.ncc_client' - '.NSClient') - -LBAAS_PROVIDER_NAME = 'netscaler' -LBAAS_PROVIDER = ('LOADBALANCER:%s:%s:default' % - (LBAAS_PROVIDER_NAME, LBAAS_DRIVER_CLASS)) - -#Test data -TESTVIP_ID = '52ab5d71-6bb2-457f-8414-22a4ba55efec' -TESTPOOL_ID = 'da477c13-24cd-4c9f-8c19-757a61ef3b9d' -TESTMEMBER_ID = '84dea8bc-3416-4fb0-83f9-2ca6e7173bee' -TESTMONITOR_ID = '9b9245a2-0413-4f15-87ef-9a41ef66048c' - -TESTVIP_PORT_ID = '327d9662-ade9-4c74-aaf6-c76f145c1180' -TESTPOOL_PORT_ID = '132c1dbb-d3d8-45aa-96e3-71f2ea51651e' -TESTPOOL_SNATIP_ADDRESS = '10.0.0.50' -TESTPOOL_SNAT_PORT = { - 'id': TESTPOOL_PORT_ID, - 'fixed_ips': [{'ip_address': TESTPOOL_SNATIP_ADDRESS}] -} -TESTVIP_IP = '10.0.1.100' -TESTMEMBER_IP = '10.0.0.5' - - -class TestLoadBalancerPluginBase(test_db_loadbalancer - .LoadBalancerPluginDbTestCase): - - def setUp(self): - super(TestLoadBalancerPluginBase, self).setUp( - lbaas_provider=LBAAS_PROVIDER) - loaded_plugins = manager.NeutronManager().get_service_plugins() - self.plugin_instance = loaded_plugins[constants.LOADBALANCER] - - -class TestNetScalerPluginDriver(TestLoadBalancerPluginBase): - - """Unit tests for the NetScaler LBaaS driver module.""" - - def setUp(self): - mock.patch.object(netscaler_driver, 'LOG').start() - - # mock the NSClient class (REST client) - client_mock_cls = mock.patch(NCC_CLIENT_CLASS).start() - - #mock the REST methods of the NSClient class - self.client_mock_instance = client_mock_cls.return_value - self.create_resource_mock = self.client_mock_instance.create_resource - self.create_resource_mock.side_effect = mock_create_resource_func - self.update_resource_mock = self.client_mock_instance.update_resource - self.update_resource_mock.side_effect = mock_update_resource_func - self.retrieve_resource_mock = (self.client_mock_instance - .retrieve_resource) - self.retrieve_resource_mock.side_effect = mock_retrieve_resource_func - self.remove_resource_mock = self.client_mock_instance.remove_resource - self.remove_resource_mock.side_effect = mock_remove_resource_func - super(TestNetScalerPluginDriver, self).setUp() - self.plugin_instance.drivers[LBAAS_PROVIDER_NAME] = ( - netscaler_driver.NetScalerPluginDriver(self.plugin_instance)) - self.driver = self.plugin_instance.drivers[LBAAS_PROVIDER_NAME] - self.context = context.get_admin_context() - - def test_create_vip(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - testvip = self._build_testvip_contents(subnet['subnet'], - pool['pool']) - expectedvip = self._build_expectedvip_contents( - testvip, - subnet['subnet']) - # mock the LBaaS plugin update_status(). - self._mock_update_status() - # reset the create_resource() mock - self.create_resource_mock.reset_mock() - # execute the method under test - self.driver.create_vip(self.context, testvip) - # First, assert that create_resource was called once - # with expected params. - self.create_resource_mock.assert_called_once_with( - None, - netscaler_driver.VIPS_RESOURCE, - netscaler_driver.VIP_RESOURCE, - expectedvip) - #Finally, assert that the vip object is now ACTIVE - self.mock_update_status_obj.assert_called_once_with( - mock.ANY, - loadbalancer_db.Vip, - expectedvip['id'], - constants.ACTIVE) - - def test_create_vip_without_connection(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - testvip = self._build_testvip_contents(subnet['subnet'], - pool['pool']) - expectedvip = self._build_expectedvip_contents( - testvip, - subnet['subnet']) - errorcode = ncc_client.NCCException.CONNECTION_ERROR - self.create_resource_mock.side_effect = ( - ncc_client.NCCException(errorcode)) - # mock the plugin's update_status() - self._mock_update_status() - # reset the create_resource() mock - self.create_resource_mock.reset_mock() - # execute the method under test. - self.driver.create_vip(self.context, testvip) - # First, assert that update_resource was called once - # with expected params. - self.create_resource_mock.assert_called_once_with( - None, - netscaler_driver.VIPS_RESOURCE, - netscaler_driver.VIP_RESOURCE, - expectedvip) - #Finally, assert that the vip object is in ERROR state - self.mock_update_status_obj.assert_called_once_with( - mock.ANY, - loadbalancer_db.Vip, - testvip['id'], - constants.ERROR) - - def test_update_vip(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - with self.vip(pool=pool, subnet=subnet) as vip: - updated_vip = self._build_updated_testvip_contents( - vip['vip'], - subnet['subnet'], - pool['pool']) - expectedvip = self._build_updated_expectedvip_contents( - updated_vip, - subnet['subnet'], - pool['pool']) - # mock the plugin's update_status() - self._mock_update_status() - # reset the update_resource() mock - self.update_resource_mock.reset_mock() - # execute the method under test - self.driver.update_vip(self.context, updated_vip, - updated_vip) - vip_resource_path = "%s/%s" % ( - (netscaler_driver.VIPS_RESOURCE, - vip['vip']['id'])) - # First, assert that update_resource was called once - # with expected params. - (self.update_resource_mock - .assert_called_once_with( - None, - vip_resource_path, - netscaler_driver.VIP_RESOURCE, - expectedvip)) - #Finally, assert that the vip object is now ACTIVE - self.mock_update_status_obj.assert_called_once_with( - mock.ANY, - loadbalancer_db.Vip, - vip['vip']['id'], - constants.ACTIVE) - - def test_delete_vip(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - with contextlib.nested( - self.vip(pool=pool, subnet=subnet), - mock.patch.object(self.driver.plugin, '_delete_db_vip') - ) as (vip, mock_delete_db_vip): - mock_delete_db_vip.return_value = None - #reset the remove_resource() mock - self.remove_resource_mock.reset_mock() - # execute the method under test - self.driver.delete_vip(self.context, vip['vip']) - vip_resource_path = "%s/%s" % ( - (netscaler_driver.VIPS_RESOURCE, - vip['vip']['id'])) - # Assert that remove_resource() was called once - # with expected params. - (self.remove_resource_mock - .assert_called_once_with(None, vip_resource_path)) - - def test_create_pool(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet'), - mock.patch.object(self.driver.plugin._core_plugin, 'get_ports'), - mock.patch.object(self.driver.plugin._core_plugin, 'create_port') - ) as (subnet, mock_get_subnet, mock_get_ports, mock_create_port): - mock_get_subnet.return_value = subnet['subnet'] - mock_get_ports.return_value = None - mock_create_port.return_value = TESTPOOL_SNAT_PORT - testpool = self._build_testpool_contents(subnet['subnet']) - expectedpool = self._build_expectedpool_contents(testpool, - subnet['subnet']) - #reset the create_resource() mock - self.create_resource_mock.reset_mock() - # mock the plugin's update_status() - self._mock_update_status() - # execute the method under test - self.driver.create_pool(self.context, testpool) - # First, assert that create_resource was called once - # with expected params. - (self.create_resource_mock - .assert_called_once_with(None, - netscaler_driver.POOLS_RESOURCE, - netscaler_driver.POOL_RESOURCE, - expectedpool)) - #Finally, assert that the pool object is now ACTIVE - self.mock_update_status_obj.assert_called_once_with( - mock.ANY, - loadbalancer_db.Pool, - expectedpool['id'], - constants.ACTIVE) - - def test_create_pool_with_error(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet'), - mock.patch.object(self.driver.plugin._core_plugin, 'get_ports'), - mock.patch.object(self.driver.plugin._core_plugin, 'create_port') - ) as (subnet, mock_get_subnet, mock_get_ports, mock_create_port): - mock_get_subnet.return_value = subnet['subnet'] - mock_get_ports.return_value = None - mock_create_port.return_value = TESTPOOL_SNAT_PORT - errorcode = ncc_client.NCCException.CONNECTION_ERROR - self.create_resource_mock.side_effect = (ncc_client - .NCCException(errorcode)) - testpool = self._build_testpool_contents(subnet['subnet']) - expectedpool = self._build_expectedpool_contents(testpool, - subnet['subnet']) - # mock the plugin's update_status() - self._mock_update_status() - #reset the create_resource() mock - self.create_resource_mock.reset_mock() - # execute the method under test. - self.driver.create_pool(self.context, testpool) - # Also assert that create_resource was called once - # with expected params. - (self.create_resource_mock - .assert_called_once_with(None, - netscaler_driver.POOLS_RESOURCE, - netscaler_driver.POOL_RESOURCE, - expectedpool)) - #Finally, assert that the pool object is in ERROR state - self.mock_update_status_obj.assert_called_once_with( - mock.ANY, - loadbalancer_db.Pool, - expectedpool['id'], - constants.ERROR) - - def test_create_pool_with_snatportcreate_failure(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet'), - mock.patch.object(self.driver.plugin._core_plugin, 'get_ports'), - mock.patch.object(self.driver.plugin._core_plugin, 'create_port') - ) as (subnet, mock_get_subnet, mock_get_ports, mock_create_port): - mock_get_subnet.return_value = subnet['subnet'] - mock_get_ports.return_value = None - mock_create_port.side_effect = exceptions.NeutronException() - testpool = self._build_testpool_contents(subnet['subnet']) - #reset the create_resource() mock - self.create_resource_mock.reset_mock() - # execute the method under test. - self.assertRaises(exceptions.NeutronException, - self.driver.create_pool, - self.context, testpool) - - def test_update_pool(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - updated_pool = self._build_updated_testpool_contents( - pool['pool'], - subnet['subnet']) - expectedpool = self._build_updated_expectedpool_contents( - updated_pool, - subnet['subnet']) - # mock the plugin's update_status() - self._mock_update_status() - # reset the update_resource() mock - self.update_resource_mock.reset_mock() - # execute the method under test. - self.driver.update_pool(self.context, pool['pool'], - updated_pool) - pool_resource_path = "%s/%s" % ( - (netscaler_driver.POOLS_RESOURCE, - pool['pool']['id'])) - # First, assert that update_resource was called once - # with expected params. - (self.update_resource_mock - .assert_called_once_with(None, - pool_resource_path, - netscaler_driver.POOL_RESOURCE, - expectedpool)) - #Finally, assert that the pool object is now ACTIVE - self.mock_update_status_obj.assert_called_once_with( - mock.ANY, - loadbalancer_db.Pool, - pool['pool']['id'], - constants.ACTIVE) - - def test_delete_pool(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with contextlib.nested( - self.pool(provider=LBAAS_PROVIDER_NAME), - mock.patch.object(self.driver.plugin._core_plugin, - 'delete_port'), - mock.patch.object(self.driver.plugin._core_plugin, - 'get_ports'), - mock.patch.object(self.driver.plugin, - 'get_pools'), - mock.patch.object(self.driver.plugin, - '_delete_db_pool') - ) as (pool, mock_delete_port, mock_get_ports, mock_get_pools, - mock_delete_db_pool): - mock_delete_port.return_value = None - mock_get_ports.return_value = [{'id': TESTPOOL_PORT_ID}] - mock_get_pools.return_value = [] - mock_delete_db_pool.return_value = None - #reset the remove_resource() mock - self.remove_resource_mock.reset_mock() - # execute the method under test. - self.driver.delete_pool(self.context, pool['pool']) - pool_resource_path = "%s/%s" % ( - (netscaler_driver.POOLS_RESOURCE, - pool['pool']['id'])) - # Assert that delete_resource was called - # once with expected params. - (self.remove_resource_mock - .assert_called_once_with(None, pool_resource_path)) - - def test_create_member(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, - 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - testmember = self._build_testmember_contents(pool['pool']) - expectedmember = self._build_expectedmember_contents( - testmember) - # mock the plugin's update_status() - self._mock_update_status() - #reset the create_resource() mock - self.create_resource_mock.reset_mock() - # execute the method under test. - self.driver.create_member(self.context, testmember) - # First, assert that create_resource was called once - # with expected params. - (self.create_resource_mock - .assert_called_once_with( - None, - netscaler_driver.POOLMEMBERS_RESOURCE, - netscaler_driver.POOLMEMBER_RESOURCE, - expectedmember)) - #Finally, assert that the member object is now ACTIVE - self.mock_update_status_obj.assert_called_once_with( - mock.ANY, - loadbalancer_db.Member, - expectedmember['id'], - constants.ACTIVE) - - def test_update_member(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - with self.member(pool_id=pool['pool']['id']) as member: - updatedmember = (self._build_updated_testmember_contents( - member['member'])) - expectedmember = (self - ._build_updated_expectedmember_contents( - updatedmember)) - # mock the plugin's update_status() - self._mock_update_status() - # reset the update_resource() mock - self.update_resource_mock.reset_mock() - # execute the method under test - self.driver.update_member(self.context, - member['member'], - updatedmember) - member_resource_path = "%s/%s" % ( - (netscaler_driver.POOLMEMBERS_RESOURCE, - member['member']['id'])) - # First, assert that update_resource was called once - # with expected params. - (self.update_resource_mock - .assert_called_once_with( - None, - member_resource_path, - netscaler_driver.POOLMEMBER_RESOURCE, - expectedmember)) - #Finally, assert that the member object is now ACTIVE - self.mock_update_status_obj.assert_called_once_with( - mock.ANY, - loadbalancer_db.Member, - member['member']['id'], - constants.ACTIVE) - - def test_delete_member(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - with contextlib.nested( - self.member(pool_id=pool['pool']['id']), - mock.patch.object(self.driver.plugin, '_delete_db_member') - ) as (member, mock_delete_db_member): - mock_delete_db_member.return_value = None - # reset the remove_resource() mock - self.remove_resource_mock.reset_mock() - # execute the method under test - self.driver.delete_member(self.context, - member['member']) - member_resource_path = "%s/%s" % ( - (netscaler_driver.POOLMEMBERS_RESOURCE, - member['member']['id'])) - # Assert that delete_resource was called once - # with expected params. - (self.remove_resource_mock - .assert_called_once_with(None, member_resource_path)) - - def test_create_pool_health_monitor(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - testhealthmonitor = self._build_testhealthmonitor_contents( - pool['pool']) - expectedhealthmonitor = ( - self._build_expectedhealthmonitor_contents( - testhealthmonitor)) - with mock.patch.object(self.driver.plugin, - 'update_pool_health_monitor') as mhm: - # reset the create_resource() mock - self.create_resource_mock.reset_mock() - # execute the method under test. - self.driver.create_pool_health_monitor(self.context, - testhealthmonitor, - pool['pool']['id']) - # First, assert that create_resource was called once - # with expected params. - resource_path = "%s/%s/%s" % ( - netscaler_driver.POOLS_RESOURCE, - pool['pool']['id'], - netscaler_driver.MONITORS_RESOURCE) - (self.create_resource_mock - .assert_called_once_with( - None, - resource_path, - netscaler_driver.MONITOR_RESOURCE, - expectedhealthmonitor)) - # Finally, assert that the healthmonitor object is - # now ACTIVE. - (mhm.assert_called_once_with( - mock.ANY, - expectedhealthmonitor['id'], - pool['pool']['id'], - constants.ACTIVE, "")) - - def test_update_pool_health_monitor(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - with self.health_monitor( - pool_id=pool['pool']['id'] - ) as (health_monitor): - updatedhealthmonitor = ( - self._build_updated_testhealthmonitor_contents( - health_monitor['health_monitor'])) - expectedhealthmonitor = ( - self._build_updated_expectedhealthmonitor_contents( - updatedhealthmonitor)) - with mock.patch.object(self.driver.plugin, - 'update_pool_health_monitor')as mhm: - # reset the update_resource() mock - self.update_resource_mock.reset_mock() - # execute the method under test. - self.driver.update_pool_health_monitor( - self.context, - health_monitor['health_monitor'], - updatedhealthmonitor, - pool['pool']['id']) - monitor_resource_path = "%s/%s" % ( - (netscaler_driver.MONITORS_RESOURCE, - health_monitor['health_monitor']['id'])) - # First, assert that update_resource was called once - # with expected params. - self.update_resource_mock.assert_called_once_with( - None, - monitor_resource_path, - netscaler_driver.MONITOR_RESOURCE, - expectedhealthmonitor) - #Finally, assert that the member object is now ACTIVE - (mhm.assert_called_once_with( - mock.ANY, - health_monitor['health_monitor']['id'], - pool['pool']['id'], - constants.ACTIVE, "")) - - def test_delete_pool_health_monitor(self): - with contextlib.nested( - self.subnet(), - mock.patch.object(self.driver.plugin._core_plugin, 'get_subnet') - ) as (subnet, mock_get_subnet): - mock_get_subnet.return_value = subnet['subnet'] - with self.pool(provider=LBAAS_PROVIDER_NAME) as pool: - with contextlib.nested( - self.health_monitor(pool_id=pool['pool']['id']), - mock.patch.object(self.driver.plugin, - '_delete_db_pool_health_monitor') - ) as (health_monitor, mock_delete_db_monitor): - mock_delete_db_monitor.return_value = None - # reset the remove_resource() mock - self.remove_resource_mock.reset_mock() - # execute the method under test. - self.driver.delete_pool_health_monitor( - self.context, - health_monitor['health_monitor'], - pool['pool']['id']) - monitor_resource_path = "%s/%s/%s/%s" % ( - netscaler_driver.POOLS_RESOURCE, - pool['pool']['id'], - netscaler_driver.MONITORS_RESOURCE, - health_monitor['health_monitor']['id']) - # Assert that delete_resource was called once - # with expected params. - self.remove_resource_mock.assert_called_once_with( - None, - monitor_resource_path) - - def _build_testvip_contents(self, subnet, pool): - vip_obj = dict(id=TESTVIP_ID, - name='testvip', - description='a test vip', - tenant_id=self._tenant_id, - subnet_id=subnet['id'], - address=TESTVIP_IP, - port_id=TESTVIP_PORT_ID, - pool_id=pool['id'], - protocol='HTTP', - protocol_port=80, - connection_limit=1000, - admin_state_up=True, - status='PENDING_CREATE', - status_description='') - return vip_obj - - def _build_expectedvip_contents(self, testvip, subnet): - expectedvip = dict(id=testvip['id'], - name=testvip['name'], - description=testvip['description'], - tenant_id=testvip['tenant_id'], - subnet_id=testvip['subnet_id'], - address=testvip['address'], - network_id=subnet['network_id'], - port_id=testvip['port_id'], - pool_id=testvip['pool_id'], - protocol=testvip['protocol'], - protocol_port=testvip['protocol_port'], - connection_limit=testvip['connection_limit'], - admin_state_up=testvip['admin_state_up']) - return expectedvip - - def _build_updated_testvip_contents(self, testvip, subnet, pool): - #update some updateable fields of the vip - testvip['name'] = 'udpated testvip' - testvip['description'] = 'An updated version of test vip' - testvip['connection_limit'] = 2000 - return testvip - - def _build_updated_expectedvip_contents(self, testvip, subnet, pool): - expectedvip = dict(name=testvip['name'], - description=testvip['description'], - connection_limit=testvip['connection_limit'], - admin_state_up=testvip['admin_state_up'], - pool_id=testvip['pool_id']) - return expectedvip - - def _build_testpool_contents(self, subnet): - pool_obj = dict(id=TESTPOOL_ID, - name='testpool', - description='a test pool', - tenant_id=self._tenant_id, - subnet_id=subnet['id'], - protocol='HTTP', - vip_id=None, - admin_state_up=True, - lb_method='ROUND_ROBIN', - status='PENDING_CREATE', - status_description='', - members=[], - health_monitors=[], - health_monitors_status=None, - provider=LBAAS_PROVIDER_NAME) - return pool_obj - - def _build_expectedpool_contents(self, testpool, subnet): - expectedpool = dict(id=testpool['id'], - name=testpool['name'], - description=testpool['description'], - tenant_id=testpool['tenant_id'], - subnet_id=testpool['subnet_id'], - network_id=subnet['network_id'], - protocol=testpool['protocol'], - vip_id=testpool['vip_id'], - lb_method=testpool['lb_method'], - snat_ip=TESTPOOL_SNATIP_ADDRESS, - port_id=TESTPOOL_PORT_ID, - admin_state_up=testpool['admin_state_up']) - return expectedpool - - def _build_updated_testpool_contents(self, testpool, subnet): - updated_pool = dict(testpool.items()) - updated_pool['name'] = 'udpated testpool' - updated_pool['description'] = 'An updated version of test pool' - updated_pool['lb_method'] = 'LEAST_CONNECTIONS' - updated_pool['admin_state_up'] = True - updated_pool['provider'] = LBAAS_PROVIDER_NAME - updated_pool['status'] = 'PENDING_UPDATE' - updated_pool['status_description'] = '' - updated_pool['members'] = [] - updated_pool["health_monitors"] = [] - updated_pool["health_monitors_status"] = None - return updated_pool - - def _build_updated_expectedpool_contents(self, testpool, subnet): - expectedpool = dict(name=testpool['name'], - description=testpool['description'], - lb_method=testpool['lb_method'], - admin_state_up=testpool['admin_state_up']) - return expectedpool - - def _build_testmember_contents(self, pool): - member_obj = dict( - id=TESTMEMBER_ID, - tenant_id=self._tenant_id, - pool_id=pool['id'], - address=TESTMEMBER_IP, - protocol_port=8080, - weight=2, - admin_state_up=True, - status='PENDING_CREATE', - status_description='') - return member_obj - - def _build_expectedmember_contents(self, testmember): - expectedmember = dict( - id=testmember['id'], - tenant_id=testmember['tenant_id'], - pool_id=testmember['pool_id'], - address=testmember['address'], - protocol_port=testmember['protocol_port'], - weight=testmember['weight'], - admin_state_up=testmember['admin_state_up']) - return expectedmember - - def _build_updated_testmember_contents(self, testmember): - updated_member = dict(testmember.items()) - updated_member.update( - weight=3, - admin_state_up=True, - status='PENDING_CREATE', - status_description='' - ) - return updated_member - - def _build_updated_expectedmember_contents(self, testmember): - expectedmember = dict(weight=testmember['weight'], - pool_id=testmember['pool_id'], - admin_state_up=testmember['admin_state_up']) - return expectedmember - - def _build_testhealthmonitor_contents(self, pool): - monitor_obj = dict( - id=TESTMONITOR_ID, - tenant_id=self._tenant_id, - type='TCP', - delay=10, - timeout=5, - max_retries=3, - admin_state_up=True, - pools=[]) - pool_obj = dict(status='PENDING_CREATE', - status_description=None, - pool_id=pool['id']) - monitor_obj['pools'].append(pool_obj) - return monitor_obj - - def _build_expectedhealthmonitor_contents(self, testhealthmonitor): - expectedmonitor = dict(id=testhealthmonitor['id'], - tenant_id=testhealthmonitor['tenant_id'], - type=testhealthmonitor['type'], - delay=testhealthmonitor['delay'], - timeout=testhealthmonitor['timeout'], - max_retries=testhealthmonitor['max_retries'], - admin_state_up=( - testhealthmonitor['admin_state_up'])) - return expectedmonitor - - def _build_updated_testhealthmonitor_contents(self, testmonitor): - updated_monitor = dict(testmonitor.items()) - updated_monitor.update( - delay=30, - timeout=3, - max_retries=5, - admin_state_up=True - ) - return updated_monitor - - def _build_updated_expectedhealthmonitor_contents(self, testmonitor): - expectedmonitor = dict(delay=testmonitor['delay'], - timeout=testmonitor['timeout'], - max_retries=testmonitor['max_retries'], - admin_state_up=testmonitor['admin_state_up']) - return expectedmonitor - - def _mock_update_status(self): - #patch the plugin's update_status() method with a mock object - self.mock_update_status_patcher = mock.patch.object( - self.driver.plugin, - 'update_status') - self.mock_update_status_obj = self.mock_update_status_patcher.start() - - -def mock_create_resource_func(*args, **kwargs): - return 201, {} - - -def mock_update_resource_func(*args, **kwargs): - return 202, {} - - -def mock_retrieve_resource_func(*args, **kwargs): - return 200, {} - - -def mock_remove_resource_func(*args, **kwargs): - return 200, {} diff --git a/neutron/tests/unit/services/loadbalancer/drivers/radware/__init__.py b/neutron/tests/unit/services/loadbalancer/drivers/radware/__init__.py deleted file mode 100644 index e708e47db..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/radware/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# copyright 2013 Radware LTD. -# -# 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. -# -# @author: Avishay Balderman, Radware diff --git a/neutron/tests/unit/services/loadbalancer/drivers/radware/test_plugin_driver.py b/neutron/tests/unit/services/loadbalancer/drivers/radware/test_plugin_driver.py deleted file mode 100644 index ca6080e1f..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/radware/test_plugin_driver.py +++ /dev/null @@ -1,961 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 Radware LTD. -# -# 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. -# -# @author: Avishay Balderman, Radware - -import re - -import contextlib -import mock -from oslo.config import cfg -from six.moves import queue as Queue - -from neutron import context -from neutron.extensions import loadbalancer -from neutron import manager -from neutron.openstack.common import jsonutils as json -from neutron.plugins.common import constants -from neutron.services.loadbalancer.drivers.radware import driver -from neutron.services.loadbalancer.drivers.radware import exceptions as r_exc -from neutron.tests.unit.db.loadbalancer import test_db_loadbalancer - -GET_200 = ('/api/workflow/', '/api/service/', '/api/workflowTemplate') -SERVER_DOWN_CODES = (-1, 301, 307) - - -class QueueMock(Queue.Queue): - def __init__(self, completion_handler): - self.completion_handler = completion_handler - super(QueueMock, self).__init__() - - def put_nowait(self, oper): - self.completion_handler(oper) - - -def _recover_function_mock(action, resource, data, headers, binary=False): - pass - - -def rest_call_function_mock(action, resource, data, headers, binary=False): - if rest_call_function_mock.RESPOND_WITH_ERROR: - return 400, 'error_status', 'error_description', None - if rest_call_function_mock.RESPOND_WITH_SERVER_DOWN in SERVER_DOWN_CODES: - val = rest_call_function_mock.RESPOND_WITH_SERVER_DOWN - return val, 'error_status', 'error_description', None - if action == 'GET': - return _get_handler(resource) - elif action == 'DELETE': - return _delete_handler(resource) - elif action == 'POST': - return _post_handler(resource, binary) - else: - return 0, None, None, None - - -def _get_handler(resource): - if resource == GET_200[2]: - if rest_call_function_mock.TEMPLATES_MISSING: - data = json.loads('[]') - else: - data = json.loads( - '[{"name":"openstack_l2_l3"},{"name":"openstack_l4"}]' - ) - return 200, '', '', data - - if resource in GET_200: - return 200, '', '', '' - else: - data = json.loads('{"complete":"True", "success": "True"}') - return 202, '', '', data - - -def _delete_handler(resource): - return 404, '', '', {'message': 'Not Found'} - - -def _post_handler(resource, binary): - if re.search(r'/api/workflow/.+/action/.+', resource): - data = json.loads('{"uri":"some_uri"}') - return 202, '', '', data - elif re.search(r'/api/service\?name=.+', resource): - data = json.loads('{"links":{"actions":{"provision":"someuri"}}}') - return 201, '', '', data - elif binary: - return 201, '', '', '' - else: - return 202, '', '', '' - -RADWARE_PROVIDER = ('LOADBALANCER:radware:neutron.services.' - 'loadbalancer.drivers.radware.driver.' - 'LoadBalancerDriver:default') - - -class TestLoadBalancerPluginBase( - test_db_loadbalancer.LoadBalancerPluginDbTestCase): - - def setUp(self): - super(TestLoadBalancerPluginBase, self).setUp( - lbaas_provider=RADWARE_PROVIDER) - - loaded_plugins = manager.NeutronManager().get_service_plugins() - self.plugin_instance = loaded_plugins[constants.LOADBALANCER] - - -class TestLoadBalancerPlugin(TestLoadBalancerPluginBase): - def setUp(self): - super(TestLoadBalancerPlugin, self).setUp() - - rest_call_function_mock.__dict__.update( - {'RESPOND_WITH_ERROR': False}) - rest_call_function_mock.__dict__.update( - {'TEMPLATES_MISSING': False}) - rest_call_function_mock.__dict__.update( - {'RESPOND_WITH_SERVER_DOWN': 200}) - - self.operation_completer_start_mock = mock.Mock( - return_value=None) - self.operation_completer_join_mock = mock.Mock( - return_value=None) - self.driver_rest_call_mock = mock.Mock( - side_effect=rest_call_function_mock) - self.flip_servers_mock = mock.Mock( - return_value=None) - self.recover_mock = mock.Mock( - side_effect=_recover_function_mock) - - radware_driver = self.plugin_instance.drivers['radware'] - radware_driver.completion_handler.start = ( - self.operation_completer_start_mock) - radware_driver.completion_handler.join = ( - self.operation_completer_join_mock) - self.orig_call = radware_driver.rest_client.call - self.orig__call = radware_driver.rest_client._call - radware_driver.rest_client.call = self.driver_rest_call_mock - radware_driver.rest_client._call = self.driver_rest_call_mock - radware_driver.rest_client._flip_servers = self.flip_servers_mock - radware_driver.rest_client._recover = self.recover_mock - radware_driver.completion_handler.rest_client.call = ( - self.driver_rest_call_mock) - - radware_driver.queue = QueueMock( - radware_driver.completion_handler.handle_operation_completion) - - self.addCleanup(radware_driver.completion_handler.join) - - def test_rest_client_recover_was_called(self): - """Call the real REST client and verify _recover is called.""" - radware_driver = self.plugin_instance.drivers['radware'] - radware_driver.rest_client.call = self.orig_call - radware_driver.rest_client._call = self.orig__call - self.assertRaises(r_exc.RESTRequestFailure, - radware_driver._verify_workflow_templates) - self.recover_mock.assert_called_once() - - def test_rest_client_flip_servers(self): - radware_driver = self.plugin_instance.drivers['radware'] - server = radware_driver.rest_client.server - sec_server = radware_driver.rest_client.secondary_server - radware_driver.rest_client._flip_servers() - self.assertEqual(server, - radware_driver.rest_client.secondary_server) - self.assertEqual(sec_server, - radware_driver.rest_client.server) - - def test_verify_workflow_templates_server_down(self): - """Test the rest call failure when backend is down.""" - for value in SERVER_DOWN_CODES: - rest_call_function_mock.__dict__.update( - {'RESPOND_WITH_SERVER_DOWN': value}) - self.assertRaises(r_exc.RESTRequestFailure, - self.plugin_instance.drivers['radware']. - _verify_workflow_templates) - - def test_verify_workflow_templates(self): - """Test the rest call failure handling by Exception raising.""" - rest_call_function_mock.__dict__.update( - {'TEMPLATES_MISSING': True}) - - self.assertRaises(r_exc.WorkflowMissing, - self.plugin_instance.drivers['radware']. - _verify_workflow_templates) - - def test_create_vip_failure(self): - """Test the rest call failure handling by Exception raising.""" - with self.network(do_delete=False) as network: - with self.subnet(network=network, do_delete=False) as subnet: - with self.pool(no_delete=True, - provider='radware', - subnet_id=subnet['subnet']['id']) as pool: - vip_data = { - 'name': 'vip1', - 'subnet_id': subnet['subnet']['id'], - 'pool_id': pool['pool']['id'], - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': constants.PENDING_CREATE, - 'tenant_id': self._tenant_id, - 'session_persistence': '' - } - - rest_call_function_mock.__dict__.update( - {'RESPOND_WITH_ERROR': True}) - - self.assertRaises(r_exc.RESTRequestFailure, - self.plugin_instance.create_vip, - context.get_admin_context(), - {'vip': vip_data}) - - def test_create_vip(self): - with self.subnet() as subnet: - with self.pool(provider='radware', - subnet_id=subnet['subnet']['id']) as pool: - vip_data = { - 'name': 'vip1', - 'subnet_id': subnet['subnet']['id'], - 'pool_id': pool['pool']['id'], - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': constants.PENDING_CREATE, - 'tenant_id': self._tenant_id, - 'session_persistence': '' - } - - vip = self.plugin_instance.create_vip( - context.get_admin_context(), {'vip': vip_data}) - - # Test creation REST calls - calls = [ - mock.call('GET', u'/api/service/srv_' + - subnet['subnet']['network_id'], None, None), - mock.call('POST', u'/api/service?name=srv_' + - subnet['subnet']['network_id'] + '&tenant=' + - vip['tenant_id'], mock.ANY, - driver.CREATE_SERVICE_HEADER), - mock.call('GET', u'/api/workflow/l2_l3_' + - subnet['subnet']['network_id'], None, None), - mock.call('POST', '/api/workflow/l2_l3_' + - subnet['subnet']['network_id'] + - '/action/setup_l2_l3', - mock.ANY, driver.TEMPLATE_HEADER), - mock.call('POST', 'someuri', - None, driver.PROVISION_HEADER), - - - mock.call('POST', '/api/workflowTemplate/' + - 'openstack_l4' + - '?name=' + pool['pool']['id'], - mock.ANY, - driver.TEMPLATE_HEADER), - mock.call('POST', '/api/workflowTemplate/' + - 'openstack_l2_l3' + - '?name=l2_l3_' + subnet['subnet']['network_id'], - mock.ANY, - driver.TEMPLATE_HEADER), - - mock.call('POST', '/api/workflow/' + pool['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER), - mock.call('GET', '/api/workflow/' + - pool['pool']['id'], None, None) - ] - self.driver_rest_call_mock.assert_has_calls(calls, - any_order=True) - - #Test DB - new_vip = self.plugin_instance.get_vip( - context.get_admin_context(), - vip['id'] - ) - self.assertEqual(new_vip['status'], constants.ACTIVE) - - # Delete VIP - self.plugin_instance.delete_vip( - context.get_admin_context(), vip['id']) - - # Test deletion REST calls - calls = [ - mock.call('DELETE', u'/api/workflow/' + pool['pool']['id'], - None, None) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - def test_create_vip_2_leg(self): - """Test creation of a VIP where Alteon VIP and PIP are different.""" - - with self.subnet(cidr='10.0.0.0/24') as subnet: - with self.subnet(cidr='10.0.1.0/24') as pool_sub: - with self.pool(provider='radware', - subnet_id=pool_sub['subnet']['id']) as pool: - vip_data = { - 'name': 'vip1', - 'subnet_id': subnet['subnet']['id'], - 'pool_id': pool['pool']['id'], - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': constants.PENDING_CREATE, - 'tenant_id': self._tenant_id, - 'session_persistence': '' - } - - vip = self.plugin_instance.create_vip( - context.get_admin_context(), {'vip': vip_data}) - name_suffix = '%s_%s' % (subnet['subnet']['network_id'], - pool_sub['subnet']['network_id']) - # Test creation REST calls - calls = [ - mock.call('GET', '/api/workflowTemplate', None, None), - mock.call('GET', '/api/service/srv_' + name_suffix, - None, None), - mock.call('POST', '/api/service?name=srv_' + - name_suffix + '&tenant=' + vip['tenant_id'], - mock.ANY, driver.CREATE_SERVICE_HEADER), - mock.call('POST', 'someuri', - None, driver.PROVISION_HEADER), - mock.call('GET', '/api/workflow/l2_l3_' + name_suffix, - None, None), - mock.call('POST', '/api/workflowTemplate/' + - 'openstack_l2_l3' + - '?name=l2_l3_' + name_suffix, - mock.ANY, - driver.TEMPLATE_HEADER), - mock.call('POST', '/api/workflow/l2_l3_' + - name_suffix + '/action/setup_l2_l3', - mock.ANY, driver.TEMPLATE_HEADER), - mock.call('GET', '/api/workflow/' + - pool['pool']['id'], None, None), - mock.call('POST', '/api/workflowTemplate/' + - 'openstack_l4' + - '?name=' + pool['pool']['id'], - mock.ANY, - driver.TEMPLATE_HEADER), - mock.call('POST', '/api/workflow/' + - pool['pool']['id'] + '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER) - ] - self.driver_rest_call_mock.assert_has_calls(calls) - #Test DB - new_vip = self.plugin_instance.get_vip( - context.get_admin_context(), - vip['id'] - ) - self.assertEqual(new_vip['status'], constants.ACTIVE) - - # Test that PIP neutron port was created - pip_port_filter = { - 'name': ['pip_' + vip['id']], - } - plugin = manager.NeutronManager.get_plugin() - num_ports = plugin.get_ports_count( - context.get_admin_context(), filters=pip_port_filter) - self.assertTrue(num_ports > 0) - - # Delete VIP - self.plugin_instance.delete_vip( - context.get_admin_context(), vip['id']) - - # Test deletion REST calls - calls = [ - mock.call('DELETE', u'/api/workflow/' + - pool['pool']['id'], None, None) - ] - self.driver_rest_call_mock.assert_has_calls(calls) - - def test_update_vip(self): - with self.subnet() as subnet: - with self.pool(provider='radware', - no_delete=True, - subnet_id=subnet['subnet']['id']) as pool: - vip_data = { - 'name': 'vip1', - 'subnet_id': subnet['subnet']['id'], - 'pool_id': pool['pool']['id'], - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': constants.PENDING_CREATE, - 'tenant_id': self._tenant_id, - 'session_persistence': '' - } - - vip = self.plugin_instance.create_vip( - context.get_admin_context(), {'vip': vip_data}) - - vip_data['status'] = constants.PENDING_UPDATE - self.plugin_instance.update_vip( - context.get_admin_context(), - vip['id'], {'vip': vip_data}) - - # Test REST calls - calls = [ - mock.call('POST', '/api/workflow/' + pool['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER), - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - updated_vip = self.plugin_instance.get_vip( - context.get_admin_context(), vip['id']) - self.assertEqual(updated_vip['status'], constants.ACTIVE) - - # delete VIP - self.plugin_instance.delete_vip( - context.get_admin_context(), vip['id']) - - def test_update_vip_2_leg(self): - """Test update of a VIP where Alteon VIP and PIP are different.""" - - with self.subnet(cidr='10.0.0.0/24') as subnet: - with self.subnet(cidr='10.0.1.0/24') as pool_subnet: - with self.pool(provider='radware', - subnet_id=pool_subnet['subnet']['id']) as pool: - vip_data = { - 'name': 'vip1', - 'subnet_id': subnet['subnet']['id'], - 'pool_id': pool['pool']['id'], - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': constants.PENDING_CREATE, - 'tenant_id': self._tenant_id, - 'session_persistence': '' - } - - vip = self.plugin_instance.create_vip( - context.get_admin_context(), {'vip': vip_data}) - - self.plugin_instance.update_vip( - context.get_admin_context(), - vip['id'], {'vip': vip_data}) - - # Test REST calls - calls = [ - mock.call('POST', '/api/workflow/' + - pool['pool']['id'] + '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER), - ] - self.driver_rest_call_mock.assert_has_calls(calls) - - updated_vip = self.plugin_instance.get_vip( - context.get_admin_context(), vip['id']) - self.assertEqual(updated_vip['status'], constants.ACTIVE) - - # delete VIP - self.plugin_instance.delete_vip( - context.get_admin_context(), vip['id']) - - def test_delete_vip_failure(self): - plugin = self.plugin_instance - - with self.network(do_delete=False) as network: - with self.subnet(network=network, do_delete=False) as subnet: - with self.pool(no_delete=True, - provider='radware', - subnet_id=subnet['subnet']['id']) as pool: - with contextlib.nested( - self.member(pool_id=pool['pool']['id'], - no_delete=True), - self.member(pool_id=pool['pool']['id'], - address='192.168.1.101', - no_delete=True), - self.health_monitor(no_delete=True), - self.vip(pool=pool, subnet=subnet, no_delete=True) - ) as (mem1, mem2, hm, vip): - - plugin.create_pool_health_monitor( - context.get_admin_context(), hm, pool['pool']['id'] - ) - - rest_call_function_mock.__dict__.update( - {'RESPOND_WITH_ERROR': True}) - - plugin.delete_vip( - context.get_admin_context(), vip['vip']['id']) - - u_vip = plugin.get_vip( - context.get_admin_context(), vip['vip']['id']) - u_pool = plugin.get_pool( - context.get_admin_context(), pool['pool']['id']) - u_mem1 = plugin.get_member( - context.get_admin_context(), mem1['member']['id']) - u_mem2 = plugin.get_member( - context.get_admin_context(), mem2['member']['id']) - u_phm = plugin.get_pool_health_monitor( - context.get_admin_context(), - hm['health_monitor']['id'], pool['pool']['id']) - - self.assertEqual(u_vip['status'], constants.ERROR) - self.assertEqual(u_pool['status'], constants.ACTIVE) - self.assertEqual(u_mem1['status'], constants.ACTIVE) - self.assertEqual(u_mem2['status'], constants.ACTIVE) - self.assertEqual(u_phm['status'], constants.ACTIVE) - - def test_delete_vip(self): - with self.subnet() as subnet: - with self.pool(provider='radware', - no_delete=True, - subnet_id=subnet['subnet']['id']) as pool: - vip_data = { - 'name': 'vip1', - 'subnet_id': subnet['subnet']['id'], - 'pool_id': pool['pool']['id'], - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': constants.PENDING_CREATE, - 'tenant_id': self._tenant_id, - 'session_persistence': '' - } - - vip = self.plugin_instance.create_vip( - context.get_admin_context(), {'vip': vip_data}) - - self.plugin_instance.delete_vip( - context.get_admin_context(), vip['id']) - - calls = [ - mock.call('DELETE', '/api/workflow/' + pool['pool']['id'], - None, None) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - self.assertRaises(loadbalancer.VipNotFound, - self.plugin_instance.get_vip, - context.get_admin_context(), vip['id']) - - def test_delete_vip_2_leg(self): - """Test deletion of a VIP where Alteon VIP and PIP are different.""" - - self.driver_rest_call_mock.reset_mock() - with self.subnet(cidr='10.0.0.0/24') as subnet: - with self.subnet(cidr='10.0.1.0/24') as pool_subnet: - with self.pool(provider='radware', - no_delete=True, - subnet_id=pool_subnet['subnet']['id']) as pool: - vip_data = { - 'name': 'vip1', - 'subnet_id': subnet['subnet']['id'], - 'pool_id': pool['pool']['id'], - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': constants.PENDING_CREATE, - 'tenant_id': self._tenant_id, - 'session_persistence': '' - } - - vip = self.plugin_instance.create_vip( - context.get_admin_context(), {'vip': vip_data}) - - self.plugin_instance.delete_vip( - context.get_admin_context(), vip['id']) - - calls = [ - mock.call('DELETE', '/api/workflow/' + - pool['pool']['id'], None, None) - ] - self.driver_rest_call_mock.assert_has_calls(calls) - - # Test that PIP neutron port was deleted - pip_port_filter = { - 'name': ['pip_' + vip['id']], - } - plugin = manager.NeutronManager.get_plugin() - num_ports = plugin.get_ports_count( - context.get_admin_context(), filters=pip_port_filter) - self.assertTrue(num_ports == 0) - - self.assertRaises(loadbalancer.VipNotFound, - self.plugin_instance.get_vip, - context.get_admin_context(), vip['id']) - - def test_update_pool(self): - with self.subnet(): - with self.pool() as pool: - del pool['pool']['provider'] - del pool['pool']['status'] - self.plugin_instance.update_pool( - context.get_admin_context(), - pool['pool']['id'], pool) - pool_db = self.plugin_instance.get_pool( - context.get_admin_context(), pool['pool']['id']) - self.assertEqual(pool_db['status'], constants.PENDING_UPDATE) - - def test_delete_pool_with_vip(self): - with self.subnet() as subnet: - with self.pool(provider='radware', - no_delete=True, - subnet_id=subnet['subnet']['id']) as pool: - with self.vip(pool=pool, subnet=subnet): - self.assertRaises(loadbalancer.PoolInUse, - self.plugin_instance.delete_pool, - context.get_admin_context(), - pool['pool']['id']) - - def test_create_member_with_vip(self): - with self.subnet() as subnet: - with self.pool(provider='radware', - subnet_id=subnet['subnet']['id']) as p: - with self.vip(pool=p, subnet=subnet): - with self.member(pool_id=p['pool']['id']): - calls = [ - mock.call( - 'POST', '/api/workflow/' + p['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ), - mock.call( - 'POST', '/api/workflow/' + p['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - def test_create_member_on_different_subnets(self): - with contextlib.nested( - self.subnet(), - self.subnet(cidr='20.0.0.0/24'), - self.subnet(cidr='30.0.0.0/24') - ) as (vip_sub, pool_sub, member_sub): - with self.pool(provider='radware', - subnet_id=pool_sub['subnet']['id']) as pool: - with contextlib.nested( - self.port(subnet=vip_sub, - fixed_ips=[{'ip_address': '10.0.0.2'}]), - self.port(subnet=pool_sub, - fixed_ips=[{'ip_address': '20.0.0.2'}]), - self.port(subnet=member_sub, - fixed_ips=[{'ip_address': '30.0.0.2'}]) - ): - with contextlib.nested( - self.member(pool_id=pool['pool']['id'], - address='10.0.0.2'), - self.member(pool_id=pool['pool']['id'], - address='20.0.0.2'), - self.member(pool_id=pool['pool']['id'], - address='30.0.0.2') - ) as (member_vip, member_pool, member_out): - with self.vip(pool=pool, subnet=vip_sub): - calls = [ - mock.call( - 'POST', '/api/workflow/' + - pool['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - mock_calls = self.driver_rest_call_mock.mock_calls - params = mock_calls[-2][1][2]['parameters'] - member_subnet_array = params['member_subnet_array'] - member_mask_array = params['member_mask_array'] - member_gw_array = params['member_gw_array'] - self.assertEqual(member_subnet_array, - ['10.0.0.0', - '255.255.255.255', - '30.0.0.0']) - self.assertEqual(member_mask_array, - ['255.255.255.0', - '255.255.255.255', - '255.255.255.0']) - self.assertEqual( - member_gw_array, - [pool_sub['subnet']['gateway_ip'], - '255.255.255.255', - pool_sub['subnet']['gateway_ip']]) - - def test_create_member_on_different_subnet_no_port(self): - with contextlib.nested( - self.subnet(), - self.subnet(cidr='20.0.0.0/24'), - self.subnet(cidr='30.0.0.0/24') - ) as (vip_sub, pool_sub, member_sub): - with self.pool(provider='radware', - subnet_id=pool_sub['subnet']['id']) as pool: - with self.member(pool_id=pool['pool']['id'], - address='30.0.0.2'): - with self.vip(pool=pool, subnet=vip_sub): - calls = [ - mock.call( - 'POST', '/api/workflow/' + - pool['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - mock_calls = self.driver_rest_call_mock.mock_calls - params = mock_calls[-2][1][2]['parameters'] - member_subnet_array = params['member_subnet_array'] - member_mask_array = params['member_mask_array'] - member_gw_array = params['member_gw_array'] - self.assertEqual(member_subnet_array, - ['30.0.0.2']) - self.assertEqual(member_mask_array, - ['255.255.255.255']) - self.assertEqual(member_gw_array, - [pool_sub['subnet']['gateway_ip']]) - - def test_create_member_on_different_subnet_multiple_ports(self): - cfg.CONF.set_override("allow_overlapping_ips", 'true') - with self.network() as other_net: - with contextlib.nested( - self.subnet(), - self.subnet(cidr='20.0.0.0/24'), - self.subnet(cidr='30.0.0.0/24'), - self.subnet(network=other_net, cidr='30.0.0.0/24') - ) as (vip_sub, pool_sub, member_sub1, member_sub2): - with self.pool(provider='radware', - subnet_id=pool_sub['subnet']['id']) as pool: - with contextlib.nested( - self.port(subnet=member_sub1, - fixed_ips=[{'ip_address': '30.0.0.2'}]), - self.port(subnet=member_sub2, - fixed_ips=[{'ip_address': '30.0.0.2'}])): - with self.member(pool_id=pool['pool']['id'], - address='30.0.0.2'): - with self.vip(pool=pool, subnet=vip_sub): - calls = [ - mock.call( - 'POST', '/api/workflow/' + - pool['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - calls = self.driver_rest_call_mock.mock_calls - params = calls[-2][1][2]['parameters'] - m_sub_array = params['member_subnet_array'] - m_mask_array = params['member_mask_array'] - m_gw_array = params['member_gw_array'] - self.assertEqual(m_sub_array, - ['30.0.0.2']) - self.assertEqual(m_mask_array, - ['255.255.255.255']) - self.assertEqual( - m_gw_array, - [pool_sub['subnet']['gateway_ip']]) - - def test_update_member_with_vip(self): - with self.subnet() as subnet: - with self.pool(provider='radware', - subnet_id=subnet['subnet']['id']) as p: - with self.member(pool_id=p['pool']['id']) as member: - with self.vip(pool=p, subnet=subnet): - self.plugin_instance.update_member( - context.get_admin_context(), - member['member']['id'], member - ) - calls = [ - mock.call( - 'POST', '/api/workflow/' + p['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ), - mock.call( - 'POST', '/api/workflow/' + p['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - updated_member = self.plugin_instance.get_member( - context.get_admin_context(), - member['member']['id'] - ) - - updated_member = self.plugin_instance.get_member( - context.get_admin_context(), - member['member']['id'] - ) - self.assertEqual(updated_member['status'], - constants.ACTIVE) - - def test_update_member_without_vip(self): - with self.subnet(): - with self.pool(provider='radware') as pool: - with self.member(pool_id=pool['pool']['id']) as member: - member['member']['status'] = constants.PENDING_UPDATE - updated_member = self.plugin_instance.update_member( - context.get_admin_context(), - member['member']['id'], member - ) - self.assertEqual(updated_member['status'], - constants.PENDING_UPDATE) - - def test_delete_member_with_vip(self): - with self.subnet() as subnet: - with self.pool(provider='radware', - subnet_id=subnet['subnet']['id']) as p: - with self.member(pool_id=p['pool']['id'], - no_delete=True) as m: - with self.vip(pool=p, subnet=subnet): - - # Reset mock and - # wait for being sure the member - # Changed status from PENDING-CREATE - # to ACTIVE - - self.plugin_instance.delete_member( - context.get_admin_context(), - m['member']['id'] - ) - - name, args, kwargs = ( - self.driver_rest_call_mock.mock_calls[-2] - ) - deletion_post_graph = str(args[2]) - - self.assertTrue(re.search( - r'.*\'member_address_array\': \[\].*', - deletion_post_graph - )) - - calls = [ - mock.call( - 'POST', '/api/workflow/' + p['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - self.assertRaises(loadbalancer.MemberNotFound, - self.plugin_instance.get_member, - context.get_admin_context(), - m['member']['id']) - - def test_delete_member_without_vip(self): - with self.subnet(): - with self.pool(provider='radware') as p: - with self.member(pool_id=p['pool']['id'], no_delete=True) as m: - self.plugin_instance.delete_member( - context.get_admin_context(), m['member']['id'] - ) - self.assertRaises(loadbalancer.MemberNotFound, - self.plugin_instance.get_member, - context.get_admin_context(), - m['member']['id']) - - def test_create_hm_with_vip(self): - with self.subnet() as subnet: - with self.health_monitor() as hm: - with self.pool(provider='radware', - subnet_id=subnet['subnet']['id']) as pool: - with self.vip(pool=pool, subnet=subnet): - - self.plugin_instance.create_pool_health_monitor( - context.get_admin_context(), - hm, pool['pool']['id'] - ) - - # Test REST calls - calls = [ - mock.call( - 'POST', '/api/workflow/' + pool['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ), - mock.call( - 'POST', '/api/workflow/' + pool['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - phm = self.plugin_instance.get_pool_health_monitor( - context.get_admin_context(), - hm['health_monitor']['id'], pool['pool']['id'] - ) - self.assertEqual(phm['status'], constants.ACTIVE) - - def test_delete_pool_hm_with_vip(self): - with self.subnet() as subnet: - with self.health_monitor(no_delete=True) as hm: - with self.pool(provider='radware', - subnet_id=subnet['subnet']['id']) as pool: - with self.vip(pool=pool, subnet=subnet): - self.plugin_instance.create_pool_health_monitor( - context.get_admin_context(), - hm, pool['pool']['id'] - ) - - self.plugin_instance.delete_pool_health_monitor( - context.get_admin_context(), - hm['health_monitor']['id'], - pool['pool']['id'] - ) - - name, args, kwargs = ( - self.driver_rest_call_mock.mock_calls[-2] - ) - deletion_post_graph = str(args[2]) - - self.assertTrue(re.search( - r'.*\'hm_uuid_array\': \[\].*', - deletion_post_graph - )) - - calls = [ - mock.call( - 'POST', '/api/workflow/' + pool['pool']['id'] + - '/action/BaseCreate', - mock.ANY, driver.TEMPLATE_HEADER - ) - ] - self.driver_rest_call_mock.assert_has_calls( - calls, any_order=True) - - self.assertRaises( - loadbalancer.PoolMonitorAssociationNotFound, - self.plugin_instance.get_pool_health_monitor, - context.get_admin_context(), - hm['health_monitor']['id'], - pool['pool']['id'] - ) diff --git a/neutron/tests/unit/services/loadbalancer/drivers/test_agent_driver_base.py b/neutron/tests/unit/services/loadbalancer/drivers/test_agent_driver_base.py deleted file mode 100644 index 6a9221306..000000000 --- a/neutron/tests/unit/services/loadbalancer/drivers/test_agent_driver_base.py +++ /dev/null @@ -1,753 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost - -import contextlib - -import mock -from six import moves -from webob import exc - -from neutron import context -from neutron.db.loadbalancer import loadbalancer_db as ldb -from neutron.db import servicetype_db as st_db -from neutron.extensions import loadbalancer -from neutron.extensions import portbindings -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.services.loadbalancer.drivers.common import agent_driver_base -from neutron.tests import base -from neutron.tests.unit.db.loadbalancer import test_db_loadbalancer -from neutron.tests.unit import testlib_api - - -class TestLoadBalancerPluginBase( - test_db_loadbalancer.LoadBalancerPluginDbTestCase): - - def setUp(self): - def reset_device_driver(): - agent_driver_base.AgentDriverBase.device_driver = None - self.addCleanup(reset_device_driver) - - self.mock_importer = mock.patch.object( - agent_driver_base, 'importutils').start() - - # needed to reload provider configuration - st_db.ServiceTypeManager._instance = None - agent_driver_base.AgentDriverBase.device_driver = 'dummy' - super(TestLoadBalancerPluginBase, self).setUp( - lbaas_provider=('LOADBALANCER:lbaas:neutron.services.' - 'loadbalancer.drivers.common.agent_driver_base.' - 'AgentDriverBase:default')) - - # we need access to loaded plugins to modify models - loaded_plugins = manager.NeutronManager().get_service_plugins() - - self.plugin_instance = loaded_plugins[constants.LOADBALANCER] - - -class TestLoadBalancerCallbacks(TestLoadBalancerPluginBase): - def setUp(self): - super(TestLoadBalancerCallbacks, self).setUp() - - self.callbacks = agent_driver_base.LoadBalancerCallbacks( - self.plugin_instance - ) - get_lbaas_agents_patcher = mock.patch( - 'neutron.services.loadbalancer.agent_scheduler' - '.LbaasAgentSchedulerDbMixin.get_lbaas_agents') - get_lbaas_agents_patcher.start() - - def test_get_ready_devices(self): - with self.vip() as vip: - with mock.patch('neutron.services.loadbalancer.agent_scheduler' - '.LbaasAgentSchedulerDbMixin.' - 'list_pools_on_lbaas_agent') as mock_agent_pools: - mock_agent_pools.return_value = { - 'pools': [{'id': vip['vip']['pool_id']}]} - ready = self.callbacks.get_ready_devices( - context.get_admin_context(), - ) - self.assertEqual(ready, [vip['vip']['pool_id']]) - - def test_get_ready_devices_multiple_vips_and_pools(self): - ctx = context.get_admin_context() - - # add 3 pools and 2 vips directly to DB - # to create 2 "ready" devices and one pool without vip - pools = [] - for i in moves.xrange(3): - pools.append(ldb.Pool(id=uuidutils.generate_uuid(), - subnet_id=self._subnet_id, - protocol="HTTP", - lb_method="ROUND_ROBIN", - status=constants.ACTIVE, - admin_state_up=True)) - ctx.session.add(pools[i]) - - vip0 = ldb.Vip(id=uuidutils.generate_uuid(), - protocol_port=80, - protocol="HTTP", - pool_id=pools[0].id, - status=constants.ACTIVE, - admin_state_up=True, - connection_limit=3) - ctx.session.add(vip0) - pools[0].vip_id = vip0.id - - vip1 = ldb.Vip(id=uuidutils.generate_uuid(), - protocol_port=80, - protocol="HTTP", - pool_id=pools[1].id, - status=constants.ACTIVE, - admin_state_up=True, - connection_limit=3) - ctx.session.add(vip1) - pools[1].vip_id = vip1.id - - ctx.session.flush() - - self.assertEqual(ctx.session.query(ldb.Pool).count(), 3) - self.assertEqual(ctx.session.query(ldb.Vip).count(), 2) - with mock.patch('neutron.services.loadbalancer.agent_scheduler' - '.LbaasAgentSchedulerDbMixin' - '.list_pools_on_lbaas_agent') as mock_agent_pools: - mock_agent_pools.return_value = {'pools': [{'id': pools[0].id}, - {'id': pools[1].id}, - {'id': pools[2].id}]} - ready = self.callbacks.get_ready_devices(ctx) - self.assertEqual(len(ready), 3) - self.assertIn(pools[0].id, ready) - self.assertIn(pools[1].id, ready) - self.assertIn(pools[2].id, ready) - # cleanup - ctx.session.query(ldb.Pool).delete() - ctx.session.query(ldb.Vip).delete() - - def test_get_ready_devices_inactive_vip(self): - with self.vip() as vip: - - # set the vip inactive need to use plugin directly since - # status is not tenant mutable - self.plugin_instance.update_vip( - context.get_admin_context(), - vip['vip']['id'], - {'vip': {'status': constants.INACTIVE}} - ) - with mock.patch('neutron.services.loadbalancer.agent_scheduler' - '.LbaasAgentSchedulerDbMixin.' - 'list_pools_on_lbaas_agent') as mock_agent_pools: - mock_agent_pools.return_value = { - 'pools': [{'id': vip['vip']['pool_id']}]} - ready = self.callbacks.get_ready_devices( - context.get_admin_context(), - ) - self.assertEqual([vip['vip']['pool_id']], ready) - - def test_get_ready_devices_inactive_pool(self): - with self.vip() as vip: - - # set the pool inactive need to use plugin directly since - # status is not tenant mutable - self.plugin_instance.update_pool( - context.get_admin_context(), - vip['vip']['pool_id'], - {'pool': {'status': constants.INACTIVE}} - ) - with mock.patch('neutron.services.loadbalancer.agent_scheduler' - '.LbaasAgentSchedulerDbMixin.' - 'list_pools_on_lbaas_agent') as mock_agent_pools: - mock_agent_pools.return_value = { - 'pools': [{'id': vip['vip']['pool_id']}]} - ready = self.callbacks.get_ready_devices( - context.get_admin_context(), - ) - self.assertFalse(ready) - - def test_get_logical_device_non_active(self): - with self.pool() as pool: - ctx = context.get_admin_context() - for status in ('INACTIVE', 'PENDING_CREATE', 'PENDING_UPDATE'): - self.plugin_instance.update_status( - ctx, ldb.Pool, pool['pool']['id'], status) - pool['pool']['status'] = status - expected = { - 'pool': pool['pool'], - 'members': [], - 'healthmonitors': [], - 'driver': 'dummy' - } - - logical_config = self.callbacks.get_logical_device( - ctx, pool['pool']['id'] - ) - - self.assertEqual(expected, logical_config) - - def test_get_logical_device_active(self): - with self.pool() as pool: - with self.vip(pool=pool) as vip: - with self.member(pool_id=vip['vip']['pool_id']) as member: - ctx = context.get_admin_context() - # activate objects - self.plugin_instance.update_status( - ctx, ldb.Pool, pool['pool']['id'], 'ACTIVE') - self.plugin_instance.update_status( - ctx, ldb.Member, member['member']['id'], 'ACTIVE') - self.plugin_instance.update_status( - ctx, ldb.Vip, vip['vip']['id'], 'ACTIVE') - - # build the expected - port = self.plugin_instance._core_plugin.get_port( - ctx, vip['vip']['port_id'] - ) - subnet = self.plugin_instance._core_plugin.get_subnet( - ctx, vip['vip']['subnet_id'] - ) - port['fixed_ips'][0]['subnet'] = subnet - - # reload pool to add members and vip - pool = self.plugin_instance.get_pool( - ctx, pool['pool']['id'] - ) - - pool['status'] = constants.ACTIVE - vip['vip']['status'] = constants.ACTIVE - vip['vip']['port'] = port - member['member']['status'] = constants.ACTIVE - - expected = { - 'pool': pool, - 'vip': vip['vip'], - 'members': [member['member']], - 'healthmonitors': [], - 'driver': 'dummy' - } - - logical_config = self.callbacks.get_logical_device( - ctx, pool['id'] - ) - - self.assertEqual(logical_config, expected) - - def test_get_logical_device_inactive_member(self): - with self.pool() as pool: - with self.vip(pool=pool) as vip: - with self.member(pool_id=vip['vip']['pool_id']) as member: - ctx = context.get_admin_context() - self.plugin_instance.update_status(ctx, ldb.Pool, - pool['pool']['id'], - 'ACTIVE') - self.plugin_instance.update_status(ctx, ldb.Vip, - vip['vip']['id'], - 'ACTIVE') - self.plugin_instance.update_status(ctx, ldb.Member, - member['member']['id'], - 'INACTIVE') - - logical_config = self.callbacks.get_logical_device( - ctx, pool['pool']['id']) - - member['member']['status'] = constants.INACTIVE - self.assertEqual([member['member']], - logical_config['members']) - - def test_get_logical_device_pending_create_member(self): - with self.pool() as pool: - with self.vip(pool=pool) as vip: - with self.member(pool_id=vip['vip']['pool_id']) as member: - ctx = context.get_admin_context() - self.plugin_instance.update_status(ctx, ldb.Pool, - pool['pool']['id'], - 'ACTIVE') - self.plugin_instance.update_status(ctx, ldb.Vip, - vip['vip']['id'], - 'ACTIVE') - - member = self.plugin_instance.get_member( - ctx, member['member']['id']) - self.assertEqual('PENDING_CREATE', - member['status']) - logical_config = self.callbacks.get_logical_device( - ctx, pool['pool']['id']) - - self.assertEqual([member], logical_config['members']) - - def test_get_logical_device_pending_create_health_monitor(self): - with self.health_monitor() as monitor: - with self.pool() as pool: - with self.vip(pool=pool) as vip: - ctx = context.get_admin_context() - self.plugin_instance.update_status(ctx, ldb.Pool, - pool['pool']['id'], - 'ACTIVE') - self.plugin_instance.update_status(ctx, ldb.Vip, - vip['vip']['id'], - 'ACTIVE') - self.plugin_instance.create_pool_health_monitor( - ctx, monitor, pool['pool']['id']) - pool = self.plugin_instance.get_pool( - ctx, pool['pool']['id']) - monitor = self.plugin_instance.get_health_monitor( - ctx, monitor['health_monitor']['id']) - - self.assertEqual( - 'PENDING_CREATE', - pool['health_monitors_status'][0]['status']) - logical_config = self.callbacks.get_logical_device( - ctx, pool['id']) - - self.assertEqual([monitor], - logical_config['healthmonitors']) - - def _update_port_test_helper(self, expected, func, **kwargs): - core = self.plugin_instance._core_plugin - - with self.pool() as pool: - with self.vip(pool=pool) as vip: - with self.member(pool_id=vip['vip']['pool_id']): - ctx = context.get_admin_context() - func(ctx, port_id=vip['vip']['port_id'], **kwargs) - - db_port = core.get_port(ctx, vip['vip']['port_id']) - - for k, v in expected.iteritems(): - self.assertEqual(db_port[k], v) - - def test_plug_vip_port(self): - exp = { - 'device_owner': 'neutron:' + constants.LOADBALANCER, - 'device_id': 'c596ce11-db30-5c72-8243-15acaae8690f', - 'admin_state_up': True - } - self._update_port_test_helper( - exp, - self.callbacks.plug_vip_port, - host='host' - ) - - def test_plug_vip_port_mock_with_host(self): - exp = { - 'device_owner': 'neutron:' + constants.LOADBALANCER, - 'device_id': 'c596ce11-db30-5c72-8243-15acaae8690f', - 'admin_state_up': True, - portbindings.HOST_ID: 'host' - } - with mock.patch.object( - self.plugin._core_plugin, 'update_port') as mock_update_port: - with self.pool() as pool: - with self.vip(pool=pool) as vip: - ctx = context.get_admin_context() - self.callbacks.plug_vip_port( - ctx, port_id=vip['vip']['port_id'], host='host') - mock_update_port.assert_called_once_with( - ctx, vip['vip']['port_id'], - {'port': testlib_api.SubDictMatch(exp)}) - - def test_unplug_vip_port(self): - exp = { - 'device_owner': '', - 'device_id': '', - 'admin_state_up': False - } - self._update_port_test_helper( - exp, - self.callbacks.unplug_vip_port, - host='host' - ) - - def test_pool_deployed(self): - with self.pool() as pool: - with self.vip(pool=pool) as vip: - with self.member(pool_id=vip['vip']['pool_id']) as member: - ctx = context.get_admin_context() - p = self.plugin_instance.get_pool(ctx, pool['pool']['id']) - self.assertEqual('PENDING_CREATE', p['status']) - v = self.plugin_instance.get_vip(ctx, vip['vip']['id']) - self.assertEqual('PENDING_CREATE', v['status']) - m = self.plugin_instance.get_member( - ctx, member['member']['id']) - self.assertEqual('PENDING_CREATE', m['status']) - - self.callbacks.pool_deployed(ctx, pool['pool']['id']) - - p = self.plugin_instance.get_pool(ctx, pool['pool']['id']) - self.assertEqual('ACTIVE', p['status']) - v = self.plugin_instance.get_vip(ctx, vip['vip']['id']) - self.assertEqual('ACTIVE', v['status']) - m = self.plugin_instance.get_member( - ctx, member['member']['id']) - self.assertEqual('ACTIVE', m['status']) - - def test_update_status_pool(self): - with self.pool() as pool: - pool_id = pool['pool']['id'] - ctx = context.get_admin_context() - p = self.plugin_instance.get_pool(ctx, pool_id) - self.assertEqual('PENDING_CREATE', p['status']) - self.callbacks.update_status(ctx, 'pool', pool_id, 'ACTIVE') - p = self.plugin_instance.get_pool(ctx, pool_id) - self.assertEqual('ACTIVE', p['status']) - - def test_update_status_pool_deleted_already(self): - with mock.patch.object(agent_driver_base, 'LOG') as mock_log: - pool_id = 'deleted_pool' - ctx = context.get_admin_context() - self.assertRaises(loadbalancer.PoolNotFound, - self.plugin_instance.get_pool, ctx, pool_id) - self.callbacks.update_status(ctx, 'pool', pool_id, 'ACTIVE') - self.assertTrue(mock_log.warning.called) - - def test_update_status_health_monitor(self): - with contextlib.nested( - self.health_monitor(), - self.pool() - ) as (hm, pool): - pool_id = pool['pool']['id'] - ctx = context.get_admin_context() - self.plugin_instance.create_pool_health_monitor(ctx, hm, pool_id) - hm_id = hm['health_monitor']['id'] - h = self.plugin_instance.get_pool_health_monitor(ctx, hm_id, - pool_id) - self.assertEqual('PENDING_CREATE', h['status']) - self.callbacks.update_status( - ctx, 'health_monitor', - {'monitor_id': hm_id, 'pool_id': pool_id}, 'ACTIVE') - h = self.plugin_instance.get_pool_health_monitor(ctx, hm_id, - pool_id) - self.assertEqual('ACTIVE', h['status']) - - -class TestLoadBalancerAgentApi(base.BaseTestCase): - def setUp(self): - super(TestLoadBalancerAgentApi, self).setUp() - - self.api = agent_driver_base.LoadBalancerAgentApi('topic') - self.mock_cast = mock.patch.object(self.api, 'cast').start() - self.mock_msg = mock.patch.object(self.api, 'make_msg').start() - - def test_init(self): - self.assertEqual(self.api.topic, 'topic') - - def _call_test_helper(self, method_name, method_args): - rv = getattr(self.api, method_name)(mock.sentinel.context, - host='host', - **method_args) - self.assertEqual(rv, self.mock_cast.return_value) - self.mock_cast.assert_called_once_with( - mock.sentinel.context, - self.mock_msg.return_value, - topic='topic.host', - version=None - ) - - if method_name == 'agent_updated': - method_args = {'payload': method_args} - self.mock_msg.assert_called_once_with( - method_name, - **method_args - ) - - def test_agent_updated(self): - self._call_test_helper('agent_updated', {'admin_state_up': 'test'}) - - def test_create_pool(self): - self._call_test_helper('create_pool', {'pool': 'test', - 'driver_name': 'dummy'}) - - def test_update_pool(self): - self._call_test_helper('update_pool', {'old_pool': 'test', - 'pool': 'test'}) - - def test_delete_pool(self): - self._call_test_helper('delete_pool', {'pool': 'test'}) - - def test_create_vip(self): - self._call_test_helper('create_vip', {'vip': 'test'}) - - def test_update_vip(self): - self._call_test_helper('update_vip', {'old_vip': 'test', - 'vip': 'test'}) - - def test_delete_vip(self): - self._call_test_helper('delete_vip', {'vip': 'test'}) - - def test_create_member(self): - self._call_test_helper('create_member', {'member': 'test'}) - - def test_update_member(self): - self._call_test_helper('update_member', {'old_member': 'test', - 'member': 'test'}) - - def test_delete_member(self): - self._call_test_helper('delete_member', {'member': 'test'}) - - def test_create_monitor(self): - self._call_test_helper('create_pool_health_monitor', - {'health_monitor': 'test', 'pool_id': 'test'}) - - def test_update_monitor(self): - self._call_test_helper('update_pool_health_monitor', - {'old_health_monitor': 'test', - 'health_monitor': 'test', - 'pool_id': 'test'}) - - def test_delete_monitor(self): - self._call_test_helper('delete_pool_health_monitor', - {'health_monitor': 'test', 'pool_id': 'test'}) - - -class TestLoadBalancerPluginNotificationWrapper(TestLoadBalancerPluginBase): - def setUp(self): - self.log = mock.patch.object(agent_driver_base, 'LOG') - api_cls = mock.patch.object(agent_driver_base, - 'LoadBalancerAgentApi').start() - super(TestLoadBalancerPluginNotificationWrapper, self).setUp() - self.mock_api = api_cls.return_value - - self.mock_get_driver = mock.patch.object(self.plugin_instance, - '_get_driver') - self.mock_get_driver.return_value = (agent_driver_base. - AgentDriverBase( - self.plugin_instance - )) - - def test_create_vip(self): - with self.subnet() as subnet: - with self.pool(subnet=subnet) as pool: - with self.vip(pool=pool, subnet=subnet) as vip: - self.mock_api.create_vip.assert_called_once_with( - mock.ANY, - vip['vip'], - 'host' - ) - - def test_update_vip(self): - with self.subnet() as subnet: - with self.pool(subnet=subnet) as pool: - with self.vip(pool=pool, subnet=subnet) as vip: - ctx = context.get_admin_context() - old_vip = vip['vip'].copy() - vip['vip'].pop('status') - new_vip = self.plugin_instance.update_vip( - ctx, - vip['vip']['id'], - vip - ) - - self.mock_api.update_vip.assert_called_once_with( - mock.ANY, - old_vip, - new_vip, - 'host' - ) - - self.assertEqual( - new_vip['status'], - constants.PENDING_UPDATE - ) - - def test_delete_vip(self): - with self.subnet() as subnet: - with self.pool(subnet=subnet) as pool: - with self.vip(pool=pool, subnet=subnet, no_delete=True) as vip: - ctx = context.get_admin_context() - self.plugin_instance.delete_vip(ctx, vip['vip']['id']) - vip['vip']['status'] = 'PENDING_DELETE' - self.mock_api.delete_vip.assert_called_once_with( - mock.ANY, - vip['vip'], - 'host' - ) - - def test_create_pool(self): - with self.pool() as pool: - self.mock_api.create_pool.assert_called_once_with( - mock.ANY, - pool['pool'], - mock.ANY, - 'dummy' - ) - - def test_update_pool_non_active(self): - with self.pool() as pool: - pool['pool']['status'] = 'INACTIVE' - ctx = context.get_admin_context() - orig_pool = pool['pool'].copy() - del pool['pool']['provider'] - self.plugin_instance.update_pool(ctx, pool['pool']['id'], pool) - self.mock_api.delete_pool.assert_called_once_with( - mock.ANY, orig_pool, 'host') - - def test_update_pool_no_vip_id(self): - with self.pool() as pool: - ctx = context.get_admin_context() - orig_pool = pool['pool'].copy() - del pool['pool']['provider'] - updated = self.plugin_instance.update_pool( - ctx, pool['pool']['id'], pool) - self.mock_api.update_pool.assert_called_once_with( - mock.ANY, orig_pool, updated, 'host') - - def test_update_pool_with_vip_id(self): - with self.pool() as pool: - with self.vip(pool=pool) as vip: - ctx = context.get_admin_context() - old_pool = pool['pool'].copy() - old_pool['vip_id'] = vip['vip']['id'] - del pool['pool']['provider'] - updated = self.plugin_instance.update_pool( - ctx, pool['pool']['id'], pool) - self.mock_api.update_pool.assert_called_once_with( - mock.ANY, old_pool, updated, 'host') - - def test_delete_pool(self): - with self.pool(no_delete=True) as pool: - req = self.new_delete_request('pools', - pool['pool']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, exc.HTTPNoContent.code) - pool['pool']['status'] = 'PENDING_DELETE' - self.mock_api.delete_pool.assert_called_once_with( - mock.ANY, pool['pool'], 'host') - - def test_create_member(self): - with self.pool() as pool: - pool_id = pool['pool']['id'] - with self.member(pool_id=pool_id) as member: - self.mock_api.create_member.assert_called_once_with( - mock.ANY, member['member'], 'host') - - def test_update_member(self): - with self.pool() as pool: - pool_id = pool['pool']['id'] - with self.member(pool_id=pool_id) as member: - ctx = context.get_admin_context() - updated = self.plugin_instance.update_member( - ctx, member['member']['id'], member) - self.mock_api.update_member.assert_called_once_with( - mock.ANY, member['member'], updated, 'host') - - def test_update_member_new_pool(self): - with self.pool() as pool1: - pool1_id = pool1['pool']['id'] - with self.pool() as pool2: - pool2_id = pool2['pool']['id'] - with self.member(pool_id=pool1_id) as member: - self.mock_api.create_member.reset_mock() - ctx = context.get_admin_context() - old_member = member['member'].copy() - member['member']['pool_id'] = pool2_id - updated = self.plugin_instance.update_member( - ctx, member['member']['id'], member) - self.mock_api.delete_member.assert_called_once_with( - mock.ANY, old_member, 'host') - self.mock_api.create_member.assert_called_once_with( - mock.ANY, updated, 'host') - - def test_delete_member(self): - with self.pool() as pool: - pool_id = pool['pool']['id'] - with self.member(pool_id=pool_id, - no_delete=True) as member: - req = self.new_delete_request('members', - member['member']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, exc.HTTPNoContent.code) - member['member']['status'] = 'PENDING_DELETE' - self.mock_api.delete_member.assert_called_once_with( - mock.ANY, member['member'], 'host') - - def test_create_pool_health_monitor(self): - with contextlib.nested( - self.health_monitor(), - self.pool(), - ) as (hm, pool): - pool_id = pool['pool']['id'] - ctx = context.get_admin_context() - self.plugin_instance.create_pool_health_monitor(ctx, hm, pool_id) - # hm now has a ref to the pool with which it is associated - hm = self.plugin.get_health_monitor( - ctx, hm['health_monitor']['id']) - self.mock_api.create_pool_health_monitor.assert_called_once_with( - mock.ANY, hm, pool_id, 'host') - - def test_delete_pool_health_monitor(self): - with contextlib.nested( - self.pool(), - self.health_monitor() - ) as (pool, hm): - pool_id = pool['pool']['id'] - ctx = context.get_admin_context() - self.plugin_instance.create_pool_health_monitor(ctx, hm, pool_id) - # hm now has a ref to the pool with which it is associated - hm = self.plugin.get_health_monitor( - ctx, hm['health_monitor']['id']) - hm['pools'][0]['status'] = 'PENDING_DELETE' - self.plugin_instance.delete_pool_health_monitor( - ctx, hm['id'], pool_id) - self.mock_api.delete_pool_health_monitor.assert_called_once_with( - mock.ANY, hm, pool_id, 'host') - - def test_update_health_monitor_associated_with_pool(self): - with contextlib.nested( - self.health_monitor(type='HTTP'), - self.pool() - ) as (monitor, pool): - data = { - 'health_monitor': { - 'id': monitor['health_monitor']['id'], - 'tenant_id': self._tenant_id - } - } - req = self.new_create_request( - 'pools', - data, - fmt=self.fmt, - id=pool['pool']['id'], - subresource='health_monitors') - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - # hm now has a ref to the pool with which it is associated - ctx = context.get_admin_context() - hm = self.plugin.get_health_monitor( - ctx, monitor['health_monitor']['id']) - self.mock_api.create_pool_health_monitor.assert_called_once_with( - mock.ANY, - hm, - pool['pool']['id'], - 'host' - ) - - self.mock_api.reset_mock() - data = {'health_monitor': {'delay': 20, - 'timeout': 20, - 'max_retries': 2, - 'admin_state_up': False}} - updated = hm.copy() - updated.update(data['health_monitor']) - req = self.new_update_request("health_monitors", - data, - monitor['health_monitor']['id']) - req.get_response(self.ext_api) - self.mock_api.update_pool_health_monitor.assert_called_once_with( - mock.ANY, - hm, - updated, - pool['pool']['id'], - 'host') diff --git a/neutron/tests/unit/services/loadbalancer/test_agent_scheduler.py b/neutron/tests/unit/services/loadbalancer/test_agent_scheduler.py deleted file mode 100644 index 5ee947944..000000000 --- a/neutron/tests/unit/services/loadbalancer/test_agent_scheduler.py +++ /dev/null @@ -1,222 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 oslo.config import cfg -from webob import exc - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.common import constants -from neutron import context -from neutron.db import servicetype_db as st_db -from neutron.extensions import agent -from neutron.extensions import lbaas_agentscheduler -from neutron.extensions import loadbalancer -from neutron import manager -from neutron.plugins.common import constants as plugin_const -from neutron.tests.unit.db.loadbalancer import test_db_loadbalancer -from neutron.tests.unit.openvswitch import test_agent_scheduler -from neutron.tests.unit import test_agent_ext_plugin -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_extensions - -LBAAS_HOSTA = 'hosta' - - -class AgentSchedulerTestMixIn(test_agent_scheduler.AgentSchedulerTestMixIn): - def _list_pools_hosted_by_lbaas_agent(self, agent_id, - expected_code=exc.HTTPOk.code, - admin_context=True): - path = "/agents/%s/%s.%s" % (agent_id, - lbaas_agentscheduler.LOADBALANCER_POOLS, - self.fmt) - return self._request_list(path, expected_code=expected_code, - admin_context=admin_context) - - def _get_lbaas_agent_hosting_pool(self, pool_id, - expected_code=exc.HTTPOk.code, - admin_context=True): - path = "/lb/pools/%s/%s.%s" % (pool_id, - lbaas_agentscheduler.LOADBALANCER_AGENT, - self.fmt) - return self._request_list(path, expected_code=expected_code, - admin_context=admin_context) - - -class LBaaSAgentSchedulerTestCase(test_agent_ext_plugin.AgentDBTestMixIn, - AgentSchedulerTestMixIn, - test_db_loadbalancer.LoadBalancerTestMixin, - test_plugin.NeutronDbPluginV2TestCase): - fmt = 'json' - plugin_str = ('neutron.plugins.openvswitch.' - 'ovs_neutron_plugin.OVSNeutronPluginV2') - - def setUp(self): - # Save the global RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - service_plugins = { - 'lb_plugin_name': test_db_loadbalancer.DB_LB_PLUGIN_KLASS} - - #default provider should support agent scheduling - cfg.CONF.set_override( - 'service_provider', - [('LOADBALANCER:lbaas:neutron.services.' - 'loadbalancer.drivers.haproxy.plugin_driver.' - 'HaproxyOnHostPluginDriver:default')], - 'service_providers') - - # need to reload provider configuration - st_db.ServiceTypeManager._instance = None - - super(LBaaSAgentSchedulerTestCase, self).setUp( - self.plugin_str, service_plugins=service_plugins) - ext_mgr = extensions.PluginAwareExtensionManager.get_instance() - self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr) - self.adminContext = context.get_admin_context() - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - agent.RESOURCE_ATTRIBUTE_MAP) - self.addCleanup(self.restore_attribute_map) - - def restore_attribute_map(self): - # Restore the original RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - - def test_report_states(self): - self._register_agent_states(lbaas_agents=True) - agents = self._list_agents() - self.assertEqual(6, len(agents['agents'])) - - def test_pool_scheduling_on_pool_creation(self): - self._register_agent_states(lbaas_agents=True) - with self.pool() as pool: - lbaas_agent = self._get_lbaas_agent_hosting_pool( - pool['pool']['id']) - self.assertIsNotNone(lbaas_agent) - self.assertEqual(lbaas_agent['agent']['agent_type'], - constants.AGENT_TYPE_LOADBALANCER) - pools = self._list_pools_hosted_by_lbaas_agent( - lbaas_agent['agent']['id']) - self.assertEqual(1, len(pools['pools'])) - self.assertEqual(pool['pool'], pools['pools'][0]) - - def test_schedule_pool_with_disabled_agent(self): - lbaas_hosta = { - 'binary': 'neutron-loadbalancer-agent', - 'host': LBAAS_HOSTA, - 'topic': 'LOADBALANCER_AGENT', - 'configurations': {'device_drivers': ['haproxy_ns']}, - 'agent_type': constants.AGENT_TYPE_LOADBALANCER} - self._register_one_agent_state(lbaas_hosta) - with self.pool() as pool: - lbaas_agent = self._get_lbaas_agent_hosting_pool( - pool['pool']['id']) - self.assertIsNotNone(lbaas_agent) - - agents = self._list_agents() - self._disable_agent(agents['agents'][0]['id']) - pool = {'pool': {'name': 'test', - 'subnet_id': 'test', - 'lb_method': 'ROUND_ROBIN', - 'protocol': 'HTTP', - 'admin_state_up': True, - 'tenant_id': 'test', - 'description': 'test'}} - lbaas_plugin = manager.NeutronManager.get_service_plugins()[ - plugin_const.LOADBALANCER] - self.assertRaises(loadbalancer.NoEligibleBackend, - lbaas_plugin.create_pool, self.adminContext, pool) - pools = lbaas_plugin.get_pools(self.adminContext) - self.assertEqual('ERROR', pools[0]['status']) - self.assertEqual('No eligible backend', - pools[0]['status_description']) - - def test_schedule_pool_with_down_agent(self): - lbaas_hosta = { - 'binary': 'neutron-loadbalancer-agent', - 'host': LBAAS_HOSTA, - 'topic': 'LOADBALANCER_AGENT', - 'configurations': {'device_drivers': ['haproxy_ns']}, - 'agent_type': constants.AGENT_TYPE_LOADBALANCER} - self._register_one_agent_state(lbaas_hosta) - is_agent_down_str = 'neutron.db.agents_db.AgentDbMixin.is_agent_down' - with mock.patch(is_agent_down_str) as mock_is_agent_down: - mock_is_agent_down.return_value = False - with self.pool() as pool: - lbaas_agent = self._get_lbaas_agent_hosting_pool( - pool['pool']['id']) - self.assertIsNotNone(lbaas_agent) - with mock.patch(is_agent_down_str) as mock_is_agent_down: - mock_is_agent_down.return_value = True - pool = {'pool': {'name': 'test', - 'subnet_id': 'test', - 'lb_method': 'ROUND_ROBIN', - 'protocol': 'HTTP', - 'provider': 'lbaas', - 'admin_state_up': True, - 'tenant_id': 'test', - 'description': 'test'}} - lbaas_plugin = manager.NeutronManager.get_service_plugins()[ - plugin_const.LOADBALANCER] - self.assertRaises(loadbalancer.NoEligibleBackend, - lbaas_plugin.create_pool, - self.adminContext, pool) - pools = lbaas_plugin.get_pools(self.adminContext) - self.assertEqual('ERROR', pools[0]['status']) - self.assertEqual('No eligible backend', - pools[0]['status_description']) - - def test_pool_unscheduling_on_pool_deletion(self): - self._register_agent_states(lbaas_agents=True) - with self.pool(no_delete=True) as pool: - lbaas_agent = self._get_lbaas_agent_hosting_pool( - pool['pool']['id']) - self.assertIsNotNone(lbaas_agent) - self.assertEqual(lbaas_agent['agent']['agent_type'], - constants.AGENT_TYPE_LOADBALANCER) - pools = self._list_pools_hosted_by_lbaas_agent( - lbaas_agent['agent']['id']) - self.assertEqual(1, len(pools['pools'])) - self.assertEqual(pool['pool'], pools['pools'][0]) - - req = self.new_delete_request('pools', - pool['pool']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, exc.HTTPNoContent.code) - pools = self._list_pools_hosted_by_lbaas_agent( - lbaas_agent['agent']['id']) - self.assertEqual(0, len(pools['pools'])) - - def test_pool_scheduling_non_admin_access(self): - self._register_agent_states(lbaas_agents=True) - with self.pool() as pool: - self._get_lbaas_agent_hosting_pool( - pool['pool']['id'], - expected_code=exc.HTTPForbidden.code, - admin_context=False) - self._list_pools_hosted_by_lbaas_agent( - 'fake_id', - expected_code=exc.HTTPForbidden.code, - admin_context=False) - - -class LBaaSAgentSchedulerTestCaseXML(LBaaSAgentSchedulerTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/services/loadbalancer/test_loadbalancer_plugin.py b/neutron/tests/unit/services/loadbalancer/test_loadbalancer_plugin.py deleted file mode 100644 index 95fef74dd..000000000 --- a/neutron/tests/unit/services/loadbalancer/test_loadbalancer_plugin.py +++ /dev/null @@ -1,464 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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 copy - -import mock -from webob import exc - -from neutron.api.v2 import attributes as attr -from neutron.extensions import loadbalancer -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_api_v2_extension - - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path - - -class LoadBalancerExtensionTestCase(test_api_v2_extension.ExtensionTestCase): - fmt = 'json' - - def setUp(self): - super(LoadBalancerExtensionTestCase, self).setUp() - self._setUpExtension( - 'neutron.extensions.loadbalancer.LoadBalancerPluginBase', - constants.LOADBALANCER, loadbalancer.RESOURCE_ATTRIBUTE_MAP, - loadbalancer.Loadbalancer, 'lb', use_quota=True) - - def test_vip_create(self): - vip_id = _uuid() - data = {'vip': {'name': 'vip1', - 'description': 'descr_vip1', - 'subnet_id': _uuid(), - 'address': '127.0.0.1', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'pool_id': _uuid(), - 'session_persistence': {'type': 'HTTP_COOKIE'}, - 'connection_limit': 100, - 'admin_state_up': True, - 'tenant_id': _uuid()}} - return_value = copy.copy(data['vip']) - return_value.update({'status': "ACTIVE", 'id': vip_id}) - - instance = self.plugin.return_value - instance.create_vip.return_value = return_value - res = self.api.post(_get_path('lb/vips', fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_vip.assert_called_with(mock.ANY, - vip=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('vip', res) - self.assertEqual(res['vip'], return_value) - - def test_vip_list(self): - vip_id = _uuid() - return_value = [{'name': 'vip1', - 'admin_state_up': True, - 'tenant_id': _uuid(), - 'id': vip_id}] - - instance = self.plugin.return_value - instance.get_vips.return_value = return_value - - res = self.api.get(_get_path('lb/vips', fmt=self.fmt)) - - instance.get_vips.assert_called_with(mock.ANY, fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_vip_update(self): - vip_id = _uuid() - update_data = {'vip': {'admin_state_up': False}} - return_value = {'name': 'vip1', - 'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': vip_id} - - instance = self.plugin.return_value - instance.update_vip.return_value = return_value - - res = self.api.put(_get_path('lb/vips', id=vip_id, fmt=self.fmt), - self.serialize(update_data)) - - instance.update_vip.assert_called_with(mock.ANY, vip_id, - vip=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('vip', res) - self.assertEqual(res['vip'], return_value) - - def test_vip_get(self): - vip_id = _uuid() - return_value = {'name': 'vip1', - 'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': vip_id} - - instance = self.plugin.return_value - instance.get_vip.return_value = return_value - - res = self.api.get(_get_path('lb/vips', id=vip_id, fmt=self.fmt)) - - instance.get_vip.assert_called_with(mock.ANY, vip_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('vip', res) - self.assertEqual(res['vip'], return_value) - - def test_vip_delete(self): - self._test_entity_delete('vip') - - def test_pool_create(self): - pool_id = _uuid() - hm_id = _uuid() - data = {'pool': {'name': 'pool1', - 'description': 'descr_pool1', - 'subnet_id': _uuid(), - 'protocol': 'HTTP', - 'lb_method': 'ROUND_ROBIN', - 'health_monitors': [hm_id], - 'admin_state_up': True, - 'tenant_id': _uuid()}} - return_value = copy.copy(data['pool']) - return_value['provider'] = 'lbaas' - return_value.update({'status': "ACTIVE", 'id': pool_id}) - - instance = self.plugin.return_value - instance.create_pool.return_value = return_value - res = self.api.post(_get_path('lb/pools', fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - data['pool']['provider'] = attr.ATTR_NOT_SPECIFIED - instance.create_pool.assert_called_with(mock.ANY, - pool=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('pool', res) - self.assertEqual(res['pool'], return_value) - - def test_pool_list(self): - pool_id = _uuid() - return_value = [{'name': 'pool1', - 'admin_state_up': True, - 'tenant_id': _uuid(), - 'id': pool_id}] - - instance = self.plugin.return_value - instance.get_pools.return_value = return_value - - res = self.api.get(_get_path('lb/pools', fmt=self.fmt)) - - instance.get_pools.assert_called_with(mock.ANY, fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_pool_update(self): - pool_id = _uuid() - update_data = {'pool': {'admin_state_up': False}} - return_value = {'name': 'pool1', - 'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': pool_id} - - instance = self.plugin.return_value - instance.update_pool.return_value = return_value - - res = self.api.put(_get_path('lb/pools', id=pool_id, fmt=self.fmt), - self.serialize(update_data)) - - instance.update_pool.assert_called_with(mock.ANY, pool_id, - pool=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('pool', res) - self.assertEqual(res['pool'], return_value) - - def test_pool_get(self): - pool_id = _uuid() - return_value = {'name': 'pool1', - 'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': pool_id} - - instance = self.plugin.return_value - instance.get_pool.return_value = return_value - - res = self.api.get(_get_path('lb/pools', id=pool_id, fmt=self.fmt)) - - instance.get_pool.assert_called_with(mock.ANY, pool_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('pool', res) - self.assertEqual(res['pool'], return_value) - - def test_pool_delete(self): - self._test_entity_delete('pool') - - def test_pool_stats(self): - pool_id = _uuid() - - stats = {'stats': 'dummy'} - instance = self.plugin.return_value - instance.stats.return_value = stats - - path = _get_path('lb/pools', id=pool_id, - action="stats", fmt=self.fmt) - res = self.api.get(path) - - instance.stats.assert_called_with(mock.ANY, pool_id) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('stats', res) - self.assertEqual(res['stats'], stats['stats']) - - def test_member_create(self): - member_id = _uuid() - data = {'member': {'pool_id': _uuid(), - 'address': '127.0.0.1', - 'protocol_port': 80, - 'weight': 1, - 'admin_state_up': True, - 'tenant_id': _uuid()}} - return_value = copy.copy(data['member']) - return_value.update({'status': "ACTIVE", 'id': member_id}) - - instance = self.plugin.return_value - instance.create_member.return_value = return_value - res = self.api.post(_get_path('lb/members', fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_member.assert_called_with(mock.ANY, - member=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('member', res) - self.assertEqual(res['member'], return_value) - - def test_member_list(self): - member_id = _uuid() - return_value = [{'name': 'member1', - 'admin_state_up': True, - 'tenant_id': _uuid(), - 'id': member_id}] - - instance = self.plugin.return_value - instance.get_members.return_value = return_value - - res = self.api.get(_get_path('lb/members', fmt=self.fmt)) - - instance.get_members.assert_called_with(mock.ANY, fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_member_update(self): - member_id = _uuid() - update_data = {'member': {'admin_state_up': False}} - return_value = {'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': member_id} - - instance = self.plugin.return_value - instance.update_member.return_value = return_value - - res = self.api.put(_get_path('lb/members', id=member_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_member.assert_called_with(mock.ANY, member_id, - member=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('member', res) - self.assertEqual(res['member'], return_value) - - def test_member_get(self): - member_id = _uuid() - return_value = {'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': member_id} - - instance = self.plugin.return_value - instance.get_member.return_value = return_value - - res = self.api.get(_get_path('lb/members', id=member_id, - fmt=self.fmt)) - - instance.get_member.assert_called_with(mock.ANY, member_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('member', res) - self.assertEqual(res['member'], return_value) - - def test_member_delete(self): - self._test_entity_delete('member') - - def test_health_monitor_create(self): - health_monitor_id = _uuid() - data = {'health_monitor': {'type': 'HTTP', - 'delay': 2, - 'timeout': 1, - 'max_retries': 3, - 'http_method': 'GET', - 'url_path': '/path', - 'expected_codes': '200-300', - 'admin_state_up': True, - 'tenant_id': _uuid()}} - return_value = copy.copy(data['health_monitor']) - return_value.update({'status': "ACTIVE", 'id': health_monitor_id}) - - instance = self.plugin.return_value - instance.create_health_monitor.return_value = return_value - res = self.api.post(_get_path('lb/health_monitors', - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_health_monitor.assert_called_with(mock.ANY, - health_monitor=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('health_monitor', res) - self.assertEqual(res['health_monitor'], return_value) - - def test_health_monitor_create_with_timeout_negative(self): - data = {'health_monitor': {'type': 'HTTP', - 'delay': 2, - 'timeout': -1, - 'max_retries': 3, - 'http_method': 'GET', - 'url_path': '/path', - 'expected_codes': '200-300', - 'admin_state_up': True, - 'tenant_id': _uuid()}} - res = self.api.post(_get_path('lb/health_monitors', - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt, - expect_errors=True) - self.assertEqual(400, res.status_int) - - def test_health_monitor_list(self): - health_monitor_id = _uuid() - return_value = [{'type': 'HTTP', - 'admin_state_up': True, - 'tenant_id': _uuid(), - 'id': health_monitor_id}] - - instance = self.plugin.return_value - instance.get_health_monitors.return_value = return_value - - res = self.api.get(_get_path('lb/health_monitors', fmt=self.fmt)) - - instance.get_health_monitors.assert_called_with( - mock.ANY, fields=mock.ANY, filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_health_monitor_update(self): - health_monitor_id = _uuid() - update_data = {'health_monitor': {'admin_state_up': False}} - return_value = {'type': 'HTTP', - 'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': health_monitor_id} - - instance = self.plugin.return_value - instance.update_health_monitor.return_value = return_value - - res = self.api.put(_get_path('lb/health_monitors', - id=health_monitor_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_health_monitor.assert_called_with( - mock.ANY, health_monitor_id, health_monitor=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('health_monitor', res) - self.assertEqual(res['health_monitor'], return_value) - - def test_health_monitor_get(self): - health_monitor_id = _uuid() - return_value = {'type': 'HTTP', - 'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': health_monitor_id} - - instance = self.plugin.return_value - instance.get_health_monitor.return_value = return_value - - res = self.api.get(_get_path('lb/health_monitors', - id=health_monitor_id, - fmt=self.fmt)) - - instance.get_health_monitor.assert_called_with( - mock.ANY, health_monitor_id, fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('health_monitor', res) - self.assertEqual(res['health_monitor'], return_value) - - def test_health_monitor_delete(self): - self._test_entity_delete('health_monitor') - - def test_create_pool_health_monitor(self): - health_monitor_id = _uuid() - data = {'health_monitor': {'id': health_monitor_id, - 'tenant_id': _uuid()}} - - return_value = copy.copy(data['health_monitor']) - instance = self.plugin.return_value - instance.create_pool_health_monitor.return_value = return_value - res = self.api.post('/lb/pools/id1/health_monitors', - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_pool_health_monitor.assert_called_with( - mock.ANY, pool_id='id1', health_monitor=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('health_monitor', res) - self.assertEqual(res['health_monitor'], return_value) - - def test_delete_pool_health_monitor(self): - health_monitor_id = _uuid() - - res = self.api.delete('/lb/pools/id1/health_monitors/%s' % - health_monitor_id) - - instance = self.plugin.return_value - instance.delete_pool_health_monitor.assert_called_with( - mock.ANY, health_monitor_id, pool_id='id1') - self.assertEqual(res.status_int, exc.HTTPNoContent.code) - - -class LoadBalancerExtensionTestCaseXML(LoadBalancerExtensionTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/services/loadbalancer/test_loadbalancer_quota_ext.py b/neutron/tests/unit/services/loadbalancer/test_loadbalancer_quota_ext.py deleted file mode 100644 index fb5ebba54..000000000 --- a/neutron/tests/unit/services/loadbalancer/test_loadbalancer_quota_ext.py +++ /dev/null @@ -1,168 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2014 OpenStack Foundation. -# All Rights Reserved. -# -# 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. - -from oslo.config import cfg - -from neutron import context -from neutron import quota -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_quota_ext - -_get_path = test_api_v2._get_path - - -class LBaaSQuotaExtensionTestCase( - test_quota_ext.QuotaExtensionTestCase): - - def setUp(self): - super(LBaaSQuotaExtensionTestCase, self).setUp() - cfg.CONF.set_override( - 'quota_items', - ['vip', 'pool', 'member', 'health_monitor', 'extra1'], - group='QUOTAS') - quota.register_resources_from_config() - - -class LBaaSQuotaExtensionDbTestCase(LBaaSQuotaExtensionTestCase): - fmt = 'json' - - def setUp(self): - cfg.CONF.set_override( - 'quota_driver', - 'neutron.db.quota_db.DbQuotaDriver', - group='QUOTAS') - super(LBaaSQuotaExtensionDbTestCase, self).setUp() - - def test_quotas_loaded_right(self): - res = self.api.get(_get_path('quotas', fmt=self.fmt)) - quota = self.deserialize(res) - self.assertEqual([], quota['quotas']) - self.assertEqual(200, res.status_int) - - def test_quotas_default_values(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - quota = self.deserialize(res) - self.assertEqual(10, quota['quota']['vip']) - self.assertEqual(10, quota['quota']['pool']) - self.assertEqual(-1, quota['quota']['member']) - self.assertEqual(-1, quota['quota']['health_monitor']) - self.assertEqual(-1, quota['quota']['extra1']) - - def test_show_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', - is_admin=True)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - self.assertEqual(200, res.status_int) - quota = self.deserialize(res) - self.assertEqual(10, quota['quota']['vip']) - self.assertEqual(10, quota['quota']['pool']) - self.assertEqual(-1, quota['quota']['member']) - self.assertEqual(-1, quota['quota']['health_monitor']) - - def test_show_quotas_with_owner_tenant(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - self.assertEqual(200, res.status_int) - quota = self.deserialize(res) - self.assertEqual(10, quota['quota']['vip']) - self.assertEqual(10, quota['quota']['pool']) - self.assertEqual(-1, quota['quota']['member']) - self.assertEqual(-1, quota['quota']['health_monitor']) - - def test_update_quotas_to_unlimited(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - quotas = {'quota': {'pool': -1}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env, - expect_errors=False) - self.assertEqual(200, res.status_int) - - def test_update_quotas_exceeding_current_limit(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - quotas = {'quota': {'pool': 120}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env, - expect_errors=False) - self.assertEqual(200, res.status_int) - - def test_update_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', - is_admin=True)} - quotas = {'quota': {'pool': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env) - self.assertEqual(200, res.status_int) - env2 = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env2) - quota = self.deserialize(res) - self.assertEqual(10, quota['quota']['vip']) - self.assertEqual(100, quota['quota']['pool']) - self.assertEqual(-1, quota['quota']['member']) - self.assertEqual(-1, quota['quota']['health_monitor']) - - -class LBaaSQuotaExtensionDbTestCaseXML(LBaaSQuotaExtensionDbTestCase): - fmt = 'xml' - - -class LBaaSQuotaExtensionCfgTestCase( - LBaaSQuotaExtensionTestCase): - - def setUp(self): - cfg.CONF.set_override( - 'quota_driver', - 'neutron.quota.ConfDriver', - group='QUOTAS') - super(LBaaSQuotaExtensionCfgTestCase, self).setUp() - - def test_quotas_default_values(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - quota = self.deserialize(res) - self.assertEqual(10, quota['quota']['vip']) - self.assertEqual(10, quota['quota']['pool']) - self.assertEqual(-1, quota['quota']['member']) - self.assertEqual(-1, quota['quota']['health_monitor']) - self.assertEqual(-1, quota['quota']['extra1']) - - def test_update_quotas_forbidden(self): - tenant_id = 'tenant_id1' - quotas = {'quota': {'pool': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), - expect_errors=True) - self.assertEqual(403, res.status_int) - - -class LBaaSQuotaExtensionCfgTestCaseXML(LBaaSQuotaExtensionCfgTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/services/metering/__init__.py b/neutron/tests/unit/services/metering/__init__.py deleted file mode 100644 index 82a447213..000000000 --- a/neutron/tests/unit/services/metering/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2013 eNovance SAS -# -# Author: Sylvain Afchain -# -# 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. diff --git a/neutron/tests/unit/services/metering/drivers/__init__.py b/neutron/tests/unit/services/metering/drivers/__init__.py deleted file mode 100644 index 82a447213..000000000 --- a/neutron/tests/unit/services/metering/drivers/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2013 eNovance SAS -# -# Author: Sylvain Afchain -# -# 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. diff --git a/neutron/tests/unit/services/metering/drivers/test_iptables_driver.py b/neutron/tests/unit/services/metering/drivers/test_iptables_driver.py deleted file mode 100644 index ad056f401..000000000 --- a/neutron/tests/unit/services/metering/drivers/test_iptables_driver.py +++ /dev/null @@ -1,408 +0,0 @@ -# Copyright (C) 2013 eNovance SAS -# -# Author: Sylvain Afchain -# -# 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 copy - -import mock -from oslo.config import cfg - -from neutron.services.metering.drivers.iptables import iptables_driver -from neutron.tests import base -from neutron.tests.unit import test_api_v2 - -_uuid = test_api_v2._uuid - - -class IptablesDriverTestCase(base.BaseTestCase): - def setUp(self): - super(IptablesDriverTestCase, self).setUp() - self.utils_exec_p = mock.patch( - 'neutron.agent.linux.utils.execute') - self.utils_exec = self.utils_exec_p.start() - self.iptables_cls_p = mock.patch( - 'neutron.agent.linux.iptables_manager.IptablesManager') - self.iptables_cls = self.iptables_cls_p.start() - self.iptables_inst = mock.Mock() - self.v4filter_inst = mock.Mock() - self.v6filter_inst = mock.Mock() - self.v4filter_inst.chains = [] - self.v6filter_inst.chains = [] - self.iptables_inst.ipv4 = {'filter': self.v4filter_inst} - self.iptables_inst.ipv6 = {'filter': self.v6filter_inst} - self.iptables_cls.return_value = self.iptables_inst - cfg.CONF.set_override('interface_driver', - 'neutron.agent.linux.interface.NullDriver') - cfg.CONF.set_override('root_helper', - 'fake_sudo', - 'AGENT') - self.metering = iptables_driver.IptablesMeteringDriver('metering', - cfg.CONF) - - def test_root_helper(self): - routers = [{'_metering_labels': [ - {'id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': []}], - 'admin_state_up': True, - 'gw_port_id': '7d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '473ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router1', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}] - self.metering.add_metering_label(None, routers) - - self.iptables_cls.assert_called_with(root_helper='fake_sudo', - namespace=mock.ANY, - binary_name=mock.ANY) - - def test_add_metering_label(self): - routers = [{'_metering_labels': [ - {'id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': []}], - 'admin_state_up': True, - 'gw_port_id': '7d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '473ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router1', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}] - - self.metering.add_metering_label(None, routers) - calls = [mock.call.add_chain('neutron-meter-l-c5df2fe5-c60', - wrap=False), - mock.call.add_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-FORWARD', '-j ' - 'neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-l-c5df2fe5-c60', - '', - wrap=False)] - - self.v4filter_inst.assert_has_calls(calls) - - def test_add_metering_label_with_rules(self): - routers = [{'_metering_labels': [ - {'id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': [{ - 'direction': 'ingress', - 'excluded': False, - 'id': '7f1a261f-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '10.0.0.0/24'}]}], - 'admin_state_up': True, - 'gw_port_id': '6d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '473ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router1', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}, - {'_metering_labels': [ - {'id': 'eeef45da-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': [{ - 'direction': 'ingress', - 'excluded': True, - 'id': 'fa2441e8-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'eeef45da-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '20.0.0.0/24'}]}], - 'admin_state_up': True, - 'gw_port_id': '7d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '373ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router2', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}] - - self.metering.add_metering_label(None, routers) - calls = [mock.call.add_chain('neutron-meter-l-c5df2fe5-c60', - wrap=False), - mock.call.add_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-FORWARD', '-j ' - 'neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-l-c5df2fe5-c60', - '', - wrap=False), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-i qg-6d411f48-ec -d 10.0.0.0/24' - ' -j neutron-meter-l-c5df2fe5-c60', - wrap=False, top=False), - mock.call.add_chain('neutron-meter-l-eeef45da-c60', - wrap=False), - mock.call.add_chain('neutron-meter-r-eeef45da-c60', - wrap=False), - mock.call.add_rule('neutron-meter-FORWARD', '-j ' - 'neutron-meter-r-eeef45da-c60', - wrap=False), - mock.call.add_rule('neutron-meter-l-eeef45da-c60', - '', - wrap=False), - mock.call.add_rule('neutron-meter-r-eeef45da-c60', - '-i qg-7d411f48-ec -d 20.0.0.0/24' - ' -j RETURN', - wrap=False, top=True)] - - self.v4filter_inst.assert_has_calls(calls) - - def test_update_metering_label_rules(self): - routers = [{'_metering_labels': [ - {'id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': [{ - 'direction': 'ingress', - 'excluded': False, - 'id': '7f1a261f-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '10.0.0.0/24'}]}], - 'admin_state_up': True, - 'gw_port_id': '6d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '473ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router1', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}] - - self.metering.add_metering_label(None, routers) - - updates = copy.deepcopy(routers) - updates[0]['_metering_labels'][0]['rules'] = [{ - 'direction': 'egress', - 'excluded': True, - 'id': '7f1a261f-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '10.0.0.0/24'}, - {'direction': 'ingress', - 'excluded': False, - 'id': '6f1a261f-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '20.0.0.0/24'}] - - self.metering.update_metering_label_rules(None, updates) - - calls = [mock.call.add_chain('neutron-meter-l-c5df2fe5-c60', - wrap=False), - mock.call.add_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-FORWARD', '-j ' - 'neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-l-c5df2fe5-c60', - '', - wrap=False), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-i qg-6d411f48-ec -d 10.0.0.0/24' - ' -j neutron-meter-l-c5df2fe5-c60', - wrap=False, top=False), - mock.call.empty_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-o qg-6d411f48-ec -d 10.0.0.0/24' - ' -j RETURN', - wrap=False, top=True), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-i qg-6d411f48-ec -d 20.0.0.0/24 -j ' - 'neutron-meter-l-c5df2fe5-c60', - wrap=False, top=False)] - - self.v4filter_inst.assert_has_calls(calls) - - def test_remove_metering_label_rule(self): - routers = [{'_metering_labels': [ - {'id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': [{ - 'direction': 'ingress', - 'excluded': False, - 'id': '7f1a261f-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '10.0.0.0/24'}, - {'direction': 'ingress', - 'excluded': False, - 'id': 'aaaa261f-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '20.0.0.0/24'}] - }], - 'admin_state_up': True, - 'gw_port_id': '7d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '473ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router1', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}] - - self.metering.add_metering_label(None, routers) - - routers = [{'_metering_labels': [ - {'id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': [{ - 'direction': 'ingress', - 'excluded': False, - 'id': '7f1a261f-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '10.0.0.0/24'}] - }], - 'admin_state_up': True, - 'gw_port_id': '7d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '473ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router1', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}] - - self.metering.update_metering_label_rules(None, routers) - calls = [mock.call.add_chain('neutron-meter-l-c5df2fe5-c60', - wrap=False), - mock.call.add_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-FORWARD', '-j ' - 'neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-l-c5df2fe5-c60', - '', - wrap=False), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-i qg-7d411f48-ec -d 10.0.0.0/24' - ' -j neutron-meter-l-c5df2fe5-c60', - wrap=False, top=False), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-i qg-7d411f48-ec -d 20.0.0.0/24' - ' -j neutron-meter-l-c5df2fe5-c60', - wrap=False, top=False), - mock.call.empty_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-i qg-7d411f48-ec -d 10.0.0.0/24' - ' -j neutron-meter-l-c5df2fe5-c60', - wrap=False, top=False)] - - self.v4filter_inst.assert_has_calls(calls) - - def test_remove_metering_label(self): - routers = [{'_metering_labels': [ - {'id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': [{ - 'direction': 'ingress', - 'excluded': False, - 'id': '7f1a261f-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '10.0.0.0/24'}] - }], - 'admin_state_up': True, - 'gw_port_id': '7d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '473ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router1', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}] - - self.metering.add_metering_label(None, routers) - self.metering.remove_metering_label(None, routers) - calls = [mock.call.add_chain('neutron-meter-l-c5df2fe5-c60', - wrap=False), - mock.call.add_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-FORWARD', '-j ' - 'neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-l-c5df2fe5-c60', - '', - wrap=False), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-i qg-7d411f48-ec -d 10.0.0.0/24' - ' -j neutron-meter-l-c5df2fe5-c60', - wrap=False, top=False), - mock.call.remove_chain('neutron-meter-l-c5df2fe5-c60', - wrap=False), - mock.call.remove_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False)] - - self.v4filter_inst.assert_has_calls(calls) - - def test_update_routers(self): - routers = [{'_metering_labels': [ - {'id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': [{ - 'direction': 'ingress', - 'excluded': False, - 'id': '7f1a261f-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'c5df2fe5-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '10.0.0.0/24'}]}], - 'admin_state_up': True, - 'gw_port_id': '6d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '473ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router1', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}, - {'_metering_labels': [ - {'id': 'eeef45da-c600-4a2a-b2f4-c0fb6df73c83', - 'rules': [{ - 'direction': 'ingress', - 'excluded': True, - 'id': 'fa2441e8-2489-4ed1-870c-a62754501379', - 'metering_label_id': 'eeef45da-c600-4a2a-b2f4-c0fb6df73c83', - 'remote_ip_prefix': '20.0.0.0/24'}]}], - 'admin_state_up': True, - 'gw_port_id': '7d411f48-ecc7-45e0-9ece-3b5bdb54fcee', - 'id': '373ec392-1711-44e3-b008-3251ccfc5099', - 'name': 'router2', - 'status': 'ACTIVE', - 'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}] - - self.metering.add_metering_label(None, routers) - - updates = copy.deepcopy(routers) - updates[0]['gw_port_id'] = '587b63c1-22a3-40b3-9834-486d1fb215a5' - - self.metering.update_routers(None, updates) - calls = [mock.call.add_chain('neutron-meter-l-c5df2fe5-c60', - wrap=False), - mock.call.add_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-FORWARD', '-j ' - 'neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-l-c5df2fe5-c60', - '', - wrap=False), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-i qg-6d411f48-ec -d 10.0.0.0/24' - ' -j neutron-meter-l-c5df2fe5-c60', - wrap=False, top=False), - mock.call.add_chain('neutron-meter-l-eeef45da-c60', - wrap=False), - mock.call.add_chain('neutron-meter-r-eeef45da-c60', - wrap=False), - mock.call.add_rule('neutron-meter-FORWARD', '-j ' - 'neutron-meter-r-eeef45da-c60', - wrap=False), - mock.call.add_rule('neutron-meter-l-eeef45da-c60', - '', - wrap=False), - mock.call.add_rule('neutron-meter-r-eeef45da-c60', - '-i qg-7d411f48-ec -d 20.0.0.0/24' - ' -j RETURN', - wrap=False, top=True), - mock.call.remove_chain('neutron-meter-l-c5df2fe5-c60', - wrap=False), - mock.call.remove_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_chain('neutron-meter-l-c5df2fe5-c60', - wrap=False), - mock.call.add_chain('neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-FORWARD', '-j ' - 'neutron-meter-r-c5df2fe5-c60', - wrap=False), - mock.call.add_rule('neutron-meter-l-c5df2fe5-c60', - '', - wrap=False), - mock.call.add_rule('neutron-meter-r-c5df2fe5-c60', - '-i qg-587b63c1-22 -d 10.0.0.0/24' - ' -j neutron-meter-l-c5df2fe5-c60', - wrap=False, top=False)] - - self.v4filter_inst.assert_has_calls(calls) diff --git a/neutron/tests/unit/services/metering/test_metering_agent.py b/neutron/tests/unit/services/metering/test_metering_agent.py deleted file mode 100644 index b3e3511fe..000000000 --- a/neutron/tests/unit/services/metering/test_metering_agent.py +++ /dev/null @@ -1,160 +0,0 @@ -# Copyright (C) 2013 eNovance SAS -# -# Author: Sylvain Afchain -# -# 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 oslo.config import cfg - -from neutron.agent.common import config -from neutron.openstack.common import uuidutils -from neutron.services.metering.agents import metering_agent -from neutron.tests import base -from neutron.tests import fake_notifier - - -_uuid = uuidutils.generate_uuid - -TENANT_ID = _uuid() -LABEL_ID = _uuid() -ROUTERS = [{'status': 'ACTIVE', - 'name': 'router1', - 'gw_port_id': None, - 'admin_state_up': True, - 'tenant_id': TENANT_ID, - '_metering_labels': [{'rules': [], - 'id': LABEL_ID}], - 'id': _uuid()}] - - -class TestMeteringOperations(base.BaseTestCase): - - def setUp(self): - super(TestMeteringOperations, self).setUp() - cfg.CONF.register_opts(metering_agent.MeteringAgent.Opts) - config.register_root_helper(cfg.CONF) - - self.noop_driver = ('neutron.services.metering.drivers.noop.' - 'noop_driver.NoopMeteringDriver') - cfg.CONF.set_override('driver', self.noop_driver) - cfg.CONF.set_override('measure_interval', 0) - cfg.CONF.set_override('report_interval', 0) - - self.setup_notification_driver() - - metering_rpc = ('neutron.services.metering.agents.metering_agent.' - 'MeteringPluginRpc._get_sync_data_metering') - self.metering_rpc_patch = mock.patch(metering_rpc, return_value=[]) - self.metering_rpc_patch.start() - - self.driver_patch = mock.patch(self.noop_driver, autospec=True) - self.driver_patch.start() - - loopingcall_patch = mock.patch( - 'neutron.openstack.common.loopingcall.FixedIntervalLoopingCall') - loopingcall_patch.start() - - self.agent = metering_agent.MeteringAgent('my agent', cfg.CONF) - self.driver = self.agent.metering_driver - - def test_add_metering_label(self): - self.agent.add_metering_label(None, ROUTERS) - self.assertEqual(self.driver.add_metering_label.call_count, 1) - - def test_remove_metering_label(self): - self.agent.remove_metering_label(None, ROUTERS) - self.assertEqual(self.driver.remove_metering_label.call_count, 1) - - def test_update_metering_label_rule(self): - self.agent.update_metering_label_rules(None, ROUTERS) - self.assertEqual(self.driver.update_metering_label_rules.call_count, 1) - - def test_routers_updated(self): - self.agent.routers_updated(None, ROUTERS) - self.assertEqual(self.driver.update_routers.call_count, 1) - - def test_get_traffic_counters(self): - self.agent._get_traffic_counters(None, ROUTERS) - self.assertEqual(self.driver.get_traffic_counters.call_count, 1) - - def test_notification_report(self): - self.agent.routers_updated(None, ROUTERS) - - self.driver.get_traffic_counters.return_value = {LABEL_ID: - {'pkts': 88, - 'bytes': 444}} - self.agent._metering_loop() - - self.assertNotEqual(len(fake_notifier.NOTIFICATIONS), 0) - for n in fake_notifier.NOTIFICATIONS: - if n['event_type'] == 'l3.meter': - break - - self.assertEqual(n['event_type'], 'l3.meter') - - payload = n['payload'] - self.assertEqual(payload['tenant_id'], TENANT_ID) - self.assertEqual(payload['label_id'], LABEL_ID) - self.assertEqual(payload['pkts'], 88) - self.assertEqual(payload['bytes'], 444) - - def test_router_deleted(self): - label_id = _uuid() - self.driver.get_traffic_counters = mock.MagicMock() - self.driver.get_traffic_counters.return_value = {label_id: - {'pkts': 44, - 'bytes': 222}} - self.agent._add_metering_info = mock.MagicMock() - - self.agent.routers_updated(None, ROUTERS) - self.agent.router_deleted(None, ROUTERS[0]['id']) - - self.assertEqual(self.agent._add_metering_info.call_count, 1) - self.assertEqual(self.driver.remove_router.call_count, 1) - - self.agent._add_metering_info.assert_called_with(label_id, 44, 222) - - -class TestMeteringDriver(base.BaseTestCase): - def setUp(self): - super(TestMeteringDriver, self).setUp() - cfg.CONF.register_opts(metering_agent.MeteringAgent.Opts) - config.register_root_helper(cfg.CONF) - - self.noop_driver = ('neutron.services.metering.drivers.noop.' - 'noop_driver.NoopMeteringDriver') - cfg.CONF.set_override('driver', self.noop_driver) - - self.agent = metering_agent.MeteringAgent('my agent', cfg.CONF) - self.driver = mock.Mock() - self.agent.metering_driver = self.driver - - def test_add_metering_label_with_bad_driver_impl(self): - del self.driver.add_metering_label - - with mock.patch.object(metering_agent, 'LOG') as log: - self.agent.add_metering_label(None, ROUTERS) - log.exception.assert_called_with(mock.ANY, - {'driver': self.noop_driver, - 'func': 'add_metering_label'}) - - def test_add_metering_label_runtime_error(self): - self.driver.add_metering_label.side_effect = RuntimeError - - with mock.patch.object(metering_agent, 'LOG') as log: - self.agent.add_metering_label(None, ROUTERS) - log.exception.assert_called_with(mock.ANY, - {'driver': self.noop_driver, - 'func': - 'add_metering_label'}) diff --git a/neutron/tests/unit/services/metering/test_metering_plugin.py b/neutron/tests/unit/services/metering/test_metering_plugin.py deleted file mode 100644 index 7d7c4c025..000000000 --- a/neutron/tests/unit/services/metering/test_metering_plugin.py +++ /dev/null @@ -1,448 +0,0 @@ -# Copyright (C) 2013 eNovance SAS -# -# Author: Sylvain Afchain -# -# 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 neutron.api.v2 import attributes as attr -from neutron.common import constants as n_constants -from neutron.common import topics -from neutron import context -from neutron.db import agents_db -from neutron.db import l3_agentschedulers_db -from neutron.db.metering import metering_rpc -from neutron.extensions import l3 as ext_l3 -from neutron.extensions import metering as ext_metering -from neutron import manager -from neutron.openstack.common import timeutils -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.tests.unit.db.metering import test_db_metering -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import test_l3_plugin - - -_uuid = uuidutils.generate_uuid - -METERING_SERVICE_PLUGIN_KLASS = ( - "neutron.services.metering." - "metering_plugin.MeteringPlugin" -) - - -class MeteringTestExtensionManager(object): - - def get_resources(self): - attr.RESOURCE_ATTRIBUTE_MAP.update(ext_metering.RESOURCE_ATTRIBUTE_MAP) - attr.RESOURCE_ATTRIBUTE_MAP.update(ext_l3.RESOURCE_ATTRIBUTE_MAP) - - l3_res = ext_l3.L3.get_resources() - metering_res = ext_metering.Metering.get_resources() - - return l3_res + metering_res - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class TestMeteringPlugin(test_db_plugin.NeutronDbPluginV2TestCase, - test_l3_plugin.L3NatTestCaseMixin, - test_db_metering.MeteringPluginDbTestCaseMixin): - - resource_prefix_map = dict( - (k.replace('_', '-'), constants.COMMON_PREFIXES[constants.METERING]) - for k in ext_metering.RESOURCE_ATTRIBUTE_MAP.keys() - ) - - def setUp(self): - plugin = 'neutron.tests.unit.test_l3_plugin.TestL3NatIntPlugin' - service_plugins = {'metering_plugin_name': - METERING_SERVICE_PLUGIN_KLASS} - ext_mgr = MeteringTestExtensionManager() - super(TestMeteringPlugin, self).setUp(plugin=plugin, ext_mgr=ext_mgr, - service_plugins=service_plugins) - - self.uuid = '654f6b9d-0f36-4ae5-bd1b-01616794ca60' - - uuid = 'neutron.openstack.common.uuidutils.generate_uuid' - self.uuid_patch = mock.patch(uuid, return_value=self.uuid) - self.mock_uuid = self.uuid_patch.start() - - fanout = ('neutron.common.rpc_compat.RpcProxy.fanout_cast') - self.fanout_patch = mock.patch(fanout) - self.mock_fanout = self.fanout_patch.start() - - self.tenant_id = 'a7e61382-47b8-4d40-bae3-f95981b5637b' - self.ctx = context.Context('', self.tenant_id, is_admin=True) - self.context_patch = mock.patch('neutron.context.Context', - return_value=self.ctx) - self.mock_context = self.context_patch.start() - - self.topic = 'metering_agent' - - def test_add_metering_label_rpc_call(self): - second_uuid = 'e27fe2df-376e-4ac7-ae13-92f050a21f84' - expected = {'args': {'routers': [{'status': 'ACTIVE', - 'name': 'router1', - 'gw_port_id': None, - 'admin_state_up': True, - 'tenant_id': self.tenant_id, - '_metering_labels': [ - {'rules': [], - 'id': self.uuid}], - 'id': self.uuid}]}, - 'namespace': None, - 'method': 'add_metering_label'} - - tenant_id_2 = '8a268a58-1610-4890-87e0-07abb8231206' - self.mock_uuid.return_value = second_uuid - with self.router(name='router2', tenant_id=tenant_id_2, - set_context=True): - self.mock_uuid.return_value = self.uuid - with self.router(name='router1', tenant_id=self.tenant_id, - set_context=True): - with self.metering_label(tenant_id=self.tenant_id, - set_context=True): - self.mock_fanout.assert_called_with(self.ctx, expected, - topic=self.topic) - - def test_remove_metering_label_rpc_call(self): - expected = {'args': - {'routers': [{'status': 'ACTIVE', - 'name': 'router1', - 'gw_port_id': None, - 'admin_state_up': True, - 'tenant_id': self.tenant_id, - '_metering_labels': [ - {'rules': [], - 'id': self.uuid}], - 'id': self.uuid}]}, - 'namespace': None, - 'method': 'add_metering_label'} - - with self.router(tenant_id=self.tenant_id, set_context=True): - with self.metering_label(tenant_id=self.tenant_id, - set_context=True): - self.mock_fanout.assert_called_with(self.ctx, expected, - topic=self.topic) - expected['method'] = 'remove_metering_label' - self.mock_fanout.assert_called_with(self.ctx, expected, - topic=self.topic) - - def test_remove_one_metering_label_rpc_call(self): - second_uuid = 'e27fe2df-376e-4ac7-ae13-92f050a21f84' - expected_add = {'args': - {'routers': [{'status': 'ACTIVE', - 'name': 'router1', - 'gw_port_id': None, - 'admin_state_up': True, - 'tenant_id': self.tenant_id, - '_metering_labels': [ - {'rules': [], - 'id': self.uuid}, - {'rules': [], - 'id': second_uuid}], - 'id': self.uuid}]}, - 'namespace': None, - 'method': 'add_metering_label'} - expected_remove = {'args': - {'routers': [{'status': 'ACTIVE', - 'name': 'router1', - 'gw_port_id': None, - 'admin_state_up': True, - 'tenant_id': self.tenant_id, - '_metering_labels': [ - {'rules': [], - 'id': second_uuid}], - 'id': self.uuid}]}, - 'namespace': None, - 'method': 'remove_metering_label'} - - with self.router(tenant_id=self.tenant_id, set_context=True): - with self.metering_label(tenant_id=self.tenant_id, - set_context=True): - self.mock_uuid.return_value = second_uuid - with self.metering_label(tenant_id=self.tenant_id, - set_context=True): - self.mock_fanout.assert_called_with(self.ctx, expected_add, - topic=self.topic) - self.mock_fanout.assert_called_with(self.ctx, expected_remove, - topic=self.topic) - - def test_update_metering_label_rules_rpc_call(self): - second_uuid = 'e27fe2df-376e-4ac7-ae13-92f050a21f84' - expected_add = {'args': - {'routers': [ - {'status': 'ACTIVE', - 'name': 'router1', - 'gw_port_id': None, - 'admin_state_up': True, - 'tenant_id': self.tenant_id, - '_metering_labels': [ - {'rules': [ - {'remote_ip_prefix': '10.0.0.0/24', - 'direction': 'ingress', - 'metering_label_id': self.uuid, - 'excluded': False, - 'id': self.uuid}, - {'remote_ip_prefix': '10.0.0.0/24', - 'direction': 'egress', - 'metering_label_id': self.uuid, - 'excluded': False, - 'id': second_uuid}], - 'id': self.uuid}], - 'id': self.uuid}]}, - 'namespace': None, - 'method': 'update_metering_label_rules'} - - expected_del = {'args': - {'routers': [ - {'status': 'ACTIVE', - 'name': 'router1', - 'gw_port_id': None, - 'admin_state_up': True, - 'tenant_id': self.tenant_id, - '_metering_labels': [ - {'rules': [ - {'remote_ip_prefix': '10.0.0.0/24', - 'direction': 'ingress', - 'metering_label_id': self.uuid, - 'excluded': False, - 'id': self.uuid}], - 'id': self.uuid}], - 'id': self.uuid}]}, - 'namespace': None, - 'method': 'update_metering_label_rules'} - - with self.router(tenant_id=self.tenant_id, set_context=True): - with self.metering_label(tenant_id=self.tenant_id, - set_context=True) as label: - l = label['metering_label'] - with self.metering_label_rule(l['id']): - self.mock_uuid.return_value = second_uuid - with self.metering_label_rule(l['id'], direction='egress'): - self.mock_fanout.assert_called_with(self.ctx, - expected_add, - topic=self.topic) - self.mock_fanout.assert_called_with(self.ctx, - expected_del, - topic=self.topic) - - def test_delete_metering_label_does_not_clear_router_tenant_id(self): - tenant_id = '654f6b9d-0f36-4ae5-bd1b-01616794ca60' - with self.metering_label(tenant_id=tenant_id, - no_delete=True) as metering_label: - with self.router(tenant_id=tenant_id, set_context=True) as r: - router = self._show('routers', r['router']['id']) - self.assertEqual(tenant_id, router['router']['tenant_id']) - metering_label_id = metering_label['metering_label']['id'] - self._delete('metering-labels', metering_label_id, 204) - router = self._show('routers', r['router']['id']) - self.assertEqual(tenant_id, router['router']['tenant_id']) - - -class TestMeteringPluginL3AgentScheduler( - l3_agentschedulers_db.L3AgentSchedulerDbMixin, - test_db_plugin.NeutronDbPluginV2TestCase, - test_l3_plugin.L3NatTestCaseMixin, - test_db_metering.MeteringPluginDbTestCaseMixin): - - resource_prefix_map = dict( - (k.replace('_', '-'), constants.COMMON_PREFIXES[constants.METERING]) - for k in ext_metering.RESOURCE_ATTRIBUTE_MAP.keys() - ) - - def setUp(self, plugin_str=None, service_plugins=None, scheduler=None): - if not plugin_str: - plugin_str = ('neutron.tests.unit.test_l3_plugin.' - 'TestL3NatIntAgentSchedulingPlugin') - - if not service_plugins: - service_plugins = {'metering_plugin_name': - METERING_SERVICE_PLUGIN_KLASS} - - if not scheduler: - scheduler = plugin_str - - ext_mgr = MeteringTestExtensionManager() - super(TestMeteringPluginL3AgentScheduler, - self).setUp(plugin=plugin_str, ext_mgr=ext_mgr, - service_plugins=service_plugins) - - self.uuid = '654f6b9d-0f36-4ae5-bd1b-01616794ca60' - - uuid = 'neutron.openstack.common.uuidutils.generate_uuid' - self.uuid_patch = mock.patch(uuid, return_value=self.uuid) - self.mock_uuid = self.uuid_patch.start() - - cast = 'neutron.common.rpc_compat.RpcProxy.cast' - self.cast_patch = mock.patch(cast) - self.mock_cast = self.cast_patch.start() - - self.tenant_id = 'a7e61382-47b8-4d40-bae3-f95981b5637b' - self.ctx = context.Context('', self.tenant_id, is_admin=True) - self.context_patch = mock.patch('neutron.context.Context', - return_value=self.ctx) - self.mock_context = self.context_patch.start() - - self.l3routers_patch = mock.patch(scheduler + - '.get_l3_agents_hosting_routers') - self.l3routers_mock = self.l3routers_patch.start() - - self.topic = 'metering_agent' - - def test_add_metering_label_rpc_call(self): - second_uuid = 'e27fe2df-376e-4ac7-ae13-92f050a21f84' - expected1 = {'args': {'routers': [{'status': 'ACTIVE', - 'name': 'router1', - 'gw_port_id': None, - 'admin_state_up': True, - 'tenant_id': self.tenant_id, - '_metering_labels': [ - {'rules': [], - 'id': second_uuid}], - 'id': self.uuid}]}, - 'namespace': None, - 'method': 'add_metering_label'} - expected2 = {'args': {'routers': [{'status': 'ACTIVE', - 'name': 'router2', - 'gw_port_id': None, - 'admin_state_up': True, - 'tenant_id': self.tenant_id, - '_metering_labels': [ - {'rules': [], - 'id': second_uuid}], - 'id': second_uuid}]}, - 'namespace': None, - 'method': 'add_metering_label'} - - # bind each router to a specific agent - agent1 = agents_db.Agent(host='agent1') - agent2 = agents_db.Agent(host='agent2') - - agents = {self.uuid: agent1, - second_uuid: agent2} - - def side_effect(context, routers, admin_state_up, active): - return [agents[routers[0]]] - - self.l3routers_mock.side_effect = side_effect - - with self.router(name='router1', tenant_id=self.tenant_id, - set_context=True): - self.mock_uuid.return_value = second_uuid - with self.router(name='router2', tenant_id=self.tenant_id, - set_context=True): - with self.metering_label(tenant_id=self.tenant_id, - set_context=True): - - topic1 = "%s.%s" % (self.topic, 'agent1') - topic2 = "%s.%s" % (self.topic, 'agent2') - - # check if there is a call per agent - expected = [mock.call(self.ctx, expected1, topic=topic1), - mock.call(self.ctx, expected2, topic=topic2)] - - self.mock_cast.assert_has_calls(expected, any_order=True) - - -class TestMeteringPluginL3AgentSchedulerServicePlugin( - TestMeteringPluginL3AgentScheduler): - - """Unit tests for the case where separate service plugin - implements L3 routing. - """ - - def setUp(self): - l3_plugin = ('neutron.tests.unit.test_l3_plugin.' - 'TestL3NatAgentSchedulingServicePlugin') - service_plugins = {'metering_plugin_name': - METERING_SERVICE_PLUGIN_KLASS, - 'l3_plugin_name': l3_plugin} - - plugin_str = ('neutron.tests.unit.test_l3_plugin.' - 'TestNoL3NatPlugin') - - super(TestMeteringPluginL3AgentSchedulerServicePlugin, self).setUp( - plugin_str=plugin_str, service_plugins=service_plugins, - scheduler=l3_plugin) - - -class TestMeteringPluginRpcFromL3Agent( - test_db_plugin.NeutronDbPluginV2TestCase, - test_l3_plugin.L3NatTestCaseMixin, - test_db_metering.MeteringPluginDbTestCaseMixin): - - resource_prefix_map = dict( - (k.replace('_', '-'), constants.COMMON_PREFIXES[constants.METERING]) - for k in ext_metering.RESOURCE_ATTRIBUTE_MAP - ) - - def setUp(self): - service_plugins = {'metering_plugin_name': - METERING_SERVICE_PLUGIN_KLASS} - - plugin = ('neutron.tests.unit.test_l3_plugin.' - 'TestL3NatIntAgentSchedulingPlugin') - - ext_mgr = MeteringTestExtensionManager() - super(TestMeteringPluginRpcFromL3Agent, - self).setUp(plugin=plugin, service_plugins=service_plugins, - ext_mgr=ext_mgr) - - self.meter_plugin = manager.NeutronManager.get_service_plugins().get( - constants.METERING) - - self.adminContext = context.get_admin_context() - self._register_l3_agent('agent1') - - def _register_l3_agent(self, host): - agent = { - 'binary': 'neutron-l3-agent', - 'host': host, - 'topic': topics.L3_AGENT, - 'configurations': {}, - 'agent_type': n_constants.AGENT_TYPE_L3, - 'start_flag': True - } - callback = agents_db.AgentExtRpcCallback() - callback.report_state(self.adminContext, - agent_state={'agent_state': agent}, - time=timeutils.strtime()) - - def test_get_sync_data_metering(self): - with self.subnet() as subnet: - s = subnet['subnet'] - self._set_net_external(s['network_id']) - with self.router(name='router1', subnet=subnet) as router: - r = router['router'] - self._add_external_gateway_to_router(r['id'], s['network_id']) - with self.metering_label(tenant_id=r['tenant_id']): - callbacks = metering_rpc.MeteringRpcCallbacks( - self.meter_plugin) - data = callbacks.get_sync_data_metering(self.adminContext, - host='agent1') - self.assertEqual('router1', data[0]['name']) - - self._register_l3_agent('agent2') - data = callbacks.get_sync_data_metering(self.adminContext, - host='agent2') - self.assertFalse(data) - - self._remove_external_gateway_from_router( - r['id'], s['network_id']) diff --git a/neutron/tests/unit/services/vpn/__init__.py b/neutron/tests/unit/services/vpn/__init__.py deleted file mode 100644 index b936bbcb8..000000000 --- a/neutron/tests/unit/services/vpn/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. -# All Rights Reserved. -# -# 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. -# @author: Swaminathan Vasudevan, Hewlett-Packard. diff --git a/neutron/tests/unit/services/vpn/device_drivers/__init__.py b/neutron/tests/unit/services/vpn/device_drivers/__init__.py deleted file mode 100644 index 9b27a7520..000000000 --- a/neutron/tests/unit/services/vpn/device_drivers/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013, Nachi Ueno, NTT I3, Inc. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/services/vpn/device_drivers/cisco_csr_mock.py b/neutron/tests/unit/services/vpn/device_drivers/cisco_csr_mock.py deleted file mode 100644 index fe2223a74..000000000 --- a/neutron/tests/unit/services/vpn/device_drivers/cisco_csr_mock.py +++ /dev/null @@ -1,579 +0,0 @@ -# Copyright 2014 Cisco Systems, Inc. All rights reserved. -# -# 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. -# -# @author: Paul Michali, Cisco Systems, Inc. - -"""Mock REST requests to Cisco Cloud Services Router.""" - -import re - -import functools -# import httmock -import requests -from requests import exceptions as r_exc - -from neutron.openstack.common import log as logging -# TODO(pcm) Remove once httmock package is added to test-requirements. For -# now, uncomment and include httmock source to UT -from neutron.tests.unit.services.vpn import device_drivers - -LOG = logging.getLogger(__name__) - -httmock = device_drivers.httmock - - -def repeat(n): - """Decorator to limit the number of times a handler is called. - - Will allow the wrapped function (handler) to be called 'n' times. - After that, this will return None for any additional calls, - allowing other handlers, if any, to be invoked. - """ - - class static: - retries = n - - def decorator(func): - @functools.wraps(func) - def wrapped(*args, **kwargs): - if static.retries == 0: - return None - static.retries -= 1 - return func(*args, **kwargs) - return wrapped - return decorator - - -def filter_request(methods, resource): - """Decorator to invoke handler once for a specific resource. - - This will call the handler only for a specific resource using - a specific method(s). Any other resource request or method will - return None, allowing other handlers, if any, to be invoked. - """ - - class static: - target_methods = [m.upper() for m in methods] - target_resource = resource - - def decorator(func): - @functools.wraps(func) - def wrapped(*args, **kwargs): - if (args[1].method in static.target_methods and - static.target_resource in args[0].path): - return func(*args, **kwargs) - else: - return None # Not for this resource - return wrapped - return decorator - - -@httmock.urlmatch(netloc=r'localhost') -def token(url, request): - if 'auth/token-services' in url.path: - return {'status_code': requests.codes.OK, - 'content': {'token-id': 'dummy-token'}} - - -@httmock.urlmatch(netloc=r'localhost') -def token_unauthorized(url, request): - if 'auth/token-services' in url.path: - return {'status_code': requests.codes.UNAUTHORIZED} - - -@httmock.urlmatch(netloc=r'wrong-host') -def token_wrong_host(url, request): - raise r_exc.ConnectionError() - - -@httmock.all_requests -def token_timeout(url, request): - raise r_exc.Timeout() - - -@filter_request(['get'], 'global/host-name') -@httmock.all_requests -def timeout(url, request): - """Simulated timeout of a normal request.""" - - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - raise r_exc.Timeout() - - -@httmock.urlmatch(netloc=r'localhost') -def no_such_resource(url, request): - """Indicate not found error, when invalid resource requested.""" - return {'status_code': requests.codes.NOT_FOUND} - - -@filter_request(['get'], 'global/host-name') -@repeat(1) -@httmock.urlmatch(netloc=r'localhost') -def expired_request(url, request): - """Simulate access denied failure on first request for this resource. - - Intent here is to simulate that the token has expired, by failing - the first request to the resource. Because of the repeat=1, this - will only be called once, and subsequent calls will not be handled - by this function, but instead will access the normal handler and - will pass. Currently configured for a GET request, but will work - with POST and PUT as well. For DELETE, would need to filter_request on a - different resource (e.g. 'global/local-users') - """ - - return {'status_code': requests.codes.UNAUTHORIZED} - - -@httmock.urlmatch(netloc=r'localhost') -def normal_get(url, request): - if request.method != 'GET': - return - LOG.debug("GET mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - if 'global/host-name' in url.path: - content = {u'kind': u'object#host-name', - u'host-name': u'Router'} - return httmock.response(requests.codes.OK, content=content) - if 'global/local-users' in url.path: - content = {u'kind': u'collection#local-user', - u'users': ['peter', 'paul', 'mary']} - return httmock.response(requests.codes.OK, content=content) - if 'interfaces/GigabitEthernet' in url.path: - actual_interface = url.path.split('/')[-1] - ip = actual_interface[-1] - content = {u'kind': u'object#interface', - u'description': u'Changed description', - u'if-name': actual_interface, - u'proxy-arp': True, - u'subnet-mask': u'255.255.255.0', - u'icmp-unreachable': True, - u'nat-direction': u'', - u'icmp-redirects': True, - u'ip-address': u'192.168.200.%s' % ip, - u'verify-unicast-source': False, - u'type': u'ethernet'} - return httmock.response(requests.codes.OK, content=content) - if 'vpn-svc/ike/policies/2' in url.path: - content = {u'kind': u'object#ike-policy', - u'priority-id': u'2', - u'version': u'v1', - u'local-auth-method': u'pre-share', - u'encryption': u'aes256', - u'hash': u'sha', - u'dhGroup': 5, - u'lifetime': 3600} - return httmock.response(requests.codes.OK, content=content) - if 'vpn-svc/ike/keyrings' in url.path: - content = {u'kind': u'object#ike-keyring', - u'keyring-name': u'5', - u'pre-shared-key-list': [ - {u'key': u'super-secret', - u'encrypted': False, - u'peer-address': u'10.10.10.20 255.255.255.0'} - ]} - return httmock.response(requests.codes.OK, content=content) - if 'vpn-svc/ipsec/policies/' in url.path: - ipsec_policy_id = url.path.split('/')[-1] - content = {u'kind': u'object#ipsec-policy', - u'mode': u'tunnel', - u'policy-id': u'%s' % ipsec_policy_id, - u'protection-suite': { - u'esp-encryption': u'esp-256-aes', - u'esp-authentication': u'esp-sha-hmac', - u'ah': u'ah-sha-hmac', - }, - u'anti-replay-window-size': u'Disable', - u'lifetime-sec': 120, - u'pfs': u'group5', - u'lifetime-kb': 4608000, - u'idle-time': None} - return httmock.response(requests.codes.OK, content=content) - if 'vpn-svc/site-to-site/Tunnel' in url.path: - tunnel = url.path.split('/')[-1] - # Use same number, to allow mock to generate IPSec policy ID - ipsec_policy_id = tunnel[6:] - content = {u'kind': u'object#vpn-site-to-site', - u'vpn-interface-name': u'%s' % tunnel, - u'ip-version': u'ipv4', - u'vpn-type': u'site-to-site', - u'ipsec-policy-id': u'%s' % ipsec_policy_id, - u'ike-profile-id': None, - u'mtu': 1500, - u'local-device': { - u'ip-address': '10.3.0.1/24', - u'tunnel-ip-address': '10.10.10.10' - }, - u'remote-device': { - u'tunnel-ip-address': '10.10.10.20' - }} - return httmock.response(requests.codes.OK, content=content) - if 'vpn-svc/ike/keepalive' in url.path: - content = {u'interval': 60, - u'retry': 4, - u'periodic': True} - return httmock.response(requests.codes.OK, content=content) - if 'routing-svc/static-routes' in url.path: - content = {u'destination-network': u'10.1.0.0/24', - u'kind': u'object#static-route', - u'next-hop-router': None, - u'outgoing-interface': u'GigabitEthernet1', - u'admin-distance': 1} - return httmock.response(requests.codes.OK, content=content) - if 'vpn-svc/site-to-site/active/sessions' in url.path: - # Only including needed fields for mock - content = {u'kind': u'collection#vpn-active-sessions', - u'items': [{u'status': u'DOWN-NEGOTIATING', - u'vpn-interface-name': u'Tunnel123'}, ]} - return httmock.response(requests.codes.OK, content=content) - - -@filter_request(['get'], 'vpn-svc/ike/keyrings') -@httmock.urlmatch(netloc=r'localhost') -def get_fqdn(url, request): - LOG.debug("GET FQDN mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - content = {u'kind': u'object#ike-keyring', - u'keyring-name': u'5', - u'pre-shared-key-list': [ - {u'key': u'super-secret', - u'encrypted': False, - u'peer-address': u'cisco.com'} - ]} - return httmock.response(requests.codes.OK, content=content) - - -@filter_request(['get'], 'vpn-svc/ipsec/policies/') -@httmock.urlmatch(netloc=r'localhost') -def get_no_ah(url, request): - LOG.debug("GET No AH mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - ipsec_policy_id = url.path.split('/')[-1] - content = {u'kind': u'object#ipsec-policy', - u'mode': u'tunnel', - u'anti-replay-window-size': u'128', - u'policy-id': u'%s' % ipsec_policy_id, - u'protection-suite': { - u'esp-encryption': u'esp-aes', - u'esp-authentication': u'esp-sha-hmac', - }, - u'lifetime-sec': 120, - u'pfs': u'group5', - u'lifetime-kb': 4608000, - u'idle-time': None} - return httmock.response(requests.codes.OK, content=content) - - -@httmock.urlmatch(netloc=r'localhost') -def get_defaults(url, request): - if request.method != 'GET': - return - LOG.debug("GET mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - if 'vpn-svc/ike/policies/2' in url.path: - content = {u'kind': u'object#ike-policy', - u'priority-id': u'2', - u'version': u'v1', - u'local-auth-method': u'pre-share', - u'encryption': u'des', - u'hash': u'sha', - u'dhGroup': 1, - u'lifetime': 86400} - return httmock.response(requests.codes.OK, content=content) - if 'vpn-svc/ipsec/policies/' in url.path: - ipsec_policy_id = url.path.split('/')[-1] - content = {u'kind': u'object#ipsec-policy', - u'mode': u'tunnel', - u'policy-id': u'%s' % ipsec_policy_id, - u'protection-suite': {}, - u'lifetime-sec': 3600, - u'pfs': u'Disable', - u'anti-replay-window-size': u'None', - u'lifetime-kb': 4608000, - u'idle-time': None} - return httmock.response(requests.codes.OK, content=content) - - -@filter_request(['get'], 'vpn-svc/site-to-site') -@httmock.urlmatch(netloc=r'localhost') -def get_unnumbered(url, request): - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - tunnel = url.path.split('/')[-1] - ipsec_policy_id = tunnel[6:] - content = {u'kind': u'object#vpn-site-to-site', - u'vpn-interface-name': u'%s' % tunnel, - u'ip-version': u'ipv4', - u'vpn-type': u'site-to-site', - u'ipsec-policy-id': u'%s' % ipsec_policy_id, - u'ike-profile-id': None, - u'mtu': 1500, - u'local-device': { - u'ip-address': u'GigabitEthernet3', - u'tunnel-ip-address': u'10.10.10.10' - }, - u'remote-device': { - u'tunnel-ip-address': u'10.10.10.20' - }} - return httmock.response(requests.codes.OK, content=content) - - -@filter_request(['get'], 'vpn-svc/site-to-site/Tunnel') -@httmock.urlmatch(netloc=r'localhost') -def get_admin_down(url, request): - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - # URI has .../Tunnel#/state, so get number from 2nd to last element - tunnel = url.path.split('/')[-2] - content = {u'kind': u'object#vpn-site-to-site-state', - u'vpn-interface-name': u'%s' % tunnel, - u'line-protocol-state': u'down', - u'enabled': False} - return httmock.response(requests.codes.OK, content=content) - - -@filter_request(['get'], 'vpn-svc/site-to-site/Tunnel') -@httmock.urlmatch(netloc=r'localhost') -def get_admin_up(url, request): - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - # URI has .../Tunnel#/state, so get number from 2nd to last element - tunnel = url.path.split('/')[-2] - content = {u'kind': u'object#vpn-site-to-site-state', - u'vpn-interface-name': u'%s' % tunnel, - u'line-protocol-state': u'down', - u'enabled': True} - return httmock.response(requests.codes.OK, content=content) - - -@filter_request(['get'], 'vpn-svc/site-to-site') -@httmock.urlmatch(netloc=r'localhost') -def get_mtu(url, request): - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - tunnel = url.path.split('/')[-1] - ipsec_policy_id = tunnel[6:] - content = {u'kind': u'object#vpn-site-to-site', - u'vpn-interface-name': u'%s' % tunnel, - u'ip-version': u'ipv4', - u'vpn-type': u'site-to-site', - u'ipsec-policy-id': u'%s' % ipsec_policy_id, - u'ike-profile-id': None, - u'mtu': 9192, - u'local-device': { - u'ip-address': u'10.3.0.1/24', - u'tunnel-ip-address': u'10.10.10.10' - }, - u'remote-device': { - u'tunnel-ip-address': u'10.10.10.20' - }} - return httmock.response(requests.codes.OK, content=content) - - -@filter_request(['get'], 'vpn-svc/ike/keepalive') -@httmock.urlmatch(netloc=r'localhost') -def get_not_configured(url, request): - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - return {'status_code': requests.codes.NOT_FOUND} - - -@filter_request(['get'], 'vpn-svc/site-to-site/active/sessions') -@httmock.urlmatch(netloc=r'localhost') -def get_none(url, request): - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - content = {u'kind': u'collection#vpn-active-sessions', - u'items': []} - return httmock.response(requests.codes.OK, content=content) - - -@filter_request(['get'], 'interfaces/GigabitEthernet3') -@httmock.urlmatch(netloc=r'localhost') -def get_local_ip(url, request): - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - content = {u'kind': u'object#interface', - u'subnet-mask': u'255.255.255.0', - u'ip-address': u'10.5.0.2'} - return httmock.response(requests.codes.OK, content=content) - - -@httmock.urlmatch(netloc=r'localhost') -def post(url, request): - if request.method != 'POST': - return - LOG.debug("POST mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - if 'interfaces/GigabitEthernet' in url.path: - return {'status_code': requests.codes.NO_CONTENT} - if 'global/local-users' in url.path: - if 'username' not in request.body: - return {'status_code': requests.codes.BAD_REQUEST} - if '"privilege": 20' in request.body: - return {'status_code': requests.codes.BAD_REQUEST} - headers = {'location': '%s/test-user' % url.geturl()} - return httmock.response(requests.codes.CREATED, headers=headers) - if 'vpn-svc/ike/policies' in url.path: - headers = {'location': "%s/2" % url.geturl()} - return httmock.response(requests.codes.CREATED, headers=headers) - if 'vpn-svc/ipsec/policies' in url.path: - m = re.search(r'"policy-id": "(\S+)"', request.body) - if m: - headers = {'location': "%s/%s" % (url.geturl(), m.group(1))} - return httmock.response(requests.codes.CREATED, headers=headers) - return {'status_code': requests.codes.BAD_REQUEST} - if 'vpn-svc/ike/keyrings' in url.path: - headers = {'location': "%s/5" % url.geturl()} - return httmock.response(requests.codes.CREATED, headers=headers) - if 'vpn-svc/site-to-site' in url.path: - m = re.search(r'"vpn-interface-name": "(\S+)"', request.body) - if m: - headers = {'location': "%s/%s" % (url.geturl(), m.group(1))} - return httmock.response(requests.codes.CREATED, headers=headers) - return {'status_code': requests.codes.BAD_REQUEST} - if 'routing-svc/static-routes' in url.path: - headers = {'location': - "%s/10.1.0.0_24_GigabitEthernet1" % url.geturl()} - return httmock.response(requests.codes.CREATED, headers=headers) - - -@filter_request(['post'], 'global/local-users') -@httmock.urlmatch(netloc=r'localhost') -def post_change_attempt(url, request): - LOG.debug("POST change value mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - return {'status_code': requests.codes.NOT_FOUND, - 'content': { - u'error-code': -1, - u'error-message': u'user test-user already exists'}} - - -@httmock.urlmatch(netloc=r'localhost') -def post_duplicate(url, request): - LOG.debug("POST duplicate mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - return {'status_code': requests.codes.BAD_REQUEST, - 'content': { - u'error-code': -1, - u'error-message': u'policy 2 exist, not allow to ' - u'update policy using POST method'}} - - -@filter_request(['post'], 'vpn-svc/site-to-site') -@httmock.urlmatch(netloc=r'localhost') -def post_missing_ipsec_policy(url, request): - LOG.debug("POST missing ipsec policy mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - return {'status_code': requests.codes.BAD_REQUEST} - - -@filter_request(['post'], 'vpn-svc/site-to-site') -@httmock.urlmatch(netloc=r'localhost') -def post_missing_ike_policy(url, request): - LOG.debug("POST missing ike policy mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - return {'status_code': requests.codes.BAD_REQUEST} - - -@filter_request(['post'], 'vpn-svc/site-to-site') -@httmock.urlmatch(netloc=r'localhost') -def post_bad_ip(url, request): - LOG.debug("POST bad IP mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - return {'status_code': requests.codes.BAD_REQUEST} - - -@filter_request(['post'], 'vpn-svc/site-to-site') -@httmock.urlmatch(netloc=r'localhost') -def post_bad_mtu(url, request): - LOG.debug("POST bad mtu mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - return {'status_code': requests.codes.BAD_REQUEST} - - -@filter_request(['post'], 'vpn-svc/ipsec/policies') -@httmock.urlmatch(netloc=r'localhost') -def post_bad_lifetime(url, request): - LOG.debug("POST bad lifetime mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - return {'status_code': requests.codes.BAD_REQUEST} - - -@filter_request(['post'], 'vpn-svc/ipsec/policies') -@httmock.urlmatch(netloc=r'localhost') -def post_bad_name(url, request): - LOG.debug("POST bad IPSec policy name for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - return {'status_code': requests.codes.BAD_REQUEST} - - -@httmock.urlmatch(netloc=r'localhost') -def put(url, request): - if request.method != 'PUT': - return - LOG.debug("PUT mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - # Any resource - return {'status_code': requests.codes.NO_CONTENT} - - -@httmock.urlmatch(netloc=r'localhost') -def delete(url, request): - if request.method != 'DELETE': - return - LOG.debug("DELETE mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - # Any resource - return {'status_code': requests.codes.NO_CONTENT} - - -@httmock.urlmatch(netloc=r'localhost') -def delete_unknown(url, request): - if request.method != 'DELETE': - return - LOG.debug("DELETE unknown mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - # Any resource - return {'status_code': requests.codes.NOT_FOUND, - 'content': { - u'error-code': -1, - u'error-message': 'user unknown not found'}} - - -@httmock.urlmatch(netloc=r'localhost') -def delete_not_allowed(url, request): - if request.method != 'DELETE': - return - LOG.debug("DELETE not allowed mock for %s", url) - if not request.headers.get('X-auth-token', None): - return {'status_code': requests.codes.UNAUTHORIZED} - # Any resource - return {'status_code': requests.codes.METHOD_NOT_ALLOWED} diff --git a/neutron/tests/unit/services/vpn/device_drivers/notest_cisco_csr_rest.py b/neutron/tests/unit/services/vpn/device_drivers/notest_cisco_csr_rest.py deleted file mode 100644 index 45bf97238..000000000 --- a/neutron/tests/unit/services/vpn/device_drivers/notest_cisco_csr_rest.py +++ /dev/null @@ -1,1346 +0,0 @@ -# Copyright 2014 Cisco Systems, Inc. All rights reserved. -# -# 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. -# -# @author: Paul Michali, Cisco Systems, Inc. - -#TODO(pcm): Rename this file to remove the "no" prefix, once httmock is -# approved and added to requirements.txt - -import random - -# TODO(pcm) Uncomment when httmock is added to test requirements. -# import httmock -import requests - -from neutron.openstack.common import log as logging -from neutron.services.vpn.device_drivers import ( - cisco_csr_rest_client as csr_client) -from neutron.tests import base -from neutron.tests.unit.services.vpn import device_drivers -# TODO(pcm) Remove once httmock is available. In the meantime, use -# temporary local copy of httmock source to run UT - - -LOG = logging.getLogger(__name__) -# Enables debug logging to console -if True: - logging.CONF.set_override('debug', True) - logging.setup('neutron') - -dummy_policy_id = 'dummy-ipsec-policy-id-name' - -httmock = device_drivers.httmock - - -# Note: Helper functions to test reuse of IDs. -def generate_pre_shared_key_id(): - return random.randint(100, 200) - - -def generate_ike_policy_id(): - return random.randint(200, 300) - - -def generate_ipsec_policy_id(): - return random.randint(300, 400) - - -class TestCsrLoginRestApi(base.BaseTestCase): - - """Test logging into CSR to obtain token-id.""" - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrLoginRestApi, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def test_get_token(self): - """Obtain the token and its expiration time.""" - with httmock.HTTMock(device_drivers.csr_request.token): - self.assertTrue(self.csr.authenticate()) - self.assertEqual(requests.codes.OK, self.csr.status) - self.assertIsNotNone(self.csr.token) - - def test_unauthorized_token_request(self): - """Negative test of invalid user/password.""" - self.csr.auth = ('stack', 'bogus') - with httmock.HTTMock(device_drivers.csr_request.token_unauthorized): - self.assertIsNone(self.csr.authenticate()) - self.assertEqual(requests.codes.UNAUTHORIZED, self.csr.status) - - def test_non_existent_host(self): - """Negative test of request to non-existent host.""" - self.csr.host = 'wrong-host' - self.csr.token = 'Set by some previously successful access' - with httmock.HTTMock(device_drivers.csr_request.token_wrong_host): - self.assertIsNone(self.csr.authenticate()) - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) - self.assertIsNone(self.csr.token) - - def test_timeout_on_token_access(self): - """Negative test of a timeout on a request.""" - with httmock.HTTMock(device_drivers.csr_request.token_timeout): - self.assertIsNone(self.csr.authenticate()) - self.assertEqual(requests.codes.REQUEST_TIMEOUT, self.csr.status) - self.assertIsNone(self.csr.token) - - -class TestCsrGetRestApi(base.BaseTestCase): - - """Test CSR GET REST API.""" - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrGetRestApi, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def test_valid_rest_gets(self): - """Simple GET requests. - - First request will do a post to get token (login). Assumes - that there are two interfaces on the CSR. - """ - - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.normal_get): - content = self.csr.get_request('global/host-name') - self.assertEqual(requests.codes.OK, self.csr.status) - self.assertIn('host-name', content) - self.assertNotEqual(None, content['host-name']) - - content = self.csr.get_request('global/local-users') - self.assertEqual(requests.codes.OK, self.csr.status) - self.assertIn('users', content) - - -class TestCsrPostRestApi(base.BaseTestCase): - - """Test CSR POST REST API.""" - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrPostRestApi, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def test_post_requests(self): - """Simple POST requests (repeatable). - - First request will do a post to get token (login). Assumes - that there are two interfaces (Ge1 and Ge2) on the CSR. - """ - - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - content = self.csr.post_request( - 'interfaces/GigabitEthernet1/statistics', - payload={'action': 'clear'}) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - self.assertIsNone(content) - content = self.csr.post_request( - 'interfaces/GigabitEthernet2/statistics', - payload={'action': 'clear'}) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - self.assertIsNone(content) - - def test_post_with_location(self): - """Create a user and verify that location returned.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - location = self.csr.post_request( - 'global/local-users', - payload={'username': 'test-user', - 'password': 'pass12345', - 'privilege': 15}) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('global/local-users/test-user', location) - - def test_post_missing_required_attribute(self): - """Negative test of POST with missing mandatory info.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - self.csr.post_request('global/local-users', - payload={'password': 'pass12345', - 'privilege': 15}) - self.assertEqual(requests.codes.BAD_REQUEST, self.csr.status) - - def test_post_invalid_attribute(self): - """Negative test of POST with invalid info.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - self.csr.post_request('global/local-users', - payload={'username': 'test-user', - 'password': 'pass12345', - 'privilege': 20}) - self.assertEqual(requests.codes.BAD_REQUEST, self.csr.status) - - def test_post_already_exists(self): - """Negative test of a duplicate POST. - - Uses the lower level _do_request() API to just perform the POST and - obtain the response, without any error processing. - """ - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - location = self.csr._do_request( - 'POST', - 'global/local-users', - payload={'username': 'test-user', - 'password': 'pass12345', - 'privilege': 15}, - more_headers=csr_client.HEADER_CONTENT_TYPE_JSON) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('global/local-users/test-user', location) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post_change_attempt): - self.csr._do_request( - 'POST', - 'global/local-users', - payload={'username': 'test-user', - 'password': 'pass12345', - 'privilege': 15}, - more_headers=csr_client.HEADER_CONTENT_TYPE_JSON) - # Note: For local-user, a 404 error is returned. For - # site-to-site connection a 400 is returned. - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) - - def test_post_changing_value(self): - """Negative test of a POST trying to change a value.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - location = self.csr.post_request( - 'global/local-users', - payload={'username': 'test-user', - 'password': 'pass12345', - 'privilege': 15}) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('global/local-users/test-user', location) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post_change_attempt): - content = self.csr.post_request('global/local-users', - payload={'username': 'test-user', - 'password': 'changed', - 'privilege': 15}) - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) - expected = {u'error-code': -1, - u'error-message': u'user test-user already exists'} - self.assertDictContainsSubset(expected, content) - - -class TestCsrPutRestApi(base.BaseTestCase): - - """Test CSR PUT REST API.""" - - def _save_resources(self): - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.normal_get): - details = self.csr.get_request('global/host-name') - if self.csr.status != requests.codes.OK: - self.fail("Unable to save original host name") - self.original_host = details['host-name'] - details = self.csr.get_request('interfaces/GigabitEthernet1') - if self.csr.status != requests.codes.OK: - self.fail("Unable to save interface Ge1 description") - self.original_if = details - if details.get('description', ''): - self.original_if['description'] = '' - self.csr.token = None - - def _restore_resources(self, user, password): - """Restore the host name and itnerface description. - - Must restore the user and password, so that authentication - token can be obtained (as some tests corrupt auth info). - Will also clear token, so that it gets a fresh token. - """ - - self.csr.auth = (user, password) - self.csr.token = None - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.put): - payload = {'host-name': self.original_host} - self.csr.put_request('global/host-name', payload=payload) - if self.csr.status != requests.codes.NO_CONTENT: - self.fail("Unable to restore host name after test") - payload = {'description': self.original_if['description'], - 'if-name': self.original_if['if-name'], - 'ip-address': self.original_if['ip-address'], - 'subnet-mask': self.original_if['subnet-mask'], - 'type': self.original_if['type']} - self.csr.put_request('interfaces/GigabitEthernet1', - payload=payload) - if self.csr.status != requests.codes.NO_CONTENT: - self.fail("Unable to restore I/F Ge1 description after test") - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - """Prepare for PUT API tests.""" - super(TestCsrPutRestApi, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - self._save_resources() - self.addCleanup(self._restore_resources, 'stack', 'cisco') - - def test_put_requests(self): - """Simple PUT requests (repeatable). - - First request will do a post to get token (login). Assumes - that there are two interfaces on the CSR (Ge1 and Ge2). - """ - - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.put, - device_drivers.csr_request.normal_get): - payload = {'host-name': 'TestHost'} - content = self.csr.put_request('global/host-name', - payload=payload) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - self.assertIsNone(content) - - payload = {'host-name': 'TestHost2'} - content = self.csr.put_request('global/host-name', - payload=payload) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - self.assertIsNone(content) - - def test_change_interface_description(self): - """Test that interface description can be changed. - - This was a problem with an earlier version of the CSR image and is - here to prevent regression. - """ - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.put, - device_drivers.csr_request.normal_get): - payload = {'description': u'Changed description', - 'if-name': self.original_if['if-name'], - 'ip-address': self.original_if['ip-address'], - 'subnet-mask': self.original_if['subnet-mask'], - 'type': self.original_if['type']} - content = self.csr.put_request( - 'interfaces/GigabitEthernet1', payload=payload) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - self.assertIsNone(content) - content = self.csr.get_request('interfaces/GigabitEthernet1') - self.assertEqual(requests.codes.OK, self.csr.status) - self.assertIn('description', content) - self.assertEqual(u'Changed description', - content['description']) - - def ignore_test_change_to_empty_interface_description(self): - """Test that interface description can be changed to empty string. - - This is a problem in the current version of the CSR image, which - rejects the change with a 400 error. This test is here to prevent - a regression (once it is fixed) Note that there is code in the - test setup to change the description to a non-empty string to - avoid failures in other tests. - """ - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.put, - device_drivers.csr_request.normal_get): - payload = {'description': '', - 'if-name': self.original_if['if-name'], - 'ip-address': self.original_if['ip-address'], - 'subnet-mask': self.original_if['subnet-mask'], - 'type': self.original_if['type']} - content = self.csr.put_request( - 'interfaces/GigabitEthernet1', payload=payload) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - self.assertIsNone(content) - content = self.csr.get_request('interfaces/GigabitEthernet1') - self.assertEqual(requests.codes.OK, self.csr.status) - self.assertIn('description', content) - self.assertEqual('', content['description']) - - -class TestCsrDeleteRestApi(base.BaseTestCase): - - """Test CSR DELETE REST API.""" - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrDeleteRestApi, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def _make_dummy_user(self): - """Create a user that will be later deleted.""" - self.csr.post_request('global/local-users', - payload={'username': 'dummy', - 'password': 'dummy', - 'privilege': 15}) - self.assertEqual(requests.codes.CREATED, self.csr.status) - - def test_delete_requests(self): - """Simple DELETE requests (creating entry first).""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.delete): - self._make_dummy_user() - self.csr.token = None # Force login - self.csr.delete_request('global/local-users/dummy') - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - # Delete again, but without logging in this time - self._make_dummy_user() - self.csr.delete_request('global/local-users/dummy') - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - - def test_delete_non_existent_entry(self): - """Negative test of trying to delete a non-existent user.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.delete_unknown): - content = self.csr.delete_request('global/local-users/unknown') - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) - expected = {u'error-code': -1, - u'error-message': u'user unknown not found'} - self.assertDictContainsSubset(expected, content) - - def test_delete_not_allowed(self): - """Negative test of trying to delete the host-name.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.delete_not_allowed): - self.csr.delete_request('global/host-name') - self.assertEqual(requests.codes.METHOD_NOT_ALLOWED, - self.csr.status) - - -class TestCsrRestApiFailures(base.BaseTestCase): - - """Test failure cases common for all REST APIs. - - Uses the lower level _do_request() to just perform the operation and get - the result, without any error handling. - """ - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=0.1): - super(TestCsrRestApiFailures, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def test_request_for_non_existent_resource(self): - """Negative test of non-existent resource on REST request.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.no_such_resource): - self.csr.post_request('no/such/request') - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) - # The result is HTTP 404 message, so no error content to check - - def test_timeout_during_request(self): - """Negative test of timeout during REST request.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.timeout): - self.csr._do_request('GET', 'global/host-name') - self.assertEqual(requests.codes.REQUEST_TIMEOUT, self.csr.status) - - def test_token_expired_on_request(self): - """Token expired before trying a REST request. - - The mock is configured to return a 401 error on the first - attempt to reference the host name. Simulate expiration of - token by changing it. - """ - - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.expired_request, - device_drivers.csr_request.normal_get): - self.csr.token = '123' # These are 44 characters, so won't match - content = self.csr._do_request('GET', 'global/host-name') - self.assertEqual(requests.codes.OK, self.csr.status) - self.assertIn('host-name', content) - self.assertNotEqual(None, content['host-name']) - - def test_failed_to_obtain_token_for_request(self): - """Negative test of unauthorized user for REST request.""" - self.csr.auth = ('stack', 'bogus') - with httmock.HTTMock(device_drivers.csr_request.token_unauthorized): - self.csr._do_request('GET', 'global/host-name') - self.assertEqual(requests.codes.UNAUTHORIZED, self.csr.status) - - -class TestCsrRestIkePolicyCreate(base.BaseTestCase): - - """Test IKE policy create REST requests.""" - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrRestIkePolicyCreate, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def test_create_delete_ike_policy(self): - """Create and then delete IKE policy.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - policy_id = '2' - policy_info = {u'priority-id': u'%s' % policy_id, - u'encryption': u'aes256', - u'hash': u'sha', - u'dhGroup': 5, - u'lifetime': 3600} - location = self.csr.create_ike_policy(policy_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ike/policies/%s' % policy_id, location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_policy = {u'kind': u'object#ike-policy', - u'version': u'v1', - u'local-auth-method': u'pre-share'} - expected_policy.update(policy_info) - self.assertEqual(expected_policy, content) - # Now delete and verify the IKE policy is gone - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.delete, - device_drivers.csr_request.no_such_resource): - self.csr.delete_ike_policy(policy_id) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) - - def test_create_ike_policy_with_defaults(self): - """Create IKE policy using defaults for all optional values.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.get_defaults): - policy_id = '2' - policy_info = {u'priority-id': u'%s' % policy_id} - location = self.csr.create_ike_policy(policy_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ike/policies/%s' % policy_id, location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_policy = {u'kind': u'object#ike-policy', - u'version': u'v1', - u'encryption': u'des', - u'hash': u'sha', - u'dhGroup': 1, - u'lifetime': 86400, - # Lower level sets this, but it is the default - u'local-auth-method': u'pre-share'} - expected_policy.update(policy_info) - self.assertEqual(expected_policy, content) - - def test_create_duplicate_ike_policy(self): - """Negative test of trying to create a duplicate IKE policy.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - policy_id = '2' - policy_info = {u'priority-id': u'%s' % policy_id, - u'encryption': u'aes', - u'hash': u'sha', - u'dhGroup': 5, - u'lifetime': 3600} - location = self.csr.create_ike_policy(policy_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ike/policies/%s' % policy_id, location) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post_duplicate): - location = self.csr.create_ike_policy(policy_info) - self.assertEqual(requests.codes.BAD_REQUEST, self.csr.status) - expected = {u'error-code': -1, - u'error-message': u'policy 2 exist, not allow to ' - u'update policy using POST method'} - self.assertDictContainsSubset(expected, location) - - -class TestCsrRestIPSecPolicyCreate(base.BaseTestCase): - - """Test IPSec policy create REST requests.""" - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrRestIPSecPolicyCreate, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def test_create_delete_ipsec_policy(self): - """Create and then delete IPSec policy.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - policy_id = '123' - policy_info = { - u'policy-id': u'%s' % policy_id, - u'protection-suite': { - u'esp-encryption': u'esp-256-aes', - u'esp-authentication': u'esp-sha-hmac', - u'ah': u'ah-sha-hmac', - }, - u'lifetime-sec': 120, - u'pfs': u'group5', - u'anti-replay-window-size': u'disable' - } - location = self.csr.create_ipsec_policy(policy_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ipsec/policies/%s' % policy_id, location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_policy = {u'kind': u'object#ipsec-policy', - u'mode': u'tunnel', - u'lifetime-kb': 4608000, - u'idle-time': None} - expected_policy.update(policy_info) - # CSR will respond with capitalized value - expected_policy[u'anti-replay-window-size'] = u'Disable' - self.assertEqual(expected_policy, content) - # Now delete and verify the IPSec policy is gone - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.delete, - device_drivers.csr_request.no_such_resource): - self.csr.delete_ipsec_policy(policy_id) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) - - def test_create_ipsec_policy_with_defaults(self): - """Create IPSec policy with default for all optional values.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.get_defaults): - policy_id = '123' - policy_info = { - u'policy-id': u'%s' % policy_id, - } - location = self.csr.create_ipsec_policy(policy_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ipsec/policies/%s' % policy_id, location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_policy = {u'kind': u'object#ipsec-policy', - u'mode': u'tunnel', - u'protection-suite': {}, - u'lifetime-sec': 3600, - u'pfs': u'Disable', - u'anti-replay-window-size': u'None', - u'lifetime-kb': 4608000, - u'idle-time': None} - expected_policy.update(policy_info) - self.assertEqual(expected_policy, content) - - def test_create_ipsec_policy_with_uuid(self): - """Create IPSec policy using UUID for id.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - policy_info = { - u'policy-id': u'%s' % dummy_policy_id, - u'protection-suite': { - u'esp-encryption': u'esp-256-aes', - u'esp-authentication': u'esp-sha-hmac', - u'ah': u'ah-sha-hmac', - }, - u'lifetime-sec': 120, - u'pfs': u'group5', - u'anti-replay-window-size': u'disable' - } - location = self.csr.create_ipsec_policy(policy_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ipsec/policies/%s' % dummy_policy_id, - location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_policy = {u'kind': u'object#ipsec-policy', - u'mode': u'tunnel', - u'lifetime-kb': 4608000, - u'idle-time': None} - expected_policy.update(policy_info) - # CSR will respond with capitalized value - expected_policy[u'anti-replay-window-size'] = u'Disable' - self.assertEqual(expected_policy, content) - - def test_create_ipsec_policy_without_ah(self): - """Create IPSec policy.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.get_no_ah): - policy_id = '10' - policy_info = { - u'policy-id': u'%s' % policy_id, - u'protection-suite': { - u'esp-encryption': u'esp-aes', - u'esp-authentication': u'esp-sha-hmac', - }, - u'lifetime-sec': 120, - u'pfs': u'group5', - u'anti-replay-window-size': u'128' - } - location = self.csr.create_ipsec_policy(policy_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ipsec/policies/%s' % policy_id, location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_policy = {u'kind': u'object#ipsec-policy', - u'mode': u'tunnel', - u'lifetime-kb': 4608000, - u'idle-time': None} - expected_policy.update(policy_info) - self.assertEqual(expected_policy, content) - - def test_invalid_ipsec_policy_lifetime(self): - """Failure test of IPSec policy with unsupported lifetime.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post_bad_lifetime): - policy_id = '123' - policy_info = { - u'policy-id': u'%s' % policy_id, - u'protection-suite': { - u'esp-encryption': u'esp-aes', - u'esp-authentication': u'esp-sha-hmac', - u'ah': u'ah-sha-hmac', - }, - u'lifetime-sec': 119, - u'pfs': u'group5', - u'anti-replay-window-size': u'128' - } - self.csr.create_ipsec_policy(policy_info) - self.assertEqual(requests.codes.BAD_REQUEST, self.csr.status) - - def test_create_ipsec_policy_with_invalid_name(self): - """Failure test of creating IPSec policy with name too long.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post_bad_name, - device_drivers.csr_request.get_defaults): - policy_id = 'policy-name-is-too-long-32-chars' - policy_info = { - u'policy-id': u'%s' % policy_id, - } - self.csr.create_ipsec_policy(policy_info) - self.assertEqual(requests.codes.BAD_REQUEST, self.csr.status) - - -class TestCsrRestPreSharedKeyCreate(base.BaseTestCase): - - """Test Pre-shared key (PSK) create REST requests.""" - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrRestPreSharedKeyCreate, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def test_create_delete_pre_shared_key(self): - """Create and then delete a keyring entry for pre-shared key.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - psk_id = '5' - psk_info = {u'keyring-name': u'%s' % psk_id, - u'pre-shared-key-list': [ - {u'key': u'super-secret', - u'encrypted': False, - u'peer-address': u'10.10.10.20/24'} - ]} - location = self.csr.create_pre_shared_key(psk_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ike/keyrings/%s' % psk_id, location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_policy = {u'kind': u'object#ike-keyring'} - expected_policy.update(psk_info) - # Note: the peer CIDR is returned as an IP and mask - expected_policy[u'pre-shared-key-list'][0][u'peer-address'] = ( - u'10.10.10.20 255.255.255.0') - self.assertEqual(expected_policy, content) - # Now delete and verify pre-shared key is gone - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.delete, - device_drivers.csr_request.no_such_resource): - self.csr.delete_pre_shared_key(psk_id) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) - - def test_create_pre_shared_key_with_fqdn_peer(self): - """Create pre-shared key using FQDN for peer address.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.get_fqdn): - psk_id = '5' - psk_info = {u'keyring-name': u'%s' % psk_id, - u'pre-shared-key-list': [ - {u'key': u'super-secret', - u'encrypted': False, - u'peer-address': u'cisco.com'} - ]} - location = self.csr.create_pre_shared_key(psk_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ike/keyrings/%s' % psk_id, location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_policy = {u'kind': u'object#ike-keyring'} - expected_policy.update(psk_info) - self.assertEqual(expected_policy, content) - - def test_create_pre_shared_key_with_duplicate_peer_address(self): - """Negative test of creating a second pre-shared key with same peer.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - psk_id = '5' - psk_info = {u'keyring-name': u'%s' % psk_id, - u'pre-shared-key-list': [ - {u'key': u'super-secret', - u'encrypted': False, - u'peer-address': u'10.10.10.20/24'} - ]} - location = self.csr.create_pre_shared_key(psk_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/ike/keyrings/%s' % psk_id, location) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post_duplicate): - psk_id = u'6' - another_psk_info = {u'keyring-name': psk_id, - u'pre-shared-key-list': [ - {u'key': u'abc123def', - u'encrypted': False, - u'peer-address': u'10.10.10.20/24'} - ]} - self.csr.create_ike_policy(another_psk_info) - self.assertEqual(requests.codes.BAD_REQUEST, self.csr.status) - - -class TestCsrRestIPSecConnectionCreate(base.BaseTestCase): - - """Test IPSec site-to-site connection REST requests. - - This requires us to have first created an IKE policy, IPSec policy, - and pre-shared key, so it's more of an itegration test, when used - with a real CSR (as we can't mock out these pre-conditions. - """ - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrRestIPSecConnectionCreate, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def _make_psk_for_test(self): - psk_id = generate_pre_shared_key_id() - self._remove_resource_for_test(self.csr.delete_pre_shared_key, - psk_id) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - psk_info = {u'keyring-name': u'%d' % psk_id, - u'pre-shared-key-list': [ - {u'key': u'super-secret', - u'encrypted': False, - u'peer-address': u'10.10.10.20/24'} - ]} - self.csr.create_pre_shared_key(psk_info) - if self.csr.status != requests.codes.CREATED: - self.fail("Unable to create PSK for test case") - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_pre_shared_key, psk_id) - return psk_id - - def _make_ike_policy_for_test(self): - policy_id = generate_ike_policy_id() - self._remove_resource_for_test(self.csr.delete_ike_policy, - policy_id) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - policy_info = {u'priority-id': u'%d' % policy_id, - u'encryption': u'aes', - u'hash': u'sha', - u'dhGroup': 5, - u'lifetime': 3600} - self.csr.create_ike_policy(policy_info) - if self.csr.status != requests.codes.CREATED: - self.fail("Unable to create IKE policy for test case") - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ike_policy, policy_id) - return policy_id - - def _make_ipsec_policy_for_test(self): - policy_id = generate_ipsec_policy_id() - self._remove_resource_for_test(self.csr.delete_ipsec_policy, - policy_id) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - policy_info = { - u'policy-id': u'%d' % policy_id, - u'protection-suite': { - u'esp-encryption': u'esp-aes', - u'esp-authentication': u'esp-sha-hmac', - u'ah': u'ah-sha-hmac', - }, - u'lifetime-sec': 120, - u'pfs': u'group5', - u'anti-replay-window-size': u'disable' - } - self.csr.create_ipsec_policy(policy_info) - if self.csr.status != requests.codes.CREATED: - self.fail("Unable to create IPSec policy for test case") - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_policy, policy_id) - return policy_id - - def _remove_resource_for_test(self, delete_resource, resource_id): - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.delete): - delete_resource(resource_id) - - def _prepare_for_site_conn_create(self, skip_psk=False, skip_ike=False, - skip_ipsec=False): - """Create the policies and PSK so can then create site conn.""" - if not skip_psk: - self._make_psk_for_test() - if not skip_ike: - self._make_ike_policy_for_test() - if not skip_ipsec: - ipsec_policy_id = self._make_ipsec_policy_for_test() - else: - ipsec_policy_id = generate_ipsec_policy_id() - # Note: Use same ID number for tunnel and IPSec policy, so that when - # GET tunnel info, the mocks can infer the IPSec policy ID from the - # tunnel number. - return (ipsec_policy_id, ipsec_policy_id) - - def test_create_delete_ipsec_connection(self): - """Create and then delete an IPSec connection.""" - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create() - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - connection_info = { - u'vpn-interface-name': u'Tunnel%d' % tunnel_id, - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'mtu': 1500, - u'local-device': {u'ip-address': u'10.3.0.1/24', - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - location = self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - 'Tunnel%d' % tunnel_id) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/site-to-site/Tunnel%d' % tunnel_id, - location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_connection = {u'kind': u'object#vpn-site-to-site', - u'ike-profile-id': None, - u'mtu': 1500, - u'ip-version': u'ipv4'} - expected_connection.update(connection_info) - self.assertEqual(expected_connection, content) - # Now delete and verify that site-to-site connection is gone - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.delete, - device_drivers.csr_request.no_such_resource): - # Only delete connection. Cleanup will take care of prerequisites - self.csr.delete_ipsec_connection('Tunnel%d' % tunnel_id) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) - - def test_create_ipsec_connection_with_no_tunnel_subnet(self): - """Create an IPSec connection without an IP address on tunnel.""" - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create() - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.get_unnumbered): - connection_info = { - u'vpn-interface-name': u'Tunnel%d' % tunnel_id, - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'local-device': {u'ip-address': u'GigabitEthernet3', - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - location = self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - 'Tunnel%d' % tunnel_id) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/site-to-site/Tunnel%d' % tunnel_id, - location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_connection = {u'kind': u'object#vpn-site-to-site', - u'ike-profile-id': None, - u'mtu': 1500, - u'ip-version': u'ipv4'} - expected_connection.update(connection_info) - self.assertEqual(expected_connection, content) - - def test_create_ipsec_connection_no_pre_shared_key(self): - """Test of connection create without associated pre-shared key. - - The CSR will create the connection, but will not be able to pass - traffic without the pre-shared key. - """ - - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create( - skip_psk=True) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - connection_info = { - u'vpn-interface-name': u'Tunnel%d' % tunnel_id, - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'mtu': 1500, - u'local-device': {u'ip-address': u'10.3.0.1/24', - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - location = self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - 'Tunnel%d' % tunnel_id) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/site-to-site/Tunnel%d' % tunnel_id, - location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_connection = {u'kind': u'object#vpn-site-to-site', - u'ike-profile-id': None, - u'mtu': 1500, - u'ip-version': u'ipv4'} - expected_connection.update(connection_info) - self.assertEqual(expected_connection, content) - - def test_create_ipsec_connection_with_default_ike_policy(self): - """Test of connection create without IKE policy (uses default). - - Without an IKE policy, the CSR will use a built-in default IKE - policy setting for the connection. - """ - - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create( - skip_ike=True) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - connection_info = { - u'vpn-interface-name': u'Tunnel%d' % tunnel_id, - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'mtu': 1500, - u'local-device': {u'ip-address': u'10.3.0.1/24', - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - location = self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - 'Tunnel%d' % tunnel_id) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/site-to-site/Tunnel%d' % tunnel_id, - location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_connection = {u'kind': u'object#vpn-site-to-site', - u'ike-profile-id': None, - u'mtu': 1500, - u'ip-version': u'ipv4'} - expected_connection.update(connection_info) - self.assertEqual(expected_connection, content) - - def test_set_ipsec_connection_admin_state_changes(self): - """Create IPSec connection in admin down state.""" - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create() - tunnel = u'Tunnel%d' % tunnel_id - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post): - connection_info = { - u'vpn-interface-name': tunnel, - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'mtu': 1500, - u'local-device': {u'ip-address': u'10.3.0.1/24', - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - location = self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - tunnel) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/site-to-site/%s' % tunnel, location) - state_uri = location + "/state" - # Note: When created, the tunnel will be in admin 'up' state - # Note: Line protocol state will be down, unless have an active conn. - expected_state = {u'kind': u'object#vpn-site-to-site-state', - u'vpn-interface-name': tunnel, - u'line-protocol-state': u'down', - u'enabled': False} - with httmock.HTTMock(device_drivers.csr_request.put, - device_drivers.csr_request.get_admin_down): - self.csr.set_ipsec_connection_state(tunnel, admin_up=False) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - content = self.csr.get_request(state_uri, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - self.assertEqual(expected_state, content) - - with httmock.HTTMock(device_drivers.csr_request.put, - device_drivers.csr_request.get_admin_up): - self.csr.set_ipsec_connection_state(tunnel, admin_up=True) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - content = self.csr.get_request(state_uri, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_state[u'enabled'] = True - self.assertEqual(expected_state, content) - - def test_create_ipsec_connection_missing_ipsec_policy(self): - """Negative test of connection create without IPSec policy.""" - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create( - skip_ipsec=True) - with httmock.HTTMock( - device_drivers.csr_request.token, - device_drivers.csr_request.post_missing_ipsec_policy): - connection_info = { - u'vpn-interface-name': u'Tunnel%d' % tunnel_id, - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'local-device': {u'ip-address': u'10.3.0.1/24', - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - 'Tunnel%d' % tunnel_id) - self.assertEqual(requests.codes.BAD_REQUEST, self.csr.status) - - def _determine_conflicting_ip(self): - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.get_local_ip): - details = self.csr.get_request('interfaces/GigabitEthernet3') - if self.csr.status != requests.codes.OK: - self.fail("Unable to obtain interface GigabitEthernet3's IP") - if_ip = details.get('ip-address') - if not if_ip: - self.fail("No IP address for GigabitEthernet3 interface") - return '.'.join(if_ip.split('.')[:3]) + '.10' - - def test_create_ipsec_connection_conficting_tunnel_ip(self): - """Negative test of connection create with conflicting tunnel IP. - - Find out the IP of a local interface (GigabitEthernet3) and create an - IP that is on the same subnet. Note: this interface needs to be up. - """ - - conflicting_ip = self._determine_conflicting_ip() - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create() - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post_bad_ip): - connection_info = { - u'vpn-interface-name': u'Tunnel%d' % tunnel_id, - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'local-device': {u'ip-address': u'%s/24' % conflicting_ip, - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - 'Tunnel%d' % tunnel_id) - self.assertEqual(requests.codes.BAD_REQUEST, self.csr.status) - - def test_create_ipsec_connection_with_max_mtu(self): - """Create an IPSec connection with max MTU value.""" - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create() - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.get_mtu): - connection_info = { - u'vpn-interface-name': u'Tunnel%d' % tunnel_id, - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'mtu': 9192, - u'local-device': {u'ip-address': u'10.3.0.1/24', - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - location = self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - 'Tunnel%d' % tunnel_id) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/site-to-site/Tunnel%d' % tunnel_id, - location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_connection = {u'kind': u'object#vpn-site-to-site', - u'ike-profile-id': None, - u'ip-version': u'ipv4'} - expected_connection.update(connection_info) - self.assertEqual(expected_connection, content) - - def test_create_ipsec_connection_with_bad_mtu(self): - """Negative test of connection create with unsupported MTU value.""" - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create() - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post_bad_mtu): - connection_info = { - u'vpn-interface-name': u'Tunnel%d' % tunnel_id, - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'mtu': 9193, - u'local-device': {u'ip-address': u'10.3.0.1/24', - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - 'Tunnel%d' % tunnel_id) - self.assertEqual(requests.codes.BAD_REQUEST, self.csr.status) - - def test_status_when_no_tunnels_exist(self): - """Get status, when there are no tunnels.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.get_none): - tunnels = self.csr.read_tunnel_statuses() - self.assertEqual(requests.codes.OK, self.csr.status) - self.assertEqual([], tunnels) - - def test_status_for_one_tunnel(self): - """Get status of one tunnel.""" - # Create the IPsec site-to-site connection first - tunnel_id, ipsec_policy_id = self._prepare_for_site_conn_create() - tunnel_id = 123 # Must hard code to work with mock - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - connection_info = { - u'vpn-interface-name': u'Tunnel123', - u'ipsec-policy-id': u'%d' % ipsec_policy_id, - u'local-device': {u'ip-address': u'10.3.0.1/24', - u'tunnel-ip-address': u'10.10.10.10'}, - u'remote-device': {u'tunnel-ip-address': u'10.10.10.20'} - } - location = self.csr.create_ipsec_connection(connection_info) - self.addCleanup(self._remove_resource_for_test, - self.csr.delete_ipsec_connection, - u'Tunnel123') - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('vpn-svc/site-to-site/Tunnel%d' % tunnel_id, - location) - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.normal_get): - tunnels = self.csr.read_tunnel_statuses() - self.assertEqual(requests.codes.OK, self.csr.status) - self.assertEqual([(u'Tunnel123', u'DOWN-NEGOTIATING'), ], tunnels) - - -class TestCsrRestIkeKeepaliveCreate(base.BaseTestCase): - - """Test IKE keepalive REST requests. - - Note: On the Cisco CSR, the IKE keepalive for v1 is a global configuration - that applies to all VPN tunnels to specify Dead Peer Detection information. - As a result, this REST API is not used in the OpenStack device driver, and - the keepalive will default to zero (disabled). - """ - - def _save_dpd_info(self): - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.normal_get): - details = self.csr.get_request('vpn-svc/ike/keepalive') - if self.csr.status == requests.codes.OK: - self.dpd = details - self.addCleanup(self._restore_dpd_info) - elif self.csr.status != requests.codes.NOT_FOUND: - self.fail("Unable to save original DPD info") - - def _restore_dpd_info(self): - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.put): - payload = {'interval': self.dpd['interval'], - 'retry': self.dpd['retry']} - self.csr.put_request('vpn-svc/ike/keepalive', payload=payload) - if self.csr.status != requests.codes.NO_CONTENT: - self.fail("Unable to restore DPD info after test") - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrRestIkeKeepaliveCreate, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - self._save_dpd_info() - self.csr.token = None - - def test_configure_ike_keepalive(self): - """Set IKE keep-alive (aka Dead Peer Detection) for the CSR.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.put, - device_drivers.csr_request.normal_get): - keepalive_info = {'interval': 60, 'retry': 4} - self.csr.configure_ike_keepalive(keepalive_info) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - content = self.csr.get_request('vpn-svc/ike/keepalive') - self.assertEqual(requests.codes.OK, self.csr.status) - expected = {'periodic': False} - expected.update(keepalive_info) - self.assertDictContainsSubset(expected, content) - - def test_disable_ike_keepalive(self): - """Disable IKE keep-alive (aka Dead Peer Detection) for the CSR.""" - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.delete, - device_drivers.csr_request.put, - device_drivers.csr_request.get_not_configured): - keepalive_info = {'interval': 0, 'retry': 4} - self.csr.configure_ike_keepalive(keepalive_info) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - - -class TestCsrRestStaticRoute(base.BaseTestCase): - - """Test static route REST requests. - - A static route is added for the peer's private network. Would create - a route for each of the peer CIDRs specified for the VPN connection. - """ - - def setUp(self, host='localhost', tunnel_ip='10.10.10.10', timeout=None): - super(TestCsrRestStaticRoute, self).setUp() - self.csr = csr_client.CsrRestClient(host, tunnel_ip, 'stack', 'cisco', - timeout) - - def test_create_delete_static_route(self): - """Create and then delete a static route for the tunnel.""" - cidr = u'10.1.0.0/24' - interface = u'GigabitEthernet1' - expected_id = '10.1.0.0_24_GigabitEthernet1' - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.post, - device_drivers.csr_request.normal_get): - route_info = {u'destination-network': cidr, - u'outgoing-interface': interface} - location = self.csr.create_static_route(route_info) - self.assertEqual(requests.codes.CREATED, self.csr.status) - self.assertIn('routing-svc/static-routes/%s' % expected_id, - location) - # Check the hard-coded items that get set as well... - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.OK, self.csr.status) - expected_route = {u'kind': u'object#static-route', - u'next-hop-router': None, - u'admin-distance': 1} - expected_route.update(route_info) - self.assertEqual(expected_route, content) - # Now delete and verify that static route is gone - with httmock.HTTMock(device_drivers.csr_request.token, - device_drivers.csr_request.delete, - device_drivers.csr_request.no_such_resource): - route_id = csr_client.make_route_id(cidr, interface) - self.csr.delete_static_route(route_id) - self.assertEqual(requests.codes.NO_CONTENT, self.csr.status) - content = self.csr.get_request(location, full_url=True) - self.assertEqual(requests.codes.NOT_FOUND, self.csr.status) diff --git a/neutron/tests/unit/services/vpn/device_drivers/test_cisco_ipsec.py b/neutron/tests/unit/services/vpn/device_drivers/test_cisco_ipsec.py deleted file mode 100644 index 3c29e7551..000000000 --- a/neutron/tests/unit/services/vpn/device_drivers/test_cisco_ipsec.py +++ /dev/null @@ -1,1709 +0,0 @@ -# Copyright 2014 Cisco Systems, Inc. All rights reserved. -# -# 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. -# -# @author: Paul Michali, Cisco Systems, Inc. - -import copy -import httplib -import os -import tempfile - -import mock - -from neutron import context -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.services.vpn.device_drivers import ( - cisco_csr_rest_client as csr_client) -from neutron.services.vpn.device_drivers import cisco_ipsec as ipsec_driver -from neutron.tests import base - -_uuid = uuidutils.generate_uuid -FAKE_HOST = 'fake_host' -FAKE_ROUTER_ID = _uuid() -FAKE_VPN_SERVICE = { - 'id': _uuid(), - 'router_id': FAKE_ROUTER_ID, - 'admin_state_up': True, - 'status': constants.PENDING_CREATE, - 'subnet': {'cidr': '10.0.0.0/24'}, - 'ipsec_site_connections': [ - {'peer_cidrs': ['20.0.0.0/24', - '30.0.0.0/24']}, - {'peer_cidrs': ['40.0.0.0/24', - '50.0.0.0/24']}] -} -FIND_CFG_FOR_CSRS = ('neutron.services.vpn.device_drivers.cisco_ipsec.' - 'find_available_csrs_from_config') - - -class TestCiscoCsrIPSecConnection(base.BaseTestCase): - def setUp(self): - super(TestCiscoCsrIPSecConnection, self).setUp() - self.conn_info = { - u'id': '123', - u'status': constants.PENDING_CREATE, - u'admin_state_up': True, - 'psk': 'secret', - 'peer_address': '192.168.1.2', - 'peer_cidrs': ['10.1.0.0/24', '10.2.0.0/24'], - 'mtu': 1500, - 'ike_policy': {'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'pfs': 'Group5', - 'ike_version': 'v1', - 'lifetime_units': 'seconds', - 'lifetime_value': 3600}, - 'ipsec_policy': {'transform_protocol': 'ah', - 'encryption_algorithm': 'aes-128', - 'auth_algorithm': 'sha1', - 'pfs': 'group5', - 'lifetime_units': 'seconds', - 'lifetime_value': 3600}, - 'cisco': {'site_conn_id': 'Tunnel0', - 'ike_policy_id': 222, - 'ipsec_policy_id': 333, - # TODO(pcm) FUTURE use vpnservice['external_ip'] - 'router_public_ip': '172.24.4.23'} - } - self.csr = mock.Mock(spec=csr_client.CsrRestClient) - self.csr.status = 201 # All calls to CSR REST API succeed - self.csr.tunnel_ip = '172.24.4.23' - self.ipsec_conn = ipsec_driver.CiscoCsrIPSecConnection(self.conn_info, - self.csr) - - def test_create_ipsec_site_connection(self): - """Ensure all steps are done to create an IPSec site connection. - - Verify that each of the driver calls occur (in order), and - the right information is stored for later deletion. - """ - expected = ['create_pre_shared_key', - 'create_ike_policy', - 'create_ipsec_policy', - 'create_ipsec_connection', - 'create_static_route', - 'create_static_route'] - expected_rollback_steps = [ - ipsec_driver.RollbackStep(action='pre_shared_key', - resource_id='123', - title='Pre-Shared Key'), - ipsec_driver.RollbackStep(action='ike_policy', - resource_id=222, - title='IKE Policy'), - ipsec_driver.RollbackStep(action='ipsec_policy', - resource_id=333, - title='IPSec Policy'), - ipsec_driver.RollbackStep(action='ipsec_connection', - resource_id='Tunnel0', - title='IPSec Connection'), - ipsec_driver.RollbackStep(action='static_route', - resource_id='10.1.0.0_24_Tunnel0', - title='Static Route'), - ipsec_driver.RollbackStep(action='static_route', - resource_id='10.2.0.0_24_Tunnel0', - title='Static Route')] - self.ipsec_conn.create_ipsec_site_connection(mock.Mock(), - self.conn_info) - client_calls = [c[0] for c in self.csr.method_calls] - self.assertEqual(expected, client_calls) - self.assertEqual(expected_rollback_steps, self.ipsec_conn.steps) - - def test_create_ipsec_site_connection_with_rollback(self): - """Failure test of IPSec site conn creation that fails and rolls back. - - Simulate a failure in the last create step (making routes for the - peer networks), and ensure that the create steps are called in - order (except for create_static_route), and that the delete - steps are called in reverse order. At the end, there should be no - rollback infromation for the connection. - """ - def fake_route_check_fails(*args, **kwargs): - if args[0] == 'Static Route': - # So that subsequent calls to CSR rest client (for rollback) - # will fake as passing. - self.csr.status = httplib.NO_CONTENT - raise ipsec_driver.CsrResourceCreateFailure(resource=args[0], - which=args[1]) - - with mock.patch.object(ipsec_driver.CiscoCsrIPSecConnection, - '_check_create', - side_effect=fake_route_check_fails): - - expected = ['create_pre_shared_key', - 'create_ike_policy', - 'create_ipsec_policy', - 'create_ipsec_connection', - 'create_static_route', - 'delete_ipsec_connection', - 'delete_ipsec_policy', - 'delete_ike_policy', - 'delete_pre_shared_key'] - self.ipsec_conn.create_ipsec_site_connection(mock.Mock(), - self.conn_info) - client_calls = [c[0] for c in self.csr.method_calls] - self.assertEqual(expected, client_calls) - self.assertEqual([], self.ipsec_conn.steps) - - def test_create_verification_with_error(self): - """Negative test of create check step had failed.""" - self.csr.status = httplib.NOT_FOUND - self.assertRaises(ipsec_driver.CsrResourceCreateFailure, - self.ipsec_conn._check_create, 'name', 'id') - - def test_failure_with_invalid_create_step(self): - """Negative test of invalid create step (programming error).""" - self.ipsec_conn.steps = [] - try: - self.ipsec_conn.do_create_action('bogus', None, '123', 'Bad Step') - except ipsec_driver.CsrResourceCreateFailure: - pass - else: - self.fail('Expected exception with invalid create step') - - def test_failure_with_invalid_delete_step(self): - """Negative test of invalid delete step (programming error).""" - self.ipsec_conn.steps = [ipsec_driver.RollbackStep(action='bogus', - resource_id='123', - title='Bogus Step')] - try: - self.ipsec_conn.do_rollback() - except ipsec_driver.CsrResourceCreateFailure: - pass - else: - self.fail('Expected exception with invalid delete step') - - def test_delete_ipsec_connection(self): - # TODO(pcm) implement - pass - - -class TestCiscoCsrIPsecConnectionCreateTransforms(base.BaseTestCase): - - """Verifies that config info is prepared/transformed correctly.""" - - def setUp(self): - super(TestCiscoCsrIPsecConnectionCreateTransforms, self).setUp() - self.conn_info = { - u'id': '123', - u'status': constants.PENDING_CREATE, - u'admin_state_up': True, - 'psk': 'secret', - 'peer_address': '192.168.1.2', - 'peer_cidrs': ['10.1.0.0/24', '10.2.0.0/24'], - 'mtu': 1500, - 'ike_policy': {'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'pfs': 'Group5', - 'ike_version': 'v1', - 'lifetime_units': 'seconds', - 'lifetime_value': 3600}, - 'ipsec_policy': {'transform_protocol': 'ah', - 'encryption_algorithm': 'aes-128', - 'auth_algorithm': 'sha1', - 'pfs': 'group5', - 'lifetime_units': 'seconds', - 'lifetime_value': 3600}, - 'cisco': {'site_conn_id': 'Tunnel0', - 'ike_policy_id': 222, - 'ipsec_policy_id': 333, - # TODO(pcm) get from vpnservice['external_ip'] - 'router_public_ip': '172.24.4.23'} - } - self.csr = mock.Mock(spec=csr_client.CsrRestClient) - self.csr.tunnel_ip = '172.24.4.23' - self.ipsec_conn = ipsec_driver.CiscoCsrIPSecConnection(self.conn_info, - self.csr) - - def test_invalid_attribute(self): - """Negative test of unknown attribute - programming error.""" - self.assertRaises(ipsec_driver.CsrDriverMismatchError, - self.ipsec_conn.translate_dialect, - 'ike_policy', 'unknown_attr', self.conn_info) - - def test_driver_unknown_mapping(self): - """Negative test of service driver providing unknown value to map.""" - self.conn_info['ike_policy']['pfs'] = "unknown_value" - self.assertRaises(ipsec_driver.CsrUnknownMappingError, - self.ipsec_conn.translate_dialect, - 'ike_policy', 'pfs', self.conn_info['ike_policy']) - - def test_psk_create_info(self): - """Ensure that pre-shared key info is created correctly.""" - expected = {u'keyring-name': '123', - u'pre-shared-key-list': [ - {u'key': 'secret', - u'encrypted': False, - u'peer-address': '192.168.1.2'}]} - psk_id = self.conn_info['id'] - psk_info = self.ipsec_conn.create_psk_info(psk_id, self.conn_info) - self.assertEqual(expected, psk_info) - - def test_create_ike_policy_info(self): - """Ensure that IKE policy info is mapped/created correctly.""" - expected = {u'priority-id': 222, - u'encryption': u'aes', - u'hash': u'sha', - u'dhGroup': 5, - u'version': u'v1', - u'lifetime': 3600} - policy_id = self.conn_info['cisco']['ike_policy_id'] - policy_info = self.ipsec_conn.create_ike_policy_info(policy_id, - self.conn_info) - self.assertEqual(expected, policy_info) - - def test_create_ike_policy_info_different_encryption(self): - """Ensure that IKE policy info is mapped/created correctly.""" - self.conn_info['ike_policy']['encryption_algorithm'] = 'aes-192' - expected = {u'priority-id': 222, - u'encryption': u'aes192', - u'hash': u'sha', - u'dhGroup': 5, - u'version': u'v1', - u'lifetime': 3600} - policy_id = self.conn_info['cisco']['ike_policy_id'] - policy_info = self.ipsec_conn.create_ike_policy_info(policy_id, - self.conn_info) - self.assertEqual(expected, policy_info) - - def test_create_ike_policy_info_non_defaults(self): - """Ensure that IKE policy info with different values.""" - self.conn_info['ike_policy'] = { - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-256', - 'pfs': 'Group14', - 'ike_version': 'v1', - 'lifetime_units': 'seconds', - 'lifetime_value': 60 - } - expected = {u'priority-id': 222, - u'encryption': u'aes256', - u'hash': u'sha', - u'dhGroup': 14, - u'version': u'v1', - u'lifetime': 60} - policy_id = self.conn_info['cisco']['ike_policy_id'] - policy_info = self.ipsec_conn.create_ike_policy_info(policy_id, - self.conn_info) - self.assertEqual(expected, policy_info) - - def test_ipsec_policy_info(self): - """Ensure that IPSec policy info is mapped/created correctly. - - Note: That although the default for anti-replay-window-size on the - CSR is 64, we force it to disabled, for OpenStack use. - """ - expected = {u'policy-id': 333, - u'protection-suite': { - u'esp-encryption': u'esp-aes', - u'esp-authentication': u'esp-sha-hmac', - u'ah': u'ah-sha-hmac' - }, - u'lifetime-sec': 3600, - u'pfs': u'group5', - u'anti-replay-window-size': u'disable'} - ipsec_policy_id = self.conn_info['cisco']['ipsec_policy_id'] - policy_info = self.ipsec_conn.create_ipsec_policy_info(ipsec_policy_id, - self.conn_info) - self.assertEqual(expected, policy_info) - - def test_ipsec_policy_info_different_encryption(self): - """Create IPSec policy with different settings.""" - self.conn_info['ipsec_policy']['transform_protocol'] = 'ah-esp' - self.conn_info['ipsec_policy']['encryption_algorithm'] = 'aes-192' - expected = {u'policy-id': 333, - u'protection-suite': { - u'esp-encryption': u'esp-192-aes', - u'esp-authentication': u'esp-sha-hmac', - u'ah': u'ah-sha-hmac' - }, - u'lifetime-sec': 3600, - u'pfs': u'group5', - u'anti-replay-window-size': u'disable'} - ipsec_policy_id = self.conn_info['cisco']['ipsec_policy_id'] - policy_info = self.ipsec_conn.create_ipsec_policy_info(ipsec_policy_id, - self.conn_info) - self.assertEqual(expected, policy_info) - - def test_ipsec_policy_info_non_defaults(self): - """Create/map IPSec policy info with different values.""" - self.conn_info['ipsec_policy'] = {'transform_protocol': 'esp', - 'encryption_algorithm': '3des', - 'auth_algorithm': 'sha1', - 'pfs': 'group14', - 'lifetime_units': 'seconds', - 'lifetime_value': 120, - 'anti-replay-window-size': 'disable'} - expected = {u'policy-id': 333, - u'protection-suite': { - u'esp-encryption': u'esp-3des', - u'esp-authentication': u'esp-sha-hmac' - }, - u'lifetime-sec': 120, - u'pfs': u'group14', - u'anti-replay-window-size': u'disable'} - ipsec_policy_id = self.conn_info['cisco']['ipsec_policy_id'] - policy_info = self.ipsec_conn.create_ipsec_policy_info(ipsec_policy_id, - self.conn_info) - self.assertEqual(expected, policy_info) - - def test_site_connection_info(self): - """Ensure site-to-site connection info is created/mapped correctly.""" - expected = {u'vpn-interface-name': 'Tunnel0', - u'ipsec-policy-id': 333, - u'local-device': { - u'ip-address': u'GigabitEthernet3', - u'tunnel-ip-address': '172.24.4.23' - }, - u'remote-device': { - u'tunnel-ip-address': '192.168.1.2' - }, - u'mtu': 1500} - ipsec_policy_id = self.conn_info['cisco']['ipsec_policy_id'] - site_conn_id = self.conn_info['cisco']['site_conn_id'] - conn_info = self.ipsec_conn.create_site_connection_info( - site_conn_id, ipsec_policy_id, self.conn_info) - self.assertEqual(expected, conn_info) - - def test_static_route_info(self): - """Create static route info for peer CIDRs.""" - expected = [('10.1.0.0_24_Tunnel0', - {u'destination-network': '10.1.0.0/24', - u'outgoing-interface': 'Tunnel0'}), - ('10.2.0.0_24_Tunnel0', - {u'destination-network': '10.2.0.0/24', - u'outgoing-interface': 'Tunnel0'})] -# self.driver.csr.make_route_id.side_effect = ['10.1.0.0_24_Tunnel0', -# '10.2.0.0_24_Tunnel0'] - site_conn_id = self.conn_info['cisco']['site_conn_id'] - routes_info = self.ipsec_conn.create_routes_info(site_conn_id, - self.conn_info) - self.assertEqual(2, len(routes_info)) - self.assertEqual(expected, routes_info) - - -class TestCiscoCsrIPsecDeviceDriverSyncStatuses(base.BaseTestCase): - - """Test status/state of services and connections, after sync.""" - - def setUp(self): - super(TestCiscoCsrIPsecDeviceDriverSyncStatuses, self).setUp() - for klass in ['neutron.common.rpc_compat.create_connection', - 'neutron.context.get_admin_context_without_session', - 'neutron.openstack.common.' - 'loopingcall.FixedIntervalLoopingCall']: - mock.patch(klass).start() - self.context = context.Context('some_user', 'some_tenant') - self.agent = mock.Mock() - conf_patch = mock.patch('oslo.config.cfg.CONF').start() - conf_patch.config_file = ['dummy'] - self.config_load = mock.patch(FIND_CFG_FOR_CSRS).start() - self.config_load.return_value = {'1.1.1.1': {'rest_mgmt': '2.2.2.2', - 'tunnel_ip': '1.1.1.3', - 'username': 'pe', - 'password': 'password', - 'timeout': 120}} - self.driver = ipsec_driver.CiscoCsrIPsecDriver(self.agent, FAKE_HOST) - self.driver.agent_rpc = mock.Mock() - self.conn_create = mock.patch.object( - ipsec_driver.CiscoCsrIPSecConnection, - 'create_ipsec_site_connection').start() - self.conn_delete = mock.patch.object( - ipsec_driver.CiscoCsrIPSecConnection, - 'delete_ipsec_site_connection').start() - self.admin_state = mock.patch.object( - ipsec_driver.CiscoCsrIPSecConnection, - 'set_admin_state').start() - self.csr = mock.Mock() - self.driver.csrs['1.1.1.1'] = self.csr - self.service123_data = {u'id': u'123', - u'status': constants.DOWN, - u'admin_state_up': False, - u'external_ip': u'1.1.1.1'} - self.conn1_data = {u'id': u'1', - u'status': constants.ACTIVE, - u'admin_state_up': True, - u'mtu': 1500, - u'psk': u'secret', - u'peer_address': '192.168.1.2', - u'peer_cidrs': ['10.1.0.0/24', '10.2.0.0/24'], - u'ike_policy': { - u'auth_algorithm': u'sha1', - u'encryption_algorithm': u'aes-128', - u'pfs': u'Group5', - u'ike_version': u'v1', - u'lifetime_units': u'seconds', - u'lifetime_value': 3600}, - u'ipsec_policy': { - u'transform_protocol': u'ah', - u'encryption_algorithm': u'aes-128', - u'auth_algorithm': u'sha1', - u'pfs': u'group5', - u'lifetime_units': u'seconds', - u'lifetime_value': 3600}, - u'cisco': {u'site_conn_id': u'Tunnel0'}} - - # NOTE: For sync, there is mark (trivial), update (tested), - # sweep (tested), and report(tested) phases. - - def test_update_ipsec_connection_create_notify(self): - """Notified of connection create request - create.""" - # Make the (existing) service - self.driver.create_vpn_service(self.service123_data) - conn_data = copy.deepcopy(self.conn1_data) - conn_data[u'status'] = constants.PENDING_CREATE - - connection = self.driver.update_connection(self.context, - u'123', conn_data) - self.assertFalse(connection.is_dirty) - self.assertEqual(u'Tunnel0', connection.tunnel) - self.assertEqual(constants.PENDING_CREATE, connection.last_status) - self.assertEqual(1, self.conn_create.call_count) - - def test_detect_no_change_to_ipsec_connection(self): - """No change to IPSec connection - nop.""" - # Make existing service, and connection that was active - vpn_service = self.driver.create_vpn_service(self.service123_data) - connection = vpn_service.create_connection(self.conn1_data) - - self.assertFalse(connection.check_for_changes(self.conn1_data)) - - def test_detect_state_only_change_to_ipsec_connection(self): - """Only IPSec connection state changed - update.""" - # Make existing service, and connection that was active - vpn_service = self.driver.create_vpn_service(self.service123_data) - connection = vpn_service.create_connection(self.conn1_data) - - conn_data = copy.deepcopy(self.conn1_data) - conn_data[u'admin_state_up'] = False - self.assertFalse(connection.check_for_changes(conn_data)) - - def test_detect_non_state_change_to_ipsec_connection(self): - """Connection change instead of/in addition to state - update.""" - # Make existing service, and connection that was active - vpn_service = self.driver.create_vpn_service(self.service123_data) - connection = vpn_service.create_connection(self.conn1_data) - - conn_data = copy.deepcopy(self.conn1_data) - conn_data[u'ipsec_policy'][u'encryption_algorithm'] = u'aes-256' - self.assertTrue(connection.check_for_changes(conn_data)) - - def test_update_ipsec_connection_changed_admin_down(self): - """Notified of connection state change - update. - - For a connection that was previously created, expect to - force connection down on an admin down (only) change. - """ - - # Make existing service, and connection that was active - vpn_service = self.driver.create_vpn_service(self.service123_data) - connection = vpn_service.create_connection(self.conn1_data) - - # Simulate that notification of connection update received - self.driver.mark_existing_connections_as_dirty() - # Modify the connection data for the 'sync' - conn_data = copy.deepcopy(self.conn1_data) - conn_data[u'admin_state_up'] = False - - connection = self.driver.update_connection(self.context, - '123', conn_data) - self.assertFalse(connection.is_dirty) - self.assertEqual(u'Tunnel0', connection.tunnel) - self.assertEqual(constants.ACTIVE, connection.last_status) - self.assertFalse(self.conn_create.called) - self.assertFalse(connection.is_admin_up) - self.assertTrue(connection.forced_down) - self.assertEqual(1, self.admin_state.call_count) - - def test_update_ipsec_connection_changed_config(self): - """Notified of connection changing config - update. - - Goal here is to detect that the connection is deleted and then - created, but not that the specific values have changed, so picking - arbitrary value (MTU). - """ - # Make existing service, and connection that was active - vpn_service = self.driver.create_vpn_service(self.service123_data) - connection = vpn_service.create_connection(self.conn1_data) - - # Simulate that notification of connection update received - self.driver.mark_existing_connections_as_dirty() - # Modify the connection data for the 'sync' - conn_data = copy.deepcopy(self.conn1_data) - conn_data[u'mtu'] = 9200 - - connection = self.driver.update_connection(self.context, - '123', conn_data) - self.assertFalse(connection.is_dirty) - self.assertEqual(u'Tunnel0', connection.tunnel) - self.assertEqual(constants.ACTIVE, connection.last_status) - self.assertEqual(1, self.conn_create.call_count) - self.assertEqual(1, self.conn_delete.call_count) - self.assertTrue(connection.is_admin_up) - self.assertFalse(connection.forced_down) - self.assertFalse(self.admin_state.called) - - def test_update_of_unknown_ipsec_connection(self): - """Notified of update of unknown connection - create. - - Occurs if agent restarts and receives a notification of change - to connection, but has no previous record of the connection. - Result will be to rebuild the connection. - """ - # Will have previously created service, but don't know of connection - self.driver.create_vpn_service(self.service123_data) - - # Simulate that notification of connection update received - self.driver.mark_existing_connections_as_dirty() - conn_data = copy.deepcopy(self.conn1_data) - conn_data[u'status'] = constants.DOWN - - connection = self.driver.update_connection(self.context, - u'123', conn_data) - self.assertFalse(connection.is_dirty) - self.assertEqual(u'Tunnel0', connection.tunnel) - self.assertEqual(constants.DOWN, connection.last_status) - self.assertEqual(1, self.conn_create.call_count) - self.assertTrue(connection.is_admin_up) - self.assertFalse(connection.forced_down) - self.assertFalse(self.admin_state.called) - - def test_update_missing_connection_admin_down(self): - """Connection not present is in admin down state - nop. - - If the agent has restarted, and a sync notification occurs with - a connection that is in admin down state, recreate the connection, - but indicate that the connection is down. - """ - # Make existing service, but no connection - self.driver.create_vpn_service(self.service123_data) - - conn_data = copy.deepcopy(self.conn1_data) - conn_data.update({u'status': constants.DOWN, - u'admin_state_up': False}) - connection = self.driver.update_connection(self.context, - u'123', conn_data) - self.assertIsNotNone(connection) - self.assertFalse(connection.is_dirty) - self.assertEqual(1, self.conn_create.call_count) - self.assertFalse(connection.is_admin_up) - self.assertTrue(connection.forced_down) - self.assertEqual(1, self.admin_state.call_count) - - def test_update_connection_admin_up(self): - """Connection updated to admin up state - record.""" - # Make existing service, and connection that was admin down - conn_data = copy.deepcopy(self.conn1_data) - conn_data.update({u'status': constants.DOWN, u'admin_state_up': False}) - service_data = {u'id': u'123', - u'status': constants.DOWN, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn_data]} - self.driver.update_service(self.context, service_data) - - # Simulate that notification of connection update received - self.driver.mark_existing_connections_as_dirty() - # Now simulate that the notification shows the connection admin up - new_conn_data = copy.deepcopy(conn_data) - new_conn_data[u'admin_state_up'] = True - - connection = self.driver.update_connection(self.context, - u'123', new_conn_data) - self.assertFalse(connection.is_dirty) - self.assertEqual(u'Tunnel0', connection.tunnel) - self.assertEqual(constants.DOWN, connection.last_status) - self.assertTrue(connection.is_admin_up) - self.assertFalse(connection.forced_down) - self.assertEqual(2, self.admin_state.call_count) - - def test_update_for_vpn_service_create(self): - """Creation of new IPSec connection on new VPN service - create. - - Service will be created and marked as 'clean', and update - processing for connection will occur (create). - """ - conn_data = copy.deepcopy(self.conn1_data) - conn_data[u'status'] = constants.PENDING_CREATE - service_data = {u'id': u'123', - u'status': constants.PENDING_CREATE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn_data]} - vpn_service = self.driver.update_service(self.context, service_data) - self.assertFalse(vpn_service.is_dirty) - self.assertEqual(constants.PENDING_CREATE, vpn_service.last_status) - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - self.assertFalse(connection.is_dirty) - self.assertEqual(u'Tunnel0', connection.tunnel) - self.assertEqual(constants.PENDING_CREATE, connection.last_status) - self.assertEqual(1, self.conn_create.call_count) - self.assertTrue(connection.is_admin_up) - self.assertFalse(connection.forced_down) - self.assertFalse(self.admin_state.called) - - def test_update_for_new_connection_on_existing_service(self): - """Creating a new IPSec connection on an existing service.""" - # Create the service before testing, and mark it dirty - prev_vpn_service = self.driver.create_vpn_service(self.service123_data) - self.driver.mark_existing_connections_as_dirty() - conn_data = copy.deepcopy(self.conn1_data) - conn_data[u'status'] = constants.PENDING_CREATE - service_data = {u'id': u'123', - u'status': constants.ACTIVE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn_data]} - vpn_service = self.driver.update_service(self.context, service_data) - # Should reuse the entry and update the status - self.assertEqual(prev_vpn_service, vpn_service) - self.assertFalse(vpn_service.is_dirty) - self.assertEqual(constants.ACTIVE, vpn_service.last_status) - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - self.assertFalse(connection.is_dirty) - self.assertEqual(u'Tunnel0', connection.tunnel) - self.assertEqual(constants.PENDING_CREATE, connection.last_status) - self.assertEqual(1, self.conn_create.call_count) - - def test_update_for_vpn_service_with_one_unchanged_connection(self): - """Existing VPN service and IPSec connection without any changes - nop. - - Service and connection will be marked clean. No processing for - either, as there are no changes. - """ - # Create a service and add in a connection that is active - prev_vpn_service = self.driver.create_vpn_service(self.service123_data) - prev_vpn_service.create_connection(self.conn1_data) - - self.driver.mark_existing_connections_as_dirty() - # Create notification with conn unchanged and service already created - service_data = {u'id': u'123', - u'status': constants.ACTIVE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [self.conn1_data]} - vpn_service = self.driver.update_service(self.context, service_data) - # Should reuse the entry and update the status - self.assertEqual(prev_vpn_service, vpn_service) - self.assertFalse(vpn_service.is_dirty) - self.assertEqual(constants.ACTIVE, vpn_service.last_status) - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - self.assertFalse(connection.is_dirty) - self.assertEqual(u'Tunnel0', connection.tunnel) - self.assertEqual(constants.ACTIVE, connection.last_status) - self.assertFalse(self.conn_create.called) - - def test_update_service_admin_down(self): - """VPN service updated to admin down state - force all down. - - If service is down, then all connections are forced down. - """ - # Create an "existing" service, prior to notification - prev_vpn_service = self.driver.create_vpn_service(self.service123_data) - - self.driver.mark_existing_connections_as_dirty() - service_data = {u'id': u'123', - u'status': constants.DOWN, - u'external_ip': u'1.1.1.1', - u'admin_state_up': False, - u'ipsec_conns': [self.conn1_data]} - vpn_service = self.driver.update_service(self.context, service_data) - self.assertEqual(prev_vpn_service, vpn_service) - self.assertFalse(vpn_service.is_dirty) - self.assertFalse(vpn_service.is_admin_up) - self.assertEqual(constants.DOWN, vpn_service.last_status) - conn = vpn_service.get_connection(u'1') - self.assertIsNotNone(conn) - self.assertFalse(conn.is_dirty) - self.assertTrue(conn.forced_down) - self.assertTrue(conn.is_admin_up) - - def test_update_new_service_admin_down(self): - """Unknown VPN service updated to admin down state - nop. - - Can happen if agent restarts and then gets its first notificaiton - of a service that is in the admin down state. Structures will be - created, but forced down. - """ - service_data = {u'id': u'123', - u'status': constants.DOWN, - u'external_ip': u'1.1.1.1', - u'admin_state_up': False, - u'ipsec_conns': [self.conn1_data]} - vpn_service = self.driver.update_service(self.context, service_data) - self.assertIsNotNone(vpn_service) - self.assertFalse(vpn_service.is_dirty) - self.assertFalse(vpn_service.is_admin_up) - self.assertEqual(constants.DOWN, vpn_service.last_status) - conn = vpn_service.get_connection(u'1') - self.assertIsNotNone(conn) - self.assertFalse(conn.is_dirty) - self.assertTrue(conn.forced_down) - self.assertTrue(conn.is_admin_up) - - def test_update_service_admin_up(self): - """VPN service updated to admin up state - restore. - - If service is up now, then connections that are admin up will come - up and connections that are admin down, will remain down. - """ - # Create an "existing" service, prior to notification - prev_vpn_service = self.driver.create_vpn_service(self.service123_data) - self.driver.mark_existing_connections_as_dirty() - conn_data1 = {u'id': u'1', u'status': constants.DOWN, - u'admin_state_up': False, - u'cisco': {u'site_conn_id': u'Tunnel0'}} - conn_data2 = {u'id': u'2', u'status': constants.ACTIVE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel1'}} - service_data = {u'id': u'123', - u'status': constants.DOWN, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn_data1, conn_data2]} - vpn_service = self.driver.update_service(self.context, service_data) - self.assertEqual(prev_vpn_service, vpn_service) - self.assertFalse(vpn_service.is_dirty) - self.assertTrue(vpn_service.is_admin_up) - self.assertEqual(constants.DOWN, vpn_service.last_status) - conn1 = vpn_service.get_connection(u'1') - self.assertIsNotNone(conn1) - self.assertFalse(conn1.is_dirty) - self.assertTrue(conn1.forced_down) - self.assertFalse(conn1.is_admin_up) - conn2 = vpn_service.get_connection(u'2') - self.assertIsNotNone(conn2) - self.assertFalse(conn2.is_dirty) - self.assertFalse(conn2.forced_down) - self.assertTrue(conn2.is_admin_up) - - def test_update_of_unknown_service_create(self): - """Create of VPN service that is currently unknown - record. - - If agent is restarted or user changes VPN service to admin up, the - notification may contain a VPN service with an IPSec connection - that is not in PENDING_CREATE state. - """ - conn_data = {u'id': u'1', u'status': constants.DOWN, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel0'}} - service_data = {u'id': u'123', - u'status': constants.ACTIVE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn_data]} - vpn_service = self.driver.update_service(self.context, service_data) - self.assertFalse(vpn_service.is_dirty) - self.assertEqual(constants.ACTIVE, vpn_service.last_status) - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - self.assertFalse(connection.is_dirty) - self.assertEqual(u'Tunnel0', connection.tunnel) - self.assertEqual(constants.DOWN, connection.last_status) - self.assertEqual(1, self.conn_create.call_count) - - def test_update_service_create_no_csr(self): - """Failure test of sync of service that is not on CSR - ignore. - - Ignore the VPN service and its IPSec connection(s) notifications for - which there is no corresponding Cisco CSR. - """ - conn_data = {u'id': u'1', u'status': constants.PENDING_CREATE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel0'}} - service_data = {u'id': u'123', - u'status': constants.PENDING_CREATE, - u'external_ip': u'2.2.2.2', - u'admin_state_up': True, - u'ipsec_conns': [conn_data]} - vpn_service = self.driver.update_service(self.context, service_data) - self.assertIsNone(vpn_service) - - def _check_connection_for_service(self, count, vpn_service): - """Helper to check the connection information for a service.""" - connection = vpn_service.get_connection(u'%d' % count) - self.assertIsNotNone(connection, "for connection %d" % count) - self.assertFalse(connection.is_dirty, "for connection %d" % count) - self.assertEqual(u'Tunnel%d' % count, connection.tunnel, - "for connection %d" % count) - self.assertEqual(constants.PENDING_CREATE, connection.last_status, - "for connection %d" % count) - return count + 1 - - def notification_for_two_services_with_two_conns(self): - """Helper used by tests to create two services, each with two conns.""" - conn1_data = {u'id': u'1', u'status': constants.PENDING_CREATE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel1'}} - conn2_data = {u'id': u'2', u'status': constants.PENDING_CREATE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel2'}} - service1_data = {u'id': u'123', - u'status': constants.PENDING_CREATE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn1_data, conn2_data]} - conn3_data = {u'id': u'3', u'status': constants.PENDING_CREATE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel3'}} - conn4_data = {u'id': u'4', u'status': constants.PENDING_CREATE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel4'}} - service2_data = {u'id': u'456', - u'status': constants.PENDING_CREATE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn3_data, conn4_data]} - return service1_data, service2_data - - def test_create_two_connections_on_two_services(self): - """High level test of multiple VPN services with connections.""" - # Build notification message - (service1_data, - service2_data) = self.notification_for_two_services_with_two_conns() - # Simulate plugin returning notifcation, when requested - self.driver.agent_rpc.get_vpn_services_on_host.return_value = [ - service1_data, service2_data] - vpn_services = self.driver.update_all_services_and_connections( - self.context) - self.assertEqual(2, len(vpn_services)) - count = 1 - for vpn_service in vpn_services: - self.assertFalse(vpn_service.is_dirty, - "for service %s" % vpn_service) - self.assertEqual(constants.PENDING_CREATE, vpn_service.last_status, - "for service %s" % vpn_service) - count = self._check_connection_for_service(count, vpn_service) - count = self._check_connection_for_service(count, vpn_service) - self.assertEqual(4, self.conn_create.call_count) - - def test_sweep_connection_marked_as_clean(self): - """Sync updated connection - no action.""" - # Create a service and connection - vpn_service = self.driver.create_vpn_service(self.service123_data) - connection = vpn_service.create_connection(self.conn1_data) - self.driver.mark_existing_connections_as_dirty() - # Simulate that the update phase visted both of them - vpn_service.is_dirty = False - connection.is_dirty = False - self.driver.remove_unknown_connections(self.context) - vpn_service = self.driver.service_state.get(u'123') - self.assertIsNotNone(vpn_service) - self.assertFalse(vpn_service.is_dirty) - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - self.assertFalse(connection.is_dirty) - - def test_sweep_connection_dirty(self): - """Sync did not update connection - delete.""" - # Create a service and connection - vpn_service = self.driver.create_vpn_service(self.service123_data) - vpn_service.create_connection(self.conn1_data) - self.driver.mark_existing_connections_as_dirty() - # Simulate that the update phase only visited the service - vpn_service.is_dirty = False - self.driver.remove_unknown_connections(self.context) - vpn_service = self.driver.service_state.get(u'123') - self.assertIsNotNone(vpn_service) - self.assertFalse(vpn_service.is_dirty) - connection = vpn_service.get_connection(u'1') - self.assertIsNone(connection) - self.assertEqual(1, self.conn_delete.call_count) - - def test_sweep_service_dirty(self): - """Sync did not update service - delete it and all conns.""" - # Create a service and connection - vpn_service = self.driver.create_vpn_service(self.service123_data) - vpn_service.create_connection(self.conn1_data) - self.driver.mark_existing_connections_as_dirty() - # Both the service and the connection are still 'dirty' - self.driver.remove_unknown_connections(self.context) - self.assertIsNone(self.driver.service_state.get(u'123')) - self.assertEqual(1, self.conn_delete.call_count) - - def test_sweep_multiple_services(self): - """One service and conn updated, one service and conn not.""" - # Create two services, each with a connection - vpn_service1 = self.driver.create_vpn_service(self.service123_data) - vpn_service1.create_connection(self.conn1_data) - service456_data = {u'id': u'456', - u'status': constants.ACTIVE, - u'admin_state_up': False, - u'external_ip': u'1.1.1.1'} - conn2_data = {u'id': u'2', u'status': constants.ACTIVE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel0'}} - prev_vpn_service2 = self.driver.create_vpn_service(service456_data) - prev_connection2 = prev_vpn_service2.create_connection(conn2_data) - self.driver.mark_existing_connections_as_dirty() - # Simulate that the update phase visited the first service and conn - prev_vpn_service2.is_dirty = False - prev_connection2.is_dirty = False - self.driver.remove_unknown_connections(self.context) - self.assertIsNone(self.driver.service_state.get(u'123')) - vpn_service2 = self.driver.service_state.get(u'456') - self.assertEqual(prev_vpn_service2, vpn_service2) - self.assertFalse(vpn_service2.is_dirty) - connection2 = vpn_service2.get_connection(u'2') - self.assertEqual(prev_connection2, connection2) - self.assertFalse(connection2.is_dirty) - self.assertEqual(1, self.conn_delete.call_count) - - def simulate_mark_update_sweep_for_service_with_conn(self, service_state, - connection_state): - """Create internal structures for single service with connection. - - The service and connection will be marked as clean, and since - none are being deleted, the service's connections_removed - attribute will remain false. - """ - # Simulate that we have done mark, update, and sweep. - conn_data = {u'id': u'1', u'status': connection_state, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel0'}} - service_data = {u'id': u'123', - u'status': service_state, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn_data]} - return self.driver.update_service(self.context, service_data) - - def test_report_fragment_connection_created(self): - """Generate report section for a created connection.""" - # Prepare service and connection in PENDING_CREATE state - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.PENDING_CREATE, constants.PENDING_CREATE) - # Simulate that CSR has reported the connection is still up - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel0', u'UP-ACTIVE'), ] - - # Get the statuses for connections existing on CSR - tunnels = vpn_service.get_ipsec_connections_status() - self.assertEqual({u'Tunnel0': constants.ACTIVE}, tunnels) - - # Check that there is a status for this connection - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - current_status = connection.find_current_status_in(tunnels) - self.assertEqual(constants.ACTIVE, current_status) - - # Create report fragment due to change - self.assertNotEqual(connection.last_status, current_status) - report_frag = connection.update_status_and_build_report(current_status) - self.assertEqual(current_status, connection.last_status) - expected = {'1': {'status': constants.ACTIVE, - 'updated_pending_status': True}} - self.assertEqual(expected, report_frag) - - def test_report_fragment_connection_unchanged_status(self): - """No report section generated for a created connection.""" - # Prepare service and connection in ACTIVE state - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.ACTIVE, constants.ACTIVE) - # Simulate that CSR has reported the connection is up - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel0', u'UP-IDLE'), ] - - # Get the statuses for connections existing on CSR - tunnels = vpn_service.get_ipsec_connections_status() - self.assertEqual({u'Tunnel0': constants.ACTIVE}, tunnels) - - # Check that there is a status for this connection - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - current_status = connection.find_current_status_in(tunnels) - self.assertEqual(constants.ACTIVE, current_status) - - # Should be no report, as no change - self.assertEqual(connection.last_status, current_status) - report_frag = connection.update_status_and_build_report(current_status) - self.assertEqual(current_status, connection.last_status) - self.assertEqual({}, report_frag) - - def test_report_fragment_connection_changed_status(self): - """Generate report section for connection with changed state.""" - # Prepare service in ACTIVE state and connection in DOWN state - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.ACTIVE, constants.DOWN) - # Simulate that CSR has reported the connection is still up - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel0', u'UP-NO-IKE'), ] - - # Get the statuses for connections existing on CSR - tunnels = vpn_service.get_ipsec_connections_status() - self.assertEqual({u'Tunnel0': constants.ACTIVE}, tunnels) - - # Check that there is a status for this connection - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - current_status = connection.find_current_status_in(tunnels) - self.assertEqual(constants.ACTIVE, current_status) - - # Create report fragment due to change - self.assertNotEqual(connection.last_status, current_status) - report_frag = connection.update_status_and_build_report(current_status) - self.assertEqual(current_status, connection.last_status) - expected = {'1': {'status': constants.ACTIVE, - 'updated_pending_status': False}} - self.assertEqual(expected, report_frag) - - def test_report_fragment_connection_failed_create(self): - """Failure test of report fragment for conn that failed creation. - - Normally, without any status from the CSR, the connection report would - be skipped, but we need to report back failures. - """ - # Prepare service and connection in PENDING_CREATE state - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.PENDING_CREATE, constants.PENDING_CREATE) - # Simulate that CSR does NOT report the status (no tunnel) - self.csr.read_tunnel_statuses.return_value = [] - - # Get the statuses for connections existing on CSR - tunnels = vpn_service.get_ipsec_connections_status() - self.assertEqual({}, tunnels) - - # Check that there is a status for this connection - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - current_status = connection.find_current_status_in(tunnels) - self.assertEqual(constants.ERROR, current_status) - - # Create report fragment due to change - self.assertNotEqual(connection.last_status, current_status) - report_frag = connection.update_status_and_build_report(current_status) - self.assertEqual(current_status, connection.last_status) - expected = {'1': {'status': constants.ERROR, - 'updated_pending_status': True}} - self.assertEqual(expected, report_frag) - - def test_report_fragment_connection_admin_down(self): - """Report for a connection that is in admin down state.""" - # Prepare service and connection with previous status ACTIVE, but - # with connection admin down - conn_data = {u'id': u'1', u'status': constants.ACTIVE, - u'admin_state_up': False, - u'cisco': {u'site_conn_id': u'Tunnel0'}} - service_data = {u'id': u'123', - u'status': constants.ACTIVE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn_data]} - vpn_service = self.driver.update_service(self.context, service_data) - # Tunnel would have been deleted, so simulate no status - self.csr.read_tunnel_statuses.return_value = [] - - connection = vpn_service.get_connection(u'1') - self.assertIsNotNone(connection) - self.assertTrue(connection.forced_down) - self.assertEqual(constants.ACTIVE, connection.last_status) - - # Create report fragment due to change - report_frag = self.driver.build_report_for_connections_on(vpn_service) - self.assertEqual(constants.DOWN, connection.last_status) - expected = {'1': {'status': constants.DOWN, - 'updated_pending_status': False}} - self.assertEqual(expected, report_frag) - - def test_report_fragment_two_connections(self): - """Generate report fragment for two connections on a service.""" - # Prepare service with two connections, one ACTIVE, one DOWN - conn1_data = {u'id': u'1', u'status': constants.DOWN, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel1'}} - conn2_data = {u'id': u'2', u'status': constants.ACTIVE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel2'}} - service_data = {u'id': u'123', - u'status': constants.ACTIVE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn1_data, conn2_data]} - vpn_service = self.driver.update_service(self.context, service_data) - # Simulate that CSR has reported the connections with diff status - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel1', u'UP-IDLE'), (u'Tunnel2', u'DOWN-NEGOTIATING')] - - # Get the report fragments for the connections - report_frag = self.driver.build_report_for_connections_on(vpn_service) - expected = {u'1': {u'status': constants.ACTIVE, - u'updated_pending_status': False}, - u'2': {u'status': constants.DOWN, - u'updated_pending_status': False}} - self.assertEqual(expected, report_frag) - - def test_report_service_create(self): - """VPN service and IPSec connection created - report.""" - # Simulate creation of the service and connection - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.PENDING_CREATE, constants.PENDING_CREATE) - # Simulate that the CSR has created the connection - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel0', u'UP-ACTIVE'), ] - - report = self.driver.build_report_for_service(vpn_service) - expected_report = { - u'id': u'123', - u'updated_pending_status': True, - u'status': constants.ACTIVE, - u'ipsec_site_connections': { - u'1': {u'status': constants.ACTIVE, - u'updated_pending_status': True} - } - } - self.assertEqual(expected_report, report) - # Check that service and connection statuses are updated - self.assertEqual(constants.ACTIVE, vpn_service.last_status) - self.assertEqual(constants.ACTIVE, - vpn_service.get_connection(u'1').last_status) - - def test_report_service_create_of_first_conn_fails(self): - """VPN service and IPSec conn created, but conn failed - report. - - Since this is the sole IPSec connection on the service, and the - create failed (connection in ERROR state), the VPN service's - status will be set to DOWN. - """ - # Simulate creation of the service and connection - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.PENDING_CREATE, constants.PENDING_CREATE) - # Simulate that the CSR has no info due to failed create - self.csr.read_tunnel_statuses.return_value = [] - - report = self.driver.build_report_for_service(vpn_service) - expected_report = { - u'id': u'123', - u'updated_pending_status': True, - u'status': constants.DOWN, - u'ipsec_site_connections': { - u'1': {u'status': constants.ERROR, - u'updated_pending_status': True} - } - } - self.assertEqual(expected_report, report) - # Check that service and connection statuses are updated - self.assertEqual(constants.DOWN, vpn_service.last_status) - self.assertEqual(constants.ERROR, - vpn_service.get_connection(u'1').last_status) - - def test_report_connection_created_on_existing_service(self): - """Creating connection on existing service - report.""" - # Simulate existing service and connection create - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.ACTIVE, constants.PENDING_CREATE) - # Simulate that the CSR has created the connection - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel0', u'UP-IDLE'), ] - - report = self.driver.build_report_for_service(vpn_service) - expected_report = { - u'id': u'123', - u'updated_pending_status': False, - u'status': constants.ACTIVE, - u'ipsec_site_connections': { - u'1': {u'status': constants.ACTIVE, - u'updated_pending_status': True} - } - } - self.assertEqual(expected_report, report) - # Check that service and connection statuses are updated - self.assertEqual(constants.ACTIVE, vpn_service.last_status) - self.assertEqual(constants.ACTIVE, - vpn_service.get_connection(u'1').last_status) - - def test_no_report_no_changes(self): - """VPN service with unchanged IPSec connection - no report. - - Note: No report will be generated if the last connection on the - service is deleted. The service (and connection) objects will - have been removed by the sweep operation and thus not reported. - On the plugin, the service should be changed to DOWN. Likewise, - if the service goes to admin down state. - """ - # Simulate an existing service and connection that are ACTIVE - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.ACTIVE, constants.ACTIVE) - # Simulate that the CSR reports the connection still active - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel0', u'UP-ACTIVE'), ] - - report = self.driver.build_report_for_service(vpn_service) - self.assertEqual({}, report) - # Check that service and connection statuses are still same - self.assertEqual(constants.ACTIVE, vpn_service.last_status) - self.assertEqual(constants.ACTIVE, - vpn_service.get_connection(u'1').last_status) - - def test_report_sole_connection_goes_down(self): - """Only connection on VPN service goes down - report. - - In addition to reporting the status change and recording the new - state for the IPSec connection, the VPN service status will be - DOWN. - """ - # Simulate an existing service and connection that are ACTIVE - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.ACTIVE, constants.ACTIVE) - # Simulate that the CSR reports the connection went down - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel0', u'DOWN-NEGOTIATING'), ] - - report = self.driver.build_report_for_service(vpn_service) - expected_report = { - u'id': u'123', - u'updated_pending_status': False, - u'status': constants.DOWN, - u'ipsec_site_connections': { - u'1': {u'status': constants.DOWN, - u'updated_pending_status': False} - } - } - self.assertEqual(expected_report, report) - # Check that service and connection statuses are updated - self.assertEqual(constants.DOWN, vpn_service.last_status) - self.assertEqual(constants.DOWN, - vpn_service.get_connection(u'1').last_status) - - def test_report_sole_connection_comes_up(self): - """Only connection on VPN service comes up - report. - - In addition to reporting the status change and recording the new - state for the IPSec connection, the VPN service status will be - ACTIVE. - """ - # Simulate an existing service and connection that are DOWN - vpn_service = self.simulate_mark_update_sweep_for_service_with_conn( - constants.DOWN, constants.DOWN) - # Simulate that the CSR reports the connection came up - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel0', u'UP-NO-IKE'), ] - - report = self.driver.build_report_for_service(vpn_service) - expected_report = { - u'id': u'123', - u'updated_pending_status': False, - u'status': constants.ACTIVE, - u'ipsec_site_connections': { - u'1': {u'status': constants.ACTIVE, - u'updated_pending_status': False} - } - } - self.assertEqual(expected_report, report) - # Check that service and connection statuses are updated - self.assertEqual(constants.ACTIVE, vpn_service.last_status) - self.assertEqual(constants.ACTIVE, - vpn_service.get_connection(u'1').last_status) - - def test_report_service_with_two_connections_gone_down(self): - """One service with two connections that went down - report. - - Shows the case where all the connections are down, so that the - service should report as DOWN, as well. - """ - # Simulate one service with two ACTIVE connections - conn1_data = {u'id': u'1', u'status': constants.ACTIVE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel1'}} - conn2_data = {u'id': u'2', u'status': constants.ACTIVE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel2'}} - service_data = {u'id': u'123', - u'status': constants.ACTIVE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn1_data, conn2_data]} - vpn_service = self.driver.update_service(self.context, service_data) - # Simulate that the CSR has reported that the connections are DOWN - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel1', u'DOWN-NEGOTIATING'), (u'Tunnel2', u'DOWN')] - - report = self.driver.build_report_for_service(vpn_service) - expected_report = { - u'id': u'123', - u'updated_pending_status': False, - u'status': constants.DOWN, - u'ipsec_site_connections': { - u'1': {u'status': constants.DOWN, - u'updated_pending_status': False}, - u'2': {u'status': constants.DOWN, - u'updated_pending_status': False}} - } - self.assertEqual(expected_report, report) - # Check that service and connection statuses are updated - self.assertEqual(constants.DOWN, vpn_service.last_status) - self.assertEqual(constants.DOWN, - vpn_service.get_connection(u'1').last_status) - self.assertEqual(constants.DOWN, - vpn_service.get_connection(u'2').last_status) - - def test_report_service_with_connection_removed(self): - """One service with two connections where one is removed - report. - - With a connection removed and the other connection unchanged, - normally there would be nothing to report for the connections, but - we need to report any possible change to the service state. In this - case, the service was ACTIVE, but since the only ACTIVE connection - is deleted and the remaining connection is DOWN, the service will - indicate as DOWN. - """ - # Simulate one service with one connection up, one down - conn1_data = {u'id': u'1', u'status': constants.ACTIVE, - u'admin_state_up': True, - u'mtu': 1500, - u'psk': u'secret', - u'peer_address': '192.168.1.2', - u'peer_cidrs': ['10.1.0.0/24', '10.2.0.0/24'], - u'ike_policy': {u'auth_algorithm': u'sha1', - u'encryption_algorithm': u'aes-128', - u'pfs': u'Group5', - u'ike_version': u'v1', - u'lifetime_units': u'seconds', - u'lifetime_value': 3600}, - u'ipsec_policy': {u'transform_protocol': u'ah', - u'encryption_algorithm': u'aes-128', - u'auth_algorithm': u'sha1', - u'pfs': u'group5', - u'lifetime_units': u'seconds', - u'lifetime_value': 3600}, - u'cisco': {u'site_conn_id': u'Tunnel1'}} - conn2_data = {u'id': u'2', u'status': constants.DOWN, - u'admin_state_up': True, - u'mtu': 1500, - u'psk': u'secret', - u'peer_address': '192.168.1.2', - u'peer_cidrs': ['10.1.0.0/24', '10.2.0.0/24'], - u'ike_policy': {u'auth_algorithm': u'sha1', - u'encryption_algorithm': u'aes-128', - u'pfs': u'Group5', - u'ike_version': u'v1', - u'lifetime_units': u'seconds', - u'lifetime_value': 3600}, - u'ipsec_policy': {u'transform_protocol': u'ah', - u'encryption_algorithm': u'aes-128', - u'auth_algorithm': u'sha1', - u'pfs': u'group5', - u'lifetime_units': u'seconds', - u'lifetime_value': 3600}, - u'cisco': {u'site_conn_id': u'Tunnel2'}} - service_data = {u'id': u'123', - u'status': constants.ACTIVE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn1_data, conn2_data]} - vpn_service = self.driver.update_service(self.context, service_data) - self.assertEqual(constants.ACTIVE, vpn_service.last_status) - self.assertEqual(constants.ACTIVE, - vpn_service.get_connection(u'1').last_status) - self.assertEqual(constants.DOWN, - vpn_service.get_connection(u'2').last_status) - - # Simulate that one is deleted - self.driver.mark_existing_connections_as_dirty() - service_data = {u'id': u'123', - u'status': constants.ACTIVE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': True, - u'ipsec_conns': [conn2_data]} - vpn_service = self.driver.update_service(self.context, service_data) - self.driver.remove_unknown_connections(self.context) - self.assertTrue(vpn_service.connections_removed) - self.assertEqual(constants.ACTIVE, vpn_service.last_status) - self.assertIsNone(vpn_service.get_connection(u'1')) - self.assertEqual(constants.DOWN, - vpn_service.get_connection(u'2').last_status) - - # Simulate that only one connection reports and status is unchanged, - # so there will be NO connection info to report. - self.csr.read_tunnel_statuses.return_value = [(u'Tunnel2', u'DOWN')] - report = self.driver.build_report_for_service(vpn_service) - expected_report = { - u'id': u'123', - u'updated_pending_status': False, - u'status': constants.DOWN, - u'ipsec_site_connections': {} - } - self.assertEqual(expected_report, report) - # Check that service and connection statuses are updated - self.assertEqual(constants.DOWN, vpn_service.last_status) - self.assertEqual(constants.DOWN, - vpn_service.get_connection(u'2').last_status) - - def test_report_service_admin_down_with_two_connections(self): - """One service admin down, with two connections - report. - - When the service is admin down, all the connections will report - as DOWN. - """ - # Simulate one service (admin down) with two ACTIVE connections - conn1_data = {u'id': u'1', u'status': constants.ACTIVE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel1'}} - conn2_data = {u'id': u'2', u'status': constants.ACTIVE, - u'admin_state_up': True, - u'cisco': {u'site_conn_id': u'Tunnel2'}} - service_data = {u'id': u'123', - u'status': constants.ACTIVE, - u'external_ip': u'1.1.1.1', - u'admin_state_up': False, - u'ipsec_conns': [conn1_data, conn2_data]} - vpn_service = self.driver.update_service(self.context, service_data) - # Since service admin down, connections will have been deleted - self.csr.read_tunnel_statuses.return_value = [] - - report = self.driver.build_report_for_service(vpn_service) - expected_report = { - u'id': u'123', - u'updated_pending_status': False, - u'status': constants.DOWN, - u'ipsec_site_connections': { - u'1': {u'status': constants.DOWN, - u'updated_pending_status': False}, - u'2': {u'status': constants.DOWN, - u'updated_pending_status': False}} - } - self.assertEqual(expected_report, report) - # Check that service and connection statuses are updated - self.assertEqual(constants.DOWN, vpn_service.last_status) - self.assertEqual(constants.DOWN, - vpn_service.get_connection(u'1').last_status) - self.assertEqual(constants.DOWN, - vpn_service.get_connection(u'2').last_status) - - def test_report_multiple_services(self): - """Status changes for several services - report.""" - # Simulate creation of the service and connection - (service1_data, - service2_data) = self.notification_for_two_services_with_two_conns() - vpn_service1 = self.driver.update_service(self.context, service1_data) - vpn_service2 = self.driver.update_service(self.context, service2_data) - # Simulate that the CSR has created the connections - self.csr.read_tunnel_statuses.return_value = [ - (u'Tunnel1', u'UP-ACTIVE'), (u'Tunnel2', u'DOWN'), - (u'Tunnel3', u'DOWN-NEGOTIATING'), (u'Tunnel4', u'UP-IDLE')] - - report = self.driver.report_status(self.context) - expected_report = [{u'id': u'123', - u'updated_pending_status': True, - u'status': constants.ACTIVE, - u'ipsec_site_connections': { - u'1': {u'status': constants.ACTIVE, - u'updated_pending_status': True}, - u'2': {u'status': constants.DOWN, - u'updated_pending_status': True}} - }, - {u'id': u'456', - u'updated_pending_status': True, - u'status': constants.ACTIVE, - u'ipsec_site_connections': { - u'3': {u'status': constants.DOWN, - u'updated_pending_status': True}, - u'4': {u'status': constants.ACTIVE, - u'updated_pending_status': True}} - }] - self.assertEqual(expected_report, report) - # Check that service and connection statuses are updated - self.assertEqual(constants.ACTIVE, vpn_service1.last_status) - self.assertEqual(constants.ACTIVE, - vpn_service1.get_connection(u'1').last_status) - self.assertEqual(constants.DOWN, - vpn_service1.get_connection(u'2').last_status) - self.assertEqual(constants.ACTIVE, vpn_service2.last_status) - self.assertEqual(constants.DOWN, - vpn_service2.get_connection(u'3').last_status) - self.assertEqual(constants.ACTIVE, - vpn_service2.get_connection(u'4').last_status) - - # TODO(pcm) FUTURE - UTs for update action, when supported. - - def test_vpnservice_updated(self): - with mock.patch.object(self.driver, 'sync') as sync: - context = mock.Mock() - self.driver.vpnservice_updated(context) - sync.assert_called_once_with(context, []) - - -class TestCiscoCsrIPsecDeviceDriverConfigLoading(base.BaseTestCase): - - def create_tempfile(self, contents): - (fd, path) = tempfile.mkstemp(prefix='test', suffix='.conf') - try: - os.write(fd, contents.encode('utf-8')) - finally: - os.close(fd) - return path - - def test_loading_csr_configuration(self): - """Ensure that Cisco CSR configs can be loaded from config files.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:3.2.1.1]\n' - 'rest_mgmt = 10.20.30.1\n' - 'tunnel_ip = 3.2.1.3\n' - 'username = me\n' - 'password = secret\n' - 'timeout = 5.0\n') - expected = {'3.2.1.1': {'rest_mgmt': '10.20.30.1', - 'tunnel_ip': '3.2.1.3', - 'username': 'me', - 'password': 'secret', - 'timeout': 5.0}} - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual(expected, csrs_found) - - def test_loading_config_without_timeout(self): - """Cisco CSR config without timeout will use default timeout.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:3.2.1.1]\n' - 'rest_mgmt = 10.20.30.1\n' - 'tunnel_ip = 3.2.1.3\n' - 'username = me\n' - 'password = secret\n') - expected = {'3.2.1.1': {'rest_mgmt': '10.20.30.1', - 'tunnel_ip': '3.2.1.3', - 'username': 'me', - 'password': 'secret', - 'timeout': csr_client.TIMEOUT}} - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual(expected, csrs_found) - - def test_skip_loading_duplicate_csr_configuration(self): - """Failure test that duplicate configurations are ignored.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:3.2.1.1]\n' - 'rest_mgmt = 10.20.30.1\n' - 'tunnel_ip = 3.2.1.3\n' - 'username = me\n' - 'password = secret\n' - 'timeout = 5.0\n' - '[CISCO_CSR_REST:3.2.1.1]\n' - 'rest_mgmt = 5.5.5.3\n' - 'tunnel_ip = 3.2.1.6\n' - 'username = me\n' - 'password = secret\n') - expected = {'3.2.1.1': {'rest_mgmt': '10.20.30.1', - 'tunnel_ip': '3.2.1.3', - 'username': 'me', - 'password': 'secret', - 'timeout': 5.0}} - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual(expected, csrs_found) - - def test_fail_loading_config_with_invalid_timeout(self): - """Failure test of invalid timeout in config info.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:3.2.1.1]\n' - 'rest_mgmt = 10.20.30.1\n' - 'tunnel_ip = 3.2.1.3\n' - 'username = me\n' - 'password = secret\n' - 'timeout = yes\n') - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual({}, csrs_found) - - def test_fail_loading_config_missing_required_info(self): - """Failure test of config missing required info.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:1.1.1.0]\n' - 'tunnel_ip = 1.1.1.3\n' - 'username = me\n' - 'password = secret\n' - 'timeout = 5.0\n' - '[CISCO_CSR_REST:2.2.2.0]\n' - 'rest_mgmt = 10.20.30.1\n' - 'username = me\n' - 'password = secret\n' - 'timeout = 5.0\n' - '[CISCO_CSR_REST:3.3.3.0]\n' - 'rest_mgmt = 10.20.30.1\n' - 'tunnel_ip = 3.3.3.3\n' - 'password = secret\n' - 'timeout = 5.0\n' - '[CISCO_CSR_REST:4.4.4.0]\n' - 'rest_mgmt = 10.20.30.1\n' - 'tunnel_ip = 4.4.4.4\n' - 'username = me\n' - 'timeout = 5.0\n') - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual({}, csrs_found) - - def test_fail_loading_config_with_invalid_router_id(self): - """Failure test of config with invalid rotuer ID.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:4.3.2.1.9]\n' - 'rest_mgmt = 10.20.30.1\n' - 'tunnel_ip = 4.3.2.3\n' - 'username = me\n' - 'password = secret\n' - 'timeout = 5.0\n') - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual({}, csrs_found) - - def test_fail_loading_config_with_invalid_mgmt_ip(self): - """Failure test of configuration with invalid management IP address.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:3.2.1.1]\n' - 'rest_mgmt = 1.1.1.1.1\n' - 'tunnel_ip = 3.2.1.3\n' - 'username = me\n' - 'password = secret\n' - 'timeout = 5.0\n') - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual({}, csrs_found) - - def test_fail_loading_config_with_invalid_tunnel_ip(self): - """Failure test of configuration with invalid tunnel IP address.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:3.2.1.1]\n' - 'rest_mgmt = 1.1.1.1\n' - 'tunnel_ip = 3.2.1.4.5\n' - 'username = me\n' - 'password = secret\n' - 'timeout = 5.0\n') - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual({}, csrs_found) - - def test_failure_no_configurations_entries(self): - """Failure test config file without any CSR definitions.""" - cfg_file = self.create_tempfile('NO CISCO SECTION AT ALL\n') - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual({}, csrs_found) - - def test_failure_no_csr_configurations_entries(self): - """Failure test config file without any CSR definitions.""" - cfg_file = self.create_tempfile('[SOME_CONFIG:123]\n' - 'username = me\n') - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual({}, csrs_found) - - def test_missing_config_value(self): - """Failure test of config file missing a value for attribute.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:3.2.1.1]\n' - 'rest_mgmt = \n' - 'tunnel_ip = 3.2.1.3\n' - 'username = me\n' - 'password = secret\n' - 'timeout = 5.0\n') - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual({}, csrs_found) - - def test_ignores_invalid_attribute_in_config(self): - """Test ignoring of config file with invalid attribute.""" - cfg_file = self.create_tempfile('[CISCO_CSR_REST:3.2.1.1]\n' - 'rest_mgmt = 1.1.1.1\n' - 'bogus = abcdef\n' - 'tunnel_ip = 3.2.1.3\n' - 'username = me\n' - 'password = secret\n' - 'timeout = 15.5\n') - expected = {'3.2.1.1': {'rest_mgmt': '1.1.1.1', - 'tunnel_ip': '3.2.1.3', - 'username': 'me', - 'password': 'secret', - 'timeout': 15.5}} - csrs_found = ipsec_driver.find_available_csrs_from_config([cfg_file]) - self.assertEqual(expected, csrs_found) diff --git a/neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py b/neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py deleted file mode 100644 index 29867a144..000000000 --- a/neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py +++ /dev/null @@ -1,258 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013, Nachi Ueno, NTT I3, Inc. -# All Rights Reserved. -# -# 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 copy -import mock - -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.services.vpn.device_drivers import ipsec as ipsec_driver -from neutron.tests import base - -_uuid = uuidutils.generate_uuid -FAKE_HOST = 'fake_host' -FAKE_ROUTER_ID = _uuid() -FAKE_VPN_SERVICE = { - 'id': _uuid(), - 'router_id': FAKE_ROUTER_ID, - 'admin_state_up': True, - 'status': constants.PENDING_CREATE, - 'subnet': {'cidr': '10.0.0.0/24'}, - 'ipsec_site_connections': [ - {'peer_cidrs': ['20.0.0.0/24', - '30.0.0.0/24']}, - {'peer_cidrs': ['40.0.0.0/24', - '50.0.0.0/24']}] -} - - -class TestIPsecDeviceDriver(base.BaseTestCase): - def setUp(self, driver=ipsec_driver.OpenSwanDriver): - super(TestIPsecDeviceDriver, self).setUp() - - for klass in [ - 'os.makedirs', - 'os.path.isdir', - 'neutron.agent.linux.utils.replace_file', - 'neutron.common.rpc_compat.create_connection', - 'neutron.services.vpn.device_drivers.ipsec.' - 'OpenSwanProcess._gen_config_content', - 'shutil.rmtree', - ]: - mock.patch(klass).start() - self.execute = mock.patch( - 'neutron.agent.linux.utils.execute').start() - self.agent = mock.Mock() - self.driver = driver( - self.agent, - FAKE_HOST) - self.driver.agent_rpc = mock.Mock() - - def test_vpnservice_updated(self): - with mock.patch.object(self.driver, 'sync') as sync: - context = mock.Mock() - self.driver.vpnservice_updated(context) - sync.assert_called_once_with(context, []) - - def test_create_router(self): - process_id = _uuid() - process = mock.Mock() - process.vpnservice = FAKE_VPN_SERVICE - self.driver.processes = { - process_id: process} - self.driver.create_router(process_id) - process.enable.assert_called_once_with() - - def test_destroy_router(self): - process_id = _uuid() - process = mock.Mock() - process.vpnservice = FAKE_VPN_SERVICE - self.driver.processes = { - process_id: process} - self.driver.destroy_router(process_id) - process.disable.assert_called_once_with() - self.assertNotIn(process_id, self.driver.processes) - - def test_sync_added(self): - self.driver.agent_rpc.get_vpn_services_on_host.return_value = [ - FAKE_VPN_SERVICE] - context = mock.Mock() - process = mock.Mock() - process.vpnservice = FAKE_VPN_SERVICE - process.connection_status = {} - process.status = constants.ACTIVE - process.updated_pending_status = True - self.driver.process_status_cache = {} - self.driver.processes = { - FAKE_ROUTER_ID: process} - self.driver.sync(context, []) - self.agent.assert_has_calls([ - mock.call.add_nat_rule( - FAKE_ROUTER_ID, - 'POSTROUTING', - '-s 10.0.0.0/24 -d 20.0.0.0/24 -m policy ' - '--dir out --pol ipsec -j ACCEPT ', - top=True), - mock.call.add_nat_rule( - FAKE_ROUTER_ID, - 'POSTROUTING', - '-s 10.0.0.0/24 -d 30.0.0.0/24 -m policy ' - '--dir out --pol ipsec -j ACCEPT ', - top=True), - mock.call.add_nat_rule( - FAKE_ROUTER_ID, - 'POSTROUTING', - '-s 10.0.0.0/24 -d 40.0.0.0/24 -m policy ' - '--dir out --pol ipsec -j ACCEPT ', - top=True), - mock.call.add_nat_rule( - FAKE_ROUTER_ID, - 'POSTROUTING', - '-s 10.0.0.0/24 -d 50.0.0.0/24 -m policy ' - '--dir out --pol ipsec -j ACCEPT ', - top=True), - mock.call.iptables_apply(FAKE_ROUTER_ID) - ]) - process.update.assert_called_once_with() - self.driver.agent_rpc.update_status.assert_called_once_with( - context, - [{'status': 'ACTIVE', - 'ipsec_site_connections': {}, - 'updated_pending_status': True, - 'id': FAKE_VPN_SERVICE['id']}]) - - def fake_ensure_process(self, process_id, vpnservice=None): - process = self.driver.processes.get(process_id) - if not process: - process = mock.Mock() - process.vpnservice = FAKE_VPN_SERVICE - process.connection_status = {} - process.status = constants.ACTIVE - process.updated_pending_status = True - self.driver.processes[process_id] = process - elif vpnservice: - process.vpnservice = vpnservice - process.update_vpnservice(vpnservice) - return process - - def test_sync_update_vpnservice(self): - with mock.patch.object(self.driver, - 'ensure_process') as ensure_process: - ensure_process.side_effect = self.fake_ensure_process - new_vpn_service = FAKE_VPN_SERVICE - updated_vpn_service = copy.deepcopy(new_vpn_service) - updated_vpn_service['ipsec_site_connections'].append( - {'peer_cidrs': ['60.0.0.0/24', - '70.0.0.0/24']}) - context = mock.Mock() - self.driver.process_status_cache = {} - self.driver.agent_rpc.get_vpn_services_on_host.return_value = [ - new_vpn_service] - self.driver.sync(context, []) - process = self.driver.processes[FAKE_ROUTER_ID] - self.assertEqual(process.vpnservice, new_vpn_service) - self.driver.agent_rpc.get_vpn_services_on_host.return_value = [ - updated_vpn_service] - self.driver.sync(context, []) - process = self.driver.processes[FAKE_ROUTER_ID] - process.update_vpnservice.assert_called_once_with( - updated_vpn_service) - self.assertEqual(process.vpnservice, updated_vpn_service) - - def test_sync_removed(self): - self.driver.agent_rpc.get_vpn_services_on_host.return_value = [] - context = mock.Mock() - process_id = _uuid() - process = mock.Mock() - process.vpnservice = FAKE_VPN_SERVICE - self.driver.processes = { - process_id: process} - self.driver.sync(context, []) - process.disable.assert_called_once_with() - self.assertNotIn(process_id, self.driver.processes) - - def test_sync_removed_router(self): - self.driver.agent_rpc.get_vpn_services_on_host.return_value = [] - context = mock.Mock() - process_id = _uuid() - self.driver.sync(context, [{'id': process_id}]) - self.assertNotIn(process_id, self.driver.processes) - - def test_status_updated_on_connection_admin_down(self): - self.driver.process_status_cache = { - '1': { - 'status': constants.ACTIVE, - 'id': 123, - 'updated_pending_status': False, - 'ipsec_site_connections': { - '10': { - 'status': constants.ACTIVE, - 'updated_pending_status': False, - }, - '20': { - 'status': constants.ACTIVE, - 'updated_pending_status': False, - } - } - } - } - # Simulate that there is no longer status for connection '20' - # e.g. connection admin down - new_status = { - 'ipsec_site_connections': { - '10': { - 'status': constants.ACTIVE, - 'updated_pending_status': False - } - } - } - self.driver.update_downed_connections('1', new_status) - existing_conn = new_status['ipsec_site_connections'].get('10') - self.assertIsNotNone(existing_conn) - self.assertEqual(constants.ACTIVE, existing_conn['status']) - missing_conn = new_status['ipsec_site_connections'].get('20') - self.assertIsNotNone(missing_conn) - self.assertEqual(constants.DOWN, missing_conn['status']) - - def test_status_updated_on_service_admin_down(self): - self.driver.process_status_cache = { - '1': { - 'status': constants.ACTIVE, - 'id': 123, - 'updated_pending_status': False, - 'ipsec_site_connections': { - '10': { - 'status': constants.ACTIVE, - 'updated_pending_status': False, - }, - '20': { - 'status': constants.ACTIVE, - 'updated_pending_status': False, - } - } - } - } - # Simulate that there are no connections now - new_status = { - 'ipsec_site_connections': {} - } - self.driver.update_downed_connections('1', new_status) - missing_conn = new_status['ipsec_site_connections'].get('10') - self.assertIsNotNone(missing_conn) - self.assertEqual(constants.DOWN, missing_conn['status']) - missing_conn = new_status['ipsec_site_connections'].get('20') - self.assertIsNotNone(missing_conn) - self.assertEqual(constants.DOWN, missing_conn['status']) diff --git a/neutron/tests/unit/services/vpn/service_drivers/__init__.py b/neutron/tests/unit/services/vpn/service_drivers/__init__.py deleted file mode 100644 index 9b27a7520..000000000 --- a/neutron/tests/unit/services/vpn/service_drivers/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013, Nachi Ueno, NTT I3, Inc. -# All Rights Reserved. -# -# 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. diff --git a/neutron/tests/unit/services/vpn/service_drivers/test_cisco_ipsec.py b/neutron/tests/unit/services/vpn/service_drivers/test_cisco_ipsec.py deleted file mode 100644 index f78d8b16c..000000000 --- a/neutron/tests/unit/services/vpn/service_drivers/test_cisco_ipsec.py +++ /dev/null @@ -1,365 +0,0 @@ -# Copyright 2014 Cisco Systems, Inc. All rights reserved. -# -# 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 neutron import context as n_ctx -from neutron.db import api as dbapi -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.services.vpn.service_drivers import cisco_csr_db as csr_db -from neutron.services.vpn.service_drivers import cisco_ipsec as ipsec_driver -from neutron.tests import base - -_uuid = uuidutils.generate_uuid - -FAKE_VPN_CONN_ID = _uuid() - -FAKE_VPN_CONNECTION = { - 'vpnservice_id': _uuid(), - 'id': FAKE_VPN_CONN_ID, - 'ikepolicy_id': _uuid(), - 'ipsecpolicy_id': _uuid(), - 'tenant_id': _uuid() -} -FAKE_VPN_SERVICE = { - 'router_id': _uuid() -} -FAKE_HOST = 'fake_host' - - -class TestCiscoIPsecDriverValidation(base.BaseTestCase): - - def setUp(self): - super(TestCiscoIPsecDriverValidation, self).setUp() - mock.patch('neutron.common.rpc_compat.create_connection').start() - self.service_plugin = mock.Mock() - self.driver = ipsec_driver.CiscoCsrIPsecVPNDriver(self.service_plugin) - self.context = n_ctx.Context('some_user', 'some_tenant') - self.vpn_service = mock.Mock() - - def test_ike_version_unsupported(self): - """Failure test that Cisco CSR REST API does not support IKE v2.""" - policy_info = {'ike_version': 'v2', - 'lifetime': {'units': 'seconds', 'value': 60}} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_ike_version, policy_info) - - def test_ike_lifetime_not_in_seconds(self): - """Failure test of unsupported lifetime units for IKE policy.""" - policy_info = {'lifetime': {'units': 'kilobytes', 'value': 1000}} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_lifetime, - "IKE Policy", policy_info) - - def test_ipsec_lifetime_not_in_seconds(self): - """Failure test of unsupported lifetime units for IPSec policy.""" - policy_info = {'lifetime': {'units': 'kilobytes', 'value': 1000}} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_lifetime, - "IPSec Policy", policy_info) - - def test_ike_lifetime_seconds_values_at_limits(self): - """Test valid lifetime values for IKE policy.""" - policy_info = {'lifetime': {'units': 'seconds', 'value': 60}} - self.driver.validate_lifetime('IKE Policy', policy_info) - policy_info = {'lifetime': {'units': 'seconds', 'value': 86400}} - self.driver.validate_lifetime('IKE Policy', policy_info) - - def test_ipsec_lifetime_seconds_values_at_limits(self): - """Test valid lifetime values for IPSec policy.""" - policy_info = {'lifetime': {'units': 'seconds', 'value': 120}} - self.driver.validate_lifetime('IPSec Policy', policy_info) - policy_info = {'lifetime': {'units': 'seconds', 'value': 2592000}} - self.driver.validate_lifetime('IPSec Policy', policy_info) - - def test_ike_lifetime_values_invalid(self): - """Failure test of unsupported lifetime values for IKE policy.""" - which = "IKE Policy" - policy_info = {'lifetime': {'units': 'seconds', 'value': 59}} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_lifetime, - which, policy_info) - policy_info = {'lifetime': {'units': 'seconds', 'value': 86401}} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_lifetime, - which, policy_info) - - def test_ipsec_lifetime_values_invalid(self): - """Failure test of unsupported lifetime values for IPSec policy.""" - which = "IPSec Policy" - policy_info = {'lifetime': {'units': 'seconds', 'value': 119}} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_lifetime, - which, policy_info) - policy_info = {'lifetime': {'units': 'seconds', 'value': 2592001}} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_lifetime, - which, policy_info) - - def test_ipsec_connection_with_mtu_at_limits(self): - """Test IPSec site-to-site connection with MTU at limits.""" - conn_info = {'mtu': 1500} - self.driver.validate_mtu(conn_info) - conn_info = {'mtu': 9192} - self.driver.validate_mtu(conn_info) - - def test_ipsec_connection_with_invalid_mtu(self): - """Failure test of IPSec site connection with unsupported MTUs.""" - conn_info = {'mtu': 1499} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_mtu, conn_info) - conn_info = {'mtu': 9193} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_mtu, conn_info) - - def simulate_gw_ip_available(self): - """Helper function indicating that tunnel has a gateway IP.""" - def have_one(): - return 1 - self.vpn_service.router.gw_port.fixed_ips.__len__ = have_one - ip_addr_mock = mock.Mock() - self.vpn_service.router.gw_port.fixed_ips = [ip_addr_mock] - return ip_addr_mock - - def test_have_public_ip_for_router(self): - """Ensure that router for IPSec connection has gateway IP.""" - self.simulate_gw_ip_available() - self.driver.validate_public_ip_present(self.vpn_service) - - def test_router_with_missing_gateway_ip(self): - """Failure test of IPSec connection with missing gateway IP.""" - self.simulate_gw_ip_available() - self.vpn_service.router.gw_port = None - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_public_ip_present, - self.vpn_service) - - def test_peer_id_is_an_ip_address(self): - """Ensure peer ID is an IP address for IPsec connection create.""" - ipsec_conn = {'peer_id': '10.10.10.10'} - self.driver.validate_peer_id(ipsec_conn) - - def test_peer_id_is_not_ip_address(self): - """Failure test of peer_id that is not an IP address.""" - ipsec_conn = {'peer_id': 'some-site.com'} - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.validate_peer_id, ipsec_conn) - - def test_validation_for_create_ipsec_connection(self): - """Ensure all validation passes for IPSec site connection create.""" - self.simulate_gw_ip_available() - # Provide the minimum needed items to validate - ipsec_conn = {'id': '1', - 'ikepolicy_id': '123', - 'ipsecpolicy_id': '2', - 'mtu': 1500, - 'peer_id': '10.10.10.10'} - self.service_plugin.get_ikepolicy = mock.Mock( - return_value={'ike_version': 'v1', - 'lifetime': {'units': 'seconds', 'value': 60}}) - self.service_plugin.get_ipsecpolicy = mock.Mock( - return_value={'lifetime': {'units': 'seconds', 'value': 120}}) - self.driver.validate_ipsec_connection(self.context, ipsec_conn, - self.vpn_service) - - -class TestCiscoIPsecDriverMapping(base.BaseTestCase): - - def setUp(self): - super(TestCiscoIPsecDriverMapping, self).setUp() - self.context = mock.patch.object(n_ctx, 'Context').start() - self.session = self.context.session - self.query_mock = self.session.query.return_value.order_by - - def test_identifying_first_mapping_id(self): - """Make sure first available ID is obtained for each ID type.""" - # Simulate mapping table is empty - get first one - self.query_mock.return_value = [] - next_id = csr_db.get_next_available_tunnel_id(self.session) - self.assertEqual(0, next_id) - - next_id = csr_db.get_next_available_ike_policy_id(self.session) - self.assertEqual(1, next_id) - - next_id = csr_db.get_next_available_ipsec_policy_id(self.session) - self.assertEqual(1, next_id) - - def test_last_mapping_id_available(self): - """Make sure can get the last ID for each of the table types.""" - # Simulate query indicates table is full - self.query_mock.return_value = [ - (x, ) for x in xrange(csr_db.MAX_CSR_TUNNELS - 1)] - next_id = csr_db.get_next_available_tunnel_id(self.session) - self.assertEqual(csr_db.MAX_CSR_TUNNELS - 1, next_id) - - self.query_mock.return_value = [ - (x, ) for x in xrange(1, csr_db.MAX_CSR_IKE_POLICIES)] - next_id = csr_db.get_next_available_ike_policy_id(self.session) - self.assertEqual(csr_db.MAX_CSR_IKE_POLICIES, next_id) - - self.query_mock.return_value = [ - (x, ) for x in xrange(1, csr_db.MAX_CSR_IPSEC_POLICIES)] - next_id = csr_db.get_next_available_ipsec_policy_id(self.session) - self.assertEqual(csr_db.MAX_CSR_IPSEC_POLICIES, next_id) - - def test_reusing_first_available_mapping_id(self): - """Ensure that we reuse the first available ID. - - Make sure that the next lowest ID is obtained from the mapping - table when there are "holes" from deletions. Database query sorts - the entries, so will return them in order. Using tunnel ID, as the - logic is the same for each ID type. - """ - self.query_mock.return_value = [(0, ), (1, ), (2, ), (5, ), (6, )] - next_id = csr_db.get_next_available_tunnel_id(self.session) - self.assertEqual(3, next_id) - - def test_no_more_mapping_ids_available(self): - """Failure test of trying to reserve ID, when none available.""" - self.query_mock.return_value = [ - (x, ) for x in xrange(csr_db.MAX_CSR_TUNNELS)] - self.assertRaises(IndexError, csr_db.get_next_available_tunnel_id, - self.session) - - self.query_mock.return_value = [ - (x, ) for x in xrange(1, csr_db.MAX_CSR_IKE_POLICIES + 1)] - self.assertRaises(IndexError, csr_db.get_next_available_ike_policy_id, - self.session) - - self.query_mock.return_value = [ - (x, ) for x in xrange(1, csr_db.MAX_CSR_IPSEC_POLICIES + 1)] - self.assertRaises(IndexError, - csr_db.get_next_available_ipsec_policy_id, - self.session) - - def test_create_tunnel_mappings(self): - """Ensure successfully create new tunnel mappings.""" - # Simulate that first IDs are obtained - self.query_mock.return_value = [] - map_db_mock = mock.patch.object(csr_db, 'IdentifierMap').start() - conn_info = {'ikepolicy_id': '10', - 'ipsecpolicy_id': '50', - 'id': '100', - 'tenant_id': '1000'} - csr_db.create_tunnel_mapping(self.context, conn_info) - map_db_mock.assert_called_once_with(csr_tunnel_id=0, - csr_ike_policy_id=1, - csr_ipsec_policy_id=1, - ipsec_site_conn_id='100', - tenant_id='1000') - # Create another, with next ID of 2 for all IDs (not mocking each - # ID separately, so will not have different IDs). - self.query_mock.return_value = [(0, ), (1, )] - map_db_mock.reset_mock() - conn_info = {'ikepolicy_id': '20', - 'ipsecpolicy_id': '60', - 'id': '101', - 'tenant_id': '1000'} - csr_db.create_tunnel_mapping(self.context, conn_info) - map_db_mock.assert_called_once_with(csr_tunnel_id=2, - csr_ike_policy_id=2, - csr_ipsec_policy_id=2, - ipsec_site_conn_id='101', - tenant_id='1000') - - -class TestCiscoIPsecDriver(base.BaseTestCase): - - """Test that various incoming requests are sent to device driver.""" - - def setUp(self): - super(TestCiscoIPsecDriver, self).setUp() - dbapi.configure_db() - self.addCleanup(dbapi.clear_db) - mock.patch('neutron.common.rpc_compat.create_connection').start() - - l3_agent = mock.Mock() - l3_agent.host = FAKE_HOST - plugin = mock.Mock() - plugin.get_l3_agents_hosting_routers.return_value = [l3_agent] - plugin_p = mock.patch('neutron.manager.NeutronManager.get_plugin') - get_plugin = plugin_p.start() - get_plugin.return_value = plugin - service_plugin_p = mock.patch( - 'neutron.manager.NeutronManager.get_service_plugins') - get_service_plugin = service_plugin_p.start() - get_service_plugin.return_value = {constants.L3_ROUTER_NAT: plugin} - - service_plugin = mock.Mock() - service_plugin.get_l3_agents_hosting_routers.return_value = [l3_agent] - service_plugin._get_vpnservice.return_value = { - 'router_id': _uuid() - } - self.db_update_mock = service_plugin.update_ipsec_site_conn_status - self.driver = ipsec_driver.CiscoCsrIPsecVPNDriver(service_plugin) - self.driver.validate_ipsec_connection = mock.Mock() - mock.patch.object(csr_db, 'create_tunnel_mapping').start() - self.context = n_ctx.Context('some_user', 'some_tenant') - - def _test_update(self, func, args, additional_info=None): - with mock.patch.object(self.driver.agent_rpc, 'cast') as cast: - func(self.context, *args) - cast.assert_called_once_with( - self.context, - {'args': additional_info, - 'namespace': None, - 'method': 'vpnservice_updated'}, - version='1.0', - topic='cisco_csr_ipsec_agent.fake_host') - - def test_create_ipsec_site_connection(self): - self._test_update(self.driver.create_ipsec_site_connection, - [FAKE_VPN_CONNECTION], - {'reason': 'ipsec-conn-create'}) - - def test_failure_validation_ipsec_connection(self): - """Failure test of validation during IPSec site connection create. - - Simulate a validation failure, and ensure that database is - updated to indicate connection is in error state. - - TODO(pcm): FUTURE - remove test case, once vendor plugin - validation is done before database commit. - """ - self.driver.validate_ipsec_connection.side_effect = ( - ipsec_driver.CsrValidationFailure(resource='IPSec Connection', - key='mtu', value=1000)) - self.assertRaises(ipsec_driver.CsrValidationFailure, - self.driver.create_ipsec_site_connection, - self.context, FAKE_VPN_CONNECTION) - self.db_update_mock.assert_called_with(self.context, - FAKE_VPN_CONN_ID, - constants.ERROR) - - def test_update_ipsec_site_connection(self): - self._test_update(self.driver.update_ipsec_site_connection, - [FAKE_VPN_CONNECTION, FAKE_VPN_CONNECTION], - {'reason': 'ipsec-conn-update'}) - - def test_delete_ipsec_site_connection(self): - self._test_update(self.driver.delete_ipsec_site_connection, - [FAKE_VPN_CONNECTION], - {'reason': 'ipsec-conn-delete'}) - - def test_update_vpnservice(self): - self._test_update(self.driver.update_vpnservice, - [FAKE_VPN_SERVICE, FAKE_VPN_SERVICE], - {'reason': 'vpn-service-update'}) - - def test_delete_vpnservice(self): - self._test_update(self.driver.delete_vpnservice, - [FAKE_VPN_SERVICE], - {'reason': 'vpn-service-delete'}) diff --git a/neutron/tests/unit/services/vpn/service_drivers/test_ipsec.py b/neutron/tests/unit/services/vpn/service_drivers/test_ipsec.py deleted file mode 100644 index 2f7cbfaf9..000000000 --- a/neutron/tests/unit/services/vpn/service_drivers/test_ipsec.py +++ /dev/null @@ -1,91 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013, Nachi Ueno, NTT I3, Inc. -# All Rights Reserved. -# -# 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 neutron import context -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.services.vpn.service_drivers import ipsec as ipsec_driver -from neutron.tests import base - -_uuid = uuidutils.generate_uuid - -FAKE_VPN_CONNECTION = { - 'vpnservice_id': _uuid() -} -FAKE_VPN_SERVICE = { - 'router_id': _uuid() -} -FAKE_HOST = 'fake_host' - - -class TestIPsecDriver(base.BaseTestCase): - def setUp(self): - super(TestIPsecDriver, self).setUp() - mock.patch('neutron.common.rpc_compat.create_connection').start() - - l3_agent = mock.Mock() - l3_agent.host = FAKE_HOST - plugin = mock.Mock() - plugin.get_l3_agents_hosting_routers.return_value = [l3_agent] - plugin_p = mock.patch('neutron.manager.NeutronManager.get_plugin') - get_plugin = plugin_p.start() - get_plugin.return_value = plugin - service_plugin_p = mock.patch( - 'neutron.manager.NeutronManager.get_service_plugins') - get_service_plugin = service_plugin_p.start() - get_service_plugin.return_value = {constants.L3_ROUTER_NAT: plugin} - - service_plugin = mock.Mock() - service_plugin.get_l3_agents_hosting_routers.return_value = [l3_agent] - service_plugin._get_vpnservice.return_value = { - 'router_id': _uuid() - } - self.driver = ipsec_driver.IPsecVPNDriver(service_plugin) - - def _test_update(self, func, args): - ctxt = context.Context('', 'somebody') - with mock.patch.object(self.driver.agent_rpc, 'cast') as cast: - func(ctxt, *args) - cast.assert_called_once_with( - ctxt, - {'args': {}, - 'namespace': None, - 'method': 'vpnservice_updated'}, - version='1.0', - topic='ipsec_agent.fake_host') - - def test_create_ipsec_site_connection(self): - self._test_update(self.driver.create_ipsec_site_connection, - [FAKE_VPN_CONNECTION]) - - def test_update_ipsec_site_connection(self): - self._test_update(self.driver.update_ipsec_site_connection, - [FAKE_VPN_CONNECTION, FAKE_VPN_CONNECTION]) - - def test_delete_ipsec_site_connection(self): - self._test_update(self.driver.delete_ipsec_site_connection, - [FAKE_VPN_CONNECTION]) - - def test_update_vpnservice(self): - self._test_update(self.driver.update_vpnservice, - [FAKE_VPN_SERVICE, FAKE_VPN_SERVICE]) - - def test_delete_vpnservice(self): - self._test_update(self.driver.delete_vpnservice, - [FAKE_VPN_SERVICE]) diff --git a/neutron/tests/unit/services/vpn/test_vpn_agent.py b/neutron/tests/unit/services/vpn/test_vpn_agent.py deleted file mode 100644 index 7b1cab523..000000000 --- a/neutron/tests/unit/services/vpn/test_vpn_agent.py +++ /dev/null @@ -1,196 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013, Nachi Ueno, NTT I3, Inc. -# All Rights Reserved. -# -# 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 oslo.config import cfg - -from neutron.agent.common import config as agent_config -from neutron.agent import l3_agent -from neutron.agent.linux import interface -from neutron.common import config as base_config -from neutron.openstack.common import uuidutils -from neutron.services.vpn import agent -from neutron.services.vpn import device_drivers -from neutron.tests import base - -_uuid = uuidutils.generate_uuid -NOOP_DEVICE_CLASS = 'NoopDeviceDriver' -NOOP_DEVICE = ('neutron.tests.unit.services.' - 'vpn.test_vpn_agent.%s' % NOOP_DEVICE_CLASS) - - -class NoopDeviceDriver(device_drivers.DeviceDriver): - def sync(self, context, processes): - pass - - def create_router(self, process_id): - pass - - def destroy_router(self, process_id): - pass - - -class TestVPNAgent(base.BaseTestCase): - def setUp(self): - super(TestVPNAgent, self).setUp() - self.conf = cfg.CONF - self.conf.register_opts(base_config.core_opts) - self.conf.register_opts(l3_agent.L3NATAgent.OPTS) - self.conf.register_opts(interface.OPTS) - agent_config.register_interface_driver_opts_helper(self.conf) - agent_config.register_use_namespaces_opts_helper(self.conf) - agent_config.register_agent_state_opts_helper(self.conf) - agent_config.register_root_helper(self.conf) - - self.conf.set_override('interface_driver', - 'neutron.agent.linux.interface.NullDriver') - self.conf.set_override( - 'vpn_device_driver', - [NOOP_DEVICE], - 'vpnagent') - - for clazz in [ - 'neutron.agent.linux.ip_lib.device_exists', - 'neutron.agent.linux.ip_lib.IPWrapper', - 'neutron.agent.linux.interface.NullDriver', - 'neutron.agent.linux.utils.execute' - ]: - mock.patch(clazz).start() - - l3pluginApi_cls = mock.patch( - 'neutron.agent.l3_agent.L3PluginApi').start() - self.plugin_api = mock.Mock() - l3pluginApi_cls.return_value = self.plugin_api - - looping_call_p = mock.patch( - 'neutron.openstack.common.loopingcall.FixedIntervalLoopingCall') - looping_call_p.start() - - self.fake_host = 'fake_host' - self.agent = agent.VPNAgent(self.fake_host) - - def test_setup_drivers(self): - self.assertEqual(1, len(self.agent.devices)) - device = self.agent.devices[0] - self.assertEqual( - NOOP_DEVICE_CLASS, - device.__class__.__name__ - ) - - def test_get_namespace(self): - router_id = _uuid() - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, None) - self.agent.router_info = {router_id: ri} - namespace = self.agent.get_namespace(router_id) - self.assertTrue(namespace.endswith(router_id)) - self.assertFalse(self.agent.get_namespace('fake_id')) - - def test_add_nat_rule(self): - router_id = _uuid() - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, None) - iptables = mock.Mock() - ri.iptables_manager.ipv4['nat'] = iptables - self.agent.router_info = {router_id: ri} - self.agent.add_nat_rule(router_id, 'fake_chain', 'fake_rule', True) - iptables.add_rule.assert_called_once_with( - 'fake_chain', 'fake_rule', top=True) - - def test_add_nat_rule_with_no_router(self): - self.agent.router_info = {} - #Should do nothing - self.agent.add_nat_rule( - 'fake_router_id', - 'fake_chain', - 'fake_rule', - True) - - def test_remove_rule(self): - router_id = _uuid() - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, None) - iptables = mock.Mock() - ri.iptables_manager.ipv4['nat'] = iptables - self.agent.router_info = {router_id: ri} - self.agent.remove_nat_rule(router_id, 'fake_chain', 'fake_rule', True) - iptables.remove_rule.assert_called_once_with( - 'fake_chain', 'fake_rule', top=True) - - def test_remove_rule_with_no_router(self): - self.agent.router_info = {} - #Should do nothing - self.agent.remove_nat_rule( - 'fake_router_id', - 'fake_chain', - 'fake_rule') - - def test_iptables_apply(self): - router_id = _uuid() - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, None) - iptables = mock.Mock() - ri.iptables_manager = iptables - self.agent.router_info = {router_id: ri} - self.agent.iptables_apply(router_id) - iptables.apply.assert_called_once_with() - - def test_iptables_apply_with_no_router(self): - #Should do nothing - self.agent.router_info = {} - self.agent.iptables_apply('fake_router_id') - - def test_router_added(self): - mock.patch( - 'neutron.agent.linux.iptables_manager.IptablesManager').start() - router_id = _uuid() - router = {'id': router_id} - device = mock.Mock() - self.agent.devices = [device] - self.agent._router_added(router_id, router) - device.create_router.assert_called_once_with(router_id) - - def test_router_removed(self): - self.plugin_api.get_external_network_id.return_value = None - mock.patch( - 'neutron.agent.linux.iptables_manager.IptablesManager').start() - router_id = _uuid() - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, None) - ri.router = { - 'id': _uuid(), - 'admin_state_up': True, - 'routes': [], - 'external_gateway_info': {}} - device = mock.Mock() - self.agent.router_info = {router_id: ri} - self.agent.devices = [device] - self.agent._router_removed(router_id) - device.destroy_router.assert_called_once_with(router_id) - - def test_process_routers(self): - self.plugin_api.get_external_network_id.return_value = None - routers = [ - {'id': _uuid(), - 'admin_state_up': True, - 'routes': [], - 'external_gateway_info': {}}] - - device = mock.Mock() - self.agent.devices = [device] - self.agent._process_routers(routers, False) - device.sync.assert_called_once_with(mock.ANY, routers) diff --git a/neutron/tests/unit/services/vpn/test_vpnaas_driver_plugin.py b/neutron/tests/unit/services/vpn/test_vpnaas_driver_plugin.py deleted file mode 100644 index 45f932ec1..000000000 --- a/neutron/tests/unit/services/vpn/test_vpnaas_driver_plugin.py +++ /dev/null @@ -1,160 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013, Nachi Ueno, NTT I3, Inc. -# All Rights Reserved. -# -# 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 contextlib - -import mock - -from neutron.common import constants -from neutron import context -from neutron import manager -from neutron.plugins.common import constants as p_constants -from neutron.services.vpn.service_drivers import ipsec as ipsec_driver -from neutron.tests.unit.db.vpn import test_db_vpnaas -from neutron.tests.unit.openvswitch import test_agent_scheduler -from neutron.tests.unit import test_agent_ext_plugin - -FAKE_HOST = test_agent_ext_plugin.L3_HOSTA -VPN_DRIVER_CLASS = 'neutron.services.vpn.plugin.VPNDriverPlugin' - - -class TestVPNDriverPlugin(test_db_vpnaas.TestVpnaas, - test_agent_scheduler.AgentSchedulerTestMixIn, - test_agent_ext_plugin.AgentDBTestMixIn): - def setUp(self): - self.adminContext = context.get_admin_context() - driver_cls_p = mock.patch( - 'neutron.services.vpn.' - 'service_drivers.ipsec.IPsecVPNDriver') - driver_cls = driver_cls_p.start() - self.driver = mock.Mock() - self.driver.service_type = ipsec_driver.IPSEC - driver_cls.return_value = self.driver - super(TestVPNDriverPlugin, self).setUp( - vpnaas_plugin=VPN_DRIVER_CLASS) - - def test_create_ipsec_site_connection(self, **extras): - super(TestVPNDriverPlugin, self).test_create_ipsec_site_connection() - self.driver.create_ipsec_site_connection.assert_called_once_with( - mock.ANY, mock.ANY) - self.driver.delete_ipsec_site_connection.assert_called_once_with( - mock.ANY, mock.ANY) - - def test_delete_vpnservice(self, **extras): - super(TestVPNDriverPlugin, self).test_delete_vpnservice() - self.driver.delete_vpnservice.assert_called_once_with( - mock.ANY, mock.ANY) - - def test_update_vpnservice(self, **extras): - super(TestVPNDriverPlugin, self).test_update_vpnservice() - self.driver.update_vpnservice.assert_called_once_with( - mock.ANY, mock.ANY, mock.ANY) - - @contextlib.contextmanager - def vpnservice_set(self): - """Test case to create a ipsec_site_connection.""" - vpnservice_name = "vpn1" - ipsec_site_connection_name = "ipsec_site_connection" - ikename = "ikepolicy1" - ipsecname = "ipsecpolicy1" - description = "my-vpn-connection" - keys = {'name': vpnservice_name, - 'description': "my-vpn-connection", - 'peer_address': '192.168.1.10', - 'peer_id': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'], - 'initiator': 'bi-directional', - 'mtu': 1500, - 'dpd_action': 'hold', - 'dpd_interval': 40, - 'dpd_timeout': 120, - 'tenant_id': self._tenant_id, - 'psk': 'abcd', - 'status': 'PENDING_CREATE', - 'admin_state_up': True} - with self.ikepolicy(name=ikename) as ikepolicy: - with self.ipsecpolicy(name=ipsecname) as ipsecpolicy: - with self.subnet() as subnet: - with self.router() as router: - plugin = manager.NeutronManager.get_plugin() - agent = {'host': FAKE_HOST, - 'agent_type': constants.AGENT_TYPE_L3, - 'binary': 'fake-binary', - 'topic': 'fake-topic'} - plugin.create_or_update_agent(self.adminContext, agent) - plugin.schedule_router( - self.adminContext, router['router']['id']) - with self.vpnservice(name=vpnservice_name, - subnet=subnet, - router=router) as vpnservice1: - keys['ikepolicy_id'] = ikepolicy['ikepolicy']['id'] - keys['ipsecpolicy_id'] = ( - ipsecpolicy['ipsecpolicy']['id'] - ) - keys['vpnservice_id'] = ( - vpnservice1['vpnservice']['id'] - ) - with self.ipsec_site_connection( - self.fmt, - ipsec_site_connection_name, - keys['peer_address'], - keys['peer_id'], - keys['peer_cidrs'], - keys['mtu'], - keys['psk'], - keys['initiator'], - keys['dpd_action'], - keys['dpd_interval'], - keys['dpd_timeout'], - vpnservice1, - ikepolicy, - ipsecpolicy, - keys['admin_state_up'], - description=description, - ): - yield vpnservice1['vpnservice'] - - def test_get_agent_hosting_vpn_services(self): - with self.vpnservice_set(): - service_plugin = manager.NeutronManager.get_service_plugins()[ - p_constants.VPN] - vpnservices = service_plugin._get_agent_hosting_vpn_services( - self.adminContext, FAKE_HOST) - vpnservices = vpnservices.all() - self.assertEqual(1, len(vpnservices)) - vpnservice_db = vpnservices[0] - self.assertEqual(1, len(vpnservice_db.ipsec_site_connections)) - ipsec_site_connection = vpnservice_db.ipsec_site_connections[0] - self.assertIsNotNone( - ipsec_site_connection['ikepolicy']) - self.assertIsNotNone( - ipsec_site_connection['ipsecpolicy']) - - def test_update_status(self): - with self.vpnservice_set() as vpnservice: - self._register_agent_states() - service_plugin = manager.NeutronManager.get_service_plugins()[ - p_constants.VPN] - service_plugin.update_status_by_agent( - self.adminContext, - [{'status': 'ACTIVE', - 'ipsec_site_connections': {}, - 'updated_pending_status': True, - 'id': vpnservice['id']}]) - vpnservices = service_plugin._get_agent_hosting_vpn_services( - self.adminContext, FAKE_HOST) - vpnservice_db = vpnservices[0] - self.assertEqual(p_constants.ACTIVE, vpnservice_db['status']) diff --git a/neutron/tests/unit/services/vpn/test_vpnaas_extension.py b/neutron/tests/unit/services/vpn/test_vpnaas_extension.py deleted file mode 100644 index beff3d7a5..000000000 --- a/neutron/tests/unit/services/vpn/test_vpnaas_extension.py +++ /dev/null @@ -1,530 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. -# All Rights Reserved. -# -# 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. -# -# @author: Swaminathan Vasudevan, Hewlett-Packard. - -import copy - -import mock -from webob import exc - -from neutron.extensions import vpnaas -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_api_v2_extension - - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path - - -class VpnaasExtensionTestCase(test_api_v2_extension.ExtensionTestCase): - fmt = 'json' - - def setUp(self): - super(VpnaasExtensionTestCase, self).setUp() - plural_mappings = {'ipsecpolicy': 'ipsecpolicies', - 'ikepolicy': 'ikepolicies', - 'ipsec_site_connection': 'ipsec-site-connections'} - self._setUpExtension( - 'neutron.extensions.vpnaas.VPNPluginBase', constants.VPN, - vpnaas.RESOURCE_ATTRIBUTE_MAP, vpnaas.Vpnaas, - 'vpn', plural_mappings=plural_mappings, - use_quota=True) - - def test_ikepolicy_create(self): - """Test case to create an ikepolicy.""" - ikepolicy_id = _uuid() - data = {'ikepolicy': {'name': 'ikepolicy1', - 'description': 'myikepolicy1', - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'phase1_negotiation_mode': 'main', - 'lifetime': { - 'units': 'seconds', - 'value': 3600}, - 'ike_version': 'v1', - 'pfs': 'group5', - 'tenant_id': _uuid()}} - - return_value = copy.copy(data['ikepolicy']) - return_value.update({'id': ikepolicy_id}) - - instance = self.plugin.return_value - instance.create_ikepolicy.return_value = return_value - res = self.api.post(_get_path('vpn/ikepolicies', fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_ikepolicy.assert_called_with(mock.ANY, - ikepolicy=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('ikepolicy', res) - self.assertEqual(res['ikepolicy'], return_value) - - def test_ikepolicy_list(self): - """Test case to list all ikepolicies.""" - ikepolicy_id = _uuid() - return_value = [{'name': 'ikepolicy1', - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'pfs': 'group5', - 'ike_version': 'v1', - 'id': ikepolicy_id}] - - instance = self.plugin.return_value - instance.get_ikepolicies.return_value = return_value - - res = self.api.get(_get_path('vpn/ikepolicies', fmt=self.fmt)) - - instance.get_ikepolicies.assert_called_with(mock.ANY, - fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_ikepolicy_update(self): - """Test case to update an ikepolicy.""" - ikepolicy_id = _uuid() - update_data = {'ikepolicy': {'name': 'ikepolicy1', - 'encryption_algorithm': 'aes-256'}} - return_value = {'name': 'ikepolicy1', - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-256', - 'phase1_negotiation_mode': 'main', - 'lifetime': { - 'units': 'seconds', - 'value': 3600}, - 'ike_version': 'v1', - 'pfs': 'group5', - 'tenant_id': _uuid(), - 'id': ikepolicy_id} - - instance = self.plugin.return_value - instance.update_ikepolicy.return_value = return_value - - res = self.api.put(_get_path('vpn/ikepolicies', id=ikepolicy_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_ikepolicy.assert_called_with(mock.ANY, ikepolicy_id, - ikepolicy=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('ikepolicy', res) - self.assertEqual(res['ikepolicy'], return_value) - - def test_ikepolicy_get(self): - """Test case to get or show an ikepolicy.""" - ikepolicy_id = _uuid() - return_value = {'name': 'ikepolicy1', - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'phase1_negotiation_mode': 'main', - 'lifetime': { - 'units': 'seconds', - 'value': 3600}, - 'ike_version': 'v1', - 'pfs': 'group5', - 'tenant_id': _uuid(), - 'id': ikepolicy_id} - - instance = self.plugin.return_value - instance.get_ikepolicy.return_value = return_value - - res = self.api.get(_get_path('vpn/ikepolicies', id=ikepolicy_id, - fmt=self.fmt)) - - instance.get_ikepolicy.assert_called_with(mock.ANY, - ikepolicy_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('ikepolicy', res) - self.assertEqual(res['ikepolicy'], return_value) - - def test_ikepolicy_delete(self): - """Test case to delete an ikepolicy.""" - self._test_entity_delete('ikepolicy') - - def test_ipsecpolicy_create(self): - """Test case to create an ipsecpolicy.""" - ipsecpolicy_id = _uuid() - data = {'ipsecpolicy': {'name': 'ipsecpolicy1', - 'description': 'myipsecpolicy1', - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'encapsulation_mode': 'tunnel', - 'lifetime': { - 'units': 'seconds', - 'value': 3600}, - 'transform_protocol': 'esp', - 'pfs': 'group5', - 'tenant_id': _uuid()}} - return_value = copy.copy(data['ipsecpolicy']) - return_value.update({'id': ipsecpolicy_id}) - - instance = self.plugin.return_value - instance.create_ipsecpolicy.return_value = return_value - res = self.api.post(_get_path('vpn/ipsecpolicies', fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_ipsecpolicy.assert_called_with(mock.ANY, - ipsecpolicy=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('ipsecpolicy', res) - self.assertEqual(res['ipsecpolicy'], return_value) - - def test_ipsecpolicy_list(self): - """Test case to list an ipsecpolicy.""" - ipsecpolicy_id = _uuid() - return_value = [{'name': 'ipsecpolicy1', - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'pfs': 'group5', - 'id': ipsecpolicy_id}] - - instance = self.plugin.return_value - instance.get_ipsecpolicies.return_value = return_value - - res = self.api.get(_get_path('vpn/ipsecpolicies', fmt=self.fmt)) - - instance.get_ipsecpolicies.assert_called_with(mock.ANY, - fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_ipsecpolicy_update(self): - """Test case to update an ipsecpolicy.""" - ipsecpolicy_id = _uuid() - update_data = {'ipsecpolicy': {'name': 'ipsecpolicy1', - 'encryption_algorithm': 'aes-256'}} - return_value = {'name': 'ipsecpolicy1', - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'encapsulation_mode': 'tunnel', - 'lifetime': { - 'units': 'seconds', - 'value': 3600}, - 'transform_protocol': 'esp', - 'pfs': 'group5', - 'tenant_id': _uuid(), - 'id': ipsecpolicy_id} - - instance = self.plugin.return_value - instance.update_ipsecpolicy.return_value = return_value - - res = self.api.put(_get_path('vpn/ipsecpolicies', - id=ipsecpolicy_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_ipsecpolicy.assert_called_with(mock.ANY, - ipsecpolicy_id, - ipsecpolicy=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('ipsecpolicy', res) - self.assertEqual(res['ipsecpolicy'], return_value) - - def test_ipsecpolicy_get(self): - """Test case to get or show an ipsecpolicy.""" - ipsecpolicy_id = _uuid() - return_value = {'name': 'ipsecpolicy1', - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'encapsulation_mode': 'tunnel', - 'lifetime': { - 'units': 'seconds', - 'value': 3600}, - 'transform_protocol': 'esp', - 'pfs': 'group5', - 'tenant_id': _uuid(), - 'id': ipsecpolicy_id} - - instance = self.plugin.return_value - instance.get_ipsecpolicy.return_value = return_value - - res = self.api.get(_get_path('vpn/ipsecpolicies', - id=ipsecpolicy_id, - fmt=self.fmt)) - - instance.get_ipsecpolicy.assert_called_with(mock.ANY, - ipsecpolicy_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('ipsecpolicy', res) - self.assertEqual(res['ipsecpolicy'], return_value) - - def test_ipsecpolicy_delete(self): - """Test case to delete an ipsecpolicy.""" - self._test_entity_delete('ipsecpolicy') - - def test_vpnservice_create(self): - """Test case to create a vpnservice.""" - vpnservice_id = _uuid() - data = {'vpnservice': {'name': 'vpnservice1', - 'description': 'descr_vpn1', - 'subnet_id': _uuid(), - 'router_id': _uuid(), - 'admin_state_up': True, - 'tenant_id': _uuid()}} - return_value = copy.copy(data['vpnservice']) - return_value.update({'status': "ACTIVE", 'id': vpnservice_id}) - - instance = self.plugin.return_value - instance.create_vpnservice.return_value = return_value - res = self.api.post(_get_path('vpn/vpnservices', fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_vpnservice.assert_called_with(mock.ANY, - vpnservice=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('vpnservice', res) - self.assertEqual(res['vpnservice'], return_value) - - def test_vpnservice_list(self): - """Test case to list all vpnservices.""" - vpnservice_id = _uuid() - return_value = [{'name': 'vpnservice1', - 'tenant_id': _uuid(), - 'status': 'ACTIVE', - 'id': vpnservice_id}] - - instance = self.plugin.return_value - instance.get_vpnservice.return_value = return_value - - res = self.api.get(_get_path('vpn/vpnservices', fmt=self.fmt)) - - instance.get_vpnservices.assert_called_with(mock.ANY, - fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_vpnservice_update(self): - """Test case to update a vpnservice.""" - vpnservice_id = _uuid() - update_data = {'vpnservice': {'admin_state_up': False}} - return_value = {'name': 'vpnservice1', - 'admin_state_up': False, - 'subnet_id': _uuid(), - 'router_id': _uuid(), - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': vpnservice_id} - - instance = self.plugin.return_value - instance.update_vpnservice.return_value = return_value - - res = self.api.put(_get_path('vpn/vpnservices', - id=vpnservice_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_vpnservice.assert_called_with(mock.ANY, - vpnservice_id, - vpnservice=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('vpnservice', res) - self.assertEqual(res['vpnservice'], return_value) - - def test_vpnservice_get(self): - """Test case to get or show a vpnservice.""" - vpnservice_id = _uuid() - return_value = {'name': 'vpnservice1', - 'admin_state_up': True, - 'subnet_id': _uuid(), - 'router_id': _uuid(), - 'tenant_id': _uuid(), - 'status': "ACTIVE", - 'id': vpnservice_id} - - instance = self.plugin.return_value - instance.get_vpnservice.return_value = return_value - - res = self.api.get(_get_path('vpn/vpnservices', - id=vpnservice_id, - fmt=self.fmt)) - - instance.get_vpnservice.assert_called_with(mock.ANY, - vpnservice_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('vpnservice', res) - self.assertEqual(res['vpnservice'], return_value) - - def test_vpnservice_delete(self): - """Test case to delete a vpnservice.""" - self._test_entity_delete('vpnservice') - - def test_ipsec_site_connection_create(self): - """Test case to create a ipsec_site_connection.""" - ipsecsite_con_id = _uuid() - ikepolicy_id = _uuid() - ipsecpolicy_id = _uuid() - data = { - 'ipsec_site_connection': {'name': 'connection1', - 'description': 'Remote-connection1', - 'peer_address': '192.168.1.10', - 'peer_id': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', - '192.168.3.0/24'], - 'mtu': 1500, - 'psk': 'abcd', - 'initiator': 'bi-directional', - 'dpd': { - 'action': 'hold', - 'interval': 30, - 'timeout': 120}, - 'ikepolicy_id': ikepolicy_id, - 'ipsecpolicy_id': ipsecpolicy_id, - 'vpnservice_id': _uuid(), - 'admin_state_up': True, - 'tenant_id': _uuid()} - } - return_value = copy.copy(data['ipsec_site_connection']) - return_value.update({'status': "ACTIVE", 'id': ipsecsite_con_id}) - - instance = self.plugin.return_value - instance.create_ipsec_site_connection.return_value = return_value - res = self.api.post(_get_path('vpn/ipsec-site-connections', - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_ipsec_site_connection.assert_called_with( - mock.ANY, ipsec_site_connection=data - ) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('ipsec_site_connection', res) - self.assertEqual(res['ipsec_site_connection'], return_value) - - def test_ipsec_site_connection_list(self): - """Test case to list all ipsec_site_connections.""" - ipsecsite_con_id = _uuid() - return_value = [{'name': 'connection1', - 'peer_address': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'], - 'route_mode': 'static', - 'auth_mode': 'psk', - 'tenant_id': _uuid(), - 'status': 'ACTIVE', - 'id': ipsecsite_con_id}] - - instance = self.plugin.return_value - instance.get_ipsec_site_connections.return_value = return_value - - res = self.api.get( - _get_path('vpn/ipsec-site-connections', fmt=self.fmt)) - - instance.get_ipsec_site_connections.assert_called_with( - mock.ANY, fields=mock.ANY, filters=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_ipsec_site_connection_update(self): - """Test case to update a ipsec_site_connection.""" - ipsecsite_con_id = _uuid() - update_data = {'ipsec_site_connection': {'admin_state_up': False}} - return_value = {'name': 'connection1', - 'description': 'Remote-connection1', - 'peer_address': '192.168.1.10', - 'peer_id': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'], - 'mtu': 1500, - 'psk': 'abcd', - 'initiator': 'bi-directional', - 'dpd': { - 'action': 'hold', - 'interval': 30, - 'timeout': 120}, - 'ikepolicy_id': _uuid(), - 'ipsecpolicy_id': _uuid(), - 'vpnservice_id': _uuid(), - 'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': 'ACTIVE', - 'id': ipsecsite_con_id} - - instance = self.plugin.return_value - instance.update_ipsec_site_connection.return_value = return_value - - res = self.api.put(_get_path('vpn/ipsec-site-connections', - id=ipsecsite_con_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_ipsec_site_connection.assert_called_with( - mock.ANY, ipsecsite_con_id, ipsec_site_connection=update_data - ) - - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('ipsec_site_connection', res) - self.assertEqual(res['ipsec_site_connection'], return_value) - - def test_ipsec_site_connection_get(self): - """Test case to get or show a ipsec_site_connection.""" - ipsecsite_con_id = _uuid() - return_value = {'name': 'connection1', - 'description': 'Remote-connection1', - 'peer_address': '192.168.1.10', - 'peer_id': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', - '192.168.3.0/24'], - 'mtu': 1500, - 'psk': 'abcd', - 'initiator': 'bi-directional', - 'dpd': { - 'action': 'hold', - 'interval': 30, - 'timeout': 120}, - 'ikepolicy_id': _uuid(), - 'ipsecpolicy_id': _uuid(), - 'vpnservice_id': _uuid(), - 'admin_state_up': True, - 'tenant_id': _uuid(), - 'status': 'ACTIVE', - 'id': ipsecsite_con_id} - - instance = self.plugin.return_value - instance.get_ipsec_site_connection.return_value = return_value - - res = self.api.get(_get_path('vpn/ipsec-site-connections', - id=ipsecsite_con_id, - fmt=self.fmt)) - - instance.get_ipsec_site_connection.assert_called_with( - mock.ANY, ipsecsite_con_id, fields=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('ipsec_site_connection', res) - self.assertEqual(res['ipsec_site_connection'], return_value) - - def test_ipsec_site_connection_delete(self): - """Test case to delete a ipsec_site_connection.""" - self._test_entity_delete('ipsec_site_connection') - - -class VpnaasExtensionTestCaseXML(VpnaasExtensionTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/test_agent_config.py b/neutron/tests/unit/test_agent_config.py deleted file mode 100644 index e2408e0ce..000000000 --- a/neutron/tests/unit/test_agent_config.py +++ /dev/null @@ -1,44 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from neutron.agent.common import config -from neutron.tests import base - - -def test_setup_conf(): - conf = config.setup_conf() - assert conf.state_path.endswith('/var/lib/neutron') - - -class TestRootHelper(base.BaseTestCase): - - def test_agent_root_helper(self): - conf = config.setup_conf() - config.register_root_helper(conf) - conf.set_override('root_helper', 'my_root_helper', 'AGENT') - self.assertEqual(config.get_root_helper(conf), 'my_root_helper') - - def test_root_helper(self): - conf = config.setup_conf() - config.register_root_helper(conf) - conf.set_override('root_helper', 'my_root_helper') - self.assertEqual(config.get_root_helper(conf), 'my_root_helper') - - def test_root_default(self): - conf = config.setup_conf() - config.register_root_helper(conf) - self.assertEqual(config.get_root_helper(conf), 'sudo') diff --git a/neutron/tests/unit/test_agent_ext_plugin.py b/neutron/tests/unit/test_agent_ext_plugin.py deleted file mode 100644 index a59cd3348..000000000 --- a/neutron/tests/unit/test_agent_ext_plugin.py +++ /dev/null @@ -1,259 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2013 OpenStack Foundation. -# All Rights Reserved. -# -# 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 copy -import time - -from oslo.config import cfg -from webob import exc - -from neutron.api.v2 import attributes -from neutron.common import constants -from neutron.common import topics -from neutron import context -from neutron.db import agents_db -from neutron.db import db_base_plugin_v2 -from neutron.extensions import agent -from neutron.openstack.common import log as logging -from neutron.openstack.common import timeutils -from neutron.openstack.common import uuidutils -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_db_plugin - - -LOG = logging.getLogger(__name__) - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path -L3_HOSTA = 'hosta' -DHCP_HOSTA = 'hosta' -L3_HOSTB = 'hostb' -DHCP_HOSTC = 'hostc' -DHCP_HOST1 = 'host1' -LBAAS_HOSTA = 'hosta' -LBAAS_HOSTB = 'hostb' - - -class AgentTestExtensionManager(object): - - def get_resources(self): - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - agent.RESOURCE_ATTRIBUTE_MAP) - return agent.Agent.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -# This plugin class is just for testing -class TestAgentPlugin(db_base_plugin_v2.NeutronDbPluginV2, - agents_db.AgentDbMixin): - supported_extension_aliases = ["agent"] - - -class AgentDBTestMixIn(object): - - def _list_agents(self, expected_res_status=None, - neutron_context=None, - query_string=None): - agent_res = self._list('agents', - neutron_context=neutron_context, - query_params=query_string) - if expected_res_status: - self.assertEqual(agent_res.status_int, expected_res_status) - return agent_res - - def _register_agent_states(self, lbaas_agents=False): - """Register two L3 agents and two DHCP agents.""" - l3_hosta = { - 'binary': 'neutron-l3-agent', - 'host': L3_HOSTA, - 'topic': topics.L3_AGENT, - 'configurations': {'use_namespaces': True, - 'router_id': None, - 'handle_internal_only_routers': - True, - 'gateway_external_network_id': - None, - 'interface_driver': 'interface_driver', - }, - 'agent_type': constants.AGENT_TYPE_L3} - l3_hostb = copy.deepcopy(l3_hosta) - l3_hostb['host'] = L3_HOSTB - dhcp_hosta = { - 'binary': 'neutron-dhcp-agent', - 'host': DHCP_HOSTA, - 'topic': 'DHCP_AGENT', - 'configurations': {'dhcp_driver': 'dhcp_driver', - 'use_namespaces': True, - }, - 'agent_type': constants.AGENT_TYPE_DHCP} - dhcp_hostc = copy.deepcopy(dhcp_hosta) - dhcp_hostc['host'] = DHCP_HOSTC - lbaas_hosta = { - 'binary': 'neutron-loadbalancer-agent', - 'host': LBAAS_HOSTA, - 'topic': 'LOADBALANCER_AGENT', - 'configurations': {'device_drivers': ['haproxy_ns']}, - 'agent_type': constants.AGENT_TYPE_LOADBALANCER} - lbaas_hostb = copy.deepcopy(lbaas_hosta) - lbaas_hostb['host'] = LBAAS_HOSTB - callback = agents_db.AgentExtRpcCallback() - callback.report_state(self.adminContext, - agent_state={'agent_state': l3_hosta}, - time=timeutils.strtime()) - callback.report_state(self.adminContext, - agent_state={'agent_state': l3_hostb}, - time=timeutils.strtime()) - callback.report_state(self.adminContext, - agent_state={'agent_state': dhcp_hosta}, - time=timeutils.strtime()) - callback.report_state(self.adminContext, - agent_state={'agent_state': dhcp_hostc}, - time=timeutils.strtime()) - - res = [l3_hosta, l3_hostb, dhcp_hosta, dhcp_hostc] - if lbaas_agents: - callback.report_state(self.adminContext, - agent_state={'agent_state': lbaas_hosta}, - time=timeutils.strtime()) - callback.report_state(self.adminContext, - agent_state={'agent_state': lbaas_hostb}, - time=timeutils.strtime()) - res += [lbaas_hosta, lbaas_hostb] - - return res - - def _register_one_dhcp_agent(self): - """Register one DHCP agent.""" - dhcp_host = { - 'binary': 'neutron-dhcp-agent', - 'host': DHCP_HOST1, - 'topic': 'DHCP_AGENT', - 'configurations': {'dhcp_driver': 'dhcp_driver', - 'use_namespaces': True, - }, - 'agent_type': constants.AGENT_TYPE_DHCP} - callback = agents_db.AgentExtRpcCallback() - callback.report_state(self.adminContext, - agent_state={'agent_state': dhcp_host}, - time=timeutils.strtime()) - return [dhcp_host] - - def _register_one_l3_agent(self, host=L3_HOSTA, internal_only=True, - ext_net_id='', ext_bridge=''): - l3 = { - 'binary': 'neutron-l3-agent', - 'host': host, - 'topic': topics.L3_AGENT, - 'configurations': {'use_namespaces': True, - 'router_id': None, - 'handle_internal_only_routers': internal_only, - 'external_network_bridge': ext_bridge, - 'gateway_external_network_id': ext_net_id, - 'interface_driver': 'interface_driver', - }, - 'agent_type': constants.AGENT_TYPE_L3} - callback = agents_db.AgentExtRpcCallback() - callback.report_state(self.adminContext, - agent_state={'agent_state': l3}, - time=timeutils.strtime()) - - -class AgentDBTestCase(AgentDBTestMixIn, - test_db_plugin.NeutronDbPluginV2TestCase): - fmt = 'json' - - def setUp(self): - self.adminContext = context.get_admin_context() - plugin = 'neutron.tests.unit.test_agent_ext_plugin.TestAgentPlugin' - # for these tests we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - # Save the original RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - ext_mgr = AgentTestExtensionManager() - self.addCleanup(self.restore_resource_attribute_map) - super(AgentDBTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr) - - def restore_resource_attribute_map(self): - # Restore the originak RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - - def test_create_agent(self): - data = {'agent': {}} - _req = self.new_create_request('agents', data, self.fmt) - _req.environ['neutron.context'] = context.Context( - '', 'tenant_id') - res = _req.get_response(self.ext_api) - self.assertEqual(res.status_int, exc.HTTPBadRequest.code) - - def test_list_agent(self): - agents = self._register_agent_states() - res = self._list('agents') - for agent in res['agents']: - if (agent['host'] == DHCP_HOSTA and - agent['agent_type'] == constants.AGENT_TYPE_DHCP): - self.assertEqual( - 'dhcp_driver', - agent['configurations']['dhcp_driver']) - break - self.assertEqual(len(agents), len(res['agents'])) - - def test_show_agent(self): - self._register_agent_states() - agents = self._list_agents( - query_string='binary=neutron-l3-agent') - self.assertEqual(2, len(agents['agents'])) - agent = self._show('agents', agents['agents'][0]['id']) - self.assertEqual('neutron-l3-agent', agent['agent']['binary']) - - def test_update_agent(self): - self._register_agent_states() - agents = self._list_agents( - query_string='binary=neutron-l3-agent&host=' + L3_HOSTB) - self.assertEqual(1, len(agents['agents'])) - com_id = agents['agents'][0]['id'] - agent = self._show('agents', com_id) - new_agent = {} - new_agent['agent'] = {} - new_agent['agent']['admin_state_up'] = False - new_agent['agent']['description'] = 'description' - self._update('agents', com_id, new_agent) - agent = self._show('agents', com_id) - self.assertFalse(agent['agent']['admin_state_up']) - self.assertEqual('description', agent['agent']['description']) - - def test_dead_agent(self): - cfg.CONF.set_override('agent_down_time', 1) - self._register_agent_states() - time.sleep(1.5) - agents = self._list_agents( - query_string='binary=neutron-l3-agent&host=' + L3_HOSTB) - self.assertFalse(agents['agents'][0]['alive']) - - -class AgentDBTestCaseXML(AgentDBTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/test_agent_linux_utils.py b/neutron/tests/unit/test_agent_linux_utils.py deleted file mode 100644 index d54d9f1eb..000000000 --- a/neutron/tests/unit/test_agent_linux_utils.py +++ /dev/null @@ -1,162 +0,0 @@ -# Copyright 2012, VMware, Inc. -# -# 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 fixtures -import mock -import testtools - -from neutron.agent.linux import utils -from neutron.tests import base - - -class FakeCreateProcess(object): - class FakeStdin(object): - def close(self): - pass - - def __init__(self, returncode): - self.returncode = returncode - self.stdin = self.FakeStdin() - - def communicate(self, process_input=None): - return '', '' - - -class AgentUtilsExecuteTest(base.BaseTestCase): - def setUp(self): - super(AgentUtilsExecuteTest, self).setUp() - self.root_helper = "echo" - self.test_file = self.useFixture( - fixtures.TempDir()).join("test_execute.tmp") - open(self.test_file, 'w').close() - self.mock_popen_p = mock.patch("subprocess.Popen.communicate") - self.mock_popen = self.mock_popen_p.start() - - def test_without_helper(self): - expected = "%s\n" % self.test_file - self.mock_popen.return_value = [expected, ""] - result = utils.execute(["ls", self.test_file]) - self.assertEqual(result, expected) - - def test_with_helper(self): - expected = "ls %s\n" % self.test_file - self.mock_popen.return_value = [expected, ""] - result = utils.execute(["ls", self.test_file], - self.root_helper) - self.assertEqual(result, expected) - - def test_stderr_true(self): - expected = "%s\n" % self.test_file - self.mock_popen.return_value = [expected, ""] - out = utils.execute(["ls", self.test_file], return_stderr=True) - self.assertIsInstance(out, tuple) - self.assertEqual(out, (expected, "")) - - def test_check_exit_code(self): - self.mock_popen.return_value = ["", ""] - stdout = utils.execute(["ls", self.test_file[:-1]], - check_exit_code=False) - self.assertEqual(stdout, "") - - def test_execute_raises(self): - self.mock_popen.side_effect = RuntimeError - self.assertRaises(RuntimeError, utils.execute, - ["ls", self.test_file[:-1]]) - - def test_process_input(self): - expected = "%s\n" % self.test_file[:-1] - self.mock_popen.return_value = [expected, ""] - result = utils.execute(["cat"], process_input="%s\n" % - self.test_file[:-1]) - self.assertEqual(result, expected) - - def test_with_addl_env(self): - expected = "%s\n" % self.test_file - self.mock_popen.return_value = [expected, ""] - result = utils.execute(["ls", self.test_file], - addl_env={'foo': 'bar'}) - self.assertEqual(result, expected) - - def test_return_code_log_error_raise_runtime(self): - with mock.patch.object(utils, 'create_process') as create_process: - create_process.return_value = FakeCreateProcess(1), 'ls' - with mock.patch.object(utils, 'LOG') as log: - self.assertRaises(RuntimeError, utils.execute, - ['ls']) - self.assertTrue(log.error.called) - - def test_return_code_log_error_no_raise_runtime(self): - with mock.patch.object(utils, 'create_process') as create_process: - create_process.return_value = FakeCreateProcess(1), 'ls' - with mock.patch.object(utils, 'LOG') as log: - utils.execute(['ls'], check_exit_code=False) - self.assertTrue(log.error.called) - - def test_return_code_log_debug(self): - with mock.patch.object(utils, 'create_process') as create_process: - create_process.return_value = FakeCreateProcess(0), 'ls' - with mock.patch.object(utils, 'LOG') as log: - utils.execute(['ls']) - self.assertTrue(log.debug.called) - - -class AgentUtilsGetInterfaceMAC(base.BaseTestCase): - def test_get_interface_mac(self): - expect_val = '01:02:03:04:05:06' - with mock.patch('fcntl.ioctl') as ioctl: - ioctl.return_value = ''.join(['\x00' * 18, - '\x01\x02\x03\x04\x05\x06', - '\x00' * 232]) - actual_val = utils.get_interface_mac('eth0') - self.assertEqual(actual_val, expect_val) - - -class AgentUtilsReplaceFile(base.BaseTestCase): - def test_replace_file(self): - # make file to replace - with mock.patch('tempfile.NamedTemporaryFile') as ntf: - ntf.return_value.name = '/baz' - with mock.patch('os.chmod') as chmod: - with mock.patch('os.rename') as rename: - utils.replace_file('/foo', 'bar') - - expected = [mock.call('w+', dir='/', delete=False), - mock.call().write('bar'), - mock.call().close()] - - ntf.assert_has_calls(expected) - chmod.assert_called_once_with('/baz', 0o644) - rename.assert_called_once_with('/baz', '/foo') - - -class TestFindChildPids(base.BaseTestCase): - - def test_returns_empty_list_for_exit_code_1(self): - with mock.patch.object(utils, 'execute', - side_effect=RuntimeError('Exit code: 1')): - self.assertEqual(utils.find_child_pids(-1), []) - - def test_returns_empty_list_for_no_output(self): - with mock.patch.object(utils, 'execute', return_value=''): - self.assertEqual(utils.find_child_pids(-1), []) - - def test_returns_list_of_child_process_ids_for_good_ouput(self): - with mock.patch.object(utils, 'execute', return_value=' 123 \n 185\n'): - self.assertEqual(utils.find_child_pids(-1), ['123', '185']) - - def test_raises_unknown_exception(self): - with testtools.ExpectedException(RuntimeError): - with mock.patch.object(utils, 'execute', - side_effect=RuntimeError()): - utils.find_child_pids(-1) diff --git a/neutron/tests/unit/test_agent_netns_cleanup.py b/neutron/tests/unit/test_agent_netns_cleanup.py deleted file mode 100644 index 71b1cd6da..000000000 --- a/neutron/tests/unit/test_agent_netns_cleanup.py +++ /dev/null @@ -1,258 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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 neutron.agent.linux import interface -from neutron.agent import netns_cleanup_util as util -from neutron.tests import base - - -class TestNetnsCleanup(base.BaseTestCase): - - def test_setup_conf(self): - expected_opts = interface.OPTS - conf = util.setup_conf() - self.assertTrue(all([opt.name in conf for opt in expected_opts])) - - def test_kill_dhcp(self, dhcp_active=True): - conf = mock.Mock() - conf.AGENT.root_helper = 'sudo', - conf.dhcp_driver = 'driver' - - method_to_patch = 'neutron.openstack.common.importutils.import_object' - - with mock.patch(method_to_patch) as import_object: - driver = mock.Mock() - driver.active = dhcp_active - import_object.return_value = driver - - util.kill_dhcp(conf, 'ns') - - expected_params = {'conf': conf, 'network': mock.ANY, - 'root_helper': conf.AGENT.root_helper, - 'plugin': mock.ANY} - import_object.assert_called_once_with('driver', **expected_params) - - if dhcp_active: - driver.assert_has_calls([mock.call.disable()]) - else: - self.assertFalse(driver.called) - - def test_kill_dhcp_no_active(self): - self.test_kill_dhcp(False) - - def test_eligible_for_deletion_ns_not_uuid(self): - ns = 'not_a_uuid' - self.assertFalse(util.eligible_for_deletion(mock.Mock(), ns)) - - def _test_eligible_for_deletion_helper(self, prefix, force, is_empty, - expected): - ns = prefix + '6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d' - conf = mock.Mock() - - with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip_wrap: - ip_wrap.return_value.namespace_is_empty.return_value = is_empty - self.assertEqual(util.eligible_for_deletion(conf, ns, force), - expected) - - expected_calls = [mock.call(conf.AGENT.root_helper, ns)] - if not force: - expected_calls.append(mock.call().namespace_is_empty()) - ip_wrap.assert_has_calls(expected_calls) - - def test_eligible_for_deletion_empty(self): - self._test_eligible_for_deletion_helper('qrouter-', False, True, True) - - def test_eligible_for_deletion_not_empty(self): - self._test_eligible_for_deletion_helper('qdhcp-', False, False, False) - - def test_eligible_for_deletion_not_empty_forced(self): - self._test_eligible_for_deletion_helper('qdhcp-', True, False, True) - - def test_unplug_device_regular_device(self): - conf = mock.Mock() - device = mock.Mock() - - util.unplug_device(conf, device) - device.assert_has_calls([mock.call.link.delete()]) - - def test_unplug_device_ovs_port(self): - conf = mock.Mock() - conf.ovs_integration_bridge = 'br-int' - - device = mock.Mock() - device.name = 'tap1' - device.link.delete.side_effect = RuntimeError - - with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge') as ovs_br_cls: - br_patch = mock.patch( - 'neutron.agent.linux.ovs_lib.get_bridge_for_iface') - with br_patch as mock_get_bridge_for_iface: - mock_get_bridge_for_iface.return_value = 'br-int' - ovs_bridge = mock.Mock() - ovs_br_cls.return_value = ovs_bridge - - util.unplug_device(conf, device) - - mock_get_bridge_for_iface.assert_called_once_with( - conf.AGENT.root_helper, 'tap1') - ovs_br_cls.assert_called_once_with('br-int', - conf.AGENT.root_helper) - ovs_bridge.assert_has_calls( - [mock.call.delete_port(device.name)]) - - def test_unplug_device_cannot_determine_bridge_port(self): - conf = mock.Mock() - conf.ovs_integration_bridge = 'br-int' - - device = mock.Mock() - device.name = 'tap1' - device.link.delete.side_effect = RuntimeError - - with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge') as ovs_br_cls: - br_patch = mock.patch( - 'neutron.agent.linux.ovs_lib.get_bridge_for_iface') - with br_patch as mock_get_bridge_for_iface: - with mock.patch.object(util.LOG, 'debug') as debug: - mock_get_bridge_for_iface.return_value = None - ovs_bridge = mock.Mock() - ovs_br_cls.return_value = ovs_bridge - - util.unplug_device(conf, device) - - mock_get_bridge_for_iface.assert_called_once_with( - conf.AGENT.root_helper, 'tap1') - self.assertEqual(ovs_br_cls.mock_calls, []) - self.assertTrue(debug.called) - - def _test_destroy_namespace_helper(self, force, num_devices): - ns = 'qrouter-6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d' - conf = mock.Mock() -# conf.AGENT.root_helper = 'sudo' - - lo_device = mock.Mock() - lo_device.name = 'lo' - - devices = [lo_device] - - while num_devices: - dev = mock.Mock() - dev.name = 'tap%d' % num_devices - devices.append(dev) - num_devices -= 1 - - with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip_wrap: - ip_wrap.return_value.get_devices.return_value = devices - ip_wrap.return_value.netns.exists.return_value = True - - with mock.patch.object(util, 'unplug_device') as unplug: - - with mock.patch.object(util, 'kill_dhcp') as kill_dhcp: - util.destroy_namespace(conf, ns, force) - expected = [mock.call(conf.AGENT.root_helper, ns)] - - if force: - expected.extend([ - mock.call().netns.exists(ns), - mock.call().get_devices(exclude_loopback=True)]) - self.assertTrue(kill_dhcp.called) - unplug.assert_has_calls( - [mock.call(conf, d) for d in - devices[1:]]) - - expected.append(mock.call().garbage_collect_namespace()) - ip_wrap.assert_has_calls(expected) - - def test_destroy_namespace_empty(self): - self._test_destroy_namespace_helper(False, 0) - - def test_destroy_namespace_not_empty(self): - self._test_destroy_namespace_helper(False, 1) - - def test_destroy_namespace_not_empty_forced(self): - self._test_destroy_namespace_helper(True, 2) - - def test_destroy_namespace_exception(self): - ns = 'qrouter-6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d' - conf = mock.Mock() - conf.AGENT.root_helper = 'sudo' - with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip_wrap: - ip_wrap.side_effect = Exception() - util.destroy_namespace(conf, ns) - - def test_main(self): - namespaces = ['ns1', 'ns2'] - with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip_wrap: - ip_wrap.get_namespaces.return_value = namespaces - - with mock.patch('eventlet.sleep') as eventlet_sleep: - conf = mock.Mock() - conf.force = False - methods_to_mock = dict( - eligible_for_deletion=mock.DEFAULT, - destroy_namespace=mock.DEFAULT, - setup_conf=mock.DEFAULT) - - with mock.patch.multiple(util, **methods_to_mock) as mocks: - mocks['eligible_for_deletion'].return_value = True - mocks['setup_conf'].return_value = conf - with mock.patch('neutron.common.config.setup_logging'): - util.main() - - mocks['eligible_for_deletion'].assert_has_calls( - [mock.call(conf, 'ns1', False), - mock.call(conf, 'ns2', False)]) - - mocks['destroy_namespace'].assert_has_calls( - [mock.call(conf, 'ns1', False), - mock.call(conf, 'ns2', False)]) - - ip_wrap.assert_has_calls( - [mock.call.get_namespaces(conf.AGENT.root_helper)]) - - eventlet_sleep.assert_called_once_with(2) - - def test_main_no_candidates(self): - namespaces = ['ns1', 'ns2'] - with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip_wrap: - ip_wrap.get_namespaces.return_value = namespaces - - with mock.patch('eventlet.sleep') as eventlet_sleep: - conf = mock.Mock() - conf.force = False - methods_to_mock = dict( - eligible_for_deletion=mock.DEFAULT, - destroy_namespace=mock.DEFAULT, - setup_conf=mock.DEFAULT) - - with mock.patch.multiple(util, **methods_to_mock) as mocks: - mocks['eligible_for_deletion'].return_value = False - mocks['setup_conf'].return_value = conf - with mock.patch('neutron.common.config.setup_logging'): - util.main() - - ip_wrap.assert_has_calls( - [mock.call.get_namespaces(conf.AGENT.root_helper)]) - - mocks['eligible_for_deletion'].assert_has_calls( - [mock.call(conf, 'ns1', False), - mock.call(conf, 'ns2', False)]) - - self.assertFalse(mocks['destroy_namespace'].called) - - self.assertFalse(eventlet_sleep.called) diff --git a/neutron/tests/unit/test_agent_ovs_cleanup.py b/neutron/tests/unit/test_agent_ovs_cleanup.py deleted file mode 100644 index defdf5a2c..000000000 --- a/neutron/tests/unit/test_agent_ovs_cleanup.py +++ /dev/null @@ -1,93 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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 contextlib -import itertools -import mock - -from neutron.agent.linux import ip_lib -from neutron.agent.linux import ovs_lib -from neutron.agent import ovs_cleanup_util as util -from neutron.openstack.common import uuidutils -from neutron.tests import base - - -class TestOVSCleanup(base.BaseTestCase): - - def test_setup_conf(self): - conf = util.setup_conf() - self.assertEqual(conf.external_network_bridge, 'br-ex') - self.assertEqual(conf.ovs_integration_bridge, 'br-int') - self.assertFalse(conf.ovs_all_ports) - self.assertEqual(conf.AGENT.root_helper, 'sudo') - - def test_main(self): - bridges = ['br-int', 'br-ex'] - ports = ['p1', 'p2', 'p3'] - conf = mock.Mock() - conf.AGENT.root_helper = 'dummy_sudo' - conf.ovs_all_ports = False - conf.ovs_integration_bridge = 'br-int' - conf.external_network_bridge = 'br-ex' - with contextlib.nested( - mock.patch('neutron.common.config.setup_logging'), - mock.patch('neutron.agent.ovs_cleanup_util.setup_conf', - return_value=conf), - mock.patch('neutron.agent.linux.ovs_lib.get_bridges', - return_value=bridges), - mock.patch('neutron.agent.linux.ovs_lib.OVSBridge'), - mock.patch.object(util, 'collect_neutron_ports', - return_value=ports), - mock.patch.object(util, 'delete_neutron_ports') - ) as (_log, _conf, _get, ovs, collect, delete): - with mock.patch('neutron.common.config.setup_logging'): - util.main() - ovs.assert_has_calls([mock.call().delete_ports( - all_ports=False)]) - collect.assert_called_once_with(set(bridges), 'dummy_sudo') - delete.assert_called_once_with(ports, 'dummy_sudo') - - def test_collect_neutron_ports(self): - port1 = ovs_lib.VifPort('tap1234', 1, uuidutils.generate_uuid(), - '11:22:33:44:55:66', 'br') - port2 = ovs_lib.VifPort('tap5678', 2, uuidutils.generate_uuid(), - '77:88:99:aa:bb:cc', 'br') - port3 = ovs_lib.VifPort('tap90ab', 3, uuidutils.generate_uuid(), - '99:00:aa:bb:cc:dd', 'br') - ports = [[port1, port2], [port3]] - portnames = [p.port_name for p in itertools.chain(*ports)] - with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge') as ovs: - ovs.return_value.get_vif_ports.side_effect = ports - bridges = ['br-int', 'br-ex'] - ret = util.collect_neutron_ports(bridges, 'dummy_sudo') - self.assertEqual(ret, portnames) - - def test_delete_neutron_ports(self): - ports = ['tap1234', 'tap5678', 'tap09ab'] - port_found = [True, False, True] - with contextlib.nested( - mock.patch.object(ip_lib, 'device_exists', - side_effect=port_found), - mock.patch.object(ip_lib, 'IPDevice') - ) as (device_exists, ip_dev): - util.delete_neutron_ports(ports, 'dummy_sudo') - device_exists.assert_has_calls([mock.call(p) for p in ports]) - ip_dev.assert_has_calls( - [mock.call('tap1234', 'dummy_sudo'), - mock.call().link.delete(), - mock.call('tap09ab', 'dummy_sudo'), - mock.call().link.delete()]) diff --git a/neutron/tests/unit/test_db_plugin.py b/neutron/tests/unit/test_db_plugin.py deleted file mode 100644 index cbc901ec8..000000000 --- a/neutron/tests/unit/test_db_plugin.py +++ /dev/null @@ -1,3982 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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 contextlib -import copy - -import mock -from oslo.config import cfg -from testtools import matchers -import webob.exc - -import neutron -from neutron.api import api_common -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.api.v2 import router -from neutron.common import constants -from neutron.common import exceptions as n_exc -from neutron.common import ipv6_utils -from neutron.common import test_lib -from neutron.common import utils -from neutron import context -from neutron.db import api as db -from neutron.db import db_base_plugin_v2 -from neutron.db import models_v2 -from neutron import manager -from neutron.openstack.common import importutils -from neutron.tests import base -from neutron.tests.unit import test_extensions -from neutron.tests.unit import testlib_api - -DB_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2' - - -def optional_ctx(obj, fallback): - if not obj: - return fallback() - - @contextlib.contextmanager - def context_wrapper(): - yield obj - return context_wrapper() - - -def _fake_get_pagination_helper(self, request): - return api_common.PaginationEmulatedHelper(request, self._primary_key) - - -def _fake_get_sorting_helper(self, request): - return api_common.SortingEmulatedHelper(request, self._attr_info) - - -class NeutronDbPluginV2TestCase(testlib_api.WebTestCase): - fmt = 'json' - resource_prefix_map = {} - - def setUp(self, plugin=None, service_plugins=None, - ext_mgr=None): - - super(NeutronDbPluginV2TestCase, self).setUp() - cfg.CONF.set_override('notify_nova_on_port_status_changes', False) - # Make sure at each test according extensions for the plugin is loaded - extensions.PluginAwareExtensionManager._instance = None - # Save the attributes map in case the plugin will alter it - # loading extensions - # Note(salvatore-orlando): shallow copy is not good enough in - # this case, but copy.deepcopy does not seem to work, since it - # causes test failures - self._attribute_map_bk = {} - for item in attributes.RESOURCE_ATTRIBUTE_MAP: - self._attribute_map_bk[item] = (attributes. - RESOURCE_ATTRIBUTE_MAP[item]. - copy()) - self._tenant_id = 'test-tenant' - - if not plugin: - plugin = DB_PLUGIN_KLASS - - # Create the default configurations - args = ['--config-file', base.etcdir('neutron.conf.test')] - # If test_config specifies some config-file, use it, as well - for config_file in test_lib.test_config.get('config_files', []): - args.extend(['--config-file', config_file]) - self.config_parse(args=args) - # Update the plugin - self.setup_coreplugin(plugin) - cfg.CONF.set_override( - 'service_plugins', - [test_lib.test_config.get(key, default) - for key, default in (service_plugins or {}).iteritems()] - ) - - cfg.CONF.set_override('base_mac', "12:34:56:78:90:ab") - cfg.CONF.set_override('max_dns_nameservers', 2) - cfg.CONF.set_override('max_subnet_host_routes', 2) - cfg.CONF.set_override('allow_pagination', True) - cfg.CONF.set_override('allow_sorting', True) - self.api = router.APIRouter() - # Set the defualt status - self.net_create_status = 'ACTIVE' - self.port_create_status = 'ACTIVE' - - def _is_native_bulk_supported(): - plugin_obj = manager.NeutronManager.get_plugin() - native_bulk_attr_name = ("_%s__native_bulk_support" - % plugin_obj.__class__.__name__) - return getattr(plugin_obj, native_bulk_attr_name, False) - - self._skip_native_bulk = not _is_native_bulk_supported() - - def _is_native_pagination_support(): - native_pagination_attr_name = ( - "_%s__native_pagination_support" % - manager.NeutronManager.get_plugin().__class__.__name__) - return (cfg.CONF.allow_pagination and - getattr(manager.NeutronManager.get_plugin(), - native_pagination_attr_name, False)) - - self._skip_native_pagination = not _is_native_pagination_support() - - def _is_native_sorting_support(): - native_sorting_attr_name = ( - "_%s__native_sorting_support" % - manager.NeutronManager.get_plugin().__class__.__name__) - return (cfg.CONF.allow_sorting and - getattr(manager.NeutronManager.get_plugin(), - native_sorting_attr_name, False)) - - self._skip_native_sorting = not _is_native_sorting_support() - if ext_mgr: - self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr) - - def tearDown(self): - self.api = None - self._deserializers = None - self._skip_native_bulk = None - self._skip_native_pagination = None - self._skip_native_sortin = None - self.ext_api = None - # NOTE(jkoelker) for a 'pluggable' framework, Neutron sure - # doesn't like when the plugin changes ;) - db.clear_db() - # Restore the original attribute map - attributes.RESOURCE_ATTRIBUTE_MAP = self._attribute_map_bk - super(NeutronDbPluginV2TestCase, self).tearDown() - - def _req(self, method, resource, data=None, fmt=None, id=None, params=None, - action=None, subresource=None, sub_id=None, context=None): - fmt = fmt or self.fmt - - path = '/%s.%s' % ( - '/'.join(p for p in - (resource, id, subresource, sub_id, action) if p), - fmt - ) - - prefix = self.resource_prefix_map.get(resource) - if prefix: - path = prefix + path - - content_type = 'application/%s' % fmt - body = None - if data is not None: # empty dict is valid - body = self.serialize(data) - return testlib_api.create_request(path, body, content_type, method, - query_string=params, context=context) - - def new_create_request(self, resource, data, fmt=None, id=None, - subresource=None): - return self._req('POST', resource, data, fmt, id=id, - subresource=subresource) - - def new_list_request(self, resource, fmt=None, params=None, - subresource=None): - return self._req( - 'GET', resource, None, fmt, params=params, subresource=subresource - ) - - def new_show_request(self, resource, id, fmt=None, - subresource=None, fields=None): - if fields: - params = "&".join(["fields=%s" % x for x in fields]) - else: - params = None - return self._req('GET', resource, None, fmt, id=id, - params=params, subresource=subresource) - - def new_delete_request(self, resource, id, fmt=None, subresource=None, - sub_id=None): - return self._req( - 'DELETE', - resource, - None, - fmt, - id=id, - subresource=subresource, - sub_id=sub_id - ) - - def new_update_request(self, resource, data, id, fmt=None, - subresource=None, context=None): - return self._req( - 'PUT', resource, data, fmt, id=id, subresource=subresource, - context=context - ) - - def new_action_request(self, resource, data, id, action, fmt=None, - subresource=None): - return self._req( - 'PUT', - resource, - data, - fmt, - id=id, - action=action, - subresource=subresource - ) - - def deserialize(self, content_type, response): - ctype = 'application/%s' % content_type - data = self._deserializers[ctype].deserialize(response.body)['body'] - return data - - def _create_bulk_from_list(self, fmt, resource, objects, **kwargs): - """Creates a bulk request from a list of objects.""" - collection = "%ss" % resource - req_data = {collection: objects} - req = self.new_create_request(collection, req_data, fmt) - if ('set_context' in kwargs and - kwargs['set_context'] is True and - 'tenant_id' in kwargs): - # create a specific auth context for this request - req.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - elif 'context' in kwargs: - req.environ['neutron.context'] = kwargs['context'] - return req.get_response(self.api) - - def _create_bulk(self, fmt, number, resource, data, name='test', **kwargs): - """Creates a bulk request for any kind of resource.""" - objects = [] - collection = "%ss" % resource - for i in range(number): - obj = copy.deepcopy(data) - obj[resource]['name'] = "%s_%s" % (name, i) - if 'override' in kwargs and i in kwargs['override']: - obj[resource].update(kwargs['override'][i]) - objects.append(obj) - req_data = {collection: objects} - req = self.new_create_request(collection, req_data, fmt) - if ('set_context' in kwargs and - kwargs['set_context'] is True and - 'tenant_id' in kwargs): - # create a specific auth context for this request - req.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - elif 'context' in kwargs: - req.environ['neutron.context'] = kwargs['context'] - return req.get_response(self.api) - - def _create_network(self, fmt, name, admin_state_up, - arg_list=None, **kwargs): - data = {'network': {'name': name, - 'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id}} - for arg in (('admin_state_up', 'tenant_id', 'shared') + - (arg_list or ())): - # Arg must be present - if arg in kwargs: - data['network'][arg] = kwargs[arg] - network_req = self.new_create_request('networks', data, fmt) - if (kwargs.get('set_context') and 'tenant_id' in kwargs): - # create a specific auth context for this request - network_req.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - - return network_req.get_response(self.api) - - def _create_network_bulk(self, fmt, number, name, - admin_state_up, **kwargs): - base_data = {'network': {'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id}} - return self._create_bulk(fmt, number, 'network', base_data, **kwargs) - - def _create_subnet(self, fmt, net_id, cidr, - expected_res_status=None, **kwargs): - data = {'subnet': {'network_id': net_id, - 'cidr': cidr, - 'ip_version': 4, - 'tenant_id': self._tenant_id}} - for arg in ('ip_version', 'tenant_id', - 'enable_dhcp', 'allocation_pools', - 'dns_nameservers', 'host_routes', - 'shared', 'ipv6_ra_mode', 'ipv6_address_mode'): - # Arg must be present and not null (but can be false) - if arg in kwargs and kwargs[arg] is not None: - data['subnet'][arg] = kwargs[arg] - - if ('gateway_ip' in kwargs and - kwargs['gateway_ip'] is not attributes.ATTR_NOT_SPECIFIED): - data['subnet']['gateway_ip'] = kwargs['gateway_ip'] - - subnet_req = self.new_create_request('subnets', data, fmt) - if (kwargs.get('set_context') and 'tenant_id' in kwargs): - # create a specific auth context for this request - subnet_req.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - - subnet_res = subnet_req.get_response(self.api) - if expected_res_status: - self.assertEqual(subnet_res.status_int, expected_res_status) - return subnet_res - - def _create_subnet_bulk(self, fmt, number, net_id, name, - ip_version=4, **kwargs): - base_data = {'subnet': {'network_id': net_id, - 'ip_version': ip_version, - 'tenant_id': self._tenant_id}} - # auto-generate cidrs as they should not overlap - overrides = dict((k, v) - for (k, v) in zip(range(number), - [{'cidr': "10.0.%s.0/24" % num} - for num in range(number)])) - kwargs.update({'override': overrides}) - return self._create_bulk(fmt, number, 'subnet', base_data, **kwargs) - - def _create_port(self, fmt, net_id, expected_res_status=None, - arg_list=None, **kwargs): - data = {'port': {'network_id': net_id, - 'tenant_id': self._tenant_id}} - - for arg in (('admin_state_up', 'device_id', - 'mac_address', 'name', 'fixed_ips', - 'tenant_id', 'device_owner', 'security_groups') + - (arg_list or ())): - # Arg must be present - if arg in kwargs: - data['port'][arg] = kwargs[arg] - # create a dhcp port device id if one hasn't been supplied - if ('device_owner' in kwargs and - kwargs['device_owner'] == constants.DEVICE_OWNER_DHCP and - 'host' in kwargs and - not 'device_id' in kwargs): - device_id = utils.get_dhcp_agent_device_id(net_id, kwargs['host']) - data['port']['device_id'] = device_id - port_req = self.new_create_request('ports', data, fmt) - if (kwargs.get('set_context') and 'tenant_id' in kwargs): - # create a specific auth context for this request - port_req.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - - port_res = port_req.get_response(self.api) - if expected_res_status: - self.assertEqual(port_res.status_int, expected_res_status) - return port_res - - def _list_ports(self, fmt, expected_res_status=None, - net_id=None, **kwargs): - query_params = None - if net_id: - query_params = "network_id=%s" % net_id - port_req = self.new_list_request('ports', fmt, query_params) - if ('set_context' in kwargs and - kwargs['set_context'] is True and - 'tenant_id' in kwargs): - # create a specific auth context for this request - port_req.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - - port_res = port_req.get_response(self.api) - if expected_res_status: - self.assertEqual(port_res.status_int, expected_res_status) - return port_res - - def _create_port_bulk(self, fmt, number, net_id, name, - admin_state_up, **kwargs): - base_data = {'port': {'network_id': net_id, - 'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id}} - return self._create_bulk(fmt, number, 'port', base_data, **kwargs) - - def _make_network(self, fmt, name, admin_state_up, **kwargs): - res = self._create_network(fmt, name, admin_state_up, **kwargs) - # TODO(salvatore-orlando): do exception handling in this test module - # in a uniform way (we do it differently for ports, subnets, and nets - # Things can go wrong - raise HTTP exc with res code only - # so it can be caught by unit tests - if res.status_int >= webob.exc.HTTPClientError.code: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - def _make_subnet(self, fmt, network, gateway, cidr, - allocation_pools=None, ip_version=4, enable_dhcp=True, - dns_nameservers=None, host_routes=None, shared=None, - ipv6_ra_mode=None, ipv6_address_mode=None): - res = self._create_subnet(fmt, - net_id=network['network']['id'], - cidr=cidr, - gateway_ip=gateway, - tenant_id=network['network']['tenant_id'], - allocation_pools=allocation_pools, - ip_version=ip_version, - enable_dhcp=enable_dhcp, - dns_nameservers=dns_nameservers, - host_routes=host_routes, - shared=shared, - ipv6_ra_mode=ipv6_ra_mode, - ipv6_address_mode=ipv6_address_mode) - # Things can go wrong - raise HTTP exc with res code only - # so it can be caught by unit tests - if res.status_int >= webob.exc.HTTPClientError.code: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - def _make_port(self, fmt, net_id, expected_res_status=None, **kwargs): - res = self._create_port(fmt, net_id, expected_res_status, **kwargs) - # Things can go wrong - raise HTTP exc with res code only - # so it can be caught by unit tests - if res.status_int >= webob.exc.HTTPClientError.code: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - def _api_for_resource(self, resource): - if resource in ['networks', 'subnets', 'ports']: - return self.api - else: - return self.ext_api - - def _delete(self, collection, id, - expected_code=webob.exc.HTTPNoContent.code, - neutron_context=None): - req = self.new_delete_request(collection, id) - if neutron_context: - # create a specific auth context for this request - req.environ['neutron.context'] = neutron_context - res = req.get_response(self._api_for_resource(collection)) - self.assertEqual(res.status_int, expected_code) - - def _show(self, resource, id, - expected_code=webob.exc.HTTPOk.code, - neutron_context=None): - req = self.new_show_request(resource, id) - if neutron_context: - # create a specific auth context for this request - req.environ['neutron.context'] = neutron_context - res = req.get_response(self._api_for_resource(resource)) - self.assertEqual(res.status_int, expected_code) - return self.deserialize(self.fmt, res) - - def _update(self, resource, id, new_data, - expected_code=webob.exc.HTTPOk.code, - neutron_context=None): - req = self.new_update_request(resource, new_data, id) - if neutron_context: - # create a specific auth context for this request - req.environ['neutron.context'] = neutron_context - res = req.get_response(self._api_for_resource(resource)) - self.assertEqual(res.status_int, expected_code) - return self.deserialize(self.fmt, res) - - def _list(self, resource, fmt=None, neutron_context=None, - query_params=None): - fmt = fmt or self.fmt - req = self.new_list_request(resource, fmt, query_params) - if neutron_context: - req.environ['neutron.context'] = neutron_context - res = req.get_response(self._api_for_resource(resource)) - self.assertEqual(res.status_int, webob.exc.HTTPOk.code) - return self.deserialize(fmt, res) - - def _fail_second_call(self, patched_plugin, orig, *args, **kwargs): - """Invoked by test cases for injecting failures in plugin.""" - def second_call(*args, **kwargs): - raise n_exc.NeutronException() - patched_plugin.side_effect = second_call - return orig(*args, **kwargs) - - def _validate_behavior_on_bulk_failure( - self, res, collection, - errcode=webob.exc.HTTPClientError.code): - self.assertEqual(res.status_int, errcode) - req = self.new_list_request(collection) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPOk.code) - items = self.deserialize(self.fmt, res) - self.assertEqual(len(items[collection]), 0) - - def _validate_behavior_on_bulk_success(self, res, collection, - names=['test_0', 'test_1']): - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - items = self.deserialize(self.fmt, res)[collection] - self.assertEqual(len(items), 2) - self.assertEqual(items[0]['name'], 'test_0') - self.assertEqual(items[1]['name'], 'test_1') - - def _test_list_resources(self, resource, items, neutron_context=None, - query_params=None): - res = self._list('%ss' % resource, - neutron_context=neutron_context, - query_params=query_params) - resource = resource.replace('-', '_') - self.assertEqual(sorted([i['id'] for i in res['%ss' % resource]]), - sorted([i[resource]['id'] for i in items])) - - @contextlib.contextmanager - def network(self, name='net1', - admin_state_up=True, - fmt=None, - do_delete=True, - **kwargs): - network = self._make_network(fmt or self.fmt, name, - admin_state_up, **kwargs) - yield network - if do_delete: - # The do_delete parameter allows you to control whether the - # created network is immediately deleted again. Therefore, this - # function is also usable in tests, which require the creation - # of many networks. - self._delete('networks', network['network']['id']) - - @contextlib.contextmanager - def subnet(self, network=None, - gateway_ip=attributes.ATTR_NOT_SPECIFIED, - cidr='10.0.0.0/24', - fmt=None, - ip_version=4, - allocation_pools=None, - enable_dhcp=True, - dns_nameservers=None, - host_routes=None, - shared=None, - do_delete=True, - ipv6_ra_mode=None, - ipv6_address_mode=None): - with optional_ctx(network, self.network) as network_to_use: - subnet = self._make_subnet(fmt or self.fmt, - network_to_use, - gateway_ip, - cidr, - allocation_pools, - ip_version, - enable_dhcp, - dns_nameservers, - host_routes, - shared=shared, - ipv6_ra_mode=ipv6_ra_mode, - ipv6_address_mode=ipv6_address_mode) - yield subnet - if do_delete: - self._delete('subnets', subnet['subnet']['id']) - - @contextlib.contextmanager - def port(self, subnet=None, fmt=None, no_delete=False, - **kwargs): - with optional_ctx(subnet, self.subnet) as subnet_to_use: - net_id = subnet_to_use['subnet']['network_id'] - port = self._make_port(fmt or self.fmt, net_id, **kwargs) - yield port - if not no_delete: - self._delete('ports', port['port']['id']) - - def _test_list_with_sort(self, resource, - items, sorts, resources=None, query_params=''): - query_str = query_params - for key, direction in sorts: - query_str = query_str + "&sort_key=%s&sort_dir=%s" % (key, - direction) - if not resources: - resources = '%ss' % resource - req = self.new_list_request(resources, - params=query_str) - api = self._api_for_resource(resources) - res = self.deserialize(self.fmt, req.get_response(api)) - resource = resource.replace('-', '_') - resources = resources.replace('-', '_') - expected_res = [item[resource]['id'] for item in items] - self.assertEqual(sorted([n['id'] for n in res[resources]]), - sorted(expected_res)) - - def _test_list_with_pagination(self, resource, items, sort, - limit, expected_page_num, - resources=None, - query_params='', - verify_key='id'): - if not resources: - resources = '%ss' % resource - query_str = query_params + '&' if query_params else '' - query_str = query_str + ("limit=%s&sort_key=%s&" - "sort_dir=%s") % (limit, sort[0], sort[1]) - req = self.new_list_request(resources, params=query_str) - items_res = [] - page_num = 0 - api = self._api_for_resource(resources) - resource = resource.replace('-', '_') - resources = resources.replace('-', '_') - while req: - page_num = page_num + 1 - res = self.deserialize(self.fmt, req.get_response(api)) - self.assertThat(len(res[resources]), - matchers.LessThan(limit + 1)) - items_res = items_res + res[resources] - req = None - if '%s_links' % resources in res: - for link in res['%s_links' % resources]: - if link['rel'] == 'next': - content_type = 'application/%s' % self.fmt - req = testlib_api.create_request(link['href'], - '', content_type) - self.assertEqual(len(res[resources]), - limit) - self.assertEqual(page_num, expected_page_num) - self.assertEqual(sorted([n[verify_key] for n in items_res]), - sorted([item[resource][verify_key] - for item in items])) - - def _test_list_with_pagination_reverse(self, resource, items, sort, - limit, expected_page_num, - resources=None, - query_params=''): - if not resources: - resources = '%ss' % resource - resource = resource.replace('-', '_') - api = self._api_for_resource(resources) - marker = items[-1][resource]['id'] - query_str = query_params + '&' if query_params else '' - query_str = query_str + ("limit=%s&page_reverse=True&" - "sort_key=%s&sort_dir=%s&" - "marker=%s") % (limit, sort[0], sort[1], - marker) - req = self.new_list_request(resources, params=query_str) - item_res = [items[-1][resource]] - page_num = 0 - resources = resources.replace('-', '_') - while req: - page_num = page_num + 1 - res = self.deserialize(self.fmt, req.get_response(api)) - self.assertThat(len(res[resources]), - matchers.LessThan(limit + 1)) - res[resources].reverse() - item_res = item_res + res[resources] - req = None - if '%s_links' % resources in res: - for link in res['%s_links' % resources]: - if link['rel'] == 'previous': - content_type = 'application/%s' % self.fmt - req = testlib_api.create_request(link['href'], - '', content_type) - self.assertEqual(len(res[resources]), - limit) - self.assertEqual(page_num, expected_page_num) - expected_res = [item[resource]['id'] for item in items] - expected_res.reverse() - self.assertEqual(sorted([n['id'] for n in item_res]), - sorted(expected_res)) - - -class TestBasicGet(NeutronDbPluginV2TestCase): - - def test_single_get_admin(self): - plugin = neutron.db.db_base_plugin_v2.NeutronDbPluginV2() - with self.network() as network: - net_id = network['network']['id'] - ctx = context.get_admin_context() - n = plugin._get_network(ctx, net_id) - self.assertEqual(net_id, n.id) - - def test_single_get_tenant(self): - plugin = neutron.db.db_base_plugin_v2.NeutronDbPluginV2() - with self.network() as network: - net_id = network['network']['id'] - ctx = context.get_admin_context() - n = plugin._get_network(ctx, net_id) - self.assertEqual(net_id, n.id) - - -class TestV2HTTPResponse(NeutronDbPluginV2TestCase): - def test_create_returns_201(self): - res = self._create_network(self.fmt, 'net2', True) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - def test_list_returns_200(self): - req = self.new_list_request('networks') - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPOk.code) - - def _check_list_with_fields(self, res, field_name): - self.assertEqual(res.status_int, webob.exc.HTTPOk.code) - body = self.deserialize(self.fmt, res) - # further checks: 1 networks - self.assertEqual(len(body['networks']), 1) - # 1 field in the network record - self.assertEqual(len(body['networks'][0]), 1) - # field is 'name' - self.assertIn(field_name, body['networks'][0]) - - def test_list_with_fields(self): - self._create_network(self.fmt, 'some_net', True) - req = self.new_list_request('networks', params="fields=name") - res = req.get_response(self.api) - self._check_list_with_fields(res, 'name') - - def test_list_with_fields_noadmin(self): - tenant_id = 'some_tenant' - self._create_network(self.fmt, - 'some_net', - True, - tenant_id=tenant_id, - set_context=True) - req = self.new_list_request('networks', params="fields=name") - req.environ['neutron.context'] = context.Context('', tenant_id) - res = req.get_response(self.api) - self._check_list_with_fields(res, 'name') - - def test_list_with_fields_noadmin_and_policy_field(self): - """If a field used by policy is selected, do not duplicate it. - - Verifies that if the field parameter explicitly specifies a field - which is used by the policy engine, then it is not duplicated - in the response. - - """ - tenant_id = 'some_tenant' - self._create_network(self.fmt, - 'some_net', - True, - tenant_id=tenant_id, - set_context=True) - req = self.new_list_request('networks', params="fields=tenant_id") - req.environ['neutron.context'] = context.Context('', tenant_id) - res = req.get_response(self.api) - self._check_list_with_fields(res, 'tenant_id') - - def test_show_returns_200(self): - with self.network() as net: - req = self.new_show_request('networks', net['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPOk.code) - - def test_delete_returns_204(self): - res = self._create_network(self.fmt, 'net1', True) - net = self.deserialize(self.fmt, res) - req = self.new_delete_request('networks', net['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_update_returns_200(self): - with self.network() as net: - req = self.new_update_request('networks', - {'network': {'name': 'steve'}}, - net['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPOk.code) - - def test_update_invalid_json_400(self): - with self.network() as net: - req = self.new_update_request('networks', - '{{"name": "aaa"}}', - net['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_bad_route_404(self): - req = self.new_list_request('doohickeys') - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - -class TestPortsV2(NeutronDbPluginV2TestCase): - def test_create_port_json(self): - keys = [('admin_state_up', True), ('status', self.port_create_status)] - with self.port(name='myname') as port: - for k, v in keys: - self.assertEqual(port['port'][k], v) - self.assertIn('mac_address', port['port']) - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual('myname', port['port']['name']) - - def test_create_port_as_admin(self): - with self.network(do_delete=False) as network: - self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id='bad_tenant_id', - device_id='fake_device', - device_owner='fake_owner', - fixed_ips=[], - set_context=False) - - def test_create_port_bad_tenant(self): - with self.network() as network: - self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPNotFound.code, - tenant_id='bad_tenant_id', - device_id='fake_device', - device_owner='fake_owner', - fixed_ips=[], - set_context=True) - - def test_create_port_public_network(self): - keys = [('admin_state_up', True), ('status', self.port_create_status)] - with self.network(shared=True) as network: - port_res = self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id='another_tenant', - set_context=True) - port = self.deserialize(self.fmt, port_res) - for k, v in keys: - self.assertEqual(port['port'][k], v) - self.assertIn('mac_address', port['port']) - self._delete('ports', port['port']['id']) - - def test_create_port_public_network_with_ip(self): - with self.network(shared=True) as network: - with self.subnet(network=network, cidr='10.0.0.0/24') as subnet: - keys = [('admin_state_up', True), - ('status', self.port_create_status), - ('fixed_ips', [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.2'}])] - port_res = self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id='another_tenant', - set_context=True) - port = self.deserialize(self.fmt, port_res) - for k, v in keys: - self.assertEqual(port['port'][k], v) - self.assertIn('mac_address', port['port']) - self._delete('ports', port['port']['id']) - - def test_create_ports_bulk_native(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk port create") - with self.network() as net: - res = self._create_port_bulk(self.fmt, 2, net['network']['id'], - 'test', True) - self._validate_behavior_on_bulk_success(res, 'ports') - for p in self.deserialize(self.fmt, res)['ports']: - self._delete('ports', p['id']) - - def test_create_ports_bulk_emulated(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - with self.network() as net: - res = self._create_port_bulk(self.fmt, 2, net['network']['id'], - 'test', True) - self._validate_behavior_on_bulk_success(res, 'ports') - for p in self.deserialize(self.fmt, res)['ports']: - self._delete('ports', p['id']) - - def test_create_ports_bulk_wrong_input(self): - with self.network() as net: - overrides = {1: {'admin_state_up': 'doh'}} - res = self._create_port_bulk(self.fmt, 2, net['network']['id'], - 'test', True, - override=overrides) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - req = self.new_list_request('ports') - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPOk.code) - ports = self.deserialize(self.fmt, res) - self.assertEqual(len(ports['ports']), 0) - - def test_create_ports_bulk_emulated_plugin_failure(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - orig = manager.NeutronManager.get_plugin().create_port - with mock.patch.object(manager.NeutronManager.get_plugin(), - 'create_port') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._fail_second_call(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - with self.network() as net: - res = self._create_port_bulk(self.fmt, 2, - net['network']['id'], - 'test', - True) - # We expect a 500 as we injected a fault in the plugin - self._validate_behavior_on_bulk_failure( - res, 'ports', webob.exc.HTTPServerError.code - ) - - def test_create_ports_bulk_native_plugin_failure(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk port create") - ctx = context.get_admin_context() - with self.network() as net: - plugin = manager.NeutronManager.get_plugin() - orig = plugin.create_port - with mock.patch.object(plugin, 'create_port') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._fail_second_call(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - res = self._create_port_bulk(self.fmt, 2, net['network']['id'], - 'test', True, context=ctx) - # We expect a 500 as we injected a fault in the plugin - self._validate_behavior_on_bulk_failure( - res, 'ports', webob.exc.HTTPServerError.code) - - def test_list_ports(self): - # for this test we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(), - self.port(), - self.port()) as ports: - self._test_list_resources('port', ports) - - def test_list_ports_filtered_by_fixed_ip(self): - # for this test we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(), self.port()) as (port1, port2): - fixed_ips = port1['port']['fixed_ips'][0] - query_params = """ -fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s -""".strip() % (fixed_ips['ip_address'], - '192.168.126.5', - fixed_ips['subnet_id']) - self._test_list_resources('port', [port1], - query_params=query_params) - - def test_list_ports_public_network(self): - with self.network(shared=True) as network: - with self.subnet(network) as subnet: - with contextlib.nested(self.port(subnet, tenant_id='tenant_1'), - self.port(subnet, tenant_id='tenant_2') - ) as (port1, port2): - # Admin request - must return both ports - self._test_list_resources('port', [port1, port2]) - # Tenant_1 request - must return single port - q_context = context.Context('', 'tenant_1') - self._test_list_resources('port', [port1], - neutron_context=q_context) - # Tenant_2 request - must return single port - q_context = context.Context('', 'tenant_2') - self._test_list_resources('port', [port2], - neutron_context=q_context) - - def test_list_ports_with_sort_native(self): - if self._skip_native_sorting: - self.skipTest("Skip test for not implemented sorting feature") - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(admin_state_up='True', - mac_address='00:00:00:00:00:01'), - self.port(admin_state_up='False', - mac_address='00:00:00:00:00:02'), - self.port(admin_state_up='False', - mac_address='00:00:00:00:00:03') - ) as (port1, port2, port3): - self._test_list_with_sort('port', (port3, port2, port1), - [('admin_state_up', 'asc'), - ('mac_address', 'desc')]) - - def test_list_ports_with_sort_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_sorting_helper', - new=_fake_get_sorting_helper) - helper_patcher.start() - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(admin_state_up='True', - mac_address='00:00:00:00:00:01'), - self.port(admin_state_up='False', - mac_address='00:00:00:00:00:02'), - self.port(admin_state_up='False', - mac_address='00:00:00:00:00:03') - ) as (port1, port2, port3): - self._test_list_with_sort('port', (port3, port2, port1), - [('admin_state_up', 'asc'), - ('mac_address', 'desc')]) - - def test_list_ports_with_pagination_native(self): - if self._skip_native_pagination: - self.skipTest("Skip test for not implemented pagination feature") - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(mac_address='00:00:00:00:00:01'), - self.port(mac_address='00:00:00:00:00:02'), - self.port(mac_address='00:00:00:00:00:03') - ) as (port1, port2, port3): - self._test_list_with_pagination('port', - (port1, port2, port3), - ('mac_address', 'asc'), 2, 2) - - def test_list_ports_with_pagination_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_pagination_helper', - new=_fake_get_pagination_helper) - helper_patcher.start() - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(mac_address='00:00:00:00:00:01'), - self.port(mac_address='00:00:00:00:00:02'), - self.port(mac_address='00:00:00:00:00:03') - ) as (port1, port2, port3): - self._test_list_with_pagination('port', - (port1, port2, port3), - ('mac_address', 'asc'), 2, 2) - - def test_list_ports_with_pagination_reverse_native(self): - if self._skip_native_pagination: - self.skipTest("Skip test for not implemented pagination feature") - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(mac_address='00:00:00:00:00:01'), - self.port(mac_address='00:00:00:00:00:02'), - self.port(mac_address='00:00:00:00:00:03') - ) as (port1, port2, port3): - self._test_list_with_pagination_reverse('port', - (port1, port2, port3), - ('mac_address', 'asc'), - 2, 2) - - def test_list_ports_with_pagination_reverse_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_pagination_helper', - new=_fake_get_pagination_helper) - helper_patcher.start() - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(mac_address='00:00:00:00:00:01'), - self.port(mac_address='00:00:00:00:00:02'), - self.port(mac_address='00:00:00:00:00:03') - ) as (port1, port2, port3): - self._test_list_with_pagination_reverse('port', - (port1, port2, port3), - ('mac_address', 'asc'), - 2, 2) - - def test_show_port(self): - with self.port() as port: - req = self.new_show_request('ports', port['port']['id'], self.fmt) - sport = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(port['port']['id'], sport['port']['id']) - - def test_delete_port(self): - with self.port(no_delete=True) as port: - self._delete('ports', port['port']['id']) - self._show('ports', port['port']['id'], - expected_code=webob.exc.HTTPNotFound.code) - - def test_delete_port_public_network(self): - with self.network(shared=True) as network: - port_res = self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id='another_tenant', - set_context=True) - - port = self.deserialize(self.fmt, port_res) - self._delete('ports', port['port']['id']) - self._show('ports', port['port']['id'], - expected_code=webob.exc.HTTPNotFound.code) - - def test_update_port(self): - with self.port() as port: - data = {'port': {'admin_state_up': False}} - req = self.new_update_request('ports', data, port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['port']['admin_state_up'], - data['port']['admin_state_up']) - - def test_update_port_not_admin(self): - res = self._create_network(self.fmt, 'net1', True, - tenant_id='not_admin', - set_context=True) - net1 = self.deserialize(self.fmt, res) - res = self._create_port(self.fmt, net1['network']['id'], - tenant_id='not_admin', set_context=True) - port = self.deserialize(self.fmt, res) - data = {'port': {'admin_state_up': False}} - neutron_context = context.Context('', 'not_admin') - port = self._update('ports', port['port']['id'], data, - neutron_context=neutron_context) - self.assertEqual(port['port']['admin_state_up'], False) - - def test_update_device_id_null(self): - with self.port() as port: - data = {'port': {'device_id': None}} - req = self.new_update_request('ports', data, port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_delete_network_if_port_exists(self): - with self.port() as port: - req = self.new_delete_request('networks', - port['port']['network_id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_delete_network_port_exists_owned_by_network(self): - res = self._create_network(fmt=self.fmt, name='net', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - network_id = network['network']['id'] - self._create_port(self.fmt, network_id, - device_owner=constants.DEVICE_OWNER_DHCP) - req = self.new_delete_request('networks', network_id) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_update_port_delete_ip(self): - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - data = {'port': {'admin_state_up': False, - 'fixed_ips': []}} - req = self.new_update_request('ports', - data, port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['port']['admin_state_up'], - data['port']['admin_state_up']) - self.assertEqual(res['port']['fixed_ips'], - data['port']['fixed_ips']) - - def test_no_more_port_exception(self): - with self.subnet(cidr='10.0.0.0/32') as subnet: - id = subnet['subnet']['network_id'] - res = self._create_port(self.fmt, id) - data = self.deserialize(self.fmt, res) - msg = str(n_exc.IpAddressGenerationFailure(net_id=id)) - self.assertEqual(data['NeutronError']['message'], msg) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_update_port_update_ip(self): - """Test update of port IP. - - Check that a configured IP 10.0.0.2 is replaced by 10.0.0.10. - """ - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - data = {'port': {'fixed_ips': [{'subnet_id': - subnet['subnet']['id'], - 'ip_address': "10.0.0.10"}]}} - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - ips = res['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.10') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - - def test_update_port_update_ip_address_only(self): - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - data = {'port': {'fixed_ips': [{'subnet_id': - subnet['subnet']['id'], - 'ip_address': "10.0.0.10"}, - {'ip_address': "10.0.0.2"}]}} - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - ips = res['port']['fixed_ips'] - self.assertEqual(len(ips), 2) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - self.assertEqual(ips[1]['ip_address'], '10.0.0.10') - self.assertEqual(ips[1]['subnet_id'], subnet['subnet']['id']) - - def test_update_port_update_ips(self): - """Update IP and associate new IP on port. - - Check a port update with the specified subnet_id's. A IP address - will be allocated for each subnet_id. - """ - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - data = {'port': {'admin_state_up': False, - 'fixed_ips': [{'subnet_id': - subnet['subnet']['id'], - 'ip_address': '10.0.0.3'}]}} - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['port']['admin_state_up'], - data['port']['admin_state_up']) - ips = res['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.3') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - - def test_update_port_add_additional_ip(self): - """Test update of port with additional IP.""" - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - data = {'port': {'admin_state_up': False, - 'fixed_ips': [{'subnet_id': - subnet['subnet']['id']}, - {'subnet_id': - subnet['subnet']['id']}]}} - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['port']['admin_state_up'], - data['port']['admin_state_up']) - ips = res['port']['fixed_ips'] - self.assertEqual(len(ips), 2) - self.assertEqual(ips[0]['ip_address'], '10.0.0.3') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - self.assertEqual(ips[1]['ip_address'], '10.0.0.4') - self.assertEqual(ips[1]['subnet_id'], subnet['subnet']['id']) - - def test_requested_duplicate_mac(self): - with self.port() as port: - mac = port['port']['mac_address'] - # check that MAC address matches base MAC - base_mac = cfg.CONF.base_mac[0:2] - self.assertTrue(mac.startswith(base_mac)) - kwargs = {"mac_address": mac} - net_id = port['port']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_mac_generation(self): - cfg.CONF.set_override('base_mac', "12:34:56:00:00:00") - with self.port() as port: - mac = port['port']['mac_address'] - self.assertTrue(mac.startswith("12:34:56")) - - def test_mac_generation_4octet(self): - cfg.CONF.set_override('base_mac', "12:34:56:78:00:00") - with self.port() as port: - mac = port['port']['mac_address'] - self.assertTrue(mac.startswith("12:34:56:78")) - - def test_bad_mac_format(self): - cfg.CONF.set_override('base_mac', "bad_mac") - try: - self.plugin._check_base_mac_format() - except Exception: - return - self.fail("No exception for illegal base_mac format") - - def test_mac_exhaustion(self): - # rather than actually consuming all MAC (would take a LONG time) - # we just raise the exception that would result. - @staticmethod - def fake_gen_mac(context, net_id): - raise n_exc.MacAddressGenerationFailure(net_id=net_id) - - with mock.patch.object(neutron.db.db_base_plugin_v2.NeutronDbPluginV2, - '_generate_mac', new=fake_gen_mac): - res = self._create_network(fmt=self.fmt, name='net1', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - net_id = network['network']['id'] - res = self._create_port(self.fmt, net_id=net_id) - self.assertEqual(res.status_int, - webob.exc.HTTPServiceUnavailable.code) - - def test_requested_duplicate_ip(self): - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - # Check configuring of duplicate IP - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id'], - 'ip_address': ips[0]['ip_address']}]} - net_id = port['port']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_requested_subnet_delete(self): - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - req = self.new_delete_request('subnet', - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - def test_requested_subnet_id(self): - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - # Request a IP from specific subnet - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id']}]} - net_id = port['port']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port2 = self.deserialize(self.fmt, res) - ips = port2['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.3') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - self._delete('ports', port2['port']['id']) - - def test_requested_subnet_id_not_on_network(self): - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - # Create new network - res = self._create_network(fmt=self.fmt, name='net2', - admin_state_up=True) - network2 = self.deserialize(self.fmt, res) - subnet2 = self._make_subnet(self.fmt, network2, "1.1.1.1", - "1.1.1.0/24", ip_version=4) - net_id = port['port']['network_id'] - # Request a IP from specific subnet - kwargs = {"fixed_ips": [{'subnet_id': - subnet2['subnet']['id']}]} - net_id = port['port']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_overlapping_subnets(self): - with self.subnet() as subnet: - tenant_id = subnet['subnet']['tenant_id'] - net_id = subnet['subnet']['network_id'] - res = self._create_subnet(self.fmt, - tenant_id=tenant_id, - net_id=net_id, - cidr='10.0.0.225/28', - ip_version=4, - gateway_ip=attributes.ATTR_NOT_SPECIFIED) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_requested_subnet_id_v4_and_v6(self): - with self.subnet() as subnet: - # Get a IPv4 and IPv6 address - tenant_id = subnet['subnet']['tenant_id'] - net_id = subnet['subnet']['network_id'] - res = self._create_subnet( - self.fmt, - tenant_id=tenant_id, - net_id=net_id, - cidr='2607:f0d0:1002:51::/124', - ip_version=6, - gateway_ip=attributes.ATTR_NOT_SPECIFIED) - subnet2 = self.deserialize(self.fmt, res) - kwargs = {"fixed_ips": - [{'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet2['subnet']['id']}]} - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port3 = self.deserialize(self.fmt, res) - ips = port3['port']['fixed_ips'] - self.assertEqual(len(ips), 2) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - self.assertEqual(ips[1]['ip_address'], '2607:f0d0:1002:51::2') - self.assertEqual(ips[1]['subnet_id'], subnet2['subnet']['id']) - res = self._create_port(self.fmt, net_id=net_id) - port4 = self.deserialize(self.fmt, res) - # Check that a v4 and a v6 address are allocated - ips = port4['port']['fixed_ips'] - self.assertEqual(len(ips), 2) - self.assertEqual(ips[0]['ip_address'], '10.0.0.3') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - self.assertEqual(ips[1]['ip_address'], '2607:f0d0:1002:51::3') - self.assertEqual(ips[1]['subnet_id'], subnet2['subnet']['id']) - self._delete('ports', port3['port']['id']) - self._delete('ports', port4['port']['id']) - - def test_ip_allocation_for_ipv6_subnet_slaac_adddress_mode(self): - res = self._create_network(fmt=self.fmt, name='net', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - v6_subnet = self._make_subnet(self.fmt, network, - gateway='fe80::1', - cidr='fe80::/80', - ip_version=6, - ipv6_ra_mode=None, - ipv6_address_mode=constants.IPV6_SLAAC) - port = self._make_port(self.fmt, network['network']['id']) - self.assertEqual(len(port['port']['fixed_ips']), 1) - port_mac = port['port']['mac_address'] - subnet_cidr = v6_subnet['subnet']['cidr'] - eui_addr = str(ipv6_utils.get_ipv6_addr_by_EUI64(subnet_cidr, - port_mac)) - self.assertEqual(port['port']['fixed_ips'][0]['ip_address'], eui_addr) - - def test_range_allocation(self): - with self.subnet(gateway_ip='10.0.0.3', - cidr='10.0.0.0/29') as subnet: - kwargs = {"fixed_ips": - [{'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}]} - net_id = subnet['subnet']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port = self.deserialize(self.fmt, res) - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 5) - alloc = ['10.0.0.1', '10.0.0.2', '10.0.0.4', '10.0.0.5', - '10.0.0.6'] - for ip in ips: - self.assertIn(ip['ip_address'], alloc) - self.assertEqual(ip['subnet_id'], - subnet['subnet']['id']) - alloc.remove(ip['ip_address']) - self.assertEqual(len(alloc), 0) - self._delete('ports', port['port']['id']) - - with self.subnet(gateway_ip='11.0.0.6', - cidr='11.0.0.0/29') as subnet: - kwargs = {"fixed_ips": - [{'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}]} - net_id = subnet['subnet']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port = self.deserialize(self.fmt, res) - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 5) - alloc = ['11.0.0.1', '11.0.0.2', '11.0.0.3', '11.0.0.4', - '11.0.0.5'] - for ip in ips: - self.assertIn(ip['ip_address'], alloc) - self.assertEqual(ip['subnet_id'], - subnet['subnet']['id']) - alloc.remove(ip['ip_address']) - self.assertEqual(len(alloc), 0) - self._delete('ports', port['port']['id']) - - def test_requested_invalid_fixed_ips(self): - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - # Test invalid subnet_id - kwargs = {"fixed_ips": - [{'subnet_id': subnet['subnet']['id']}, - {'subnet_id': - '00000000-ffff-ffff-ffff-000000000000'}]} - net_id = port['port']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port2 = self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - # Test invalid IP address on specified subnet_id - kwargs = {"fixed_ips": - [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '1.1.1.1'}]} - net_id = port['port']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port2 = self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - # Test invalid addresses - IP's not on subnet or network - # address or broadcast address - bad_ips = ['1.1.1.1', '10.0.0.0', '10.0.0.255'] - net_id = port['port']['network_id'] - for ip in bad_ips: - kwargs = {"fixed_ips": [{'ip_address': ip}]} - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port2 = self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - # Enable allocation of gateway address - kwargs = {"fixed_ips": - [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.1'}]} - net_id = port['port']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port2 = self.deserialize(self.fmt, res) - ips = port2['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.1') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - self._delete('ports', port2['port']['id']) - - def test_invalid_ip(self): - with self.subnet() as subnet: - # Allocate specific IP - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '1011.0.0.5'}]} - net_id = subnet['subnet']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_requested_split(self): - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - ports_to_delete = [] - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - # Allocate specific IP - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.5'}]} - net_id = port['port']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port2 = self.deserialize(self.fmt, res) - ports_to_delete.append(port2) - ips = port2['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.5') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - # Allocate specific IP's - allocated = ['10.0.0.3', '10.0.0.4', '10.0.0.6'] - - for a in allocated: - res = self._create_port(self.fmt, net_id=net_id) - port2 = self.deserialize(self.fmt, res) - ports_to_delete.append(port2) - ips = port2['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], a) - self.assertEqual(ips[0]['subnet_id'], - subnet['subnet']['id']) - - for p in ports_to_delete: - self._delete('ports', p['port']['id']) - - def test_duplicate_ips(self): - with self.subnet() as subnet: - # Allocate specific IP - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.5'}, - {'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.5'}]} - net_id = subnet['subnet']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_fixed_ip_invalid_subnet_id(self): - with self.subnet() as subnet: - # Allocate specific IP - kwargs = {"fixed_ips": [{'subnet_id': 'i am invalid', - 'ip_address': '10.0.0.5'}]} - net_id = subnet['subnet']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_fixed_ip_invalid_ip(self): - with self.subnet() as subnet: - # Allocate specific IP - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.55555'}]} - net_id = subnet['subnet']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_requested_ips_only(self): - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], '10.0.0.2') - self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id']) - ips_only = ['10.0.0.18', '10.0.0.20', '10.0.0.22', '10.0.0.21', - '10.0.0.3', '10.0.0.17', '10.0.0.19'] - ports_to_delete = [] - for i in ips_only: - kwargs = {"fixed_ips": [{'ip_address': i}]} - net_id = port['port']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port = self.deserialize(self.fmt, res) - ports_to_delete.append(port) - ips = port['port']['fixed_ips'] - self.assertEqual(len(ips), 1) - self.assertEqual(ips[0]['ip_address'], i) - self.assertEqual(ips[0]['subnet_id'], - subnet['subnet']['id']) - for p in ports_to_delete: - self._delete('ports', p['port']['id']) - - def test_invalid_admin_state(self): - with self.network() as network: - data = {'port': {'network_id': network['network']['id'], - 'tenant_id': network['network']['tenant_id'], - 'admin_state_up': 7, - 'fixed_ips': []}} - port_req = self.new_create_request('ports', data) - res = port_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_invalid_mac_address(self): - with self.network() as network: - data = {'port': {'network_id': network['network']['id'], - 'tenant_id': network['network']['tenant_id'], - 'admin_state_up': 1, - 'mac_address': 'mac', - 'fixed_ips': []}} - port_req = self.new_create_request('ports', data) - res = port_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_max_fixed_ips_exceeded(self): - with self.subnet(gateway_ip='10.0.0.3', - cidr='10.0.0.0/24') as subnet: - kwargs = {"fixed_ips": - [{'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}]} - net_id = subnet['subnet']['network_id'] - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_max_fixed_ips_exceeded(self): - with self.subnet(gateway_ip='10.0.0.3', - cidr='10.0.0.0/24') as subnet: - with self.port(subnet) as port: - data = {'port': {'fixed_ips': - [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.2'}, - {'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.4'}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}, - {'subnet_id': subnet['subnet']['id']}]}} - req = self.new_update_request('ports', data, - port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_delete_ports_by_device_id(self): - plugin = manager.NeutronManager.get_plugin() - ctx = context.get_admin_context() - with self.subnet() as subnet: - with contextlib.nested( - self.port(subnet=subnet, device_id='owner1', no_delete=True), - self.port(subnet=subnet, device_id='owner1', no_delete=True), - self.port(subnet=subnet, device_id='owner2'), - ) as (p1, p2, p3): - network_id = subnet['subnet']['network_id'] - plugin.delete_ports_by_device_id(ctx, 'owner1', - network_id) - self._show('ports', p1['port']['id'], - expected_code=webob.exc.HTTPNotFound.code) - self._show('ports', p2['port']['id'], - expected_code=webob.exc.HTTPNotFound.code) - self._show('ports', p3['port']['id'], - expected_code=webob.exc.HTTPOk.code) - - def _test_delete_ports_by_device_id_second_call_failure(self, plugin): - ctx = context.get_admin_context() - with self.subnet() as subnet: - with contextlib.nested( - self.port(subnet=subnet, device_id='owner1', no_delete=True), - self.port(subnet=subnet, device_id='owner1'), - self.port(subnet=subnet, device_id='owner2'), - ) as (p1, p2, p3): - orig = plugin.delete_port - with mock.patch.object(plugin, 'delete_port') as del_port: - - def side_effect(*args, **kwargs): - return self._fail_second_call(del_port, orig, - *args, **kwargs) - - del_port.side_effect = side_effect - network_id = subnet['subnet']['network_id'] - self.assertRaises(n_exc.NeutronException, - plugin.delete_ports_by_device_id, - ctx, 'owner1', network_id) - self._show('ports', p1['port']['id'], - expected_code=webob.exc.HTTPNotFound.code) - self._show('ports', p2['port']['id'], - expected_code=webob.exc.HTTPOk.code) - self._show('ports', p3['port']['id'], - expected_code=webob.exc.HTTPOk.code) - - def test_delete_ports_by_device_id_second_call_failure(self): - plugin = manager.NeutronManager.get_plugin() - self._test_delete_ports_by_device_id_second_call_failure(plugin) - - def _test_delete_ports_ignores_port_not_found(self, plugin): - ctx = context.get_admin_context() - with self.subnet() as subnet: - with contextlib.nested( - self.port(subnet=subnet, device_id='owner1'), - mock.patch.object(plugin, 'delete_port') - ) as (p, del_port): - del_port.side_effect = n_exc.PortNotFound( - port_id=p['port']['id'] - ) - network_id = subnet['subnet']['network_id'] - try: - plugin.delete_ports_by_device_id(ctx, 'owner1', - network_id) - except n_exc.PortNotFound: - self.fail("delete_ports_by_device_id unexpectedly raised " - "a PortNotFound exception. It should ignore " - "this exception because it is often called at " - "the same time other concurrent operations are " - "deleting some of the same ports.") - - def test_delete_ports_ignores_port_not_found(self): - plugin = manager.NeutronManager.get_plugin() - self._test_delete_ports_ignores_port_not_found(plugin) - - -class TestNetworksV2(NeutronDbPluginV2TestCase): - # NOTE(cerberus): successful network update and delete are - # effectively tested above - def test_create_network(self): - name = 'net1' - keys = [('subnets', []), ('name', name), ('admin_state_up', True), - ('status', self.net_create_status), ('shared', False)] - with self.network(name=name) as net: - for k, v in keys: - self.assertEqual(net['network'][k], v) - - def test_create_public_network(self): - name = 'public_net' - keys = [('subnets', []), ('name', name), ('admin_state_up', True), - ('status', self.net_create_status), ('shared', True)] - with self.network(name=name, shared=True) as net: - for k, v in keys: - self.assertEqual(net['network'][k], v) - - def test_create_public_network_no_admin_tenant(self): - name = 'public_net' - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - with self.network(name=name, - shared=True, - tenant_id="another_tenant", - set_context=True): - pass - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPForbidden.code) - - def test_update_network(self): - with self.network() as network: - data = {'network': {'name': 'a_brand_new_name'}} - req = self.new_update_request('networks', - data, - network['network']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['network']['name'], - data['network']['name']) - - def test_update_shared_network_noadmin_returns_403(self): - with self.network(shared=True) as network: - data = {'network': {'name': 'a_brand_new_name'}} - req = self.new_update_request('networks', - data, - network['network']['id']) - req.environ['neutron.context'] = context.Context('', 'somebody') - res = req.get_response(self.api) - # The API layer always returns 404 on updates in place of 403 - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - def test_update_network_set_shared(self): - with self.network(shared=False) as network: - data = {'network': {'shared': True}} - req = self.new_update_request('networks', - data, - network['network']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertTrue(res['network']['shared']) - - def test_update_network_set_shared_owner_returns_404(self): - with self.network(shared=False) as network: - net_owner = network['network']['tenant_id'] - data = {'network': {'shared': True}} - req = self.new_update_request('networks', - data, - network['network']['id']) - req.environ['neutron.context'] = context.Context('u', net_owner) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - def test_update_network_with_subnet_set_shared(self): - with self.network(shared=False) as network: - with self.subnet(network=network) as subnet: - data = {'network': {'shared': True}} - req = self.new_update_request('networks', - data, - network['network']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertTrue(res['network']['shared']) - # must query db to see whether subnet's shared attribute - # has been updated or not - ctx = context.Context('', '', is_admin=True) - subnet_db = manager.NeutronManager.get_plugin()._get_subnet( - ctx, subnet['subnet']['id']) - self.assertEqual(subnet_db['shared'], True) - - def test_update_network_set_not_shared_single_tenant(self): - with self.network(shared=True) as network: - res1 = self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id=network['network']['tenant_id'], - set_context=True) - data = {'network': {'shared': False}} - req = self.new_update_request('networks', - data, - network['network']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertFalse(res['network']['shared']) - port1 = self.deserialize(self.fmt, res1) - self._delete('ports', port1['port']['id']) - - def test_update_network_set_not_shared_other_tenant_returns_409(self): - with self.network(shared=True) as network: - res1 = self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id='somebody_else', - set_context=True) - data = {'network': {'shared': False}} - req = self.new_update_request('networks', - data, - network['network']['id']) - self.assertEqual(req.get_response(self.api).status_int, - webob.exc.HTTPConflict.code) - port1 = self.deserialize(self.fmt, res1) - self._delete('ports', port1['port']['id']) - - def test_update_network_set_not_shared_multi_tenants_returns_409(self): - with self.network(shared=True) as network: - res1 = self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id='somebody_else', - set_context=True) - res2 = self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id=network['network']['tenant_id'], - set_context=True) - data = {'network': {'shared': False}} - req = self.new_update_request('networks', - data, - network['network']['id']) - self.assertEqual(req.get_response(self.api).status_int, - webob.exc.HTTPConflict.code) - port1 = self.deserialize(self.fmt, res1) - port2 = self.deserialize(self.fmt, res2) - self._delete('ports', port1['port']['id']) - self._delete('ports', port2['port']['id']) - - def test_update_network_set_not_shared_multi_tenants2_returns_409(self): - with self.network(shared=True) as network: - res1 = self._create_port(self.fmt, - network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id='somebody_else', - set_context=True) - self._create_subnet(self.fmt, - network['network']['id'], - '10.0.0.0/24', - webob.exc.HTTPCreated.code, - tenant_id=network['network']['tenant_id'], - set_context=True) - data = {'network': {'shared': False}} - req = self.new_update_request('networks', - data, - network['network']['id']) - self.assertEqual(req.get_response(self.api).status_int, - webob.exc.HTTPConflict.code) - - port1 = self.deserialize(self.fmt, res1) - self._delete('ports', port1['port']['id']) - - def test_create_networks_bulk_native(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk network create") - res = self._create_network_bulk(self.fmt, 2, 'test', True) - self._validate_behavior_on_bulk_success(res, 'networks') - - def test_create_networks_bulk_native_quotas(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk network create") - quota = 4 - cfg.CONF.set_override('quota_network', quota, group='QUOTAS') - res = self._create_network_bulk(self.fmt, quota + 1, 'test', True) - self._validate_behavior_on_bulk_failure( - res, 'networks', - errcode=webob.exc.HTTPConflict.code) - - def test_create_networks_bulk_tenants_and_quotas(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk network create") - quota = 2 - cfg.CONF.set_override('quota_network', quota, group='QUOTAS') - networks = [{'network': {'name': 'n1', - 'tenant_id': self._tenant_id}}, - {'network': {'name': 'n2', - 'tenant_id': self._tenant_id}}, - {'network': {'name': 'n1', - 'tenant_id': 't1'}}, - {'network': {'name': 'n2', - 'tenant_id': 't1'}}] - - res = self._create_bulk_from_list(self.fmt, 'network', networks) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - def test_create_networks_bulk_tenants_and_quotas_fail(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk network create") - quota = 2 - cfg.CONF.set_override('quota_network', quota, group='QUOTAS') - networks = [{'network': {'name': 'n1', - 'tenant_id': self._tenant_id}}, - {'network': {'name': 'n2', - 'tenant_id': self._tenant_id}}, - {'network': {'name': 'n1', - 'tenant_id': 't1'}}, - {'network': {'name': 'n3', - 'tenant_id': self._tenant_id}}, - {'network': {'name': 'n2', - 'tenant_id': 't1'}}] - - res = self._create_bulk_from_list(self.fmt, 'network', networks) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_create_networks_bulk_emulated(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - res = self._create_network_bulk(self.fmt, 2, 'test', True) - self._validate_behavior_on_bulk_success(res, 'networks') - - def test_create_networks_bulk_wrong_input(self): - res = self._create_network_bulk(self.fmt, 2, 'test', True, - override={1: - {'admin_state_up': 'doh'}}) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - req = self.new_list_request('networks') - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPOk.code) - nets = self.deserialize(self.fmt, res) - self.assertEqual(len(nets['networks']), 0) - - def test_create_networks_bulk_emulated_plugin_failure(self): - real_has_attr = hasattr - - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - orig = manager.NeutronManager.get_plugin().create_network - #ensures the API choose the emulation code path - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - with mock.patch.object(manager.NeutronManager.get_plugin(), - 'create_network') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._fail_second_call(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - res = self._create_network_bulk(self.fmt, 2, 'test', True) - # We expect a 500 as we injected a fault in the plugin - self._validate_behavior_on_bulk_failure( - res, 'networks', webob.exc.HTTPServerError.code - ) - - def test_create_networks_bulk_native_plugin_failure(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk network create") - orig = manager.NeutronManager.get_plugin().create_network - with mock.patch.object(manager.NeutronManager.get_plugin(), - 'create_network') as patched_plugin: - - def side_effect(*args, **kwargs): - return self._fail_second_call(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - res = self._create_network_bulk(self.fmt, 2, 'test', True) - # We expect a 500 as we injected a fault in the plugin - self._validate_behavior_on_bulk_failure( - res, 'networks', webob.exc.HTTPServerError.code - ) - - def test_list_networks(self): - with contextlib.nested(self.network(), - self.network(), - self.network()) as networks: - self._test_list_resources('network', networks) - - def test_list_networks_with_sort_native(self): - if self._skip_native_sorting: - self.skipTest("Skip test for not implemented sorting feature") - with contextlib.nested(self.network(admin_status_up=True, - name='net1'), - self.network(admin_status_up=False, - name='net2'), - self.network(admin_status_up=False, - name='net3') - ) as (net1, net2, net3): - self._test_list_with_sort('network', (net3, net2, net1), - [('admin_state_up', 'asc'), - ('name', 'desc')]) - - def test_list_networks_with_sort_extended_attr_native_returns_400(self): - if self._skip_native_sorting: - self.skipTest("Skip test for not implemented sorting feature") - with contextlib.nested(self.network(admin_status_up=True, - name='net1'), - self.network(admin_status_up=False, - name='net2'), - self.network(admin_status_up=False, - name='net3') - ): - req = self.new_list_request( - 'networks', - params='sort_key=provider:segmentation_id&sort_dir=asc') - res = req.get_response(self.api) - self.assertEqual(webob.exc.HTTPClientError.code, res.status_int) - - def test_list_networks_with_sort_remote_key_native_returns_400(self): - if self._skip_native_sorting: - self.skipTest("Skip test for not implemented sorting feature") - with contextlib.nested(self.network(admin_status_up=True, - name='net1'), - self.network(admin_status_up=False, - name='net2'), - self.network(admin_status_up=False, - name='net3') - ): - req = self.new_list_request( - 'networks', params='sort_key=subnets&sort_dir=asc') - res = req.get_response(self.api) - self.assertEqual(webob.exc.HTTPClientError.code, res.status_int) - - def test_list_networks_with_sort_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_sorting_helper', - new=_fake_get_sorting_helper) - helper_patcher.start() - with contextlib.nested(self.network(admin_status_up=True, - name='net1'), - self.network(admin_status_up=False, - name='net2'), - self.network(admin_status_up=False, - name='net3') - ) as (net1, net2, net3): - self._test_list_with_sort('network', (net3, net2, net1), - [('admin_state_up', 'asc'), - ('name', 'desc')]) - - def test_list_networks_with_pagination_native(self): - if self._skip_native_pagination: - self.skipTest("Skip test for not implemented pagination feature") - with contextlib.nested(self.network(name='net1'), - self.network(name='net2'), - self.network(name='net3') - ) as (net1, net2, net3): - self._test_list_with_pagination('network', - (net1, net2, net3), - ('name', 'asc'), 2, 2) - - def test_list_networks_with_pagination_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_pagination_helper', - new=_fake_get_pagination_helper) - helper_patcher.start() - with contextlib.nested(self.network(name='net1'), - self.network(name='net2'), - self.network(name='net3') - ) as (net1, net2, net3): - self._test_list_with_pagination('network', - (net1, net2, net3), - ('name', 'asc'), 2, 2) - - def test_list_networks_without_pk_in_fields_pagination_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_pagination_helper', - new=_fake_get_pagination_helper) - helper_patcher.start() - with contextlib.nested(self.network(name='net1', - shared=True), - self.network(name='net2', - shared=False), - self.network(name='net3', - shared=True) - ) as (net1, net2, net3): - self._test_list_with_pagination('network', - (net1, net2, net3), - ('name', 'asc'), 2, 2, - query_params="fields=name", - verify_key='name') - - def test_list_networks_without_pk_in_fields_pagination_native(self): - if self._skip_native_pagination: - self.skipTest("Skip test for not implemented pagination feature") - with contextlib.nested(self.network(name='net1'), - self.network(name='net2'), - self.network(name='net3') - ) as (net1, net2, net3): - self._test_list_with_pagination('network', - (net1, net2, net3), - ('name', 'asc'), 2, 2, - query_params="fields=shared", - verify_key='shared') - - def test_list_networks_with_pagination_reverse_native(self): - if self._skip_native_pagination: - self.skipTest("Skip test for not implemented pagination feature") - with contextlib.nested(self.network(name='net1'), - self.network(name='net2'), - self.network(name='net3') - ) as (net1, net2, net3): - self._test_list_with_pagination_reverse('network', - (net1, net2, net3), - ('name', 'asc'), 2, 2) - - def test_list_networks_with_pagination_reverse_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_pagination_helper', - new=_fake_get_pagination_helper) - helper_patcher.start() - with contextlib.nested(self.network(name='net1'), - self.network(name='net2'), - self.network(name='net3') - ) as (net1, net2, net3): - self._test_list_with_pagination_reverse('network', - (net1, net2, net3), - ('name', 'asc'), 2, 2) - - def test_list_networks_with_parameters(self): - with contextlib.nested(self.network(name='net1', - admin_state_up=False), - self.network(name='net2')) as (net1, net2): - query_params = 'admin_state_up=False' - self._test_list_resources('network', [net1], - query_params=query_params) - query_params = 'admin_state_up=True' - self._test_list_resources('network', [net2], - query_params=query_params) - - def test_list_networks_with_fields(self): - with self.network(name='net1') as net1: - req = self.new_list_request('networks', - params='fields=name') - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(1, len(res['networks'])) - self.assertEqual(res['networks'][0]['name'], - net1['network']['name']) - self.assertIsNone(res['networks'][0].get('id')) - - def test_list_networks_with_parameters_invalid_values(self): - with contextlib.nested(self.network(name='net1', - admin_state_up=False), - self.network(name='net2')) as (net1, net2): - req = self.new_list_request('networks', - params='admin_state_up=fake') - res = req.get_response(self.api) - self.assertEqual(webob.exc.HTTPClientError.code, res.status_int) - - def test_list_shared_networks_with_non_admin_user(self): - with contextlib.nested(self.network(shared=False, - name='net1', - tenant_id='tenant1'), - self.network(shared=True, - name='net2', - tenant_id='another_tenant'), - self.network(shared=False, - name='net3', - tenant_id='another_tenant') - ) as (net1, net2, net3): - ctx = context.Context(user_id='non_admin', - tenant_id='tenant1', - is_admin=False) - self._test_list_resources('network', (net1, net2), ctx) - - def test_show_network(self): - with self.network(name='net1') as net: - req = self.new_show_request('networks', net['network']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['network']['name'], - net['network']['name']) - - def test_show_network_with_subnet(self): - with self.network(name='net1') as net: - with self.subnet(net) as subnet: - req = self.new_show_request('networks', net['network']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['network']['subnets'][0], - subnet['subnet']['id']) - - def test_invalid_admin_status(self): - value = [[7, False, webob.exc.HTTPClientError.code], - [True, True, webob.exc.HTTPCreated.code], - ["True", True, webob.exc.HTTPCreated.code], - ["true", True, webob.exc.HTTPCreated.code], - [1, True, webob.exc.HTTPCreated.code], - ["False", False, webob.exc.HTTPCreated.code], - [False, False, webob.exc.HTTPCreated.code], - ["false", False, webob.exc.HTTPCreated.code], - ["7", False, webob.exc.HTTPClientError.code]] - for v in value: - data = {'network': {'name': 'net', - 'admin_state_up': v[0], - 'tenant_id': self._tenant_id}} - network_req = self.new_create_request('networks', data) - req = network_req.get_response(self.api) - self.assertEqual(req.status_int, v[2]) - if v[2] == webob.exc.HTTPCreated.code: - res = self.deserialize(self.fmt, req) - self.assertEqual(res['network']['admin_state_up'], v[1]) - - -class TestSubnetsV2(NeutronDbPluginV2TestCase): - - def _test_create_subnet(self, network=None, expected=None, **kwargs): - keys = kwargs.copy() - keys.setdefault('cidr', '10.0.0.0/24') - keys.setdefault('ip_version', 4) - keys.setdefault('enable_dhcp', True) - with self.subnet(network=network, **keys) as subnet: - # verify the response has each key with the correct value - for k in keys: - self.assertIn(k, subnet['subnet']) - if isinstance(keys[k], list): - self.assertEqual(sorted(subnet['subnet'][k]), - sorted(keys[k])) - else: - self.assertEqual(subnet['subnet'][k], keys[k]) - # verify the configured validations are correct - if expected: - for k in expected: - self.assertIn(k, subnet['subnet']) - if isinstance(expected[k], list): - self.assertEqual(sorted(subnet['subnet'][k]), - sorted(expected[k])) - else: - self.assertEqual(subnet['subnet'][k], expected[k]) - return subnet - - def test_create_subnet(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - subnet = self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr) - self.assertEqual(4, subnet['subnet']['ip_version']) - self.assertIn('name', subnet['subnet']) - - def test_create_two_subnets(self): - gateway_ips = ['10.0.0.1', '10.0.1.1'] - cidrs = ['10.0.0.0/24', '10.0.1.0/24'] - with self.network() as network: - with self.subnet(network=network, - gateway_ip=gateway_ips[0], - cidr=cidrs[0]): - with self.subnet(network=network, - gateway_ip=gateway_ips[1], - cidr=cidrs[1]): - net_req = self.new_show_request('networks', - network['network']['id']) - raw_res = net_req.get_response(self.api) - net_res = self.deserialize(self.fmt, raw_res) - for subnet_id in net_res['network']['subnets']: - sub_req = self.new_show_request('subnets', subnet_id) - raw_res = sub_req.get_response(self.api) - sub_res = self.deserialize(self.fmt, raw_res) - self.assertIn(sub_res['subnet']['cidr'], cidrs) - self.assertIn(sub_res['subnet']['gateway_ip'], - gateway_ips) - - def test_create_two_subnets_same_cidr_returns_400(self): - gateway_ip_1 = '10.0.0.1' - cidr_1 = '10.0.0.0/24' - gateway_ip_2 = '10.0.0.10' - cidr_2 = '10.0.0.0/24' - with self.network() as network: - with self.subnet(network=network, - gateway_ip=gateway_ip_1, - cidr=cidr_1): - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - with self.subnet(network=network, - gateway_ip=gateway_ip_2, - cidr=cidr_2): - pass - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnet_bad_V4_cidr(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0', - 'ip_version': '4', - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.2.1'}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_bad_V6_cidr(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': 'fe80::', - 'ip_version': '6', - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': 'fe80::1'}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_2_subnets_overlapping_cidr_allowed_returns_200(self): - cidr_1 = '10.0.0.0/23' - cidr_2 = '10.0.0.0/24' - cfg.CONF.set_override('allow_overlapping_ips', True) - - with contextlib.nested(self.subnet(cidr=cidr_1), - self.subnet(cidr=cidr_2)): - pass - - def test_create_2_subnets_overlapping_cidr_not_allowed_returns_400(self): - cidr_1 = '10.0.0.0/23' - cidr_2 = '10.0.0.0/24' - cfg.CONF.set_override('allow_overlapping_ips', False) - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - with contextlib.nested(self.subnet(cidr=cidr_1), - self.subnet(cidr=cidr_2)): - pass - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnets_bulk_native(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk subnet create") - with self.network() as net: - res = self._create_subnet_bulk(self.fmt, 2, net['network']['id'], - 'test') - self._validate_behavior_on_bulk_success(res, 'subnets') - - def test_create_subnets_bulk_emulated(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - with self.network() as net: - res = self._create_subnet_bulk(self.fmt, 2, - net['network']['id'], - 'test') - self._validate_behavior_on_bulk_success(res, 'subnets') - - def test_create_subnets_bulk_emulated_plugin_failure(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - orig = manager.NeutronManager.get_plugin().create_subnet - with mock.patch.object(manager.NeutronManager.get_plugin(), - 'create_subnet') as patched_plugin: - - def side_effect(*args, **kwargs): - self._fail_second_call(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - with self.network() as net: - res = self._create_subnet_bulk(self.fmt, 2, - net['network']['id'], - 'test') - # We expect a 500 as we injected a fault in the plugin - self._validate_behavior_on_bulk_failure( - res, 'subnets', webob.exc.HTTPServerError.code - ) - - def test_create_subnets_bulk_native_plugin_failure(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk subnet create") - plugin = manager.NeutronManager.get_plugin() - orig = plugin.create_subnet - with mock.patch.object(plugin, 'create_subnet') as patched_plugin: - def side_effect(*args, **kwargs): - return self._fail_second_call(patched_plugin, orig, - *args, **kwargs) - - patched_plugin.side_effect = side_effect - with self.network() as net: - res = self._create_subnet_bulk(self.fmt, 2, - net['network']['id'], - 'test') - - # We expect a 500 as we injected a fault in the plugin - self._validate_behavior_on_bulk_failure( - res, 'subnets', webob.exc.HTTPServerError.code - ) - - def test_delete_subnet(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - # Create new network - res = self._create_network(fmt=self.fmt, name='net', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - subnet = self._make_subnet(self.fmt, network, gateway_ip, - cidr, ip_version=4) - req = self.new_delete_request('subnets', subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_delete_subnet_port_exists_owned_by_network(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - # Create new network - res = self._create_network(fmt=self.fmt, name='net', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - subnet = self._make_subnet(self.fmt, network, gateway_ip, - cidr, ip_version=4) - self._create_port(self.fmt, - network['network']['id'], - device_owner=constants.DEVICE_OWNER_DHCP) - req = self.new_delete_request('subnets', subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_delete_subnet_dhcp_port_associated_with_other_subnets(self): - res = self._create_network(fmt=self.fmt, name='net', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - subnet1 = self._make_subnet(self.fmt, network, '10.0.0.1', - '10.0.0.0/24', ip_version=4) - subnet2 = self._make_subnet(self.fmt, network, '10.0.1.1', - '10.0.1.0/24', ip_version=4) - res = self._create_port(self.fmt, - network['network']['id'], - device_owner=constants.DEVICE_OWNER_DHCP, - fixed_ips=[ - {'subnet_id': subnet1['subnet']['id']}, - {'subnet_id': subnet2['subnet']['id']} - ]) - port = self.deserialize(self.fmt, res) - expected_subnets = [subnet1['subnet']['id'], subnet2['subnet']['id']] - self.assertEqual(expected_subnets, - [s['subnet_id'] for s in port['port']['fixed_ips']]) - req = self.new_delete_request('subnets', subnet1['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 204) - port = self._show('ports', port['port']['id']) - - expected_subnets = [subnet2['subnet']['id']] - self.assertEqual(expected_subnets, - [s['subnet_id'] for s in port['port']['fixed_ips']]) - req = self.new_delete_request('subnets', subnet2['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 204) - port = self._show('ports', port['port']['id']) - self.assertFalse(port['port']['fixed_ips']) - - def test_delete_subnet_port_exists_owned_by_other(self): - with self.subnet() as subnet: - with self.port(subnet=subnet): - id = subnet['subnet']['id'] - req = self.new_delete_request('subnets', id) - res = req.get_response(self.api) - data = self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - msg = str(n_exc.SubnetInUse(subnet_id=id)) - self.assertEqual(data['NeutronError']['message'], msg) - - def test_delete_subnet_with_other_subnet_on_network_still_in_use(self): - with self.network() as network: - with contextlib.nested( - self.subnet(network=network), - self.subnet(network=network, cidr='10.0.1.0/24', - do_delete=False)) as (subnet1, subnet2): - subnet1_id = subnet1['subnet']['id'] - subnet2_id = subnet2['subnet']['id'] - with self.port( - subnet=subnet1, - fixed_ips=[{'subnet_id': subnet1_id}]): - req = self.new_delete_request('subnets', subnet2_id) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPNoContent.code) - - def test_delete_network(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - # Create new network - res = self._create_network(fmt=self.fmt, name='net', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - self._make_subnet(self.fmt, network, gateway_ip, cidr, ip_version=4) - req = self.new_delete_request('networks', network['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_create_subnet_bad_tenant(self): - with self.network() as network: - self._create_subnet(self.fmt, - network['network']['id'], - '10.0.2.0/24', - webob.exc.HTTPNotFound.code, - ip_version=4, - tenant_id='bad_tenant_id', - gateway_ip='10.0.2.1', - device_owner='fake_owner', - set_context=True) - - def test_create_subnet_as_admin(self): - with self.network(do_delete=False) as network: - self._create_subnet(self.fmt, - network['network']['id'], - '10.0.2.0/24', - webob.exc.HTTPCreated.code, - ip_version=4, - tenant_id='bad_tenant_id', - gateway_ip='10.0.2.1', - device_owner='fake_owner', - set_context=False) - - def test_create_subnet_nonzero_cidr(self): - with contextlib.nested( - self.subnet(cidr='10.129.122.5/8'), - self.subnet(cidr='11.129.122.5/15'), - self.subnet(cidr='12.129.122.5/16'), - self.subnet(cidr='13.129.122.5/18'), - self.subnet(cidr='14.129.122.5/22'), - self.subnet(cidr='15.129.122.5/24'), - self.subnet(cidr='16.129.122.5/28'), - self.subnet(cidr='17.129.122.5/32') - ) as subs: - # the API should accept and correct these for users - self.assertEqual(subs[0]['subnet']['cidr'], '10.0.0.0/8') - self.assertEqual(subs[1]['subnet']['cidr'], '11.128.0.0/15') - self.assertEqual(subs[2]['subnet']['cidr'], '12.129.0.0/16') - self.assertEqual(subs[3]['subnet']['cidr'], '13.129.64.0/18') - self.assertEqual(subs[4]['subnet']['cidr'], '14.129.120.0/22') - self.assertEqual(subs[5]['subnet']['cidr'], '15.129.122.0/24') - self.assertEqual(subs[6]['subnet']['cidr'], '16.129.122.0/28') - self.assertEqual(subs[7]['subnet']['cidr'], '17.129.122.5/32') - - def test_create_subnet_bad_ip_version(self): - with self.network() as network: - # Check bad IP version - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 'abc', - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.2.1'}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_bad_ip_version_null(self): - with self.network() as network: - # Check bad IP version - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': None, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.2.1'}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_bad_uuid(self): - with self.network() as network: - # Check invalid UUID - data = {'subnet': {'network_id': None, - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.2.1'}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_bad_boolean(self): - with self.network() as network: - # Check invalid boolean - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': '4', - 'enable_dhcp': None, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.2.1'}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_bad_pools(self): - with self.network() as network: - # Check allocation pools - allocation_pools = [[{'end': '10.0.0.254'}], - [{'start': '10.0.0.254'}], - [{'start': '1000.0.0.254'}], - [{'start': '10.0.0.2', 'end': '10.0.0.254'}, - {'end': '10.0.0.254'}], - None, - [{'start': '10.0.0.2', 'end': '10.0.0.3'}, - {'start': '10.0.0.2', 'end': '10.0.0.3'}]] - tenant_id = network['network']['tenant_id'] - for pool in allocation_pools: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': '4', - 'tenant_id': tenant_id, - 'gateway_ip': '10.0.2.1', - 'allocation_pools': pool}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_create_subnet_bad_nameserver(self): - with self.network() as network: - # Check nameservers - nameserver_pools = [['1100.0.0.2'], - ['1.1.1.2', '1.1000.1.3'], - ['1.1.1.2', '1.1.1.2']] - tenant_id = network['network']['tenant_id'] - for nameservers in nameserver_pools: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': '4', - 'tenant_id': tenant_id, - 'gateway_ip': '10.0.2.1', - 'dns_nameservers': nameservers}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_create_subnet_bad_hostroutes(self): - with self.network() as network: - # Check hostroutes - hostroute_pools = [[{'destination': '100.0.0.0/24'}], - [{'nexthop': '10.0.2.20'}], - [{'nexthop': '10.0.2.20', - 'destination': '100.0.0.0/8'}, - {'nexthop': '10.0.2.20', - 'destination': '100.0.0.0/8'}]] - tenant_id = network['network']['tenant_id'] - for hostroutes in hostroute_pools: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': '4', - 'tenant_id': tenant_id, - 'gateway_ip': '10.0.2.1', - 'host_routes': hostroutes}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_create_subnet_defaults(self): - gateway = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.254'}] - enable_dhcp = True - subnet = self._test_create_subnet() - # verify cidr & gw have been correctly generated - self.assertEqual(subnet['subnet']['cidr'], cidr) - self.assertEqual(subnet['subnet']['gateway_ip'], gateway) - self.assertEqual(subnet['subnet']['enable_dhcp'], enable_dhcp) - self.assertEqual(subnet['subnet']['allocation_pools'], - allocation_pools) - - def test_create_subnet_gw_values(self): - # Gateway not in subnet - gateway = '100.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.1', - 'end': '10.0.0.254'}] - expected = {'gateway_ip': gateway, - 'cidr': cidr, - 'allocation_pools': allocation_pools} - self._test_create_subnet(expected=expected, gateway_ip=gateway) - # Gateway is last IP in range - gateway = '10.0.0.254' - allocation_pools = [{'start': '10.0.0.1', - 'end': '10.0.0.253'}] - expected = {'gateway_ip': gateway, - 'cidr': cidr, - 'allocation_pools': allocation_pools} - self._test_create_subnet(expected=expected, gateway_ip=gateway) - # Gateway is first in subnet - gateway = '10.0.0.1' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.254'}] - expected = {'gateway_ip': gateway, - 'cidr': cidr, - 'allocation_pools': allocation_pools} - self._test_create_subnet(expected=expected, - gateway_ip=gateway) - - def test_create_subnet_gw_outside_cidr_force_on_returns_400(self): - cfg.CONF.set_override('force_gateway_on_subnet', True) - with self.network() as network: - self._create_subnet(self.fmt, - network['network']['id'], - '10.0.0.0/24', - webob.exc.HTTPClientError.code, - gateway_ip='100.0.0.1') - - def test_create_subnet_gw_of_network_force_on_returns_400(self): - cfg.CONF.set_override('force_gateway_on_subnet', True) - with self.network() as network: - self._create_subnet(self.fmt, - network['network']['id'], - '10.0.0.0/24', - webob.exc.HTTPClientError.code, - gateway_ip='10.0.0.0') - - def test_create_subnet_gw_bcast_force_on_returns_400(self): - cfg.CONF.set_override('force_gateway_on_subnet', True) - with self.network() as network: - self._create_subnet(self.fmt, - network['network']['id'], - '10.0.0.0/24', - webob.exc.HTTPClientError.code, - gateway_ip='10.0.0.255') - - def test_create_subnet_with_allocation_pool(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.100'}] - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools) - - def test_create_subnet_with_none_gateway(self): - cidr = '10.0.0.0/24' - self._test_create_subnet(gateway_ip=None, - cidr=cidr) - - def test_create_subnet_with_none_gateway_fully_allocated(self): - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.1', - 'end': '10.0.0.254'}] - self._test_create_subnet(gateway_ip=None, - cidr=cidr, - allocation_pools=allocation_pools) - - def test_subnet_with_allocation_range(self): - with self.network() as network: - net_id = network['network']['id'] - data = {'subnet': {'network_id': net_id, - 'cidr': '10.0.0.0/24', - 'ip_version': 4, - 'gateway_ip': '10.0.0.1', - 'tenant_id': network['network']['tenant_id'], - 'allocation_pools': [{'start': '10.0.0.100', - 'end': '10.0.0.120'}]}} - subnet_req = self.new_create_request('subnets', data) - subnet = self.deserialize(self.fmt, - subnet_req.get_response(self.api)) - # Check fixed IP not in allocation range - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.10'}]} - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - port = self.deserialize(self.fmt, res) - # delete the port - self._delete('ports', port['port']['id']) - - # Check when fixed IP is gateway - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.1'}]} - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - port = self.deserialize(self.fmt, res) - # delete the port - self._delete('ports', port['port']['id']) - - def test_create_subnet_with_none_gateway_allocation_pool(self): - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.100'}] - self._test_create_subnet(gateway_ip=None, - cidr=cidr, - allocation_pools=allocation_pools) - - def test_create_subnet_with_v6_allocation_pool(self): - gateway_ip = 'fe80::1' - cidr = 'fe80::/80' - allocation_pools = [{'start': 'fe80::2', - 'end': 'fe80::ffff:fffa:ffff'}] - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, ip_version=6, - allocation_pools=allocation_pools) - - def test_create_subnet_with_large_allocation_pool(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/8' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.100'}, - {'start': '10.1.0.0', - 'end': '10.200.0.100'}] - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools) - - def test_create_subnet_multiple_allocation_pools(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.100'}, - {'start': '10.0.0.110', - 'end': '10.0.0.150'}] - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools) - - def test_create_subnet_with_dhcp_disabled(self): - enable_dhcp = False - self._test_create_subnet(enable_dhcp=enable_dhcp) - - def test_create_subnet_default_gw_conflict_allocation_pool_returns_409( - self): - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.1', - 'end': '10.0.0.5'}] - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(cidr=cidr, - allocation_pools=allocation_pools) - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPConflict.code) - - def test_create_subnet_gateway_in_allocation_pool_returns_409(self): - gateway_ip = '10.0.0.50' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.1', - 'end': '10.0.0.100'}] - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools) - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPConflict.code) - - def test_create_subnet_overlapping_allocation_pools_returns_409(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.150'}, - {'start': '10.0.0.140', - 'end': '10.0.0.180'}] - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools) - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPConflict.code) - - def test_create_subnet_invalid_allocation_pool_returns_400(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.256'}] - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools) - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnet_out_of_range_allocation_pool_returns_400(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.1.6'}] - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools) - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnet_shared_returns_400(self): - cidr = '10.0.0.0/24' - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(cidr=cidr, - shared=True) - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnet_inconsistent_ipv6_cidrv4(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 6, - 'tenant_id': network['network']['tenant_id']}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_inconsistent_ipv4_cidrv6(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': 'fe80::0/80', - 'ip_version': 4, - 'tenant_id': network['network']['tenant_id']}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_inconsistent_ipv4_gatewayv6(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'gateway_ip': 'fe80::1', - 'tenant_id': network['network']['tenant_id']}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_inconsistent_ipv6_gatewayv4(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': 'fe80::0/80', - 'ip_version': 6, - 'gateway_ip': '192.168.0.1', - 'tenant_id': network['network']['tenant_id']}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_inconsistent_ipv6_dns_v4(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': 'fe80::0/80', - 'ip_version': 6, - 'dns_nameservers': ['192.168.0.1'], - 'tenant_id': network['network']['tenant_id']}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_inconsistent_ipv4_hostroute_dst_v6(self): - host_routes = [{'destination': 'fe80::0/48', - 'nexthop': '10.0.2.20'}] - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'host_routes': host_routes, - 'tenant_id': network['network']['tenant_id']}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_inconsistent_ipv4_hostroute_np_v6(self): - host_routes = [{'destination': '172.16.0.0/24', - 'nexthop': 'fe80::1'}] - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'host_routes': host_routes, - 'tenant_id': network['network']['tenant_id']}} - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_ipv6_attributes(self): - gateway_ip = 'fe80::1' - cidr = 'fe80::/80' - - for mode in constants.IPV6_MODES: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, ip_version=6, - ipv6_ra_mode=mode, - ipv6_address_mode=mode) - - def test_create_subnet_ipv6_attributes_no_dhcp_enabled(self): - gateway_ip = 'fe80::1' - cidr = 'fe80::/80' - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - for mode in constants.IPV6_MODES: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, ip_version=6, - enable_dhcp=False, - ipv6_ra_mode=mode, - ipv6_address_mode=mode) - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnet_invalid_ipv6_ra_mode(self): - gateway_ip = 'fe80::1' - cidr = 'fe80::/80' - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, ip_version=6, - ipv6_ra_mode='foo', - ipv6_address_mode='slaac') - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnet_invalid_ipv6_address_mode(self): - gateway_ip = 'fe80::1' - cidr = 'fe80::/80' - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, ip_version=6, - ipv6_ra_mode='slaac', - ipv6_address_mode='baz') - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnet_invalid_ipv6_combination(self): - gateway_ip = 'fe80::1' - cidr = 'fe80::/80' - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, ip_version=6, - ipv6_ra_mode='stateful', - ipv6_address_mode='stateless') - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnet_ipv6_single_attribute_set(self): - gateway_ip = 'fe80::1' - cidr = 'fe80::/80' - for mode in constants.IPV6_MODES: - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, ip_version=6, - ipv6_ra_mode=None, - ipv6_address_mode=mode) - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, ip_version=6, - ipv6_ra_mode=mode, - ipv6_address_mode=None) - - def test_create_subnet_ipv6_ra_mode_ip_version_4(self): - cidr = '10.0.2.0/24' - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet(cidr=cidr, ip_version=4, - ipv6_ra_mode=constants.DHCPV6_STATEFUL) - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_create_subnet_ipv6_address_mode_ip_version_4(self): - cidr = '10.0.2.0/24' - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_subnet( - cidr=cidr, ip_version=4, - ipv6_address_mode=constants.DHCPV6_STATEFUL) - self.assertEqual(ctx_manager.exception.code, - webob.exc.HTTPClientError.code) - - def test_update_subnet_no_gateway(self): - with self.subnet() as subnet: - data = {'subnet': {'gateway_ip': '11.0.0.1'}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['subnet']['gateway_ip'], - data['subnet']['gateway_ip']) - data = {'subnet': {'gateway_ip': None}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertIsNone(data['subnet']['gateway_ip']) - - def test_update_subnet(self): - with self.subnet() as subnet: - data = {'subnet': {'gateway_ip': '11.0.0.1'}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['subnet']['gateway_ip'], - data['subnet']['gateway_ip']) - - def test_update_subnet_adding_additional_host_routes_and_dns(self): - host_routes = [{'destination': '172.16.0.0/24', - 'nexthop': '10.0.2.2'}] - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'dns_nameservers': ['192.168.0.1'], - 'host_routes': host_routes, - 'tenant_id': network['network']['tenant_id']}} - subnet_req = self.new_create_request('subnets', data) - res = self.deserialize(self.fmt, subnet_req.get_response(self.api)) - - host_routes = [{'destination': '172.16.0.0/24', - 'nexthop': '10.0.2.2'}, - {'destination': '192.168.0.0/24', - 'nexthop': '10.0.2.3'}] - - dns_nameservers = ['192.168.0.1', '192.168.0.2'] - data = {'subnet': {'host_routes': host_routes, - 'dns_nameservers': dns_nameservers}} - req = self.new_update_request('subnets', data, - res['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(sorted(res['subnet']['host_routes']), - sorted(host_routes)) - self.assertEqual(sorted(res['subnet']['dns_nameservers']), - sorted(dns_nameservers)) - - def test_update_subnet_shared_returns_400(self): - with self.network(shared=True) as network: - with self.subnet(network=network) as subnet: - data = {'subnet': {'shared': True}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_gw_outside_cidr_force_on_returns_400(self): - cfg.CONF.set_override('force_gateway_on_subnet', True) - with self.network() as network: - with self.subnet(network=network) as subnet: - data = {'subnet': {'gateway_ip': '100.0.0.1'}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_gw_ip_in_use_returns_409(self): - with self.network() as network: - with self.subnet( - network=network, - allocation_pools=[{'start': '10.0.0.100', - 'end': '10.0.0.253'}]) as subnet: - subnet_data = subnet['subnet'] - with self.port( - subnet=subnet, - fixed_ips=[{'subnet_id': subnet_data['id'], - 'ip_address': subnet_data['gateway_ip']}]): - data = {'subnet': {'gateway_ip': '10.0.0.99'}} - req = self.new_update_request('subnets', data, - subnet_data['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 409) - - def test_update_subnet_inconsistent_ipv4_gatewayv6(self): - with self.network() as network: - with self.subnet(network=network) as subnet: - data = {'subnet': {'gateway_ip': 'fe80::1'}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_inconsistent_ipv6_gatewayv4(self): - with self.network() as network: - with self.subnet(network=network, - ip_version=6, cidr='fe80::/48') as subnet: - data = {'subnet': {'gateway_ip': '10.1.1.1'}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_inconsistent_ipv4_dns_v6(self): - dns_nameservers = ['fe80::1'] - with self.network() as network: - with self.subnet(network=network) as subnet: - data = {'subnet': {'dns_nameservers': dns_nameservers}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_inconsistent_ipv6_hostroute_dst_v4(self): - host_routes = [{'destination': 'fe80::0/48', - 'nexthop': '10.0.2.20'}] - with self.network() as network: - with self.subnet(network=network, - ip_version=6, cidr='fe80::/48') as subnet: - data = {'subnet': {'host_routes': host_routes}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_inconsistent_ipv6_hostroute_np_v4(self): - host_routes = [{'destination': '172.16.0.0/24', - 'nexthop': 'fe80::1'}] - with self.network() as network: - with self.subnet(network=network, - ip_version=6, cidr='fe80::/48') as subnet: - data = {'subnet': {'host_routes': host_routes}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_gateway_in_allocation_pool_returns_409(self): - allocation_pools = [{'start': '10.0.0.2', 'end': '10.0.0.254'}] - with self.network() as network: - with self.subnet(network=network, - allocation_pools=allocation_pools, - cidr='10.0.0.0/24') as subnet: - data = {'subnet': {'gateway_ip': '10.0.0.50'}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPConflict.code) - - def test_update_subnet_ipv6_attributes(self): - with self.subnet(ip_version=6, cidr='fe80::/80', - ipv6_ra_mode=constants.IPV6_SLAAC, - ipv6_address_mode=constants.IPV6_SLAAC) as subnet: - data = {'subnet': {'ipv6_ra_mode': constants.DHCPV6_STATEFUL, - 'ipv6_address_mode': constants.DHCPV6_STATEFUL}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['subnet']['ipv6_ra_mode'], - data['subnet']['ipv6_ra_mode']) - self.assertEqual(res['subnet']['ipv6_address_mode'], - data['subnet']['ipv6_address_mode']) - - def test_update_subnet_ipv6_inconsistent_ra_attribute(self): - with self.subnet(ip_version=6, cidr='fe80::/80', - ipv6_ra_mode=constants.IPV6_SLAAC, - ipv6_address_mode=constants.IPV6_SLAAC) as subnet: - data = {'subnet': {'ipv6_ra_mode': constants.DHCPV6_STATEFUL}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_ipv6_inconsistent_address_attribute(self): - with self.subnet(ip_version=6, cidr='fe80::/80', - ipv6_ra_mode=constants.IPV6_SLAAC, - ipv6_address_mode=constants.IPV6_SLAAC) as subnet: - data = {'subnet': {'ipv6_address_mode': constants.DHCPV6_STATEFUL}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_ipv6_inconsistent_enable_dhcp(self): - with self.subnet(ip_version=6, cidr='fe80::/80', - ipv6_ra_mode=constants.IPV6_SLAAC, - ipv6_address_mode=constants.IPV6_SLAAC) as subnet: - data = {'subnet': {'enable_dhcp': False}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_ipv6_ra_mode_ip_version_4(self): - with self.network() as network: - with self.subnet(network=network) as subnet: - data = {'subnet': {'ipv6_ra_mode': - constants.DHCPV6_STATEFUL}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_ipv6_address_mode_ip_version_4(self): - with self.network() as network: - with self.subnet(network=network) as subnet: - data = {'subnet': {'ipv6_address_mode': - constants.DHCPV6_STATEFUL}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_update_subnet_allocation_pools(self): - """Test that we can successfully update with sane params. - - This will create a subnet with specified allocation_pools - Then issue an update (PUT) to update these using correct - (i.e. non erroneous) params. Finally retrieve the updated - subnet and verify. - """ - allocation_pools = [{'start': '192.168.0.2', 'end': '192.168.0.254'}] - with self.network() as network: - with self.subnet(network=network, - allocation_pools=allocation_pools, - cidr='192.168.0.0/24') as subnet: - data = {'subnet': {'allocation_pools': [ - {'start': '192.168.0.10', 'end': '192.168.0.20'}, - {'start': '192.168.0.30', 'end': '192.168.0.40'}]}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - #check res code but then do GET on subnet for verification - res = req.get_response(self.api) - self.assertEqual(res.status_code, 200) - req = self.new_show_request('subnets', subnet['subnet']['id'], - self.fmt) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(len(res['subnet']['allocation_pools']), 2) - res_vals = res['subnet']['allocation_pools'][0].values() +\ - res['subnet']['allocation_pools'][1].values() - for pool_val in ['10', '20', '30', '40']: - self.assertTrue('192.168.0.%s' % (pool_val) in res_vals) - - #updating alloc pool to something outside subnet.cidr - def test_update_subnet_allocation_pools_invalid_pool_for_cidr(self): - """Test update alloc pool to something outside subnet.cidr. - - This makes sure that an erroneous allocation_pool specified - in a subnet update (outside subnet cidr) will result in an error. - """ - allocation_pools = [{'start': '192.168.0.2', 'end': '192.168.0.254'}] - with self.network() as network: - with self.subnet(network=network, - allocation_pools=allocation_pools, - cidr='192.168.0.0/24') as subnet: - data = {'subnet': {'allocation_pools': [ - {'start': '10.0.0.10', 'end': '10.0.0.20'}]}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, - webob.exc.HTTPClientError.code) - - def test_show_subnet(self): - with self.network() as network: - with self.subnet(network=network) as subnet: - req = self.new_show_request('subnets', - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['subnet']['id'], - subnet['subnet']['id']) - self.assertEqual(res['subnet']['network_id'], - network['network']['id']) - - def test_list_subnets(self): - with self.network() as network: - with contextlib.nested(self.subnet(network=network, - gateway_ip='10.0.0.1', - cidr='10.0.0.0/24'), - self.subnet(network=network, - gateway_ip='10.0.1.1', - cidr='10.0.1.0/24'), - self.subnet(network=network, - gateway_ip='10.0.2.1', - cidr='10.0.2.0/24')) as subnets: - self._test_list_resources('subnet', subnets) - - def test_list_subnets_shared(self): - with self.network(shared=True) as network: - with self.subnet(network=network, cidr='10.0.0.0/24') as subnet: - with self.subnet(cidr='10.0.1.0/24') as priv_subnet: - # normal user should see only 1 subnet - req = self.new_list_request('subnets') - req.environ['neutron.context'] = context.Context( - '', 'some_tenant') - res = self.deserialize(self.fmt, - req.get_response(self.api)) - self.assertEqual(len(res['subnets']), 1) - self.assertEqual(res['subnets'][0]['cidr'], - subnet['subnet']['cidr']) - # admin will see both subnets - admin_req = self.new_list_request('subnets') - admin_res = self.deserialize( - self.fmt, admin_req.get_response(self.api)) - self.assertEqual(len(admin_res['subnets']), 2) - cidrs = [sub['cidr'] for sub in admin_res['subnets']] - self.assertIn(subnet['subnet']['cidr'], cidrs) - self.assertIn(priv_subnet['subnet']['cidr'], cidrs) - - def test_list_subnets_with_parameter(self): - with self.network() as network: - with contextlib.nested(self.subnet(network=network, - gateway_ip='10.0.0.1', - cidr='10.0.0.0/24'), - self.subnet(network=network, - gateway_ip='10.0.1.1', - cidr='10.0.1.0/24') - ) as subnets: - query_params = 'ip_version=4&ip_version=6' - self._test_list_resources('subnet', subnets, - query_params=query_params) - query_params = 'ip_version=6' - self._test_list_resources('subnet', [], - query_params=query_params) - - def test_list_subnets_with_sort_native(self): - if self._skip_native_sorting: - self.skipTest("Skip test for not implemented sorting feature") - with contextlib.nested(self.subnet(enable_dhcp=True, - cidr='10.0.0.0/24'), - self.subnet(enable_dhcp=False, - cidr='11.0.0.0/24'), - self.subnet(enable_dhcp=False, - cidr='12.0.0.0/24') - ) as (subnet1, subnet2, subnet3): - self._test_list_with_sort('subnet', (subnet3, subnet2, subnet1), - [('enable_dhcp', 'asc'), - ('cidr', 'desc')]) - - def test_list_subnets_with_sort_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_sorting_helper', - new=_fake_get_sorting_helper) - helper_patcher.start() - with contextlib.nested(self.subnet(enable_dhcp=True, - cidr='10.0.0.0/24'), - self.subnet(enable_dhcp=False, - cidr='11.0.0.0/24'), - self.subnet(enable_dhcp=False, - cidr='12.0.0.0/24') - ) as (subnet1, subnet2, subnet3): - self._test_list_with_sort('subnet', (subnet3, - subnet2, - subnet1), - [('enable_dhcp', 'asc'), - ('cidr', 'desc')]) - - def test_list_subnets_with_pagination_native(self): - if self._skip_native_pagination: - self.skipTest("Skip test for not implemented sorting feature") - with contextlib.nested(self.subnet(cidr='10.0.0.0/24'), - self.subnet(cidr='11.0.0.0/24'), - self.subnet(cidr='12.0.0.0/24') - ) as (subnet1, subnet2, subnet3): - self._test_list_with_pagination('subnet', - (subnet1, subnet2, subnet3), - ('cidr', 'asc'), 2, 2) - - def test_list_subnets_with_pagination_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_pagination_helper', - new=_fake_get_pagination_helper) - helper_patcher.start() - with contextlib.nested(self.subnet(cidr='10.0.0.0/24'), - self.subnet(cidr='11.0.0.0/24'), - self.subnet(cidr='12.0.0.0/24') - ) as (subnet1, subnet2, subnet3): - self._test_list_with_pagination('subnet', - (subnet1, subnet2, subnet3), - ('cidr', 'asc'), 2, 2) - - def test_list_subnets_with_pagination_reverse_native(self): - if self._skip_native_sorting: - self.skipTest("Skip test for not implemented sorting feature") - with contextlib.nested(self.subnet(cidr='10.0.0.0/24'), - self.subnet(cidr='11.0.0.0/24'), - self.subnet(cidr='12.0.0.0/24') - ) as (subnet1, subnet2, subnet3): - self._test_list_with_pagination_reverse('subnet', - (subnet1, subnet2, - subnet3), - ('cidr', 'asc'), 2, 2) - - def test_list_subnets_with_pagination_reverse_emulated(self): - helper_patcher = mock.patch( - 'neutron.api.v2.base.Controller._get_pagination_helper', - new=_fake_get_pagination_helper) - helper_patcher.start() - with contextlib.nested(self.subnet(cidr='10.0.0.0/24'), - self.subnet(cidr='11.0.0.0/24'), - self.subnet(cidr='12.0.0.0/24') - ) as (subnet1, subnet2, subnet3): - self._test_list_with_pagination_reverse('subnet', - (subnet1, subnet2, - subnet3), - ('cidr', 'asc'), 2, 2) - - def test_invalid_ip_version(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 7, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.2.1'}} - - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_invalid_subnet(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': 'invalid', - 'ip_version': 4, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.2.1'}} - - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_invalid_ip_address(self): - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': 'ipaddress'}} - - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_invalid_uuid(self): - with self.network() as network: - data = {'subnet': {'network_id': 'invalid-uuid', - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.0.1'}} - - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_with_one_dns(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.100'}] - dns_nameservers = ['1.2.3.4'] - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools, - dns_nameservers=dns_nameservers) - - def test_create_subnet_with_two_dns(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.100'}] - dns_nameservers = ['1.2.3.4', '4.3.2.1'] - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools, - dns_nameservers=dns_nameservers) - - def test_create_subnet_with_too_many_dns(self): - with self.network() as network: - dns_list = ['1.1.1.1', '2.2.2.2', '3.3.3.3'] - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.0.1', - 'dns_nameservers': dns_list}} - - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_create_subnet_with_one_host_route(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.100'}] - host_routes = [{'destination': '135.207.0.0/16', - 'nexthop': '1.2.3.4'}] - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools, - host_routes=host_routes) - - def test_create_subnet_with_two_host_routes(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.100'}] - host_routes = [{'destination': '135.207.0.0/16', - 'nexthop': '1.2.3.4'}, - {'destination': '12.0.0.0/8', - 'nexthop': '4.3.2.1'}] - - self._test_create_subnet(gateway_ip=gateway_ip, - cidr=cidr, - allocation_pools=allocation_pools, - host_routes=host_routes) - - def test_create_subnet_with_too_many_routes(self): - with self.network() as network: - host_routes = [{'destination': '135.207.0.0/16', - 'nexthop': '1.2.3.4'}, - {'destination': '12.0.0.0/8', - 'nexthop': '4.3.2.1'}, - {'destination': '141.212.0.0/16', - 'nexthop': '2.2.2.2'}] - - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.0.1', - 'host_routes': host_routes}} - - subnet_req = self.new_create_request('subnets', data) - res = subnet_req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_update_subnet_dns(self): - with self.subnet() as subnet: - data = {'subnet': {'dns_nameservers': ['11.0.0.1']}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['subnet']['dns_nameservers'], - data['subnet']['dns_nameservers']) - - def test_update_subnet_dns_to_None(self): - with self.subnet(dns_nameservers=['11.0.0.1']) as subnet: - data = {'subnet': {'dns_nameservers': None}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual([], res['subnet']['dns_nameservers']) - data = {'subnet': {'dns_nameservers': ['11.0.0.3']}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(data['subnet']['dns_nameservers'], - res['subnet']['dns_nameservers']) - - def test_update_subnet_dns_with_too_many_entries(self): - with self.subnet() as subnet: - dns_list = ['1.1.1.1', '2.2.2.2', '3.3.3.3'] - data = {'subnet': {'dns_nameservers': dns_list}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_update_subnet_route(self): - with self.subnet() as subnet: - data = {'subnet': {'host_routes': - [{'destination': '12.0.0.0/8', 'nexthop': '1.2.3.4'}]}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(res['subnet']['host_routes'], - data['subnet']['host_routes']) - - def test_update_subnet_route_to_None(self): - with self.subnet(host_routes=[{'destination': '12.0.0.0/8', - 'nexthop': '1.2.3.4'}]) as subnet: - data = {'subnet': {'host_routes': None}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual([], res['subnet']['host_routes']) - data = {'subnet': {'host_routes': [{'destination': '12.0.0.0/8', - 'nexthop': '1.2.3.4'}]}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(data['subnet']['host_routes'], - res['subnet']['host_routes']) - - def test_update_subnet_route_with_too_many_entries(self): - with self.subnet() as subnet: - data = {'subnet': {'host_routes': [ - {'destination': '12.0.0.0/8', 'nexthop': '1.2.3.4'}, - {'destination': '13.0.0.0/8', 'nexthop': '1.2.3.5'}, - {'destination': '14.0.0.0/8', 'nexthop': '1.2.3.6'}]}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPClientError.code) - - def test_delete_subnet_with_dns(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - dns_nameservers = ['1.2.3.4'] - # Create new network - res = self._create_network(fmt=self.fmt, name='net', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - subnet = self._make_subnet(self.fmt, network, gateway_ip, - cidr, ip_version=4, - dns_nameservers=dns_nameservers) - req = self.new_delete_request('subnets', subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_delete_subnet_with_route(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - host_routes = [{'destination': '135.207.0.0/16', - 'nexthop': '1.2.3.4'}] - # Create new network - res = self._create_network(fmt=self.fmt, name='net', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - subnet = self._make_subnet(self.fmt, network, gateway_ip, - cidr, ip_version=4, - host_routes=host_routes) - req = self.new_delete_request('subnets', subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_delete_subnet_with_dns_and_route(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - dns_nameservers = ['1.2.3.4'] - host_routes = [{'destination': '135.207.0.0/16', - 'nexthop': '1.2.3.4'}] - # Create new network - res = self._create_network(fmt=self.fmt, name='net', - admin_state_up=True) - network = self.deserialize(self.fmt, res) - subnet = self._make_subnet(self.fmt, network, gateway_ip, - cidr, ip_version=4, - dns_nameservers=dns_nameservers, - host_routes=host_routes) - req = self.new_delete_request('subnets', subnet['subnet']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def _helper_test_validate_subnet(self, option, exception): - cfg.CONF.set_override(option, 0) - with self.network() as network: - subnet = {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'tenant_id': network['network']['tenant_id'], - 'gateway_ip': '10.0.2.1', - 'dns_nameservers': ['8.8.8.8'], - 'host_routes': [{'destination': '135.207.0.0/16', - 'nexthop': '1.2.3.4'}]} - plugin = manager.NeutronManager.get_plugin() - e = self.assertRaises(exception, - plugin._validate_subnet, - context.get_admin_context( - load_admin_roles=False), - subnet) - self.assertThat( - str(e), - matchers.Not(matchers.Contains('built-in function id'))) - - def test_validate_subnet_dns_nameservers_exhausted(self): - self._helper_test_validate_subnet( - 'max_dns_nameservers', - n_exc.DNSNameServersExhausted) - - def test_validate_subnet_host_routes_exhausted(self): - self._helper_test_validate_subnet( - 'max_subnet_host_routes', - n_exc.HostRoutesExhausted) - - -class DbModelTestCase(base.BaseTestCase): - """DB model tests.""" - def test_repr(self): - """testing the string representation of 'model' classes.""" - network = models_v2.Network(name="net_net", status="OK", - admin_state_up=True) - actual_repr_output = repr(network) - exp_start_with = "") - final_exp = exp_start_with + exp_middle + exp_end_with - self.assertEqual(actual_repr_output, final_exp) - - -class TestNeutronDbPluginV2(base.BaseTestCase): - """Unit Tests for NeutronDbPluginV2 IPAM Logic.""" - - def test_generate_ip(self): - with mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2, - '_try_generate_ip') as generate: - with mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2, - '_rebuild_availability_ranges') as rebuild: - - db_base_plugin_v2.NeutronDbPluginV2._generate_ip('c', 's') - - generate.assert_called_once_with('c', 's') - self.assertEqual(0, rebuild.call_count) - - def test_generate_ip_exhausted_pool(self): - with mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2, - '_try_generate_ip') as generate: - with mock.patch.object(db_base_plugin_v2.NeutronDbPluginV2, - '_rebuild_availability_ranges') as rebuild: - - exception = n_exc.IpAddressGenerationFailure(net_id='n') - generate.side_effect = exception - - # I want the side_effect to throw an exception once but I - # didn't see a way to do this. So, let it throw twice and - # catch the second one. Check below to ensure that - # _try_generate_ip was called twice. - try: - db_base_plugin_v2.NeutronDbPluginV2._generate_ip('c', 's') - except n_exc.IpAddressGenerationFailure: - pass - - self.assertEqual(2, generate.call_count) - rebuild.assert_called_once_with('c', 's') - - def test_rebuild_availability_ranges(self): - pools = [{'id': 'a', - 'first_ip': '192.168.1.3', - 'last_ip': '192.168.1.10'}, - {'id': 'b', - 'first_ip': '192.168.1.100', - 'last_ip': '192.168.1.120'}] - - allocations = [{'ip_address': '192.168.1.3'}, - {'ip_address': '192.168.1.78'}, - {'ip_address': '192.168.1.7'}, - {'ip_address': '192.168.1.110'}, - {'ip_address': '192.168.1.11'}, - {'ip_address': '192.168.1.4'}, - {'ip_address': '192.168.1.111'}] - - ip_qry = mock.Mock() - ip_qry.with_lockmode.return_value = ip_qry - ip_qry.filter_by.return_value = allocations - - pool_qry = mock.Mock() - pool_qry.options.return_value = pool_qry - pool_qry.with_lockmode.return_value = pool_qry - pool_qry.filter_by.return_value = pools - - def return_queries_side_effect(*args, **kwargs): - if args[0] == models_v2.IPAllocation: - return ip_qry - if args[0] == models_v2.IPAllocationPool: - return pool_qry - - context = mock.Mock() - context.session.query.side_effect = return_queries_side_effect - subnets = [mock.MagicMock()] - - db_base_plugin_v2.NeutronDbPluginV2._rebuild_availability_ranges( - context, subnets) - - actual = [[args[0].allocation_pool_id, - args[0].first_ip, args[0].last_ip] - for _name, args, _kwargs in context.session.add.mock_calls] - - self.assertEqual([['a', '192.168.1.5', '192.168.1.6'], - ['a', '192.168.1.8', '192.168.1.10'], - ['b', '192.168.1.100', '192.168.1.109'], - ['b', '192.168.1.112', '192.168.1.120']], actual) - - -class NeutronDbPluginV2AsMixinTestCase(base.BaseTestCase): - """Tests for NeutronDbPluginV2 as Mixin. - - While NeutronDbPluginV2TestCase checks NeutronDbPlugin and all plugins as - a complete plugin, this test case verifies abilities of NeutronDbPlugin - which are provided to other plugins (e.g. DB operations). This test case - may include tests only for NeutronDbPlugin, so this should not be used in - unit tests for other plugins. - """ - - def setUp(self): - super(NeutronDbPluginV2AsMixinTestCase, self).setUp() - self.plugin = importutils.import_object(DB_PLUGIN_KLASS) - self.context = context.get_admin_context() - self.net_data = {'network': {'id': 'fake-id', - 'name': 'net1', - 'admin_state_up': True, - 'tenant_id': 'test-tenant', - 'shared': False}} - self.addCleanup(db.clear_db) - - def test_create_network_with_default_status(self): - net = self.plugin.create_network(self.context, self.net_data) - default_net_create_status = 'ACTIVE' - expected = [('id', 'fake-id'), ('name', 'net1'), - ('admin_state_up', True), ('tenant_id', 'test-tenant'), - ('shared', False), ('status', default_net_create_status)] - for k, v in expected: - self.assertEqual(net[k], v) - - def test_create_network_with_status_BUILD(self): - self.net_data['network']['status'] = 'BUILD' - net = self.plugin.create_network(self.context, self.net_data) - self.assertEqual(net['status'], 'BUILD') - - -class TestBasicGetXML(TestBasicGet): - fmt = 'xml' - - -class TestNetworksV2XML(TestNetworksV2): - fmt = 'xml' - - -class TestPortsV2XML(TestPortsV2): - fmt = 'xml' - - -class TestSubnetsV2XML(TestSubnetsV2): - fmt = 'xml' - - -class TestV2HTTPResponseXML(TestV2HTTPResponse): - fmt = 'xml' diff --git a/neutron/tests/unit/test_db_rpc_base.py b/neutron/tests/unit/test_db_rpc_base.py deleted file mode 100644 index 3ba662313..000000000 --- a/neutron/tests/unit/test_db_rpc_base.py +++ /dev/null @@ -1,233 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 neutron.common import constants -from neutron.common import exceptions as n_exc -from neutron.db import dhcp_rpc_base -from neutron.openstack.common.db import exception as db_exc -from neutron.tests import base - - -class TestDhcpRpcCallbackMixin(base.BaseTestCase): - - def setUp(self): - super(TestDhcpRpcCallbackMixin, self).setUp() - self.plugin_p = mock.patch('neutron.manager.NeutronManager.get_plugin') - get_plugin = self.plugin_p.start() - self.plugin = mock.MagicMock() - get_plugin.return_value = self.plugin - self.callbacks = dhcp_rpc_base.DhcpRpcCallbackMixin() - self.log_p = mock.patch('neutron.db.dhcp_rpc_base.LOG') - self.log = self.log_p.start() - - def test_get_active_networks(self): - plugin_retval = [dict(id='a'), dict(id='b')] - self.plugin.get_networks.return_value = plugin_retval - - networks = self.callbacks.get_active_networks(mock.Mock(), host='host') - - self.assertEqual(networks, ['a', 'b']) - self.plugin.assert_has_calls( - [mock.call.get_networks(mock.ANY, - filters=dict(admin_state_up=[True]))]) - - self.assertEqual(len(self.log.mock_calls), 1) - - def _test__port_action_with_failures(self, exc=None, action=None): - port = { - 'network_id': 'foo_network_id', - 'device_owner': constants.DEVICE_OWNER_DHCP, - 'fixed_ips': [{'subnet_id': 'foo_subnet_id'}] - } - self.plugin.create_port.side_effect = exc - self.assertIsNone(self.callbacks._port_action(self.plugin, - mock.Mock(), - {'port': port}, - action)) - - def _test__port_action_good_action(self, action, port, expected_call): - self.callbacks._port_action(self.plugin, mock.Mock(), - port, action) - self.plugin.assert_has_calls(expected_call) - - def test_port_action_create_port(self): - self._test__port_action_good_action( - 'create_port', mock.Mock(), - mock.call.create_port(mock.ANY, mock.ANY)) - - def test_port_action_update_port(self): - fake_port = {'id': 'foo_port_id', 'port': mock.Mock()} - self._test__port_action_good_action( - 'update_port', fake_port, - mock.call.update_port(mock.ANY, 'foo_port_id', mock.ANY)) - - def test__port_action_bad_action(self): - self.assertRaises( - n_exc.Invalid, - self._test__port_action_with_failures, - exc=None, - action='foo_action') - - def test_create_port_catch_network_not_found(self): - self._test__port_action_with_failures( - exc=n_exc.NetworkNotFound(net_id='foo_network_id'), - action='create_port') - - def test_create_port_catch_subnet_not_found(self): - self._test__port_action_with_failures( - exc=n_exc.SubnetNotFound(subnet_id='foo_subnet_id'), - action='create_port') - - def test_create_port_catch_db_error(self): - self._test__port_action_with_failures(exc=db_exc.DBError(), - action='create_port') - - def test_create_port_catch_ip_generation_failure_reraise(self): - self.assertRaises( - n_exc.IpAddressGenerationFailure, - self._test__port_action_with_failures, - exc=n_exc.IpAddressGenerationFailure(net_id='foo_network_id'), - action='create_port') - - def test_create_port_catch_and_handle_ip_generation_failure(self): - self.plugin.get_subnet.side_effect = ( - n_exc.SubnetNotFound(subnet_id='foo_subnet_id')) - self._test__port_action_with_failures( - exc=n_exc.IpAddressGenerationFailure(net_id='foo_network_id'), - action='create_port') - - def test_get_network_info_return_none_on_not_found(self): - self.plugin.get_network.side_effect = n_exc.NetworkNotFound(net_id='a') - retval = self.callbacks.get_network_info(mock.Mock(), network_id='a') - self.assertIsNone(retval) - - def test_get_network_info(self): - network_retval = dict(id='a') - - subnet_retval = mock.Mock() - port_retval = mock.Mock() - - self.plugin.get_network.return_value = network_retval - self.plugin.get_subnets.return_value = subnet_retval - self.plugin.get_ports.return_value = port_retval - - retval = self.callbacks.get_network_info(mock.Mock(), network_id='a') - self.assertEqual(retval, network_retval) - self.assertEqual(retval['subnets'], subnet_retval) - self.assertEqual(retval['ports'], port_retval) - - def _test_get_dhcp_port_helper(self, port_retval, other_expectations=[], - update_port=None, create_port=None): - subnets_retval = [dict(id='a', enable_dhcp=True), - dict(id='b', enable_dhcp=False)] - - self.plugin.get_subnets.return_value = subnets_retval - if port_retval: - self.plugin.get_ports.return_value = [port_retval] - else: - self.plugin.get_ports.return_value = [] - if isinstance(update_port, n_exc.NotFound): - self.plugin.update_port.side_effect = update_port - else: - self.plugin.update_port.return_value = update_port - self.plugin.create_port.return_value = create_port - - retval = self.callbacks.get_dhcp_port(mock.Mock(), - network_id='netid', - device_id='devid', - host='host') - - expected = [mock.call.get_subnets(mock.ANY, - filters=dict(network_id=['netid'])), - mock.call.get_ports(mock.ANY, - filters=dict(network_id=['netid'], - device_id=['devid']))] - - expected.extend(other_expectations) - self.plugin.assert_has_calls(expected) - return retval - - def test_update_dhcp_port(self): - self.callbacks.update_dhcp_port(mock.Mock(), - host='foo_host', - port_id='foo_port_id', - port=mock.Mock()) - self.plugin.assert_has_calls( - mock.call.update_port(mock.ANY, 'foo_port_id', mock.ANY)) - - def test_get_dhcp_port_existing(self): - port_retval = dict(id='port_id', fixed_ips=[dict(subnet_id='a')]) - expectations = [ - mock.call.update_port(mock.ANY, 'port_id', dict(port=port_retval))] - - self._test_get_dhcp_port_helper(port_retval, expectations, - update_port=port_retval) - self.assertEqual(len(self.log.mock_calls), 1) - - def _test_get_dhcp_port_create_new(self, update_port=None): - self.plugin.get_network.return_value = dict(tenant_id='tenantid') - create_spec = dict(tenant_id='tenantid', device_id='devid', - network_id='netid', name='', - admin_state_up=True, - device_owner=constants.DEVICE_OWNER_DHCP, - mac_address=mock.ANY) - create_retval = create_spec.copy() - create_retval['id'] = 'port_id' - create_retval['fixed_ips'] = [dict(subnet_id='a', enable_dhcp=True)] - - create_spec['fixed_ips'] = [dict(subnet_id='a')] - - expectations = [ - mock.call.get_network(mock.ANY, 'netid'), - mock.call.create_port(mock.ANY, dict(port=create_spec))] - - retval = self._test_get_dhcp_port_helper(None, expectations, - update_port=update_port, - create_port=create_retval) - self.assertEqual(create_retval, retval) - self.assertEqual(len(self.log.mock_calls), 2) - - def test_get_dhcp_port_create_new(self): - self._test_get_dhcp_port_create_new() - - def test_get_dhcp_port_create_new_with_failure_on_port_update(self): - self._test_get_dhcp_port_create_new( - update_port=n_exc.PortNotFound(port_id='foo')) - - def test_release_dhcp_port(self): - port_retval = dict(id='port_id', fixed_ips=[dict(subnet_id='a')]) - self.plugin.get_ports.return_value = [port_retval] - - self.callbacks.release_dhcp_port(mock.ANY, network_id='netid', - device_id='devid') - - self.plugin.assert_has_calls([ - mock.call.delete_ports_by_device_id(mock.ANY, 'devid', 'netid')]) - - def test_release_port_fixed_ip(self): - port_retval = dict(id='port_id', fixed_ips=[dict(subnet_id='a')]) - port_update = dict(id='port_id', fixed_ips=[]) - self.plugin.get_ports.return_value = [port_retval] - - self.callbacks.release_port_fixed_ip(mock.ANY, network_id='netid', - device_id='devid', subnet_id='a') - - self.plugin.assert_has_calls([ - mock.call.get_ports(mock.ANY, filters=dict(network_id=['netid'], - device_id=['devid'])), - mock.call.update_port(mock.ANY, 'port_id', - dict(port=port_update))]) diff --git a/neutron/tests/unit/test_debug_commands.py b/neutron/tests/unit/test_debug_commands.py deleted file mode 100644 index 16b6c8dda..000000000 --- a/neutron/tests/unit/test_debug_commands.py +++ /dev/null @@ -1,363 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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 socket - -import mock -from oslo.config import cfg - -from neutron.agent.common import config -from neutron.agent.linux import interface -from neutron.common import config as common_config -from neutron.debug import commands -from neutron.debug import debug_agent -from neutron.tests import base - - -class MyApp(object): - def __init__(self, _stdout): - self.stdout = _stdout - - -class TestDebugCommands(base.BaseTestCase): - def setUp(self): - super(TestDebugCommands, self).setUp() - cfg.CONF.register_opts(interface.OPTS) - cfg.CONF.register_opts(debug_agent.NeutronDebugAgent.OPTS) - common_config.init([]) - config.register_interface_driver_opts_helper(cfg.CONF) - config.register_use_namespaces_opts_helper(cfg.CONF) - config.register_root_helper(cfg.CONF) - cfg.CONF.set_override('use_namespaces', True) - - device_exists_p = mock.patch( - 'neutron.agent.linux.ip_lib.device_exists', return_value=False) - device_exists_p.start() - namespace_p = mock.patch( - 'neutron.agent.linux.ip_lib.IpNetnsCommand') - namespace_p.start() - ensure_namespace_p = mock.patch( - 'neutron.agent.linux.ip_lib.IPWrapper.ensure_namespace') - ensure_namespace_p.start() - dvr_cls_p = mock.patch('neutron.agent.linux.interface.NullDriver') - driver_cls = dvr_cls_p.start() - mock_driver = mock.MagicMock() - mock_driver.DEV_NAME_LEN = ( - interface.LinuxInterfaceDriver.DEV_NAME_LEN) - mock_driver.get_device_name.return_value = 'tap12345678-12' - driver_cls.return_value = mock_driver - self.driver = mock_driver - - client_cls_p = mock.patch('neutronclient.v2_0.client.Client') - client_cls = client_cls_p.start() - client_inst = mock.Mock() - client_cls.return_value = client_inst - - fake_network = {'network': {'id': 'fake_net', - 'tenant_id': 'fake_tenant', - 'subnets': ['fake_subnet']}} - fake_port = {'port': - {'id': 'fake_port', - 'device_owner': 'fake_device', - 'mac_address': 'aa:bb:cc:dd:ee:ffa', - 'network_id': 'fake_net', - 'fixed_ips': - [{'subnet_id': 'fake_subnet', 'ip_address': '10.0.0.3'}] - }} - fake_ports = {'ports': [fake_port['port']]} - self.fake_ports = fake_ports - allocation_pools = [{'start': '10.0.0.2', - 'end': '10.0.0.254'}] - fake_subnet_v4 = {'subnet': {'name': 'fake_subnet_v4', - 'id': 'fake_subnet', - 'network_id': 'fake_net', - 'gateway_ip': '10.0.0.1', - 'dns_nameservers': ['10.0.0.2'], - 'host_routes': [], - 'cidr': '10.0.0.0/24', - 'allocation_pools': allocation_pools, - 'enable_dhcp': True, - 'ip_version': 4}} - - client_inst.list_ports.return_value = fake_ports - client_inst.create_port.return_value = fake_port - client_inst.show_port.return_value = fake_port - client_inst.show_network.return_value = fake_network - client_inst.show_subnet.return_value = fake_subnet_v4 - self.client = client_inst - mock_std = mock.Mock() - self.app = MyApp(mock_std) - self.app.debug_agent = debug_agent.NeutronDebugAgent(cfg.CONF, - client_inst, - mock_driver) - - def _test_create_probe(self, device_owner): - cmd = commands.CreateProbe(self.app, None) - cmd_parser = cmd.get_parser('create_probe') - if device_owner == debug_agent.DEVICE_OWNER_COMPUTE_PROBE: - args = ['fake_net', '--device-owner', 'compute'] - else: - args = ['fake_net'] - parsed_args = cmd_parser.parse_args(args) - cmd.run(parsed_args) - fake_port = {'port': - {'device_owner': device_owner, - 'admin_state_up': True, - 'network_id': 'fake_net', - 'tenant_id': 'fake_tenant', - 'binding:host_id': cfg.CONF.host, - 'fixed_ips': [{'subnet_id': 'fake_subnet'}], - 'device_id': socket.gethostname()}} - namespace = 'qprobe-fake_port' - self.client.assert_has_calls([mock.call.show_network('fake_net'), - mock.call.show_subnet('fake_subnet'), - mock.call.create_port(fake_port), - mock.call.show_subnet('fake_subnet')]) - self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY), - mock.call.plug('fake_net', - 'fake_port', - 'tap12345678-12', - 'aa:bb:cc:dd:ee:ffa', - bridge=None, - namespace=namespace), - mock.call.init_l3('tap12345678-12', - ['10.0.0.3/24'], - namespace=namespace - )]) - - def test_create_network_probe(self): - self._test_create_probe(debug_agent.DEVICE_OWNER_NETWORK_PROBE) - - def test_create_nova_probe(self): - self._test_create_probe(debug_agent.DEVICE_OWNER_COMPUTE_PROBE) - - def _test_create_probe_external(self, device_owner): - fake_network = {'network': {'id': 'fake_net', - 'tenant_id': 'fake_tenant', - 'router:external': True, - 'subnets': ['fake_subnet']}} - self.client.show_network.return_value = fake_network - cmd = commands.CreateProbe(self.app, None) - cmd_parser = cmd.get_parser('create_probe') - if device_owner == debug_agent.DEVICE_OWNER_COMPUTE_PROBE: - args = ['fake_net', '--device-owner', 'compute'] - else: - args = ['fake_net'] - parsed_args = cmd_parser.parse_args(args) - cmd.run(parsed_args) - fake_port = {'port': - {'device_owner': device_owner, - 'admin_state_up': True, - 'network_id': 'fake_net', - 'tenant_id': 'fake_tenant', - 'binding:host_id': cfg.CONF.host, - 'fixed_ips': [{'subnet_id': 'fake_subnet'}], - 'device_id': socket.gethostname()}} - namespace = 'qprobe-fake_port' - self.client.assert_has_calls([mock.call.show_network('fake_net'), - mock.call.show_subnet('fake_subnet'), - mock.call.create_port(fake_port), - mock.call.show_subnet('fake_subnet')]) - self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY), - mock.call.plug('fake_net', - 'fake_port', - 'tap12345678-12', - 'aa:bb:cc:dd:ee:ffa', - bridge='br-ex', - namespace=namespace), - mock.call.init_l3('tap12345678-12', - ['10.0.0.3/24'], - namespace=namespace - )]) - - def test_create_network_probe_external(self): - self._test_create_probe_external( - debug_agent.DEVICE_OWNER_NETWORK_PROBE) - - def test_create_nova_probe_external(self): - self._test_create_probe_external( - debug_agent.DEVICE_OWNER_COMPUTE_PROBE) - - def test_delete_probe(self): - cmd = commands.DeleteProbe(self.app, None) - cmd_parser = cmd.get_parser('delete_probe') - args = ['fake_port'] - parsed_args = cmd_parser.parse_args(args) - cmd.run(parsed_args) - namespace = 'qprobe-fake_port' - self.client.assert_has_calls([mock.call.show_port('fake_port'), - mock.call.show_network('fake_net'), - mock.call.show_subnet('fake_subnet'), - mock.call.delete_port('fake_port')]) - self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY), - mock.call.unplug('tap12345678-12', - namespace=namespace, - bridge=None)]) - - def test_delete_probe_external(self): - fake_network = {'network': {'id': 'fake_net', - 'tenant_id': 'fake_tenant', - 'router:external': True, - 'subnets': ['fake_subnet']}} - self.client.show_network.return_value = fake_network - cmd = commands.DeleteProbe(self.app, None) - cmd_parser = cmd.get_parser('delete_probe') - args = ['fake_port'] - parsed_args = cmd_parser.parse_args(args) - cmd.run(parsed_args) - namespace = 'qprobe-fake_port' - self.client.assert_has_calls([mock.call.show_port('fake_port'), - mock.call.show_network('fake_net'), - mock.call.show_subnet('fake_subnet'), - mock.call.delete_port('fake_port')]) - self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY), - mock.call.unplug('tap12345678-12', - namespace=namespace, - bridge='br-ex')]) - - def test_delete_probe_without_namespace(self): - cfg.CONF.set_override('use_namespaces', False) - cmd = commands.DeleteProbe(self.app, None) - cmd_parser = cmd.get_parser('delete_probe') - args = ['fake_port'] - parsed_args = cmd_parser.parse_args(args) - cmd.run(parsed_args) - self.client.assert_has_calls([mock.call.show_port('fake_port'), - mock.call.show_network('fake_net'), - mock.call.show_subnet('fake_subnet'), - mock.call.delete_port('fake_port')]) - self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY), - mock.call.unplug('tap12345678-12', - bridge=None)]) - - def test_list_probe(self): - cmd = commands.ListProbe(self.app, None) - cmd_parser = cmd.get_parser('list_probe') - args = [] - parsed_args = cmd_parser.parse_args(args) - cmd.run(parsed_args) - self.client.assert_has_calls( - [mock.call.list_ports( - device_owner=[debug_agent.DEVICE_OWNER_NETWORK_PROBE, - debug_agent.DEVICE_OWNER_COMPUTE_PROBE])]) - - def test_exec_command(self): - cmd = commands.ExecProbe(self.app, None) - cmd_parser = cmd.get_parser('exec_command') - args = ['fake_port', 'fake_command'] - parsed_args = cmd_parser.parse_args(args) - with mock.patch('neutron.agent.linux.ip_lib.IpNetnsCommand') as ns: - cmd.run(parsed_args) - ns.assert_has_calls([mock.call.execute(mock.ANY)]) - self.client.assert_has_calls([mock.call.show_port('fake_port')]) - - def test_exec_command_without_namespace(self): - cfg.CONF.set_override('use_namespaces', False) - cmd = commands.ExecProbe(self.app, None) - cmd_parser = cmd.get_parser('exec_command') - args = ['fake_port', 'fake_command'] - parsed_args = cmd_parser.parse_args(args) - with mock.patch('neutron.agent.linux.utils.execute') as exe: - cmd.run(parsed_args) - exe.assert_has_calls([mock.call.execute(mock.ANY)]) - self.client.assert_has_calls([mock.call.show_port('fake_port')]) - - def test_clear_probe(self): - cmd = commands.ClearProbe(self.app, None) - cmd_parser = cmd.get_parser('clear_probe') - args = [] - parsed_args = cmd_parser.parse_args(args) - cmd.run(parsed_args) - namespace = 'qprobe-fake_port' - self.client.assert_has_calls( - [mock.call.list_ports( - device_id=socket.gethostname(), - device_owner=[debug_agent.DEVICE_OWNER_NETWORK_PROBE, - debug_agent.DEVICE_OWNER_COMPUTE_PROBE]), - mock.call.show_port('fake_port'), - mock.call.show_network('fake_net'), - mock.call.show_subnet('fake_subnet'), - mock.call.delete_port('fake_port')]) - self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY), - mock.call.unplug('tap12345678-12', - namespace=namespace, - bridge=None)]) - - def test_ping_all_with_ensure_port(self): - fake_ports = self.fake_ports - - def fake_port_list(network_id=None, device_owner=None, device_id=None): - if network_id: - # In order to test ensure_port, return [] - return {'ports': []} - return fake_ports - self.client.list_ports.side_effect = fake_port_list - cmd = commands.PingAll(self.app, None) - cmd_parser = cmd.get_parser('ping_all') - args = [] - parsed_args = cmd_parser.parse_args(args) - namespace = 'qprobe-fake_port' - with mock.patch('neutron.agent.linux.ip_lib.IpNetnsCommand') as ns: - cmd.run(parsed_args) - ns.assert_has_calls([mock.call.execute(mock.ANY)]) - fake_port = {'port': - {'device_owner': debug_agent.DEVICE_OWNER_NETWORK_PROBE, - 'admin_state_up': True, - 'network_id': 'fake_net', - 'tenant_id': 'fake_tenant', - 'binding:host_id': cfg.CONF.host, - 'fixed_ips': [{'subnet_id': 'fake_subnet'}], - 'device_id': socket.gethostname()}} - expected = [mock.call.show_network('fake_net'), - mock.call.show_subnet('fake_subnet'), - mock.call.create_port(fake_port), - mock.call.show_subnet('fake_subnet')] - self.client.assert_has_calls(expected) - self.driver.assert_has_calls([mock.call.init_l3('tap12345678-12', - ['10.0.0.3/24'], - namespace=namespace - )]) - - def test_ping_all(self): - cmd = commands.PingAll(self.app, None) - cmd_parser = cmd.get_parser('ping_all') - args = [] - parsed_args = cmd_parser.parse_args(args) - with mock.patch('neutron.agent.linux.ip_lib.IpNetnsCommand') as ns: - cmd.run(parsed_args) - ns.assert_has_calls([mock.call.execute(mock.ANY)]) - expected = [mock.call.list_ports(), - mock.call.list_ports( - network_id='fake_net', - device_owner=debug_agent.DEVICE_OWNER_NETWORK_PROBE, - device_id=socket.gethostname()), - mock.call.show_subnet('fake_subnet'), - mock.call.show_port('fake_port')] - self.client.assert_has_calls(expected) - - def test_ping_all_v6(self): - fake_subnet_v6 = {'subnet': {'name': 'fake_v6', - 'ip_version': 6}} - self.client.show_subnet.return_value = fake_subnet_v6 - cmd = commands.PingAll(self.app, None) - cmd_parser = cmd.get_parser('ping_all') - args = [] - parsed_args = cmd_parser.parse_args(args) - with mock.patch('neutron.agent.linux.ip_lib.IpNetnsCommand') as ns: - cmd.run(parsed_args) - ns.assert_has_calls([mock.call.execute(mock.ANY)]) - self.client.assert_has_calls([mock.call.list_ports()]) diff --git a/neutron/tests/unit/test_dhcp_agent.py b/neutron/tests/unit/test_dhcp_agent.py deleted file mode 100644 index 0b0826bb9..000000000 --- a/neutron/tests/unit/test_dhcp_agent.py +++ /dev/null @@ -1,1466 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# 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 copy -import sys -import uuid - -import eventlet -import mock -from oslo.config import cfg -import testtools - -from neutron.agent.common import config -from neutron.agent import dhcp_agent -from neutron.agent.linux import dhcp -from neutron.agent.linux import interface -from neutron.common import config as common_config -from neutron.common import constants as const -from neutron.common import exceptions -from neutron.common import rpc_compat -from neutron.tests import base - - -HOSTNAME = 'hostname' -dev_man = dhcp.DeviceManager -rpc_api = dhcp_agent.DhcpPluginApi -DEVICE_MANAGER = '%s.%s' % (dev_man.__module__, dev_man.__name__) -DHCP_PLUGIN = '%s.%s' % (rpc_api.__module__, rpc_api.__name__) - - -fake_tenant_id = 'aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa' -fake_subnet1_allocation_pools = dhcp.DictModel(dict(id='', start='172.9.9.2', - end='172.9.9.254')) -fake_subnet1 = dhcp.DictModel(dict(id='bbbbbbbb-bbbb-bbbb-bbbbbbbbbbbb', - network_id='12345678-1234-5678-1234567890ab', - cidr='172.9.9.0/24', enable_dhcp=True, name='', - tenant_id=fake_tenant_id, - gateway_ip='172.9.9.1', host_routes=[], - dns_nameservers=[], ip_version=4, - allocation_pools=fake_subnet1_allocation_pools)) - -fake_subnet2_allocation_pools = dhcp.DictModel(dict(id='', start='172.9.8.2', - end='172.9.8.254')) -fake_subnet2 = dhcp.DictModel(dict(id='dddddddd-dddd-dddd-dddddddddddd', - network_id='12345678-1234-5678-1234567890ab', - cidr='172.9.8.0/24', enable_dhcp=False, name='', - tenant_id=fake_tenant_id, gateway_ip='172.9.8.1', - host_routes=[], dns_nameservers=[], ip_version=4, - allocation_pools=fake_subnet2_allocation_pools)) - -fake_subnet3 = dhcp.DictModel(dict(id='bbbbbbbb-1111-2222-bbbbbbbbbbbb', - network_id='12345678-1234-5678-1234567890ab', - cidr='192.168.1.1/24', enable_dhcp=True)) - -fake_meta_subnet = dhcp.DictModel(dict(id='bbbbbbbb-1111-2222-bbbbbbbbbbbb', - network_id='12345678-1234-5678-1234567890ab', - cidr='169.254.169.252/30', - gateway_ip='169.254.169.253', - enable_dhcp=True)) - -fake_fixed_ip1 = dhcp.DictModel(dict(id='', subnet_id=fake_subnet1.id, - ip_address='172.9.9.9')) -fake_meta_fixed_ip = dhcp.DictModel(dict(id='', subnet=fake_meta_subnet, - ip_address='169.254.169.254')) -fake_allocation_pool_subnet1 = dhcp.DictModel(dict(id='', start='172.9.9.2', - end='172.9.9.254')) - -fake_port1 = dhcp.DictModel(dict(id='12345678-1234-aaaa-1234567890ab', - device_id='dhcp-12345678-1234-aaaa-1234567890ab', - allocation_pools=fake_subnet1_allocation_pools, - mac_address='aa:bb:cc:dd:ee:ff', - network_id='12345678-1234-5678-1234567890ab', - fixed_ips=[fake_fixed_ip1])) - -fake_port2 = dhcp.DictModel(dict(id='12345678-1234-aaaa-123456789000', - mac_address='aa:bb:cc:dd:ee:99', - network_id='12345678-1234-5678-1234567890ab', - fixed_ips=[])) - -fake_meta_port = dhcp.DictModel(dict(id='12345678-1234-aaaa-1234567890ab', - mac_address='aa:bb:cc:dd:ee:ff', - network_id='12345678-1234-5678-1234567890ab', - device_owner=const.DEVICE_OWNER_ROUTER_INTF, - device_id='forzanapoli', - fixed_ips=[fake_meta_fixed_ip])) - -fake_network = dhcp.NetModel(True, dict(id='12345678-1234-5678-1234567890ab', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa', - admin_state_up=True, - subnets=[fake_subnet1, fake_subnet2], - ports=[fake_port1])) - -fake_meta_network = dhcp.NetModel( - True, dict(id='12345678-1234-5678-1234567890ab', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa', - admin_state_up=True, - subnets=[fake_meta_subnet], - ports=[fake_meta_port])) - -fake_down_network = dhcp.NetModel( - True, dict(id='12345678-dddd-dddd-1234567890ab', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa', - admin_state_up=False, - subnets=[], - ports=[])) - - -class TestDhcpAgent(base.BaseTestCase): - def setUp(self): - super(TestDhcpAgent, self).setUp() - dhcp_agent.register_options() - cfg.CONF.set_override('interface_driver', - 'neutron.agent.linux.interface.NullDriver') - # disable setting up periodic state reporting - cfg.CONF.set_override('report_interval', 0, 'AGENT') - - self.driver_cls_p = mock.patch( - 'neutron.agent.dhcp_agent.importutils.import_class') - self.driver = mock.Mock(name='driver') - self.driver.existing_dhcp_networks.return_value = [] - self.driver_cls = self.driver_cls_p.start() - self.driver_cls.return_value = self.driver - self.mock_makedirs_p = mock.patch("os.makedirs") - self.mock_makedirs = self.mock_makedirs_p.start() - - def test_dhcp_agent_manager(self): - state_rpc_str = 'neutron.agent.rpc.PluginReportStateAPI' - # sync_state is needed for this test - cfg.CONF.set_override('report_interval', 1, 'AGENT') - with mock.patch.object(dhcp_agent.DhcpAgentWithStateReport, - 'sync_state', - autospec=True) as mock_sync_state: - with mock.patch.object(dhcp_agent.DhcpAgentWithStateReport, - 'periodic_resync', - autospec=True) as mock_periodic_resync: - with mock.patch(state_rpc_str) as state_rpc: - with mock.patch.object(sys, 'argv') as sys_argv: - sys_argv.return_value = [ - 'dhcp', '--config-file', - base.etcdir('neutron.conf.test')] - cfg.CONF.register_opts(dhcp_agent.DhcpAgent.OPTS) - config.register_interface_driver_opts_helper(cfg.CONF) - config.register_agent_state_opts_helper(cfg.CONF) - config.register_root_helper(cfg.CONF) - cfg.CONF.register_opts(dhcp.OPTS) - cfg.CONF.register_opts(interface.OPTS) - common_config.init(sys.argv[1:]) - agent_mgr = dhcp_agent.DhcpAgentWithStateReport( - 'testhost') - eventlet.greenthread.sleep(1) - agent_mgr.after_start() - mock_sync_state.assert_called_once_with(agent_mgr) - mock_periodic_resync.assert_called_once_with(agent_mgr) - state_rpc.assert_has_calls( - [mock.call(mock.ANY), - mock.call().report_state(mock.ANY, mock.ANY, - mock.ANY)]) - - def test_dhcp_agent_main_agent_manager(self): - logging_str = 'neutron.agent.common.config.setup_logging' - launcher_str = 'neutron.openstack.common.service.ServiceLauncher' - with mock.patch(logging_str): - with mock.patch.object(sys, 'argv') as sys_argv: - with mock.patch(launcher_str) as launcher: - sys_argv.return_value = ['dhcp', '--config-file', - base.etcdir('neutron.conf.test')] - dhcp_agent.main() - launcher.assert_has_calls( - [mock.call(), mock.call().launch_service(mock.ANY), - mock.call().wait()]) - - def test_run_completes_single_pass(self): - with mock.patch(DEVICE_MANAGER): - dhcp = dhcp_agent.DhcpAgent(HOSTNAME) - attrs_to_mock = dict( - [(a, mock.DEFAULT) for a in - ['sync_state', 'periodic_resync']]) - with mock.patch.multiple(dhcp, **attrs_to_mock) as mocks: - dhcp.run() - mocks['sync_state'].assert_called_once_with() - mocks['periodic_resync'].assert_called_once_with() - - def test_call_driver(self): - network = mock.Mock() - network.id = '1' - dhcp = dhcp_agent.DhcpAgent(cfg.CONF) - self.assertTrue(dhcp.call_driver('foo', network)) - self.driver.assert_called_once_with(cfg.CONF, - mock.ANY, - 'sudo', - mock.ANY, - mock.ANY) - - def _test_call_driver_failure(self, exc=None, - trace_level='exception', expected_sync=True): - network = mock.Mock() - network.id = '1' - self.driver.return_value.foo.side_effect = exc or Exception - with mock.patch.object(dhcp_agent.LOG, trace_level) as log: - dhcp = dhcp_agent.DhcpAgent(HOSTNAME) - with mock.patch.object(dhcp, - 'schedule_resync') as schedule_resync: - self.assertIsNone(dhcp.call_driver('foo', network)) - self.driver.assert_called_once_with(cfg.CONF, - mock.ANY, - 'sudo', - mock.ANY, - mock.ANY) - self.assertEqual(log.call_count, 1) - self.assertEqual(expected_sync, schedule_resync.called) - - def test_call_driver_failure(self): - self._test_call_driver_failure() - - def test_call_driver_remote_error_net_not_found(self): - self._test_call_driver_failure( - exc=rpc_compat.RemoteError(exc_type='NetworkNotFound'), - trace_level='warning') - - def test_call_driver_network_not_found(self): - self._test_call_driver_failure( - exc=exceptions.NetworkNotFound(net_id='1'), - trace_level='warning') - - def test_call_driver_conflict(self): - self._test_call_driver_failure( - exc=exceptions.Conflict(), - trace_level='warning', - expected_sync=False) - - def _test_sync_state_helper(self, known_networks, active_networks): - with mock.patch(DHCP_PLUGIN) as plug: - mock_plugin = mock.Mock() - mock_plugin.get_active_networks_info.return_value = active_networks - plug.return_value = mock_plugin - - dhcp = dhcp_agent.DhcpAgent(HOSTNAME) - - attrs_to_mock = dict( - [(a, mock.DEFAULT) for a in - ['refresh_dhcp_helper', 'disable_dhcp_helper', 'cache']]) - - with mock.patch.multiple(dhcp, **attrs_to_mock) as mocks: - mocks['cache'].get_network_ids.return_value = known_networks - dhcp.sync_state() - - exp_refresh = [ - mock.call(net_id) for net_id in active_networks] - - diff = set(known_networks) - set(active_networks) - exp_disable = [mock.call(net_id) for net_id in diff] - - mocks['cache'].assert_has_calls([mock.call.get_network_ids()]) - mocks['refresh_dhcp_helper'].assert_has_called(exp_refresh) - mocks['disable_dhcp_helper'].assert_has_called(exp_disable) - - def test_sync_state_initial(self): - self._test_sync_state_helper([], ['a']) - - def test_sync_state_same(self): - self._test_sync_state_helper(['a'], ['a']) - - def test_sync_state_disabled_net(self): - self._test_sync_state_helper(['b'], ['a']) - - def test_sync_state_waitall(self): - class mockNetwork(): - id = '0' - admin_state_up = True - subnets = [] - - def __init__(self, id): - self.id = id - with mock.patch.object(dhcp_agent.eventlet.GreenPool, 'waitall') as w: - active_networks = [mockNetwork('1'), mockNetwork('2'), - mockNetwork('3'), mockNetwork('4'), - mockNetwork('5')] - known_networks = ['1', '2', '3', '4', '5'] - self._test_sync_state_helper(known_networks, active_networks) - w.assert_called_once_with() - - def test_sync_state_plugin_error(self): - with mock.patch(DHCP_PLUGIN) as plug: - mock_plugin = mock.Mock() - mock_plugin.get_active_networks_info.side_effect = Exception - plug.return_value = mock_plugin - - with mock.patch.object(dhcp_agent.LOG, 'exception') as log: - dhcp = dhcp_agent.DhcpAgent(HOSTNAME) - with mock.patch.object(dhcp, - 'schedule_resync') as schedule_resync: - dhcp.sync_state() - - self.assertTrue(log.called) - self.assertTrue(schedule_resync.called) - - def test_periodic_resync(self): - dhcp = dhcp_agent.DhcpAgent(HOSTNAME) - with mock.patch.object(dhcp_agent.eventlet, 'spawn') as spawn: - dhcp.periodic_resync() - spawn.assert_called_once_with(dhcp._periodic_resync_helper) - - def test_periodoc_resync_helper(self): - with mock.patch.object(dhcp_agent.eventlet, 'sleep') as sleep: - dhcp = dhcp_agent.DhcpAgent(HOSTNAME) - dhcp.needs_resync_reasons = ['reason1', 'reason2'] - with mock.patch.object(dhcp, 'sync_state') as sync_state: - sync_state.side_effect = RuntimeError - with testtools.ExpectedException(RuntimeError): - dhcp._periodic_resync_helper() - sync_state.assert_called_once_with() - sleep.assert_called_once_with(dhcp.conf.resync_interval) - self.assertEqual(len(dhcp.needs_resync_reasons), 0) - - def test_populate_cache_on_start_without_active_networks_support(self): - # emul dhcp driver that doesn't support retrieving of active networks - self.driver.existing_dhcp_networks.side_effect = NotImplementedError - - with mock.patch.object(dhcp_agent.LOG, 'debug') as log: - dhcp = dhcp_agent.DhcpAgent(HOSTNAME) - - self.driver.existing_dhcp_networks.assert_called_once_with( - dhcp.conf, - cfg.CONF.root_helper - ) - - self.assertFalse(dhcp.cache.get_network_ids()) - self.assertTrue(log.called) - - def test_populate_cache_on_start(self): - networks = ['aaa', 'bbb'] - self.driver.existing_dhcp_networks.return_value = networks - - dhcp = dhcp_agent.DhcpAgent(HOSTNAME) - - self.driver.existing_dhcp_networks.assert_called_once_with( - dhcp.conf, - cfg.CONF.root_helper - ) - - self.assertEqual(set(networks), set(dhcp.cache.get_network_ids())) - - def test_none_interface_driver(self): - cfg.CONF.set_override('interface_driver', None) - with mock.patch.object(dhcp, 'LOG') as log: - self.assertRaises(SystemExit, dhcp.DeviceManager, - cfg.CONF, 'sudo', None) - msg = 'An interface driver must be specified' - log.error.assert_called_once_with(msg) - - def test_nonexistent_interface_driver(self): - # Temporarily turn off mock, so could use the real import_class - # to import interface_driver. - self.driver_cls_p.stop() - self.addCleanup(self.driver_cls_p.start) - cfg.CONF.set_override('interface_driver', 'foo') - with mock.patch.object(dhcp, 'LOG') as log: - self.assertRaises(SystemExit, dhcp.DeviceManager, - cfg.CONF, 'sudo', None) - self.assertEqual(log.error.call_count, 1) - - -class TestLogArgs(base.BaseTestCase): - - def test_log_args_without_log_dir_and_file(self): - conf_dict = {'debug': True, - 'verbose': False, - 'log_dir': None, - 'log_file': None, - 'use_syslog': True, - 'syslog_log_facility': 'LOG_USER'} - conf = dhcp.DictModel(conf_dict) - expected_args = ['--debug', - '--use-syslog', - '--syslog-log-facility=LOG_USER'] - args = config.get_log_args(conf, 'log_file_name') - self.assertEqual(expected_args, args) - - def test_log_args_without_log_file(self): - conf_dict = {'debug': True, - 'verbose': True, - 'log_dir': '/etc/tests', - 'log_file': None, - 'use_syslog': False, - 'syslog_log_facility': 'LOG_USER'} - conf = dhcp.DictModel(conf_dict) - expected_args = ['--debug', - '--verbose', - '--log-file=log_file_name', - '--log-dir=/etc/tests'] - args = config.get_log_args(conf, 'log_file_name') - self.assertEqual(expected_args, args) - - def test_log_args_with_log_dir_and_file(self): - conf_dict = {'debug': True, - 'verbose': False, - 'log_dir': '/etc/tests', - 'log_file': 'tests/filelog', - 'use_syslog': False, - 'syslog_log_facility': 'LOG_USER'} - conf = dhcp.DictModel(conf_dict) - expected_args = ['--debug', - '--log-file=log_file_name', - '--log-dir=/etc/tests/tests'] - args = config.get_log_args(conf, 'log_file_name') - self.assertEqual(expected_args, args) - - def test_log_args_without_log_dir(self): - conf_dict = {'debug': True, - 'verbose': False, - 'log_file': 'tests/filelog', - 'log_dir': None, - 'use_syslog': False, - 'syslog_log_facility': 'LOG_USER'} - conf = dhcp.DictModel(conf_dict) - expected_args = ['--debug', - '--log-file=log_file_name', - '--log-dir=tests'] - args = config.get_log_args(conf, 'log_file_name') - self.assertEqual(expected_args, args) - - def test_log_args_with_filelog_and_syslog(self): - conf_dict = {'debug': True, - 'verbose': True, - 'log_file': 'tests/filelog', - 'log_dir': '/etc/tests', - 'use_syslog': True, - 'syslog_log_facility': 'LOG_USER'} - conf = dhcp.DictModel(conf_dict) - expected_args = ['--debug', - '--verbose', - '--log-file=log_file_name', - '--log-dir=/etc/tests/tests'] - args = config.get_log_args(conf, 'log_file_name') - self.assertEqual(expected_args, args) - - -class TestDhcpAgentEventHandler(base.BaseTestCase): - def setUp(self): - super(TestDhcpAgentEventHandler, self).setUp() - config.register_interface_driver_opts_helper(cfg.CONF) - cfg.CONF.register_opts(dhcp.OPTS) - cfg.CONF.set_override('interface_driver', - 'neutron.agent.linux.interface.NullDriver') - config.register_root_helper(cfg.CONF) - cfg.CONF.register_opts(dhcp_agent.DhcpAgent.OPTS) - - self.plugin_p = mock.patch(DHCP_PLUGIN) - plugin_cls = self.plugin_p.start() - self.plugin = mock.Mock() - plugin_cls.return_value = self.plugin - - self.cache_p = mock.patch('neutron.agent.dhcp_agent.NetworkCache') - cache_cls = self.cache_p.start() - self.cache = mock.Mock() - cache_cls.return_value = self.cache - self.mock_makedirs_p = mock.patch("os.makedirs") - self.mock_makedirs = self.mock_makedirs_p.start() - self.mock_init_p = mock.patch('neutron.agent.dhcp_agent.' - 'DhcpAgent._populate_networks_cache') - self.mock_init = self.mock_init_p.start() - with mock.patch.object(dhcp.Dnsmasq, - 'check_version') as check_v: - check_v.return_value = dhcp.Dnsmasq.MINIMUM_VERSION - self.dhcp = dhcp_agent.DhcpAgent(HOSTNAME) - self.call_driver_p = mock.patch.object(self.dhcp, 'call_driver') - self.call_driver = self.call_driver_p.start() - self.schedule_resync_p = mock.patch.object(self.dhcp, - 'schedule_resync') - self.schedule_resync = self.schedule_resync_p.start() - self.external_process_p = mock.patch( - 'neutron.agent.linux.external_process.ProcessManager' - ) - self.external_process = self.external_process_p.start() - - def _enable_dhcp_helper(self, isolated_metadata=False): - if isolated_metadata: - cfg.CONF.set_override('enable_isolated_metadata', True) - self.plugin.get_network_info.return_value = fake_network - self.dhcp.enable_dhcp_helper(fake_network.id) - self.plugin.assert_has_calls( - [mock.call.get_network_info(fake_network.id)]) - self.call_driver.assert_called_once_with('enable', fake_network) - self.cache.assert_has_calls([mock.call.put(fake_network)]) - if isolated_metadata: - self.external_process.assert_has_calls([ - mock.call( - cfg.CONF, - '12345678-1234-5678-1234567890ab', - 'sudo', - 'qdhcp-12345678-1234-5678-1234567890ab'), - mock.call().enable(mock.ANY) - ]) - else: - self.assertFalse(self.external_process.call_count) - - def test_enable_dhcp_helper_enable_isolated_metadata(self): - self._enable_dhcp_helper(isolated_metadata=True) - - def test_enable_dhcp_helper(self): - self._enable_dhcp_helper() - - def test_enable_dhcp_helper_down_network(self): - self.plugin.get_network_info.return_value = fake_down_network - self.dhcp.enable_dhcp_helper(fake_down_network.id) - self.plugin.assert_has_calls( - [mock.call.get_network_info(fake_down_network.id)]) - self.assertFalse(self.call_driver.called) - self.assertFalse(self.cache.called) - self.assertFalse(self.external_process.called) - - def test_enable_dhcp_helper_network_none(self): - self.plugin.get_network_info.return_value = None - with mock.patch.object(dhcp_agent.LOG, 'warn') as log: - self.dhcp.enable_dhcp_helper('fake_id') - self.plugin.assert_has_calls( - [mock.call.get_network_info('fake_id')]) - self.assertFalse(self.call_driver.called) - self.assertTrue(log.called) - self.assertFalse(self.dhcp.schedule_resync.called) - - def test_enable_dhcp_helper_exception_during_rpc(self): - self.plugin.get_network_info.side_effect = Exception - with mock.patch.object(dhcp_agent.LOG, 'exception') as log: - self.dhcp.enable_dhcp_helper(fake_network.id) - self.plugin.assert_has_calls( - [mock.call.get_network_info(fake_network.id)]) - self.assertFalse(self.call_driver.called) - self.assertTrue(log.called) - self.assertTrue(self.schedule_resync.called) - self.assertFalse(self.cache.called) - self.assertFalse(self.external_process.called) - - def test_enable_dhcp_helper_driver_failure(self): - self.plugin.get_network_info.return_value = fake_network - self.call_driver.return_value = False - self.dhcp.enable_dhcp_helper(fake_network.id) - self.plugin.assert_has_calls( - [mock.call.get_network_info(fake_network.id)]) - self.call_driver.assert_called_once_with('enable', fake_network) - self.assertFalse(self.cache.called) - self.assertFalse(self.external_process.called) - - def _disable_dhcp_helper_known_network(self, isolated_metadata=False): - if isolated_metadata: - cfg.CONF.set_override('enable_isolated_metadata', True) - self.cache.get_network_by_id.return_value = fake_network - self.dhcp.disable_dhcp_helper(fake_network.id) - self.cache.assert_has_calls( - [mock.call.get_network_by_id(fake_network.id)]) - self.call_driver.assert_called_once_with('disable', fake_network) - if isolated_metadata: - self.external_process.assert_has_calls([ - mock.call( - cfg.CONF, - '12345678-1234-5678-1234567890ab', - 'sudo', - 'qdhcp-12345678-1234-5678-1234567890ab'), - mock.call().disable() - ]) - else: - self.assertFalse(self.external_process.call_count) - - def test_disable_dhcp_helper_known_network_isolated_metadata(self): - self._disable_dhcp_helper_known_network(isolated_metadata=True) - - def test_disable_dhcp_helper_known_network(self): - self._disable_dhcp_helper_known_network() - - def test_disable_dhcp_helper_unknown_network(self): - self.cache.get_network_by_id.return_value = None - self.dhcp.disable_dhcp_helper('abcdef') - self.cache.assert_has_calls( - [mock.call.get_network_by_id('abcdef')]) - self.assertEqual(0, self.call_driver.call_count) - self.assertFalse(self.external_process.called) - - def _disable_dhcp_helper_driver_failure(self, isolated_metadata=False): - if isolated_metadata: - cfg.CONF.set_override('enable_isolated_metadata', True) - self.cache.get_network_by_id.return_value = fake_network - self.call_driver.return_value = False - self.dhcp.disable_dhcp_helper(fake_network.id) - self.cache.assert_has_calls( - [mock.call.get_network_by_id(fake_network.id)]) - self.call_driver.assert_called_once_with('disable', fake_network) - self.cache.assert_has_calls( - [mock.call.get_network_by_id(fake_network.id)]) - if isolated_metadata: - self.external_process.assert_has_calls([ - mock.call( - cfg.CONF, - '12345678-1234-5678-1234567890ab', - 'sudo', - 'qdhcp-12345678-1234-5678-1234567890ab'), - mock.call().disable() - ]) - else: - self.assertFalse(self.external_process.call_count) - - def test_disable_dhcp_helper_driver_failure_isolated_metadata(self): - self._disable_dhcp_helper_driver_failure(isolated_metadata=True) - - def test_disable_dhcp_helper_driver_failure(self): - self._disable_dhcp_helper_driver_failure() - - def test_enable_isolated_metadata_proxy(self): - class_path = 'neutron.agent.linux.external_process.ProcessManager' - with mock.patch(class_path) as ext_process: - self.dhcp.enable_isolated_metadata_proxy(fake_network) - ext_process.assert_has_calls([ - mock.call( - cfg.CONF, - '12345678-1234-5678-1234567890ab', - 'sudo', - 'qdhcp-12345678-1234-5678-1234567890ab'), - mock.call().enable(mock.ANY) - ]) - - def test_disable_isolated_metadata_proxy(self): - class_path = 'neutron.agent.linux.external_process.ProcessManager' - with mock.patch(class_path) as ext_process: - self.dhcp.disable_isolated_metadata_proxy(fake_network) - ext_process.assert_has_calls([ - mock.call( - cfg.CONF, - '12345678-1234-5678-1234567890ab', - 'sudo', - 'qdhcp-12345678-1234-5678-1234567890ab'), - mock.call().disable() - ]) - - def test_enable_isolated_metadata_proxy_with_metadata_network(self): - cfg.CONF.set_override('enable_metadata_network', True) - cfg.CONF.set_override('debug', True) - cfg.CONF.set_override('log_file', 'test.log') - class_path = 'neutron.agent.linux.ip_lib.IPWrapper' - self.external_process_p.stop() - # Ensure the mock is restored if this test fail - try: - with mock.patch(class_path) as ip_wrapper: - self.dhcp.enable_isolated_metadata_proxy(fake_meta_network) - ip_wrapper.assert_has_calls([mock.call( - 'sudo', - 'qdhcp-12345678-1234-5678-1234567890ab'), - mock.call().netns.execute([ - 'neutron-ns-metadata-proxy', - mock.ANY, - mock.ANY, - '--router_id=forzanapoli', - mock.ANY, - mock.ANY, - '--debug', - ('--log-file=neutron-ns-metadata-proxy-%s.log' % - fake_meta_network.id)]) - ]) - finally: - self.external_process_p.start() - - def test_network_create_end(self): - payload = dict(network=dict(id=fake_network.id)) - - with mock.patch.object(self.dhcp, 'enable_dhcp_helper') as enable: - self.dhcp.network_create_end(None, payload) - enable.assertCalledOnceWith(fake_network.id) - - def test_network_update_end_admin_state_up(self): - payload = dict(network=dict(id=fake_network.id, admin_state_up=True)) - with mock.patch.object(self.dhcp, 'enable_dhcp_helper') as enable: - self.dhcp.network_update_end(None, payload) - enable.assertCalledOnceWith(fake_network.id) - - def test_network_update_end_admin_state_down(self): - payload = dict(network=dict(id=fake_network.id, admin_state_up=False)) - with mock.patch.object(self.dhcp, 'disable_dhcp_helper') as disable: - self.dhcp.network_update_end(None, payload) - disable.assertCalledOnceWith(fake_network.id) - - def test_network_delete_end(self): - payload = dict(network_id=fake_network.id) - - with mock.patch.object(self.dhcp, 'disable_dhcp_helper') as disable: - self.dhcp.network_delete_end(None, payload) - disable.assertCalledOnceWith(fake_network.id) - - def test_refresh_dhcp_helper_no_dhcp_enabled_networks(self): - network = dhcp.NetModel(True, dict(id='net-id', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa', - admin_state_up=True, - subnets=[], - ports=[])) - - self.cache.get_network_by_id.return_value = network - self.plugin.get_network_info.return_value = network - with mock.patch.object(self.dhcp, 'disable_dhcp_helper') as disable: - self.dhcp.refresh_dhcp_helper(network.id) - disable.assert_called_once_with(network.id) - self.assertFalse(self.cache.called) - self.assertFalse(self.call_driver.called) - self.cache.assert_has_calls( - [mock.call.get_network_by_id('net-id')]) - - def test_refresh_dhcp_helper_exception_during_rpc(self): - network = dhcp.NetModel(True, dict(id='net-id', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa', - admin_state_up=True, - subnets=[], - ports=[])) - - self.cache.get_network_by_id.return_value = network - self.plugin.get_network_info.side_effect = Exception - with mock.patch.object(dhcp_agent.LOG, 'exception') as log: - self.dhcp.refresh_dhcp_helper(network.id) - self.assertFalse(self.call_driver.called) - self.cache.assert_has_calls( - [mock.call.get_network_by_id('net-id')]) - self.assertTrue(log.called) - self.assertTrue(self.dhcp.schedule_resync.called) - - def test_subnet_update_end(self): - payload = dict(subnet=dict(network_id=fake_network.id)) - self.cache.get_network_by_id.return_value = fake_network - self.plugin.get_network_info.return_value = fake_network - - self.dhcp.subnet_update_end(None, payload) - - self.cache.assert_has_calls([mock.call.put(fake_network)]) - self.call_driver.assert_called_once_with('reload_allocations', - fake_network) - - def test_subnet_update_end_restart(self): - new_state = dhcp.NetModel(True, dict(id=fake_network.id, - tenant_id=fake_network.tenant_id, - admin_state_up=True, - subnets=[fake_subnet1, fake_subnet3], - ports=[fake_port1])) - - payload = dict(subnet=dict(network_id=fake_network.id)) - self.cache.get_network_by_id.return_value = fake_network - self.plugin.get_network_info.return_value = new_state - - self.dhcp.subnet_update_end(None, payload) - - self.cache.assert_has_calls([mock.call.put(new_state)]) - self.call_driver.assert_called_once_with('restart', - new_state) - - def test_subnet_update_end_delete_payload(self): - prev_state = dhcp.NetModel(True, dict(id=fake_network.id, - tenant_id=fake_network.tenant_id, - admin_state_up=True, - subnets=[fake_subnet1, fake_subnet3], - ports=[fake_port1])) - - payload = dict(subnet_id=fake_subnet1.id) - self.cache.get_network_by_subnet_id.return_value = prev_state - self.cache.get_network_by_id.return_value = prev_state - self.plugin.get_network_info.return_value = fake_network - - self.dhcp.subnet_delete_end(None, payload) - - self.cache.assert_has_calls([ - mock.call.get_network_by_subnet_id( - 'bbbbbbbb-bbbb-bbbb-bbbbbbbbbbbb'), - mock.call.get_network_by_id('12345678-1234-5678-1234567890ab'), - mock.call.put(fake_network)]) - self.call_driver.assert_called_once_with('restart', - fake_network) - - def test_port_update_end(self): - payload = dict(port=fake_port2) - self.cache.get_network_by_id.return_value = fake_network - self.cache.get_port_by_id.return_value = fake_port2 - self.dhcp.port_update_end(None, payload) - self.cache.assert_has_calls( - [mock.call.get_network_by_id(fake_port2.network_id), - mock.call.put_port(mock.ANY)]) - self.call_driver.assert_called_once_with('reload_allocations', - fake_network) - - def test_port_update_change_ip_on_port(self): - payload = dict(port=fake_port1) - self.cache.get_network_by_id.return_value = fake_network - updated_fake_port1 = copy.deepcopy(fake_port1) - updated_fake_port1.fixed_ips[0].ip_address = '172.9.9.99' - self.cache.get_port_by_id.return_value = updated_fake_port1 - self.dhcp.port_update_end(None, payload) - self.cache.assert_has_calls( - [mock.call.get_network_by_id(fake_port1.network_id), - mock.call.put_port(mock.ANY)]) - self.call_driver.assert_has_calls( - [mock.call.call_driver('reload_allocations', fake_network)]) - - def test_port_delete_end(self): - payload = dict(port_id=fake_port2.id) - self.cache.get_network_by_id.return_value = fake_network - self.cache.get_port_by_id.return_value = fake_port2 - - self.dhcp.port_delete_end(None, payload) - self.cache.assert_has_calls( - [mock.call.get_port_by_id(fake_port2.id), - mock.call.get_network_by_id(fake_network.id), - mock.call.remove_port(fake_port2)]) - self.call_driver.assert_has_calls( - [mock.call.call_driver('reload_allocations', fake_network)]) - - def test_port_delete_end_unknown_port(self): - payload = dict(port_id='unknown') - self.cache.get_port_by_id.return_value = None - - self.dhcp.port_delete_end(None, payload) - - self.cache.assert_has_calls([mock.call.get_port_by_id('unknown')]) - self.assertEqual(self.call_driver.call_count, 0) - - -class TestDhcpPluginApiProxy(base.BaseTestCase): - def setUp(self): - super(TestDhcpPluginApiProxy, self).setUp() - self.proxy = dhcp_agent.DhcpPluginApi('foo', {}, None) - self.proxy.host = 'foo' - - self.call_p = mock.patch.object(self.proxy, 'call') - self.call = self.call_p.start() - self.make_msg_p = mock.patch.object(self.proxy, 'make_msg') - self.make_msg = self.make_msg_p.start() - - def test_get_network_info(self): - self.call.return_value = dict(a=1) - retval = self.proxy.get_network_info('netid') - self.assertEqual(retval.a, 1) - self.assertTrue(self.call.called) - self.make_msg.assert_called_once_with('get_network_info', - network_id='netid', - host='foo') - - def test_get_dhcp_port(self): - self.call.return_value = dict(a=1) - retval = self.proxy.get_dhcp_port('netid', 'devid') - self.assertEqual(retval.a, 1) - self.assertTrue(self.call.called) - self.make_msg.assert_called_once_with('get_dhcp_port', - network_id='netid', - device_id='devid', - host='foo') - - def test_get_dhcp_port_none(self): - self.call.return_value = None - self.assertIsNone(self.proxy.get_dhcp_port('netid', 'devid')) - - def test_get_active_networks_info(self): - self.proxy.get_active_networks_info() - self.make_msg.assert_called_once_with('get_active_networks_info', - host='foo') - - def test_create_dhcp_port(self): - port_body = ( - {'port': - {'name': '', 'admin_state_up': True, - 'network_id': fake_network.id, - 'tenant_id': fake_network.tenant_id, - 'fixed_ips': [{'subnet_id': fake_fixed_ip1.subnet_id}], - 'device_id': mock.ANY}}) - - self.proxy.create_dhcp_port(port_body) - self.make_msg.assert_called_once_with('create_dhcp_port', - port=port_body, - host='foo') - - def test_create_dhcp_port_none(self): - self.call.return_value = None - port_body = ( - {'port': - {'name': '', 'admin_state_up': True, - 'network_id': fake_network.id, - 'tenant_id': fake_network.tenant_id, - 'fixed_ips': [{'subnet_id': fake_fixed_ip1.subnet_id}], - 'device_id': mock.ANY}}) - self.assertIsNone(self.proxy.create_dhcp_port(port_body)) - - def test_update_dhcp_port_none(self): - self.call.return_value = None - port_body = {'port': {'fixed_ips': - [{'subnet_id': fake_fixed_ip1.subnet_id}]}} - self.assertIsNone(self.proxy.update_dhcp_port(fake_port1.id, - port_body)) - - def test_update_dhcp_port(self): - port_body = {'port': {'fixed_ips': - [{'subnet_id': fake_fixed_ip1.subnet_id}]}} - self.proxy.update_dhcp_port(fake_port1.id, port_body) - self.make_msg.assert_called_once_with('update_dhcp_port', - port_id=fake_port1.id, - port=port_body, - host='foo') - - def test_release_dhcp_port(self): - self.proxy.release_dhcp_port('netid', 'devid') - self.assertTrue(self.call.called) - self.make_msg.assert_called_once_with('release_dhcp_port', - network_id='netid', - device_id='devid', - host='foo') - - def test_release_port_fixed_ip(self): - self.proxy.release_port_fixed_ip('netid', 'devid', 'subid') - self.assertTrue(self.call.called) - self.make_msg.assert_called_once_with('release_port_fixed_ip', - network_id='netid', - subnet_id='subid', - device_id='devid', - host='foo') - - -class TestNetworkCache(base.BaseTestCase): - def test_put_network(self): - nc = dhcp_agent.NetworkCache() - nc.put(fake_network) - self.assertEqual(nc.cache, - {fake_network.id: fake_network}) - self.assertEqual(nc.subnet_lookup, - {fake_subnet1.id: fake_network.id, - fake_subnet2.id: fake_network.id}) - self.assertEqual(nc.port_lookup, - {fake_port1.id: fake_network.id}) - - def test_put_network_existing(self): - prev_network_info = mock.Mock() - nc = dhcp_agent.NetworkCache() - with mock.patch.object(nc, 'remove') as remove: - nc.cache[fake_network.id] = prev_network_info - - nc.put(fake_network) - remove.assert_called_once_with(prev_network_info) - self.assertEqual(nc.cache, - {fake_network.id: fake_network}) - self.assertEqual(nc.subnet_lookup, - {fake_subnet1.id: fake_network.id, - fake_subnet2.id: fake_network.id}) - self.assertEqual(nc.port_lookup, - {fake_port1.id: fake_network.id}) - - def test_remove_network(self): - nc = dhcp_agent.NetworkCache() - nc.cache = {fake_network.id: fake_network} - nc.subnet_lookup = {fake_subnet1.id: fake_network.id, - fake_subnet2.id: fake_network.id} - nc.port_lookup = {fake_port1.id: fake_network.id} - nc.remove(fake_network) - - self.assertEqual(len(nc.cache), 0) - self.assertEqual(len(nc.subnet_lookup), 0) - self.assertEqual(len(nc.port_lookup), 0) - - def test_get_network_by_id(self): - nc = dhcp_agent.NetworkCache() - nc.put(fake_network) - - self.assertEqual(nc.get_network_by_id(fake_network.id), fake_network) - - def test_get_network_ids(self): - nc = dhcp_agent.NetworkCache() - nc.put(fake_network) - - self.assertEqual(nc.get_network_ids(), [fake_network.id]) - - def test_get_network_by_subnet_id(self): - nc = dhcp_agent.NetworkCache() - nc.put(fake_network) - - self.assertEqual(nc.get_network_by_subnet_id(fake_subnet1.id), - fake_network) - - def test_get_network_by_port_id(self): - nc = dhcp_agent.NetworkCache() - nc.put(fake_network) - - self.assertEqual(nc.get_network_by_port_id(fake_port1.id), - fake_network) - - def test_put_port(self): - fake_net = dhcp.NetModel( - True, dict(id='12345678-1234-5678-1234567890ab', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa', - subnets=[fake_subnet1], - ports=[fake_port1])) - nc = dhcp_agent.NetworkCache() - nc.put(fake_net) - nc.put_port(fake_port2) - self.assertEqual(len(nc.port_lookup), 2) - self.assertIn(fake_port2, fake_net.ports) - - def test_put_port_existing(self): - fake_net = dhcp.NetModel( - True, dict(id='12345678-1234-5678-1234567890ab', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa', - subnets=[fake_subnet1], - ports=[fake_port1, fake_port2])) - nc = dhcp_agent.NetworkCache() - nc.put(fake_net) - nc.put_port(fake_port2) - - self.assertEqual(len(nc.port_lookup), 2) - self.assertIn(fake_port2, fake_net.ports) - - def test_remove_port_existing(self): - fake_net = dhcp.NetModel( - True, dict(id='12345678-1234-5678-1234567890ab', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa', - subnets=[fake_subnet1], - ports=[fake_port1, fake_port2])) - nc = dhcp_agent.NetworkCache() - nc.put(fake_net) - nc.remove_port(fake_port2) - - self.assertEqual(len(nc.port_lookup), 1) - self.assertNotIn(fake_port2, fake_net.ports) - - def test_get_port_by_id(self): - nc = dhcp_agent.NetworkCache() - nc.put(fake_network) - self.assertEqual(nc.get_port_by_id(fake_port1.id), fake_port1) - - -class FakePort1: - id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - - -class FakeV4Subnet: - id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' - ip_version = 4 - cidr = '192.168.0.0/24' - gateway_ip = '192.168.0.1' - enable_dhcp = True - - -class FakeV4SubnetNoGateway: - id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - ip_version = 4 - cidr = '192.168.1.0/24' - gateway_ip = None - enable_dhcp = True - - -class FakeV4Network: - id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - subnets = [FakeV4Subnet()] - ports = [FakePort1()] - namespace = 'qdhcp-aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - - -class FakeV4NetworkNoSubnet: - id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - subnets = [] - ports = [] - - -class FakeV4NetworkNoGateway: - id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' - subnets = [FakeV4SubnetNoGateway()] - ports = [FakePort1()] - - -class TestDeviceManager(base.BaseTestCase): - def setUp(self): - super(TestDeviceManager, self).setUp() - config.register_interface_driver_opts_helper(cfg.CONF) - config.register_use_namespaces_opts_helper(cfg.CONF) - cfg.CONF.register_opts(dhcp_agent.DhcpAgent.OPTS) - cfg.CONF.register_opts(dhcp.OPTS) - cfg.CONF.set_override('interface_driver', - 'neutron.agent.linux.interface.NullDriver') - config.register_root_helper(cfg.CONF) - cfg.CONF.set_override('use_namespaces', True) - cfg.CONF.set_override('enable_isolated_metadata', True) - - self.ensure_device_is_ready_p = mock.patch( - 'neutron.agent.linux.ip_lib.ensure_device_is_ready') - self.ensure_device_is_ready = (self.ensure_device_is_ready_p.start()) - - self.dvr_cls_p = mock.patch('neutron.agent.linux.interface.NullDriver') - self.iproute_cls_p = mock.patch('neutron.agent.linux.' - 'ip_lib.IpRouteCommand') - driver_cls = self.dvr_cls_p.start() - iproute_cls = self.iproute_cls_p.start() - self.mock_driver = mock.MagicMock() - self.mock_driver.DEV_NAME_LEN = ( - interface.LinuxInterfaceDriver.DEV_NAME_LEN) - self.mock_iproute = mock.MagicMock() - driver_cls.return_value = self.mock_driver - iproute_cls.return_value = self.mock_iproute - - def _test_setup_helper(self, device_is_ready, net=None, port=None): - net = net or fake_network - port = port or fake_port1 - plugin = mock.Mock() - plugin.create_dhcp_port.return_value = port or fake_port1 - plugin.get_dhcp_port.return_value = port or fake_port1 - self.ensure_device_is_ready.return_value = device_is_ready - self.mock_driver.get_device_name.return_value = 'tap12345678-12' - - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, plugin) - dh._set_default_route = mock.Mock() - interface_name = dh.setup(net) - - self.assertEqual(interface_name, 'tap12345678-12') - - plugin.assert_has_calls([ - mock.call.create_dhcp_port( - {'port': {'name': '', 'admin_state_up': True, - 'network_id': net.id, 'tenant_id': net.tenant_id, - 'fixed_ips': - [{'subnet_id': fake_fixed_ip1.subnet_id}], - 'device_id': mock.ANY}})]) - - expected_ips = ['172.9.9.9/24', '169.254.169.254/16'] - expected = [ - mock.call.get_device_name(port), - mock.call.init_l3( - 'tap12345678-12', - expected_ips, - namespace=net.namespace)] - - if not device_is_ready: - expected.insert(1, - mock.call.plug(net.id, - port.id, - 'tap12345678-12', - 'aa:bb:cc:dd:ee:ff', - namespace=net.namespace)) - self.mock_driver.assert_has_calls(expected) - - dh._set_default_route.assert_called_once_with(net, 'tap12345678-12') - - def test_setup(self): - cfg.CONF.set_override('enable_metadata_network', False) - self._test_setup_helper(False) - cfg.CONF.set_override('enable_metadata_network', True) - self._test_setup_helper(False) - - def test_setup_device_is_ready(self): - self._test_setup_helper(True) - - def test_create_dhcp_port_raise_conflict(self): - plugin = mock.Mock() - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, plugin) - plugin.create_dhcp_port.return_value = None - self.assertRaises(exceptions.Conflict, - dh.setup_dhcp_port, - fake_network) - - def test_create_dhcp_port_create_new(self): - plugin = mock.Mock() - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, plugin) - plugin.create_dhcp_port.return_value = fake_network.ports[0] - dh.setup_dhcp_port(fake_network) - plugin.assert_has_calls([ - mock.call.create_dhcp_port( - {'port': {'name': '', 'admin_state_up': True, - 'network_id': - fake_network.id, 'tenant_id': fake_network.tenant_id, - 'fixed_ips': - [{'subnet_id': fake_fixed_ip1.subnet_id}], - 'device_id': mock.ANY}})]) - - def test_create_dhcp_port_update_add_subnet(self): - plugin = mock.Mock() - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, plugin) - fake_network_copy = copy.deepcopy(fake_network) - fake_network_copy.ports[0].device_id = dh.get_device_id(fake_network) - fake_network_copy.subnets[1].enable_dhcp = True - plugin.update_dhcp_port.return_value = fake_network.ports[0] - dh.setup_dhcp_port(fake_network_copy) - port_body = {'port': { - 'network_id': fake_network.id, - 'fixed_ips': [{'subnet_id': fake_fixed_ip1.subnet_id, - 'ip_address': fake_fixed_ip1.ip_address}, - {'subnet_id': fake_subnet2.id}]}} - - plugin.assert_has_calls([ - mock.call.update_dhcp_port(fake_network_copy.ports[0].id, - port_body)]) - - def test_update_dhcp_port_raises_conflict(self): - plugin = mock.Mock() - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, plugin) - fake_network_copy = copy.deepcopy(fake_network) - fake_network_copy.ports[0].device_id = dh.get_device_id(fake_network) - fake_network_copy.subnets[1].enable_dhcp = True - plugin.update_dhcp_port.return_value = None - self.assertRaises(exceptions.Conflict, - dh.setup_dhcp_port, - fake_network_copy) - - def test_create_dhcp_port_no_update_or_create(self): - plugin = mock.Mock() - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, plugin) - fake_network_copy = copy.deepcopy(fake_network) - fake_network_copy.ports[0].device_id = dh.get_device_id(fake_network) - dh.setup_dhcp_port(fake_network_copy) - self.assertFalse(plugin.setup_dhcp_port.called) - self.assertFalse(plugin.update_dhcp_port.called) - - def test_destroy(self): - fake_net = dhcp.NetModel( - True, dict(id='12345678-1234-5678-1234567890ab', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa')) - - fake_port = dhcp.DictModel( - dict(id='12345678-1234-aaaa-1234567890ab', - mac_address='aa:bb:cc:dd:ee:ff')) - - with mock.patch('neutron.agent.linux.interface.NullDriver') as dvr_cls: - mock_driver = mock.MagicMock() - mock_driver.get_device_name.return_value = 'tap12345678-12' - dvr_cls.return_value = mock_driver - - plugin = mock.Mock() - plugin.get_dhcp_port.return_value = fake_port - - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, plugin) - dh.destroy(fake_net, 'tap12345678-12') - - dvr_cls.assert_called_once_with(cfg.CONF) - mock_driver.assert_has_calls( - [mock.call.unplug('tap12345678-12', - namespace='qdhcp-' + fake_net.id)]) - plugin.assert_has_calls( - [mock.call.release_dhcp_port(fake_net.id, mock.ANY)]) - - def test_get_interface_name(self): - fake_net = dhcp.NetModel( - True, dict(id='12345678-1234-5678-1234567890ab', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa')) - - fake_port = dhcp.DictModel( - dict(id='12345678-1234-aaaa-1234567890ab', - mac_address='aa:bb:cc:dd:ee:ff')) - - with mock.patch('neutron.agent.linux.interface.NullDriver') as dvr_cls: - mock_driver = mock.MagicMock() - mock_driver.get_device_name.return_value = 'tap12345678-12' - dvr_cls.return_value = mock_driver - - plugin = mock.Mock() - plugin.get_dhcp_port.return_value = fake_port - - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, plugin) - dh.get_interface_name(fake_net, fake_port) - - dvr_cls.assert_called_once_with(cfg.CONF) - mock_driver.assert_has_calls( - [mock.call.get_device_name(fake_port)]) - - self.assertEqual(len(plugin.mock_calls), 0) - - def test_get_device_id(self): - fake_net = dhcp.NetModel( - True, dict(id='12345678-1234-5678-1234567890ab', - tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa')) - expected = ('dhcp1ae5f96c-c527-5079-82ea-371a01645457-12345678-1234-' - '5678-1234567890ab') - - with mock.patch('uuid.uuid5') as uuid5: - uuid5.return_value = '1ae5f96c-c527-5079-82ea-371a01645457' - - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - uuid5.called_once_with(uuid.NAMESPACE_DNS, cfg.CONF.host) - self.assertEqual(dh.get_device_id(fake_net), expected) - - def test_update(self): - # Try with namespaces and no metadata network - cfg.CONF.set_override('use_namespaces', True) - cfg.CONF.set_override('enable_metadata_network', False) - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - dh._set_default_route = mock.Mock() - network = mock.Mock() - - dh.update(network, 'ns-12345678-12') - - dh._set_default_route.assert_called_once_with(network, - 'ns-12345678-12') - - # No namespaces, shouldn't set default route. - cfg.CONF.set_override('use_namespaces', False) - cfg.CONF.set_override('enable_metadata_network', False) - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - dh._set_default_route = mock.Mock() - - dh.update(FakeV4Network(), 'tap12345678-12') - - self.assertFalse(dh._set_default_route.called) - - # Meta data network enabled, don't interfere with its gateway. - cfg.CONF.set_override('use_namespaces', True) - cfg.CONF.set_override('enable_metadata_network', True) - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - dh._set_default_route = mock.Mock() - - dh.update(FakeV4Network(), 'ns-12345678-12') - - self.assertTrue(dh._set_default_route.called) - - # For completeness - cfg.CONF.set_override('use_namespaces', False) - cfg.CONF.set_override('enable_metadata_network', True) - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - dh._set_default_route = mock.Mock() - - dh.update(FakeV4Network(), 'ns-12345678-12') - - self.assertFalse(dh._set_default_route.called) - - def test_set_default_route(self): - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - with mock.patch.object(dhcp.ip_lib, 'IPDevice') as mock_IPDevice: - device = mock.Mock() - mock_IPDevice.return_value = device - device.route.get_gateway.return_value = None - # Basic one subnet with gateway. - network = FakeV4Network() - dh._set_default_route(network, 'tap-name') - - self.assertEqual(device.route.get_gateway.call_count, 1) - self.assertFalse(device.route.delete_gateway.called) - device.route.add_gateway.assert_called_once_with('192.168.0.1') - - def test_set_default_route_no_subnet(self): - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - with mock.patch.object(dhcp.ip_lib, 'IPDevice') as mock_IPDevice: - device = mock.Mock() - mock_IPDevice.return_value = device - device.route.get_gateway.return_value = None - network = FakeV4NetworkNoSubnet() - network.namespace = 'qdhcp-1234' - dh._set_default_route(network, 'tap-name') - - self.assertEqual(device.route.get_gateway.call_count, 1) - self.assertFalse(device.route.delete_gateway.called) - self.assertFalse(device.route.add_gateway.called) - - def test_set_default_route_no_subnet_delete_gateway(self): - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - with mock.patch.object(dhcp.ip_lib, 'IPDevice') as mock_IPDevice: - device = mock.Mock() - mock_IPDevice.return_value = device - device.route.get_gateway.return_value = dict(gateway='192.168.0.1') - network = FakeV4NetworkNoSubnet() - network.namespace = 'qdhcp-1234' - dh._set_default_route(network, 'tap-name') - - self.assertEqual(device.route.get_gateway.call_count, 1) - device.route.delete_gateway.assert_called_once_with('192.168.0.1') - self.assertFalse(device.route.add_gateway.called) - - def test_set_default_route_no_gateway(self): - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - with mock.patch.object(dhcp.ip_lib, 'IPDevice') as mock_IPDevice: - device = mock.Mock() - mock_IPDevice.return_value = device - device.route.get_gateway.return_value = dict(gateway='192.168.0.1') - network = FakeV4NetworkNoGateway() - network.namespace = 'qdhcp-1234' - dh._set_default_route(network, 'tap-name') - - self.assertEqual(device.route.get_gateway.call_count, 1) - device.route.delete_gateway.assert_called_once_with('192.168.0.1') - self.assertFalse(device.route.add_gateway.called) - - def test_set_default_route_do_nothing(self): - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - with mock.patch.object(dhcp.ip_lib, 'IPDevice') as mock_IPDevice: - device = mock.Mock() - mock_IPDevice.return_value = device - device.route.get_gateway.return_value = dict(gateway='192.168.0.1') - network = FakeV4Network() - dh._set_default_route(network, 'tap-name') - - self.assertEqual(device.route.get_gateway.call_count, 1) - self.assertFalse(device.route.delete_gateway.called) - self.assertFalse(device.route.add_gateway.called) - - def test_set_default_route_change_gateway(self): - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - with mock.patch.object(dhcp.ip_lib, 'IPDevice') as mock_IPDevice: - device = mock.Mock() - mock_IPDevice.return_value = device - device.route.get_gateway.return_value = dict(gateway='192.168.0.2') - network = FakeV4Network() - dh._set_default_route(network, 'tap-name') - - self.assertEqual(device.route.get_gateway.call_count, 1) - self.assertFalse(device.route.delete_gateway.called) - device.route.add_gateway.assert_called_once_with('192.168.0.1') - - def test_set_default_route_two_subnets(self): - # Try two subnets. Should set gateway from the first. - dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, None) - with mock.patch.object(dhcp.ip_lib, 'IPDevice') as mock_IPDevice: - device = mock.Mock() - mock_IPDevice.return_value = device - device.route.get_gateway.return_value = None - network = FakeV4Network() - subnet2 = FakeV4Subnet() - subnet2.gateway_ip = '192.168.1.1' - network.subnets = [subnet2, FakeV4Subnet()] - dh._set_default_route(network, 'tap-name') - - self.assertEqual(device.route.get_gateway.call_count, 1) - self.assertFalse(device.route.delete_gateway.called) - device.route.add_gateway.assert_called_once_with('192.168.1.1') - - -class TestDictModel(base.BaseTestCase): - def test_basic_dict(self): - d = dict(a=1, b=2) - - m = dhcp.DictModel(d) - self.assertEqual(m.a, 1) - self.assertEqual(m.b, 2) - - def test_dict_has_sub_dict(self): - d = dict(a=dict(b=2)) - m = dhcp.DictModel(d) - self.assertEqual(m.a.b, 2) - - def test_dict_contains_list(self): - d = dict(a=[1, 2]) - - m = dhcp.DictModel(d) - self.assertEqual(m.a, [1, 2]) - - def test_dict_contains_list_of_dicts(self): - d = dict(a=[dict(b=2), dict(c=3)]) - - m = dhcp.DictModel(d) - self.assertEqual(m.a[0].b, 2) - self.assertEqual(m.a[1].c, 3) - - -class TestNetModel(base.BaseTestCase): - def test_ns_name(self): - network = dhcp.NetModel(True, {'id': 'foo'}) - self.assertEqual(network.namespace, 'qdhcp-foo') - - def test_ns_name_false_namespace(self): - network = dhcp.NetModel(False, {'id': 'foo'}) - self.assertIsNone(network.namespace) - - def test_ns_name_none_namespace(self): - network = dhcp.NetModel(None, {'id': 'foo'}) - self.assertIsNone(network.namespace) diff --git a/neutron/tests/unit/test_dhcp_scheduler.py b/neutron/tests/unit/test_dhcp_scheduler.py deleted file mode 100644 index fd071f73a..000000000 --- a/neutron/tests/unit/test_dhcp_scheduler.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright 2014 OpenStack Foundation -# -# 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 neutron.common import constants -from neutron.common import topics -from neutron import context -from neutron.db import agents_db -from neutron.db import agentschedulers_db -from neutron.db import api as db -from neutron.db import models_v2 -from neutron.openstack.common import timeutils -from neutron.scheduler import dhcp_agent_scheduler -from neutron.tests import base - - -class DhcpSchedulerTestCase(base.BaseTestCase): - - def setUp(self): - super(DhcpSchedulerTestCase, self).setUp() - db.configure_db() - self.ctx = context.get_admin_context() - self.network_id = 'foo_network_id' - self._save_networks([self.network_id]) - self.addCleanup(db.clear_db) - - def _get_agents(self, hosts): - return [ - agents_db.Agent( - binary='neutron-dhcp-agent', - host=host, - topic=topics.DHCP_AGENT, - configurations="", - agent_type=constants.AGENT_TYPE_DHCP, - created_at=timeutils.utcnow(), - started_at=timeutils.utcnow(), - heartbeat_timestamp=timeutils.utcnow()) - for host in hosts - ] - - def _save_agents(self, agents): - for agent in agents: - with self.ctx.session.begin(subtransactions=True): - self.ctx.session.add(agent) - - def _save_networks(self, networks): - for network_id in networks: - with self.ctx.session.begin(subtransactions=True): - self.ctx.session.add(models_v2.Network(id=network_id)) - - def _test__schedule_bind_network(self, agents, network_id): - scheduler = dhcp_agent_scheduler.ChanceScheduler() - scheduler._schedule_bind_network(self.ctx, agents, network_id) - results = ( - self.ctx.session.query(agentschedulers_db.NetworkDhcpAgentBinding). - filter_by(network_id=network_id).all()) - self.assertEqual(len(agents), len(results)) - for result in results: - self.assertEqual(network_id, result.network_id) - - def test__schedule_bind_network_single_agent(self): - agents = self._get_agents(['host-a']) - self._save_agents(agents) - self._test__schedule_bind_network(agents, self.network_id) - - def test__schedule_bind_network_multi_agents(self): - agents = self._get_agents(['host-a', 'host-b']) - self._save_agents(agents) - self._test__schedule_bind_network(agents, self.network_id) - - def test__schedule_bind_network_multi_agent_fail_one(self): - agents = self._get_agents(['host-a']) - self._save_agents(agents) - self._test__schedule_bind_network(agents, self.network_id) - with mock.patch.object(dhcp_agent_scheduler.LOG, 'info') as fake_log: - self._test__schedule_bind_network(agents, self.network_id) - self.assertEqual(1, fake_log.call_count) diff --git a/neutron/tests/unit/test_extension_allowedaddresspairs.py b/neutron/tests/unit/test_extension_allowedaddresspairs.py deleted file mode 100644 index 28dcd91b1..000000000 --- a/neutron/tests/unit/test_extension_allowedaddresspairs.py +++ /dev/null @@ -1,262 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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. - - -from neutron.api.v2 import attributes as attr -from neutron.db import allowedaddresspairs_db as addr_pair_db -from neutron.db import db_base_plugin_v2 -from neutron.db import portsecurity_db -from neutron.extensions import allowedaddresspairs as addr_pair -from neutron.extensions import portsecurity as psec -from neutron import manager -from neutron.tests.unit import test_db_plugin - -DB_PLUGIN_KLASS = ('neutron.tests.unit.test_extension_allowedaddresspairs.' - 'AllowedAddressPairTestPlugin') - - -class AllowedAddressPairTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - def setUp(self, plugin=None, ext_mgr=None): - super(AllowedAddressPairTestCase, self).setUp(plugin) - - # Check if a plugin supports security groups - plugin_obj = manager.NeutronManager.get_plugin() - self._skip_port_security = ('port-security' not in - plugin_obj.supported_extension_aliases) - - -class AllowedAddressPairTestPlugin(portsecurity_db.PortSecurityDbMixin, - db_base_plugin_v2.NeutronDbPluginV2, - addr_pair_db.AllowedAddressPairsMixin): - - """Test plugin that implements necessary calls on create/delete port for - associating ports with port security and allowed address pairs. - """ - - supported_extension_aliases = ["allowed-address-pairs"] - - def create_port(self, context, port): - p = port['port'] - with context.session.begin(subtransactions=True): - neutron_db = super(AllowedAddressPairTestPlugin, self).create_port( - context, port) - p.update(neutron_db) - if attr.is_attr_set(p.get(addr_pair.ADDRESS_PAIRS)): - self._process_create_allowed_address_pairs( - context, p, - p[addr_pair.ADDRESS_PAIRS]) - else: - p[addr_pair.ADDRESS_PAIRS] = None - - return port['port'] - - def update_port(self, context, id, port): - delete_addr_pairs = self._check_update_deletes_allowed_address_pairs( - port) - has_addr_pairs = self._check_update_has_allowed_address_pairs(port) - - with context.session.begin(subtransactions=True): - ret_port = super(AllowedAddressPairTestPlugin, self).update_port( - context, id, port) - # copy values over - but not fixed_ips - port['port'].pop('fixed_ips', None) - ret_port.update(port['port']) - - if (delete_addr_pairs or has_addr_pairs): - # delete address pairds and readd them - self._delete_allowed_address_pairs(context, id) - self._process_create_allowed_address_pairs( - context, ret_port, - ret_port[addr_pair.ADDRESS_PAIRS]) - - return ret_port - - -class AllowedAddressPairDBTestCase(AllowedAddressPairTestCase): - def setUp(self, plugin=None, ext_mgr=None): - plugin = plugin or DB_PLUGIN_KLASS - super(AllowedAddressPairDBTestCase, - self).setUp(plugin=plugin, ext_mgr=ext_mgr) - - -class TestAllowedAddressPairs(AllowedAddressPairDBTestCase): - - def test_create_port_allowed_address_pairs(self): - with self.network() as net: - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1'}] - res = self._create_port(self.fmt, net['network']['id'], - arg_list=(addr_pair.ADDRESS_PAIRS,), - allowed_address_pairs=address_pairs) - port = self.deserialize(self.fmt, res) - self.assertEqual(port['port'][addr_pair.ADDRESS_PAIRS], - address_pairs) - self._delete('ports', port['port']['id']) - - def test_create_port_security_true_allowed_address_pairs(self): - if self._skip_port_security: - self.skipTest("Plugin does not implement port-security extension") - - with self.network() as net: - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1'}] - res = self._create_port(self.fmt, net['network']['id'], - arg_list=('port_security_enabled', - addr_pair.ADDRESS_PAIRS,), - port_security_enabled=True, - allowed_address_pairs=address_pairs) - port = self.deserialize(self.fmt, res) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - self.assertEqual(port['port'][addr_pair.ADDRESS_PAIRS], - address_pairs) - self._delete('ports', port['port']['id']) - - def test_create_port_security_false_allowed_address_pairs(self): - if self._skip_port_security: - self.skipTest("Plugin does not implement port-security extension") - - with self.network() as net: - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1'}] - res = self._create_port(self.fmt, net['network']['id'], - arg_list=('port_security_enabled', - addr_pair.ADDRESS_PAIRS,), - port_security_enabled=False, - allowed_address_pairs=address_pairs) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, 409) - - def test_create_port_bad_mac(self): - address_pairs = [{'mac_address': 'invalid_mac', - 'ip_address': '10.0.0.1'}] - self._create_port_with_address_pairs(address_pairs, 400) - - def test_create_port_bad_ip(self): - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1222'}] - self._create_port_with_address_pairs(address_pairs, 400) - - def test_create_missing_ip_field(self): - address_pairs = [{'mac_address': '00:00:00:00:00:01'}] - self._create_port_with_address_pairs(address_pairs, 400) - - def test_create_duplicate_mac_ip(self): - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1'}, - {'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1'}] - self._create_port_with_address_pairs(address_pairs, 400) - - def test_create_overlap_with_fixed_ip(self): - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.2'}] - with self.network() as network: - with self.subnet(network=network, cidr='10.0.0.0/24') as subnet: - fixed_ips = [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.2'}] - res = self._create_port(self.fmt, network['network']['id'], - arg_list=(addr_pair.ADDRESS_PAIRS, - 'fixed_ips'), - allowed_address_pairs=address_pairs, - fixed_ips=fixed_ips) - self.assertEqual(res.status_int, 201) - port = self.deserialize(self.fmt, res) - self._delete('ports', port['port']['id']) - - def test_create_port_extra_args(self): - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1', - 'icbb': 'agreed'}] - self._create_port_with_address_pairs(address_pairs, 400) - - def _create_port_with_address_pairs(self, address_pairs, ret_code): - with self.network() as net: - res = self._create_port(self.fmt, net['network']['id'], - arg_list=(addr_pair.ADDRESS_PAIRS,), - allowed_address_pairs=address_pairs) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, ret_code) - - def test_update_add_address_pairs(self): - with self.network() as net: - res = self._create_port(self.fmt, net['network']['id']) - port = self.deserialize(self.fmt, res) - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1'}] - update_port = {'port': {addr_pair.ADDRESS_PAIRS: - address_pairs}} - req = self.new_update_request('ports', update_port, - port['port']['id']) - port = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(port['port'][addr_pair.ADDRESS_PAIRS], - address_pairs) - self._delete('ports', port['port']['id']) - - def test_create_address_gets_port_mac(self): - with self.network() as net: - address_pairs = [{'ip_address': '23.23.23.23'}] - res = self._create_port(self.fmt, net['network']['id'], - arg_list=('port_security_enabled', - addr_pair.ADDRESS_PAIRS,), - allowed_address_pairs=address_pairs) - port = self.deserialize(self.fmt, res)['port'] - port_addr_mac = port[addr_pair.ADDRESS_PAIRS][0]['mac_address'] - self.assertEqual(port_addr_mac, - port['mac_address']) - self._delete('ports', port['id']) - - def test_update_port_security_off_address_pairs(self): - if self._skip_port_security: - self.skipTest("Plugin does not implement port-security extension") - with self.network() as net: - with self.subnet(network=net): - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1'}] - res = self._create_port(self.fmt, net['network']['id'], - arg_list=('port_security_enabled', - addr_pair.ADDRESS_PAIRS,), - port_security_enabled=True, - allowed_address_pairs=address_pairs) - port = self.deserialize(self.fmt, res) - update_port = {'port': {psec.PORTSECURITY: False}} - # If plugin implements security groups we also need to remove - # the security group on port. - plugin_obj = manager.NeutronManager.get_plugin() - if 'security-groups' in plugin_obj.supported_extension_aliases: - update_port['port']['security_groups'] = [] - req = self.new_update_request('ports', update_port, - port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 409) - self._delete('ports', port['port']['id']) - - def test_create_port_remove_allowed_address_pairs(self): - with self.network() as net: - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.1'}] - res = self._create_port(self.fmt, net['network']['id'], - arg_list=(addr_pair.ADDRESS_PAIRS,), - allowed_address_pairs=address_pairs) - port = self.deserialize(self.fmt, res) - update_port = {'port': {addr_pair.ADDRESS_PAIRS: []}} - req = self.new_update_request('ports', update_port, - port['port']['id']) - port = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(port['port'][addr_pair.ADDRESS_PAIRS], []) - self._delete('ports', port['port']['id']) - - -class TestAllowedAddressPairsXML(TestAllowedAddressPairs): - fmt = 'xml' diff --git a/neutron/tests/unit/test_extension_ext_gw_mode.py b/neutron/tests/unit/test_extension_ext_gw_mode.py deleted file mode 100644 index cabb1428e..000000000 --- a/neutron/tests/unit/test_extension_ext_gw_mode.py +++ /dev/null @@ -1,421 +0,0 @@ -# Copyright 2013 VMware, Inc. -# All rights reserved. -# -# 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 oslo.config import cfg -from webob import exc - -from neutron.common import constants -from neutron.db import api as db_api -from neutron.db import external_net_db -from neutron.db import l3_db -from neutron.db import l3_gwmode_db -from neutron.db import models_v2 -from neutron.extensions import l3 -from neutron.extensions import l3_ext_gw_mode -from neutron.openstack.common import uuidutils -from neutron.tests import base -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import test_l3_plugin - -_uuid = uuidutils.generate_uuid -FAKE_GW_PORT_ID = _uuid() -FAKE_GW_PORT_MAC = 'aa:bb:cc:dd:ee:ff' -FAKE_FIP_EXT_PORT_ID = _uuid() -FAKE_FIP_EXT_PORT_MAC = '11:22:33:44:55:66' -FAKE_FIP_INT_PORT_ID = _uuid() -FAKE_FIP_INT_PORT_MAC = 'aa:aa:aa:aa:aa:aa' -FAKE_ROUTER_PORT_ID = _uuid() -FAKE_ROUTER_PORT_MAC = 'bb:bb:bb:bb:bb:bb' - - -class TestExtensionManager(object): - - def get_resources(self): - # Simulate extension of L3 attribute map - for key in l3.RESOURCE_ATTRIBUTE_MAP.keys(): - l3.RESOURCE_ATTRIBUTE_MAP[key].update( - l3_ext_gw_mode.EXTENDED_ATTRIBUTES_2_0.get(key, {})) - return l3.L3.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -# A simple class for making a concrete class out of the mixin -# for the case of a plugin that integrates l3 routing. -class TestDbIntPlugin(test_l3_plugin.TestL3NatIntPlugin, - l3_gwmode_db.L3_NAT_db_mixin): - - supported_extension_aliases = ["external-net", "router", "ext-gw-mode"] - - -# A simple class for making a concrete class out of the mixin -# for the case of a l3 router service plugin -class TestDbSepPlugin(test_l3_plugin.TestL3NatServicePlugin, - l3_gwmode_db.L3_NAT_db_mixin): - - supported_extension_aliases = ["router", "ext-gw-mode"] - - -class TestL3GwModeMixin(base.BaseTestCase): - - def setUp(self): - super(TestL3GwModeMixin, self).setUp() - plugin = __name__ + '.' + TestDbIntPlugin.__name__ - self.setup_coreplugin(plugin) - self.target_object = TestDbIntPlugin() - # Patch the context - ctx_patcher = mock.patch('neutron.context', autospec=True) - mock_context = ctx_patcher.start() - self.addCleanup(db_api.clear_db) - self.context = mock_context.get_admin_context() - # This ensure also calls to elevated work in unit tests - self.context.elevated.return_value = self.context - self.context.session = db_api.get_session() - # Create sample data for tests - self.ext_net_id = _uuid() - self.int_net_id = _uuid() - self.int_sub_id = _uuid() - self.tenant_id = 'the_tenant' - self.network = models_v2.Network( - id=self.ext_net_id, - tenant_id=self.tenant_id, - admin_state_up=True, - status=constants.NET_STATUS_ACTIVE) - self.net_ext = external_net_db.ExternalNetwork( - network_id=self.ext_net_id) - self.context.session.add(self.network) - # The following is to avoid complains from sqlite on - # foreign key violations - self.context.session.flush() - self.context.session.add(self.net_ext) - self.router = l3_db.Router( - id=_uuid(), - name=None, - tenant_id=self.tenant_id, - admin_state_up=True, - status=constants.NET_STATUS_ACTIVE, - enable_snat=True, - gw_port_id=None) - self.context.session.add(self.router) - self.context.session.flush() - self.router_gw_port = models_v2.Port( - id=FAKE_GW_PORT_ID, - tenant_id=self.tenant_id, - device_id=self.router.id, - device_owner=l3_db.DEVICE_OWNER_ROUTER_GW, - admin_state_up=True, - status=constants.PORT_STATUS_ACTIVE, - mac_address=FAKE_GW_PORT_MAC, - network_id=self.ext_net_id) - self.router.gw_port_id = self.router_gw_port.id - self.context.session.add(self.router) - self.context.session.add(self.router_gw_port) - self.context.session.flush() - self.fip_ext_port = models_v2.Port( - id=FAKE_FIP_EXT_PORT_ID, - tenant_id=self.tenant_id, - admin_state_up=True, - device_id=self.router.id, - device_owner=l3_db.DEVICE_OWNER_FLOATINGIP, - status=constants.PORT_STATUS_ACTIVE, - mac_address=FAKE_FIP_EXT_PORT_MAC, - network_id=self.ext_net_id) - self.context.session.add(self.fip_ext_port) - self.context.session.flush() - self.int_net = models_v2.Network( - id=self.int_net_id, - tenant_id=self.tenant_id, - admin_state_up=True, - status=constants.NET_STATUS_ACTIVE) - self.int_sub = models_v2.Subnet( - id=self.int_sub_id, - tenant_id=self.tenant_id, - ip_version=4, - cidr='3.3.3.0/24', - gateway_ip='3.3.3.1', - network_id=self.int_net_id) - self.router_port = models_v2.Port( - id=FAKE_ROUTER_PORT_ID, - tenant_id=self.tenant_id, - admin_state_up=True, - device_id=self.router.id, - device_owner=l3_db.DEVICE_OWNER_ROUTER_INTF, - status=constants.PORT_STATUS_ACTIVE, - mac_address=FAKE_ROUTER_PORT_MAC, - network_id=self.int_net_id) - self.router_port_ip_info = models_v2.IPAllocation( - port_id=self.router_port.id, - network_id=self.int_net.id, - subnet_id=self.int_sub_id, - ip_address='3.3.3.1') - self.context.session.add(self.int_net) - self.context.session.add(self.int_sub) - self.context.session.add(self.router_port) - self.context.session.add(self.router_port_ip_info) - self.context.session.flush() - self.fip_int_port = models_v2.Port( - id=FAKE_FIP_INT_PORT_ID, - tenant_id=self.tenant_id, - admin_state_up=True, - device_id='something', - device_owner='compute:nova', - status=constants.PORT_STATUS_ACTIVE, - mac_address=FAKE_FIP_INT_PORT_MAC, - network_id=self.int_net_id) - self.fip_int_ip_info = models_v2.IPAllocation( - port_id=self.fip_int_port.id, - network_id=self.int_net.id, - subnet_id=self.int_sub_id, - ip_address='3.3.3.3') - self.fip = l3_db.FloatingIP( - id=_uuid(), - floating_ip_address='1.1.1.2', - floating_network_id=self.ext_net_id, - floating_port_id=FAKE_FIP_EXT_PORT_ID, - fixed_port_id=None, - fixed_ip_address=None, - router_id=None) - self.context.session.add(self.fip_int_port) - self.context.session.add(self.fip_int_ip_info) - self.context.session.add(self.fip) - self.context.session.flush() - self.fip_request = {'port_id': FAKE_FIP_INT_PORT_ID, - 'tenant_id': self.tenant_id} - - def _reset_ext_gw(self): - # Reset external gateway - self.router.gw_port_id = None - self.context.session.add(self.router) - self.context.session.flush() - - def _test_update_router_gw(self, gw_info, expected_enable_snat): - self.target_object._update_router_gw_info( - self.context, self.router.id, gw_info) - router = self.target_object._get_router( - self.context, self.router.id) - try: - self.assertEqual(FAKE_GW_PORT_ID, - router.gw_port.id) - self.assertEqual(FAKE_GW_PORT_MAC, - router.gw_port.mac_address) - except AttributeError: - self.assertIsNone(router.gw_port) - self.assertEqual(expected_enable_snat, router.enable_snat) - - def test_update_router_gw_with_gw_info_none(self): - self._test_update_router_gw(None, True) - - def test_update_router_gw_with_network_only(self): - info = {'network_id': self.ext_net_id} - self._test_update_router_gw(info, True) - - def test_update_router_gw_with_snat_disabled(self): - info = {'network_id': self.ext_net_id, - 'enable_snat': False} - self._test_update_router_gw(info, False) - - def test_make_router_dict_no_ext_gw(self): - self._reset_ext_gw() - router_dict = self.target_object._make_router_dict(self.router) - self.assertIsNone(router_dict[l3.EXTERNAL_GW_INFO]) - - def test_make_router_dict_with_ext_gw(self): - router_dict = self.target_object._make_router_dict(self.router) - self.assertEqual({'network_id': self.ext_net_id, - 'enable_snat': True}, - router_dict[l3.EXTERNAL_GW_INFO]) - - def test_make_router_dict_with_ext_gw_snat_disabled(self): - self.router.enable_snat = False - router_dict = self.target_object._make_router_dict(self.router) - self.assertEqual({'network_id': self.ext_net_id, - 'enable_snat': False}, - router_dict[l3.EXTERNAL_GW_INFO]) - - def test_build_routers_list_no_ext_gw(self): - self._reset_ext_gw() - router_dict = self.target_object._make_router_dict(self.router) - routers = self.target_object._build_routers_list([router_dict], []) - self.assertEqual(1, len(routers)) - router = routers[0] - self.assertIsNone(router.get('gw_port')) - self.assertIsNone(router.get('enable_snat')) - - def test_build_routers_list_with_ext_gw(self): - router_dict = self.target_object._make_router_dict(self.router) - routers = self.target_object._build_routers_list( - [router_dict], [self.router.gw_port]) - self.assertEqual(1, len(routers)) - router = routers[0] - self.assertIsNotNone(router.get('gw_port')) - self.assertEqual(FAKE_GW_PORT_ID, router['gw_port']['id']) - self.assertTrue(router.get('enable_snat')) - - def test_build_routers_list_with_ext_gw_snat_disabled(self): - self.router.enable_snat = False - router_dict = self.target_object._make_router_dict(self.router) - routers = self.target_object._build_routers_list( - [router_dict], [self.router.gw_port]) - self.assertEqual(1, len(routers)) - router = routers[0] - self.assertIsNotNone(router.get('gw_port')) - self.assertEqual(FAKE_GW_PORT_ID, router['gw_port']['id']) - self.assertFalse(router.get('enable_snat')) - - -class ExtGwModeIntTestCase(test_db_plugin.NeutronDbPluginV2TestCase, - test_l3_plugin.L3NatTestCaseMixin): - - def setUp(self, plugin=None, svc_plugins=None, ext_mgr=None): - # Store l3 resource attribute map as it will be updated - self._l3_attribute_map_bk = {} - for item in l3.RESOURCE_ATTRIBUTE_MAP: - self._l3_attribute_map_bk[item] = ( - l3.RESOURCE_ATTRIBUTE_MAP[item].copy()) - plugin = plugin or ( - 'neutron.tests.unit.test_extension_ext_gw_mode.TestDbIntPlugin') - # for these tests we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - ext_mgr = ext_mgr or TestExtensionManager() - super(ExtGwModeIntTestCase, self).setUp(plugin=plugin, - ext_mgr=ext_mgr, - service_plugins=svc_plugins) - self.addCleanup(self.restore_l3_attribute_map) - - def restore_l3_attribute_map(self): - l3.RESOURCE_ATTRIBUTE_MAP = self._l3_attribute_map_bk - - def tearDown(self): - super(ExtGwModeIntTestCase, self).tearDown() - - def _set_router_external_gateway(self, router_id, network_id, - snat_enabled=None, - expected_code=exc.HTTPOk.code, - neutron_context=None): - ext_gw_info = {'network_id': network_id} - # Need to set enable_snat also if snat_enabled == False - if snat_enabled is not None: - ext_gw_info['enable_snat'] = snat_enabled - return self._update('routers', router_id, - {'router': {'external_gateway_info': - ext_gw_info}}, - expected_code=expected_code, - neutron_context=neutron_context) - - def test_router_create_show_no_ext_gwinfo(self): - name = 'router1' - tenant_id = _uuid() - expected_value = [('name', name), ('tenant_id', tenant_id), - ('admin_state_up', True), ('status', 'ACTIVE'), - ('external_gateway_info', None)] - with self.router(name=name, admin_state_up=True, - tenant_id=tenant_id) as router: - res = self._show('routers', router['router']['id']) - for k, v in expected_value: - self.assertEqual(res['router'][k], v) - - def _test_router_create_show_ext_gwinfo(self, snat_input_value, - snat_expected_value): - name = 'router1' - tenant_id = _uuid() - with self.subnet() as s: - ext_net_id = s['subnet']['network_id'] - self._set_net_external(ext_net_id) - input_value = {'network_id': ext_net_id} - if snat_input_value in (True, False): - input_value['enable_snat'] = snat_input_value - expected_value = [('name', name), ('tenant_id', tenant_id), - ('admin_state_up', True), ('status', 'ACTIVE'), - ('external_gateway_info', - {'network_id': ext_net_id, - 'enable_snat': snat_expected_value})] - with self.router( - name=name, admin_state_up=True, tenant_id=tenant_id, - external_gateway_info=input_value) as router: - res = self._show('routers', router['router']['id']) - for k, v in expected_value: - self.assertEqual(res['router'][k], v) - - def test_router_create_show_ext_gwinfo_default(self): - self._test_router_create_show_ext_gwinfo(None, True) - - def test_router_create_show_ext_gwinfo_with_snat_enabled(self): - self._test_router_create_show_ext_gwinfo(True, True) - - def test_router_create_show_ext_gwinfo_with_snat_disabled(self): - self._test_router_create_show_ext_gwinfo(False, False) - - def _test_router_update_ext_gwinfo(self, snat_input_value, - snat_expected_value=False, - expected_http_code=exc.HTTPOk.code): - with self.router() as r: - with self.subnet() as s: - try: - ext_net_id = s['subnet']['network_id'] - self._set_net_external(ext_net_id) - self._set_router_external_gateway( - r['router']['id'], ext_net_id, - snat_enabled=snat_input_value, - expected_code=expected_http_code) - if expected_http_code != exc.HTTPOk.code: - return - body = self._show('routers', r['router']['id']) - res_gw_info = body['router']['external_gateway_info'] - self.assertEqual(res_gw_info['network_id'], ext_net_id) - self.assertEqual(res_gw_info['enable_snat'], - snat_expected_value) - finally: - self._remove_external_gateway_from_router( - r['router']['id'], ext_net_id) - - def test_router_update_ext_gwinfo_default(self): - self._test_router_update_ext_gwinfo(None, True) - - def test_router_update_ext_gwinfo_with_snat_enabled(self): - self._test_router_update_ext_gwinfo(True, True) - - def test_router_update_ext_gwinfo_with_snat_disabled(self): - self._test_router_update_ext_gwinfo(False, False) - - def test_router_update_ext_gwinfo_with_invalid_snat_setting(self): - self._test_router_update_ext_gwinfo( - 'xxx', None, expected_http_code=exc.HTTPBadRequest.code) - - -class ExtGwModeSepTestCase(ExtGwModeIntTestCase): - - def setUp(self, plugin=None): - # Store l3 resource attribute map as it will be updated - self._l3_attribute_map_bk = {} - for item in l3.RESOURCE_ATTRIBUTE_MAP: - self._l3_attribute_map_bk[item] = ( - l3.RESOURCE_ATTRIBUTE_MAP[item].copy()) - plugin = plugin or ( - 'neutron.tests.unit.test_l3_plugin.TestNoL3NatPlugin') - # the L3 service plugin - l3_plugin = ('neutron.tests.unit.test_extension_ext_gw_mode.' - 'TestDbSepPlugin') - svc_plugins = {'l3_plugin_name': l3_plugin} - # for these tests we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - super(ExtGwModeSepTestCase, self).setUp(plugin=plugin, - svc_plugins=svc_plugins) - self.addCleanup(self.restore_l3_attribute_map) diff --git a/neutron/tests/unit/test_extension_ext_net.py b/neutron/tests/unit/test_extension_ext_net.py deleted file mode 100644 index b525b9dd6..000000000 --- a/neutron/tests/unit/test_extension_ext_net.py +++ /dev/null @@ -1,176 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2013 OpenStack Foundation. -# All Rights Reserved. -# -# 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 contextlib -import itertools - -import mock -import testtools -from webob import exc - -from neutron import context -from neutron.db import models_v2 -from neutron.extensions import external_net as external_net -from neutron import manager -from neutron.openstack.common import log as logging -from neutron.openstack.common import uuidutils -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_db_plugin - - -LOG = logging.getLogger(__name__) - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path - - -class ExtNetTestExtensionManager(object): - - def get_resources(self): - return [] - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class ExtNetDBTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - - def _create_network(self, fmt, name, admin_state_up, **kwargs): - """Override the routine for allowing the router:external attribute.""" - # attributes containing a colon should be passed with - # a double underscore - new_args = dict(itertools.izip(map(lambda x: x.replace('__', ':'), - kwargs), - kwargs.values())) - arg_list = new_args.pop('arg_list', ()) + (external_net.EXTERNAL,) - return super(ExtNetDBTestCase, self)._create_network( - fmt, name, admin_state_up, arg_list=arg_list, **new_args) - - def setUp(self): - plugin = 'neutron.tests.unit.test_l3_plugin.TestNoL3NatPlugin' - ext_mgr = ExtNetTestExtensionManager() - super(ExtNetDBTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr) - - def _set_net_external(self, net_id): - self._update('networks', net_id, - {'network': {external_net.EXTERNAL: True}}) - - def test_list_nets_external(self): - with self.network() as n1: - self._set_net_external(n1['network']['id']) - with self.network(): - body = self._list('networks') - self.assertEqual(len(body['networks']), 2) - - body = self._list('networks', - query_params="%s=True" % - external_net.EXTERNAL) - self.assertEqual(len(body['networks']), 1) - - body = self._list('networks', - query_params="%s=False" % - external_net.EXTERNAL) - self.assertEqual(len(body['networks']), 1) - - def test_list_nets_external_pagination(self): - if self._skip_native_pagination: - self.skipTest("Skip test for not implemented pagination feature") - with contextlib.nested(self.network(name='net1'), - self.network(name='net3')) as (n1, n3): - self._set_net_external(n1['network']['id']) - self._set_net_external(n3['network']['id']) - with self.network(name='net2') as n2: - self._test_list_with_pagination( - 'network', (n1, n3), ('name', 'asc'), 1, 3, - query_params='router:external=True') - self._test_list_with_pagination( - 'network', (n2, ), ('name', 'asc'), 1, 2, - query_params='router:external=False') - - def test_get_network_succeeds_without_filter(self): - plugin = manager.NeutronManager.get_plugin() - ctx = context.Context(None, None, is_admin=True) - result = plugin.get_networks(ctx, filters=None) - self.assertEqual(result, []) - - def test_network_filter_hook_admin_context(self): - plugin = manager.NeutronManager.get_plugin() - ctx = context.Context(None, None, is_admin=True) - model = models_v2.Network - conditions = plugin._network_filter_hook(ctx, model, []) - self.assertEqual(conditions, []) - - def test_network_filter_hook_nonadmin_context(self): - plugin = manager.NeutronManager.get_plugin() - ctx = context.Context('edinson', 'cavani') - model = models_v2.Network - txt = "externalnetworks.network_id IS NOT NULL" - conditions = plugin._network_filter_hook(ctx, model, []) - self.assertEqual(conditions.__str__(), txt) - # Try to concatenate conditions - conditions = plugin._network_filter_hook(ctx, model, conditions) - self.assertEqual(conditions.__str__(), "%s OR %s" % (txt, txt)) - - def test_create_port_external_network_non_admin_fails(self): - with self.network(router__external=True) as ext_net: - with self.subnet(network=ext_net) as ext_subnet: - with testtools.ExpectedException( - exc.HTTPClientError) as ctx_manager: - with self.port(subnet=ext_subnet, - set_context='True', - tenant_id='noadmin'): - pass - self.assertEqual(ctx_manager.exception.code, 403) - - def test_create_port_external_network_admin_succeeds(self): - with self.network(router__external=True) as ext_net: - with self.subnet(network=ext_net) as ext_subnet: - with self.port(subnet=ext_subnet) as port: - self.assertEqual(port['port']['network_id'], - ext_net['network']['id']) - - def test_create_external_network_non_admin_fails(self): - with testtools.ExpectedException(exc.HTTPClientError) as ctx_manager: - with self.network(router__external=True, - set_context='True', - tenant_id='noadmin'): - pass - self.assertEqual(ctx_manager.exception.code, 403) - - def test_create_external_network_admin_succeeds(self): - with self.network(router__external=True) as ext_net: - self.assertEqual(ext_net['network'][external_net.EXTERNAL], - True) - - def test_delete_network_check_disassociated_floatingips(self): - with mock.patch.object(manager.NeutronManager, - 'get_service_plugins') as srv_plugins: - l3_mock = mock.Mock() - srv_plugins.return_value = {'L3_ROUTER_NAT': l3_mock} - with self.network(do_delete=False) as net: - req = self.new_delete_request('networks', net['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, exc.HTTPNoContent.code) - (l3_mock.delete_disassociated_floatingips - .assert_called_once_with(mock.ANY, net['network']['id'])) - - -class ExtNetDBTestCaseXML(ExtNetDBTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/test_extension_extradhcpopts.py b/neutron/tests/unit/test_extension_extradhcpopts.py deleted file mode 100644 index 8d0f1e26c..000000000 --- a/neutron/tests/unit/test_extension_extradhcpopts.py +++ /dev/null @@ -1,266 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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. -# -# @author: D.E. Kehn, dekehn@gmail.com -# - -import copy -import webob.exc - -from neutron.db import db_base_plugin_v2 -from neutron.db import extradhcpopt_db as edo_db -from neutron.extensions import extra_dhcp_opt as edo_ext -from neutron.openstack.common import log as logging -from neutron.tests.unit import test_db_plugin - -LOG = logging.getLogger(__name__) - -DB_PLUGIN_KLASS = ( - 'neutron.tests.unit.test_extension_extradhcpopts.ExtraDhcpOptTestPlugin') - - -class ExtraDhcpOptTestPlugin(db_base_plugin_v2.NeutronDbPluginV2, - edo_db.ExtraDhcpOptMixin): - """Test plugin that implements necessary calls on create/delete port for - associating ports with extra dhcp options. - """ - - supported_extension_aliases = ["extra_dhcp_opt"] - - def create_port(self, context, port): - with context.session.begin(subtransactions=True): - edos = port['port'].get(edo_ext.EXTRADHCPOPTS, []) - new_port = super(ExtraDhcpOptTestPlugin, self).create_port( - context, port) - self._process_port_create_extra_dhcp_opts(context, new_port, edos) - return new_port - - def update_port(self, context, id, port): - with context.session.begin(subtransactions=True): - rtn_port = super(ExtraDhcpOptTestPlugin, self).update_port( - context, id, port) - self._update_extra_dhcp_opts_on_port(context, id, port, rtn_port) - return rtn_port - - -class ExtraDhcpOptDBTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - - def setUp(self, plugin=DB_PLUGIN_KLASS): - super(ExtraDhcpOptDBTestCase, self).setUp(plugin=plugin) - - -class TestExtraDhcpOpt(ExtraDhcpOptDBTestCase): - def _check_opts(self, expected, returned): - self.assertEqual(len(expected), len(returned)) - for opt in returned: - name = opt['opt_name'] - for exp in expected: - if name == exp['opt_name']: - val = exp['opt_value'] - break - self.assertEqual(opt['opt_value'], val) - - def test_create_port_with_extradhcpopts(self): - opt_list = [{'opt_name': 'bootfile-name', - 'opt_value': 'pxelinux.0'}, - {'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}, - {'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}] - - params = {edo_ext.EXTRADHCPOPTS: opt_list, - 'arg_list': (edo_ext.EXTRADHCPOPTS,)} - - with self.port(**params) as port: - self._check_opts(opt_list, - port['port'][edo_ext.EXTRADHCPOPTS]) - - def test_create_port_with_none_extradhcpopts(self): - opt_list = [{'opt_name': 'bootfile-name', - 'opt_value': None}, - {'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}, - {'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}] - expected = [{'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}, - {'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}] - - params = {edo_ext.EXTRADHCPOPTS: opt_list, - 'arg_list': (edo_ext.EXTRADHCPOPTS,)} - - with self.port(**params) as port: - self._check_opts(expected, - port['port'][edo_ext.EXTRADHCPOPTS]) - - def test_update_port_with_extradhcpopts_with_same(self): - opt_list = [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0'}, - {'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}, - {'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}] - upd_opts = [{'opt_name': 'bootfile-name', 'opt_value': 'changeme.0'}] - expected_opts = opt_list[:] - for i in expected_opts: - if i['opt_name'] == upd_opts[0]['opt_name']: - i['opt_value'] = upd_opts[0]['opt_value'] - break - - params = {edo_ext.EXTRADHCPOPTS: opt_list, - 'arg_list': (edo_ext.EXTRADHCPOPTS,)} - - with self.port(**params) as port: - update_port = {'port': {edo_ext.EXTRADHCPOPTS: upd_opts}} - - req = self.new_update_request('ports', update_port, - port['port']['id']) - port = self.deserialize('json', req.get_response(self.api)) - self._check_opts(expected_opts, - port['port'][edo_ext.EXTRADHCPOPTS]) - - def test_update_port_with_additional_extradhcpopt(self): - opt_list = [{'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}, - {'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}] - upd_opts = [{'opt_name': 'bootfile-name', 'opt_value': 'changeme.0'}] - expected_opts = copy.deepcopy(opt_list) - expected_opts.append(upd_opts[0]) - params = {edo_ext.EXTRADHCPOPTS: opt_list, - 'arg_list': (edo_ext.EXTRADHCPOPTS,)} - - with self.port(**params) as port: - update_port = {'port': {edo_ext.EXTRADHCPOPTS: upd_opts}} - - req = self.new_update_request('ports', update_port, - port['port']['id']) - port = self.deserialize('json', req.get_response(self.api)) - self._check_opts(expected_opts, - port['port'][edo_ext.EXTRADHCPOPTS]) - - def test_update_port_with_extradhcpopts(self): - opt_list = [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0'}, - {'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}, - {'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}] - upd_opts = [{'opt_name': 'bootfile-name', 'opt_value': 'changeme.0'}] - expected_opts = copy.deepcopy(opt_list) - for i in expected_opts: - if i['opt_name'] == upd_opts[0]['opt_name']: - i['opt_value'] = upd_opts[0]['opt_value'] - break - - params = {edo_ext.EXTRADHCPOPTS: opt_list, - 'arg_list': (edo_ext.EXTRADHCPOPTS,)} - - with self.port(**params) as port: - update_port = {'port': {edo_ext.EXTRADHCPOPTS: upd_opts}} - - req = self.new_update_request('ports', update_port, - port['port']['id']) - port = self.deserialize('json', req.get_response(self.api)) - self._check_opts(expected_opts, - port['port'][edo_ext.EXTRADHCPOPTS]) - - def test_update_port_with_extradhcpopt_delete(self): - opt_list = [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0'}, - {'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}, - {'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}] - upd_opts = [{'opt_name': 'bootfile-name', 'opt_value': None}] - expected_opts = [] - - expected_opts = [opt for opt in opt_list - if opt['opt_name'] != 'bootfile-name'] - - params = {edo_ext.EXTRADHCPOPTS: opt_list, - 'arg_list': (edo_ext.EXTRADHCPOPTS,)} - - with self.port(**params) as port: - update_port = {'port': {edo_ext.EXTRADHCPOPTS: upd_opts}} - - req = self.new_update_request('ports', update_port, - port['port']['id']) - port = self.deserialize('json', req.get_response(self.api)) - self._check_opts(expected_opts, - port['port'][edo_ext.EXTRADHCPOPTS]) - - def test_update_port_without_extradhcpopt_delete(self): - upd_opts = [{'opt_name': 'bootfile-name', 'opt_value': None}] - - with self.port() as port: - update_port = {'port': {edo_ext.EXTRADHCPOPTS: upd_opts}} - - req = self.new_update_request('ports', update_port, - port['port']['id']) - port = self.deserialize('json', req.get_response(self.api)) - edo_attr = port['port'].get(edo_ext.EXTRADHCPOPTS) - self.assertEqual(edo_attr, []) - - def test_update_port_adding_extradhcpopts(self): - opt_list = [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0'}, - {'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}, - {'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}] - with self.port() as port: - update_port = {'port': {edo_ext.EXTRADHCPOPTS: opt_list}} - - req = self.new_update_request('ports', update_port, - port['port']['id']) - port = self.deserialize('json', req.get_response(self.api)) - self._check_opts(opt_list, - port['port'][edo_ext.EXTRADHCPOPTS]) - - def test_update_port_with_blank_string_extradhcpopt(self): - opt_list = [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0'}, - {'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}, - {'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}] - upd_opts = [{'opt_name': 'bootfile-name', 'opt_value': ' '}] - - params = {edo_ext.EXTRADHCPOPTS: opt_list, - 'arg_list': (edo_ext.EXTRADHCPOPTS,)} - - with self.port(**params) as port: - update_port = {'port': {edo_ext.EXTRADHCPOPTS: upd_opts}} - - req = self.new_update_request('ports', update_port, - port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_update_port_with_blank_name_extradhcpopt(self): - opt_list = [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0'}, - {'opt_name': 'tftp-server', - 'opt_value': '123.123.123.123'}, - {'opt_name': 'server-ip-address', - 'opt_value': '123.123.123.456'}] - upd_opts = [{'opt_name': ' ', 'opt_value': 'pxelinux.0'}] - - params = {edo_ext.EXTRADHCPOPTS: opt_list, - 'arg_list': (edo_ext.EXTRADHCPOPTS,)} - - with self.port(**params) as port: - update_port = {'port': {edo_ext.EXTRADHCPOPTS: upd_opts}} - - req = self.new_update_request('ports', update_port, - port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) diff --git a/neutron/tests/unit/test_extension_extraroute.py b/neutron/tests/unit/test_extension_extraroute.py deleted file mode 100644 index 826ca80a2..000000000 --- a/neutron/tests/unit/test_extension_extraroute.py +++ /dev/null @@ -1,500 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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 contextlib -from oslo.config import cfg -from webob import exc - -from neutron.common import constants -from neutron.db import extraroute_db -from neutron.extensions import extraroute -from neutron.extensions import l3 -from neutron.openstack.common import log as logging -from neutron.openstack.common import uuidutils -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_l3_plugin as test_l3 - - -LOG = logging.getLogger(__name__) - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path - - -class ExtraRouteTestExtensionManager(object): - - def get_resources(self): - l3.RESOURCE_ATTRIBUTE_MAP['routers'].update( - extraroute.EXTENDED_ATTRIBUTES_2_0['routers']) - return l3.L3.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -# This plugin class is for tests with plugin that integrates L3. -class TestExtraRouteIntPlugin(test_l3.TestL3NatIntPlugin, - extraroute_db.ExtraRoute_db_mixin): - supported_extension_aliases = ["external-net", "router", "extraroute"] - - -# A fake l3 service plugin class with extra route capability for -# plugins that delegate away L3 routing functionality -class TestExtraRouteL3NatServicePlugin(test_l3.TestL3NatServicePlugin, - extraroute_db.ExtraRoute_db_mixin): - supported_extension_aliases = ["router", "extraroute"] - - -class ExtraRouteDBTestCaseBase(object): - def _routes_update_prepare(self, router_id, subnet_id, - port_id, routes, skip_add=False): - if not skip_add: - self._router_interface_action('add', router_id, subnet_id, port_id) - self._update('routers', router_id, {'router': {'routes': routes}}) - return self._show('routers', router_id) - - def _routes_update_cleanup(self, port_id, subnet_id, router_id, routes): - self._update('routers', router_id, {'router': {'routes': routes}}) - self._router_interface_action('remove', router_id, subnet_id, port_id) - - def test_route_update_with_one_route(self): - routes = [{'destination': '135.207.0.0/16', 'nexthop': '10.0.1.3'}] - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - body = self._routes_update_prepare(r['router']['id'], - None, p['port']['id'], - routes) - self.assertEqual(body['router']['routes'], routes) - self._routes_update_cleanup(p['port']['id'], - None, r['router']['id'], []) - - def test_route_clear_routes_with_None(self): - routes = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}, - {'destination': '12.0.0.0/8', - 'nexthop': '10.0.1.4'}, - {'destination': '141.212.0.0/16', - 'nexthop': '10.0.1.5'}] - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - self._routes_update_prepare(r['router']['id'], - None, p['port']['id'], routes) - body = self._update('routers', r['router']['id'], - {'router': {'routes': None}}) - self.assertEqual(body['router']['routes'], []) - self._routes_update_cleanup(p['port']['id'], - None, r['router']['id'], []) - - def test_router_interface_in_use_by_route(self): - routes = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}] - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - body = self._routes_update_prepare(r['router']['id'], - None, p['port']['id'], - routes) - self.assertEqual(body['router']['routes'], routes) - self._router_interface_action( - 'remove', - r['router']['id'], - None, - p['port']['id'], - expected_code=exc.HTTPConflict.code) - - self._routes_update_cleanup(p['port']['id'], - None, r['router']['id'], []) - - def test_route_update_with_multi_routes(self): - routes = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}, - {'destination': '12.0.0.0/8', - 'nexthop': '10.0.1.4'}, - {'destination': '141.212.0.0/16', - 'nexthop': '10.0.1.5'}] - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - body = self._routes_update_prepare(r['router']['id'], - None, p['port']['id'], - routes) - self.assertEqual(sorted(body['router']['routes']), - sorted(routes)) - self._routes_update_cleanup(p['port']['id'], - None, r['router']['id'], []) - - def test_routes_update_for_multiple_routers(self): - routes1 = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.0.3'}] - routes2 = [{'destination': '12.0.0.0/8', - 'nexthop': '10.0.0.4'}] - with contextlib.nested( - self.router(), - self.router(), - self.subnet(cidr='10.0.0.0/24')) as (r1, r2, s): - with contextlib.nested( - self.port(subnet=s, no_delete=True), - self.port(subnet=s, no_delete=True)) as (p1, p2): - body = self._routes_update_prepare(r1['router']['id'], - None, p1['port']['id'], - routes1) - self.assertEqual(body['router']['routes'], routes1) - - body = self._routes_update_prepare(r2['router']['id'], - None, p2['port']['id'], - routes2) - self.assertEqual(body['router']['routes'], routes2) - - self._routes_update_cleanup(p1['port']['id'], - None, r1['router']['id'], []) - self._routes_update_cleanup(p2['port']['id'], - None, r2['router']['id'], []) - - def test_router_update_delete_routes(self): - routes_orig = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}, - {'destination': '12.0.0.0/8', - 'nexthop': '10.0.1.4'}, - {'destination': '141.212.0.0/16', - 'nexthop': '10.0.1.5'}] - routes_left = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}, - {'destination': '141.212.0.0/16', - 'nexthop': '10.0.1.5'}] - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - body = self._routes_update_prepare(r['router']['id'], - None, p['port']['id'], - routes_orig) - self.assertEqual(sorted(body['router']['routes']), - sorted(routes_orig)) - body = self._routes_update_prepare(r['router']['id'], - None, p['port']['id'], - routes_left, - skip_add=True) - self.assertEqual(sorted(body['router']['routes']), - sorted(routes_left)) - self._routes_update_cleanup(p['port']['id'], - None, r['router']['id'], []) - - def _test_malformed_route(self, routes): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - - self._update('routers', r['router']['id'], - {'router': {'routes': routes}}, - expected_code=exc.HTTPBadRequest.code) - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_no_destination_route(self): - self._test_malformed_route([{'nexthop': '10.0.1.6'}]) - - def test_no_nexthop_route(self): - self._test_malformed_route({'destination': '135.207.0.0/16'}) - - def test_none_destination(self): - self._test_malformed_route([{'destination': None, - 'nexthop': '10.0.1.3'}]) - - def test_none_nexthop(self): - self._test_malformed_route([{'destination': '135.207.0.0/16', - 'nexthop': None}]) - - def test_nexthop_is_port_ip(self): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - port_ip = p['port']['fixed_ips'][0]['ip_address'] - routes = [{'destination': '135.207.0.0/16', - 'nexthop': port_ip}] - - self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}, - expected_code=exc.HTTPBadRequest.code) - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_update_with_too_many_routes(self): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - - routes = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}, - {'destination': '12.0.0.0/8', - 'nexthop': '10.0.1.4'}, - {'destination': '141.212.0.0/16', - 'nexthop': '10.0.1.5'}, - {'destination': '192.168.0.0/16', - 'nexthop': '10.0.1.6'}] - - self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}, - expected_code=exc.HTTPBadRequest.code) - - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_update_with_dup_address(self): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - - routes = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}, - {'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}] - - self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}, - expected_code=exc.HTTPBadRequest.code) - - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_update_with_invalid_ip_address(self): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - - routes = [{'destination': '512.207.0.0/16', - 'nexthop': '10.0.1.3'}] - - self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}, - expected_code=exc.HTTPBadRequest.code) - - routes = [{'destination': '127.207.0.0/48', - 'nexthop': '10.0.1.3'}] - - self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}, - expected_code=exc.HTTPBadRequest.code) - - routes = [{'destination': 'invalid_ip_address', - 'nexthop': '10.0.1.3'}] - - self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}, - expected_code=exc.HTTPBadRequest.code) - - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_update_with_invalid_nexthop_ip(self): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - - routes = [{'destination': '127.207.0.0/16', - 'nexthop': ' 300.10.10.4'}] - - self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}, - expected_code=exc.HTTPBadRequest.code) - - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_update_with_nexthop_is_outside_port_subnet(self): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - with self.port(subnet=s, no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - - routes = [{'destination': '127.207.0.0/16', - 'nexthop': ' 20.10.10.4'}] - - self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}, - expected_code=exc.HTTPBadRequest.code) - - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_update_on_external_port(self): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s: - self._set_net_external(s['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - net_id = body['router']['external_gateway_info']['network_id'] - self.assertEqual(net_id, s['subnet']['network_id']) - port_res = self._list_ports( - 'json', - 200, - s['subnet']['network_id'], - tenant_id=r['router']['tenant_id'], - device_own=constants.DEVICE_OWNER_ROUTER_GW) - port_list = self.deserialize('json', port_res) - self.assertEqual(len(port_list['ports']), 1) - - routes = [{'destination': '135.207.0.0/16', - 'nexthop': '10.0.1.3'}] - - body = self._update('routers', r['router']['id'], - {'router': {'routes': - routes}}) - - body = self._show('routers', r['router']['id']) - self.assertEqual(body['router']['routes'], - routes) - - self._remove_external_gateway_from_router( - r['router']['id'], - s['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - gw_info = body['router']['external_gateway_info'] - self.assertIsNone(gw_info) - - def test_router_list_with_sort(self): - with contextlib.nested(self.router(name='router1'), - self.router(name='router2'), - self.router(name='router3') - ) as (router1, router2, router3): - self._test_list_with_sort('router', (router3, router2, router1), - [('name', 'desc')]) - - def test_router_list_with_pagination(self): - with contextlib.nested(self.router(name='router1'), - self.router(name='router2'), - self.router(name='router3') - ) as (router1, router2, router3): - self._test_list_with_pagination('router', - (router1, router2, router3), - ('name', 'asc'), 2, 2) - - def test_router_list_with_pagination_reverse(self): - with contextlib.nested(self.router(name='router1'), - self.router(name='router2'), - self.router(name='router3') - ) as (router1, router2, router3): - self._test_list_with_pagination_reverse('router', - (router1, router2, - router3), - ('name', 'asc'), 2, 2) - - -class ExtraRouteDBIntTestCase(test_l3.L3NatDBIntTestCase, - ExtraRouteDBTestCaseBase): - - def setUp(self, plugin=None, ext_mgr=None): - if not plugin: - plugin = ('neutron.tests.unit.test_extension_extraroute.' - 'TestExtraRouteIntPlugin') - # for these tests we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - cfg.CONF.set_default('max_routes', 3) - ext_mgr = ExtraRouteTestExtensionManager() - super(test_l3.L3BaseForIntTests, self).setUp(plugin=plugin, - ext_mgr=ext_mgr) - self.setup_notification_driver() - - -class ExtraRouteDBIntTestCaseXML(ExtraRouteDBIntTestCase): - fmt = 'xml' - - -class ExtraRouteDBSepTestCase(test_l3.L3NatDBSepTestCase, - ExtraRouteDBTestCaseBase): - def setUp(self): - # the plugin without L3 support - plugin = 'neutron.tests.unit.test_l3_plugin.TestNoL3NatPlugin' - # the L3 service plugin - l3_plugin = ('neutron.tests.unit.test_extension_extraroute.' - 'TestExtraRouteL3NatServicePlugin') - service_plugins = {'l3_plugin_name': l3_plugin} - - # for these tests we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - cfg.CONF.set_default('max_routes', 3) - ext_mgr = ExtraRouteTestExtensionManager() - super(test_l3.L3BaseForSepTests, self).setUp( - plugin=plugin, ext_mgr=ext_mgr, - service_plugins=service_plugins) - - self.setup_notification_driver() - - -class ExtraRouteDBSepTestCaseXML(ExtraRouteDBSepTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/test_extension_firewall.py b/neutron/tests/unit/test_extension_firewall.py deleted file mode 100644 index 62f2fec79..000000000 --- a/neutron/tests/unit/test_extension_firewall.py +++ /dev/null @@ -1,495 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 Big Switch Networks, Inc. -# All Rights Reserved. -# -# 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. - -# @author: Sumit Naiksatam, sumitnaiksatam@gmail.com, Big Switch Networks, Inc. - -import copy - -import mock -from webob import exc -import webtest - -from neutron.extensions import firewall -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants -from neutron.tests import base -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_api_v2_extension - - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path - - -class FirewallExtensionTestCase(test_api_v2_extension.ExtensionTestCase): - fmt = 'json' - - def setUp(self): - super(FirewallExtensionTestCase, self).setUp() - plural_mappings = {'firewall_policy': 'firewall_policies'} - self._setUpExtension( - 'neutron.extensions.firewall.FirewallPluginBase', - constants.FIREWALL, firewall.RESOURCE_ATTRIBUTE_MAP, - firewall.Firewall, 'fw', plural_mappings=plural_mappings) - - def test_create_firewall(self): - fw_id = _uuid() - data = {'firewall': {'description': 'descr_firewall1', - 'name': 'firewall1', - 'admin_state_up': True, - 'firewall_policy_id': _uuid(), - 'shared': False, - 'tenant_id': _uuid()}} - return_value = copy.copy(data['firewall']) - return_value.update({'id': fw_id}) - # since 'shared' is hidden - del return_value['shared'] - - instance = self.plugin.return_value - instance.create_firewall.return_value = return_value - res = self.api.post(_get_path('fw/firewalls', fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_firewall.assert_called_with(mock.ANY, - firewall=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('firewall', res) - self.assertEqual(res['firewall'], return_value) - - def test_firewall_list(self): - fw_id = _uuid() - return_value = [{'tenant_id': _uuid(), - 'id': fw_id}] - - instance = self.plugin.return_value - instance.get_firewalls.return_value = return_value - - res = self.api.get(_get_path('fw/firewalls', fmt=self.fmt)) - - instance.get_firewalls.assert_called_with(mock.ANY, - fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_firewall_get(self): - fw_id = _uuid() - return_value = {'tenant_id': _uuid(), - 'id': fw_id} - - instance = self.plugin.return_value - instance.get_firewall.return_value = return_value - - res = self.api.get(_get_path('fw/firewalls', - id=fw_id, fmt=self.fmt)) - - instance.get_firewall.assert_called_with(mock.ANY, - fw_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('firewall', res) - self.assertEqual(res['firewall'], return_value) - - def test_firewall_update(self): - fw_id = _uuid() - update_data = {'firewall': {'name': 'new_name'}} - return_value = {'tenant_id': _uuid(), - 'id': fw_id} - - instance = self.plugin.return_value - instance.update_firewall.return_value = return_value - - res = self.api.put(_get_path('fw/firewalls', id=fw_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_firewall.assert_called_with(mock.ANY, fw_id, - firewall=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('firewall', res) - self.assertEqual(res['firewall'], return_value) - - def test_firewall_delete(self): - self._test_entity_delete('firewall') - - def _test_create_firewall_rule(self, src_port, dst_port): - rule_id = _uuid() - data = {'firewall_rule': {'description': 'descr_firewall_rule1', - 'name': 'rule1', - 'shared': False, - 'protocol': 'tcp', - 'ip_version': 4, - 'source_ip_address': '192.168.0.1', - 'destination_ip_address': '127.0.0.1', - 'source_port': src_port, - 'destination_port': dst_port, - 'action': 'allow', - 'enabled': True, - 'tenant_id': _uuid()}} - expected_ret_val = copy.copy(data['firewall_rule']) - expected_ret_val['source_port'] = str(src_port) - expected_ret_val['destination_port'] = str(dst_port) - expected_call_args = copy.copy(expected_ret_val) - expected_ret_val['id'] = rule_id - instance = self.plugin.return_value - instance.create_firewall_rule.return_value = expected_ret_val - res = self.api.post(_get_path('fw/firewall_rules', fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_firewall_rule.assert_called_with(mock.ANY, - firewall_rule= - {'firewall_rule': - expected_call_args}) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('firewall_rule', res) - self.assertEqual(res['firewall_rule'], expected_ret_val) - - def test_create_firewall_rule_with_integer_ports(self): - self._test_create_firewall_rule(1, 10) - - def test_create_firewall_rule_with_string_ports(self): - self._test_create_firewall_rule('1', '10') - - def test_create_firewall_rule_with_port_range(self): - self._test_create_firewall_rule('1:20', '30:40') - - def test_firewall_rule_list(self): - rule_id = _uuid() - return_value = [{'tenant_id': _uuid(), - 'id': rule_id}] - - instance = self.plugin.return_value - instance.get_firewall_rules.return_value = return_value - - res = self.api.get(_get_path('fw/firewall_rules', fmt=self.fmt)) - - instance.get_firewall_rules.assert_called_with(mock.ANY, - fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_firewall_rule_get(self): - rule_id = _uuid() - return_value = {'tenant_id': _uuid(), - 'id': rule_id} - - instance = self.plugin.return_value - instance.get_firewall_rule.return_value = return_value - - res = self.api.get(_get_path('fw/firewall_rules', - id=rule_id, fmt=self.fmt)) - - instance.get_firewall_rule.assert_called_with(mock.ANY, - rule_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('firewall_rule', res) - self.assertEqual(res['firewall_rule'], return_value) - - def test_firewall_rule_update(self): - rule_id = _uuid() - update_data = {'firewall_rule': {'action': 'deny'}} - return_value = {'tenant_id': _uuid(), - 'id': rule_id} - - instance = self.plugin.return_value - instance.update_firewall_rule.return_value = return_value - - res = self.api.put(_get_path('fw/firewall_rules', id=rule_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_firewall_rule.assert_called_with(mock.ANY, - rule_id, - firewall_rule= - update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('firewall_rule', res) - self.assertEqual(res['firewall_rule'], return_value) - - def test_firewall_rule_delete(self): - self._test_entity_delete('firewall_rule') - - def test_create_firewall_policy(self): - policy_id = _uuid() - data = {'firewall_policy': {'description': 'descr_firewall_policy1', - 'name': 'new_fw_policy1', - 'shared': False, - 'firewall_rules': [_uuid(), _uuid()], - 'audited': False, - 'tenant_id': _uuid()}} - return_value = copy.copy(data['firewall_policy']) - return_value.update({'id': policy_id}) - - instance = self.plugin.return_value - instance.create_firewall_policy.return_value = return_value - res = self.api.post(_get_path('fw/firewall_policies', - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_firewall_policy.assert_called_with(mock.ANY, - firewall_policy= - data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('firewall_policy', res) - self.assertEqual(res['firewall_policy'], return_value) - - def test_firewall_policy_list(self): - policy_id = _uuid() - return_value = [{'tenant_id': _uuid(), - 'id': policy_id}] - - instance = self.plugin.return_value - instance.get_firewall_policies.return_value = return_value - - res = self.api.get(_get_path('fw/firewall_policies', - fmt=self.fmt)) - - instance.get_firewall_policies.assert_called_with(mock.ANY, - fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_firewall_policy_get(self): - policy_id = _uuid() - return_value = {'tenant_id': _uuid(), - 'id': policy_id} - - instance = self.plugin.return_value - instance.get_firewall_policy.return_value = return_value - - res = self.api.get(_get_path('fw/firewall_policies', - id=policy_id, fmt=self.fmt)) - - instance.get_firewall_policy.assert_called_with(mock.ANY, - policy_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('firewall_policy', res) - self.assertEqual(res['firewall_policy'], return_value) - - def test_firewall_policy_update(self): - policy_id = _uuid() - update_data = {'firewall_policy': {'audited': True}} - return_value = {'tenant_id': _uuid(), - 'id': policy_id} - - instance = self.plugin.return_value - instance.update_firewall_policy.return_value = return_value - - res = self.api.put(_get_path('fw/firewall_policies', - id=policy_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_firewall_policy.assert_called_with(mock.ANY, - policy_id, - firewall_policy= - update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('firewall_policy', res) - self.assertEqual(res['firewall_policy'], return_value) - - def test_firewall_policy_update_malformed_rules(self): - # emulating client request when no rule uuids are provided for - # --firewall_rules parameter - update_data = {'firewall_policy': {'firewall_rules': True}} - # have to check for generic AppError - self.assertRaises( - webtest.AppError, - self.api.put, - _get_path('fw/firewall_policies', id=_uuid(), fmt=self.fmt), - self.serialize(update_data)) - - def test_firewall_policy_delete(self): - self._test_entity_delete('firewall_policy') - - def test_firewall_policy_insert_rule(self): - firewall_policy_id = _uuid() - firewall_rule_id = _uuid() - ref_firewall_rule_id = _uuid() - - insert_data = {'firewall_rule_id': firewall_rule_id, - 'insert_before': ref_firewall_rule_id, - 'insert_after': None} - return_value = {'firewall_policy': - {'tenant_id': _uuid(), - 'id': firewall_policy_id, - 'firewall_rules': [ref_firewall_rule_id, - firewall_rule_id]}} - - instance = self.plugin.return_value - instance.insert_rule.return_value = return_value - - path = _get_path('fw/firewall_policies', id=firewall_policy_id, - action="insert_rule", - fmt=self.fmt) - res = self.api.put(path, self.serialize(insert_data)) - instance.insert_rule.assert_called_with(mock.ANY, firewall_policy_id, - insert_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertEqual(res, return_value) - - def test_firewall_policy_remove_rule(self): - firewall_policy_id = _uuid() - firewall_rule_id = _uuid() - - remove_data = {'firewall_rule_id': firewall_rule_id} - return_value = {'firewall_policy': - {'tenant_id': _uuid(), - 'id': firewall_policy_id, - 'firewall_rules': []}} - - instance = self.plugin.return_value - instance.remove_rule.return_value = return_value - - path = _get_path('fw/firewall_policies', id=firewall_policy_id, - action="remove_rule", - fmt=self.fmt) - res = self.api.put(path, self.serialize(remove_data)) - instance.remove_rule.assert_called_with(mock.ANY, firewall_policy_id, - remove_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertEqual(res, return_value) - - -class FirewallExtensionTestCaseXML(FirewallExtensionTestCase): - fmt = 'xml' - - -class TestFirewallAttributeValidators(base.BaseTestCase): - - def test_validate_port_range(self): - msg = firewall._validate_port_range(None) - self.assertIsNone(msg) - - msg = firewall._validate_port_range('10') - self.assertIsNone(msg) - - msg = firewall._validate_port_range(10) - self.assertIsNone(msg) - - msg = firewall._validate_port_range(-1) - self.assertEqual(msg, "Invalid port '-1'") - - msg = firewall._validate_port_range('66000') - self.assertEqual(msg, "Invalid port '66000'") - - msg = firewall._validate_port_range('10:20') - self.assertIsNone(msg) - - msg = firewall._validate_port_range('1:65535') - self.assertIsNone(msg) - - msg = firewall._validate_port_range('0:65535') - self.assertEqual(msg, "Invalid port '0'") - - msg = firewall._validate_port_range('1:65536') - self.assertEqual(msg, "Invalid port '65536'") - - msg = firewall._validate_port_range('abc:efg') - self.assertEqual(msg, "Port 'abc' is not a valid number") - - msg = firewall._validate_port_range('1:efg') - self.assertEqual(msg, "Port 'efg' is not a valid number") - - msg = firewall._validate_port_range('-1:10') - self.assertEqual(msg, "Invalid port '-1'") - - msg = firewall._validate_port_range('66000:10') - self.assertEqual(msg, "Invalid port '66000'") - - msg = firewall._validate_port_range('10:66000') - self.assertEqual(msg, "Invalid port '66000'") - - msg = firewall._validate_port_range('1:-10') - self.assertEqual(msg, "Invalid port '-10'") - - def test_validate_ip_or_subnet_or_none(self): - msg = firewall._validate_ip_or_subnet_or_none(None) - self.assertIsNone(msg) - - msg = firewall._validate_ip_or_subnet_or_none('1.1.1.1') - self.assertIsNone(msg) - - msg = firewall._validate_ip_or_subnet_or_none('1.1.1.0/24') - self.assertIsNone(msg) - - ip_addr = '1111.1.1.1' - msg = firewall._validate_ip_or_subnet_or_none(ip_addr) - self.assertEqual(msg, ("'%s' is not a valid IP address and " - "'%s' is not a valid IP subnet") % (ip_addr, - ip_addr)) - - ip_addr = '1.1.1.1 has whitespace' - msg = firewall._validate_ip_or_subnet_or_none(ip_addr) - self.assertEqual(msg, ("'%s' is not a valid IP address and " - "'%s' is not a valid IP subnet") % (ip_addr, - ip_addr)) - - ip_addr = '111.1.1.1\twhitespace' - msg = firewall._validate_ip_or_subnet_or_none(ip_addr) - self.assertEqual(msg, ("'%s' is not a valid IP address and " - "'%s' is not a valid IP subnet") % (ip_addr, - ip_addr)) - - ip_addr = '111.1.1.1\nwhitespace' - msg = firewall._validate_ip_or_subnet_or_none(ip_addr) - self.assertEqual(msg, ("'%s' is not a valid IP address and " - "'%s' is not a valid IP subnet") % (ip_addr, - ip_addr)) - - # Valid - IPv4 - cidr = "10.0.2.0/24" - msg = firewall._validate_ip_or_subnet_or_none(cidr, None) - self.assertIsNone(msg) - - # Valid - IPv6 without final octets - cidr = "fe80::/24" - msg = firewall._validate_ip_or_subnet_or_none(cidr, None) - self.assertIsNone(msg) - - # Valid - IPv6 with final octets - cidr = "fe80::0/24" - msg = firewall._validate_ip_or_subnet_or_none(cidr, None) - self.assertIsNone(msg) - - cidr = "fe80::" - msg = firewall._validate_ip_or_subnet_or_none(cidr, None) - self.assertIsNone(msg) - - # Invalid - IPv6 with final octets, missing mask - cidr = "fe80::0" - msg = firewall._validate_ip_or_subnet_or_none(cidr, None) - self.assertIsNone(msg) - - # Invalid - Address format error - cidr = 'invalid' - msg = firewall._validate_ip_or_subnet_or_none(cidr, None) - self.assertEqual(msg, ("'%s' is not a valid IP address and " - "'%s' is not a valid IP subnet") % (cidr, - cidr)) diff --git a/neutron/tests/unit/test_extension_pnet.py b/neutron/tests/unit/test_extension_pnet.py deleted file mode 100644 index fa88bbf33..000000000 --- a/neutron/tests/unit/test_extension_pnet.py +++ /dev/null @@ -1,161 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 VMware -# All rights reserved. -# -# 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. -# -# @author: Salvatore Orlando, VMware -# - -import mock -from oslo.config import cfg -from webob import exc as web_exc -import webtest - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.api.v2 import router -from neutron import context -from neutron.extensions import providernet as pnet -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron import quota -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_extensions -from neutron.tests.unit import testlib_api - - -class ProviderExtensionManager(object): - - def get_resources(self): - return [] - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - def get_extended_resources(self, version): - return pnet.get_extended_resources(version) - - -class ProvidernetExtensionTestCase(testlib_api.WebTestCase): - fmt = 'json' - - def setUp(self): - super(ProvidernetExtensionTestCase, self).setUp() - - plugin = 'neutron.neutron_plugin_base_v2.NeutronPluginBaseV2' - - # Ensure existing ExtensionManager is not used - extensions.PluginAwareExtensionManager._instance = None - - # Save the global RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - - # Update the plugin and extensions path - self.setup_coreplugin(plugin) - cfg.CONF.set_override('allow_pagination', True) - cfg.CONF.set_override('allow_sorting', True) - self._plugin_patcher = mock.patch(plugin, autospec=True) - self.plugin = self._plugin_patcher.start() - # Ensure Quota checks never fail because of mock - instance = self.plugin.return_value - instance.get_networks_count.return_value = 1 - # Instantiate mock plugin and enable the 'provider' extension - manager.NeutronManager.get_plugin().supported_extension_aliases = ( - ["provider"]) - ext_mgr = ProviderExtensionManager() - self.ext_mdw = test_extensions.setup_extensions_middleware(ext_mgr) - self.addCleanup(self._plugin_patcher.stop) - self.addCleanup(self._restore_attribute_map) - self.api = webtest.TestApp(router.APIRouter()) - - quota.QUOTAS._driver = None - cfg.CONF.set_override('quota_driver', 'neutron.quota.ConfDriver', - group='QUOTAS') - - def _restore_attribute_map(self): - # Restore the global RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - - def _prepare_net_data(self): - return {'name': 'net1', - pnet.NETWORK_TYPE: 'sometype', - pnet.PHYSICAL_NETWORK: 'physnet', - pnet.SEGMENTATION_ID: 666} - - def _put_network_with_provider_attrs(self, ctx, expect_errors=False): - data = self._prepare_net_data() - env = {'neutron.context': ctx} - instance = self.plugin.return_value - instance.get_network.return_value = {'tenant_id': ctx.tenant_id, - 'shared': False} - net_id = uuidutils.generate_uuid() - res = self.api.put(test_api_v2._get_path('networks', - id=net_id, - fmt=self.fmt), - self.serialize({'network': data}), - extra_environ=env, - expect_errors=expect_errors) - return res, data, net_id - - def _post_network_with_provider_attrs(self, ctx, expect_errors=False): - data = self._prepare_net_data() - env = {'neutron.context': ctx} - res = self.api.post(test_api_v2._get_path('networks', fmt=self.fmt), - self.serialize({'network': data}), - content_type='application/' + self.fmt, - extra_environ=env, - expect_errors=expect_errors) - return res, data - - def test_network_create_with_provider_attrs(self): - ctx = context.get_admin_context() - ctx.tenant_id = 'an_admin' - res, data = self._post_network_with_provider_attrs(ctx) - instance = self.plugin.return_value - exp_input = {'network': data} - exp_input['network'].update({'admin_state_up': True, - 'tenant_id': 'an_admin', - 'shared': False}) - instance.create_network.assert_called_with(mock.ANY, - network=exp_input) - self.assertEqual(res.status_int, web_exc.HTTPCreated.code) - - def test_network_update_with_provider_attrs(self): - ctx = context.get_admin_context() - ctx.tenant_id = 'an_admin' - res, data, net_id = self._put_network_with_provider_attrs(ctx) - instance = self.plugin.return_value - exp_input = {'network': data} - instance.update_network.assert_called_with(mock.ANY, - net_id, - network=exp_input) - self.assertEqual(res.status_int, web_exc.HTTPOk.code) - - def test_network_create_with_provider_attrs_noadmin_returns_403(self): - tenant_id = 'no_admin' - ctx = context.Context('', tenant_id, is_admin=False) - res, _1 = self._post_network_with_provider_attrs(ctx, True) - self.assertEqual(res.status_int, web_exc.HTTPForbidden.code) - - def test_network_update_with_provider_attrs_noadmin_returns_404(self): - tenant_id = 'no_admin' - ctx = context.Context('', tenant_id, is_admin=False) - res, _1, _2 = self._put_network_with_provider_attrs(ctx, True) - self.assertEqual(res.status_int, web_exc.HTTPNotFound.code) diff --git a/neutron/tests/unit/test_extension_portsecurity.py b/neutron/tests/unit/test_extension_portsecurity.py deleted file mode 100644 index b40166f71..000000000 --- a/neutron/tests/unit/test_extension_portsecurity.py +++ /dev/null @@ -1,392 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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. - - -from neutron.api.v2 import attributes as attr -from neutron import context -from neutron.db import db_base_plugin_v2 -from neutron.db import portsecurity_db -from neutron.db import securitygroups_db -from neutron.extensions import portsecurity as psec -from neutron.extensions import securitygroup as ext_sg -from neutron import manager -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import test_extension_security_group - -DB_PLUGIN_KLASS = ('neutron.tests.unit.test_extension_portsecurity.' - 'PortSecurityTestPlugin') - - -class PortSecurityTestCase( - test_extension_security_group.SecurityGroupsTestCase, - test_db_plugin.NeutronDbPluginV2TestCase): - - def setUp(self, plugin=None): - ext_mgr = ( - test_extension_security_group.SecurityGroupTestExtensionManager()) - super(PortSecurityTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr) - - # Check if a plugin supports security groups - plugin_obj = manager.NeutronManager.get_plugin() - self._skip_security_group = ('security-group' not in - plugin_obj.supported_extension_aliases) - - def tearDown(self): - super(PortSecurityTestCase, self).tearDown() - self._skip_security_group = None - - -class PortSecurityTestPlugin(db_base_plugin_v2.NeutronDbPluginV2, - securitygroups_db.SecurityGroupDbMixin, - portsecurity_db.PortSecurityDbMixin): - - """Test plugin that implements necessary calls on create/delete port for - associating ports with security groups and port security. - """ - - supported_extension_aliases = ["security-group", "port-security"] - - def create_network(self, context, network): - tenant_id = self._get_tenant_id_for_create(context, network['network']) - self._ensure_default_security_group(context, tenant_id) - with context.session.begin(subtransactions=True): - neutron_db = super(PortSecurityTestPlugin, self).create_network( - context, network) - neutron_db.update(network['network']) - self._process_network_port_security_create( - context, network['network'], neutron_db) - return neutron_db - - def update_network(self, context, id, network): - with context.session.begin(subtransactions=True): - neutron_db = super(PortSecurityTestPlugin, self).update_network( - context, id, network) - if psec.PORTSECURITY in network['network']: - self._process_network_port_security_update( - context, network['network'], neutron_db) - return neutron_db - - def get_network(self, context, id, fields=None): - with context.session.begin(subtransactions=True): - net = super(PortSecurityTestPlugin, self).get_network( - context, id) - return self._fields(net, fields) - - def create_port(self, context, port): - p = port['port'] - with context.session.begin(subtransactions=True): - p[ext_sg.SECURITYGROUPS] = self._get_security_groups_on_port( - context, port) - neutron_db = super(PortSecurityTestPlugin, self).create_port( - context, port) - p.update(neutron_db) - - (port_security, has_ip) = self._determine_port_security_and_has_ip( - context, p) - p[psec.PORTSECURITY] = port_security - self._process_port_port_security_create(context, p, neutron_db) - - if (attr.is_attr_set(p.get(ext_sg.SECURITYGROUPS)) and - not (port_security and has_ip)): - raise psec.PortSecurityAndIPRequiredForSecurityGroups() - - # Port requires ip and port_security enabled for security group - if has_ip and port_security: - self._ensure_default_security_group_on_port(context, port) - - if (p.get(ext_sg.SECURITYGROUPS) and p[psec.PORTSECURITY]): - self._process_port_create_security_group( - context, p, p[ext_sg.SECURITYGROUPS]) - - return port['port'] - - def update_port(self, context, id, port): - delete_security_groups = self._check_update_deletes_security_groups( - port) - has_security_groups = self._check_update_has_security_groups(port) - with context.session.begin(subtransactions=True): - ret_port = super(PortSecurityTestPlugin, self).update_port( - context, id, port) - # copy values over - but not fixed_ips - port['port'].pop('fixed_ips', None) - ret_port.update(port['port']) - - # populate port_security setting - if psec.PORTSECURITY not in ret_port: - ret_port[psec.PORTSECURITY] = self._get_port_security_binding( - context, id) - has_ip = self._ip_on_port(ret_port) - # checks if security groups were updated adding/modifying - # security groups, port security is set and port has ip - if (has_security_groups and (not ret_port[psec.PORTSECURITY] - or not has_ip)): - raise psec.PortSecurityAndIPRequiredForSecurityGroups() - - # Port security/IP was updated off. Need to check that no security - # groups are on port. - if ret_port[psec.PORTSECURITY] is not True or not has_ip: - if has_security_groups: - raise psec.PortSecurityAndIPRequiredForSecurityGroups() - - # get security groups on port - filters = {'port_id': [id]} - security_groups = (super(PortSecurityTestPlugin, self). - _get_port_security_group_bindings( - context, filters)) - if security_groups and not delete_security_groups: - raise psec.PortSecurityPortHasSecurityGroup() - - if (delete_security_groups or has_security_groups): - # delete the port binding and read it with the new rules. - self._delete_port_security_group_bindings(context, id) - sgids = self._get_security_groups_on_port(context, port) - # process port create sec groups needs port id - port['id'] = id - self._process_port_create_security_group(context, - ret_port, sgids) - - if psec.PORTSECURITY in port['port']: - self._process_port_port_security_update( - context, port['port'], ret_port) - - return ret_port - - -class PortSecurityDBTestCase(PortSecurityTestCase): - def setUp(self, plugin=None): - plugin = plugin or DB_PLUGIN_KLASS - super(PortSecurityDBTestCase, self).setUp(plugin) - - -class TestPortSecurity(PortSecurityDBTestCase): - def test_create_network_with_portsecurity_mac(self): - res = self._create_network('json', 'net1', True) - net = self.deserialize('json', res) - self.assertEqual(net['network'][psec.PORTSECURITY], True) - - def test_create_network_with_portsecurity_false(self): - res = self._create_network('json', 'net1', True, - arg_list=('port_security_enabled',), - port_security_enabled=False) - net = self.deserialize('json', res) - self.assertEqual(net['network'][psec.PORTSECURITY], False) - - def test_updating_network_port_security(self): - res = self._create_network('json', 'net1', True, - port_security_enabled='True') - net = self.deserialize('json', res) - self.assertEqual(net['network'][psec.PORTSECURITY], True) - update_net = {'network': {psec.PORTSECURITY: False}} - req = self.new_update_request('networks', update_net, - net['network']['id']) - net = self.deserialize('json', req.get_response(self.api)) - self.assertEqual(net['network'][psec.PORTSECURITY], False) - req = self.new_show_request('networks', net['network']['id']) - net = self.deserialize('json', req.get_response(self.api)) - self.assertEqual(net['network'][psec.PORTSECURITY], False) - - def test_create_port_default_true(self): - with self.network() as net: - res = self._create_port('json', net['network']['id']) - port = self.deserialize('json', res) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - self._delete('ports', port['port']['id']) - - def test_create_port_passing_true(self): - res = self._create_network('json', 'net1', True, - arg_list=('port_security_enabled',), - port_security_enabled=True) - net = self.deserialize('json', res) - res = self._create_port('json', net['network']['id']) - port = self.deserialize('json', res) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - self._delete('ports', port['port']['id']) - - def test_create_port_on_port_security_false_network(self): - res = self._create_network('json', 'net1', True, - arg_list=('port_security_enabled',), - port_security_enabled=False) - net = self.deserialize('json', res) - res = self._create_port('json', net['network']['id']) - port = self.deserialize('json', res) - self.assertEqual(port['port'][psec.PORTSECURITY], False) - self._delete('ports', port['port']['id']) - - def test_create_port_security_overrides_network_value(self): - res = self._create_network('json', 'net1', True, - arg_list=('port_security_enabled',), - port_security_enabled=False) - net = self.deserialize('json', res) - res = self._create_port('json', net['network']['id'], - arg_list=('port_security_enabled',), - port_security_enabled=True) - port = self.deserialize('json', res) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - self._delete('ports', port['port']['id']) - - def test_create_port_fails_with_secgroup_and_port_security_false(self): - if self._skip_security_group: - self.skipTest("Plugin does not support security groups") - with self.network() as net: - with self.subnet(network=net): - security_group = self.deserialize( - 'json', - self._create_security_group(self.fmt, 'asdf', 'asdf')) - security_group_id = security_group['security_group']['id'] - res = self._create_port('json', net['network']['id'], - arg_list=('security_groups', - 'port_security_enabled'), - security_groups=[security_group_id], - port_security_enabled=False) - self.assertEqual(res.status_int, 400) - - def test_create_port_with_default_security_group(self): - if self._skip_security_group: - self.skipTest("Plugin does not support security groups") - with self.network() as net: - with self.subnet(network=net): - res = self._create_port('json', net['network']['id']) - port = self.deserialize('json', res) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - self.assertEqual(len(port['port'][ext_sg.SECURITYGROUPS]), 1) - self._delete('ports', port['port']['id']) - - def test_create_port_with_security_group_and_net_sec_false(self): - # This tests that port_security_enabled is true when creating - # a port on a network that is marked as port_security_enabled=False - # that has a subnet and securiy_groups are passed it. - if self._skip_security_group: - self.skipTest("Plugin does not support security groups") - res = self._create_network('json', 'net1', True, - arg_list=('port_security_enabled',), - port_security_enabled=False) - net = self.deserialize('json', res) - self._create_subnet('json', net['network']['id'], '10.0.0.0/24') - security_group = self.deserialize( - 'json', self._create_security_group(self.fmt, 'asdf', 'asdf')) - security_group_id = security_group['security_group']['id'] - res = self._create_port('json', net['network']['id'], - arg_list=('security_groups',), - security_groups=[security_group_id]) - port = self.deserialize('json', res) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - self.assertEqual(port['port']['security_groups'], [security_group_id]) - self._delete('ports', port['port']['id']) - - def test_update_port_security_off_with_security_group(self): - if self._skip_security_group: - self.skipTest("Plugin does not support security groups") - with self.network() as net: - with self.subnet(network=net): - res = self._create_port('json', net['network']['id']) - port = self.deserialize('json', res) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - - update_port = {'port': {psec.PORTSECURITY: False}} - req = self.new_update_request('ports', update_port, - port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 409) - # remove security group on port - update_port = {'port': {ext_sg.SECURITYGROUPS: None}} - req = self.new_update_request('ports', update_port, - port['port']['id']) - - self.deserialize('json', req.get_response(self.api)) - self._delete('ports', port['port']['id']) - - def test_update_port_remove_port_security_security_group(self): - if self._skip_security_group: - self.skipTest("Plugin does not support security groups") - with self.network() as net: - with self.subnet(network=net): - res = self._create_port('json', net['network']['id'], - arg_list=('port_security_enabled',), - port_security_enabled=True) - port = self.deserialize('json', res) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - - # remove security group on port - update_port = {'port': {ext_sg.SECURITYGROUPS: None, - psec.PORTSECURITY: False}} - req = self.new_update_request('ports', update_port, - port['port']['id']) - port = self.deserialize('json', req.get_response(self.api)) - self.assertEqual(port['port'][psec.PORTSECURITY], False) - self.assertEqual(len(port['port'][ext_sg.SECURITYGROUPS]), 0) - self._delete('ports', port['port']['id']) - - def test_update_port_remove_port_security_security_group_read(self): - if self._skip_security_group: - self.skipTest("Plugin does not support security groups") - with self.network() as net: - with self.subnet(network=net): - res = self._create_port('json', net['network']['id'], - arg_list=('port_security_enabled',), - port_security_enabled=True) - port = self.deserialize('json', res) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - - # remove security group on port - update_port = {'port': {ext_sg.SECURITYGROUPS: None, - psec.PORTSECURITY: False}} - req = self.new_update_request('ports', update_port, - port['port']['id']) - self.deserialize('json', req.get_response(self.api)) - - sg_id = port['port'][ext_sg.SECURITYGROUPS] - update_port = {'port': {ext_sg.SECURITYGROUPS: [sg_id[0]], - psec.PORTSECURITY: True}} - - req = self.new_update_request('ports', update_port, - port['port']['id']) - - port = self.deserialize('json', req.get_response(self.api)) - self.assertEqual(port['port'][psec.PORTSECURITY], True) - self.assertEqual(len(port['port'][ext_sg.SECURITYGROUPS]), 1) - self._delete('ports', port['port']['id']) - - def test_create_port_security_off_shared_network(self): - with self.network(shared=True) as net: - with self.subnet(network=net): - res = self._create_port('json', net['network']['id'], - arg_list=('port_security_enabled',), - port_security_enabled=False, - tenant_id='not_network_owner', - set_context=True) - self.deserialize('json', res) - self.assertEqual(res.status_int, 403) - - def test_update_port_security_off_shared_network(self): - with self.network(shared=True, do_delete=False) as net: - with self.subnet(network=net, do_delete=False): - res = self._create_port('json', net['network']['id'], - tenant_id='not_network_owner', - set_context=True) - port = self.deserialize('json', res) - # remove security group on port - update_port = {'port': {ext_sg.SECURITYGROUPS: None, - psec.PORTSECURITY: False}} - req = self.new_update_request('ports', update_port, - port['port']['id']) - req.environ['neutron.context'] = context.Context( - '', 'not_network_owner') - res = req.get_response(self.api) - # TODO(salvatore-orlando): Expected error is 404 because - # the current API controller always returns this error - # code for any policy check failures on update. - # It should be 404 when the caller cannot access the whole - # resource, and 403 when it cannot access a single attribute - self.assertEqual(res.status_int, 404) diff --git a/neutron/tests/unit/test_extension_security_group.py b/neutron/tests/unit/test_extension_security_group.py deleted file mode 100644 index 4a38f6da2..000000000 --- a/neutron/tests/unit/test_extension_security_group.py +++ /dev/null @@ -1,1431 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. - -# 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 contextlib - -import mock -import webob.exc - -from neutron.api.v2 import attributes as attr -from neutron.common import constants as const -from neutron.common import exceptions as n_exc -from neutron import context -from neutron.db import db_base_plugin_v2 -from neutron.db import securitygroups_db -from neutron.extensions import securitygroup as ext_sg -from neutron.tests import base -from neutron.tests.unit import test_db_plugin - -DB_PLUGIN_KLASS = ('neutron.tests.unit.test_extension_security_group.' - 'SecurityGroupTestPlugin') - - -class SecurityGroupTestExtensionManager(object): - - def get_resources(self): - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attr.RESOURCE_ATTRIBUTE_MAP.update( - ext_sg.RESOURCE_ATTRIBUTE_MAP) - return ext_sg.Securitygroup.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class SecurityGroupsTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - - def _create_security_group(self, fmt, name, description, **kwargs): - - data = {'security_group': {'name': name, - 'tenant_id': kwargs.get('tenant_id', - 'test_tenant'), - 'description': description}} - security_group_req = self.new_create_request('security-groups', data, - fmt) - if (kwargs.get('set_context') and 'tenant_id' in kwargs): - # create a specific auth context for this request - security_group_req.environ['neutron.context'] = ( - context.Context('', kwargs['tenant_id'])) - return security_group_req.get_response(self.ext_api) - - def _build_security_group_rule(self, security_group_id, direction, proto, - port_range_min=None, port_range_max=None, - remote_ip_prefix=None, remote_group_id=None, - tenant_id='test_tenant', - ethertype=const.IPv4): - - data = {'security_group_rule': {'security_group_id': security_group_id, - 'direction': direction, - 'protocol': proto, - 'ethertype': ethertype, - 'tenant_id': tenant_id, - 'ethertype': ethertype}} - if port_range_min: - data['security_group_rule']['port_range_min'] = port_range_min - - if port_range_max: - data['security_group_rule']['port_range_max'] = port_range_max - - if remote_ip_prefix: - data['security_group_rule']['remote_ip_prefix'] = remote_ip_prefix - - if remote_group_id: - data['security_group_rule']['remote_group_id'] = remote_group_id - - return data - - def _create_security_group_rule(self, fmt, rules, **kwargs): - - security_group_rule_req = self.new_create_request( - 'security-group-rules', rules, fmt) - - if (kwargs.get('set_context') and 'tenant_id' in kwargs): - # create a specific auth context for this request - security_group_rule_req.environ['neutron.context'] = ( - context.Context('', kwargs['tenant_id'])) - return security_group_rule_req.get_response(self.ext_api) - - def _make_security_group(self, fmt, name, description, **kwargs): - res = self._create_security_group(fmt, name, description, **kwargs) - if res.status_int >= webob.exc.HTTPBadRequest.code: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - def _make_security_group_rule(self, fmt, rules, **kwargs): - res = self._create_security_group_rule(self.fmt, rules) - if res.status_int >= webob.exc.HTTPBadRequest.code: - raise webob.exc.HTTPClientError(code=res.status_int) - return self.deserialize(fmt, res) - - @contextlib.contextmanager - def security_group(self, name='webservers', description='webservers', - fmt=None, no_delete=False): - if not fmt: - fmt = self.fmt - security_group = self._make_security_group(fmt, name, description) - yield security_group - if not no_delete: - self._delete('security-groups', - security_group['security_group']['id']) - - @contextlib.contextmanager - def security_group_rule(self, security_group_id='4cd70774-cc67-4a87-9b39-7' - 'd1db38eb087', - direction='ingress', protocol=const.PROTO_NAME_TCP, - port_range_min='22', port_range_max='22', - remote_ip_prefix=None, remote_group_id=None, - fmt=None, no_delete=False, ethertype=const.IPv4): - if not fmt: - fmt = self.fmt - rule = self._build_security_group_rule(security_group_id, - direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix, - remote_group_id, - ethertype=ethertype) - security_group_rule = self._make_security_group_rule(self.fmt, rule) - yield security_group_rule - if not no_delete: - self._delete('security-group-rules', - security_group_rule['security_group_rule']['id']) - - def _delete_default_security_group_egress_rules(self, security_group_id): - """Deletes default egress rules given a security group ID.""" - res = self._list( - 'security-group-rules', - query_params='security_group_id=%s' % security_group_id) - - for r in res['security_group_rules']: - if (r['direction'] == 'egress' and not r['port_range_max'] and - not r['port_range_min'] and not r['protocol'] - and not r['remote_ip_prefix']): - self._delete('security-group-rules', r['id']) - - def _assert_sg_rule_has_kvs(self, security_group_rule, expected_kvs): - """Asserts that the sg rule has expected key/value pairs passed - in as expected_kvs dictionary - """ - for k, v in expected_kvs.iteritems(): - self.assertEqual(security_group_rule[k], v) - - -class SecurityGroupsTestCaseXML(SecurityGroupsTestCase): - fmt = 'xml' - - -class SecurityGroupTestPlugin(db_base_plugin_v2.NeutronDbPluginV2, - securitygroups_db.SecurityGroupDbMixin): - """Test plugin that implements necessary calls on create/delete port for - associating ports with security groups. - """ - - __native_pagination_support = True - __native_sorting_support = True - - supported_extension_aliases = ["security-group"] - - def create_port(self, context, port): - tenant_id = self._get_tenant_id_for_create(context, port['port']) - default_sg = self._ensure_default_security_group(context, tenant_id) - if not attr.is_attr_set(port['port'].get(ext_sg.SECURITYGROUPS)): - port['port'][ext_sg.SECURITYGROUPS] = [default_sg] - session = context.session - with session.begin(subtransactions=True): - sgids = self._get_security_groups_on_port(context, port) - port = super(SecurityGroupTestPlugin, self).create_port(context, - port) - self._process_port_create_security_group(context, port, - sgids) - return port - - def update_port(self, context, id, port): - session = context.session - with session.begin(subtransactions=True): - if ext_sg.SECURITYGROUPS in port['port']: - port['port'][ext_sg.SECURITYGROUPS] = ( - self._get_security_groups_on_port(context, port)) - # delete the port binding and read it with the new rules - self._delete_port_security_group_bindings(context, id) - port['port']['id'] = id - self._process_port_create_security_group( - context, port['port'], - port['port'].get(ext_sg.SECURITYGROUPS)) - port = super(SecurityGroupTestPlugin, self).update_port( - context, id, port) - return port - - def create_network(self, context, network): - tenant_id = self._get_tenant_id_for_create(context, network['network']) - self._ensure_default_security_group(context, tenant_id) - return super(SecurityGroupTestPlugin, self).create_network(context, - network) - - def get_ports(self, context, filters=None, fields=None, - sorts=[], limit=None, marker=None, - page_reverse=False): - neutron_lports = super(SecurityGroupTestPlugin, self).get_ports( - context, filters, sorts=sorts, limit=limit, marker=marker, - page_reverse=page_reverse) - return neutron_lports - - -class SecurityGroupDBTestCase(SecurityGroupsTestCase): - def setUp(self, plugin=None, ext_mgr=None): - plugin = plugin or DB_PLUGIN_KLASS - ext_mgr = ext_mgr or SecurityGroupTestExtensionManager() - super(SecurityGroupDBTestCase, - self).setUp(plugin=plugin, ext_mgr=ext_mgr) - - -class TestSecurityGroups(SecurityGroupDBTestCase): - def test_create_security_group(self): - name = 'webservers' - description = 'my webservers' - keys = [('name', name,), ('description', description)] - with self.security_group(name, description) as security_group: - for k, v, in keys: - self.assertEqual(security_group['security_group'][k], v) - - # Verify that default egress rules have been created - - sg_rules = security_group['security_group']['security_group_rules'] - self.assertEqual(len(sg_rules), 2) - - v4_rules = [r for r in sg_rules if r['ethertype'] == const.IPv4] - self.assertEqual(len(v4_rules), 1) - v4_rule = v4_rules[0] - expected = {'direction': 'egress', - 'ethertype': const.IPv4, - 'remote_group_id': None, - 'remote_ip_prefix': None, - 'protocol': None, - 'port_range_max': None, - 'port_range_min': None} - self._assert_sg_rule_has_kvs(v4_rule, expected) - - v6_rules = [r for r in sg_rules if r['ethertype'] == const.IPv6] - self.assertEqual(len(v6_rules), 1) - v6_rule = v6_rules[0] - expected = {'direction': 'egress', - 'ethertype': const.IPv6, - 'remote_group_id': None, - 'remote_ip_prefix': None, - 'protocol': None, - 'port_range_max': None, - 'port_range_min': None} - self._assert_sg_rule_has_kvs(v6_rule, expected) - - def test_update_security_group(self): - with self.security_group() as sg: - data = {'security_group': {'name': 'new_name', - 'description': 'new_desc'}} - req = self.new_update_request('security-groups', - data, - sg['security_group']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self.assertEqual(res['security_group']['name'], - data['security_group']['name']) - self.assertEqual(res['security_group']['description'], - data['security_group']['description']) - - def test_update_security_group_name_to_default_fail(self): - with self.security_group() as sg: - data = {'security_group': {'name': 'default', - 'description': 'new_desc'}} - req = self.new_update_request('security-groups', - data, - sg['security_group']['id']) - req.environ['neutron.context'] = context.Context('', 'somebody') - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_update_default_security_group_name_fail(self): - with self.network(): - res = self.new_list_request('security-groups') - sg = self.deserialize(self.fmt, res.get_response(self.ext_api)) - data = {'security_group': {'name': 'new_name', - 'description': 'new_desc'}} - req = self.new_update_request('security-groups', - data, - sg['security_groups'][0]['id']) - req.environ['neutron.context'] = context.Context('', 'somebody') - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - def test_update_default_security_group_with_description(self): - with self.network(): - res = self.new_list_request('security-groups') - sg = self.deserialize(self.fmt, res.get_response(self.ext_api)) - data = {'security_group': {'description': 'new_desc'}} - req = self.new_update_request('security-groups', - data, - sg['security_groups'][0]['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - self.assertEqual(res['security_group']['description'], - data['security_group']['description']) - - def test_default_security_group(self): - with self.network(): - res = self.new_list_request('security-groups') - groups = self.deserialize(self.fmt, res.get_response(self.ext_api)) - self.assertEqual(len(groups['security_groups']), 1) - - def test_create_default_security_group_fail(self): - name = 'default' - description = 'my webservers' - res = self._create_security_group(self.fmt, name, description) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_list_security_groups(self): - with contextlib.nested(self.security_group(name='sg1', - description='sg'), - self.security_group(name='sg2', - description='sg'), - self.security_group(name='sg3', - description='sg') - ) as security_groups: - self._test_list_resources('security-group', - security_groups, - query_params='description=sg') - - def test_list_security_groups_with_sort(self): - with contextlib.nested(self.security_group(name='sg1', - description='sg'), - self.security_group(name='sg2', - description='sg'), - self.security_group(name='sg3', - description='sg') - ) as (sg1, sg2, sg3): - self._test_list_with_sort('security-group', - (sg3, sg2, sg1), - [('name', 'desc')], - query_params='description=sg') - - def test_list_security_groups_with_pagination(self): - with contextlib.nested(self.security_group(name='sg1', - description='sg'), - self.security_group(name='sg2', - description='sg'), - self.security_group(name='sg3', - description='sg') - ) as (sg1, sg2, sg3): - self._test_list_with_pagination('security-group', - (sg1, sg2, sg3), - ('name', 'asc'), 2, 2, - query_params='description=sg') - - def test_list_security_groups_with_pagination_reverse(self): - with contextlib.nested(self.security_group(name='sg1', - description='sg'), - self.security_group(name='sg2', - description='sg'), - self.security_group(name='sg3', - description='sg') - ) as (sg1, sg2, sg3): - self._test_list_with_pagination_reverse( - 'security-group', (sg1, sg2, sg3), ('name', 'asc'), 2, 2, - query_params='description=sg') - - def test_create_security_group_rule_ethertype_invalid_as_number(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - ethertype = 2 - rule = self._build_security_group_rule( - security_group_id, 'ingress', const.PROTO_NAME_TCP, '22', - '22', None, None, ethertype=ethertype) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_invalid_ip_prefix(self): - name = 'webservers' - description = 'my webservers' - for bad_prefix in ['bad_ip', 256, "2001:db8:a::123/129", '172.30./24']: - with self.security_group(name, description) as sg: - sg_id = sg['security_group']['id'] - remote_ip_prefix = bad_prefix - rule = self._build_security_group_rule( - sg_id, - 'ingress', - const.PROTO_NAME_TCP, - '22', '22', - remote_ip_prefix) - res = self._create_security_group_rule(self.fmt, rule) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_invalid_ethertype_for_prefix(self): - name = 'webservers' - description = 'my webservers' - test_addr = {'192.168.1.1/24': 'ipv4', '192.168.1.1/24': 'IPv6', - '2001:db8:1234::/48': 'ipv6', - '2001:db8:1234::/48': 'IPv4'} - for prefix, ether in test_addr.iteritems(): - with self.security_group(name, description) as sg: - sg_id = sg['security_group']['id'] - ethertype = ether - remote_ip_prefix = prefix - rule = self._build_security_group_rule( - sg_id, - 'ingress', - const.PROTO_NAME_TCP, - '22', '22', - remote_ip_prefix, - None, - None, - ethertype) - res = self._create_security_group_rule(self.fmt, rule) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_with_unmasked_prefix(self): - name = 'webservers' - description = 'my webservers' - addr = {'10.1.2.3': {'mask': '32', 'ethertype': 'IPv4'}, - 'fe80::2677:3ff:fe7d:4c': {'mask': '128', 'ethertype': 'IPv6'}} - for ip in addr: - with self.security_group(name, description) as sg: - sg_id = sg['security_group']['id'] - ethertype = addr[ip]['ethertype'] - remote_ip_prefix = ip - rule = self._build_security_group_rule( - sg_id, - 'ingress', - const.PROTO_NAME_TCP, - '22', '22', - remote_ip_prefix, - None, - None, - ethertype) - res = self._create_security_group_rule(self.fmt, rule) - self.assertEqual(res.status_int, 201) - res_sg = self.deserialize(self.fmt, res) - prefix = res_sg['security_group_rule']['remote_ip_prefix'] - self.assertEqual(prefix, '%s/%s' % (ip, addr[ip]['mask'])) - - def test_create_security_group_rule_tcp_protocol_as_number(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - protocol = const.PROTO_NUM_TCP # TCP - rule = self._build_security_group_rule( - security_group_id, 'ingress', protocol, '22', '22') - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - def test_create_security_group_rule_protocol_as_number(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - protocol = 2 - rule = self._build_security_group_rule( - security_group_id, 'ingress', protocol) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - def test_create_security_group_rule_case_insensitive(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - direction = "ingress" - remote_ip_prefix = "10.0.0.0/24" - protocol = 'TCP' - port_range_min = 22 - port_range_max = 22 - ethertype = 'ipV4' - with self.security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix, - ethertype=ethertype) as rule: - - # the lower case value will be return - self.assertEqual(rule['security_group_rule']['protocol'], - protocol.lower()) - self.assertEqual(rule['security_group_rule']['ethertype'], - const.IPv4) - - def test_get_security_group(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - remote_group_id = sg['security_group']['id'] - res = self.new_show_request('security-groups', remote_group_id) - security_group_id = sg['security_group']['id'] - direction = "ingress" - remote_ip_prefix = "10.0.0.0/24" - protocol = const.PROTO_NAME_TCP - port_range_min = 22 - port_range_max = 22 - keys = [('remote_ip_prefix', remote_ip_prefix), - ('security_group_id', security_group_id), - ('direction', direction), - ('protocol', protocol), - ('port_range_min', port_range_min), - ('port_range_max', port_range_max)] - with self.security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix): - - group = self.deserialize( - self.fmt, res.get_response(self.ext_api)) - sg_rule = group['security_group']['security_group_rules'] - self.assertEqual(group['security_group']['id'], - remote_group_id) - self.assertEqual(len(sg_rule), 3) - sg_rule = [r for r in sg_rule if r['direction'] == 'ingress'] - for k, v, in keys: - self.assertEqual(sg_rule[0][k], v) - - def test_delete_security_group(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description, no_delete=True) as sg: - remote_group_id = sg['security_group']['id'] - self._delete('security-groups', remote_group_id, - webob.exc.HTTPNoContent.code) - - def test_delete_default_security_group_admin(self): - with self.network(): - res = self.new_list_request('security-groups') - sg = self.deserialize(self.fmt, res.get_response(self.ext_api)) - self._delete('security-groups', sg['security_groups'][0]['id'], - webob.exc.HTTPNoContent.code) - - def test_delete_default_security_group_nonadmin(self): - with self.network(): - res = self.new_list_request('security-groups') - sg = self.deserialize(self.fmt, res.get_response(self.ext_api)) - neutron_context = context.Context('', 'test-tenant') - self._delete('security-groups', sg['security_groups'][0]['id'], - webob.exc.HTTPConflict.code, - neutron_context=neutron_context) - - def test_security_group_list_creates_default_security_group(self): - neutron_context = context.Context('', 'test-tenant') - sg = self._list('security-groups', - neutron_context=neutron_context).get('security_groups') - self.assertEqual(len(sg), 1) - - def test_default_security_group_rules(self): - with self.network(): - res = self.new_list_request('security-groups') - groups = self.deserialize(self.fmt, res.get_response(self.ext_api)) - self.assertEqual(len(groups['security_groups']), 1) - security_group_id = groups['security_groups'][0]['id'] - res = self.new_list_request('security-group-rules') - rules = self.deserialize(self.fmt, res.get_response(self.ext_api)) - self.assertEqual(len(rules['security_group_rules']), 4) - - # Verify default rule for v4 egress - sg_rules = rules['security_group_rules'] - rules = [ - r for r in sg_rules - if r['direction'] == 'egress' and r['ethertype'] == const.IPv4 - ] - self.assertEqual(len(rules), 1) - v4_egress = rules[0] - - expected = {'direction': 'egress', - 'ethertype': const.IPv4, - 'remote_group_id': None, - 'remote_ip_prefix': None, - 'protocol': None, - 'port_range_max': None, - 'port_range_min': None} - self._assert_sg_rule_has_kvs(v4_egress, expected) - - # Verify default rule for v6 egress - rules = [ - r for r in sg_rules - if r['direction'] == 'egress' and r['ethertype'] == const.IPv6 - ] - self.assertEqual(len(rules), 1) - v6_egress = rules[0] - - expected = {'direction': 'egress', - 'ethertype': const.IPv6, - 'remote_group_id': None, - 'remote_ip_prefix': None, - 'protocol': None, - 'port_range_max': None, - 'port_range_min': None} - self._assert_sg_rule_has_kvs(v6_egress, expected) - - # Verify default rule for v4 ingress - rules = [ - r for r in sg_rules - if r['direction'] == 'ingress' and r['ethertype'] == const.IPv4 - ] - self.assertEqual(len(rules), 1) - v4_ingress = rules[0] - - expected = {'direction': 'ingress', - 'ethertype': const.IPv4, - 'remote_group_id': security_group_id, - 'remote_ip_prefix': None, - 'protocol': None, - 'port_range_max': None, - 'port_range_min': None} - self._assert_sg_rule_has_kvs(v4_ingress, expected) - - # Verify default rule for v6 ingress - rules = [ - r for r in sg_rules - if r['direction'] == 'ingress' and r['ethertype'] == const.IPv6 - ] - self.assertEqual(len(rules), 1) - v6_ingress = rules[0] - - expected = {'direction': 'ingress', - 'ethertype': const.IPv6, - 'remote_group_id': security_group_id, - 'remote_ip_prefix': None, - 'protocol': None, - 'port_range_max': None, - 'port_range_min': None} - self._assert_sg_rule_has_kvs(v6_ingress, expected) - - def test_create_security_group_rule_remote_ip_prefix(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - direction = "ingress" - remote_ip_prefix = "10.0.0.0/24" - protocol = const.PROTO_NAME_TCP - port_range_min = 22 - port_range_max = 22 - keys = [('remote_ip_prefix', remote_ip_prefix), - ('security_group_id', security_group_id), - ('direction', direction), - ('protocol', protocol), - ('port_range_min', port_range_min), - ('port_range_max', port_range_max)] - with self.security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix) as rule: - for k, v, in keys: - self.assertEqual(rule['security_group_rule'][k], v) - - def test_create_security_group_rule_group_id(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - with self.security_group(name, description) as sg2: - security_group_id = sg['security_group']['id'] - direction = "ingress" - remote_group_id = sg2['security_group']['id'] - protocol = const.PROTO_NAME_TCP - port_range_min = 22 - port_range_max = 22 - keys = [('remote_group_id', remote_group_id), - ('security_group_id', security_group_id), - ('direction', direction), - ('protocol', protocol), - ('port_range_min', port_range_min), - ('port_range_max', port_range_max)] - with self.security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_group_id=remote_group_id - ) as rule: - for k, v, in keys: - self.assertEqual(rule['security_group_rule'][k], v) - - def test_create_security_group_rule_icmp_with_type_and_code(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - direction = "ingress" - remote_ip_prefix = "10.0.0.0/24" - protocol = const.PROTO_NAME_ICMP - # port_range_min (ICMP type) is greater than port_range_max - # (ICMP code) in order to confirm min <= max port check is - # not called for ICMP. - port_range_min = 8 - port_range_max = 5 - keys = [('remote_ip_prefix', remote_ip_prefix), - ('security_group_id', security_group_id), - ('direction', direction), - ('protocol', protocol), - ('port_range_min', port_range_min), - ('port_range_max', port_range_max)] - with self.security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix) as rule: - for k, v, in keys: - self.assertEqual(rule['security_group_rule'][k], v) - - def test_create_security_group_rule_icmp_with_type_only(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - direction = "ingress" - remote_ip_prefix = "10.0.0.0/24" - protocol = const.PROTO_NAME_ICMP - # ICMP type - port_range_min = 8 - # ICMP code - port_range_max = None - keys = [('remote_ip_prefix', remote_ip_prefix), - ('security_group_id', security_group_id), - ('direction', direction), - ('protocol', protocol), - ('port_range_min', port_range_min), - ('port_range_max', port_range_max)] - with self.security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix) as rule: - for k, v, in keys: - self.assertEqual(rule['security_group_rule'][k], v) - - def test_create_security_group_source_group_ip_and_ip_prefix(self): - security_group_id = "4cd70774-cc67-4a87-9b39-7d1db38eb087" - direction = "ingress" - remote_ip_prefix = "10.0.0.0/24" - protocol = const.PROTO_NAME_TCP - port_range_min = 22 - port_range_max = 22 - remote_group_id = "9cd70774-cc67-4a87-9b39-7d1db38eb087" - rule = self._build_security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix, - remote_group_id) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_bad_security_group_id(self): - security_group_id = "4cd70774-cc67-4a87-9b39-7d1db38eb087" - direction = "ingress" - remote_ip_prefix = "10.0.0.0/24" - protocol = const.PROTO_NAME_TCP - port_range_min = 22 - port_range_max = 22 - rule = self._build_security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - def test_create_security_group_rule_bad_tenant(self): - with self.security_group() as sg: - rule = {'security_group_rule': - {'security_group_id': sg['security_group']['id'], - 'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'port_range_min': '22', - 'port_range_max': '22', - 'tenant_id': "bad_tenant"}} - - res = self._create_security_group_rule(self.fmt, rule, - tenant_id='bad_tenant', - set_context=True) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - def test_create_security_group_rule_bad_tenant_remote_group_id(self): - with self.security_group() as sg: - res = self._create_security_group(self.fmt, 'webservers', - 'webservers', - tenant_id='bad_tenant') - sg2 = self.deserialize(self.fmt, res) - rule = {'security_group_rule': - {'security_group_id': sg2['security_group']['id'], - 'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'port_range_min': '22', - 'port_range_max': '22', - 'tenant_id': 'bad_tenant', - 'remote_group_id': sg['security_group']['id']}} - - res = self._create_security_group_rule(self.fmt, rule, - tenant_id='bad_tenant', - set_context=True) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - def test_create_security_group_rule_bad_tenant_security_group_rule(self): - with self.security_group() as sg: - res = self._create_security_group(self.fmt, 'webservers', - 'webservers', - tenant_id='bad_tenant') - self.deserialize(self.fmt, res) - rule = {'security_group_rule': - {'security_group_id': sg['security_group']['id'], - 'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'port_range_min': '22', - 'port_range_max': '22', - 'tenant_id': 'bad_tenant'}} - - res = self._create_security_group_rule(self.fmt, rule, - tenant_id='bad_tenant', - set_context=True) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - def test_create_security_group_rule_bad_remote_group_id(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - remote_group_id = "4cd70774-cc67-4a87-9b39-7d1db38eb087" - direction = "ingress" - protocol = const.PROTO_NAME_TCP - port_range_min = 22 - port_range_max = 22 - rule = self._build_security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_group_id=remote_group_id) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) - - def test_create_security_group_rule_duplicate_rules(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - with self.security_group_rule(security_group_id): - rule = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_TCP, '22', '22') - self._create_security_group_rule(self.fmt, rule) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_create_security_group_rule_min_port_greater_max(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - with self.security_group_rule(security_group_id): - for protocol in [const.PROTO_NAME_TCP, const.PROTO_NAME_UDP, - const.PROTO_NUM_TCP, const.PROTO_NUM_UDP]: - rule = self._build_security_group_rule( - sg['security_group']['id'], - 'ingress', protocol, '50', '22') - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, - webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_ports_but_no_protocol(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - with self.security_group_rule(security_group_id): - rule = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', None, '22', '22') - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_port_range_min_only(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - with self.security_group_rule(security_group_id): - rule = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_TCP, '22', None) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_port_range_max_only(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - with self.security_group_rule(security_group_id): - rule = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_TCP, None, '22') - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_icmp_type_too_big(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - with self.security_group_rule(security_group_id): - rule = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_ICMP, '256', None) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_icmp_code_too_big(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - with self.security_group_rule(security_group_id): - rule = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_ICMP, '8', '256') - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_icmp_with_code_only(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - with self.security_group_rule(security_group_id): - rule = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_ICMP, None, '2') - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_list_ports_security_group(self): - with self.network() as n: - with self.subnet(n): - self._create_port(self.fmt, n['network']['id']) - req = self.new_list_request('ports') - res = req.get_response(self.api) - ports = self.deserialize(self.fmt, res) - port = ports['ports'][0] - self.assertEqual(len(port[ext_sg.SECURITYGROUPS]), 1) - self._delete('ports', port['id']) - - def test_list_security_group_rules(self): - with self.security_group(name='sg') as sg: - security_group_id = sg['security_group']['id'] - with contextlib.nested(self.security_group_rule(security_group_id, - direction='egress', - port_range_min=22, - port_range_max=22), - self.security_group_rule(security_group_id, - direction='egress', - port_range_min=23, - port_range_max=23), - self.security_group_rule(security_group_id, - direction='egress', - port_range_min=24, - port_range_max=24) - ) as (sgr1, sgr2, sgr3): - - # Delete default rules as they would fail the following - # assertion at the end. - self._delete_default_security_group_egress_rules( - security_group_id) - - q = 'direction=egress&security_group_id=' + security_group_id - self._test_list_resources('security-group-rule', - [sgr1, sgr2, sgr3], - query_params=q) - - def test_list_security_group_rules_with_sort(self): - with self.security_group(name='sg') as sg: - security_group_id = sg['security_group']['id'] - with contextlib.nested(self.security_group_rule(security_group_id, - direction='egress', - port_range_min=22, - port_range_max=22), - self.security_group_rule(security_group_id, - direction='egress', - port_range_min=23, - port_range_max=23), - self.security_group_rule(security_group_id, - direction='egress', - port_range_min=24, - port_range_max=24) - ) as (sgr1, sgr2, sgr3): - - # Delete default rules as they would fail the following - # assertion at the end. - self._delete_default_security_group_egress_rules( - security_group_id) - - q = 'direction=egress&security_group_id=' + security_group_id - self._test_list_with_sort('security-group-rule', - (sgr3, sgr2, sgr1), - [('port_range_max', 'desc')], - query_params=q) - - def test_list_security_group_rules_with_pagination(self): - with self.security_group(name='sg') as sg: - security_group_id = sg['security_group']['id'] - with contextlib.nested(self.security_group_rule(security_group_id, - direction='egress', - port_range_min=22, - port_range_max=22), - self.security_group_rule(security_group_id, - direction='egress', - port_range_min=23, - port_range_max=23), - self.security_group_rule(security_group_id, - direction='egress', - port_range_min=24, - port_range_max=24) - ) as (sgr1, sgr2, sgr3): - - # Delete default rules as they would fail the following - # assertion at the end. - self._delete_default_security_group_egress_rules( - security_group_id) - - q = 'direction=egress&security_group_id=' + security_group_id - self._test_list_with_pagination( - 'security-group-rule', (sgr3, sgr2, sgr1), - ('port_range_max', 'desc'), 2, 2, - query_params=q) - - def test_list_security_group_rules_with_pagination_reverse(self): - with self.security_group(name='sg') as sg: - security_group_id = sg['security_group']['id'] - with contextlib.nested(self.security_group_rule(security_group_id, - direction='egress', - port_range_min=22, - port_range_max=22), - self.security_group_rule(security_group_id, - direction='egress', - port_range_min=23, - port_range_max=23), - self.security_group_rule(security_group_id, - direction='egress', - port_range_min=24, - port_range_max=24) - ) as (sgr1, sgr2, sgr3): - self._test_list_with_pagination_reverse( - 'security-group-rule', (sgr3, sgr2, sgr1), - ('port_range_max', 'desc'), 2, 2, - query_params='direction=egress') - - def test_update_port_with_security_group(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - - data = {'port': {'fixed_ips': port['port']['fixed_ips'], - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: - [sg['security_group']['id']]}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - self.assertEqual(res['port'][ext_sg.SECURITYGROUPS][0], - sg['security_group']['id']) - - # Test update port without security group - data = {'port': {'fixed_ips': port['port']['fixed_ips'], - 'name': port['port']['name']}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - self.assertEqual(res['port'][ext_sg.SECURITYGROUPS][0], - sg['security_group']['id']) - - self._delete('ports', port['port']['id']) - - def test_update_port_with_multiple_security_groups(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg1: - with self.security_group() as sg2: - res = self._create_port( - self.fmt, n['network']['id'], - security_groups=[sg1['security_group']['id'], - sg2['security_group']['id']]) - port = self.deserialize(self.fmt, res) - self.assertEqual(len( - port['port'][ext_sg.SECURITYGROUPS]), 2) - self._delete('ports', port['port']['id']) - - def test_update_port_remove_security_group_empty_list(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - res = self._create_port(self.fmt, n['network']['id'], - security_groups=( - [sg['security_group']['id']])) - port = self.deserialize(self.fmt, res) - - data = {'port': {'fixed_ips': port['port']['fixed_ips'], - 'name': port['port']['name'], - 'security_groups': []}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - self.assertEqual(res['port'].get(ext_sg.SECURITYGROUPS), - []) - self._delete('ports', port['port']['id']) - - def test_update_port_remove_security_group_none(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - res = self._create_port(self.fmt, n['network']['id'], - security_groups=( - [sg['security_group']['id']])) - port = self.deserialize(self.fmt, res) - - data = {'port': {'fixed_ips': port['port']['fixed_ips'], - 'name': port['port']['name'], - 'security_groups': None}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - self.assertEqual(res['port'].get(ext_sg.SECURITYGROUPS), - []) - self._delete('ports', port['port']['id']) - - def test_create_port_with_bad_security_group(self): - with self.network() as n: - with self.subnet(n): - res = self._create_port(self.fmt, n['network']['id'], - security_groups=['bad_id']) - - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_delete_security_group_port_in_use(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - res = self._create_port(self.fmt, n['network']['id'], - security_groups=( - [sg['security_group']['id']])) - port = self.deserialize(self.fmt, res) - self.assertEqual(port['port'][ext_sg.SECURITYGROUPS][0], - sg['security_group']['id']) - # try to delete security group that's in use - res = self._delete('security-groups', - sg['security_group']['id'], - webob.exc.HTTPConflict.code) - # delete the blocking port - self._delete('ports', port['port']['id']) - - def test_create_security_group_rule_bulk_native(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk " - "security_group_rule create") - with self.security_group() as sg: - rule1 = self._build_security_group_rule(sg['security_group']['id'], - 'ingress', - const.PROTO_NAME_TCP, '22', - '22', '10.0.0.1/24') - rule2 = self._build_security_group_rule(sg['security_group']['id'], - 'ingress', - const.PROTO_NAME_TCP, '23', - '23', '10.0.0.1/24') - rules = {'security_group_rules': [rule1['security_group_rule'], - rule2['security_group_rule']]} - res = self._create_security_group_rule(self.fmt, rules) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - def test_create_security_group_rule_bulk_emulated(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - with self.security_group() as sg: - rule1 = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_TCP, '22', '22', '10.0.0.1/24') - rule2 = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_TCP, '23', '23', '10.0.0.1/24') - rules = {'security_group_rules': [rule1['security_group_rule'], - rule2['security_group_rule']] - } - res = self._create_security_group_rule(self.fmt, rules) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - def test_create_security_group_rule_allow_all_ipv4(self): - with self.security_group() as sg: - rule = {'security_group_id': sg['security_group']['id'], - 'direction': 'ingress', - 'ethertype': 'IPv4', - 'tenant_id': 'test_tenant'} - - res = self._create_security_group_rule( - self.fmt, {'security_group_rule': rule}) - rule = self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - def test_create_security_group_rule_allow_all_ipv4_v6_bulk(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk " - "security_group_rule create") - with self.security_group() as sg: - rule_v4 = {'security_group_id': sg['security_group']['id'], - 'direction': 'ingress', - 'ethertype': 'IPv4', - 'tenant_id': 'test_tenant'} - rule_v6 = {'security_group_id': sg['security_group']['id'], - 'direction': 'ingress', - 'ethertype': 'IPv6', - 'tenant_id': 'test_tenant'} - - rules = {'security_group_rules': [rule_v4, rule_v6]} - res = self._create_security_group_rule(self.fmt, rules) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - def test_create_security_group_rule_duplicate_rule_in_post(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk " - "security_group_rule create") - with self.security_group() as sg: - rule = self._build_security_group_rule(sg['security_group']['id'], - 'ingress', - const.PROTO_NAME_TCP, '22', - '22', '10.0.0.1/24') - rules = {'security_group_rules': [rule['security_group_rule'], - rule['security_group_rule']]} - res = self._create_security_group_rule(self.fmt, rules) - rule = self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_create_security_group_rule_duplicate_rule_in_post_emulated(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - - with self.security_group() as sg: - rule = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_TCP, '22', '22', '10.0.0.1/24') - rules = {'security_group_rules': [rule['security_group_rule'], - rule['security_group_rule']]} - res = self._create_security_group_rule(self.fmt, rules) - rule = self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_create_security_group_rule_duplicate_rule_db(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk " - "security_group_rule create") - with self.security_group() as sg: - rule = self._build_security_group_rule(sg['security_group']['id'], - 'ingress', - const.PROTO_NAME_TCP, '22', - '22', '10.0.0.1/24') - rules = {'security_group_rules': [rule]} - self._create_security_group_rule(self.fmt, rules) - res = self._create_security_group_rule(self.fmt, rules) - rule = self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_create_security_group_rule_duplicate_rule_db_emulated(self): - real_has_attr = hasattr - - #ensures the API choose the emulation code path - def fakehasattr(item, attr): - if attr.endswith('__native_bulk_support'): - return False - return real_has_attr(item, attr) - - with mock.patch('__builtin__.hasattr', - new=fakehasattr): - with self.security_group() as sg: - rule = self._build_security_group_rule( - sg['security_group']['id'], 'ingress', - const.PROTO_NAME_TCP, '22', '22', '10.0.0.1/24') - rules = {'security_group_rules': [rule]} - self._create_security_group_rule(self.fmt, rules) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) - - def test_create_security_group_rule_different_security_group_ids(self): - if self._skip_native_bulk: - self.skipTest("Plugin does not support native bulk " - "security_group_rule create") - with self.security_group() as sg1: - with self.security_group() as sg2: - rule1 = self._build_security_group_rule( - sg1['security_group']['id'], 'ingress', - const.PROTO_NAME_TCP, '22', '22', '10.0.0.1/24') - rule2 = self._build_security_group_rule( - sg2['security_group']['id'], 'ingress', - const.PROTO_NAME_TCP, '23', '23', '10.0.0.1/24') - - rules = {'security_group_rules': [rule1['security_group_rule'], - rule2['security_group_rule']] - } - res = self._create_security_group_rule(self.fmt, rules) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_with_invalid_ethertype(self): - security_group_id = "4cd70774-cc67-4a87-9b39-7d1db38eb087" - direction = "ingress" - remote_ip_prefix = "10.0.0.0/24" - protocol = const.PROTO_NAME_TCP - port_range_min = 22 - port_range_max = 22 - remote_group_id = "9cd70774-cc67-4a87-9b39-7d1db38eb087" - rule = self._build_security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix, - remote_group_id, - ethertype='IPv5') - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_security_group_rule_with_invalid_protocol(self): - security_group_id = "4cd70774-cc67-4a87-9b39-7d1db38eb087" - direction = "ingress" - remote_ip_prefix = "10.0.0.0/24" - protocol = 'tcp/ip' - port_range_min = 22 - port_range_max = 22 - remote_group_id = "9cd70774-cc67-4a87-9b39-7d1db38eb087" - rule = self._build_security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_ip_prefix, - remote_group_id) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_create_port_with_non_uuid(self): - with self.network() as n: - with self.subnet(n): - res = self._create_port(self.fmt, n['network']['id'], - security_groups=['not_valid']) - - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - -class TestConvertIPPrefixToCIDR(base.BaseTestCase): - - def test_convert_bad_ip_prefix_to_cidr(self): - for val in ['bad_ip', 256, "2001:db8:a::123/129"]: - self.assertRaises(n_exc.InvalidCIDR, - ext_sg.convert_ip_prefix_to_cidr, val) - self.assertIsNone(ext_sg.convert_ip_prefix_to_cidr(None)) - - def test_convert_ip_prefix_no_netmask_to_cidr(self): - addr = {'10.1.2.3': '32', 'fe80::2677:3ff:fe7d:4c': '128'} - for k, v in addr.iteritems(): - self.assertEqual(ext_sg.convert_ip_prefix_to_cidr(k), - '%s/%s' % (k, v)) - - def test_convert_ip_prefix_with_netmask_to_cidr(self): - addresses = ['10.1.0.0/16', '10.1.2.3/32', '2001:db8:1234::/48'] - for addr in addresses: - self.assertEqual(ext_sg.convert_ip_prefix_to_cidr(addr), addr) - - -class TestSecurityGroupsXML(TestSecurityGroups): - fmt = 'xml' diff --git a/neutron/tests/unit/test_iptables_firewall.py b/neutron/tests/unit/test_iptables_firewall.py deleted file mode 100644 index 06f490d55..000000000 --- a/neutron/tests/unit/test_iptables_firewall.py +++ /dev/null @@ -1,1225 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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 copy - -import mock -from oslo.config import cfg - -from neutron.agent.common import config as a_cfg -from neutron.agent.linux import iptables_firewall -from neutron.common import constants -from neutron.tests import base -from neutron.tests.unit import test_api_v2 - - -_uuid = test_api_v2._uuid -FAKE_PREFIX = {'IPv4': '10.0.0.0/24', - 'IPv6': 'fe80::/48'} -FAKE_IP = {'IPv4': '10.0.0.1', - 'IPv6': 'fe80::1'} - - -class IptablesFirewallTestCase(base.BaseTestCase): - def setUp(self): - super(IptablesFirewallTestCase, self).setUp() - cfg.CONF.register_opts(a_cfg.ROOT_HELPER_OPTS, 'AGENT') - self.utils_exec_p = mock.patch( - 'neutron.agent.linux.utils.execute') - self.utils_exec = self.utils_exec_p.start() - self.iptables_cls_p = mock.patch( - 'neutron.agent.linux.iptables_manager.IptablesManager') - iptables_cls = self.iptables_cls_p.start() - self.iptables_inst = mock.Mock() - self.v4filter_inst = mock.Mock() - self.v6filter_inst = mock.Mock() - self.iptables_inst.ipv4 = {'filter': self.v4filter_inst} - self.iptables_inst.ipv6 = {'filter': self.v6filter_inst} - iptables_cls.return_value = self.iptables_inst - - self.firewall = iptables_firewall.IptablesFirewallDriver() - self.firewall.iptables = self.iptables_inst - - def _fake_port(self): - return {'device': 'tapfake_dev', - 'mac_address': 'ff:ff:ff:ff:ff:ff', - 'fixed_ips': [FAKE_IP['IPv4'], - FAKE_IP['IPv6']]} - - def test_prepare_port_filter_with_no_sg(self): - port = self._fake_port() - self.firewall.prepare_port_filter(port) - calls = [mock.call.add_chain('sg-fallback'), - mock.call.add_rule('sg-fallback', '-j DROP'), - mock.call.ensure_remove_chain('sg-chain'), - mock.call.add_chain('sg-chain'), - mock.call.add_chain('ifake_dev'), - mock.call.add_rule('FORWARD', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged ' - '-j $sg-chain'), - mock.call.add_rule('sg-chain', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged ' - '-j $ifake_dev'), - mock.call.add_rule( - 'ifake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ifake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ifake_dev', '-j $sg-fallback'), - mock.call.add_chain('ofake_dev'), - mock.call.add_rule('FORWARD', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $sg-chain'), - mock.call.add_rule('sg-chain', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $ofake_dev'), - mock.call.add_rule('INPUT', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $ofake_dev'), - mock.call.add_chain('sfake_dev'), - mock.call.add_rule( - 'sfake_dev', '-m mac --mac-source ff:ff:ff:ff:ff:ff ' - '-s 10.0.0.1 -j RETURN'), - mock.call.add_rule('sfake_dev', '-j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 68 --dport 67 -j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sfake_dev'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 67 --dport 68 -j DROP'), - mock.call.add_rule( - 'ofake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sg-fallback'), - mock.call.add_rule('sg-chain', '-j ACCEPT')] - - self.v4filter_inst.assert_has_calls(calls) - - def test_filter_ipv4_ingress(self): - rule = {'ethertype': 'IPv4', - 'direction': 'ingress'} - ingress = mock.call.add_rule('ifake_dev', '-j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule('ifake_dev', '-s %s -j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_tcp(self): - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'tcp'} - ingress = mock.call.add_rule('ifake_dev', '-p tcp -m tcp -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_tcp_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'tcp', - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule('ifake_dev', - '-s %s -p tcp -m tcp -j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_icmp(self): - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'icmp'} - ingress = mock.call.add_rule('ifake_dev', '-p icmp -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_icmp_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'icmp', - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule( - 'ifake_dev', '-s %s -p icmp -j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_tcp_port(self): - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 10} - ingress = mock.call.add_rule('ifake_dev', - '-p tcp -m tcp --dport 10 -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_tcp_mport(self): - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 100} - ingress = mock.call.add_rule( - 'ifake_dev', - '-p tcp -m tcp -m multiport --dports 10:100 -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_tcp_mport_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 100, - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule( - 'ifake_dev', - '-s %s -p tcp -m tcp -m multiport --dports 10:100 ' - '-j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_udp(self): - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'udp'} - ingress = mock.call.add_rule('ifake_dev', '-p udp -m udp -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_udp_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'udp', - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule('ifake_dev', - '-s %s -p udp -m udp -j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_udp_port(self): - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 10} - ingress = mock.call.add_rule('ifake_dev', - '-p udp -m udp --dport 10 -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_udp_mport(self): - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 100} - ingress = mock.call.add_rule( - 'ifake_dev', - '-p udp -m udp -m multiport --dports 10:100 -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_ingress_udp_mport_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'ingress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 100, - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule( - 'ifake_dev', - '-s %s -p udp -m udp -m multiport --dports 10:100 ' - '-j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress(self): - rule = {'ethertype': 'IPv4', - 'direction': 'egress'} - egress = mock.call.add_rule('ofake_dev', '-j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule('ofake_dev', '-s %s -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_tcp(self): - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'tcp'} - egress = mock.call.add_rule('ofake_dev', '-p tcp -m tcp -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_tcp_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'tcp', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule('ofake_dev', - '-s %s -p tcp -m tcp -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_icmp(self): - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'icmp'} - egress = mock.call.add_rule('ofake_dev', '-p icmp -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_icmp_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'icmp', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', '-s %s -p icmp -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_icmp_type(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'icmp', - 'source_port_range_min': 8, - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p icmp --icmp-type 8 -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_icmp_type_name(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'icmp', - 'source_port_range_min': 'echo-request', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p icmp --icmp-type echo-request -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_icmp_type_code(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'icmp', - 'source_port_range_min': 8, - 'source_port_range_max': 0, - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p icmp --icmp-type 8/0 -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_tcp_port(self): - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 10} - egress = mock.call.add_rule('ofake_dev', - '-p tcp -m tcp --dport 10 -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_tcp_mport(self): - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 100} - egress = mock.call.add_rule( - 'ofake_dev', - '-p tcp -m tcp -m multiport --dports 10:100 -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_tcp_mport_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 100, - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p tcp -m tcp -m multiport --dports 10:100 ' - '-j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_udp(self): - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'udp'} - egress = mock.call.add_rule('ofake_dev', '-p udp -m udp -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_udp_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'udp', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule('ofake_dev', - '-s %s -p udp -m udp -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_udp_port(self): - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 10} - egress = mock.call.add_rule('ofake_dev', - '-p udp -m udp --dport 10 -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_udp_mport(self): - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 100} - egress = mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp -m multiport --dports 10:100 -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv4_egress_udp_mport_prefix(self): - prefix = FAKE_PREFIX['IPv4'] - rule = {'ethertype': 'IPv4', - 'direction': 'egress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 100, - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p udp -m udp -m multiport --dports 10:100 ' - '-j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress(self): - rule = {'ethertype': 'IPv6', - 'direction': 'ingress'} - ingress = mock.call.add_rule('ifake_dev', '-j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule('ifake_dev', '-s %s -j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_tcp(self): - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'tcp'} - ingress = mock.call.add_rule('ifake_dev', '-p tcp -m tcp -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_tcp_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'tcp', - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule('ifake_dev', - '-s %s -p tcp -m tcp -j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_tcp_port(self): - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 10} - ingress = mock.call.add_rule('ifake_dev', - '-p tcp -m tcp --dport 10 -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_icmp(self): - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'icmp'} - ingress = mock.call.add_rule('ifake_dev', '-p icmpv6 -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_icmp_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'icmp', - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule( - 'ifake_dev', '-s %s -p icmpv6 -j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_tcp_mport(self): - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 100} - ingress = mock.call.add_rule( - 'ifake_dev', - '-p tcp -m tcp -m multiport --dports 10:100 -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_tcp_mport_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 100, - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule( - 'ifake_dev', - '-s %s -p tcp -m tcp -m multiport --dports 10:100 ' - '-j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_udp(self): - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'udp'} - ingress = mock.call.add_rule('ifake_dev', '-p udp -m udp -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_udp_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'udp', - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule('ifake_dev', - '-s %s -p udp -m udp -j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_udp_port(self): - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 10} - ingress = mock.call.add_rule('ifake_dev', - '-p udp -m udp --dport 10 -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_udp_mport(self): - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 100} - ingress = mock.call.add_rule( - 'ifake_dev', - '-p udp -m udp -m multiport --dports 10:100 -j RETURN') - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_ingress_udp_mport_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'ingress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 100, - 'source_ip_prefix': prefix} - ingress = mock.call.add_rule( - 'ifake_dev', - '-s %s -p udp -m udp -m multiport --dports 10:100 ' - '-j RETURN' % prefix) - egress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress(self): - rule = {'ethertype': 'IPv6', - 'direction': 'egress'} - egress = mock.call.add_rule('ofake_dev', '-j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule('ofake_dev', '-s %s -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_tcp(self): - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'tcp'} - egress = mock.call.add_rule('ofake_dev', '-p tcp -m tcp -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_tcp_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'tcp', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule('ofake_dev', - '-s %s -p tcp -m tcp -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_icmp(self): - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'icmp'} - egress = mock.call.add_rule('ofake_dev', '-p icmpv6 -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_icmp_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'icmp', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', '-s %s -p icmpv6 -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_icmp_type(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'icmp', - 'source_port_range_min': 8, - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p icmpv6 --icmpv6-type 8 -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_icmp_type_name(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'icmp', - 'source_port_range_min': 'echo-request', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p icmpv6 --icmpv6-type echo-request -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_icmp_type_code(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'icmp', - 'source_port_range_min': 8, - 'source_port_range_max': 0, - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p icmpv6 --icmpv6-type 8/0 -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_tcp_port(self): - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 10} - egress = mock.call.add_rule('ofake_dev', - '-p tcp -m tcp --dport 10 -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_tcp_mport(self): - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 100} - egress = mock.call.add_rule( - 'ofake_dev', - '-p tcp -m tcp -m multiport --dports 10:100 -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_tcp_mport_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'tcp', - 'port_range_min': 10, - 'port_range_max': 100, - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p tcp -m tcp -m multiport --dports 10:100 ' - '-j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_udp(self): - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'udp'} - egress = mock.call.add_rule('ofake_dev', '-p udp -m udp -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_udp_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'udp', - 'source_ip_prefix': prefix} - egress = mock.call.add_rule('ofake_dev', - '-s %s -p udp -m udp -j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_udp_port(self): - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 10} - egress = mock.call.add_rule('ofake_dev', - '-p udp -m udp --dport 10 -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_udp_mport(self): - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 100} - egress = mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp -m multiport --dports 10:100 -j RETURN') - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def test_filter_ipv6_egress_udp_mport_prefix(self): - prefix = FAKE_PREFIX['IPv6'] - rule = {'ethertype': 'IPv6', - 'direction': 'egress', - 'protocol': 'udp', - 'port_range_min': 10, - 'port_range_max': 100, - 'source_ip_prefix': prefix} - egress = mock.call.add_rule( - 'ofake_dev', - '-s %s -p udp -m udp -m multiport --dports 10:100 ' - '-j RETURN' % prefix) - ingress = None - self._test_prepare_port_filter(rule, ingress, egress) - - def _test_prepare_port_filter(self, - rule, - ingress_expected_call=None, - egress_expected_call=None): - port = self._fake_port() - ethertype = rule['ethertype'] - prefix = FAKE_IP[ethertype] - filter_inst = self.v4filter_inst - dhcp_rule = [mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 68 --dport 67 -j RETURN')] - - if ethertype == 'IPv6': - filter_inst = self.v6filter_inst - - dhcp_rule = [mock.call.add_rule('ofake_dev', - '-p icmpv6 -j RETURN'), - mock.call.add_rule('ofake_dev', '-p udp -m udp ' - '--sport 546 --dport 547 ' - '-j RETURN')] - sg = [rule] - port['security_group_rules'] = sg - self.firewall.prepare_port_filter(port) - calls = [mock.call.add_chain('sg-fallback'), - mock.call.add_rule('sg-fallback', '-j DROP'), - mock.call.ensure_remove_chain('sg-chain'), - mock.call.add_chain('sg-chain'), - mock.call.add_chain('ifake_dev'), - mock.call.add_rule('FORWARD', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged ' - '-j $sg-chain'), - mock.call.add_rule('sg-chain', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged ' - '-j $ifake_dev'), - ] - if ethertype == 'IPv6': - for icmp6_type in constants.ICMPV6_ALLOWED_TYPES: - calls.append( - mock.call.add_rule('ifake_dev', - '-p icmpv6 --icmpv6-type %s -j RETURN' % - icmp6_type)) - calls += [mock.call.add_rule('ifake_dev', - '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ifake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN')] - - if ingress_expected_call: - calls.append(ingress_expected_call) - - calls += [mock.call.add_rule('ifake_dev', '-j $sg-fallback'), - mock.call.add_chain('ofake_dev'), - mock.call.add_rule('FORWARD', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $sg-chain'), - mock.call.add_rule('sg-chain', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $ofake_dev'), - mock.call.add_rule('INPUT', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $ofake_dev'), - mock.call.add_chain('sfake_dev'), - mock.call.add_rule( - 'sfake_dev', - '-m mac --mac-source ff:ff:ff:ff:ff:ff -s %s -j RETURN' - % prefix), - mock.call.add_rule('sfake_dev', '-j DROP')] - calls += dhcp_rule - calls.append(mock.call.add_rule('ofake_dev', '-j $sfake_dev')) - if ethertype == 'IPv4': - calls.append(mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 67 --dport 68 -j DROP')) - if ethertype == 'IPv6': - calls.append(mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 547 --dport 546 -j DROP')) - - calls += [mock.call.add_rule( - 'ofake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN')] - - if egress_expected_call: - calls.append(egress_expected_call) - - calls += [mock.call.add_rule('ofake_dev', '-j $sg-fallback'), - mock.call.add_rule('sg-chain', '-j ACCEPT')] - - filter_inst.assert_has_calls(calls) - - def test_update_delete_port_filter(self): - port = self._fake_port() - port['security_group_rules'] = [{'ethertype': 'IPv4', - 'direction': 'ingress'}] - self.firewall.prepare_port_filter(port) - port['security_group_rules'] = [{'ethertype': 'IPv4', - 'direction': 'egress'}] - self.firewall.update_port_filter(port) - self.firewall.update_port_filter({'device': 'no-exist-device'}) - self.firewall.remove_port_filter(port) - self.firewall.remove_port_filter({'device': 'no-exist-device'}) - calls = [mock.call.add_chain('sg-fallback'), - mock.call.add_rule('sg-fallback', '-j DROP'), - mock.call.ensure_remove_chain('sg-chain'), - mock.call.add_chain('sg-chain'), - mock.call.add_chain('ifake_dev'), - mock.call.add_rule( - 'FORWARD', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged -j $sg-chain'), - mock.call.add_rule( - 'sg-chain', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged -j $ifake_dev'), - mock.call.add_rule( - 'ifake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ifake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ifake_dev', '-j RETURN'), - mock.call.add_rule('ifake_dev', '-j $sg-fallback'), - mock.call.add_chain('ofake_dev'), - mock.call.add_rule( - 'FORWARD', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged -j $sg-chain'), - mock.call.add_rule( - 'sg-chain', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged -j $ofake_dev'), - mock.call.add_rule( - 'INPUT', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged -j $ofake_dev'), - mock.call.add_chain('sfake_dev'), - mock.call.add_rule( - 'sfake_dev', - '-m mac --mac-source ff:ff:ff:ff:ff:ff -s 10.0.0.1 ' - '-j RETURN'), - mock.call.add_rule('sfake_dev', '-j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 68 --dport 67 -j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sfake_dev'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 67 --dport 68 -j DROP'), - mock.call.add_rule( - 'ofake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sg-fallback'), - mock.call.add_rule('sg-chain', '-j ACCEPT'), - mock.call.ensure_remove_chain('ifake_dev'), - mock.call.ensure_remove_chain('ofake_dev'), - mock.call.ensure_remove_chain('sfake_dev'), - mock.call.ensure_remove_chain('sg-chain'), - mock.call.add_chain('sg-chain'), - mock.call.add_chain('ifake_dev'), - mock.call.add_rule( - 'FORWARD', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged -j $sg-chain'), - mock.call.add_rule( - 'sg-chain', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged -j $ifake_dev'), - mock.call.add_rule( - 'ifake_dev', - '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ifake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ifake_dev', '-j $sg-fallback'), - mock.call.add_chain('ofake_dev'), - mock.call.add_rule( - 'FORWARD', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged -j $sg-chain'), - mock.call.add_rule( - 'sg-chain', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged -j $ofake_dev'), - mock.call.add_rule( - 'INPUT', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged -j $ofake_dev'), - mock.call.add_chain('sfake_dev'), - mock.call.add_rule( - 'sfake_dev', - '-m mac --mac-source ff:ff:ff:ff:ff:ff -s 10.0.0.1 ' - '-j RETURN'), - mock.call.add_rule('sfake_dev', '-j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 68 --dport 67 -j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sfake_dev'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 67 --dport 68 -j DROP'), - mock.call.add_rule( - 'ofake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ofake_dev', '-j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sg-fallback'), - mock.call.add_rule('sg-chain', '-j ACCEPT'), - mock.call.ensure_remove_chain('ifake_dev'), - mock.call.ensure_remove_chain('ofake_dev'), - mock.call.ensure_remove_chain('sfake_dev'), - mock.call.ensure_remove_chain('sg-chain'), - mock.call.add_chain('sg-chain')] - - self.v4filter_inst.assert_has_calls(calls) - - def test_remove_unknown_port(self): - port = self._fake_port() - self.firewall.remove_port_filter(port) - # checking no exception occures - self.v4filter_inst.assert_has_calls([]) - - def test_defer_apply(self): - with self.firewall.defer_apply(): - pass - self.iptables_inst.assert_has_calls([mock.call.defer_apply_on(), - mock.call.defer_apply_off()]) - - def test_filter_defer_with_exception(self): - try: - with self.firewall.defer_apply(): - raise Exception("same exception") - except Exception: - pass - self.iptables_inst.assert_has_calls([mock.call.defer_apply_on(), - mock.call.defer_apply_off()]) - - def _mock_chain_applies(self): - class CopyingMock(mock.MagicMock): - """Copies arguments so mutable arguments can be asserted on. - - Copied verbatim from unittest.mock documentation. - """ - def __call__(self, *args, **kwargs): - args = copy.deepcopy(args) - kwargs = copy.deepcopy(kwargs) - return super(CopyingMock, self).__call__(*args, **kwargs) - # Need to use CopyingMock because _{setup,remove}_chains_apply are - # usually called with that's modified between calls (i.e., - # self.firewall.filtered_ports). - chain_applies = CopyingMock() - self.firewall._setup_chains_apply = chain_applies.setup - self.firewall._remove_chains_apply = chain_applies.remove - return chain_applies - - def test_mock_chain_applies(self): - chain_applies = self._mock_chain_applies() - port_prepare = {'device': 'd1', 'mac_address': 'prepare'} - port_update = {'device': 'd1', 'mac_address': 'update'} - self.firewall.prepare_port_filter(port_prepare) - self.firewall.update_port_filter(port_update) - self.firewall.remove_port_filter(port_update) - chain_applies.assert_has_calls([mock.call.remove({}), - mock.call.setup({'d1': port_prepare}), - mock.call.remove({'d1': port_prepare}), - mock.call.setup({'d1': port_update}), - mock.call.remove({'d1': port_update}), - mock.call.setup({})]) - - def test_defer_chain_apply_need_pre_defer_copy(self): - chain_applies = self._mock_chain_applies() - port = self._fake_port() - device2port = {port['device']: port} - self.firewall.prepare_port_filter(port) - with self.firewall.defer_apply(): - self.firewall.remove_port_filter(port) - chain_applies.assert_has_calls([mock.call.remove({}), - mock.call.setup(device2port), - mock.call.remove(device2port), - mock.call.setup({})]) - - def test_defer_chain_apply_coalesce_simple(self): - chain_applies = self._mock_chain_applies() - port = self._fake_port() - with self.firewall.defer_apply(): - self.firewall.prepare_port_filter(port) - self.firewall.update_port_filter(port) - self.firewall.remove_port_filter(port) - chain_applies.assert_has_calls([mock.call.remove({}), - mock.call.setup({})]) - - def test_defer_chain_apply_coalesce_multiple_ports(self): - chain_applies = self._mock_chain_applies() - port1 = {'device': 'd1', 'mac_address': 'mac1'} - port2 = {'device': 'd2', 'mac_address': 'mac2'} - device2port = {'d1': port1, 'd2': port2} - with self.firewall.defer_apply(): - self.firewall.prepare_port_filter(port1) - self.firewall.prepare_port_filter(port2) - chain_applies.assert_has_calls([mock.call.remove({}), - mock.call.setup(device2port)]) - - def test_ip_spoofing_filter_with_multiple_ips(self): - port = {'device': 'tapfake_dev', - 'mac_address': 'ff:ff:ff:ff:ff:ff', - 'fixed_ips': ['10.0.0.1', 'fe80::1', '10.0.0.2']} - self.firewall.prepare_port_filter(port) - calls = [mock.call.add_chain('sg-fallback'), - mock.call.add_rule('sg-fallback', '-j DROP'), - mock.call.ensure_remove_chain('sg-chain'), - mock.call.add_chain('sg-chain'), - mock.call.add_chain('ifake_dev'), - mock.call.add_rule('FORWARD', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged ' - '-j $sg-chain'), - mock.call.add_rule('sg-chain', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged ' - '-j $ifake_dev'), - mock.call.add_rule( - 'ifake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ifake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ifake_dev', '-j $sg-fallback'), - mock.call.add_chain('ofake_dev'), - mock.call.add_rule('FORWARD', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $sg-chain'), - mock.call.add_rule('sg-chain', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $ofake_dev'), - mock.call.add_rule('INPUT', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $ofake_dev'), - mock.call.add_chain('sfake_dev'), - mock.call.add_rule( - 'sfake_dev', - '-m mac --mac-source ff:ff:ff:ff:ff:ff -s 10.0.0.1 ' - '-j RETURN'), - mock.call.add_rule( - 'sfake_dev', - '-m mac --mac-source ff:ff:ff:ff:ff:ff -s 10.0.0.2 ' - '-j RETURN'), - mock.call.add_rule('sfake_dev', '-j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 68 --dport 67 -j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sfake_dev'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 67 --dport 68 -j DROP'), - mock.call.add_rule( - 'ofake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sg-fallback'), - mock.call.add_rule('sg-chain', '-j ACCEPT')] - self.v4filter_inst.assert_has_calls(calls) - - def test_ip_spoofing_no_fixed_ips(self): - port = {'device': 'tapfake_dev', - 'mac_address': 'ff:ff:ff:ff:ff:ff', - 'fixed_ips': []} - self.firewall.prepare_port_filter(port) - calls = [mock.call.add_chain('sg-fallback'), - mock.call.add_rule('sg-fallback', '-j DROP'), - mock.call.ensure_remove_chain('sg-chain'), - mock.call.add_chain('sg-chain'), - mock.call.add_chain('ifake_dev'), - mock.call.add_rule('FORWARD', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged ' - '-j $sg-chain'), - mock.call.add_rule('sg-chain', - '-m physdev --physdev-out tapfake_dev ' - '--physdev-is-bridged ' - '-j $ifake_dev'), - mock.call.add_rule( - 'ifake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ifake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ifake_dev', '-j $sg-fallback'), - mock.call.add_chain('ofake_dev'), - mock.call.add_rule('FORWARD', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $sg-chain'), - mock.call.add_rule('sg-chain', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $ofake_dev'), - mock.call.add_rule('INPUT', - '-m physdev --physdev-in tapfake_dev ' - '--physdev-is-bridged ' - '-j $ofake_dev'), - mock.call.add_chain('sfake_dev'), - mock.call.add_rule( - 'sfake_dev', - '-m mac --mac-source ff:ff:ff:ff:ff:ff -j RETURN'), - mock.call.add_rule('sfake_dev', '-j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 68 --dport 67 -j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sfake_dev'), - mock.call.add_rule( - 'ofake_dev', - '-p udp -m udp --sport 67 --dport 68 -j DROP'), - mock.call.add_rule( - 'ofake_dev', '-m state --state INVALID -j DROP'), - mock.call.add_rule( - 'ofake_dev', - '-m state --state RELATED,ESTABLISHED -j RETURN'), - mock.call.add_rule('ofake_dev', '-j $sg-fallback'), - mock.call.add_rule('sg-chain', '-j ACCEPT')] - self.v4filter_inst.assert_has_calls(calls) diff --git a/neutron/tests/unit/test_iptables_manager.py b/neutron/tests/unit/test_iptables_manager.py deleted file mode 100644 index 5e16406bd..000000000 --- a/neutron/tests/unit/test_iptables_manager.py +++ /dev/null @@ -1,705 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Locaweb. -# All Rights Reserved. -# -# 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. -# -# @author: Juliano Martinez, Locaweb. - -import inspect -import os - -import mock - -from neutron.agent.linux import iptables_manager -from neutron.tests import base -from neutron.tests import tools - - -IPTABLES_ARG = {'bn': iptables_manager.binary_name} - -NAT_DUMP = ('# Generated by iptables_manager\n' - '*nat\n' - ':neutron-postrouting-bottom - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - ':%(bn)s-snat - [0:0]\n' - ':%(bn)s-PREROUTING - [0:0]\n' - ':%(bn)s-float-snat - [0:0]\n' - ':%(bn)s-POSTROUTING - [0:0]\n' - '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n' - '[0:0] -A POSTROUTING -j neutron-postrouting-bottom\n' - '[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat\n' - '[0:0] -A %(bn)s-snat -j ' - '%(bn)s-float-snat\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' % IPTABLES_ARG) - -FILTER_DUMP = ('# Generated by iptables_manager\n' - '*filter\n' - ':neutron-filter-top - [0:0]\n' - ':%(bn)s-FORWARD - [0:0]\n' - ':%(bn)s-INPUT - [0:0]\n' - ':%(bn)s-local - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - '[0:0] -A FORWARD -j neutron-filter-top\n' - '[0:0] -A OUTPUT -j neutron-filter-top\n' - '[0:0] -A neutron-filter-top -j %(bn)s-local\n' - '[0:0] -A INPUT -j %(bn)s-INPUT\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A FORWARD -j %(bn)s-FORWARD\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' % IPTABLES_ARG) - - -class IptablesManagerStateFulTestCase(base.BaseTestCase): - - def setUp(self): - super(IptablesManagerStateFulTestCase, self).setUp() - self.root_helper = 'sudo' - self.iptables = (iptables_manager. - IptablesManager(root_helper=self.root_helper)) - self.execute = mock.patch.object(self.iptables, "execute").start() - - def test_binary_name(self): - self.assertEqual(iptables_manager.binary_name, - os.path.basename(inspect.stack()[-1][1])[:16]) - - def test_get_chain_name(self): - name = '0123456789' * 5 - # 28 chars is the maximum length of iptables chain name. - self.assertEqual(iptables_manager.get_chain_name(name, wrap=False), - name[:28]) - # 11 chars is the maximum length of chain name of iptable_manager - # if binary_name is prepended. - self.assertEqual(iptables_manager.get_chain_name(name, wrap=True), - name[:11]) - - def test_add_and_remove_chain_custom_binary_name(self): - bn = ("abcdef" * 5) - - self.iptables = (iptables_manager. - IptablesManager(root_helper=self.root_helper, - binary_name=bn)) - self.execute = mock.patch.object(self.iptables, "execute").start() - - iptables_args = {'bn': bn[:16]} - - filter_dump = ('# Generated by iptables_manager\n' - '*filter\n' - ':neutron-filter-top - [0:0]\n' - ':%(bn)s-FORWARD - [0:0]\n' - ':%(bn)s-INPUT - [0:0]\n' - ':%(bn)s-local - [0:0]\n' - ':%(bn)s-filter - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - '[0:0] -A FORWARD -j neutron-filter-top\n' - '[0:0] -A OUTPUT -j neutron-filter-top\n' - '[0:0] -A neutron-filter-top -j %(bn)s-local\n' - '[0:0] -A INPUT -j %(bn)s-INPUT\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A FORWARD -j %(bn)s-FORWARD\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' % iptables_args) - - filter_dump_mod = ('# Generated by iptables_manager\n' - '*filter\n' - ':neutron-filter-top - [0:0]\n' - ':%(bn)s-FORWARD - [0:0]\n' - ':%(bn)s-INPUT - [0:0]\n' - ':%(bn)s-local - [0:0]\n' - ':%(bn)s-filter - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - '[0:0] -A FORWARD -j neutron-filter-top\n' - '[0:0] -A OUTPUT -j neutron-filter-top\n' - '[0:0] -A neutron-filter-top -j %(bn)s-local\n' - '[0:0] -A INPUT -j %(bn)s-INPUT\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A FORWARD -j %(bn)s-FORWARD\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' - % iptables_args) - - nat_dump = ('# Generated by iptables_manager\n' - '*nat\n' - ':neutron-postrouting-bottom - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - ':%(bn)s-snat - [0:0]\n' - ':%(bn)s-PREROUTING - [0:0]\n' - ':%(bn)s-float-snat - [0:0]\n' - ':%(bn)s-POSTROUTING - [0:0]\n' - '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n' - '[0:0] -A POSTROUTING -j neutron-postrouting-bottom\n' - '[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat\n' - '[0:0] -A %(bn)s-snat -j ' - '%(bn)s-float-snat\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' % iptables_args) - - expected_calls_and_values = [ - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=nat_dump + filter_dump_mod, - root_helper=self.root_helper), - None), - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=nat_dump + filter_dump, - root_helper=self.root_helper), - None), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - self.iptables.ipv4['filter'].add_chain('filter') - self.iptables.apply() - - self.iptables.ipv4['filter'].empty_chain('filter') - self.iptables.apply() - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_empty_chain_custom_binary_name(self): - bn = ("abcdef" * 5)[:16] - - self.iptables = (iptables_manager. - IptablesManager(root_helper=self.root_helper, - binary_name=bn)) - self.execute = mock.patch.object(self.iptables, "execute").start() - - iptables_args = {'bn': bn} - - filter_dump = ('# Generated by iptables_manager\n' - '*filter\n' - ':neutron-filter-top - [0:0]\n' - ':%(bn)s-FORWARD - [0:0]\n' - ':%(bn)s-INPUT - [0:0]\n' - ':%(bn)s-local - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - '[0:0] -A FORWARD -j neutron-filter-top\n' - '[0:0] -A OUTPUT -j neutron-filter-top\n' - '[0:0] -A neutron-filter-top -j %(bn)s-local\n' - '[0:0] -A INPUT -j %(bn)s-INPUT\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A FORWARD -j %(bn)s-FORWARD\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' % iptables_args) - - filter_dump_mod = ('# Generated by iptables_manager\n' - '*filter\n' - ':neutron-filter-top - [0:0]\n' - ':%(bn)s-FORWARD - [0:0]\n' - ':%(bn)s-INPUT - [0:0]\n' - ':%(bn)s-local - [0:0]\n' - ':%(bn)s-filter - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - '[0:0] -A FORWARD -j neutron-filter-top\n' - '[0:0] -A OUTPUT -j neutron-filter-top\n' - '[0:0] -A neutron-filter-top -j %(bn)s-local\n' - '[0:0] -A INPUT -j %(bn)s-INPUT\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A FORWARD -j %(bn)s-FORWARD\n' - '[0:0] -A %(bn)s-filter -s 0/0 -d 192.168.0.2\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' - % iptables_args) - - nat_dump = ('# Generated by iptables_manager\n' - '*nat\n' - ':neutron-postrouting-bottom - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - ':%(bn)s-snat - [0:0]\n' - ':%(bn)s-PREROUTING - [0:0]\n' - ':%(bn)s-float-snat - [0:0]\n' - ':%(bn)s-POSTROUTING - [0:0]\n' - '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n' - '[0:0] -A POSTROUTING -j neutron-postrouting-bottom\n' - '[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat\n' - '[0:0] -A %(bn)s-snat -j ' - '%(bn)s-float-snat\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' % iptables_args) - - expected_calls_and_values = [ - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=nat_dump + filter_dump_mod, - root_helper=self.root_helper), - None), - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=nat_dump + filter_dump, - root_helper=self.root_helper), - None), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - self.iptables.ipv4['filter'].add_chain('filter') - self.iptables.ipv4['filter'].add_rule('filter', - '-s 0/0 -d 192.168.0.2') - self.iptables.apply() - - self.iptables.ipv4['filter'].remove_chain('filter') - self.iptables.apply() - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_add_and_remove_chain(self): - filter_dump_mod = ('# Generated by iptables_manager\n' - '*filter\n' - ':neutron-filter-top - [0:0]\n' - ':%(bn)s-FORWARD - [0:0]\n' - ':%(bn)s-INPUT - [0:0]\n' - ':%(bn)s-local - [0:0]\n' - ':%(bn)s-filter - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - '[0:0] -A FORWARD -j neutron-filter-top\n' - '[0:0] -A OUTPUT -j neutron-filter-top\n' - '[0:0] -A neutron-filter-top -j %(bn)s-local\n' - '[0:0] -A INPUT -j %(bn)s-INPUT\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A FORWARD -j %(bn)s-FORWARD\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' - % IPTABLES_ARG) - - expected_calls_and_values = [ - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=NAT_DUMP + filter_dump_mod, - root_helper=self.root_helper), - None), - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=NAT_DUMP + FILTER_DUMP, - root_helper=self.root_helper), - None), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - self.iptables.ipv4['filter'].add_chain('filter') - self.iptables.apply() - - self.iptables.ipv4['filter'].remove_chain('filter') - self.iptables.apply() - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_add_filter_rule(self): - filter_dump_mod = ('# Generated by iptables_manager\n' - '*filter\n' - ':neutron-filter-top - [0:0]\n' - ':%(bn)s-FORWARD - [0:0]\n' - ':%(bn)s-INPUT - [0:0]\n' - ':%(bn)s-local - [0:0]\n' - ':%(bn)s-filter - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - '[0:0] -A FORWARD -j neutron-filter-top\n' - '[0:0] -A OUTPUT -j neutron-filter-top\n' - '[0:0] -A neutron-filter-top -j %(bn)s-local\n' - '[0:0] -A INPUT -j %(bn)s-INPUT\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A FORWARD -j %(bn)s-FORWARD\n' - '[0:0] -A %(bn)s-filter -j DROP\n' - '[0:0] -A %(bn)s-INPUT -s 0/0 -d 192.168.0.2 -j ' - '%(bn)s-filter\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' - % IPTABLES_ARG) - - expected_calls_and_values = [ - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=NAT_DUMP + filter_dump_mod, - root_helper=self.root_helper), - None), - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=NAT_DUMP + FILTER_DUMP, - root_helper=self.root_helper - ), - None), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - self.iptables.ipv4['filter'].add_chain('filter') - self.iptables.ipv4['filter'].add_rule('filter', '-j DROP') - self.iptables.ipv4['filter'].add_rule('INPUT', - '-s 0/0 -d 192.168.0.2 -j' - ' %(bn)s-filter' % IPTABLES_ARG) - self.iptables.apply() - - self.iptables.ipv4['filter'].remove_rule('filter', '-j DROP') - self.iptables.ipv4['filter'].remove_rule('INPUT', - '-s 0/0 -d 192.168.0.2 -j' - ' %(bn)s-filter' - % IPTABLES_ARG) - self.iptables.ipv4['filter'].remove_chain('filter') - - self.iptables.apply() - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_rule_with_wrap_target(self): - name = '0123456789' * 5 - wrap = "%s-%s" % (iptables_manager.binary_name, - iptables_manager.get_chain_name(name)) - - iptables_args = {'bn': iptables_manager.binary_name, - 'wrap': wrap} - - filter_dump_mod = ('# Generated by iptables_manager\n' - '*filter\n' - ':neutron-filter-top - [0:0]\n' - ':%(bn)s-FORWARD - [0:0]\n' - ':%(bn)s-INPUT - [0:0]\n' - ':%(bn)s-local - [0:0]\n' - ':%(wrap)s - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - '[0:0] -A FORWARD -j neutron-filter-top\n' - '[0:0] -A OUTPUT -j neutron-filter-top\n' - '[0:0] -A neutron-filter-top -j %(bn)s-local\n' - '[0:0] -A INPUT -j %(bn)s-INPUT\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A FORWARD -j %(bn)s-FORWARD\n' - '[0:0] -A %(bn)s-INPUT -s 0/0 -d 192.168.0.2 -j ' - '%(wrap)s\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' - % iptables_args) - - expected_calls_and_values = [ - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=NAT_DUMP + filter_dump_mod, - root_helper=self.root_helper), - None), - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=NAT_DUMP + FILTER_DUMP, - root_helper=self.root_helper), - None), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - self.iptables.ipv4['filter'].add_chain(name) - self.iptables.ipv4['filter'].add_rule('INPUT', - '-s 0/0 -d 192.168.0.2 -j' - ' $%s' % name) - self.iptables.apply() - - self.iptables.ipv4['filter'].remove_rule('INPUT', - '-s 0/0 -d 192.168.0.2 -j' - ' $%s' % name) - self.iptables.ipv4['filter'].remove_chain(name) - - self.iptables.apply() - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_add_nat_rule(self): - nat_dump = ('# Generated by iptables_manager\n' - '*nat\n' - ':neutron-postrouting-bottom - [0:0]\n' - ':%(bn)s-float-snat - [0:0]\n' - ':%(bn)s-POSTROUTING - [0:0]\n' - ':%(bn)s-PREROUTING - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - ':%(bn)s-snat - [0:0]\n' - '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n' - '[0:0] -A POSTROUTING -j neutron-postrouting-bottom\n' - '[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat\n' - '[0:0] -A %(bn)s-snat -j %(bn)s-float-snat\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' - % IPTABLES_ARG) - - nat_dump_mod = ('# Generated by iptables_manager\n' - '*nat\n' - ':neutron-postrouting-bottom - [0:0]\n' - ':%(bn)s-float-snat - [0:0]\n' - ':%(bn)s-POSTROUTING - [0:0]\n' - ':%(bn)s-PREROUTING - [0:0]\n' - ':%(bn)s-nat - [0:0]\n' - ':%(bn)s-OUTPUT - [0:0]\n' - ':%(bn)s-snat - [0:0]\n' - '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n' - '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' - '[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n' - '[0:0] -A POSTROUTING -j neutron-postrouting-bottom\n' - '[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat\n' - '[0:0] -A %(bn)s-snat -j %(bn)s-float-snat\n' - '[0:0] -A %(bn)s-PREROUTING -d 192.168.0.3 -j ' - '%(bn)s-nat\n' - '[0:0] -A %(bn)s-nat -p tcp --dport 8080 -j ' - 'REDIRECT --to-port 80\n' - 'COMMIT\n' - '# Completed by iptables_manager\n' - % IPTABLES_ARG) - - expected_calls_and_values = [ - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=nat_dump_mod + FILTER_DUMP, - root_helper=self.root_helper), - None), - (mock.call(['iptables-save', '-c'], - root_helper=self.root_helper), - ''), - (mock.call(['iptables-restore', '-c'], - process_input=nat_dump + FILTER_DUMP, - root_helper=self.root_helper), - None), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - self.iptables.ipv4['nat'].add_chain('nat') - self.iptables.ipv4['nat'].add_rule('PREROUTING', - '-d 192.168.0.3 -j ' - '%(bn)s-nat' % IPTABLES_ARG) - self.iptables.ipv4['nat'].add_rule('nat', - '-p tcp --dport 8080' + - ' -j REDIRECT --to-port 80') - - self.iptables.apply() - - self.iptables.ipv4['nat'].remove_rule('nat', - '-p tcp --dport 8080 -j' - ' REDIRECT --to-port 80') - self.iptables.ipv4['nat'].remove_rule('PREROUTING', - '-d 192.168.0.3 -j ' - '%(bn)s-nat' % IPTABLES_ARG) - self.iptables.ipv4['nat'].remove_chain('nat') - - self.iptables.apply() - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_add_rule_to_a_nonexistent_chain(self): - self.assertRaises(LookupError, self.iptables.ipv4['filter'].add_rule, - 'nonexistent', '-j DROP') - - def test_remove_nonexistent_chain(self): - with mock.patch.object(iptables_manager, "LOG") as log: - self.iptables.ipv4['filter'].remove_chain('nonexistent') - log.warn.assert_called_once_with( - 'Attempted to remove chain %s which does not exist', - 'nonexistent') - - def test_remove_nonexistent_rule(self): - with mock.patch.object(iptables_manager, "LOG") as log: - self.iptables.ipv4['filter'].remove_rule('nonexistent', '-j DROP') - log.warn.assert_called_once_with( - 'Tried to remove rule that was not there: ' - '%(chain)r %(rule)r %(wrap)r %(top)r', - {'wrap': True, 'top': False, 'rule': '-j DROP', - 'chain': 'nonexistent'}) - - def test_iptables_failure_with_no_failing_line_number(self): - with mock.patch.object(iptables_manager, "LOG") as log: - # generate Runtime errors on iptables-restore calls - def iptables_restore_failer(*args, **kwargs): - if 'iptables-restore' in args[0]: - self.input_lines = kwargs['process_input'].split('\n') - # don't provide a specific failure message so all lines - # are logged - raise RuntimeError() - return FILTER_DUMP - self.execute.side_effect = iptables_restore_failer - # _apply_synchronized calls iptables-restore so it should raise - # a RuntimeError - self.assertRaises(RuntimeError, - self.iptables._apply_synchronized) - # The RuntimeError should have triggered a log of the input to the - # process that it failed to execute. Verify by comparing the log - # call to the 'process_input' arg given to the failed iptables-restore - # call. - # Failure without a specific line number in the error should cause - # all lines to be logged with numbers. - logged = ['%7d. %s' % (n, l) - for n, l in enumerate(self.input_lines, 1)] - log.error.assert_called_once_with(_( - 'IPTablesManager.apply failed to apply the ' - 'following set of iptables rules:\n%s'), - '\n'.join(logged) - ) - - def test_iptables_failure_on_specific_line(self): - with mock.patch.object(iptables_manager, "LOG") as log: - # generate Runtime errors on iptables-restore calls - def iptables_restore_failer(*args, **kwargs): - if 'iptables-restore' in args[0]: - self.input_lines = kwargs['process_input'].split('\n') - # pretend line 11 failed - msg = ("Exit code: 1\nStdout: ''\n" - "Stderr: 'iptables-restore: line 11 failed\n'") - raise RuntimeError(msg) - return FILTER_DUMP - self.execute.side_effect = iptables_restore_failer - # _apply_synchronized calls iptables-restore so it should raise - # a RuntimeError - self.assertRaises(RuntimeError, - self.iptables._apply_synchronized) - # The RuntimeError should have triggered a log of the input to the - # process that it failed to execute. Verify by comparing the log - # call to the 'process_input' arg given to the failed iptables-restore - # call. - # Line 11 of the input was marked as failing so lines (11 - context) - # to (11 + context) should be logged - ctx = iptables_manager.IPTABLES_ERROR_LINES_OF_CONTEXT - log_start = max(0, 11 - ctx) - log_end = 11 + ctx - logged = ['%7d. %s' % (n, l) - for n, l in enumerate(self.input_lines[log_start:log_end], - log_start + 1)] - log.error.assert_called_once_with(_( - 'IPTablesManager.apply failed to apply the ' - 'following set of iptables rules:\n%s'), - '\n'.join(logged) - ) - - def test_get_traffic_counters_chain_notexists(self): - with mock.patch.object(iptables_manager, "LOG") as log: - acc = self.iptables.get_traffic_counters('chain1') - self.assertIsNone(acc) - self.assertEqual(0, self.execute.call_count) - log.warn.assert_called_once_with( - 'Attempted to get traffic counters of chain %s which ' - 'does not exist', 'chain1') - - def test_get_traffic_counters(self): - iptables_dump = ( - 'Chain OUTPUT (policy ACCEPT 400 packets, 65901 bytes)\n' - ' pkts bytes target prot opt in out source' - ' destination \n' - ' 400 65901 chain1 all -- * * 0.0.0.0/0' - ' 0.0.0.0/0 \n' - ' 400 65901 chain2 all -- * * 0.0.0.0/0' - ' 0.0.0.0/0 \n') - - expected_calls_and_values = [ - (mock.call(['iptables', '-t', 'filter', '-L', 'OUTPUT', - '-n', '-v', '-x'], - root_helper=self.root_helper), - iptables_dump), - (mock.call(['iptables', '-t', 'nat', '-L', 'OUTPUT', '-n', - '-v', '-x'], - root_helper=self.root_helper), - ''), - (mock.call(['ip6tables', '-t', 'filter', '-L', 'OUTPUT', - '-n', '-v', '-x'], - root_helper=self.root_helper), - iptables_dump), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - acc = self.iptables.get_traffic_counters('OUTPUT') - self.assertEqual(acc['pkts'], 1600) - self.assertEqual(acc['bytes'], 263604) - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def test_get_traffic_counters_with_zero(self): - iptables_dump = ( - 'Chain OUTPUT (policy ACCEPT 400 packets, 65901 bytes)\n' - ' pkts bytes target prot opt in out source' - ' destination \n' - ' 400 65901 chain1 all -- * * 0.0.0.0/0' - ' 0.0.0.0/0 \n' - ' 400 65901 chain2 all -- * * 0.0.0.0/0' - ' 0.0.0.0/0 \n') - - expected_calls_and_values = [ - (mock.call(['iptables', '-t', 'filter', '-L', 'OUTPUT', - '-n', '-v', '-x', '-Z'], - root_helper=self.root_helper), - iptables_dump), - (mock.call(['iptables', '-t', 'nat', '-L', 'OUTPUT', '-n', - '-v', '-x', '-Z'], - root_helper=self.root_helper), - ''), - (mock.call(['ip6tables', '-t', 'filter', '-L', 'OUTPUT', - '-n', '-v', '-x', '-Z'], - root_helper=self.root_helper), - iptables_dump), - ] - tools.setup_mock_calls(self.execute, expected_calls_and_values) - - acc = self.iptables.get_traffic_counters('OUTPUT', zero=True) - self.assertEqual(acc['pkts'], 1600) - self.assertEqual(acc['bytes'], 263604) - - tools.verify_mock_calls(self.execute, expected_calls_and_values) - - def _test_find_last_entry(self, find_str): - filter_list = [':neutron-filter-top - [0:0]', - ':%(bn)s-FORWARD - [0:0]', - ':%(bn)s-INPUT - [0:0]', - ':%(bn)s-local - [0:0]', - ':%(wrap)s - [0:0]', - ':%(bn)s-OUTPUT - [0:0]', - '[0:0] -A FORWARD -j neutron-filter-top', - '[0:0] -A OUTPUT -j neutron-filter-top' - % IPTABLES_ARG] - - return self.iptables._find_last_entry(filter_list, find_str) - - def test_find_last_entry_old_dup(self): - find_str = 'neutron-filter-top' - match_str = '[0:0] -A OUTPUT -j neutron-filter-top' - ret_str = self._test_find_last_entry(find_str) - self.assertEqual(ret_str, match_str) - - def test_find_last_entry_none(self): - find_str = 'neutron-filter-NOTFOUND' - ret_str = self._test_find_last_entry(find_str) - self.assertIsNone(ret_str) - - -class IptablesManagerStateLessTestCase(base.BaseTestCase): - - def setUp(self): - super(IptablesManagerStateLessTestCase, self).setUp() - self.iptables = (iptables_manager.IptablesManager(state_less=True)) - - def test_nat_not_found(self): - self.assertNotIn('nat', self.iptables.ipv4) diff --git a/neutron/tests/unit/test_ipv6.py b/neutron/tests/unit/test_ipv6.py deleted file mode 100644 index 47bfd2a4b..000000000 --- a/neutron/tests/unit/test_ipv6.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2013 IBM Corp. -# All Rights Reserved. -# -# 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. - -from neutron.common import ipv6_utils -from neutron.tests import base - - -class IPv6byEUI64TestCase(base.BaseTestCase): - """Unit tests for generate IPv6 by EUI-64 operations.""" - - def test_generate_IPv6_by_EUI64(self): - addr = ipv6_utils.get_ipv6_addr_by_EUI64('2001:db8::', - '00:16:3e:33:44:55') - self.assertEqual('2001:db8::216:3eff:fe33:4455', addr.format()) - - def test_generate_IPv6_with_IPv4_prefix(self): - ipv4_prefix = '10.0.8' - mac = '00:16:3e:33:44:55' - self.assertRaises(TypeError, lambda: - ipv6_utils.get_ipv6_addr_by_EUI64(ipv4_prefix, mac)) - - def test_generate_IPv6_with_bad_mac(self): - bad_mac = '00:16:3e:33:44:5Z' - prefix = '2001:db8::' - self.assertRaises(TypeError, lambda: - ipv6_utils.get_ipv6_addr_by_EUI64(prefix, bad_mac)) - - def test_generate_IPv6_with_bad_prefix(self): - mac = '00:16:3e:33:44:55' - bad_prefix = 'bb' - self.assertRaises(TypeError, lambda: - ipv6_utils.get_ipv6_addr_by_EUI64(bad_prefix, mac)) - - def test_generate_IPv6_with_error_prefix_type(self): - mac = '00:16:3e:33:44:55' - prefix = 123 - self.assertRaises(TypeError, lambda: - ipv6_utils.get_ipv6_addr_by_EUI64(prefix, mac)) diff --git a/neutron/tests/unit/test_l3_agent.py b/neutron/tests/unit/test_l3_agent.py deleted file mode 100644 index 841425dfb..000000000 --- a/neutron/tests/unit/test_l3_agent.py +++ /dev/null @@ -1,1379 +0,0 @@ -# Copyright 2012 VMware, Inc. -# All Rights Reserved. -# -# 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 contextlib -import copy - -import mock -import netaddr -from oslo.config import cfg -from testtools import matchers - -from neutron.agent.common import config as agent_config -from neutron.agent import l3_agent -from neutron.agent.linux import interface -from neutron.common import config as base_config -from neutron.common import constants as l3_constants -from neutron.common import exceptions as n_exc -from neutron.openstack.common import processutils -from neutron.openstack.common import uuidutils -from neutron.tests import base - - -_uuid = uuidutils.generate_uuid -HOSTNAME = 'myhost' -FAKE_ID = _uuid() - - -class TestBasicRouterOperations(base.BaseTestCase): - - def setUp(self): - super(TestBasicRouterOperations, self).setUp() - self.conf = cfg.ConfigOpts() - self.conf.register_opts(base_config.core_opts) - self.conf.register_opts(l3_agent.L3NATAgent.OPTS) - agent_config.register_interface_driver_opts_helper(self.conf) - agent_config.register_use_namespaces_opts_helper(self.conf) - agent_config.register_root_helper(self.conf) - self.conf.register_opts(interface.OPTS) - self.conf.set_override('router_id', 'fake_id') - self.conf.set_override('interface_driver', - 'neutron.agent.linux.interface.NullDriver') - self.conf.root_helper = 'sudo' - - self.device_exists_p = mock.patch( - 'neutron.agent.linux.ip_lib.device_exists') - self.device_exists = self.device_exists_p.start() - - self.utils_exec_p = mock.patch( - 'neutron.agent.linux.utils.execute') - self.utils_exec = self.utils_exec_p.start() - - self.external_process_p = mock.patch( - 'neutron.agent.linux.external_process.ProcessManager') - self.external_process = self.external_process_p.start() - - self.send_arp_p = mock.patch( - 'neutron.agent.l3_agent.L3NATAgent._send_gratuitous_arp_packet') - self.send_arp = self.send_arp_p.start() - - self.dvr_cls_p = mock.patch('neutron.agent.linux.interface.NullDriver') - driver_cls = self.dvr_cls_p.start() - self.mock_driver = mock.MagicMock() - self.mock_driver.DEV_NAME_LEN = ( - interface.LinuxInterfaceDriver.DEV_NAME_LEN) - driver_cls.return_value = self.mock_driver - - self.ip_cls_p = mock.patch('neutron.agent.linux.ip_lib.IPWrapper') - ip_cls = self.ip_cls_p.start() - self.mock_ip = mock.MagicMock() - ip_cls.return_value = self.mock_ip - - self.l3pluginApi_cls_p = mock.patch( - 'neutron.agent.l3_agent.L3PluginApi') - l3pluginApi_cls = self.l3pluginApi_cls_p.start() - self.plugin_api = mock.Mock() - l3pluginApi_cls.return_value = self.plugin_api - - self.looping_call_p = mock.patch( - 'neutron.openstack.common.loopingcall.FixedIntervalLoopingCall') - self.looping_call_p.start() - - def test_router_info_create(self): - id = _uuid() - ri = l3_agent.RouterInfo(id, self.conf.root_helper, - self.conf.use_namespaces, None) - - self.assertTrue(ri.ns_name.endswith(id)) - - def test_router_info_create_with_router(self): - id = _uuid() - ex_gw_port = {'id': _uuid(), - 'network_id': _uuid(), - 'fixed_ips': [{'ip_address': '19.4.4.4', - 'subnet_id': _uuid()}], - 'subnet': {'cidr': '19.4.4.0/24', - 'gateway_ip': '19.4.4.1'}} - router = { - 'id': _uuid(), - 'enable_snat': True, - 'routes': [], - 'gw_port': ex_gw_port} - ri = l3_agent.RouterInfo(id, self.conf.root_helper, - self.conf.use_namespaces, router) - self.assertTrue(ri.ns_name.endswith(id)) - self.assertEqual(ri.router, router) - - def test_agent_create(self): - l3_agent.L3NATAgent(HOSTNAME, self.conf) - - def _test_internal_network_action(self, action): - port_id = _uuid() - router_id = _uuid() - network_id = _uuid() - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, None) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - cidr = '99.0.1.9/24' - mac = 'ca:fe:de:ad:be:ef' - interface_name = agent.get_internal_device_name(port_id) - - if action == 'add': - self.device_exists.return_value = False - agent.internal_network_added(ri, network_id, - port_id, cidr, mac) - self.assertEqual(self.mock_driver.plug.call_count, 1) - self.assertEqual(self.mock_driver.init_l3.call_count, 1) - self.send_arp.assert_called_once_with(ri, interface_name, - '99.0.1.9') - elif action == 'remove': - self.device_exists.return_value = True - agent.internal_network_removed(ri, port_id, cidr) - self.assertEqual(self.mock_driver.unplug.call_count, 1) - else: - raise Exception("Invalid action %s" % action) - - def test_agent_add_internal_network(self): - self._test_internal_network_action('add') - - def test_agent_remove_internal_network(self): - self._test_internal_network_action('remove') - - def _test_external_gateway_action(self, action): - router_id = _uuid() - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, None) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - internal_cidrs = ['100.0.1.0/24', '200.74.0.0/16'] - ex_gw_port = {'fixed_ips': [{'ip_address': '20.0.0.30', - 'subnet_id': _uuid()}], - 'subnet': {'gateway_ip': '20.0.0.1'}, - 'extra_subnets': [{'cidr': '172.16.0.0/24'}], - 'id': _uuid(), - 'network_id': _uuid(), - 'mac_address': 'ca:fe:de:ad:be:ef', - 'ip_cidr': '20.0.0.30/24'} - interface_name = agent.get_external_device_name(ex_gw_port['id']) - - if action == 'add': - self.device_exists.return_value = False - ri.router = mock.Mock() - ri.router.get.return_value = [{'floating_ip_address': - '192.168.1.34'}] - agent.external_gateway_added(ri, ex_gw_port, - interface_name, internal_cidrs) - self.assertEqual(self.mock_driver.plug.call_count, 1) - self.assertEqual(self.mock_driver.init_l3.call_count, 1) - self.send_arp.assert_called_once_with(ri, interface_name, - '20.0.0.30') - kwargs = {'preserve_ips': ['192.168.1.34/32'], - 'namespace': 'qrouter-' + router_id, - 'gateway': '20.0.0.1', - 'extra_subnets': [{'cidr': '172.16.0.0/24'}]} - self.mock_driver.init_l3.assert_called_with(interface_name, - ['20.0.0.30/24'], - **kwargs) - - elif action == 'remove': - self.device_exists.return_value = True - agent.external_gateway_removed(ri, ex_gw_port, - interface_name, internal_cidrs) - self.assertEqual(self.mock_driver.unplug.call_count, 1) - else: - raise Exception("Invalid action %s" % action) - - def test_agent_add_external_gateway(self): - self._test_external_gateway_action('add') - - def _test_arping(self, namespace): - if not namespace: - self.conf.set_override('use_namespaces', False) - - router_id = _uuid() - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, None) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - floating_ip = '20.0.0.101' - interface_name = agent.get_external_device_name(router_id) - agent._arping(ri, interface_name, floating_ip) - - arping_cmd = ['arping', '-A', - '-I', interface_name, - '-c', self.conf.send_arp_for_ha, - floating_ip] - self.mock_ip.netns.execute.assert_any_call( - arping_cmd, check_exit_code=True) - - def test_arping_namespace(self): - self._test_arping(namespace=True) - - def test_arping_no_namespace(self): - self._test_arping(namespace=False) - - def test_agent_remove_external_gateway(self): - self._test_external_gateway_action('remove') - - def _check_agent_method_called(self, agent, calls, namespace): - self.mock_ip.netns.execute.assert_has_calls( - [mock.call(call, check_exit_code=False) for call in calls], - any_order=True) - - def _test_routing_table_update(self, namespace): - if not namespace: - self.conf.set_override('use_namespaces', False) - - router_id = _uuid() - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, - None) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - fake_route1 = {'destination': '135.207.0.0/16', - 'nexthop': '1.2.3.4'} - fake_route2 = {'destination': '135.207.111.111/32', - 'nexthop': '1.2.3.4'} - - agent._update_routing_table(ri, 'replace', fake_route1) - expected = [['ip', 'route', 'replace', 'to', '135.207.0.0/16', - 'via', '1.2.3.4']] - self._check_agent_method_called(agent, expected, namespace) - - agent._update_routing_table(ri, 'delete', fake_route1) - expected = [['ip', 'route', 'delete', 'to', '135.207.0.0/16', - 'via', '1.2.3.4']] - self._check_agent_method_called(agent, expected, namespace) - - agent._update_routing_table(ri, 'replace', fake_route2) - expected = [['ip', 'route', 'replace', 'to', '135.207.111.111/32', - 'via', '1.2.3.4']] - self._check_agent_method_called(agent, expected, namespace) - - agent._update_routing_table(ri, 'delete', fake_route2) - expected = [['ip', 'route', 'delete', 'to', '135.207.111.111/32', - 'via', '1.2.3.4']] - self._check_agent_method_called(agent, expected, namespace) - - def test_agent_routing_table_updated(self): - self._test_routing_table_update(namespace=True) - - def test_agent_routing_table_updated_no_namespace(self): - self._test_routing_table_update(namespace=False) - - def test_routes_updated(self): - self._test_routes_updated(namespace=True) - - def test_routes_updated_no_namespace(self): - self._test_routes_updated(namespace=False) - - def _test_routes_updated(self, namespace=True): - if not namespace: - self.conf.set_override('use_namespaces', False) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router_id = _uuid() - - ri = l3_agent.RouterInfo(router_id, self.conf.root_helper, - self.conf.use_namespaces, - None) - ri.router = {} - - fake_old_routes = [] - fake_new_routes = [{'destination': "110.100.31.0/24", - 'nexthop': "10.100.10.30"}, - {'destination': "110.100.30.0/24", - 'nexthop': "10.100.10.30"}] - ri.routes = fake_old_routes - ri.router['routes'] = fake_new_routes - agent.routes_updated(ri) - - expected = [['ip', 'route', 'replace', 'to', '110.100.30.0/24', - 'via', '10.100.10.30'], - ['ip', 'route', 'replace', 'to', '110.100.31.0/24', - 'via', '10.100.10.30']] - - self._check_agent_method_called(agent, expected, namespace) - - fake_new_routes = [{'destination': "110.100.30.0/24", - 'nexthop': "10.100.10.30"}] - ri.router['routes'] = fake_new_routes - agent.routes_updated(ri) - expected = [['ip', 'route', 'delete', 'to', '110.100.31.0/24', - 'via', '10.100.10.30']] - - self._check_agent_method_called(agent, expected, namespace) - fake_new_routes = [] - ri.router['routes'] = fake_new_routes - agent.routes_updated(ri) - - expected = [['ip', 'route', 'delete', 'to', '110.100.30.0/24', - 'via', '10.100.10.30']] - self._check_agent_method_called(agent, expected, namespace) - - def _verify_snat_rules(self, rules, router, negate=False): - interfaces = router[l3_constants.INTERFACE_KEY] - source_cidrs = [] - for interface in interfaces: - prefix = interface['subnet']['cidr'].split('/')[1] - source_cidr = "%s/%s" % (interface['fixed_ips'][0]['ip_address'], - prefix) - source_cidrs.append(source_cidr) - source_nat_ip = router['gw_port']['fixed_ips'][0]['ip_address'] - interface_name = ('qg-%s' % router['gw_port']['id'])[:14] - expected_rules = [ - '! -i %s ! -o %s -m conntrack ! --ctstate DNAT -j ACCEPT' % - (interface_name, interface_name)] - for source_cidr in source_cidrs: - # Create SNAT rules for IPv4 only - if (netaddr.IPNetwork(source_cidr).version == 4 and - netaddr.IPNetwork(source_nat_ip).version == 4): - value_dict = {'source_cidr': source_cidr, - 'source_nat_ip': source_nat_ip} - expected_rules.append('-s %(source_cidr)s -j SNAT --to-source ' - '%(source_nat_ip)s' % value_dict) - for r in rules: - if negate: - self.assertNotIn(r.rule, expected_rules) - else: - self.assertIn(r.rule, expected_rules) - - def _prepare_router_data(self, ip_version=4, - enable_snat=None, num_internal_ports=1): - if ip_version == 4: - ip_addr = '19.4.4.4' - cidr = '19.4.4.0/24' - gateway_ip = '19.4.4.1' - elif ip_version == 6: - ip_addr = 'fd00::4' - cidr = 'fd00::/64' - gateway_ip = 'fd00::1' - - router_id = _uuid() - ex_gw_port = {'id': _uuid(), - 'network_id': _uuid(), - 'fixed_ips': [{'ip_address': ip_addr, - 'subnet_id': _uuid()}], - 'subnet': {'cidr': cidr, - 'gateway_ip': gateway_ip}} - int_ports = [] - for i in range(num_internal_ports): - int_ports.append({'id': _uuid(), - 'network_id': _uuid(), - 'admin_state_up': True, - 'fixed_ips': [{'ip_address': '35.4.%s.4' % i, - 'subnet_id': _uuid()}], - 'mac_address': 'ca:fe:de:ad:be:ef', - 'subnet': {'cidr': '35.4.%s.0/24' % i, - 'gateway_ip': '35.4.%s.1' % i}}) - - router = { - 'id': router_id, - l3_constants.INTERFACE_KEY: int_ports, - 'routes': [], - 'gw_port': ex_gw_port} - if enable_snat is not None: - router['enable_snat'] = enable_snat - return router - - def test_process_router(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - fake_fip_id = 'fake_fip_id' - agent.process_router_floating_ip_addresses = mock.Mock() - agent.process_router_floating_ip_nat_rules = mock.Mock() - agent.process_router_floating_ip_addresses.return_value = { - fake_fip_id: 'ACTIVE'} - agent.external_gateway_added = mock.Mock() - router = self._prepare_router_data() - fake_floatingips1 = {'floatingips': [ - {'id': fake_fip_id, - 'floating_ip_address': '8.8.8.8', - 'fixed_ip_address': '7.7.7.7', - 'port_id': _uuid()}]} - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.process_router(ri) - ex_gw_port = agent._get_ex_gw_port(ri) - agent.process_router_floating_ip_addresses.assert_called_with( - ri, ex_gw_port) - agent.process_router_floating_ip_addresses.reset_mock() - agent.process_router_floating_ip_nat_rules.assert_called_with(ri) - agent.process_router_floating_ip_nat_rules.reset_mock() - - # remap floating IP to a new fixed ip - fake_floatingips2 = copy.deepcopy(fake_floatingips1) - fake_floatingips2['floatingips'][0]['fixed_ip_address'] = '7.7.7.8' - - router[l3_constants.FLOATINGIP_KEY] = fake_floatingips2['floatingips'] - agent.process_router(ri) - ex_gw_port = agent._get_ex_gw_port(ri) - agent.process_router_floating_ip_addresses.assert_called_with( - ri, ex_gw_port) - agent.process_router_floating_ip_addresses.reset_mock() - agent.process_router_floating_ip_nat_rules.assert_called_with(ri) - agent.process_router_floating_ip_nat_rules.reset_mock() - - # remove just the floating ips - del router[l3_constants.FLOATINGIP_KEY] - agent.process_router(ri) - ex_gw_port = agent._get_ex_gw_port(ri) - agent.process_router_floating_ip_addresses.assert_called_with( - ri, ex_gw_port) - agent.process_router_floating_ip_addresses.reset_mock() - agent.process_router_floating_ip_nat_rules.assert_called_with(ri) - agent.process_router_floating_ip_nat_rules.reset_mock() - - # now no ports so state is torn down - del router[l3_constants.INTERFACE_KEY] - del router['gw_port'] - agent.process_router(ri) - self.assertEqual(self.send_arp.call_count, 1) - self.assertFalse(agent.process_router_floating_ip_addresses.called) - self.assertFalse(agent.process_router_floating_ip_nat_rules.called) - - @mock.patch('neutron.agent.linux.ip_lib.IPDevice') - def test_process_router_floating_ip_addresses_add(self, IPDevice): - fip_id = _uuid() - fip = { - 'id': fip_id, 'port_id': _uuid(), - 'floating_ip_address': '15.1.2.3', - 'fixed_ip_address': '192.168.0.1' - } - - IPDevice.return_value = device = mock.Mock() - device.addr.list.return_value = [] - - ri = mock.MagicMock() - ri.router.get.return_value = [fip] - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - fip_statuses = agent.process_router_floating_ip_addresses( - ri, {'id': _uuid()}) - self.assertEqual({fip_id: l3_constants.FLOATINGIP_STATUS_ACTIVE}, - fip_statuses) - device.addr.add.assert_called_once_with(4, '15.1.2.3/32', '15.1.2.3') - - def test_process_router_floating_ip_nat_rules_add(self): - fip = { - 'id': _uuid(), 'port_id': _uuid(), - 'floating_ip_address': '15.1.2.3', - 'fixed_ip_address': '192.168.0.1' - } - - ri = mock.MagicMock() - ri.router.get.return_value = [fip] - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - agent.process_router_floating_ip_nat_rules(ri) - - nat = ri.iptables_manager.ipv4['nat'] - nat.clear_rules_by_tag.assert_called_once_with('floating_ip') - rules = agent.floating_forward_rules('15.1.2.3', '192.168.0.1') - for chain, rule in rules: - nat.add_rule.assert_any_call(chain, rule, tag='floating_ip') - - @mock.patch('neutron.agent.linux.ip_lib.IPDevice') - def test_process_router_floating_ip_addresses_remove(self, IPDevice): - IPDevice.return_value = device = mock.Mock() - device.addr.list.return_value = [{'cidr': '15.1.2.3/32'}] - - ri = mock.MagicMock() - ri.router.get.return_value = [] - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - fip_statuses = agent.process_router_floating_ip_addresses( - ri, {'id': _uuid()}) - self.assertEqual({}, fip_statuses) - device.addr.delete.assert_called_once_with(4, '15.1.2.3/32') - - def test_process_router_floating_ip_nat_rules_remove(self): - ri = mock.MagicMock() - ri.router.get.return_value = [] - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - agent.process_router_floating_ip_nat_rules(ri) - - nat = ri.iptables_manager.ipv4['nat'] - nat = ri.iptables_manager.ipv4['nat`'] - nat.clear_rules_by_tag.assert_called_once_with('floating_ip') - - @mock.patch('neutron.agent.linux.ip_lib.IPDevice') - def test_process_router_floating_ip_addresses_remap(self, IPDevice): - fip_id = _uuid() - fip = { - 'id': fip_id, 'port_id': _uuid(), - 'floating_ip_address': '15.1.2.3', - 'fixed_ip_address': '192.168.0.2' - } - - IPDevice.return_value = device = mock.Mock() - device.addr.list.return_value = [{'cidr': '15.1.2.3/32'}] - ri = mock.MagicMock() - - ri.router.get.return_value = [fip] - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - fip_statuses = agent.process_router_floating_ip_addresses( - ri, {'id': _uuid()}) - self.assertEqual({fip_id: l3_constants.FLOATINGIP_STATUS_ACTIVE}, - fip_statuses) - - self.assertFalse(device.addr.add.called) - self.assertFalse(device.addr.delete.called) - - @mock.patch('neutron.agent.linux.ip_lib.IPDevice') - def test_process_router_with_disabled_floating_ip(self, IPDevice): - fip_id = _uuid() - fip = { - 'id': fip_id, 'port_id': _uuid(), - 'floating_ip_address': '15.1.2.3', - 'fixed_ip_address': '192.168.0.2' - } - - ri = mock.MagicMock() - ri.floating_ips = [fip] - ri.router.get.return_value = [] - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - fip_statuses = agent.process_router_floating_ip_addresses( - ri, {'id': _uuid()}) - - self.assertIsNone(fip_statuses.get(fip_id)) - - @mock.patch('neutron.agent.linux.ip_lib.IPDevice') - def test_process_router_floating_ip_with_device_add_error(self, IPDevice): - IPDevice.return_value = device = mock.Mock() - device.addr.add.side_effect = processutils.ProcessExecutionError - device.addr.list.return_value = [] - fip_id = _uuid() - fip = { - 'id': fip_id, 'port_id': _uuid(), - 'floating_ip_address': '15.1.2.3', - 'fixed_ip_address': '192.168.0.2' - } - ri = mock.MagicMock() - ri.router.get.return_value = [fip] - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - fip_statuses = agent.process_router_floating_ip_addresses( - ri, {'id': _uuid()}) - - self.assertEqual({fip_id: l3_constants.FLOATINGIP_STATUS_ERROR}, - fip_statuses) - - def test_process_router_snat_disabled(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = self._prepare_router_data(enable_snat=True) - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - # Process with NAT - agent.process_router(ri) - orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:] - # Reprocess without NAT - router['enable_snat'] = False - # Reassign the router object to RouterInfo - ri.router = router - agent.process_router(ri) - # For some reason set logic does not work well with - # IpTablesRule instances - nat_rules_delta = [r for r in orig_nat_rules - if r not in ri.iptables_manager.ipv4['nat'].rules] - self.assertEqual(len(nat_rules_delta), 2) - self._verify_snat_rules(nat_rules_delta, router) - self.assertEqual(self.send_arp.call_count, 1) - - def test_process_router_snat_enabled(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = self._prepare_router_data(enable_snat=False) - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - # Process without NAT - agent.process_router(ri) - orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:] - # Reprocess with NAT - router['enable_snat'] = True - # Reassign the router object to RouterInfo - ri.router = router - agent.process_router(ri) - # For some reason set logic does not work well with - # IpTablesRule instances - nat_rules_delta = [r for r in ri.iptables_manager.ipv4['nat'].rules - if r not in orig_nat_rules] - self.assertEqual(len(nat_rules_delta), 2) - self._verify_snat_rules(nat_rules_delta, router) - self.assertEqual(self.send_arp.call_count, 1) - - def test_process_router_interface_added(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = self._prepare_router_data() - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - # Process with NAT - agent.process_router(ri) - orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:] - # Add an interface and reprocess - router[l3_constants.INTERFACE_KEY].append( - {'id': _uuid(), - 'network_id': _uuid(), - 'admin_state_up': True, - 'fixed_ips': [{'ip_address': '35.4.1.4', - 'subnet_id': _uuid()}], - 'mac_address': 'ca:fe:de:ad:be:ef', - 'subnet': {'cidr': '35.4.1.0/24', - 'gateway_ip': '35.4.1.1'}}) - # Reassign the router object to RouterInfo - ri.router = router - agent.process_router(ri) - # For some reason set logic does not work well with - # IpTablesRule instances - nat_rules_delta = [r for r in ri.iptables_manager.ipv4['nat'].rules - if r not in orig_nat_rules] - self.assertEqual(len(nat_rules_delta), 1) - self._verify_snat_rules(nat_rules_delta, router) - # send_arp is called both times process_router is called - self.assertEqual(self.send_arp.call_count, 2) - - def test_process_ipv6_only_gw(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = self._prepare_router_data(ip_version=6) - # Get NAT rules without the gw_port - gw_port = router['gw_port'] - router['gw_port'] = None - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - agent.process_router(ri) - orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:] - - # Get NAT rules with the gw_port - router['gw_port'] = gw_port - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - with mock.patch.object( - agent, - 'external_gateway_nat_rules') as external_gateway_nat_rules: - agent.process_router(ri) - new_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:] - - # There should be no change with the NAT rules - self.assertFalse(external_gateway_nat_rules.called) - self.assertEqual(orig_nat_rules, new_nat_rules) - - def test_process_router_ipv6_interface_added(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = self._prepare_router_data() - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - # Process with NAT - agent.process_router(ri) - orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:] - # Add an IPv6 interface and reprocess - router[l3_constants.INTERFACE_KEY].append( - {'id': _uuid(), - 'network_id': _uuid(), - 'admin_state_up': True, - 'fixed_ips': [{'ip_address': 'fd00::2', - 'subnet_id': _uuid()}], - 'mac_address': 'ca:fe:de:ad:be:ef', - 'subnet': {'cidr': 'fd00::/64', - 'gateway_ip': 'fd00::1'}}) - # Reassign the router object to RouterInfo - ri.router = router - agent.process_router(ri) - # For some reason set logic does not work well with - # IpTablesRule instances - nat_rules_delta = [r for r in ri.iptables_manager.ipv4['nat'].rules - if r not in orig_nat_rules] - self.assertFalse(nat_rules_delta) - - def test_process_router_ipv6v4_interface_added(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = self._prepare_router_data() - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - # Process with NAT - agent.process_router(ri) - orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:] - # Add an IPv4 and IPv6 interface and reprocess - router[l3_constants.INTERFACE_KEY].append( - {'id': _uuid(), - 'network_id': _uuid(), - 'admin_state_up': True, - 'fixed_ips': [{'ip_address': '35.4.1.4', - 'subnet_id': _uuid()}], - 'mac_address': 'ca:fe:de:ad:be:ef', - 'subnet': {'cidr': '35.4.1.0/24', - 'gateway_ip': '35.4.1.1'}}) - - router[l3_constants.INTERFACE_KEY].append( - {'id': _uuid(), - 'network_id': _uuid(), - 'admin_state_up': True, - 'fixed_ips': [{'ip_address': 'fd00::2', - 'subnet_id': _uuid()}], - 'mac_address': 'ca:fe:de:ad:be:ef', - 'subnet': {'cidr': 'fd00::/64', - 'gateway_ip': 'fd00::1'}}) - # Reassign the router object to RouterInfo - ri.router = router - agent.process_router(ri) - # For some reason set logic does not work well with - # IpTablesRule instances - nat_rules_delta = [r for r in ri.iptables_manager.ipv4['nat'].rules - if r not in orig_nat_rules] - self.assertEqual(1, len(nat_rules_delta)) - self._verify_snat_rules(nat_rules_delta, router) - - def test_process_router_interface_removed(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = self._prepare_router_data(num_internal_ports=2) - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - # Process with NAT - agent.process_router(ri) - orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:] - # Add an interface and reprocess - del router[l3_constants.INTERFACE_KEY][1] - # Reassign the router object to RouterInfo - ri.router = router - agent.process_router(ri) - # For some reason set logic does not work well with - # IpTablesRule instances - nat_rules_delta = [r for r in orig_nat_rules - if r not in ri.iptables_manager.ipv4['nat'].rules] - self.assertEqual(len(nat_rules_delta), 1) - self._verify_snat_rules(nat_rules_delta, router, negate=True) - # send_arp is called both times process_router is called - self.assertEqual(self.send_arp.call_count, 2) - - def test_process_router_internal_network_added_unexpected_error(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = self._prepare_router_data() - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - with mock.patch.object( - l3_agent.L3NATAgent, - 'internal_network_added') as internal_network_added: - # raise RuntimeError to simulate that an unexpected exception - # occurrs - internal_network_added.side_effect = RuntimeError - self.assertRaises(RuntimeError, agent.process_router, ri) - self.assertNotIn( - router[l3_constants.INTERFACE_KEY][0], ri.internal_ports) - - # The unexpected exception has been fixed manually - internal_network_added.side_effect = None - - # _sync_routers_task finds out that _rpc_loop failed to process the - # router last time, it will retry in the next run. - agent.process_router(ri) - # We were able to add the port to ri.internal_ports - self.assertIn( - router[l3_constants.INTERFACE_KEY][0], ri.internal_ports) - - def test_process_router_internal_network_removed_unexpected_error(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router = self._prepare_router_data() - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - # add an internal port - agent.process_router(ri) - - with mock.patch.object( - l3_agent.L3NATAgent, - 'internal_network_removed') as internal_net_removed: - # raise RuntimeError to simulate that an unexpected exception - # occurrs - internal_net_removed.side_effect = RuntimeError - ri.internal_ports[0]['admin_state_up'] = False - # The above port is set to down state, remove it. - self.assertRaises(RuntimeError, agent.process_router, ri) - self.assertIn( - router[l3_constants.INTERFACE_KEY][0], ri.internal_ports) - - # The unexpected exception has been fixed manually - internal_net_removed.side_effect = None - - # _sync_routers_task finds out that _rpc_loop failed to process the - # router last time, it will retry in the next run. - agent.process_router(ri) - # We were able to remove the port from ri.internal_ports - self.assertNotIn( - router[l3_constants.INTERFACE_KEY][0], ri.internal_ports) - - def test_process_router_floatingip_disabled(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - with mock.patch.object( - agent.plugin_rpc, - 'update_floatingip_statuses') as mock_update_fip_status: - fip_id = _uuid() - router = self._prepare_router_data(num_internal_ports=1) - router[l3_constants.FLOATINGIP_KEY] = [ - {'id': fip_id, - 'floating_ip_address': '8.8.8.8', - 'fixed_ip_address': '7.7.7.7', - 'port_id': router[l3_constants.INTERFACE_KEY][0]['id']}] - - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - agent.process_router(ri) - # Assess the call for putting the floating IP up was performed - mock_update_fip_status.assert_called_once_with( - mock.ANY, ri.router_id, - {fip_id: l3_constants.FLOATINGIP_STATUS_ACTIVE}) - mock_update_fip_status.reset_mock() - # Process the router again, this time without floating IPs - router[l3_constants.FLOATINGIP_KEY] = [] - ri.router = router - agent.process_router(ri) - # Assess the call for putting the floating IP up was performed - mock_update_fip_status.assert_called_once_with( - mock.ANY, ri.router_id, - {fip_id: l3_constants.FLOATINGIP_STATUS_DOWN}) - - def test_process_router_floatingip_exception(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - agent.process_router_floating_ip_addresses = mock.Mock() - agent.process_router_floating_ip_addresses.side_effect = RuntimeError - with mock.patch.object( - agent.plugin_rpc, - 'update_floatingip_statuses') as mock_update_fip_status: - fip_id = _uuid() - router = self._prepare_router_data(num_internal_ports=1) - router[l3_constants.FLOATINGIP_KEY] = [ - {'id': fip_id, - 'floating_ip_address': '8.8.8.8', - 'fixed_ip_address': '7.7.7.7', - 'port_id': router[l3_constants.INTERFACE_KEY][0]['id']}] - - ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper, - self.conf.use_namespaces, router=router) - agent.external_gateway_added = mock.Mock() - agent.process_router(ri) - # Assess the call for putting the floating IP into Error - # was performed - mock_update_fip_status.assert_called_once_with( - mock.ANY, ri.router_id, - {fip_id: l3_constants.FLOATINGIP_STATUS_ERROR}) - - def test_handle_router_snat_rules_add_back_jump(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - ri = mock.MagicMock() - port = {'fixed_ips': [{'ip_address': '192.168.1.4'}]} - - agent._handle_router_snat_rules(ri, port, [], "iface", "add_rules") - - nat = ri.iptables_manager.ipv4['nat'] - nat.empty_chain.assert_any_call('snat') - nat.add_rule.assert_any_call('snat', '-j $float-snat') - for call in nat.mock_calls: - name, args, kwargs = call - if name == 'add_rule': - self.assertEqual(args, ('snat', '-j $float-snat')) - self.assertEqual(kwargs, {}) - break - - def test_handle_router_snat_rules_add_rules(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - ri = l3_agent.RouterInfo(_uuid(), self.conf.root_helper, - self.conf.use_namespaces, None) - ex_gw_port = {'fixed_ips': [{'ip_address': '192.168.1.4'}]} - internal_cidrs = ['10.0.0.0/24'] - agent._handle_router_snat_rules(ri, ex_gw_port, internal_cidrs, - "iface", "add_rules") - - nat_rules = map(str, ri.iptables_manager.ipv4['nat'].rules) - wrap_name = ri.iptables_manager.wrap_name - - jump_float_rule = "-A %s-snat -j %s-float-snat" % (wrap_name, - wrap_name) - internal_net_rule = ("-A %s-snat -s %s -j SNAT --to-source %s") % ( - wrap_name, internal_cidrs[0], - ex_gw_port['fixed_ips'][0]['ip_address']) - - self.assertIn(jump_float_rule, nat_rules) - - self.assertIn(internal_net_rule, nat_rules) - self.assertThat(nat_rules.index(jump_float_rule), - matchers.LessThan(nat_rules.index(internal_net_rule))) - - def test_process_router_delete_stale_internal_devices(self): - class FakeDev(object): - def __init__(self, name): - self.name = name - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - stale_devlist = [FakeDev('qr-a1b2c3d4-e5'), - FakeDev('qr-b2c3d4e5-f6')] - stale_devnames = [dev.name for dev in stale_devlist] - - get_devices_return = [] - get_devices_return.extend(stale_devlist) - self.mock_ip.get_devices.return_value = get_devices_return - - router = self._prepare_router_data(enable_snat=True, - num_internal_ports=1) - ri = l3_agent.RouterInfo(router['id'], - self.conf.root_helper, - self.conf.use_namespaces, - router=router) - - internal_ports = ri.router.get(l3_constants.INTERFACE_KEY, []) - self.assertEqual(len(internal_ports), 1) - internal_port = internal_ports[0] - - with contextlib.nested(mock.patch.object(l3_agent.L3NATAgent, - 'internal_network_removed'), - mock.patch.object(l3_agent.L3NATAgent, - 'internal_network_added'), - mock.patch.object(l3_agent.L3NATAgent, - 'external_gateway_removed'), - mock.patch.object(l3_agent.L3NATAgent, - 'external_gateway_added') - ) as (internal_network_removed, - internal_network_added, - external_gateway_removed, - external_gateway_added): - - agent.process_router(ri) - - self.assertEqual(external_gateway_added.call_count, 1) - self.assertFalse(external_gateway_removed.called) - self.assertFalse(internal_network_removed.called) - internal_network_added.assert_called_once_with( - ri, - internal_port['network_id'], - internal_port['id'], - internal_port['ip_cidr'], - internal_port['mac_address']) - self.assertEqual(self.mock_driver.unplug.call_count, - len(stale_devnames)) - calls = [mock.call(stale_devname, - namespace=ri.ns_name, - prefix=l3_agent.INTERNAL_DEV_PREFIX) - for stale_devname in stale_devnames] - self.mock_driver.unplug.assert_has_calls(calls, any_order=True) - - def test_process_router_delete_stale_external_devices(self): - class FakeDev(object): - def __init__(self, name): - self.name = name - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - stale_devlist = [FakeDev('qg-a1b2c3d4-e5')] - stale_devnames = [dev.name for dev in stale_devlist] - - router = self._prepare_router_data(enable_snat=True, - num_internal_ports=1) - del router['gw_port'] - ri = l3_agent.RouterInfo(router['id'], - self.conf.root_helper, - self.conf.use_namespaces, - router=router) - - self.mock_ip.get_devices.return_value = stale_devlist - - agent.process_router(ri) - - self.mock_driver.unplug.assert_called_with( - stale_devnames[0], - bridge="br-ex", - namespace=ri.ns_name, - prefix=l3_agent.EXTERNAL_DEV_PREFIX) - - def test_router_deleted(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - agent.router_deleted(None, FAKE_ID) - # verify that will set fullsync - self.assertIn(FAKE_ID, agent.removed_routers) - - def test_routers_updated(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - agent.routers_updated(None, [FAKE_ID]) - # verify that will set fullsync - self.assertIn(FAKE_ID, agent.updated_routers) - - def test_removed_from_agent(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - agent.router_removed_from_agent(None, {'router_id': FAKE_ID}) - # verify that will set fullsync - self.assertIn(FAKE_ID, agent.removed_routers) - - def test_added_to_agent(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - agent.router_added_to_agent(None, [FAKE_ID]) - # verify that will set fullsync - self.assertIn(FAKE_ID, agent.updated_routers) - - def test_process_router_delete(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - ex_gw_port = {'id': _uuid(), - 'network_id': _uuid(), - 'fixed_ips': [{'ip_address': '19.4.4.4', - 'subnet_id': _uuid()}], - 'subnet': {'cidr': '19.4.4.0/24', - 'gateway_ip': '19.4.4.1'}} - router = { - 'id': _uuid(), - 'enable_snat': True, - 'routes': [], - 'gw_port': ex_gw_port} - agent._router_added(router['id'], router) - agent.router_deleted(None, router['id']) - agent._process_router_delete() - self.assertFalse(list(agent.removed_routers)) - - def test_destroy_router_namespace_skips_ns_removal(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - agent._destroy_router_namespace("fakens") - self.assertEqual(self.mock_ip.netns.delete.call_count, 0) - - def test_destroy_router_namespace_removes_ns(self): - self.conf.set_override('router_delete_namespaces', True) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - agent._destroy_router_namespace("fakens") - self.mock_ip.netns.delete.assert_called_once_with("fakens") - - def _configure_metadata_proxy(self, enableflag=True): - if not enableflag: - self.conf.set_override('enable_metadata_proxy', False) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - router_id = _uuid() - router = {'id': _uuid(), - 'external_gateway_info': {}, - 'routes': []} - with mock.patch.object( - agent, '_destroy_metadata_proxy') as destroy_proxy: - with mock.patch.object( - agent, '_spawn_metadata_proxy') as spawn_proxy: - agent._router_added(router_id, router) - if enableflag: - spawn_proxy.assert_called_with(mock.ANY, mock.ANY) - else: - self.assertFalse(spawn_proxy.call_count) - agent._router_removed(router_id) - if enableflag: - destroy_proxy.assert_called_with(mock.ANY, mock.ANY) - else: - self.assertFalse(destroy_proxy.call_count) - - def test_enable_metadata_proxy(self): - self._configure_metadata_proxy() - - def test_disable_metadata_proxy_spawn(self): - self._configure_metadata_proxy(enableflag=False) - - def test_metadata_nat_rules(self): - self.conf.set_override('enable_metadata_proxy', False) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - self.assertEqual([], agent.metadata_nat_rules()) - - self.conf.set_override('metadata_port', '8775') - self.conf.set_override('enable_metadata_proxy', True) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - rules = ('PREROUTING', '-s 0.0.0.0/0 -d 169.254.169.254/32 ' - '-p tcp -m tcp --dport 80 -j REDIRECT --to-port 8775') - self.assertEqual([rules], agent.metadata_nat_rules()) - - def test_router_id_specified_in_conf(self): - self.conf.set_override('use_namespaces', False) - self.conf.set_override('router_id', '') - self.assertRaises(SystemExit, l3_agent.L3NATAgent, - HOSTNAME, self.conf) - - self.conf.set_override('router_id', '1234') - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - self.assertEqual(['1234'], agent._router_ids()) - self.assertFalse(agent._clean_stale_namespaces) - - def test_process_routers_with_no_ext_net_in_conf(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - self.plugin_api.get_external_network_id.return_value = 'aaa' - - routers = [ - {'id': _uuid(), - 'routes': [], - 'admin_state_up': True, - 'external_gateway_info': {'network_id': 'aaa'}}] - - agent._process_routers(routers) - self.assertIn(routers[0]['id'], agent.router_info) - self.plugin_api.get_external_network_id.assert_called_with( - agent.context) - - def test_process_routers_with_cached_ext_net(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - self.plugin_api.get_external_network_id.return_value = 'aaa' - agent.target_ex_net_id = 'aaa' - - routers = [ - {'id': _uuid(), - 'routes': [], - 'admin_state_up': True, - 'external_gateway_info': {'network_id': 'aaa'}}] - - agent._process_routers(routers) - self.assertIn(routers[0]['id'], agent.router_info) - self.assertFalse(self.plugin_api.get_external_network_id.called) - - def test_process_routers_with_stale_cached_ext_net(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - self.plugin_api.get_external_network_id.return_value = 'aaa' - agent.target_ex_net_id = 'bbb' - - routers = [ - {'id': _uuid(), - 'routes': [], - 'admin_state_up': True, - 'external_gateway_info': {'network_id': 'aaa'}}] - - agent._process_routers(routers) - self.assertIn(routers[0]['id'], agent.router_info) - self.plugin_api.get_external_network_id.assert_called_with( - agent.context) - - def test_process_routers_with_no_ext_net_in_conf_and_two_net_plugin(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - routers = [ - {'id': _uuid(), - 'routes': [], - 'admin_state_up': True, - 'external_gateway_info': {'network_id': 'aaa'}}] - - agent.router_info = {} - self.plugin_api.get_external_network_id.side_effect = ( - n_exc.TooManyExternalNetworks()) - self.assertRaises(n_exc.TooManyExternalNetworks, - agent._process_routers, - routers) - self.assertNotIn(routers[0]['id'], agent.router_info) - - def test_process_routers_with_ext_net_in_conf(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - self.plugin_api.get_external_network_id.return_value = 'aaa' - - routers = [ - {'id': _uuid(), - 'routes': [], - 'admin_state_up': True, - 'external_gateway_info': {'network_id': 'aaa'}}, - {'id': _uuid(), - 'routes': [], - 'admin_state_up': True, - 'external_gateway_info': {'network_id': 'bbb'}}] - - agent.router_info = {} - self.conf.set_override('gateway_external_network_id', 'aaa') - agent._process_routers(routers) - self.assertIn(routers[0]['id'], agent.router_info) - self.assertNotIn(routers[1]['id'], agent.router_info) - - def test_process_routers_with_no_bridge_no_ext_net_in_conf(self): - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - self.plugin_api.get_external_network_id.return_value = 'aaa' - - routers = [ - {'id': _uuid(), - 'routes': [], - 'admin_state_up': True, - 'external_gateway_info': {'network_id': 'aaa'}}, - {'id': _uuid(), - 'routes': [], - 'admin_state_up': True, - 'external_gateway_info': {'network_id': 'bbb'}}] - - agent.router_info = {} - self.conf.set_override('external_network_bridge', '') - agent._process_routers(routers) - self.assertIn(routers[0]['id'], agent.router_info) - self.assertIn(routers[1]['id'], agent.router_info) - - def test_nonexistent_interface_driver(self): - self.conf.set_override('interface_driver', None) - with mock.patch.object(l3_agent, 'LOG') as log: - self.assertRaises(SystemExit, l3_agent.L3NATAgent, - HOSTNAME, self.conf) - msg = 'An interface driver must be specified' - log.error.assert_called_once_with(msg) - - self.conf.set_override('interface_driver', 'wrong_driver') - with mock.patch.object(l3_agent, 'LOG') as log: - self.assertRaises(SystemExit, l3_agent.L3NATAgent, - HOSTNAME, self.conf) - msg = "Error importing interface driver 'wrong_driver'" - log.error.assert_called_once_with(msg) - - def test_metadata_filter_rules(self): - self.conf.set_override('enable_metadata_proxy', False) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - self.assertEqual([], agent.metadata_filter_rules()) - - self.conf.set_override('metadata_port', '8775') - self.conf.set_override('enable_metadata_proxy', True) - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - rules = ('INPUT', '-s 0.0.0.0/0 -d 127.0.0.1 ' - '-p tcp -m tcp --dport 8775 -j ACCEPT') - self.assertEqual([rules], agent.metadata_filter_rules()) - - def _cleanup_namespace_test(self, - stale_namespace_list, - router_list, - other_namespaces): - self.conf.set_override('router_delete_namespaces', True) - - good_namespace_list = [l3_agent.NS_PREFIX + r['id'] - for r in router_list] - self.mock_ip.get_namespaces.return_value = (stale_namespace_list + - good_namespace_list + - other_namespaces) - - agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) - - self.assertTrue(agent._clean_stale_namespaces) - - pm = self.external_process.return_value - pm.reset_mock() - - agent._destroy_router_namespace = mock.MagicMock() - agent._cleanup_namespaces(router_list) - - self.assertEqual(pm.disable.call_count, len(stale_namespace_list)) - self.assertEqual(agent._destroy_router_namespace.call_count, - len(stale_namespace_list)) - expected_args = [mock.call(ns) for ns in stale_namespace_list] - agent._destroy_router_namespace.assert_has_calls(expected_args, - any_order=True) - self.assertFalse(agent._clean_stale_namespaces) - - def test_cleanup_namespace(self): - self.conf.set_override('router_id', None) - stale_namespaces = [l3_agent.NS_PREFIX + 'foo', - l3_agent.NS_PREFIX + 'bar'] - other_namespaces = ['unknown'] - - self._cleanup_namespace_test(stale_namespaces, - [], - other_namespaces) - - def test_cleanup_namespace_with_registered_router_ids(self): - self.conf.set_override('router_id', None) - stale_namespaces = [l3_agent.NS_PREFIX + 'cccc', - l3_agent.NS_PREFIX + 'eeeee'] - router_list = [{'id': 'foo'}, {'id': 'aaaa'}] - other_namespaces = ['qdhcp-aabbcc', 'unknown'] - - self._cleanup_namespace_test(stale_namespaces, - router_list, - other_namespaces) - - def test_cleanup_namespace_with_conf_router_id(self): - self.conf.set_override('router_id', 'bbbbb') - stale_namespaces = [l3_agent.NS_PREFIX + 'cccc', - l3_agent.NS_PREFIX + 'eeeee', - l3_agent.NS_PREFIX + self.conf.router_id] - router_list = [{'id': 'foo'}, {'id': 'aaaa'}] - other_namespaces = ['qdhcp-aabbcc', 'unknown'] - - self._cleanup_namespace_test(stale_namespaces, - router_list, - other_namespaces) - - -class TestL3AgentEventHandler(base.BaseTestCase): - - def setUp(self): - super(TestL3AgentEventHandler, self).setUp() - cfg.CONF.register_opts(l3_agent.L3NATAgent.OPTS) - agent_config.register_interface_driver_opts_helper(cfg.CONF) - agent_config.register_use_namespaces_opts_helper(cfg.CONF) - cfg.CONF.set_override( - 'interface_driver', 'neutron.agent.linux.interface.NullDriver' - ) - cfg.CONF.set_override('use_namespaces', True) - agent_config.register_root_helper(cfg.CONF) - - device_exists_p = mock.patch( - 'neutron.agent.linux.ip_lib.device_exists') - device_exists_p.start() - - utils_exec_p = mock.patch( - 'neutron.agent.linux.utils.execute') - utils_exec_p.start() - - drv_cls_p = mock.patch('neutron.agent.linux.interface.NullDriver') - driver_cls = drv_cls_p.start() - mock_driver = mock.MagicMock() - mock_driver.DEV_NAME_LEN = ( - interface.LinuxInterfaceDriver.DEV_NAME_LEN) - driver_cls.return_value = mock_driver - - l3_plugin_p = mock.patch( - 'neutron.agent.l3_agent.L3PluginApi') - l3_plugin_cls = l3_plugin_p.start() - l3_plugin_cls.return_value = mock.Mock() - - self.external_process_p = mock.patch( - 'neutron.agent.linux.external_process.ProcessManager' - ) - self.external_process_p.start() - looping_call_p = mock.patch( - 'neutron.openstack.common.loopingcall.FixedIntervalLoopingCall') - looping_call_p.start() - self.agent = l3_agent.L3NATAgent(HOSTNAME) - - def test_spawn_metadata_proxy(self): - router_id = _uuid() - metadata_port = 8080 - ip_class_path = 'neutron.agent.linux.ip_lib.IPWrapper' - - cfg.CONF.set_override('metadata_port', metadata_port) - cfg.CONF.set_override('log_file', 'test.log') - cfg.CONF.set_override('debug', True) - - self.external_process_p.stop() - ns = 'qrouter-' + router_id - try: - with mock.patch(ip_class_path) as ip_mock: - self.agent._spawn_metadata_proxy(router_id, ns) - ip_mock.assert_has_calls([ - mock.call('sudo', ns), - mock.call().netns.execute([ - 'neutron-ns-metadata-proxy', - mock.ANY, - mock.ANY, - '--router_id=%s' % router_id, - mock.ANY, - '--metadata_port=%s' % metadata_port, - '--debug', - '--log-file=neutron-ns-metadata-proxy-%s.log' % - router_id - ]) - ]) - finally: - self.external_process_p.start() diff --git a/neutron/tests/unit/test_l3_plugin.py b/neutron/tests/unit/test_l3_plugin.py deleted file mode 100644 index 4eb80d0d3..000000000 --- a/neutron/tests/unit/test_l3_plugin.py +++ /dev/null @@ -1,2070 +0,0 @@ -# Copyright 2012 VMware, Inc. -# All rights reserved. -# -# 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 contextlib -import copy - -import mock -import netaddr -from oslo.config import cfg -from webob import exc - -from neutron.api.v2 import attributes -from neutron.common import constants as l3_constants -from neutron.common import exceptions as n_exc -from neutron import context -from neutron.db import api as qdbapi -from neutron.db import db_base_plugin_v2 -from neutron.db import external_net_db -from neutron.db import l3_agentschedulers_db -from neutron.db import l3_db -from neutron.db import l3_rpc_base -from neutron.db import model_base -from neutron.extensions import external_net -from neutron.extensions import l3 -from neutron import manager -from neutron.openstack.common import importutils -from neutron.openstack.common import log as logging -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants as service_constants -from neutron.tests import fake_notifier -from neutron.tests.unit import test_agent_ext_plugin -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_api_v2_extension -from neutron.tests.unit import test_db_plugin - - -LOG = logging.getLogger(__name__) - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path - - -class L3TestExtensionManager(object): - - def get_resources(self): - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - l3.RESOURCE_ATTRIBUTE_MAP) - return l3.L3.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class L3NatExtensionTestCase(test_api_v2_extension.ExtensionTestCase): - fmt = 'json' - - def setUp(self): - super(L3NatExtensionTestCase, self).setUp() - self._setUpExtension( - 'neutron.extensions.l3.RouterPluginBase', None, - l3.RESOURCE_ATTRIBUTE_MAP, l3.L3, '', - allow_pagination=True, allow_sorting=True, - supported_extension_aliases=['router'], - use_quota=True) - - def test_router_create(self): - router_id = _uuid() - data = {'router': {'name': 'router1', 'admin_state_up': True, - 'tenant_id': _uuid(), - 'external_gateway_info': None}} - return_value = copy.deepcopy(data['router']) - return_value.update({'status': "ACTIVE", 'id': router_id}) - - instance = self.plugin.return_value - instance.create_router.return_value = return_value - instance.get_routers_count.return_value = 0 - res = self.api.post(_get_path('routers', fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_router.assert_called_with(mock.ANY, - router=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('router', res) - router = res['router'] - self.assertEqual(router['id'], router_id) - self.assertEqual(router['status'], "ACTIVE") - self.assertEqual(router['admin_state_up'], True) - - def test_router_list(self): - router_id = _uuid() - return_value = [{'name': 'router1', 'admin_state_up': True, - 'tenant_id': _uuid(), 'id': router_id}] - - instance = self.plugin.return_value - instance.get_routers.return_value = return_value - - res = self.api.get(_get_path('routers', fmt=self.fmt)) - - instance.get_routers.assert_called_with(mock.ANY, fields=mock.ANY, - filters=mock.ANY, - sorts=mock.ANY, - limit=mock.ANY, - marker=mock.ANY, - page_reverse=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('routers', res) - self.assertEqual(1, len(res['routers'])) - self.assertEqual(router_id, res['routers'][0]['id']) - - def test_router_update(self): - router_id = _uuid() - update_data = {'router': {'admin_state_up': False}} - return_value = {'name': 'router1', 'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", 'id': router_id} - - instance = self.plugin.return_value - instance.update_router.return_value = return_value - - res = self.api.put(_get_path('routers', id=router_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_router.assert_called_with(mock.ANY, router_id, - router=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('router', res) - router = res['router'] - self.assertEqual(router['id'], router_id) - self.assertEqual(router['status'], "ACTIVE") - self.assertEqual(router['admin_state_up'], False) - - def test_router_get(self): - router_id = _uuid() - return_value = {'name': 'router1', 'admin_state_up': False, - 'tenant_id': _uuid(), - 'status': "ACTIVE", 'id': router_id} - - instance = self.plugin.return_value - instance.get_router.return_value = return_value - - res = self.api.get(_get_path('routers', id=router_id, - fmt=self.fmt)) - - instance.get_router.assert_called_with(mock.ANY, router_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('router', res) - router = res['router'] - self.assertEqual(router['id'], router_id) - self.assertEqual(router['status'], "ACTIVE") - self.assertEqual(router['admin_state_up'], False) - - def test_router_delete(self): - router_id = _uuid() - - res = self.api.delete(_get_path('routers', id=router_id)) - - instance = self.plugin.return_value - instance.delete_router.assert_called_with(mock.ANY, router_id) - self.assertEqual(res.status_int, exc.HTTPNoContent.code) - - def test_router_add_interface(self): - router_id = _uuid() - subnet_id = _uuid() - port_id = _uuid() - - interface_data = {'subnet_id': subnet_id} - return_value = copy.deepcopy(interface_data) - return_value['port_id'] = port_id - - instance = self.plugin.return_value - instance.add_router_interface.return_value = return_value - - path = _get_path('routers', id=router_id, - action="add_router_interface", - fmt=self.fmt) - res = self.api.put(path, self.serialize(interface_data)) - - instance.add_router_interface.assert_called_with(mock.ANY, router_id, - interface_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_id', res) - self.assertEqual(res['port_id'], port_id) - self.assertEqual(res['subnet_id'], subnet_id) - - -class L3NatExtensionTestCaseXML(L3NatExtensionTestCase): - fmt = 'xml' - - -# This base plugin class is for tests. -class TestL3NatBasePlugin(db_base_plugin_v2.NeutronDbPluginV2, - external_net_db.External_net_db_mixin): - - __native_pagination_support = True - __native_sorting_support = True - - def create_network(self, context, network): - session = context.session - with session.begin(subtransactions=True): - net = super(TestL3NatBasePlugin, self).create_network(context, - network) - self._process_l3_create(context, net, network['network']) - return net - - def update_network(self, context, id, network): - - session = context.session - with session.begin(subtransactions=True): - net = super(TestL3NatBasePlugin, self).update_network(context, id, - network) - self._process_l3_update(context, net, network['network']) - return net - - def delete_network(self, context, id): - with context.session.begin(subtransactions=True): - self._process_l3_delete(context, id) - super(TestL3NatBasePlugin, self).delete_network(context, id) - - def delete_port(self, context, id, l3_port_check=True): - plugin = manager.NeutronManager.get_service_plugins().get( - service_constants.L3_ROUTER_NAT) - if plugin: - if l3_port_check: - plugin.prevent_l3_port_deletion(context, id) - plugin.disassociate_floatingips(context, id) - return super(TestL3NatBasePlugin, self).delete_port(context, id) - - -# This plugin class is for tests with plugin that integrates L3. -class TestL3NatIntPlugin(TestL3NatBasePlugin, - l3_db.L3_NAT_db_mixin): - - supported_extension_aliases = ["external-net", "router"] - - -# This plugin class is for tests with plugin that integrates L3 and L3 agent -# scheduling. -class TestL3NatIntAgentSchedulingPlugin(TestL3NatIntPlugin, - l3_agentschedulers_db. - L3AgentSchedulerDbMixin): - - supported_extension_aliases = ["external-net", "router", - "l3_agent_scheduler"] - router_scheduler = importutils.import_object( - cfg.CONF.router_scheduler_driver) - - -# This plugin class is for tests with plugin not supporting L3. -class TestNoL3NatPlugin(TestL3NatBasePlugin): - - __native_pagination_support = True - __native_sorting_support = True - - supported_extension_aliases = ["external-net"] - - -# A L3 routing service plugin class for tests with plugins that -# delegate away L3 routing functionality -class TestL3NatServicePlugin(db_base_plugin_v2.CommonDbMixin, - l3_db.L3_NAT_db_mixin): - - supported_extension_aliases = ["router"] - - def __init__(self): - qdbapi.register_models(base=model_base.BASEV2) - - def get_plugin_type(self): - return service_constants.L3_ROUTER_NAT - - def get_plugin_description(self): - return "L3 Routing Service Plugin for testing" - - -# A L3 routing with L3 agent scheduling service plugin class for tests with -# plugins that delegate away L3 routing functionality -class TestL3NatAgentSchedulingServicePlugin(TestL3NatServicePlugin, - l3_agentschedulers_db. - L3AgentSchedulerDbMixin): - - supported_extension_aliases = ["router", "l3_agent_scheduler"] - - -class L3NatTestCaseMixin(object): - - def _create_router(self, fmt, tenant_id, name=None, - admin_state_up=None, set_context=False, - arg_list=None, **kwargs): - data = {'router': {'tenant_id': tenant_id}} - if name: - data['router']['name'] = name - if admin_state_up: - data['router']['admin_state_up'] = admin_state_up - for arg in (('admin_state_up', 'tenant_id') + (arg_list or ())): - # Arg must be present and not empty - if arg in kwargs and kwargs[arg]: - data['router'][arg] = kwargs[arg] - router_req = self.new_create_request('routers', data, fmt) - if set_context and tenant_id: - # create a specific auth context for this request - router_req.environ['neutron.context'] = context.Context( - '', tenant_id) - - return router_req.get_response(self.ext_api) - - def _make_router(self, fmt, tenant_id, name=None, admin_state_up=None, - external_gateway_info=None, set_context=False, - arg_list=None, **kwargs): - if external_gateway_info: - arg_list = ('external_gateway_info', ) + (arg_list or ()) - res = self._create_router(fmt, tenant_id, name, - admin_state_up, set_context, - arg_list=arg_list, - external_gateway_info=external_gateway_info, - **kwargs) - return self.deserialize(fmt, res) - - def _add_external_gateway_to_router(self, router_id, network_id, - expected_code=exc.HTTPOk.code, - neutron_context=None): - return self._update('routers', router_id, - {'router': {'external_gateway_info': - {'network_id': network_id}}}, - expected_code=expected_code, - neutron_context=neutron_context) - - def _remove_external_gateway_from_router(self, router_id, network_id, - expected_code=exc.HTTPOk.code, - external_gw_info=None): - return self._update('routers', router_id, - {'router': {'external_gateway_info': - external_gw_info}}, - expected_code=expected_code) - - def _router_interface_action(self, action, router_id, subnet_id, port_id, - expected_code=exc.HTTPOk.code, - expected_body=None, - tenant_id=None): - interface_data = {} - if subnet_id: - interface_data.update({'subnet_id': subnet_id}) - if port_id and (action != 'add' or not subnet_id): - interface_data.update({'port_id': port_id}) - - req = self.new_action_request('routers', interface_data, router_id, - "%s_router_interface" % action) - # if tenant_id was specified, create a tenant context for this request - if tenant_id: - req.environ['neutron.context'] = context.Context( - '', tenant_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, expected_code) - response = self.deserialize(self.fmt, res) - if expected_body: - self.assertEqual(response, expected_body) - return response - - @contextlib.contextmanager - def router(self, name='router1', admin_state_up=True, - fmt=None, tenant_id=_uuid(), - external_gateway_info=None, set_context=False, - **kwargs): - router = self._make_router(fmt or self.fmt, tenant_id, name, - admin_state_up, external_gateway_info, - set_context, **kwargs) - yield router - self._delete('routers', router['router']['id']) - - def _set_net_external(self, net_id): - self._update('networks', net_id, - {'network': {external_net.EXTERNAL: True}}) - - def _create_floatingip(self, fmt, network_id, port_id=None, - fixed_ip=None, set_context=False): - data = {'floatingip': {'floating_network_id': network_id, - 'tenant_id': self._tenant_id}} - if port_id: - data['floatingip']['port_id'] = port_id - if fixed_ip: - data['floatingip']['fixed_ip_address'] = fixed_ip - floatingip_req = self.new_create_request('floatingips', data, fmt) - if set_context and self._tenant_id: - # create a specific auth context for this request - floatingip_req.environ['neutron.context'] = context.Context( - '', self._tenant_id) - return floatingip_req.get_response(self.ext_api) - - def _make_floatingip(self, fmt, network_id, port_id=None, - fixed_ip=None, set_context=False): - res = self._create_floatingip(fmt, network_id, port_id, - fixed_ip, set_context) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - return self.deserialize(fmt, res) - - def _validate_floating_ip(self, fip): - body = self._list('floatingips') - self.assertEqual(len(body['floatingips']), 1) - self.assertEqual(body['floatingips'][0]['id'], - fip['floatingip']['id']) - - body = self._show('floatingips', fip['floatingip']['id']) - self.assertEqual(body['floatingip']['id'], - fip['floatingip']['id']) - - @contextlib.contextmanager - def floatingip_with_assoc(self, port_id=None, fmt=None, fixed_ip=None, - set_context=False): - with self.subnet(cidr='11.0.0.0/24') as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - private_port = None - if port_id: - private_port = self._show('ports', port_id) - with test_db_plugin.optional_ctx(private_port, - self.port) as private_port: - with self.router() as r: - sid = private_port['port']['fixed_ips'][0]['subnet_id'] - private_sub = {'subnet': {'id': sid}} - floatingip = None - - self._add_external_gateway_to_router( - r['router']['id'], - public_sub['subnet']['network_id']) - self._router_interface_action( - 'add', r['router']['id'], - private_sub['subnet']['id'], None) - - floatingip = self._make_floatingip( - fmt or self.fmt, - public_sub['subnet']['network_id'], - port_id=private_port['port']['id'], - fixed_ip=fixed_ip, - set_context=False) - yield floatingip - - if floatingip: - self._delete('floatingips', - floatingip['floatingip']['id']) - self._router_interface_action( - 'remove', r['router']['id'], - private_sub['subnet']['id'], None) - self._remove_external_gateway_from_router( - r['router']['id'], - public_sub['subnet']['network_id']) - - @contextlib.contextmanager - def floatingip_no_assoc_with_public_sub( - self, private_sub, fmt=None, set_context=False, public_sub=None): - self._set_net_external(public_sub['subnet']['network_id']) - with self.router() as r: - floatingip = None - - self._add_external_gateway_to_router( - r['router']['id'], - public_sub['subnet']['network_id']) - self._router_interface_action('add', r['router']['id'], - private_sub['subnet']['id'], - None) - - floatingip = self._make_floatingip( - fmt or self.fmt, - public_sub['subnet']['network_id'], - set_context=set_context) - yield floatingip, r - - if floatingip: - self._delete('floatingips', - floatingip['floatingip']['id']) - self._router_interface_action('remove', r['router']['id'], - private_sub['subnet']['id'], - None) - self._remove_external_gateway_from_router( - r['router']['id'], - public_sub['subnet']['network_id']) - - @contextlib.contextmanager - def floatingip_no_assoc(self, private_sub, fmt=None, set_context=False): - with self.subnet(cidr='12.0.0.0/24') as public_sub: - with self.floatingip_no_assoc_with_public_sub( - private_sub, fmt, set_context, public_sub) as (f, r): - # Yield only the floating ip object - yield f - - -class L3NatTestCaseBase(L3NatTestCaseMixin): - - def test_router_create(self): - name = 'router1' - tenant_id = _uuid() - expected_value = [('name', name), ('tenant_id', tenant_id), - ('admin_state_up', True), ('status', 'ACTIVE'), - ('external_gateway_info', None)] - with self.router(name='router1', admin_state_up=True, - tenant_id=tenant_id) as router: - for k, v in expected_value: - self.assertEqual(router['router'][k], v) - - def test_router_create_call_extensions(self): - self.extension_called = False - - def _extend_router_dict_test_attr(*args, **kwargs): - self.extension_called = True - - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( - l3.ROUTERS, [_extend_router_dict_test_attr]) - self.assertFalse(self.extension_called) - with self.router(): - self.assertTrue(self.extension_called) - - def test_router_create_with_gwinfo(self): - with self.subnet() as s: - self._set_net_external(s['subnet']['network_id']) - data = {'router': {'tenant_id': _uuid()}} - data['router']['name'] = 'router1' - data['router']['external_gateway_info'] = { - 'network_id': s['subnet']['network_id']} - router_req = self.new_create_request('routers', data, self.fmt) - res = router_req.get_response(self.ext_api) - router = self.deserialize(self.fmt, res) - self.assertEqual( - s['subnet']['network_id'], - router['router']['external_gateway_info']['network_id']) - self._delete('routers', router['router']['id']) - - def test_router_list(self): - with contextlib.nested(self.router(), - self.router(), - self.router() - ) as routers: - self._test_list_resources('router', routers) - - def test_router_list_with_parameters(self): - with contextlib.nested(self.router(name='router1'), - self.router(name='router2'), - ) as (router1, router2): - query_params = 'name=router1' - self._test_list_resources('router', [router1], - query_params=query_params) - query_params = 'name=router2' - self._test_list_resources('router', [router2], - query_params=query_params) - query_params = 'name=router3' - self._test_list_resources('router', [], - query_params=query_params) - - def test_router_list_with_sort(self): - with contextlib.nested(self.router(name='router1'), - self.router(name='router2'), - self.router(name='router3') - ) as (router1, router2, router3): - self._test_list_with_sort('router', (router3, router2, router1), - [('name', 'desc')]) - - def test_router_list_with_pagination(self): - with contextlib.nested(self.router(name='router1'), - self.router(name='router2'), - self.router(name='router3') - ) as (router1, router2, router3): - self._test_list_with_pagination('router', - (router1, router2, router3), - ('name', 'asc'), 2, 2) - - def test_router_list_with_pagination_reverse(self): - with contextlib.nested(self.router(name='router1'), - self.router(name='router2'), - self.router(name='router3') - ) as (router1, router2, router3): - self._test_list_with_pagination_reverse('router', - (router1, router2, - router3), - ('name', 'asc'), 2, 2) - - def test_router_update(self): - rname1 = "yourrouter" - rname2 = "nachorouter" - with self.router(name=rname1) as r: - body = self._show('routers', r['router']['id']) - self.assertEqual(body['router']['name'], rname1) - - body = self._update('routers', r['router']['id'], - {'router': {'name': rname2}}) - - body = self._show('routers', r['router']['id']) - self.assertEqual(body['router']['name'], rname2) - - def test_router_update_gateway(self): - with self.router() as r: - with self.subnet() as s1: - with self.subnet() as s2: - self._set_net_external(s1['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s1['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - net_id = (body['router'] - ['external_gateway_info']['network_id']) - self.assertEqual(net_id, s1['subnet']['network_id']) - self._set_net_external(s2['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s2['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - net_id = (body['router'] - ['external_gateway_info']['network_id']) - self.assertEqual(net_id, s2['subnet']['network_id']) - # Validate that we can clear the gateway with - # an empty dict, in any other case, we fall back - # on None as default value - self._remove_external_gateway_from_router( - r['router']['id'], - s2['subnet']['network_id'], - external_gw_info={}) - - def test_router_update_gateway_with_existed_floatingip(self): - with self.subnet() as subnet: - self._set_net_external(subnet['subnet']['network_id']) - with self.floatingip_with_assoc() as fip: - self._add_external_gateway_to_router( - fip['floatingip']['router_id'], - subnet['subnet']['network_id'], - expected_code=exc.HTTPConflict.code) - - def test_router_update_gateway_to_empty_with_existed_floatingip(self): - with self.floatingip_with_assoc() as fip: - self._remove_external_gateway_from_router( - fip['floatingip']['router_id'], None, - expected_code=exc.HTTPConflict.code) - - def test_router_add_interface_subnet(self): - exp_notifications = ['router.create.start', - 'router.create.end', - 'network.create.start', - 'network.create.end', - 'subnet.create.start', - 'subnet.create.end', - 'router.interface.create', - 'router.interface.delete'] - fake_notifier.reset() - with self.router() as r: - with self.subnet() as s: - body = self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None) - self.assertIn('port_id', body) - - # fetch port and confirm device_id - r_port_id = body['port_id'] - body = self._show('ports', r_port_id) - self.assertEqual(body['port']['device_id'], r['router']['id']) - - body = self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None) - body = self._show('ports', r_port_id, - expected_code=exc.HTTPNotFound.code) - - self.assertEqual( - set(exp_notifications), - set(n['event_type'] for n in fake_notifier.NOTIFICATIONS)) - - for n in fake_notifier.NOTIFICATIONS: - if n['event_type'].startswith('router.interface.'): - payload = n['payload']['router_interface'] - self.assertIn('id', payload) - self.assertEqual(payload['id'], r['router']['id']) - self.assertIn('tenant_id', payload) - stid = s['subnet']['tenant_id'] - # tolerate subnet tenant deliberately to '' in the - # nsx metadata access case - self.assertIn(payload['tenant_id'], [stid, '']) - - def test_router_add_interface_subnet_with_bad_tenant_returns_404(self): - with mock.patch('neutron.context.Context.to_dict') as tdict: - tenant_id = _uuid() - admin_context = {'roles': ['admin']} - tenant_context = {'tenant_id': 'bad_tenant', - 'roles': []} - tdict.return_value = admin_context - with self.router(tenant_id=tenant_id) as r: - with self.network(tenant_id=tenant_id) as n: - with self.subnet(network=n) as s: - tdict.return_value = tenant_context - err_code = exc.HTTPNotFound.code - self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None, - err_code) - tdict.return_value = admin_context - body = self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None) - self.assertIn('port_id', body) - tdict.return_value = tenant_context - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None, - err_code) - tdict.return_value = admin_context - body = self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None) - - def test_router_add_interface_subnet_with_port_from_other_tenant(self): - tenant_id = _uuid() - other_tenant_id = _uuid() - with contextlib.nested( - self.router(tenant_id=tenant_id), - self.network(tenant_id=tenant_id), - self.network(tenant_id=other_tenant_id)) as (r, n1, n2): - with contextlib.nested( - self.subnet(network=n1, cidr='10.0.0.0/24'), - self.subnet(network=n2, cidr='10.1.0.0/24')) as (s1, s2): - body = self._router_interface_action( - 'add', - r['router']['id'], - s2['subnet']['id'], - None) - self.assertIn('port_id', body) - self._router_interface_action( - 'add', - r['router']['id'], - s1['subnet']['id'], - None, - tenant_id=tenant_id) - self.assertIn('port_id', body) - self._router_interface_action( - 'remove', - r['router']['id'], - s1['subnet']['id'], - None, - tenant_id=tenant_id) - body = self._router_interface_action( - 'remove', - r['router']['id'], - s2['subnet']['id'], - None) - - def test_router_add_interface_port(self): - with self.router() as r: - with self.port(no_delete=True) as p: - body = self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - self.assertIn('port_id', body) - self.assertEqual(body['port_id'], p['port']['id']) - - # fetch port and confirm device_id - body = self._show('ports', p['port']['id']) - self.assertEqual(body['port']['device_id'], r['router']['id']) - - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_add_interface_port_bad_tenant_returns_404(self): - with mock.patch('neutron.context.Context.to_dict') as tdict: - admin_context = {'roles': ['admin']} - tenant_context = {'tenant_id': 'bad_tenant', - 'roles': []} - tdict.return_value = admin_context - with self.router() as r: - with self.port(no_delete=True) as p: - tdict.return_value = tenant_context - err_code = exc.HTTPNotFound.code - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id'], - err_code) - tdict.return_value = admin_context - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - - tdict.return_value = tenant_context - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id'], - err_code) - - tdict.return_value = admin_context - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_add_interface_dup_subnet1_returns_400(self): - with self.router() as r: - with self.subnet() as s: - self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None) - self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None, - expected_code=exc. - HTTPBadRequest.code) - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None) - - def test_router_add_interface_dup_subnet2_returns_400(self): - with self.router() as r: - with self.subnet() as s: - with self.port(subnet=s, no_delete=True) as p1: - with self.port(subnet=s) as p2: - self._router_interface_action('add', - r['router']['id'], - None, - p1['port']['id']) - self._router_interface_action('add', - r['router']['id'], - None, - p2['port']['id'], - expected_code=exc. - HTTPBadRequest.code) - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p1['port']['id']) - - def test_router_add_interface_overlapped_cidr_returns_400(self): - with self.router() as r: - with self.subnet(cidr='10.0.1.0/24') as s1: - self._router_interface_action('add', - r['router']['id'], - s1['subnet']['id'], - None) - - def try_overlapped_cidr(cidr): - with self.subnet(cidr=cidr) as s2: - self._router_interface_action('add', - r['router']['id'], - s2['subnet']['id'], - None, - expected_code=exc. - HTTPBadRequest.code) - # another subnet with same cidr - try_overlapped_cidr('10.0.1.0/24') - # another subnet with overlapped cidr including s1 - try_overlapped_cidr('10.0.0.0/16') - # another subnet with overlapped cidr included by s1 - try_overlapped_cidr('10.0.1.1/32') - # clean-up - self._router_interface_action('remove', - r['router']['id'], - s1['subnet']['id'], - None) - - def test_router_add_interface_no_data_returns_400(self): - with self.router() as r: - self._router_interface_action('add', - r['router']['id'], - None, - None, - expected_code=exc. - HTTPBadRequest.code) - - def test_router_add_gateway_dup_subnet1_returns_400(self): - with self.router() as r: - with self.subnet() as s: - self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None) - self._set_net_external(s['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s['subnet']['network_id'], - expected_code=exc.HTTPBadRequest.code) - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None) - - def test_router_add_gateway_dup_subnet2_returns_400(self): - with self.router() as r: - with self.subnet() as s: - self._set_net_external(s['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s['subnet']['network_id']) - self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None, - expected_code=exc. - HTTPBadRequest.code) - self._remove_external_gateway_from_router( - r['router']['id'], - s['subnet']['network_id']) - - def test_router_add_gateway(self): - with self.router() as r: - with self.subnet() as s: - self._set_net_external(s['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - net_id = body['router']['external_gateway_info']['network_id'] - self.assertEqual(net_id, s['subnet']['network_id']) - self._remove_external_gateway_from_router( - r['router']['id'], - s['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - gw_info = body['router']['external_gateway_info'] - self.assertIsNone(gw_info) - - def test_router_add_gateway_tenant_ctx(self): - with self.router(tenant_id='noadmin', - set_context=True) as r: - with self.subnet() as s: - self._set_net_external(s['subnet']['network_id']) - ctx = context.Context('', 'noadmin') - self._add_external_gateway_to_router( - r['router']['id'], - s['subnet']['network_id'], - neutron_context=ctx) - body = self._show('routers', r['router']['id']) - net_id = body['router']['external_gateway_info']['network_id'] - self.assertEqual(net_id, s['subnet']['network_id']) - self._remove_external_gateway_from_router( - r['router']['id'], - s['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - gw_info = body['router']['external_gateway_info'] - self.assertIsNone(gw_info) - - def test_create_router_port_with_device_id_of_other_teants_router(self): - with self.router() as admin_router: - with self.network(tenant_id='tenant_a', - set_context=True) as n: - with self.subnet(network=n): - self._create_port( - self.fmt, n['network']['id'], - tenant_id='tenant_a', - device_id=admin_router['router']['id'], - device_owner='network:router_interface', - set_context=True, - expected_res_status=exc.HTTPConflict.code) - - def test_create_non_router_port_device_id_of_other_teants_router_update( - self): - # This tests that HTTPConflict is raised if we create a non-router - # port that matches the device_id of another tenants router and then - # we change the device_owner to be network:router_interface. - with self.router() as admin_router: - with self.network(tenant_id='tenant_a', - set_context=True) as n: - with self.subnet(network=n): - port_res = self._create_port( - self.fmt, n['network']['id'], - tenant_id='tenant_a', - device_id=admin_router['router']['id'], - set_context=True) - port = self.deserialize(self.fmt, port_res) - neutron_context = context.Context('', 'tenant_a') - data = {'port': {'device_owner': - 'network:router_interface'}} - self._update('ports', port['port']['id'], data, - neutron_context=neutron_context, - expected_code=exc.HTTPConflict.code) - self._delete('ports', port['port']['id']) - - def test_update_port_device_id_to_different_tenants_router(self): - with self.router() as admin_router: - with self.router(tenant_id='tenant_a', - set_context=True) as tenant_router: - with self.network(tenant_id='tenant_a', - set_context=True) as n: - with self.subnet(network=n) as s: - port = self._router_interface_action( - 'add', tenant_router['router']['id'], - s['subnet']['id'], None, tenant_id='tenant_a') - neutron_context = context.Context('', 'tenant_a') - data = {'port': - {'device_id': admin_router['router']['id']}} - self._update('ports', port['port_id'], data, - neutron_context=neutron_context, - expected_code=exc.HTTPConflict.code) - self._router_interface_action( - 'remove', tenant_router['router']['id'], - s['subnet']['id'], None, tenant_id='tenant_a') - - def test_router_add_gateway_invalid_network_returns_404(self): - with self.router() as r: - self._add_external_gateway_to_router( - r['router']['id'], - "foobar", expected_code=exc.HTTPNotFound.code) - - def test_router_add_gateway_net_not_external_returns_400(self): - with self.router() as r: - with self.subnet() as s: - # intentionally do not set net as external - self._add_external_gateway_to_router( - r['router']['id'], - s['subnet']['network_id'], - expected_code=exc.HTTPBadRequest.code) - - def test_router_add_gateway_no_subnet_returns_400(self): - with self.router() as r: - with self.network() as n: - self._set_net_external(n['network']['id']) - self._add_external_gateway_to_router( - r['router']['id'], - n['network']['id'], expected_code=exc.HTTPBadRequest.code) - - def test_router_remove_interface_inuse_returns_409(self): - with self.router() as r: - with self.subnet() as s: - self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None) - self._delete('routers', r['router']['id'], - expected_code=exc.HTTPConflict.code) - - # remove interface so test can exit without errors - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None) - - def test_router_remove_interface_wrong_subnet_returns_400(self): - with self.router() as r: - with self.subnet() as s: - with self.port(no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - p['port']['id'], - exc.HTTPBadRequest.code) - #remove properly to clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_router_remove_interface_returns_200(self): - with self.router() as r: - with self.port(no_delete=True) as p: - body = self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id'], - expected_body=body) - - def test_router_remove_interface_wrong_port_returns_404(self): - with self.router() as r: - with self.subnet(): - with self.port(no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - # create another port for testing failure case - res = self._create_port(self.fmt, p['port']['network_id']) - p2 = self.deserialize(self.fmt, res) - self._router_interface_action('remove', - r['router']['id'], - None, - p2['port']['id'], - exc.HTTPNotFound.code) - # remove correct interface to cleanup - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - # remove extra port created - self._delete('ports', p2['port']['id']) - - def test_router_delete(self): - with self.router() as router: - router_id = router['router']['id'] - req = self.new_show_request('router', router_id) - res = req.get_response(self._api_for_resource('router')) - self.assertEqual(res.status_int, 404) - - def test_router_delete_with_port_existed_returns_409(self): - with self.subnet() as subnet: - res = self._create_router(self.fmt, _uuid()) - router = self.deserialize(self.fmt, res) - self._router_interface_action('add', - router['router']['id'], - subnet['subnet']['id'], - None) - self._delete('routers', router['router']['id'], - exc.HTTPConflict.code) - self._router_interface_action('remove', - router['router']['id'], - subnet['subnet']['id'], - None) - self._delete('routers', router['router']['id']) - - def test_router_delete_with_floatingip_existed_returns_409(self): - with self.port() as p: - private_sub = {'subnet': {'id': - p['port']['fixed_ips'][0]['subnet_id']}} - with self.subnet(cidr='12.0.0.0/24') as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - res = self._create_router(self.fmt, _uuid()) - r = self.deserialize(self.fmt, res) - self._add_external_gateway_to_router( - r['router']['id'], - public_sub['subnet']['network_id']) - self._router_interface_action('add', r['router']['id'], - private_sub['subnet']['id'], - None) - res = self._create_floatingip( - self.fmt, public_sub['subnet']['network_id'], - port_id=p['port']['id']) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - floatingip = self.deserialize(self.fmt, res) - self._delete('routers', r['router']['id'], - expected_code=exc.HTTPConflict.code) - # Cleanup - self._delete('floatingips', floatingip['floatingip']['id']) - self._router_interface_action('remove', r['router']['id'], - private_sub['subnet']['id'], - None) - self._delete('routers', r['router']['id']) - - def test_router_show(self): - name = 'router1' - tenant_id = _uuid() - expected_value = [('name', name), ('tenant_id', tenant_id), - ('admin_state_up', True), ('status', 'ACTIVE'), - ('external_gateway_info', None)] - with self.router(name='router1', admin_state_up=True, - tenant_id=tenant_id) as router: - res = self._show('routers', router['router']['id']) - for k, v in expected_value: - self.assertEqual(res['router'][k], v) - - def test_network_update_external_failure(self): - with self.router() as r: - with self.subnet() as s1: - self._set_net_external(s1['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s1['subnet']['network_id']) - self._update('networks', s1['subnet']['network_id'], - {'network': {external_net.EXTERNAL: False}}, - expected_code=exc.HTTPConflict.code) - self._remove_external_gateway_from_router( - r['router']['id'], - s1['subnet']['network_id']) - - def test_network_update_external(self): - with self.router() as r: - with self.network('test_net') as testnet: - self._set_net_external(testnet['network']['id']) - with self.subnet() as s1: - self._set_net_external(s1['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s1['subnet']['network_id']) - self._update('networks', testnet['network']['id'], - {'network': {external_net.EXTERNAL: False}}) - self._remove_external_gateway_from_router( - r['router']['id'], - s1['subnet']['network_id']) - - def test_floatingip_crd_ops(self): - with self.floatingip_with_assoc() as fip: - self._validate_floating_ip(fip) - - # post-delete, check that it is really gone - body = self._list('floatingips') - self.assertEqual(len(body['floatingips']), 0) - - self._show('floatingips', fip['floatingip']['id'], - expected_code=exc.HTTPNotFound.code) - - def _test_floatingip_with_assoc_fails(self, plugin_class): - with self.subnet(cidr='200.0.0.0/24') as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - with self.port() as private_port: - with self.router() as r: - sid = private_port['port']['fixed_ips'][0]['subnet_id'] - private_sub = {'subnet': {'id': sid}} - self._add_external_gateway_to_router( - r['router']['id'], - public_sub['subnet']['network_id']) - self._router_interface_action('add', r['router']['id'], - private_sub['subnet']['id'], - None) - method = plugin_class + '._update_fip_assoc' - with mock.patch(method) as pl: - pl.side_effect = n_exc.BadRequest( - resource='floatingip', - msg='fake_error') - res = self._create_floatingip( - self.fmt, - public_sub['subnet']['network_id'], - port_id=private_port['port']['id']) - self.assertEqual(res.status_int, 400) - for p in self._list('ports')['ports']: - if (p['device_owner'] == - l3_constants.DEVICE_OWNER_FLOATINGIP): - self.fail('garbage port is not deleted') - self._remove_external_gateway_from_router( - r['router']['id'], - public_sub['subnet']['network_id']) - self._router_interface_action('remove', - r['router']['id'], - private_sub['subnet']['id'], - None) - - def test_floatingip_with_assoc_fails(self): - self._test_floatingip_with_assoc_fails( - 'neutron.db.l3_db.L3_NAT_db_mixin') - - def _test_floatingip_with_ip_generation_failure(self, plugin_class): - with self.subnet(cidr='200.0.0.0/24') as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - with self.port() as private_port: - with self.router() as r: - sid = private_port['port']['fixed_ips'][0]['subnet_id'] - private_sub = {'subnet': {'id': sid}} - self._add_external_gateway_to_router( - r['router']['id'], - public_sub['subnet']['network_id']) - self._router_interface_action('add', r['router']['id'], - private_sub['subnet']['id'], - None) - method = plugin_class + '._update_fip_assoc' - with mock.patch(method) as pl: - pl.side_effect = n_exc.IpAddressGenerationFailure( - net_id='netid') - res = self._create_floatingip( - self.fmt, - public_sub['subnet']['network_id'], - port_id=private_port['port']['id']) - self.assertEqual(res.status_int, exc.HTTPConflict.code) - - for p in self._list('ports')['ports']: - if (p['device_owner'] == - l3_constants.DEVICE_OWNER_FLOATINGIP): - self.fail('garbage port is not deleted') - - self._remove_external_gateway_from_router( - r['router']['id'], - public_sub['subnet']['network_id']) - self._router_interface_action('remove', - r['router']['id'], - private_sub['subnet']['id'], - None) - - def test_floatingip_update( - self, expected_status=l3_constants.FLOATINGIP_STATUS_ACTIVE): - with self.port() as p: - private_sub = {'subnet': {'id': - p['port']['fixed_ips'][0]['subnet_id']}} - with self.floatingip_no_assoc(private_sub) as fip: - body = self._show('floatingips', fip['floatingip']['id']) - self.assertIsNone(body['floatingip']['port_id']) - self.assertIsNone(body['floatingip']['fixed_ip_address']) - self.assertEqual(body['floatingip']['status'], expected_status) - - port_id = p['port']['id'] - ip_address = p['port']['fixed_ips'][0]['ip_address'] - body = self._update('floatingips', fip['floatingip']['id'], - {'floatingip': {'port_id': port_id}}) - self.assertEqual(body['floatingip']['port_id'], port_id) - self.assertEqual(body['floatingip']['fixed_ip_address'], - ip_address) - - def test_floatingip_create_different_fixed_ip_same_port(self): - '''This tests that it is possible to delete a port that has - multiple floating ip addresses associated with it (each floating - address associated with a unique fixed address). - ''' - - with self.router() as r: - with self.subnet(cidr='11.0.0.0/24') as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - public_sub['subnet']['network_id']) - - with self.subnet() as private_sub: - ip_range = list(netaddr.IPNetwork( - private_sub['subnet']['cidr'])) - fixed_ips = [{'ip_address': str(ip_range[-3])}, - {'ip_address': str(ip_range[-2])}] - - self._router_interface_action( - 'add', r['router']['id'], - private_sub['subnet']['id'], None) - - with self.port(subnet=private_sub, - fixed_ips=fixed_ips) as p: - - fip1 = self._make_floatingip( - self.fmt, - public_sub['subnet']['network_id'], - p['port']['id'], - fixed_ip=str(ip_range[-2])) - fip2 = self._make_floatingip( - self.fmt, - public_sub['subnet']['network_id'], - p['port']['id'], - fixed_ip=str(ip_range[-3])) - - # Test that floating ips are assigned successfully. - body = self._show('floatingips', - fip1['floatingip']['id']) - self.assertEqual( - body['floatingip']['port_id'], - fip1['floatingip']['port_id']) - - body = self._show('floatingips', - fip2['floatingip']['id']) - self.assertEqual( - body['floatingip']['port_id'], - fip2['floatingip']['port_id']) - - # Test that port has been successfully deleted. - body = self._show('ports', p['port']['id'], - expected_code=exc.HTTPNotFound.code) - - for fip in [fip1, fip2]: - self._delete('floatingips', - fip['floatingip']['id']) - - self._router_interface_action( - 'remove', r['router']['id'], - private_sub['subnet']['id'], None) - - self._remove_external_gateway_from_router( - r['router']['id'], - public_sub['subnet']['network_id']) - - def test_floatingip_update_different_fixed_ip_same_port(self): - with self.subnet() as s: - ip_range = list(netaddr.IPNetwork(s['subnet']['cidr'])) - fixed_ips = [{'ip_address': str(ip_range[-3])}, - {'ip_address': str(ip_range[-2])}] - with self.port(subnet=s, fixed_ips=fixed_ips) as p: - with self.floatingip_with_assoc( - port_id=p['port']['id'], - fixed_ip=str(ip_range[-3])) as fip: - body = self._show('floatingips', fip['floatingip']['id']) - self.assertEqual(fip['floatingip']['id'], - body['floatingip']['id']) - self.assertEqual(fip['floatingip']['port_id'], - body['floatingip']['port_id']) - self.assertEqual(str(ip_range[-3]), - body['floatingip']['fixed_ip_address']) - self.assertIsNotNone(body['floatingip']['router_id']) - body_2 = self._update( - 'floatingips', fip['floatingip']['id'], - {'floatingip': {'port_id': p['port']['id'], - 'fixed_ip_address': str(ip_range[-2])} - }) - self.assertEqual(fip['floatingip']['port_id'], - body_2['floatingip']['port_id']) - self.assertEqual(str(ip_range[-2]), - body_2['floatingip']['fixed_ip_address']) - - def test_floatingip_update_different_router(self): - # Create subnet with different CIDRs to account for plugins which - # do not support overlapping IPs - with contextlib.nested(self.subnet(cidr='10.0.0.0/24'), - self.subnet(cidr='10.0.1.0/24')) as ( - s1, s2): - with contextlib.nested(self.port(subnet=s1), - self.port(subnet=s2)) as (p1, p2): - private_sub1 = {'subnet': - {'id': - p1['port']['fixed_ips'][0]['subnet_id']}} - private_sub2 = {'subnet': - {'id': - p2['port']['fixed_ips'][0]['subnet_id']}} - with self.subnet(cidr='12.0.0.0/24') as public_sub: - with contextlib.nested( - self.floatingip_no_assoc_with_public_sub( - private_sub1, public_sub=public_sub), - self.floatingip_no_assoc_with_public_sub( - private_sub2, public_sub=public_sub)) as ( - (fip1, r1), (fip2, r2)): - - def assert_no_assoc(fip): - body = self._show('floatingips', - fip['floatingip']['id']) - self.assertIsNone(body['floatingip']['port_id']) - self.assertIsNone( - body['floatingip']['fixed_ip_address']) - - assert_no_assoc(fip1) - assert_no_assoc(fip2) - - def associate_and_assert(fip, port): - port_id = port['port']['id'] - ip_address = (port['port']['fixed_ips'] - [0]['ip_address']) - body = self._update( - 'floatingips', fip['floatingip']['id'], - {'floatingip': {'port_id': port_id}}) - self.assertEqual(body['floatingip']['port_id'], - port_id) - self.assertEqual( - body['floatingip']['fixed_ip_address'], - ip_address) - return body['floatingip']['router_id'] - - fip1_r1_res = associate_and_assert(fip1, p1) - self.assertEqual(fip1_r1_res, r1['router']['id']) - # The following operation will associate the floating - # ip to a different router - fip1_r2_res = associate_and_assert(fip1, p2) - self.assertEqual(fip1_r2_res, r2['router']['id']) - fip2_r1_res = associate_and_assert(fip2, p1) - self.assertEqual(fip2_r1_res, r1['router']['id']) - # disassociate fip1 - self._update( - 'floatingips', fip1['floatingip']['id'], - {'floatingip': {'port_id': None}}) - fip2_r2_res = associate_and_assert(fip2, p2) - self.assertEqual(fip2_r2_res, r2['router']['id']) - - def test_floatingip_with_assoc(self): - with self.floatingip_with_assoc() as fip: - body = self._show('floatingips', fip['floatingip']['id']) - self.assertEqual(body['floatingip']['id'], - fip['floatingip']['id']) - self.assertEqual(body['floatingip']['port_id'], - fip['floatingip']['port_id']) - self.assertIsNotNone(body['floatingip']['fixed_ip_address']) - self.assertIsNotNone(body['floatingip']['router_id']) - - def test_floatingip_port_delete(self): - with self.subnet() as private_sub: - with self.floatingip_no_assoc(private_sub) as fip: - with self.port(subnet=private_sub) as p: - body = self._update('floatingips', fip['floatingip']['id'], - {'floatingip': - {'port_id': p['port']['id']}}) - # note: once this port goes out of scope, the port will be - # deleted, which is what we want to test. We want to confirm - # that the fields are set back to None - body = self._show('floatingips', fip['floatingip']['id']) - self.assertEqual(body['floatingip']['id'], - fip['floatingip']['id']) - self.assertIsNone(body['floatingip']['port_id']) - self.assertIsNone(body['floatingip']['fixed_ip_address']) - self.assertIsNone(body['floatingip']['router_id']) - - def test_two_fips_one_port_invalid_return_409(self): - with self.floatingip_with_assoc() as fip1: - res = self._create_floatingip( - self.fmt, - fip1['floatingip']['floating_network_id'], - fip1['floatingip']['port_id']) - self.assertEqual(res.status_int, exc.HTTPConflict.code) - - def test_floating_ip_direct_port_delete_returns_409(self): - found = False - with self.floatingip_with_assoc(): - for p in self._list('ports')['ports']: - if p['device_owner'] == l3_constants.DEVICE_OWNER_FLOATINGIP: - self._delete('ports', p['id'], - expected_code=exc.HTTPConflict.code) - found = True - self.assertTrue(found) - - def _test_floatingip_with_invalid_create_port(self, plugin_class): - with self.port() as p: - private_sub = {'subnet': {'id': - p['port']['fixed_ips'][0]['subnet_id']}} - with self.subnet(cidr='12.0.0.0/24') as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - res = self._create_router(self.fmt, _uuid()) - r = self.deserialize(self.fmt, res) - self._add_external_gateway_to_router( - r['router']['id'], - public_sub['subnet']['network_id']) - self._router_interface_action( - 'add', r['router']['id'], - private_sub['subnet']['id'], - None) - - with mock.patch(plugin_class + '.create_port') as createport: - createport.return_value = {'fixed_ips': []} - res = self._create_floatingip( - self.fmt, public_sub['subnet']['network_id'], - port_id=p['port']['id']) - self.assertEqual(res.status_int, - exc.HTTPBadRequest.code) - self._router_interface_action('remove', - r['router']['id'], - private_sub - ['subnet']['id'], - None) - self._delete('routers', r['router']['id']) - - def test_floatingip_with_invalid_create_port(self): - self._test_floatingip_with_invalid_create_port( - 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2') - - def test_create_floatingip_no_ext_gateway_return_404(self): - with self.subnet() as public_sub: - self._set_net_external(public_sub['subnet']['network_id']) - with self.port() as private_port: - with self.router(): - res = self._create_floatingip( - self.fmt, - public_sub['subnet']['network_id'], - port_id=private_port['port']['id']) - # this should be some kind of error - self.assertEqual(res.status_int, exc.HTTPNotFound.code) - - def test_create_floating_non_ext_network_returns_400(self): - with self.subnet() as public_sub: - # normally we would set the network of public_sub to be - # external, but the point of this test is to handle when - # that is not the case - with self.router(): - res = self._create_floatingip( - self.fmt, - public_sub['subnet']['network_id']) - self.assertEqual(res.status_int, exc.HTTPBadRequest.code) - - def test_create_floatingip_no_public_subnet_returns_400(self): - with self.network() as public_network: - with self.port() as private_port: - with self.router() as r: - sid = private_port['port']['fixed_ips'][0]['subnet_id'] - private_sub = {'subnet': {'id': sid}} - self._router_interface_action('add', r['router']['id'], - private_sub['subnet']['id'], - None) - - res = self._create_floatingip( - self.fmt, - public_network['network']['id'], - port_id=private_port['port']['id']) - self.assertEqual(res.status_int, exc.HTTPBadRequest.code) - # cleanup - self._router_interface_action('remove', - r['router']['id'], - private_sub['subnet']['id'], - None) - - def test_create_floatingip_invalid_floating_network_id_returns_400(self): - # API-level test - no need to create all objects for l3 plugin - res = self._create_floatingip(self.fmt, 'iamnotanuuid', - uuidutils.generate_uuid(), '192.168.0.1') - self.assertEqual(res.status_int, 400) - - def test_create_floatingip_invalid_floating_port_id_returns_400(self): - # API-level test - no need to create all objects for l3 plugin - res = self._create_floatingip(self.fmt, uuidutils.generate_uuid(), - 'iamnotanuuid', '192.168.0.1') - self.assertEqual(res.status_int, 400) - - def test_create_floatingip_invalid_fixed_ip_address_returns_400(self): - # API-level test - no need to create all objects for l3 plugin - res = self._create_floatingip(self.fmt, uuidutils.generate_uuid(), - uuidutils.generate_uuid(), 'iamnotnanip') - self.assertEqual(res.status_int, 400) - - def test_floatingip_list_with_sort(self): - with contextlib.nested(self.subnet(cidr="10.0.0.0/24"), - self.subnet(cidr="11.0.0.0/24"), - self.subnet(cidr="12.0.0.0/24") - ) as (s1, s2, s3): - network_id1 = s1['subnet']['network_id'] - network_id2 = s2['subnet']['network_id'] - network_id3 = s3['subnet']['network_id'] - self._set_net_external(network_id1) - self._set_net_external(network_id2) - self._set_net_external(network_id3) - fp1 = self._make_floatingip(self.fmt, network_id1) - fp2 = self._make_floatingip(self.fmt, network_id2) - fp3 = self._make_floatingip(self.fmt, network_id3) - try: - self._test_list_with_sort('floatingip', (fp3, fp2, fp1), - [('floating_ip_address', 'desc')]) - finally: - self._delete('floatingips', fp1['floatingip']['id']) - self._delete('floatingips', fp2['floatingip']['id']) - self._delete('floatingips', fp3['floatingip']['id']) - - def test_floatingip_list_with_port_id(self): - with self.floatingip_with_assoc() as fip: - port_id = fip['floatingip']['port_id'] - res = self._list('floatingips', - query_params="port_id=%s" % port_id) - self.assertEqual(len(res['floatingips']), 1) - res = self._list('floatingips', query_params="port_id=aaa") - self.assertEqual(len(res['floatingips']), 0) - - def test_floatingip_list_with_pagination(self): - with contextlib.nested(self.subnet(cidr="10.0.0.0/24"), - self.subnet(cidr="11.0.0.0/24"), - self.subnet(cidr="12.0.0.0/24") - ) as (s1, s2, s3): - network_id1 = s1['subnet']['network_id'] - network_id2 = s2['subnet']['network_id'] - network_id3 = s3['subnet']['network_id'] - self._set_net_external(network_id1) - self._set_net_external(network_id2) - self._set_net_external(network_id3) - fp1 = self._make_floatingip(self.fmt, network_id1) - fp2 = self._make_floatingip(self.fmt, network_id2) - fp3 = self._make_floatingip(self.fmt, network_id3) - try: - self._test_list_with_pagination( - 'floatingip', (fp1, fp2, fp3), - ('floating_ip_address', 'asc'), 2, 2) - finally: - self._delete('floatingips', fp1['floatingip']['id']) - self._delete('floatingips', fp2['floatingip']['id']) - self._delete('floatingips', fp3['floatingip']['id']) - - def test_floatingip_list_with_pagination_reverse(self): - with contextlib.nested(self.subnet(cidr="10.0.0.0/24"), - self.subnet(cidr="11.0.0.0/24"), - self.subnet(cidr="12.0.0.0/24") - ) as (s1, s2, s3): - network_id1 = s1['subnet']['network_id'] - network_id2 = s2['subnet']['network_id'] - network_id3 = s3['subnet']['network_id'] - self._set_net_external(network_id1) - self._set_net_external(network_id2) - self._set_net_external(network_id3) - fp1 = self._make_floatingip(self.fmt, network_id1) - fp2 = self._make_floatingip(self.fmt, network_id2) - fp3 = self._make_floatingip(self.fmt, network_id3) - try: - self._test_list_with_pagination_reverse( - 'floatingip', (fp1, fp2, fp3), - ('floating_ip_address', 'asc'), 2, 2) - finally: - self._delete('floatingips', fp1['floatingip']['id']) - self._delete('floatingips', fp2['floatingip']['id']) - self._delete('floatingips', fp3['floatingip']['id']) - - def test_floatingip_delete_router_intf_with_subnet_id_returns_409(self): - found = False - with self.floatingip_with_assoc(): - for p in self._list('ports')['ports']: - if p['device_owner'] == l3_constants.DEVICE_OWNER_ROUTER_INTF: - subnet_id = p['fixed_ips'][0]['subnet_id'] - router_id = p['device_id'] - self._router_interface_action( - 'remove', router_id, subnet_id, None, - expected_code=exc.HTTPConflict.code) - found = True - break - self.assertTrue(found) - - def test_floatingip_delete_router_intf_with_port_id_returns_409(self): - found = False - with self.floatingip_with_assoc(): - for p in self._list('ports')['ports']: - if p['device_owner'] == l3_constants.DEVICE_OWNER_ROUTER_INTF: - router_id = p['device_id'] - self._router_interface_action( - 'remove', router_id, None, p['id'], - expected_code=exc.HTTPConflict.code) - found = True - break - self.assertTrue(found) - - def test_router_delete_subnet_inuse_returns_409(self): - with self.router() as r: - with self.subnet() as s: - self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None) - # subnet cannot be delete as it's attached to a router - self._delete('subnets', s['subnet']['id'], - expected_code=exc.HTTPConflict.code) - # remove interface so test can exit without errors - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None) - - def test_delete_ext_net_with_disassociated_floating_ips(self): - with self.network() as net: - net_id = net['network']['id'] - self._set_net_external(net_id) - with self.subnet(network=net, do_delete=False): - self._make_floatingip(self.fmt, net_id) - - -class L3AgentDbTestCaseBase(L3NatTestCaseMixin): - - """Unit tests for methods called by the L3 agent.""" - - def test_l3_agent_routers_query_interfaces(self): - with self.router() as r: - with self.port(no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - - routers = self.plugin.get_sync_data( - context.get_admin_context(), None) - self.assertEqual(1, len(routers)) - interfaces = routers[0][l3_constants.INTERFACE_KEY] - self.assertEqual(1, len(interfaces)) - subnet_id = interfaces[0]['subnet']['id'] - wanted_subnetid = p['port']['fixed_ips'][0]['subnet_id'] - self.assertEqual(wanted_subnetid, subnet_id) - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_l3_agent_routers_query_ignore_interfaces_with_moreThanOneIp(self): - with self.router() as r: - with self.subnet(cidr='9.0.1.0/24') as subnet: - with self.port(subnet=subnet, - no_delete=True, - fixed_ips=[{'ip_address': '9.0.1.3'}]) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - port = {'port': {'fixed_ips': - [{'ip_address': '9.0.1.4', - 'subnet_id': subnet['subnet']['id']}, - {'ip_address': '9.0.1.5', - 'subnet_id': subnet['subnet']['id']}]}} - ctx = context.get_admin_context() - self.core_plugin.update_port(ctx, p['port']['id'], port) - routers = self.plugin.get_sync_data(ctx, None) - self.assertEqual(1, len(routers)) - interfaces = routers[0].get(l3_constants.INTERFACE_KEY, []) - self.assertEqual(1, len(interfaces)) - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - - def test_l3_agent_routers_query_gateway(self): - with self.router() as r: - with self.subnet() as s: - self._set_net_external(s['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s['subnet']['network_id']) - routers = self.plugin.get_sync_data( - context.get_admin_context(), [r['router']['id']]) - self.assertEqual(1, len(routers)) - gw_port = routers[0]['gw_port'] - self.assertEqual(s['subnet']['id'], gw_port['subnet']['id']) - self._remove_external_gateway_from_router( - r['router']['id'], - s['subnet']['network_id']) - - def test_l3_agent_routers_query_floatingips(self): - with self.floatingip_with_assoc() as fip: - routers = self.plugin.get_sync_data( - context.get_admin_context(), [fip['floatingip']['router_id']]) - self.assertEqual(1, len(routers)) - floatingips = routers[0][l3_constants.FLOATINGIP_KEY] - self.assertEqual(1, len(floatingips)) - self.assertEqual(floatingips[0]['id'], - fip['floatingip']['id']) - self.assertEqual(floatingips[0]['port_id'], - fip['floatingip']['port_id']) - self.assertIsNotNone(floatingips[0]['fixed_ip_address']) - self.assertIsNotNone(floatingips[0]['router_id']) - - def _test_notify_op_agent(self, target_func, *args): - l3_rpc_agent_api_str = ( - 'neutron.api.rpc.agentnotifiers.l3_rpc_agent_api.L3AgentNotifyAPI') - plugin = manager.NeutronManager.get_service_plugins()[ - service_constants.L3_ROUTER_NAT] - oldNotify = plugin.l3_rpc_notifier - try: - with mock.patch(l3_rpc_agent_api_str) as notifyApi: - plugin.l3_rpc_notifier = notifyApi - kargs = [item for item in args] - kargs.append(notifyApi) - target_func(*kargs) - except Exception: - plugin.l3_rpc_notifier = oldNotify - raise - else: - plugin.l3_rpc_notifier = oldNotify - - def _test_router_gateway_op_agent(self, notifyApi): - with self.router() as r: - with self.subnet() as s: - self._set_net_external(s['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s['subnet']['network_id']) - self._remove_external_gateway_from_router( - r['router']['id'], - s['subnet']['network_id']) - self.assertEqual( - 2, notifyApi.routers_updated.call_count) - - def test_router_gateway_op_agent(self): - self._test_notify_op_agent(self._test_router_gateway_op_agent) - - def _test_interfaces_op_agent(self, r, notifyApi): - with self.port(no_delete=True) as p: - self._router_interface_action('add', - r['router']['id'], - None, - p['port']['id']) - # clean-up - self._router_interface_action('remove', - r['router']['id'], - None, - p['port']['id']) - self.assertEqual(2, notifyApi.routers_updated.call_count) - - def test_interfaces_op_agent(self): - with self.router() as r: - self._test_notify_op_agent( - self._test_interfaces_op_agent, r) - - def _test_floatingips_op_agent(self, notifyApi): - with self.floatingip_with_assoc(): - pass - # add gateway, add interface, associate, deletion of floatingip, - # delete gateway, delete interface - self.assertEqual(6, notifyApi.routers_updated.call_count) - - def test_floatingips_op_agent(self): - self._test_notify_op_agent(self._test_floatingips_op_agent) - - -class L3BaseForIntTests(test_db_plugin.NeutronDbPluginV2TestCase): - - mock_rescheduling = True - - def setUp(self, plugin=None, ext_mgr=None, service_plugins=None): - if not plugin: - plugin = 'neutron.tests.unit.test_l3_plugin.TestL3NatIntPlugin' - # for these tests we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - ext_mgr = ext_mgr or L3TestExtensionManager() - - if self.mock_rescheduling: - mock.patch('%s._check_router_needs_rescheduling' % plugin, - new=lambda *a: False).start() - - super(L3BaseForIntTests, self).setUp(plugin=plugin, ext_mgr=ext_mgr, - service_plugins=service_plugins) - - self.setup_notification_driver() - - -class L3BaseForSepTests(test_db_plugin.NeutronDbPluginV2TestCase): - - def setUp(self, plugin=None, ext_mgr=None): - # the plugin without L3 support - if not plugin: - plugin = 'neutron.tests.unit.test_l3_plugin.TestNoL3NatPlugin' - # the L3 service plugin - l3_plugin = ('neutron.tests.unit.test_l3_plugin.' - 'TestL3NatServicePlugin') - service_plugins = {'l3_plugin_name': l3_plugin} - - # for these tests we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - if not ext_mgr: - ext_mgr = L3TestExtensionManager() - super(L3BaseForSepTests, self).setUp(plugin=plugin, ext_mgr=ext_mgr, - service_plugins=service_plugins) - - self.setup_notification_driver() - - -class L3NatDBIntAgentSchedulingTestCase(L3BaseForIntTests, - L3NatTestCaseMixin, - test_agent_ext_plugin. - AgentDBTestMixIn): - - """Unit tests for core plugin with L3 routing and scheduling integrated.""" - - def setUp(self, plugin='neutron.tests.unit.test_l3_plugin.' - 'TestL3NatIntAgentSchedulingPlugin', - ext_mgr=None, service_plugins=None): - self.mock_rescheduling = False - super(L3NatDBIntAgentSchedulingTestCase, self).setUp( - plugin, ext_mgr, service_plugins) - self.adminContext = context.get_admin_context() - - def _assert_router_on_agent(self, router_id, agent_host): - plugin = manager.NeutronManager.get_service_plugins().get( - service_constants.L3_ROUTER_NAT) - agents = plugin.list_l3_agents_hosting_router( - self.adminContext, router_id)['agents'] - self.assertEqual(len(agents), 1) - self.assertEqual(agents[0]['host'], agent_host) - - def test_update_gateway_agent_exists_supporting_network(self): - with contextlib.nested(self.router(), - self.subnet(), - self.subnet()) as (r, s1, s2): - self._set_net_external(s1['subnet']['network_id']) - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_one_l3_agent( - host='host1', - ext_net_id=s1['subnet']['network_id']) - self._register_one_l3_agent( - host='host2', internal_only=False, - ext_net_id=s2['subnet']['network_id']) - l3_rpc.sync_routers(self.adminContext, - host='host1') - self._assert_router_on_agent(r['router']['id'], 'host1') - - self._add_external_gateway_to_router( - r['router']['id'], - s1['subnet']['network_id']) - self._assert_router_on_agent(r['router']['id'], 'host1') - - self._set_net_external(s2['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s2['subnet']['network_id']) - self._assert_router_on_agent(r['router']['id'], 'host2') - - self._remove_external_gateway_from_router( - r['router']['id'], - s2['subnet']['network_id']) - - def test_update_gateway_agent_exists_supporting_multiple_network(self): - with contextlib.nested(self.router(), - self.subnet(), - self.subnet()) as (r, s1, s2): - self._set_net_external(s1['subnet']['network_id']) - l3_rpc = l3_rpc_base.L3RpcCallbackMixin() - self._register_one_l3_agent( - host='host1', - ext_net_id=s1['subnet']['network_id']) - self._register_one_l3_agent( - host='host2', internal_only=False, - ext_net_id='', ext_bridge='') - l3_rpc.sync_routers(self.adminContext, - host='host1') - self._assert_router_on_agent(r['router']['id'], 'host1') - - self._add_external_gateway_to_router( - r['router']['id'], - s1['subnet']['network_id']) - self._assert_router_on_agent(r['router']['id'], 'host1') - - self._set_net_external(s2['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s2['subnet']['network_id']) - self._assert_router_on_agent(r['router']['id'], 'host2') - - self._remove_external_gateway_from_router( - r['router']['id'], - s2['subnet']['network_id']) - - def test_router_update_gateway_no_eligible_l3_agent(self): - with self.router() as r: - with self.subnet() as s1: - with self.subnet() as s2: - self._set_net_external(s1['subnet']['network_id']) - self._set_net_external(s2['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s1['subnet']['network_id'], - expected_code=exc.HTTPBadRequest.code) - - -class L3AgentDbIntTestCase(L3BaseForIntTests, L3AgentDbTestCaseBase): - - """Unit tests for methods called by the L3 agent for - the case where core plugin implements L3 routing. - """ - - def setUp(self): - self.core_plugin = TestL3NatIntPlugin() - # core plugin is also plugin providing L3 routing - self.plugin = self.core_plugin - super(L3AgentDbIntTestCase, self).setUp() - - -class L3AgentDbSepTestCase(L3BaseForSepTests, L3AgentDbTestCaseBase): - - """Unit tests for methods called by the L3 agent for the - case where separate service plugin implements L3 routing. - """ - - def setUp(self): - self.core_plugin = TestNoL3NatPlugin() - # core plugin is also plugin providing L3 routing - self.plugin = TestL3NatServicePlugin() - super(L3AgentDbSepTestCase, self).setUp() - - -class L3NatDBIntTestCase(L3BaseForIntTests, L3NatTestCaseBase): - - """Unit tests for core plugin with L3 routing integrated.""" - pass - - -class L3NatDBSepTestCase(L3BaseForSepTests, L3NatTestCaseBase): - - """Unit tests for a separate L3 routing service plugin.""" - pass - - -class L3NatDBIntTestCaseXML(L3NatDBIntTestCase): - fmt = 'xml' - - -class L3NatDBSepTestCaseXML(L3NatDBSepTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/test_l3_schedulers.py b/neutron/tests/unit/test_l3_schedulers.py deleted file mode 100644 index 99bf8d83e..000000000 --- a/neutron/tests/unit/test_l3_schedulers.py +++ /dev/null @@ -1,206 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. -# -# @author: Sylvain Afchain, eNovance SAS -# @author: Emilien Macchi, eNovance SAS - -import contextlib -import uuid - -import mock -from oslo.config import cfg - -from neutron.api.v2 import attributes as attr -from neutron.common import constants -from neutron.common import topics -from neutron import context as q_context -from neutron.db import agents_db -from neutron.db import l3_agentschedulers_db -from neutron.extensions import l3 as ext_l3 -from neutron import manager -from neutron.openstack.common import timeutils -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import test_l3_plugin - -HOST = 'my_l3_host' -FIRST_L3_AGENT = { - 'binary': 'neutron-l3-agent', - 'host': HOST, - 'topic': topics.L3_AGENT, - 'configurations': {}, - 'agent_type': constants.AGENT_TYPE_L3, - 'start_flag': True -} - -HOST_2 = 'my_l3_host_2' -SECOND_L3_AGENT = { - 'binary': 'neutron-l3-agent', - 'host': HOST_2, - 'topic': topics.L3_AGENT, - 'configurations': {}, - 'agent_type': constants.AGENT_TYPE_L3, - 'start_flag': True -} - -DB_PLUGIN_KLASS = ('neutron.plugins.openvswitch.ovs_neutron_plugin.' - 'OVSNeutronPluginV2') - - -class L3SchedulerTestExtensionManager(object): - - def get_resources(self): - attr.RESOURCE_ATTRIBUTE_MAP.update(ext_l3.RESOURCE_ATTRIBUTE_MAP) - l3_res = ext_l3.L3.get_resources() - return l3_res - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class L3SchedulerTestCase(l3_agentschedulers_db.L3AgentSchedulerDbMixin, - test_db_plugin.NeutronDbPluginV2TestCase, - test_l3_plugin.L3NatTestCaseMixin): - - def setUp(self): - ext_mgr = L3SchedulerTestExtensionManager() - super(L3SchedulerTestCase, self).setUp(plugin=DB_PLUGIN_KLASS, - ext_mgr=ext_mgr) - - self.adminContext = q_context.get_admin_context() - self.plugin = manager.NeutronManager.get_plugin() - self._register_l3_agents() - - def _register_l3_agents(self): - callback = agents_db.AgentExtRpcCallback() - callback.report_state(self.adminContext, - agent_state={'agent_state': FIRST_L3_AGENT}, - time=timeutils.strtime()) - agent_db = self.plugin.get_agents_db(self.adminContext, - filters={'host': [HOST]}) - self.agent_id1 = agent_db[0].id - - callback.report_state(self.adminContext, - agent_state={'agent_state': SECOND_L3_AGENT}, - time=timeutils.strtime()) - agent_db = self.plugin.get_agents_db(self.adminContext, - filters={'host': [HOST]}) - self.agent_id2 = agent_db[0].id - - def _set_l3_agent_admin_state(self, context, agent_id, state=True): - update = {'agent': {'admin_state_up': state}} - self.plugin.update_agent(context, agent_id, update) - - @contextlib.contextmanager - def router_with_ext_gw(self, name='router1', admin_state_up=True, - fmt=None, tenant_id=str(uuid.uuid4()), - external_gateway_info=None, - subnet=None, set_context=False, - **kwargs): - router = self._make_router(fmt or self.fmt, tenant_id, name, - admin_state_up, external_gateway_info, - set_context, **kwargs) - self._add_external_gateway_to_router( - router['router']['id'], - subnet['subnet']['network_id']) - - yield router - - self._remove_external_gateway_from_router( - router['router']['id'], subnet['subnet']['network_id']) - self._delete('routers', router['router']['id']) - - -class L3AgentChanceSchedulerTestCase(L3SchedulerTestCase): - - def test_random_scheduling(self): - random_patch = mock.patch('random.choice') - random_mock = random_patch.start() - - def side_effect(seq): - return seq[0] - random_mock.side_effect = side_effect - - with self.subnet() as subnet: - self._set_net_external(subnet['subnet']['network_id']) - with self.router_with_ext_gw(name='r1', subnet=subnet) as r1: - agents = self.get_l3_agents_hosting_routers( - self.adminContext, [r1['router']['id']], - admin_state_up=True) - - self.assertEqual(len(agents), 1) - self.assertEqual(random_mock.call_count, 1) - - with self.router_with_ext_gw(name='r2', subnet=subnet) as r2: - agents = self.get_l3_agents_hosting_routers( - self.adminContext, [r2['router']['id']], - admin_state_up=True) - - self.assertEqual(len(agents), 1) - self.assertEqual(random_mock.call_count, 2) - - random_patch.stop() - - -class L3AgentLeastRoutersSchedulerTestCase(L3SchedulerTestCase): - def setUp(self): - cfg.CONF.set_override('router_scheduler_driver', - 'neutron.scheduler.l3_agent_scheduler.' - 'LeastRoutersScheduler') - - super(L3AgentLeastRoutersSchedulerTestCase, self).setUp() - - def test_scheduler(self): - # disable one agent to force the scheduling to the only one. - self._set_l3_agent_admin_state(self.adminContext, - self.agent_id2, False) - - with self.subnet() as subnet: - self._set_net_external(subnet['subnet']['network_id']) - with self.router_with_ext_gw(name='r1', subnet=subnet) as r1: - agents = self.get_l3_agents_hosting_routers( - self.adminContext, [r1['router']['id']], - admin_state_up=True) - self.assertEqual(len(agents), 1) - - agent_id1 = agents[0]['id'] - - with self.router_with_ext_gw(name='r2', subnet=subnet) as r2: - agents = self.get_l3_agents_hosting_routers( - self.adminContext, [r2['router']['id']], - admin_state_up=True) - self.assertEqual(len(agents), 1) - - agent_id2 = agents[0]['id'] - - self.assertEqual(agent_id1, agent_id2) - - # re-enable the second agent to see whether the next router - # spawned will be on this one. - self._set_l3_agent_admin_state(self.adminContext, - self.agent_id2, True) - - with self.router_with_ext_gw(name='r3', - subnet=subnet) as r3: - agents = self.get_l3_agents_hosting_routers( - self.adminContext, [r3['router']['id']], - admin_state_up=True) - self.assertEqual(len(agents), 1) - - agent_id3 = agents[0]['id'] - - self.assertNotEqual(agent_id1, agent_id3) diff --git a/neutron/tests/unit/test_linux_daemon.py b/neutron/tests/unit/test_linux_daemon.py deleted file mode 100644 index ab65a2bb2..000000000 --- a/neutron/tests/unit/test_linux_daemon.py +++ /dev/null @@ -1,211 +0,0 @@ -# -# Copyright 2012 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost - -import os -import sys - -import mock -import testtools - -from neutron.agent.linux import daemon -from neutron.tests import base - -FAKE_FD = 8 - - -class TestPidfile(base.BaseTestCase): - def setUp(self): - super(TestPidfile, self).setUp() - self.os_p = mock.patch.object(daemon, 'os') - self.os = self.os_p.start() - self.os.open.return_value = FAKE_FD - - self.fcntl_p = mock.patch.object(daemon, 'fcntl') - self.fcntl = self.fcntl_p.start() - self.fcntl.flock.return_value = 0 - - def test_init(self): - self.os.O_CREAT = os.O_CREAT - self.os.O_RDWR = os.O_RDWR - - daemon.Pidfile('thefile', 'python') - self.os.open.assert_called_once_with('thefile', os.O_CREAT | os.O_RDWR) - self.fcntl.flock.assert_called_once_with(FAKE_FD, self.fcntl.LOCK_EX | - self.fcntl.LOCK_NB) - - def test_init_open_fail(self): - self.os.open.side_effect = IOError - - with mock.patch.object(daemon.sys, 'stderr'): - with testtools.ExpectedException(SystemExit): - daemon.Pidfile('thefile', 'python') - sys.assert_has_calls([ - mock.call.stderr.write(mock.ANY), - mock.call.exit(1)] - ) - - def test_unlock(self): - p = daemon.Pidfile('thefile', 'python') - p.unlock() - self.fcntl.flock.assert_has_calls([ - mock.call(FAKE_FD, self.fcntl.LOCK_EX | self.fcntl.LOCK_NB), - mock.call(FAKE_FD, self.fcntl.LOCK_UN)] - ) - - def test_write(self): - p = daemon.Pidfile('thefile', 'python') - p.write(34) - - self.os.assert_has_calls([ - mock.call.ftruncate(FAKE_FD, 0), - mock.call.write(FAKE_FD, '34'), - mock.call.fsync(FAKE_FD)] - ) - - def test_read(self): - self.os.read.return_value = '34' - p = daemon.Pidfile('thefile', 'python') - self.assertEqual(34, p.read()) - - def test_is_running(self): - with mock.patch('__builtin__.open') as mock_open: - p = daemon.Pidfile('thefile', 'python') - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.readline.return_value = 'python' - - with mock.patch.object(p, 'read') as read: - read.return_value = 34 - self.assertTrue(p.is_running()) - - mock_open.assert_called_once_with('/proc/34/cmdline', 'r') - - def test_is_running_uuid_true(self): - with mock.patch('__builtin__.open') as mock_open: - p = daemon.Pidfile('thefile', 'python', uuid='1234') - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.readline.return_value = 'python 1234' - - with mock.patch.object(p, 'read') as read: - read.return_value = 34 - self.assertTrue(p.is_running()) - - mock_open.assert_called_once_with('/proc/34/cmdline', 'r') - - def test_is_running_uuid_false(self): - with mock.patch('__builtin__.open') as mock_open: - p = daemon.Pidfile('thefile', 'python', uuid='6789') - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.readline.return_value = 'python 1234' - - with mock.patch.object(p, 'read') as read: - read.return_value = 34 - self.assertFalse(p.is_running()) - - mock_open.assert_called_once_with('/proc/34/cmdline', 'r') - - -class TestDaemon(base.BaseTestCase): - def setUp(self): - super(TestDaemon, self).setUp() - self.os_p = mock.patch.object(daemon, 'os') - self.os = self.os_p.start() - - self.pidfile_p = mock.patch.object(daemon, 'Pidfile') - self.pidfile = self.pidfile_p.start() - - def test_init(self): - d = daemon.Daemon('pidfile') - self.assertEqual(d.procname, 'python') - - def test_fork_parent(self): - self.os.fork.return_value = 1 - with testtools.ExpectedException(SystemExit): - d = daemon.Daemon('pidfile') - d._fork() - - def test_fork_child(self): - self.os.fork.return_value = 0 - d = daemon.Daemon('pidfile') - self.assertIsNone(d._fork()) - - def test_fork_error(self): - self.os.fork.side_effect = lambda: OSError(1) - with mock.patch.object(daemon.sys, 'stderr'): - with testtools.ExpectedException(SystemExit): - d = daemon.Daemon('pidfile', 'stdin') - d._fork() - - def test_daemonize(self): - d = daemon.Daemon('pidfile') - with mock.patch.object(d, '_fork') as fork: - with mock.patch.object(daemon, 'atexit') as atexit: - with mock.patch.object(daemon, 'signal') as signal: - signal.SIGTERM = 15 - with mock.patch.object(daemon, 'sys') as sys: - sys.stdin.fileno.return_value = 0 - sys.stdout.fileno.return_value = 1 - sys.stderr.fileno.return_value = 2 - d.daemonize() - - signal.signal.assert_called_once_with(15, d.handle_sigterm) - atexit.register.assert_called_once_with(d.delete_pid) - fork.assert_has_calls([mock.call(), mock.call()]) - - self.os.assert_has_calls([ - mock.call.chdir('/'), - mock.call.setsid(), - mock.call.umask(0), - mock.call.dup2(mock.ANY, 0), - mock.call.dup2(mock.ANY, 1), - mock.call.dup2(mock.ANY, 2), - mock.call.getpid()] - ) - - def test_delete_pid(self): - self.pidfile.return_value.__str__.return_value = 'pidfile' - d = daemon.Daemon('pidfile') - d.delete_pid() - self.os.remove.assert_called_once_with('pidfile') - - def test_handle_sigterm(self): - d = daemon.Daemon('pidfile') - with mock.patch.object(daemon, 'sys') as sys: - d.handle_sigterm(15, 1234) - sys.exit.assert_called_once_with(0) - - def test_start(self): - self.pidfile.return_value.is_running.return_value = False - d = daemon.Daemon('pidfile') - - with mock.patch.object(d, 'daemonize') as daemonize: - with mock.patch.object(d, 'run') as run: - d.start() - run.assert_called_once_with() - daemonize.assert_called_once_with() - - def test_start_running(self): - self.pidfile.return_value.is_running.return_value = True - d = daemon.Daemon('pidfile') - - with mock.patch.object(daemon.sys, 'stderr'): - with mock.patch.object(d, 'daemonize') as daemonize: - with testtools.ExpectedException(SystemExit): - d.start() - self.assertFalse(daemonize.called) diff --git a/neutron/tests/unit/test_linux_dhcp.py b/neutron/tests/unit/test_linux_dhcp.py deleted file mode 100644 index bedf1755f..000000000 --- a/neutron/tests/unit/test_linux_dhcp.py +++ /dev/null @@ -1,1252 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# 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 contextlib -import os - -import mock -from oslo.config import cfg - -from neutron.agent.common import config -from neutron.agent.linux import dhcp -from neutron.common import config as base_config -from neutron.common import constants -from neutron.openstack.common import log as logging -from neutron.tests import base - -LOG = logging.getLogger(__name__) - - -class FakeIPAllocation: - def __init__(self, address, subnet_id=None): - self.ip_address = address - self.subnet_id = subnet_id - - -class DhcpOpt(object): - def __init__(self, **kwargs): - self.__dict__.update(kwargs) - - def __str__(self): - return str(self.__dict__) - - -class FakePort1: - id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - admin_state_up = True - device_owner = 'foo1' - fixed_ips = [FakeIPAllocation('192.168.0.2')] - mac_address = '00:00:80:aa:bb:cc' - - def __init__(self): - self.extra_dhcp_opts = [] - - -class FakePort2: - id = 'ffffffff-ffff-ffff-ffff-ffffffffffff' - admin_state_up = False - device_owner = 'foo2' - fixed_ips = [FakeIPAllocation('fdca:3ba5:a17a:4ba3::2')] - mac_address = '00:00:f3:aa:bb:cc' - - def __init__(self): - self.extra_dhcp_opts = [] - - -class FakePort3: - id = '44444444-4444-4444-4444-444444444444' - admin_state_up = True - device_owner = 'foo3' - fixed_ips = [FakeIPAllocation('192.168.0.3'), - FakeIPAllocation('fdca:3ba5:a17a:4ba3::3')] - mac_address = '00:00:0f:aa:bb:cc' - - def __init__(self): - self.extra_dhcp_opts = [] - - -class FakeRouterPort: - id = 'rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr' - admin_state_up = True - device_owner = constants.DEVICE_OWNER_ROUTER_INTF - fixed_ips = [FakeIPAllocation('192.168.0.1', - 'dddddddd-dddd-dddd-dddd-dddddddddddd')] - mac_address = '00:00:0f:rr:rr:rr' - - def __init__(self): - self.extra_dhcp_opts = [] - - -class FakePortMultipleAgents1: - id = 'rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr' - admin_state_up = True - device_owner = constants.DEVICE_OWNER_DHCP - fixed_ips = [FakeIPAllocation('192.168.0.5', - 'dddddddd-dddd-dddd-dddd-dddddddddddd')] - mac_address = '00:00:0f:dd:dd:dd' - - def __init__(self): - self.extra_dhcp_opts = [] - - -class FakePortMultipleAgents2: - id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - admin_state_up = True - device_owner = constants.DEVICE_OWNER_DHCP - fixed_ips = [FakeIPAllocation('192.168.0.6', - 'dddddddd-dddd-dddd-dddd-dddddddddddd')] - mac_address = '00:00:0f:ee:ee:ee' - - def __init__(self): - self.extra_dhcp_opts = [] - - -class FakeV4HostRoute: - destination = '20.0.0.1/24' - nexthop = '20.0.0.1' - - -class FakeV4HostRouteGateway: - destination = '0.0.0.0/0' - nexthop = '10.0.0.1' - - -class FakeV6HostRoute: - destination = '2001:0200:feed:7ac0::/64' - nexthop = '2001:0200:feed:7ac0::1' - - -class FakeV4Subnet: - id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' - ip_version = 4 - cidr = '192.168.0.0/24' - gateway_ip = '192.168.0.1' - enable_dhcp = True - host_routes = [FakeV4HostRoute] - dns_nameservers = ['8.8.8.8'] - - -class FakeV4SubnetGatewayRoute: - id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' - ip_version = 4 - cidr = '192.168.0.0/24' - gateway_ip = '192.168.0.1' - enable_dhcp = True - host_routes = [FakeV4HostRouteGateway] - dns_nameservers = ['8.8.8.8'] - - -class FakeV4SubnetMultipleAgentsWithoutDnsProvided: - id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' - ip_version = 4 - cidr = '192.168.0.0/24' - gateway_ip = '192.168.0.1' - enable_dhcp = True - dns_nameservers = [] - host_routes = [] - - -class FakeV4MultipleAgentsWithoutDnsProvided: - id = 'ffffffff-ffff-ffff-ffff-ffffffffffff' - subnets = [FakeV4SubnetMultipleAgentsWithoutDnsProvided()] - ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort(), - FakePortMultipleAgents1(), FakePortMultipleAgents2()] - namespace = 'qdhcp-ns' - - -class FakeV4SubnetMultipleAgentsWithDnsProvided: - id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' - ip_version = 4 - cidr = '192.168.0.0/24' - gateway_ip = '192.168.0.1' - enable_dhcp = True - dns_nameservers = ['8.8.8.8'] - host_routes = [] - - -class FakeV4MultipleAgentsWithDnsProvided: - id = 'ffffffff-ffff-ffff-ffff-ffffffffffff' - subnets = [FakeV4SubnetMultipleAgentsWithDnsProvided()] - ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort(), - FakePortMultipleAgents1(), FakePortMultipleAgents2()] - namespace = 'qdhcp-ns' - - -class FakeV6Subnet: - id = 'ffffffff-ffff-ffff-ffff-ffffffffffff' - ip_version = 6 - cidr = 'fdca:3ba5:a17a:4ba3::/64' - gateway_ip = 'fdca:3ba5:a17a:4ba3::1' - enable_dhcp = True - host_routes = [FakeV6HostRoute] - dns_nameservers = ['2001:0200:feed:7ac0::1'] - - -class FakeV4SubnetNoDHCP: - id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - ip_version = 4 - cidr = '192.168.1.0/24' - gateway_ip = '192.168.1.1' - enable_dhcp = False - host_routes = [] - dns_nameservers = [] - - -class FakeV4SubnetNoGateway: - id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - ip_version = 4 - cidr = '192.168.1.0/24' - gateway_ip = None - enable_dhcp = True - host_routes = [] - dns_nameservers = [] - - -class FakeV4SubnetNoRouter: - id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - ip_version = 4 - cidr = '192.168.1.0/24' - gateway_ip = '192.168.1.1' - enable_dhcp = True - host_routes = [] - dns_nameservers = [] - - -class FakeV4Network: - id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - subnets = [FakeV4Subnet()] - ports = [FakePort1()] - namespace = 'qdhcp-ns' - - -class FakeV6Network: - id = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb' - subnets = [FakeV6Subnet()] - ports = [FakePort2()] - namespace = 'qdhcp-ns' - - -class FakeDualNetwork: - id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' - subnets = [FakeV4Subnet(), FakeV6Subnet()] - ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort()] - namespace = 'qdhcp-ns' - - -class FakeDualNetworkGatewayRoute: - id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' - subnets = [FakeV4SubnetGatewayRoute(), FakeV6Subnet()] - ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort()] - namespace = 'qdhcp-ns' - - -class FakeDualNetworkSingleDHCP: - id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' - subnets = [FakeV4Subnet(), FakeV4SubnetNoDHCP()] - ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort()] - namespace = 'qdhcp-ns' - - -class FakeV4NoGatewayNetwork: - id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' - subnets = [FakeV4SubnetNoGateway()] - ports = [FakePort1()] - - -class FakeV4NetworkNoRouter: - id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' - subnets = [FakeV4SubnetNoRouter()] - ports = [FakePort1()] - - -class FakeDualV4Pxe3Ports: - id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' - subnets = [FakeV4Subnet(), FakeV4SubnetNoDHCP()] - ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort()] - namespace = 'qdhcp-ns' - - def __init__(self, port_detail="portsSame"): - if port_detail == "portsSame": - self.ports[0].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - self.ports[1].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.1.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.1.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux2.0')] - self.ports[2].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.1.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.1.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux3.0')] - else: - self.ports[0].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.2'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - self.ports[1].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.5'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.5'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux2.0')] - self.ports[2].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.7'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.7'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux3.0')] - - -class FakeV4NetworkPxe2Ports: - id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' - subnets = [FakeV4Subnet()] - ports = [FakePort1(), FakePort2(), FakeRouterPort()] - namespace = 'qdhcp-ns' - - def __init__(self, port_detail="portsSame"): - if port_detail == "portsSame": - self.ports[0].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - self.ports[1].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - else: - self.ports[0].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - self.ports[1].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.5'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.5'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - - -class FakeV4NetworkPxe3Ports: - id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' - subnets = [FakeV4Subnet()] - ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort()] - namespace = 'qdhcp-ns' - - def __init__(self, port_detail="portsSame"): - if port_detail == "portsSame": - self.ports[0].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - self.ports[1].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.1.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.1.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - self.ports[2].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.1.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.1.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - else: - self.ports[0].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.3'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.2'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0')] - self.ports[1].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.5'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.5'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux2.0')] - self.ports[2].extra_dhcp_opts = [ - DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.7'), - DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.7'), - DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux3.0')] - - -class LocalChild(dhcp.DhcpLocalProcess): - PORTS = {4: [4], 6: [6]} - - def __init__(self, *args, **kwargs): - super(LocalChild, self).__init__(*args, **kwargs) - self.called = [] - - def reload_allocations(self): - self.called.append('reload') - - def restart(self): - self.called.append('restart') - - def spawn_process(self): - self.called.append('spawn') - - -class TestBase(base.BaseTestCase): - def setUp(self): - super(TestBase, self).setUp() - self.conf = config.setup_conf() - self.conf.register_opts(base_config.core_opts) - self.conf.register_opts(dhcp.OPTS) - config.register_interface_driver_opts_helper(self.conf) - instance = mock.patch("neutron.agent.linux.dhcp.DeviceManager") - self.mock_mgr = instance.start() - self.conf.register_opt(cfg.BoolOpt('enable_isolated_metadata', - default=True)) - self.config_parse(self.conf) - self.conf.set_override('state_path', '') - self.conf.use_namespaces = True - - self.replace_p = mock.patch('neutron.agent.linux.utils.replace_file') - self.execute_p = mock.patch('neutron.agent.linux.utils.execute') - self.safe = self.replace_p.start() - self.execute = self.execute_p.start() - - -class TestDhcpBase(TestBase): - - def test_existing_dhcp_networks_abstract_error(self): - self.assertRaises(NotImplementedError, - dhcp.DhcpBase.existing_dhcp_networks, - None, None) - - def test_check_version_abstract_error(self): - self.assertRaises(NotImplementedError, - dhcp.DhcpBase.check_version) - - def test_base_abc_error(self): - self.assertRaises(TypeError, dhcp.DhcpBase, None) - - def test_restart(self): - class SubClass(dhcp.DhcpBase): - def __init__(self): - dhcp.DhcpBase.__init__(self, cfg.CONF, FakeV4Network(), None) - self.called = [] - - def enable(self): - self.called.append('enable') - - def disable(self, retain_port=False): - self.called.append('disable %s' % retain_port) - - def reload_allocations(self): - pass - - @property - def active(self): - return True - - c = SubClass() - c.restart() - self.assertEqual(c.called, ['disable True', 'enable']) - - -class TestDhcpLocalProcess(TestBase): - def test_active(self): - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.readline.return_value = \ - 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - - with mock.patch.object(LocalChild, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=4) - lp = LocalChild(self.conf, FakeV4Network()) - self.assertTrue(lp.active) - - mock_open.assert_called_once_with('/proc/4/cmdline', 'r') - - def test_active_none(self): - dummy_cmd_line = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - self.execute.return_value = (dummy_cmd_line, '') - with mock.patch.object(LocalChild, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=None) - lp = LocalChild(self.conf, FakeV4Network()) - self.assertFalse(lp.active) - - def test_active_cmd_mismatch(self): - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.readline.return_value = \ - 'bbbbbbbb-bbbb-bbbb-aaaa-aaaaaaaaaaaa' - - with mock.patch.object(LocalChild, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=4) - lp = LocalChild(self.conf, FakeV4Network()) - self.assertFalse(lp.active) - - mock_open.assert_called_once_with('/proc/4/cmdline', 'r') - - def test_get_conf_file_name(self): - tpl = '/dhcp/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/dev' - with mock.patch('os.path.isdir') as isdir: - isdir.return_value = False - with mock.patch('os.makedirs') as makedirs: - lp = LocalChild(self.conf, FakeV4Network()) - self.assertEqual(lp.get_conf_file_name('dev'), tpl) - self.assertFalse(makedirs.called) - - def test_get_conf_file_name_ensure_dir(self): - tpl = '/dhcp/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/dev' - with mock.patch('os.path.isdir') as isdir: - isdir.return_value = False - with mock.patch('os.makedirs') as makedirs: - lp = LocalChild(self.conf, FakeV4Network()) - self.assertEqual(lp.get_conf_file_name('dev', True), tpl) - self.assertTrue(makedirs.called) - - def test_enable_already_active(self): - with mock.patch.object(LocalChild, 'active') as patched: - patched.__get__ = mock.Mock(return_value=True) - lp = LocalChild(self.conf, FakeV4Network()) - lp.enable() - - self.assertEqual(lp.called, ['restart']) - - def test_enable(self): - attrs_to_mock = dict( - [(a, mock.DEFAULT) for a in - ['active', 'get_conf_file_name', 'interface_name']] - ) - - with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks: - mocks['active'].__get__ = mock.Mock(return_value=False) - mocks['get_conf_file_name'].return_value = '/dir' - mocks['interface_name'].__set__ = mock.Mock() - lp = LocalChild(self.conf, - FakeDualNetwork()) - lp.enable() - - self.mock_mgr.assert_has_calls( - [mock.call(self.conf, 'sudo', None), - mock.call().setup(mock.ANY)]) - self.assertEqual(lp.called, ['spawn']) - self.assertTrue(mocks['interface_name'].__set__.called) - - def test_disable_not_active(self): - attrs_to_mock = dict([(a, mock.DEFAULT) for a in - ['active', 'interface_name', 'pid']]) - with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks: - mocks['active'].__get__ = mock.Mock(return_value=False) - mocks['pid'].__get__ = mock.Mock(return_value=5) - mocks['interface_name'].__get__ = mock.Mock(return_value='tap0') - with mock.patch.object(dhcp.LOG, 'debug') as log: - network = FakeDualNetwork() - lp = LocalChild(self.conf, network) - lp.device_manager = mock.Mock() - lp.disable() - msg = log.call_args[0][0] - self.assertIn('does not exist', msg) - lp.device_manager.destroy.assert_called_once_with( - network, 'tap0') - - def test_disable_unknown_network(self): - attrs_to_mock = dict([(a, mock.DEFAULT) for a in - ['active', 'interface_name', 'pid']]) - with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks: - mocks['active'].__get__ = mock.Mock(return_value=False) - mocks['pid'].__get__ = mock.Mock(return_value=None) - mocks['interface_name'].__get__ = mock.Mock(return_value='tap0') - with mock.patch.object(dhcp.LOG, 'debug') as log: - lp = LocalChild(self.conf, FakeDualNetwork()) - lp.disable() - msg = log.call_args[0][0] - self.assertIn('No DHCP', msg) - - def test_disable_retain_port(self): - attrs_to_mock = dict([(a, mock.DEFAULT) for a in - ['active', 'interface_name', 'pid']]) - network = FakeDualNetwork() - with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks: - mocks['active'].__get__ = mock.Mock(return_value=True) - mocks['pid'].__get__ = mock.Mock(return_value=5) - mocks['interface_name'].__get__ = mock.Mock(return_value='tap0') - lp = LocalChild(self.conf, network) - lp.disable(retain_port=True) - - exp_args = ['kill', '-9', 5] - self.execute.assert_called_once_with(exp_args, 'sudo') - - def test_disable(self): - attrs_to_mock = dict([(a, mock.DEFAULT) for a in - ['active', 'interface_name', 'pid']]) - network = FakeDualNetwork() - with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks: - mocks['active'].__get__ = mock.Mock(return_value=True) - mocks['pid'].__get__ = mock.Mock(return_value=5) - mocks['interface_name'].__get__ = mock.Mock(return_value='tap0') - lp = LocalChild(self.conf, network) - with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip: - lp.disable() - - self.mock_mgr.assert_has_calls([mock.call(self.conf, 'sudo', None), - mock.call().destroy(network, 'tap0')]) - exp_args = ['kill', '-9', 5] - self.execute.assert_called_once_with(exp_args, 'sudo') - - self.assertEqual(ip.return_value.netns.delete.call_count, 0) - - def test_disable_delete_ns(self): - self.conf.set_override('dhcp_delete_namespaces', True) - attrs_to_mock = dict([(a, mock.DEFAULT) for a in ['active', 'pid']]) - - with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks: - mocks['active'].__get__ = mock.Mock(return_value=False) - mocks['pid'].__get__ = mock.Mock(return_value=False) - lp = LocalChild(self.conf, FakeDualNetwork()) - with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip: - lp.disable() - - ip.return_value.netns.delete.assert_called_with('qdhcp-ns') - - def test_pid(self): - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.read.return_value = '5' - lp = LocalChild(self.conf, FakeDualNetwork()) - self.assertEqual(lp.pid, 5) - - def test_pid_no_an_int(self): - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.read.return_value = 'foo' - lp = LocalChild(self.conf, FakeDualNetwork()) - self.assertIsNone(lp.pid) - - def test_pid_invalid_file(self): - with mock.patch.object(LocalChild, 'get_conf_file_name') as conf_file: - conf_file.return_value = '.doesnotexist/pid' - lp = LocalChild(self.conf, FakeDualNetwork()) - self.assertIsNone(lp.pid) - - def test_get_interface_name(self): - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.read.return_value = 'tap0' - lp = LocalChild(self.conf, FakeDualNetwork()) - self.assertEqual(lp.interface_name, 'tap0') - - def test_set_interface_name(self): - with mock.patch('neutron.agent.linux.utils.replace_file') as replace: - lp = LocalChild(self.conf, FakeDualNetwork()) - with mock.patch.object(lp, 'get_conf_file_name') as conf_file: - conf_file.return_value = '/interface' - lp.interface_name = 'tap0' - conf_file.assert_called_once_with('interface', - ensure_conf_dir=True) - replace.assert_called_once_with(mock.ANY, 'tap0') - - -class TestDnsmasq(TestBase): - def _test_spawn(self, extra_options, network=FakeDualNetwork(), - max_leases=16777216, lease_duration=86400): - def mock_get_conf_file_name(kind, ensure_conf_dir=False): - return '/dhcp/%s/%s' % (network.id, kind) - - def fake_argv(index): - if index == 0: - return '/usr/local/bin/neutron-dhcp-agent' - else: - raise IndexError - - expected = [ - 'ip', - 'netns', - 'exec', - 'qdhcp-ns', - 'env', - 'NEUTRON_NETWORK_ID=%s' % network.id, - 'dnsmasq', - '--no-hosts', - '--no-resolv', - '--strict-order', - '--bind-interfaces', - '--interface=tap0', - '--except-interface=lo', - '--pid-file=/dhcp/%s/pid' % network.id, - '--dhcp-hostsfile=/dhcp/%s/host' % network.id, - '--addn-hosts=/dhcp/%s/addn_hosts' % network.id, - '--dhcp-optsfile=/dhcp/%s/opts' % network.id, - '--leasefile-ro'] - - seconds = '' - if lease_duration == -1: - lease_duration = 'infinite' - else: - seconds = 's' - expected.extend('--dhcp-range=set:tag%d,%s,static,%s%s' % - (i, s.cidr.split('/')[0], lease_duration, seconds) - for i, s in enumerate(network.subnets)) - - expected.append('--dhcp-lease-max=%d' % max_leases) - expected.extend(extra_options) - - self.execute.return_value = ('', '') - - attrs_to_mock = dict( - [(a, mock.DEFAULT) for a in - ['_output_opts_file', 'get_conf_file_name', 'interface_name']] - ) - - with mock.patch.multiple(dhcp.Dnsmasq, **attrs_to_mock) as mocks: - mocks['get_conf_file_name'].side_effect = mock_get_conf_file_name - mocks['_output_opts_file'].return_value = ( - '/dhcp/%s/opts' % network.id - ) - mocks['interface_name'].__get__ = mock.Mock(return_value='tap0') - - with mock.patch.object(dhcp.sys, 'argv') as argv: - argv.__getitem__.side_effect = fake_argv - dm = dhcp.Dnsmasq(self.conf, network, version=float(2.59)) - dm.spawn_process() - self.assertTrue(mocks['_output_opts_file'].called) - self.execute.assert_called_once_with(expected, - root_helper='sudo', - check_exit_code=True) - - def test_spawn(self): - self._test_spawn(['--conf-file=', '--domain=openstacklocal']) - - def test_spawn_infinite_lease_duration(self): - self.conf.set_override('dhcp_lease_duration', -1) - self._test_spawn(['--conf-file=', '--domain=openstacklocal'], - FakeDualNetwork(), 16777216, -1) - - def test_spawn_cfg_config_file(self): - self.conf.set_override('dnsmasq_config_file', '/foo') - self._test_spawn(['--conf-file=/foo', '--domain=openstacklocal']) - - def test_spawn_no_dhcp_domain(self): - self.conf.set_override('dhcp_domain', '') - self._test_spawn(['--conf-file=']) - - def test_spawn_cfg_dns_server(self): - self.conf.set_override('dnsmasq_dns_servers', ['8.8.8.8']) - self._test_spawn(['--conf-file=', - '--server=8.8.8.8', - '--domain=openstacklocal']) - - def test_spawn_cfg_multiple_dns_server(self): - self.conf.set_override('dnsmasq_dns_servers', ['8.8.8.8', - '9.9.9.9']) - self._test_spawn(['--conf-file=', - '--server=8.8.8.8', - '--server=9.9.9.9', - '--domain=openstacklocal']) - - def test_spawn_max_leases_is_smaller_than_cap(self): - self._test_spawn( - ['--conf-file=', '--domain=openstacklocal'], - network=FakeV4Network(), - max_leases=256) - - def test_output_opts_file(self): - fake_v6 = '2001:0200:feed:7ac0::1' - fake_v6_cidr = '2001:0200:feed:7ac0::/64' - expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:tag1,option:dns-server,%s\n' - 'tag:tag1,option:classless-static-route,%s,%s\n' - 'tag:tag1,249,%s,%s').lstrip() % (fake_v6, - fake_v6_cidr, fake_v6, - fake_v6_cidr, fake_v6) - - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(), - version=float(2.59)) - dm._output_opts_file() - - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_gateway_route(self): - fake_v6 = '2001:0200:feed:7ac0::1' - fake_v6_cidr = '2001:0200:feed:7ac0::/64' - expected = """ -tag:tag0,option:dns-server,8.8.8.8 -tag:tag0,option:router,192.168.0.1 -tag:tag1,option:dns-server,%s -tag:tag1,option:classless-static-route,%s,%s -tag:tag1,249,%s,%s""".lstrip() % (fake_v6, - fake_v6_cidr, fake_v6, - fake_v6_cidr, fake_v6) - - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkGatewayRoute(), - version=float(2.59)) - dm._output_opts_file() - - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_multiple_agents_without_dns_provided(self): - expected = """ -tag:tag0,option:router,192.168.0.1 -tag:tag0,option:dns-server,192.168.0.5,192.168.0.6""".lstrip() - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, - FakeV4MultipleAgentsWithoutDnsProvided(), - version=float(2.59)) - dm._output_opts_file() - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_multiple_agents_with_dns_provided(self): - expected = """ -tag:tag0,option:dns-server,8.8.8.8 -tag:tag0,option:router,192.168.0.1""".lstrip() - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, - FakeV4MultipleAgentsWithDnsProvided(), - version=float(2.59)) - dm._output_opts_file() - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_single_dhcp(self): - expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1').lstrip() - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkSingleDHCP(), - version=float(2.59)) - dm._output_opts_file() - - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_single_dhcp_ver2_48(self): - expected = ( - 'tag0,option:dns-server,8.8.8.8\n' - 'tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag0,249,20.0.0.1/24,20.0.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag0,option:router,192.168.0.1').lstrip() - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkSingleDHCP(), - version=float(2.48)) - dm._output_opts_file() - - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_no_gateway(self): - expected = """ -tag:tag0,option:classless-static-route,169.254.169.254/32,192.168.1.1 -tag:tag0,249,169.254.169.254/32,192.168.1.1 -tag:tag0,option:router""".lstrip() - - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, FakeV4NoGatewayNetwork(), - version=float(2.59)) - with mock.patch.object(dm, '_make_subnet_interface_ip_map') as ipm: - ipm.return_value = {FakeV4SubnetNoGateway.id: '192.168.1.1'} - - dm._output_opts_file() - self.assertTrue(ipm.called) - - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_no_neutron_router_on_subnet(self): - expected = ( - 'tag:tag0,option:classless-static-route,' - '169.254.169.254/32,192.168.1.2,0.0.0.0/0,192.168.1.1\n' - 'tag:tag0,249,169.254.169.254/32,192.168.1.2,' - '0.0.0.0/0,192.168.1.1\n' - 'tag:tag0,option:router,192.168.1.1').lstrip() - - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, FakeV4NetworkNoRouter(), - version=float(2.59)) - with mock.patch.object(dm, '_make_subnet_interface_ip_map') as ipm: - ipm.return_value = {FakeV4SubnetNoRouter.id: '192.168.1.2'} - - dm._output_opts_file() - self.assertTrue(ipm.called) - - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_pxe_2port_1net(self): - expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:tftp-server,192.168.0.3\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:server-ip-address,192.168.0.2\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:bootfile-name,pxelinux.0\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:tftp-server,192.168.0.3\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:server-ip-address,192.168.0.2\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:bootfile-name,pxelinux.0') - expected = expected.lstrip() - - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - fp = FakeV4NetworkPxe2Ports() - dm = dhcp.Dnsmasq(self.conf, fp, version=float(2.59)) - dm._output_opts_file() - - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_pxe_2port_1net_diff_details(self): - expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:tftp-server,192.168.0.3\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:server-ip-address,192.168.0.2\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:bootfile-name,pxelinux.0\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:tftp-server,192.168.0.5\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:server-ip-address,192.168.0.5\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:bootfile-name,pxelinux.0') - expected = expected.lstrip() - - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, FakeV4NetworkPxe2Ports("portsDiff"), - version=float(2.59)) - dm._output_opts_file() - - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_pxe_3port_1net_diff_details(self): - expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:tftp-server,192.168.0.3\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:server-ip-address,192.168.0.2\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:bootfile-name,pxelinux.0\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:tftp-server,192.168.0.5\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:server-ip-address,192.168.0.5\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:bootfile-name,pxelinux2.0\n' - 'tag:44444444-4444-4444-4444-444444444444,' - 'option:tftp-server,192.168.0.7\n' - 'tag:44444444-4444-4444-4444-444444444444,' - 'option:server-ip-address,192.168.0.7\n' - 'tag:44444444-4444-4444-4444-444444444444,' - 'option:bootfile-name,pxelinux3.0') - expected = expected.lstrip() - - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, - FakeV4NetworkPxe3Ports("portsDifferent"), - version=float(2.59)) - dm._output_opts_file() - - self.safe.assert_called_once_with('/foo/opts', expected) - - def test_output_opts_file_pxe_3port_2net(self): - expected = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:tftp-server,192.168.0.3\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:server-ip-address,192.168.0.2\n' - 'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' - 'option:bootfile-name,pxelinux.0\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:tftp-server,192.168.1.3\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:server-ip-address,192.168.1.2\n' - 'tag:ffffffff-ffff-ffff-ffff-ffffffffffff,' - 'option:bootfile-name,pxelinux2.0\n' - 'tag:44444444-4444-4444-4444-444444444444,' - 'option:tftp-server,192.168.1.3\n' - 'tag:44444444-4444-4444-4444-444444444444,' - 'option:server-ip-address,192.168.1.2\n' - 'tag:44444444-4444-4444-4444-444444444444,' - 'option:bootfile-name,pxelinux3.0') - expected = expected.lstrip() - - with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: - conf_fn.return_value = '/foo/opts' - dm = dhcp.Dnsmasq(self.conf, FakeDualV4Pxe3Ports(), - version=float(2.59)) - dm._output_opts_file() - - self.safe.assert_called_once_with('/foo/opts', expected) - - @property - def _test_reload_allocation_data(self): - exp_host_name = '/dhcp/cccccccc-cccc-cccc-cccc-cccccccccccc/host' - exp_host_data = ('00:00:80:aa:bb:cc,host-192-168-0-2.openstacklocal,' - '192.168.0.2\n' - '00:00:f3:aa:bb:cc,host-fdca-3ba5-a17a-4ba3--2.' - 'openstacklocal,[fdca:3ba5:a17a:4ba3::2]\n' - '00:00:0f:aa:bb:cc,host-192-168-0-3.openstacklocal,' - '192.168.0.3\n' - '00:00:0f:aa:bb:cc,host-fdca-3ba5-a17a-4ba3--3.' - 'openstacklocal,[fdca:3ba5:a17a:4ba3::3]\n' - '00:00:0f:rr:rr:rr,host-192-168-0-1.openstacklocal,' - '192.168.0.1\n').lstrip() - exp_addn_name = '/dhcp/cccccccc-cccc-cccc-cccc-cccccccccccc/addn_hosts' - exp_addn_data = ( - '192.168.0.2\t' - 'host-192-168-0-2.openstacklocal host-192-168-0-2\n' - 'fdca:3ba5:a17a:4ba3::2\t' - 'host-fdca-3ba5-a17a-4ba3--2.openstacklocal ' - 'host-fdca-3ba5-a17a-4ba3--2\n' - '192.168.0.3\thost-192-168-0-3.openstacklocal ' - 'host-192-168-0-3\n' - 'fdca:3ba5:a17a:4ba3::3\t' - 'host-fdca-3ba5-a17a-4ba3--3.openstacklocal ' - 'host-fdca-3ba5-a17a-4ba3--3\n' - '192.168.0.1\t' - 'host-192-168-0-1.openstacklocal ' - 'host-192-168-0-1\n' - ).lstrip() - exp_opt_name = '/dhcp/cccccccc-cccc-cccc-cccc-cccccccccccc/opts' - fake_v6 = '2001:0200:feed:7ac0::1' - fake_v6_cidr = '2001:0200:feed:7ac0::/64' - exp_opt_data = ( - 'tag:tag0,option:dns-server,8.8.8.8\n' - 'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,' - '0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,249,20.0.0.1/24,20.0.0.1,0.0.0.0/0,192.168.0.1\n' - 'tag:tag0,option:router,192.168.0.1\n' - 'tag:tag1,option:dns-server,%s\n' - 'tag:tag1,option:classless-static-route,%s,%s\n' - 'tag:tag1,249,%s,%s').lstrip() % (fake_v6, - fake_v6_cidr, fake_v6, - fake_v6_cidr, fake_v6) - return (exp_host_name, exp_host_data, - exp_addn_name, exp_addn_data, - exp_opt_name, exp_opt_data,) - - def test_reload_allocations(self): - (exp_host_name, exp_host_data, - exp_addn_name, exp_addn_data, - exp_opt_name, exp_opt_data,) = self._test_reload_allocation_data - - exp_args = ['kill', '-HUP', 5] - - fake_net = FakeDualNetwork() - dm = dhcp.Dnsmasq(self.conf, fake_net, version=float(2.59)) - - with contextlib.nested( - mock.patch('os.path.isdir', return_value=True), - mock.patch.object(dhcp.Dnsmasq, 'active'), - mock.patch.object(dhcp.Dnsmasq, 'pid'), - mock.patch.object(dhcp.Dnsmasq, 'interface_name'), - mock.patch.object(dhcp.Dnsmasq, '_make_subnet_interface_ip_map'), - mock.patch.object(dm, 'device_manager') - ) as (isdir, active, pid, interface_name, ip_map, device_manager): - active.__get__ = mock.Mock(return_value=True) - pid.__get__ = mock.Mock(return_value=5) - interface_name.__get__ = mock.Mock(return_value='tap12345678-12') - ip_map.return_value = {} - dm.reload_allocations() - - self.assertTrue(ip_map.called) - self.safe.assert_has_calls([mock.call(exp_host_name, exp_host_data), - mock.call(exp_addn_name, exp_addn_data), - mock.call(exp_opt_name, exp_opt_data)]) - self.execute.assert_called_once_with(exp_args, 'sudo') - device_manager.update.assert_called_with(fake_net, 'tap12345678-12') - - def test_reload_allocations_stale_pid(self): - (exp_host_name, exp_host_data, - exp_addn_name, exp_addn_data, - exp_opt_name, exp_opt_data,) = self._test_reload_allocation_data - - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.readline.return_value = None - - with mock.patch('os.path.isdir') as isdir: - isdir.return_value = True - with mock.patch.object(dhcp.Dnsmasq, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=5) - dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(), - version=float(2.59)) - - method_name = '_make_subnet_interface_ip_map' - with mock.patch.object(dhcp.Dnsmasq, method_name) as ipmap: - ipmap.return_value = {} - with mock.patch.object(dhcp.Dnsmasq, 'interface_name'): - dm.reload_allocations() - self.assertTrue(ipmap.called) - - self.safe.assert_has_calls([ - mock.call(exp_host_name, exp_host_data), - mock.call(exp_addn_name, exp_addn_data), - mock.call(exp_opt_name, exp_opt_data), - ]) - mock_open.assert_called_once_with('/proc/5/cmdline', 'r') - - def test_release_unused_leases(self): - dnsmasq = dhcp.Dnsmasq(self.conf, FakeDualNetwork()) - - ip1 = '192.168.1.2' - mac1 = '00:00:80:aa:bb:cc' - ip2 = '192.168.1.3' - mac2 = '00:00:80:cc:bb:aa' - - old_leases = set([(ip1, mac1), (ip2, mac2)]) - dnsmasq._read_hosts_file_leases = mock.Mock(return_value=old_leases) - dnsmasq._output_hosts_file = mock.Mock() - dnsmasq._release_lease = mock.Mock() - dnsmasq.network.ports = [] - - dnsmasq._release_unused_leases() - - dnsmasq._release_lease.assert_has_calls([mock.call(mac1, ip1), - mock.call(mac2, ip2)], - any_order=True) - - def test_release_unused_leases_one_lease(self): - dnsmasq = dhcp.Dnsmasq(self.conf, FakeDualNetwork()) - - ip1 = '192.168.0.2' - mac1 = '00:00:80:aa:bb:cc' - ip2 = '192.168.0.3' - mac2 = '00:00:80:cc:bb:aa' - - old_leases = set([(ip1, mac1), (ip2, mac2)]) - dnsmasq._read_hosts_file_leases = mock.Mock(return_value=old_leases) - dnsmasq._output_hosts_file = mock.Mock() - dnsmasq._release_lease = mock.Mock() - dnsmasq.network.ports = [FakePort1()] - - dnsmasq._release_unused_leases() - - dnsmasq._release_lease.assert_has_calls([mock.call(mac2, ip2)], - any_order=True) - - def test_read_hosts_file_leases(self): - filename = '/path/to/file' - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - lines = ["00:00:80:aa:bb:cc,inst-name,192.168.0.1"] - mock_open.return_value.readlines.return_value = lines - - dnsmasq = dhcp.Dnsmasq(self.conf, FakeDualNetwork()) - leases = dnsmasq._read_hosts_file_leases(filename) - - self.assertEqual(set([("192.168.0.1", "00:00:80:aa:bb:cc")]), leases) - mock_exists.assert_called_once_with(filename) - mock_open.assert_called_once_with(filename) - - def test_make_subnet_interface_ip_map(self): - with mock.patch('neutron.agent.linux.ip_lib.IPDevice') as ip_dev: - ip_dev.return_value.addr.list.return_value = [ - {'cidr': '192.168.0.1/24'} - ] - - dm = dhcp.Dnsmasq(self.conf, - FakeDualNetwork()) - - self.assertEqual( - dm._make_subnet_interface_ip_map(), - {FakeV4Subnet.id: '192.168.0.1'} - ) - - def test_remove_config_files(self): - net = FakeV4Network() - path = '/opt/data/neutron/dhcp' - self.conf.dhcp_confs = path - - with mock.patch('shutil.rmtree') as rmtree: - lp = LocalChild(self.conf, net) - lp._remove_config_files() - - rmtree.assert_called_once_with(os.path.join(path, net.id), - ignore_errors=True) - - def test_existing_dhcp_networks(self): - path = '/opt/data/neutron/dhcp' - self.conf.dhcp_confs = path - - cases = { - # network_uuid --> is_dhcp_alive? - 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa': True, - 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb': False, - 'not_uuid_like_name': True - } - - def active_fake(self, instance, cls): - return cases[instance.network.id] - - with mock.patch('os.listdir') as mock_listdir: - with mock.patch.object(dhcp.Dnsmasq, 'active') as mock_active: - mock_active.__get__ = active_fake - mock_listdir.return_value = cases.keys() - - result = dhcp.Dnsmasq.existing_dhcp_networks(self.conf, 'sudo') - - mock_listdir.assert_called_once_with(path) - self.assertEqual(['aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', - 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'], - result) - - def _check_version(self, cmd_out, expected_value): - with mock.patch('neutron.agent.linux.utils.execute') as cmd: - cmd.return_value = cmd_out - result = dhcp.Dnsmasq.check_version() - self.assertEqual(result, expected_value) - - def test_check_minimum_version(self): - self._check_version('Dnsmasq version 2.59 Copyright (c)...', - float(2.59)) - - def test_check_future_version(self): - self._check_version('Dnsmasq version 2.65 Copyright (c)...', - float(2.65)) - - def test_check_fail_version(self): - self._check_version('Dnsmasq version 2.48 Copyright (c)...', - float(2.48)) - - def test_check_version_failed_cmd_execution(self): - self._check_version('Error while executing command', 0) diff --git a/neutron/tests/unit/test_linux_external_process.py b/neutron/tests/unit/test_linux_external_process.py deleted file mode 100644 index 9207e5df0..000000000 --- a/neutron/tests/unit/test_linux_external_process.py +++ /dev/null @@ -1,202 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost - -import mock - -from neutron.agent.linux import external_process as ep -from neutron.tests import base - - -class TestProcessManager(base.BaseTestCase): - def setUp(self): - super(TestProcessManager, self).setUp() - self.execute_p = mock.patch('neutron.agent.linux.utils.execute') - self.execute = self.execute_p.start() - self.conf = mock.Mock() - self.conf.external_pids = '/var/path' - - def test_enable_no_namespace(self): - callback = mock.Mock() - callback.return_value = ['the', 'cmd'] - - with mock.patch.object(ep.ProcessManager, 'get_pid_file_name') as name: - name.return_value = 'pidfile' - with mock.patch.object(ep.ProcessManager, 'active') as active: - active.__get__ = mock.Mock(return_value=False) - - manager = ep.ProcessManager(self.conf, 'uuid') - manager.enable(callback) - callback.assert_called_once_with('pidfile') - name.assert_called_once_with(ensure_pids_dir=True) - self.execute.assert_called_once_with(['the', 'cmd'], - root_helper='sudo', - check_exit_code=True) - - def test_enable_with_namespace(self): - callback = mock.Mock() - callback.return_value = ['the', 'cmd'] - - with mock.patch.object(ep.ProcessManager, 'get_pid_file_name') as name: - name.return_value = 'pidfile' - with mock.patch.object(ep.ProcessManager, 'active') as active: - active.__get__ = mock.Mock(return_value=False) - - manager = ep.ProcessManager(self.conf, 'uuid', namespace='ns') - with mock.patch.object(ep, 'ip_lib') as ip_lib: - manager.enable(callback) - callback.assert_called_once_with('pidfile') - name.assert_called_once_with(ensure_pids_dir=True) - ip_lib.assert_has_calls([ - mock.call.IPWrapper('sudo', 'ns'), - mock.call.IPWrapper().netns.execute(['the', 'cmd'])] - ) - - def test_enable_with_namespace_process_active(self): - callback = mock.Mock() - callback.return_value = ['the', 'cmd'] - - with mock.patch.object(ep.ProcessManager, 'active') as active: - active.__get__ = mock.Mock(return_value=True) - - manager = ep.ProcessManager(self.conf, 'uuid', namespace='ns') - with mock.patch.object(ep, 'ip_lib'): - manager.enable(callback) - self.assertFalse(callback.called) - - def test_disable_no_namespace(self): - with mock.patch.object(ep.ProcessManager, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=4) - with mock.patch.object(ep.ProcessManager, 'active') as active: - active.__get__ = mock.Mock(return_value=True) - - manager = ep.ProcessManager(self.conf, 'uuid') - manager.disable() - self.execute(['kill', '-9', 4], 'sudo') - - def test_disable_namespace(self): - with mock.patch.object(ep.ProcessManager, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=4) - with mock.patch.object(ep.ProcessManager, 'active') as active: - active.__get__ = mock.Mock(return_value=True) - - manager = ep.ProcessManager(self.conf, 'uuid', namespace='ns') - - with mock.patch.object(ep, 'utils') as utils: - manager.disable() - utils.assert_has_calls( - mock.call.execute(['kill', '-9', 4], 'sudo')) - - def test_disable_not_active(self): - with mock.patch.object(ep.ProcessManager, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=4) - with mock.patch.object(ep.ProcessManager, 'active') as active: - active.__get__ = mock.Mock(return_value=False) - with mock.patch.object(ep.LOG, 'debug') as debug: - manager = ep.ProcessManager(self.conf, 'uuid') - manager.disable() - debug.assert_called_once_with(mock.ANY, mock.ANY) - - def test_disable_no_pid(self): - with mock.patch.object(ep.ProcessManager, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=None) - with mock.patch.object(ep.ProcessManager, 'active') as active: - active.__get__ = mock.Mock(return_value=False) - with mock.patch.object(ep.LOG, 'debug') as debug: - manager = ep.ProcessManager(self.conf, 'uuid') - manager.disable() - debug.assert_called_once_with(mock.ANY, mock.ANY) - - def test_get_pid_file_name_existing(self): - with mock.patch.object(ep.os.path, 'isdir') as isdir: - isdir.return_value = True - manager = ep.ProcessManager(self.conf, 'uuid') - retval = manager.get_pid_file_name(ensure_pids_dir=True) - self.assertEqual(retval, '/var/path/uuid.pid') - - def test_get_pid_file_name_not_existing(self): - with mock.patch.object(ep.os.path, 'isdir') as isdir: - with mock.patch.object(ep.os, 'makedirs') as makedirs: - isdir.return_value = False - manager = ep.ProcessManager(self.conf, 'uuid') - retval = manager.get_pid_file_name(ensure_pids_dir=True) - self.assertEqual(retval, '/var/path/uuid.pid') - makedirs.assert_called_once_with('/var/path', 0o755) - - def test_get_pid_file_name_default(self): - with mock.patch.object(ep.os.path, 'isdir') as isdir: - isdir.return_value = True - manager = ep.ProcessManager(self.conf, 'uuid') - retval = manager.get_pid_file_name(ensure_pids_dir=False) - self.assertEqual(retval, '/var/path/uuid.pid') - self.assertFalse(isdir.called) - - def test_pid(self): - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.read.return_value = '5' - manager = ep.ProcessManager(self.conf, 'uuid') - self.assertEqual(manager.pid, 5) - - def test_pid_no_an_int(self): - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.read.return_value = 'foo' - manager = ep.ProcessManager(self.conf, 'uuid') - self.assertIsNone(manager.pid, 5) - - def test_pid_invalid_file(self): - with mock.patch.object(ep.ProcessManager, 'get_pid_file_name') as name: - name.return_value = '.doesnotexist/pid' - manager = ep.ProcessManager(self.conf, 'uuid') - self.assertIsNone(manager.pid) - - def test_active(self): - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.readline.return_value = \ - 'python foo --router_id=uuid' - with mock.patch.object(ep.ProcessManager, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=4) - manager = ep.ProcessManager(self.conf, 'uuid') - self.assertTrue(manager.active) - - mock_open.assert_called_once_with('/proc/4/cmdline', 'r') - - def test_active_none(self): - dummy_cmd_line = 'python foo --router_id=uuid' - self.execute.return_value = dummy_cmd_line - with mock.patch.object(ep.ProcessManager, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=None) - manager = ep.ProcessManager(self.conf, 'uuid') - self.assertFalse(manager.active) - - def test_active_cmd_mismatch(self): - with mock.patch('__builtin__.open') as mock_open: - mock_open.return_value.__enter__ = lambda s: s - mock_open.return_value.__exit__ = mock.Mock() - mock_open.return_value.readline.return_value = \ - 'python foo --router_id=anotherid' - with mock.patch.object(ep.ProcessManager, 'pid') as pid: - pid.__get__ = mock.Mock(return_value=4) - manager = ep.ProcessManager(self.conf, 'uuid') - self.assertFalse(manager.active) - - mock_open.assert_called_once_with('/proc/4/cmdline', 'r') diff --git a/neutron/tests/unit/test_linux_interface.py b/neutron/tests/unit/test_linux_interface.py deleted file mode 100644 index ffdec24bc..000000000 --- a/neutron/tests/unit/test_linux_interface.py +++ /dev/null @@ -1,620 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# 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 neutron.agent.common import config -from neutron.agent.linux import dhcp -from neutron.agent.linux import interface -from neutron.agent.linux import ip_lib -from neutron.agent.linux import utils -from neutron.extensions import flavor -from neutron.openstack.common import uuidutils -from neutron.tests import base - - -class BaseChild(interface.LinuxInterfaceDriver): - def plug(*args): - pass - - def unplug(*args): - pass - - -class FakeNetwork: - id = '12345678-1234-5678-90ab-ba0987654321' - - -class FakeSubnet: - cidr = '192.168.1.1/24' - - -class FakeAllocation: - subnet = FakeSubnet() - ip_address = '192.168.1.2' - ip_version = 4 - - -class FakePort: - id = 'abcdef01-1234-5678-90ab-ba0987654321' - fixed_ips = [FakeAllocation] - device_id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' - network = FakeNetwork() - network_id = network.id - - -class TestBase(base.BaseTestCase): - def setUp(self): - super(TestBase, self).setUp() - self.conf = config.setup_conf() - self.conf.register_opts(interface.OPTS) - config.register_root_helper(self.conf) - self.ip_dev_p = mock.patch.object(ip_lib, 'IPDevice') - self.ip_dev = self.ip_dev_p.start() - self.ip_p = mock.patch.object(ip_lib, 'IPWrapper') - self.ip = self.ip_p.start() - self.device_exists_p = mock.patch.object(ip_lib, 'device_exists') - self.device_exists = self.device_exists_p.start() - - -class TestABCDriver(TestBase): - def test_get_device_name(self): - bc = BaseChild(self.conf) - device_name = bc.get_device_name(FakePort()) - self.assertEqual('tapabcdef01-12', device_name) - - def test_l3_init(self): - addresses = [dict(ip_version=4, scope='global', - dynamic=False, cidr='172.16.77.240/24')] - self.ip_dev().addr.list = mock.Mock(return_value=addresses) - self.ip_dev().route.list_onlink_routes.return_value = [] - - bc = BaseChild(self.conf) - ns = '12345678-1234-5678-90ab-ba0987654321' - bc.init_l3('tap0', ['192.168.1.2/24'], namespace=ns, - extra_subnets=[{'cidr': '172.20.0.0/24'}]) - self.ip_dev.assert_has_calls( - [mock.call('tap0', 'sudo', namespace=ns), - mock.call().addr.list(scope='global', filters=['permanent']), - mock.call().addr.add(4, '192.168.1.2/24', '192.168.1.255'), - mock.call().addr.delete(4, '172.16.77.240/24'), - mock.call().route.list_onlink_routes(), - mock.call().route.add_onlink_route('172.20.0.0/24')]) - - def test_l3_init_delete_onlink_routes(self): - addresses = [dict(ip_version=4, scope='global', - dynamic=False, cidr='172.16.77.240/24')] - self.ip_dev().addr.list = mock.Mock(return_value=addresses) - self.ip_dev().route.list_onlink_routes.return_value = ['172.20.0.0/24'] - - bc = BaseChild(self.conf) - ns = '12345678-1234-5678-90ab-ba0987654321' - bc.init_l3('tap0', ['192.168.1.2/24'], namespace=ns) - self.ip_dev.assert_has_calls( - [mock.call().route.list_onlink_routes(), - mock.call().route.delete_onlink_route('172.20.0.0/24')]) - - def test_l3_init_with_preserve(self): - addresses = [dict(ip_version=4, scope='global', - dynamic=False, cidr='192.168.1.3/32')] - self.ip_dev().addr.list = mock.Mock(return_value=addresses) - - bc = BaseChild(self.conf) - ns = '12345678-1234-5678-90ab-ba0987654321' - bc.init_l3('tap0', ['192.168.1.2/24'], namespace=ns, - preserve_ips=['192.168.1.3/32']) - self.ip_dev.assert_has_calls( - [mock.call('tap0', 'sudo', namespace=ns), - mock.call().addr.list(scope='global', filters=['permanent']), - mock.call().addr.add(4, '192.168.1.2/24', '192.168.1.255')]) - self.assertFalse(self.ip_dev().addr.delete.called) - - def test_l3_init_with_ipv6(self): - addresses = [dict(ip_version=6, - scope='global', - dynamic=False, - cidr='2001:db8:a::123/64')] - self.ip_dev().addr.list = mock.Mock(return_value=addresses) - bc = BaseChild(self.conf) - ns = '12345678-1234-5678-90ab-ba0987654321' - bc.init_l3('tap0', ['2001:db8:a::124/64'], namespace=ns) - self.ip_dev.assert_has_calls( - [mock.call('tap0', 'sudo', namespace=ns), - mock.call().addr.list(scope='global', filters=['permanent']), - mock.call().addr.add(6, '2001:db8:a::124/64', - '2001:db8:a:0:ffff:ffff:ffff:ffff'), - mock.call().addr.delete(6, '2001:db8:a::123/64')]) - - def test_l3_init_with_duplicated_ipv6(self): - addresses = [dict(ip_version=6, - scope='global', - dynamic=False, - cidr='2001:db8:a::123/64')] - self.ip_dev().addr.list = mock.Mock(return_value=addresses) - bc = BaseChild(self.conf) - ns = '12345678-1234-5678-90ab-ba0987654321' - bc.init_l3('tap0', ['2001:db8:a::123/64'], namespace=ns) - self.assertFalse(self.ip_dev().addr.add.called) - - def test_l3_init_with_duplicated_ipv6_uncompact(self): - addresses = [dict(ip_version=6, - scope='global', - dynamic=False, - cidr='2001:db8:a::123/64')] - self.ip_dev().addr.list = mock.Mock(return_value=addresses) - bc = BaseChild(self.conf) - ns = '12345678-1234-5678-90ab-ba0987654321' - bc.init_l3('tap0', - ['2001:db8:a:0000:0000:0000:0000:0123/64'], - namespace=ns) - self.assertFalse(self.ip_dev().addr.add.called) - - -class TestOVSInterfaceDriver(TestBase): - - def test_get_device_name(self): - br = interface.OVSInterfaceDriver(self.conf) - device_name = br.get_device_name(FakePort()) - self.assertEqual('tapabcdef01-12', device_name) - - def test_plug_no_ns(self): - self._test_plug() - - def test_plug_with_ns(self): - self._test_plug(namespace='01234567-1234-1234-99') - - def test_plug_alt_bridge(self): - self._test_plug(bridge='br-foo') - - def test_plug_configured_bridge(self): - br = 'br-v' - self.conf.set_override('ovs_use_veth', False) - self.conf.set_override('ovs_integration_bridge', br) - self.assertEqual(self.conf.ovs_integration_bridge, br) - - def device_exists(dev, root_helper=None, namespace=None): - return dev == br - - ovs = interface.OVSInterfaceDriver(self.conf) - with mock.patch.object(ovs, '_ovs_add_port') as add_port: - self.device_exists.side_effect = device_exists - ovs.plug('01234567-1234-1234-99', - 'port-1234', - 'tap0', - 'aa:bb:cc:dd:ee:ff', - bridge=None, - namespace=None) - - add_port.assert_called_once_with('br-v', - 'tap0', - 'port-1234', - 'aa:bb:cc:dd:ee:ff', - internal=True) - - def _test_plug(self, additional_expectation=[], bridge=None, - namespace=None): - - if not bridge: - bridge = 'br-int' - - def device_exists(dev, root_helper=None, namespace=None): - return dev == bridge - - vsctl_cmd = ['ovs-vsctl', '--', '--if-exists', 'del-port', - 'tap0', '--', 'add-port', - bridge, 'tap0', '--', 'set', 'Interface', 'tap0', - 'type=internal', '--', 'set', 'Interface', 'tap0', - 'external-ids:iface-id=port-1234', '--', 'set', - 'Interface', 'tap0', - 'external-ids:iface-status=active', '--', 'set', - 'Interface', 'tap0', - 'external-ids:attached-mac=aa:bb:cc:dd:ee:ff'] - - with mock.patch.object(utils, 'execute') as execute: - ovs = interface.OVSInterfaceDriver(self.conf) - self.device_exists.side_effect = device_exists - ovs.plug('01234567-1234-1234-99', - 'port-1234', - 'tap0', - 'aa:bb:cc:dd:ee:ff', - bridge=bridge, - namespace=namespace) - execute.assert_called_once_with(vsctl_cmd, 'sudo') - - expected = [mock.call('sudo'), - mock.call().device('tap0'), - mock.call().device().link.set_address('aa:bb:cc:dd:ee:ff')] - expected.extend(additional_expectation) - if namespace: - expected.extend( - [mock.call().ensure_namespace(namespace), - mock.call().ensure_namespace().add_device_to_namespace( - mock.ANY)]) - expected.extend([mock.call().device().link.set_up()]) - - self.ip.assert_has_calls(expected) - - def test_mtu_int(self): - self.assertIsNone(self.conf.network_device_mtu) - self.conf.set_override('network_device_mtu', 9000) - self.assertEqual(self.conf.network_device_mtu, 9000) - - def test_plug_mtu(self): - self.conf.set_override('network_device_mtu', 9000) - self._test_plug([mock.call().device().link.set_mtu(9000)]) - - def test_unplug(self, bridge=None): - if not bridge: - bridge = 'br-int' - with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge') as ovs_br: - ovs = interface.OVSInterfaceDriver(self.conf) - ovs.unplug('tap0') - ovs_br.assert_has_calls([mock.call(bridge, 'sudo'), - mock.call().delete_port('tap0')]) - - -class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver): - - def setUp(self): - super(TestOVSInterfaceDriverWithVeth, self).setUp() - self.conf.set_override('ovs_use_veth', True) - - def test_get_device_name(self): - br = interface.OVSInterfaceDriver(self.conf) - device_name = br.get_device_name(FakePort()) - self.assertEqual('ns-abcdef01-12', device_name) - - def test_plug_with_prefix(self): - self._test_plug(devname='qr-0', prefix='qr-') - - def _test_plug(self, devname=None, bridge=None, namespace=None, - prefix=None, mtu=None): - - if not devname: - devname = 'ns-0' - if not bridge: - bridge = 'br-int' - - def device_exists(dev, root_helper=None, namespace=None): - return dev == bridge - - ovs = interface.OVSInterfaceDriver(self.conf) - self.device_exists.side_effect = device_exists - - root_dev = mock.Mock() - ns_dev = mock.Mock() - self.ip().add_veth = mock.Mock(return_value=(root_dev, ns_dev)) - expected = [mock.call('sudo'), - mock.call().add_veth('tap0', devname, - namespace2=namespace)] - - vsctl_cmd = ['ovs-vsctl', '--', '--if-exists', 'del-port', - 'tap0', '--', 'add-port', - bridge, 'tap0', '--', 'set', 'Interface', 'tap0', - 'external-ids:iface-id=port-1234', '--', 'set', - 'Interface', 'tap0', - 'external-ids:iface-status=active', '--', 'set', - 'Interface', 'tap0', - 'external-ids:attached-mac=aa:bb:cc:dd:ee:ff'] - with mock.patch.object(utils, 'execute') as execute: - ovs.plug('01234567-1234-1234-99', - 'port-1234', - devname, - 'aa:bb:cc:dd:ee:ff', - bridge=bridge, - namespace=namespace, - prefix=prefix) - execute.assert_called_once_with(vsctl_cmd, 'sudo') - - ns_dev.assert_has_calls( - [mock.call.link.set_address('aa:bb:cc:dd:ee:ff')]) - if mtu: - ns_dev.assert_has_calls([mock.call.link.set_mtu(mtu)]) - root_dev.assert_has_calls([mock.call.link.set_mtu(mtu)]) - - self.ip.assert_has_calls(expected) - root_dev.assert_has_calls([mock.call.link.set_up()]) - ns_dev.assert_has_calls([mock.call.link.set_up()]) - - def test_plug_mtu(self): - self.conf.set_override('network_device_mtu', 9000) - self._test_plug(mtu=9000) - - def test_unplug(self, bridge=None): - if not bridge: - bridge = 'br-int' - with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge') as ovs_br: - ovs = interface.OVSInterfaceDriver(self.conf) - ovs.unplug('ns-0', bridge=bridge) - ovs_br.assert_has_calls([mock.call(bridge, 'sudo'), - mock.call().delete_port('tap0')]) - self.ip_dev.assert_has_calls([mock.call('ns-0', 'sudo', None), - mock.call().link.delete()]) - - -class TestBridgeInterfaceDriver(TestBase): - def test_get_device_name(self): - br = interface.BridgeInterfaceDriver(self.conf) - device_name = br.get_device_name(FakePort()) - self.assertEqual('ns-abcdef01-12', device_name) - - def test_plug_no_ns(self): - self._test_plug() - - def test_plug_with_ns(self): - self._test_plug(namespace='01234567-1234-1234-99') - - def _test_plug(self, namespace=None, mtu=None): - def device_exists(device, root_helper=None, namespace=None): - return device.startswith('brq') - - root_veth = mock.Mock() - ns_veth = mock.Mock() - - self.ip().add_veth = mock.Mock(return_value=(root_veth, ns_veth)) - - self.device_exists.side_effect = device_exists - br = interface.BridgeInterfaceDriver(self.conf) - mac_address = 'aa:bb:cc:dd:ee:ff' - br.plug('01234567-1234-1234-99', - 'port-1234', - 'ns-0', - mac_address, - namespace=namespace) - - ip_calls = [mock.call('sudo'), - mock.call().add_veth('tap0', 'ns-0', namespace2=namespace)] - ns_veth.assert_has_calls([mock.call.link.set_address(mac_address)]) - if mtu: - ns_veth.assert_has_calls([mock.call.link.set_mtu(mtu)]) - root_veth.assert_has_calls([mock.call.link.set_mtu(mtu)]) - - self.ip.assert_has_calls(ip_calls) - - root_veth.assert_has_calls([mock.call.link.set_up()]) - ns_veth.assert_has_calls([mock.call.link.set_up()]) - - def test_plug_dev_exists(self): - self.device_exists.return_value = True - with mock.patch('neutron.agent.linux.interface.LOG.info') as log: - br = interface.BridgeInterfaceDriver(self.conf) - br.plug('01234567-1234-1234-99', - 'port-1234', - 'tap0', - 'aa:bb:cc:dd:ee:ff') - self.ip_dev.assert_has_calls([]) - self.assertEqual(log.call_count, 1) - - def test_plug_mtu(self): - self.device_exists.return_value = False - self.conf.set_override('network_device_mtu', 9000) - self._test_plug(mtu=9000) - - def test_unplug_no_device(self): - self.device_exists.return_value = False - self.ip_dev().link.delete.side_effect = RuntimeError - with mock.patch('neutron.agent.linux.interface.LOG') as log: - br = interface.BridgeInterfaceDriver(self.conf) - br.unplug('tap0') - [mock.call(), mock.call('tap0', 'sudo'), mock.call().link.delete()] - self.assertEqual(log.error.call_count, 1) - - def test_unplug(self): - self.device_exists.return_value = True - with mock.patch('neutron.agent.linux.interface.LOG.debug') as log: - br = interface.BridgeInterfaceDriver(self.conf) - br.unplug('tap0') - self.assertEqual(log.call_count, 1) - - self.ip_dev.assert_has_calls([mock.call('tap0', 'sudo', None), - mock.call().link.delete()]) - - -class TestMetaInterfaceDriver(TestBase): - def setUp(self): - super(TestMetaInterfaceDriver, self).setUp() - config.register_interface_driver_opts_helper(self.conf) - self.conf.register_opts(dhcp.OPTS) - self.client_cls_p = mock.patch('neutronclient.v2_0.client.Client') - client_cls = self.client_cls_p.start() - self.client_inst = mock.Mock() - client_cls.return_value = self.client_inst - - fake_network = {'network': {flavor.FLAVOR_NETWORK: 'fake1'}} - fake_port = {'ports': - [{'mac_address': - 'aa:bb:cc:dd:ee:ffa', 'network_id': 'test'}]} - - self.client_inst.list_ports.return_value = fake_port - self.client_inst.show_network.return_value = fake_network - - self.conf.set_override('auth_url', 'http://localhost:35357/v2.0') - self.conf.set_override('auth_region', 'RegionOne') - self.conf.set_override('admin_user', 'neutron') - self.conf.set_override('admin_password', 'password') - self.conf.set_override('admin_tenant_name', 'service') - self.conf.set_override( - 'meta_flavor_driver_mappings', - 'fake1:neutron.agent.linux.interface.OVSInterfaceDriver,' - 'fake2:neutron.agent.linux.interface.BridgeInterfaceDriver') - - def test_get_driver_by_network_id(self): - meta_interface = interface.MetaInterfaceDriver(self.conf) - driver = meta_interface._get_driver_by_network_id('test') - self.assertIsInstance(driver, interface.OVSInterfaceDriver) - - def test_set_device_plugin_tag(self): - meta_interface = interface.MetaInterfaceDriver(self.conf) - driver = meta_interface._get_driver_by_network_id('test') - meta_interface._set_device_plugin_tag(driver, - 'tap0', - namespace=None) - expected = [mock.call('tap0', 'sudo', None), - mock.call().link.set_alias('fake1')] - self.ip_dev.assert_has_calls(expected) - namespace = '01234567-1234-1234-99' - meta_interface._set_device_plugin_tag(driver, - 'tap1', - namespace=namespace) - expected = [mock.call('tap1', 'sudo', '01234567-1234-1234-99'), - mock.call().link.set_alias('fake1')] - self.ip_dev.assert_has_calls(expected) - - def test_get_device_plugin_tag(self): - meta_interface = interface.MetaInterfaceDriver(self.conf) - self.ip_dev().link.alias = 'fake1' - plugin_tag0 = meta_interface._get_device_plugin_tag('tap0', - namespace=None) - expected = [mock.call('tap0', 'sudo', None)] - self.ip_dev.assert_has_calls(expected) - self.assertEqual('fake1', plugin_tag0) - namespace = '01234567-1234-1234-99' - expected = [mock.call('tap1', 'sudo', '01234567-1234-1234-99')] - plugin_tag1 = meta_interface._get_device_plugin_tag( - 'tap1', - namespace=namespace) - self.ip_dev.assert_has_calls(expected) - self.assertEqual('fake1', plugin_tag1) - - -class TestIVSInterfaceDriver(TestBase): - - def setUp(self): - super(TestIVSInterfaceDriver, self).setUp() - - def test_get_device_name(self): - br = interface.IVSInterfaceDriver(self.conf) - device_name = br.get_device_name(FakePort()) - self.assertEqual('ns-abcdef01-12', device_name) - - def test_plug_with_prefix(self): - self._test_plug(devname='qr-0', prefix='qr-') - - def _test_plug(self, devname=None, namespace=None, - prefix=None, mtu=None): - - if not devname: - devname = 'ns-0' - - def device_exists(dev, root_helper=None, namespace=None): - return dev == 'indigo' - - ivs = interface.IVSInterfaceDriver(self.conf) - self.device_exists.side_effect = device_exists - - root_dev = mock.Mock() - _ns_dev = mock.Mock() - ns_dev = mock.Mock() - self.ip().add_veth = mock.Mock(return_value=(root_dev, _ns_dev)) - self.ip().device = mock.Mock(return_value=(ns_dev)) - expected = [mock.call('sudo'), mock.call().add_veth('tap0', devname), - mock.call().device(devname)] - - ivsctl_cmd = ['ivs-ctl', 'add-port', 'tap0'] - - with mock.patch.object(utils, 'execute') as execute: - ivs.plug('01234567-1234-1234-99', - 'port-1234', - devname, - 'aa:bb:cc:dd:ee:ff', - namespace=namespace, - prefix=prefix) - execute.assert_called_once_with(ivsctl_cmd, 'sudo') - - ns_dev.assert_has_calls( - [mock.call.link.set_address('aa:bb:cc:dd:ee:ff')]) - if mtu: - ns_dev.assert_has_calls([mock.call.link.set_mtu(mtu)]) - root_dev.assert_has_calls([mock.call.link.set_mtu(mtu)]) - if namespace: - expected.extend( - [mock.call().ensure_namespace(namespace), - mock.call().ensure_namespace().add_device_to_namespace( - mock.ANY)]) - - self.ip.assert_has_calls(expected) - root_dev.assert_has_calls([mock.call.link.set_up()]) - ns_dev.assert_has_calls([mock.call.link.set_up()]) - - def test_plug_mtu(self): - self.conf.set_override('network_device_mtu', 9000) - self._test_plug(mtu=9000) - - def test_plug_namespace(self): - self._test_plug(namespace='mynamespace') - - def test_unplug(self): - ivs = interface.IVSInterfaceDriver(self.conf) - ivsctl_cmd = ['ivs-ctl', 'del-port', 'tap0'] - with mock.patch.object(utils, 'execute') as execute: - ivs.unplug('ns-0') - execute.assert_called_once_with(ivsctl_cmd, 'sudo') - self.ip_dev.assert_has_calls([mock.call('ns-0', 'sudo', None), - mock.call().link.delete()]) - - -class TestMidonetInterfaceDriver(TestBase): - def setUp(self): - self.conf = config.setup_conf() - self.conf.register_opts(interface.OPTS) - config.register_root_helper(self.conf) - self.driver = interface.MidonetInterfaceDriver(self.conf) - self.network_id = uuidutils.generate_uuid() - self.port_id = uuidutils.generate_uuid() - self.device_name = "tap0" - self.mac_address = "aa:bb:cc:dd:ee:ff" - self.bridge = "br-test" - self.namespace = "ns-test" - super(TestMidonetInterfaceDriver, self).setUp() - - def test_plug(self): - cmd = ['mm-ctl', '--bind-port', self.port_id, 'tap0'] - self.device_exists.return_value = False - - root_dev = mock.Mock() - ns_dev = mock.Mock() - self.ip().add_veth = mock.Mock(return_value=(root_dev, ns_dev)) - with mock.patch.object(utils, 'execute') as execute: - self.driver.plug( - self.network_id, self.port_id, - self.device_name, self.mac_address, - self.bridge, self.namespace) - execute.assert_called_once_with(cmd, 'sudo') - - expected = [mock.call(), mock.call('sudo'), - mock.call().add_veth(self.device_name, - self.device_name, - namespace2=self.namespace), - mock.call().ensure_namespace(self.namespace), - mock.call().ensure_namespace().add_device_to_namespace( - mock.ANY)] - - ns_dev.assert_has_calls( - [mock.call.link.set_address(self.mac_address)]) - - root_dev.assert_has_calls([mock.call.link.set_up()]) - ns_dev.assert_has_calls([mock.call.link.set_up()]) - self.ip.assert_has_calls(expected, True) - - def test_unplug(self): - self.driver.unplug(self.device_name, self.bridge, self.namespace) - - self.ip_dev.assert_has_calls([ - mock.call(self.device_name, self.driver.root_helper, - self.namespace), - mock.call().link.delete()]) - self.ip.assert_has_calls(mock.call().garbage_collect_namespace()) diff --git a/neutron/tests/unit/test_linux_ip_lib.py b/neutron/tests/unit/test_linux_ip_lib.py deleted file mode 100644 index a002c1d29..000000000 --- a/neutron/tests/unit/test_linux_ip_lib.py +++ /dev/null @@ -1,860 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# 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 neutron.agent.linux import ip_lib -from neutron.common import exceptions -from neutron.tests import base - -NETNS_SAMPLE = [ - '12345678-1234-5678-abcd-1234567890ab', - 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', - 'cccccccc-cccc-cccc-cccc-cccccccccccc'] - -LINK_SAMPLE = [ - '1: lo: mtu 16436 qdisc noqueue state UNKNOWN \\' - 'link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0', - '2: eth0: mtu 1500 qdisc mq state UP ' - 'qlen 1000\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff' - '\ alias openvswitch', - '3: br-int: mtu 1500 qdisc noop state DOWN ' - '\ link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff promiscuity 0', - '4: gw-ddc717df-49: mtu 1500 qdisc noop ' - 'state DOWN \ link/ether fe:dc:ba:fe:dc:ba brd ff:ff:ff:ff:ff:ff ' - 'promiscuity 0', - '5: foo:foo: mtu 1500 qdisc mq state ' - 'UP qlen 1000\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff ' - 'promiscuity 0', - '6: foo@foo: mtu 1500 qdisc mq state ' - 'UP qlen 1000\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff ' - 'promiscuity 0', - '7: foo:foo@foo: mtu 1500 qdisc mq ' - 'state UP qlen 1000' - '\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff promiscuity 0', - '8: foo@foo:foo: mtu 1500 qdisc mq ' - 'state UP qlen 1000' - '\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff promiscuity 0', - '9: bar.9@eth0: mtu 1500 qdisc ' - ' noqueue master brq0b24798c-07 state UP mode DEFAULT' - '\ link/ether ab:04:49:b6:ab:a0 brd ff:ff:ff:ff:ff:ff promiscuity 0' - '\ vlan protocol 802.1q id 9 ', - '10: bar@eth0: mtu 1500 qdisc ' - ' noqueue master brq0b24798c-07 state UP mode DEFAULT' - '\ link/ether ab:04:49:b6:ab:a0 brd ff:ff:ff:ff:ff:ff promiscuity 0' - '\ vlan protocol 802.1Q id 10 ', - '11: bar:bar@eth0: mtu 1500 qdisc mq ' - 'state UP qlen 1000' - '\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff promiscuity 0' - '\ vlan id 11 ', - '12: bar@bar@eth0: mtu 1500 qdisc mq ' - 'state UP qlen 1000' - '\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff promiscuity 0' - '\ vlan id 12 ', - '13: bar:bar@bar@eth0: mtu 1500 ' - 'qdisc mq state UP qlen 1000' - '\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff promiscuity 0' - '\ vlan protocol 802.1q id 13 ', - '14: bar@bar:bar@eth0: mtu 1500 ' - 'qdisc mq state UP qlen 1000' - '\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff promiscuity 0' - '\ vlan protocol 802.1Q id 14 '] - -ADDR_SAMPLE = (""" -2: eth0: mtu 1500 qdisc mq state UP qlen 1000 - link/ether dd:cc:aa:b9:76:ce brd ff:ff:ff:ff:ff:ff - inet 172.16.77.240/24 brd 172.16.77.255 scope global eth0 - inet6 2001:470:9:1224:5595:dd51:6ba2:e788/64 scope global temporary dynamic - valid_lft 14187sec preferred_lft 3387sec - inet6 2001:470:9:1224:fd91:272:581e:3a32/64 scope global temporary """ - """deprecated dynamic - valid_lft 14187sec preferred_lft 0sec - inet6 2001:470:9:1224:4508:b885:5fb:740b/64 scope global temporary """ - """deprecated dynamic - valid_lft 14187sec preferred_lft 0sec - inet6 2001:470:9:1224:dfcc:aaff:feb9:76ce/64 scope global dynamic - valid_lft 14187sec preferred_lft 3387sec - inet6 fe80::dfcc:aaff:feb9:76ce/64 scope link - valid_lft forever preferred_lft forever -""") - -ADDR_SAMPLE2 = (""" -2: eth0: mtu 1500 qdisc mq state UP qlen 1000 - link/ether dd:cc:aa:b9:76:ce brd ff:ff:ff:ff:ff:ff - inet 172.16.77.240/24 scope global eth0 - inet6 2001:470:9:1224:5595:dd51:6ba2:e788/64 scope global temporary dynamic - valid_lft 14187sec preferred_lft 3387sec - inet6 2001:470:9:1224:fd91:272:581e:3a32/64 scope global temporary """ - """deprecated dynamic - valid_lft 14187sec preferred_lft 0sec - inet6 2001:470:9:1224:4508:b885:5fb:740b/64 scope global temporary """ - """deprecated dynamic - valid_lft 14187sec preferred_lft 0sec - inet6 2001:470:9:1224:dfcc:aaff:feb9:76ce/64 scope global dynamic - valid_lft 14187sec preferred_lft 3387sec - inet6 fe80::dfcc:aaff:feb9:76ce/64 scope link - valid_lft forever preferred_lft forever -""") - -GATEWAY_SAMPLE1 = (""" -default via 10.35.19.254 metric 100 -10.35.16.0/22 proto kernel scope link src 10.35.17.97 -""") - -GATEWAY_SAMPLE2 = (""" -default via 10.35.19.254 metric 100 -""") - -GATEWAY_SAMPLE3 = (""" -10.35.16.0/22 proto kernel scope link src 10.35.17.97 -""") - -GATEWAY_SAMPLE4 = (""" -default via 10.35.19.254 -""") - -GATEWAY_SAMPLE5 = (""" -default via 192.168.99.1 proto static -""") - -GATEWAY_SAMPLE6 = (""" -default via 192.168.99.1 proto static metric 100 -""") - -DEVICE_ROUTE_SAMPLE = ("10.0.0.0/24 scope link src 10.0.0.2") - -SUBNET_SAMPLE1 = ("10.0.0.0/24 dev qr-23380d11-d2 scope link src 10.0.0.1\n" - "10.0.0.0/24 dev tap1d7888a7-10 scope link src 10.0.0.2") -SUBNET_SAMPLE2 = ("10.0.0.0/24 dev tap1d7888a7-10 scope link src 10.0.0.2\n" - "10.0.0.0/24 dev qr-23380d11-d2 scope link src 10.0.0.1") - - -class TestSubProcessBase(base.BaseTestCase): - def setUp(self): - super(TestSubProcessBase, self).setUp() - self.execute_p = mock.patch('neutron.agent.linux.utils.execute') - self.execute = self.execute_p.start() - - def test_execute_wrapper(self): - ip_lib.SubProcessBase._execute('o', 'link', ('list',), 'sudo') - - self.execute.assert_called_once_with(['ip', '-o', 'link', 'list'], - root_helper='sudo') - - def test_execute_wrapper_int_options(self): - ip_lib.SubProcessBase._execute([4], 'link', ('list',)) - - self.execute.assert_called_once_with(['ip', '-4', 'link', 'list'], - root_helper=None) - - def test_execute_wrapper_no_options(self): - ip_lib.SubProcessBase._execute([], 'link', ('list',)) - - self.execute.assert_called_once_with(['ip', 'link', 'list'], - root_helper=None) - - def test_run_no_namespace(self): - base = ip_lib.SubProcessBase('sudo') - base._run([], 'link', ('list',)) - self.execute.assert_called_once_with(['ip', 'link', 'list'], - root_helper=None) - - def test_run_namespace(self): - base = ip_lib.SubProcessBase('sudo', 'ns') - base._run([], 'link', ('list',)) - self.execute.assert_called_once_with(['ip', 'netns', 'exec', 'ns', - 'ip', 'link', 'list'], - root_helper='sudo') - - def test_as_root_namespace(self): - base = ip_lib.SubProcessBase('sudo', 'ns') - base._as_root([], 'link', ('list',)) - self.execute.assert_called_once_with(['ip', 'netns', 'exec', 'ns', - 'ip', 'link', 'list'], - root_helper='sudo') - - def test_as_root_no_root_helper(self): - base = ip_lib.SubProcessBase() - self.assertRaises(exceptions.SudoRequired, - base._as_root, - [], 'link', ('list',)) - - -class TestIpWrapper(base.BaseTestCase): - def setUp(self): - super(TestIpWrapper, self).setUp() - self.execute_p = mock.patch.object(ip_lib.IPWrapper, '_execute') - self.execute = self.execute_p.start() - - def test_get_devices(self): - self.execute.return_value = '\n'.join(LINK_SAMPLE) - retval = ip_lib.IPWrapper('sudo').get_devices() - self.assertEqual(retval, - [ip_lib.IPDevice('lo'), - ip_lib.IPDevice('eth0'), - ip_lib.IPDevice('br-int'), - ip_lib.IPDevice('gw-ddc717df-49'), - ip_lib.IPDevice('foo:foo'), - ip_lib.IPDevice('foo@foo'), - ip_lib.IPDevice('foo:foo@foo'), - ip_lib.IPDevice('foo@foo:foo'), - ip_lib.IPDevice('bar.9'), - ip_lib.IPDevice('bar'), - ip_lib.IPDevice('bar:bar'), - ip_lib.IPDevice('bar@bar'), - ip_lib.IPDevice('bar:bar@bar'), - ip_lib.IPDevice('bar@bar:bar')]) - - self.execute.assert_called_once_with(['o', 'd'], 'link', ('list',), - 'sudo', None) - - def test_get_devices_malformed_line(self): - self.execute.return_value = '\n'.join(LINK_SAMPLE + ['gibberish']) - retval = ip_lib.IPWrapper('sudo').get_devices() - self.assertEqual(retval, - [ip_lib.IPDevice('lo'), - ip_lib.IPDevice('eth0'), - ip_lib.IPDevice('br-int'), - ip_lib.IPDevice('gw-ddc717df-49'), - ip_lib.IPDevice('foo:foo'), - ip_lib.IPDevice('foo@foo'), - ip_lib.IPDevice('foo:foo@foo'), - ip_lib.IPDevice('foo@foo:foo'), - ip_lib.IPDevice('bar.9'), - ip_lib.IPDevice('bar'), - ip_lib.IPDevice('bar:bar'), - ip_lib.IPDevice('bar@bar'), - ip_lib.IPDevice('bar:bar@bar'), - ip_lib.IPDevice('bar@bar:bar')]) - - self.execute.assert_called_once_with(['o', 'd'], 'link', ('list',), - 'sudo', None) - - def test_get_namespaces(self): - self.execute.return_value = '\n'.join(NETNS_SAMPLE) - retval = ip_lib.IPWrapper.get_namespaces('sudo') - self.assertEqual(retval, - ['12345678-1234-5678-abcd-1234567890ab', - 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', - 'cccccccc-cccc-cccc-cccc-cccccccccccc']) - - self.execute.assert_called_once_with('', 'netns', ('list',), - root_helper='sudo') - - def test_add_tuntap(self): - ip_lib.IPWrapper('sudo').add_tuntap('tap0') - self.execute.assert_called_once_with('', 'tuntap', - ('add', 'tap0', 'mode', 'tap'), - 'sudo', None) - - def test_add_veth(self): - ip_lib.IPWrapper('sudo').add_veth('tap0', 'tap1') - self.execute.assert_called_once_with('', 'link', - ('add', 'tap0', 'type', 'veth', - 'peer', 'name', 'tap1'), - 'sudo', None) - - def test_add_veth_with_namespaces(self): - ns2 = 'ns2' - with mock.patch.object(ip_lib.IPWrapper, 'ensure_namespace') as en: - ip_lib.IPWrapper('sudo').add_veth('tap0', 'tap1', namespace2=ns2) - en.assert_has_calls([mock.call(ns2)]) - self.execute.assert_called_once_with('', 'link', - ('add', 'tap0', 'type', 'veth', - 'peer', 'name', 'tap1', - 'netns', ns2), - 'sudo', None) - - def test_get_device(self): - dev = ip_lib.IPWrapper('sudo', 'ns').device('eth0') - self.assertEqual(dev.root_helper, 'sudo') - self.assertEqual(dev.namespace, 'ns') - self.assertEqual(dev.name, 'eth0') - - def test_ensure_namespace(self): - with mock.patch.object(ip_lib, 'IPDevice') as ip_dev: - ip = ip_lib.IPWrapper('sudo') - with mock.patch.object(ip.netns, 'exists') as ns_exists: - ns_exists.return_value = False - ip.ensure_namespace('ns') - self.execute.assert_has_calls( - [mock.call([], 'netns', ('add', 'ns'), 'sudo', None)]) - ip_dev.assert_has_calls([mock.call('lo', 'sudo', 'ns'), - mock.call().link.set_up()]) - - def test_ensure_namespace_existing(self): - with mock.patch.object(ip_lib, 'IpNetnsCommand') as ip_ns_cmd: - ip_ns_cmd.exists.return_value = True - ns = ip_lib.IPWrapper('sudo').ensure_namespace('ns') - self.assertFalse(self.execute.called) - self.assertEqual(ns.namespace, 'ns') - - def test_namespace_is_empty_no_devices(self): - ip = ip_lib.IPWrapper('sudo', 'ns') - with mock.patch.object(ip, 'get_devices') as get_devices: - get_devices.return_value = [] - - self.assertTrue(ip.namespace_is_empty()) - get_devices.assert_called_once_with(exclude_loopback=True) - - def test_namespace_is_empty(self): - ip = ip_lib.IPWrapper('sudo', 'ns') - with mock.patch.object(ip, 'get_devices') as get_devices: - get_devices.return_value = [mock.Mock()] - - self.assertFalse(ip.namespace_is_empty()) - get_devices.assert_called_once_with(exclude_loopback=True) - - def test_garbage_collect_namespace_does_not_exist(self): - with mock.patch.object(ip_lib, 'IpNetnsCommand') as ip_ns_cmd_cls: - ip_ns_cmd_cls.return_value.exists.return_value = False - ip = ip_lib.IPWrapper('sudo', 'ns') - with mock.patch.object(ip, 'namespace_is_empty') as mock_is_empty: - - self.assertFalse(ip.garbage_collect_namespace()) - ip_ns_cmd_cls.assert_has_calls([mock.call().exists('ns')]) - self.assertNotIn(mock.call().delete('ns'), - ip_ns_cmd_cls.return_value.mock_calls) - self.assertEqual(mock_is_empty.mock_calls, []) - - def test_garbage_collect_namespace_existing_empty_ns(self): - with mock.patch.object(ip_lib, 'IpNetnsCommand') as ip_ns_cmd_cls: - ip_ns_cmd_cls.return_value.exists.return_value = True - - ip = ip_lib.IPWrapper('sudo', 'ns') - - with mock.patch.object(ip, 'namespace_is_empty') as mock_is_empty: - mock_is_empty.return_value = True - self.assertTrue(ip.garbage_collect_namespace()) - - mock_is_empty.assert_called_once_with() - expected = [mock.call().exists('ns'), - mock.call().delete('ns')] - ip_ns_cmd_cls.assert_has_calls(expected) - - def test_garbage_collect_namespace_existing_not_empty(self): - lo_device = mock.Mock() - lo_device.name = 'lo' - tap_device = mock.Mock() - tap_device.name = 'tap1' - - with mock.patch.object(ip_lib, 'IpNetnsCommand') as ip_ns_cmd_cls: - ip_ns_cmd_cls.return_value.exists.return_value = True - - ip = ip_lib.IPWrapper('sudo', 'ns') - - with mock.patch.object(ip, 'namespace_is_empty') as mock_is_empty: - mock_is_empty.return_value = False - - self.assertFalse(ip.garbage_collect_namespace()) - - mock_is_empty.assert_called_once_with() - expected = [mock.call(ip), - mock.call().exists('ns')] - self.assertEqual(ip_ns_cmd_cls.mock_calls, expected) - self.assertNotIn(mock.call().delete('ns'), - ip_ns_cmd_cls.mock_calls) - - def test_add_vxlan_valid_port_length(self): - retval = ip_lib.IPWrapper('sudo').add_vxlan('vxlan0', 'vni0', - group='group0', - dev='dev0', ttl='ttl0', - tos='tos0', - local='local0', proxy=True, - port=('1', '2')) - self.assertIsInstance(retval, ip_lib.IPDevice) - self.assertEqual(retval.name, 'vxlan0') - self.execute.assert_called_once_with('', 'link', - ['add', 'vxlan0', 'type', - 'vxlan', 'id', 'vni0', 'group', - 'group0', 'dev', 'dev0', - 'ttl', 'ttl0', 'tos', 'tos0', - 'local', 'local0', 'proxy', - 'port', '1', '2'], - 'sudo', None) - - def test_add_vxlan_invalid_port_length(self): - wrapper = ip_lib.IPWrapper('sudo') - self.assertRaises(exceptions.NetworkVxlanPortRangeError, - wrapper.add_vxlan, 'vxlan0', 'vni0', group='group0', - dev='dev0', ttl='ttl0', tos='tos0', - local='local0', proxy=True, - port=('1', '2', '3')) - - def test_add_device_to_namespace(self): - dev = mock.Mock() - ip_lib.IPWrapper('sudo', 'ns').add_device_to_namespace(dev) - dev.assert_has_calls([mock.call.link.set_netns('ns')]) - - def test_add_device_to_namespace_is_none(self): - dev = mock.Mock() - ip_lib.IPWrapper('sudo').add_device_to_namespace(dev) - self.assertEqual(dev.mock_calls, []) - - -class TestIpRule(base.BaseTestCase): - def setUp(self): - super(TestIpRule, self).setUp() - self.execute_p = mock.patch.object(ip_lib.IpRule, '_execute') - self.execute = self.execute_p.start() - - def test_add_rule_from(self): - ip_lib.IpRule('sudo').add_rule_from('192.168.45.100', 2, 100) - self.execute.assert_called_once_with('', 'rule', - ('add', 'from', '192.168.45.100', - 'lookup', 2, 'priority', 100), - 'sudo', None) - - def test_delete_rule_priority(self): - ip_lib.IpRule('sudo').delete_rule_priority(100) - self.execute.assert_called_once_with('', 'rule', - ('del', 'priority', 100), - 'sudo', None) - - -class TestIPDevice(base.BaseTestCase): - def test_eq_same_name(self): - dev1 = ip_lib.IPDevice('tap0') - dev2 = ip_lib.IPDevice('tap0') - self.assertEqual(dev1, dev2) - - def test_eq_diff_name(self): - dev1 = ip_lib.IPDevice('tap0') - dev2 = ip_lib.IPDevice('tap1') - self.assertNotEqual(dev1, dev2) - - def test_eq_same_namespace(self): - dev1 = ip_lib.IPDevice('tap0', 'ns1') - dev2 = ip_lib.IPDevice('tap0', 'ns1') - self.assertEqual(dev1, dev2) - - def test_eq_diff_namespace(self): - dev1 = ip_lib.IPDevice('tap0', 'sudo', 'ns1') - dev2 = ip_lib.IPDevice('tap0', 'sudo', 'ns2') - self.assertNotEqual(dev1, dev2) - - def test_eq_other_is_none(self): - dev1 = ip_lib.IPDevice('tap0', 'sudo', 'ns1') - self.assertIsNotNone(dev1) - - def test_str(self): - self.assertEqual(str(ip_lib.IPDevice('tap0')), 'tap0') - - -class TestIPCommandBase(base.BaseTestCase): - def setUp(self): - super(TestIPCommandBase, self).setUp() - self.ip = mock.Mock() - self.ip.root_helper = 'sudo' - self.ip.namespace = 'namespace' - self.ip_cmd = ip_lib.IpCommandBase(self.ip) - self.ip_cmd.COMMAND = 'foo' - - def test_run(self): - self.ip_cmd._run('link', 'show') - self.ip.assert_has_calls([mock.call._run([], 'foo', ('link', 'show'))]) - - def test_run_with_options(self): - self.ip_cmd._run('link', options='o') - self.ip.assert_has_calls([mock.call._run('o', 'foo', ('link', ))]) - - def test_as_root(self): - self.ip_cmd._as_root('link') - self.ip.assert_has_calls( - [mock.call._as_root([], 'foo', ('link', ), False)]) - - def test_as_root_with_options(self): - self.ip_cmd._as_root('link', options='o') - self.ip.assert_has_calls( - [mock.call._as_root('o', 'foo', ('link', ), False)]) - - -class TestIPDeviceCommandBase(base.BaseTestCase): - def setUp(self): - super(TestIPDeviceCommandBase, self).setUp() - self.ip_dev = mock.Mock() - self.ip_dev.name = 'eth0' - self.ip_dev.root_helper = 'sudo' - self.ip_dev._execute = mock.Mock(return_value='executed') - self.ip_cmd = ip_lib.IpDeviceCommandBase(self.ip_dev) - self.ip_cmd.COMMAND = 'foo' - - def test_name_property(self): - self.assertEqual(self.ip_cmd.name, 'eth0') - - -class TestIPCmdBase(base.BaseTestCase): - def setUp(self): - super(TestIPCmdBase, self).setUp() - self.parent = mock.Mock() - self.parent.name = 'eth0' - self.parent.root_helper = 'sudo' - - def _assert_call(self, options, args): - self.parent.assert_has_calls([ - mock.call._run(options, self.command, args)]) - - def _assert_sudo(self, options, args, force_root_namespace=False): - self.parent.assert_has_calls( - [mock.call._as_root(options, self.command, args, - force_root_namespace)]) - - -class TestIpLinkCommand(TestIPCmdBase): - def setUp(self): - super(TestIpLinkCommand, self).setUp() - self.parent._run.return_value = LINK_SAMPLE[1] - self.command = 'link' - self.link_cmd = ip_lib.IpLinkCommand(self.parent) - - def test_set_address(self): - self.link_cmd.set_address('aa:bb:cc:dd:ee:ff') - self._assert_sudo([], ('set', 'eth0', 'address', 'aa:bb:cc:dd:ee:ff')) - - def test_set_mtu(self): - self.link_cmd.set_mtu(1500) - self._assert_sudo([], ('set', 'eth0', 'mtu', 1500)) - - def test_set_up(self): - self.link_cmd.set_up() - self._assert_sudo([], ('set', 'eth0', 'up')) - - def test_set_down(self): - self.link_cmd.set_down() - self._assert_sudo([], ('set', 'eth0', 'down')) - - def test_set_netns(self): - self.link_cmd.set_netns('foo') - self._assert_sudo([], ('set', 'eth0', 'netns', 'foo')) - self.assertEqual(self.parent.namespace, 'foo') - - def test_set_name(self): - self.link_cmd.set_name('tap1') - self._assert_sudo([], ('set', 'eth0', 'name', 'tap1')) - self.assertEqual(self.parent.name, 'tap1') - - def test_set_alias(self): - self.link_cmd.set_alias('openvswitch') - self._assert_sudo([], ('set', 'eth0', 'alias', 'openvswitch')) - - def test_delete(self): - self.link_cmd.delete() - self._assert_sudo([], ('delete', 'eth0')) - - def test_address_property(self): - self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) - self.assertEqual(self.link_cmd.address, 'cc:dd:ee:ff:ab:cd') - - def test_mtu_property(self): - self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) - self.assertEqual(self.link_cmd.mtu, 1500) - - def test_qdisc_property(self): - self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) - self.assertEqual(self.link_cmd.qdisc, 'mq') - - def test_qlen_property(self): - self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) - self.assertEqual(self.link_cmd.qlen, 1000) - - def test_alias_property(self): - self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) - self.assertEqual(self.link_cmd.alias, 'openvswitch') - - def test_state_property(self): - self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) - self.assertEqual(self.link_cmd.state, 'UP') - - def test_settings_property(self): - expected = {'mtu': 1500, - 'qlen': 1000, - 'state': 'UP', - 'qdisc': 'mq', - 'brd': 'ff:ff:ff:ff:ff:ff', - 'link/ether': 'cc:dd:ee:ff:ab:cd', - 'alias': 'openvswitch'} - self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) - self.assertEqual(self.link_cmd.attributes, expected) - self._assert_call('o', ('show', 'eth0')) - - -class TestIpAddrCommand(TestIPCmdBase): - def setUp(self): - super(TestIpAddrCommand, self).setUp() - self.parent.name = 'tap0' - self.command = 'addr' - self.addr_cmd = ip_lib.IpAddrCommand(self.parent) - - def test_add_address(self): - self.addr_cmd.add(4, '192.168.45.100/24', '192.168.45.255') - self._assert_sudo([4], - ('add', '192.168.45.100/24', 'brd', '192.168.45.255', - 'scope', 'global', 'dev', 'tap0')) - - def test_add_address_scoped(self): - self.addr_cmd.add(4, '192.168.45.100/24', '192.168.45.255', - scope='link') - self._assert_sudo([4], - ('add', '192.168.45.100/24', 'brd', '192.168.45.255', - 'scope', 'link', 'dev', 'tap0')) - - def test_del_address(self): - self.addr_cmd.delete(4, '192.168.45.100/24') - self._assert_sudo([4], - ('del', '192.168.45.100/24', 'dev', 'tap0')) - - def test_flush(self): - self.addr_cmd.flush() - self._assert_sudo([], ('flush', 'tap0')) - - def test_list(self): - expected = [ - dict(ip_version=4, scope='global', - dynamic=False, cidr='172.16.77.240/24', - broadcast='172.16.77.255'), - dict(ip_version=6, scope='global', - dynamic=True, cidr='2001:470:9:1224:5595:dd51:6ba2:e788/64', - broadcast='::'), - dict(ip_version=6, scope='global', - dynamic=True, cidr='2001:470:9:1224:fd91:272:581e:3a32/64', - broadcast='::'), - dict(ip_version=6, scope='global', - dynamic=True, cidr='2001:470:9:1224:4508:b885:5fb:740b/64', - broadcast='::'), - dict(ip_version=6, scope='global', - dynamic=True, cidr='2001:470:9:1224:dfcc:aaff:feb9:76ce/64', - broadcast='::'), - dict(ip_version=6, scope='link', - dynamic=False, cidr='fe80::dfcc:aaff:feb9:76ce/64', - broadcast='::')] - - test_cases = [ADDR_SAMPLE, ADDR_SAMPLE2] - - for test_case in test_cases: - self.parent._run = mock.Mock(return_value=test_case) - self.assertEqual(self.addr_cmd.list(), expected) - self._assert_call([], ('show', 'tap0')) - - def test_list_filtered(self): - expected = [ - dict(ip_version=4, scope='global', - dynamic=False, cidr='172.16.77.240/24', - broadcast='172.16.77.255')] - - test_cases = [ADDR_SAMPLE, ADDR_SAMPLE2] - - for test_case in test_cases: - output = '\n'.join(test_case.split('\n')[0:4]) - self.parent._run.return_value = output - self.assertEqual(self.addr_cmd.list('global', - filters=['permanent']), expected) - self._assert_call([], ('show', 'tap0', 'permanent', 'scope', - 'global')) - - -class TestIpRouteCommand(TestIPCmdBase): - def setUp(self): - super(TestIpRouteCommand, self).setUp() - self.parent.name = 'eth0' - self.command = 'route' - self.route_cmd = ip_lib.IpRouteCommand(self.parent) - - def test_add_gateway(self): - gateway = '192.168.45.100' - metric = 100 - table = 14 - self.route_cmd.add_gateway(gateway, metric, table) - self._assert_sudo([], - ('replace', 'default', 'via', gateway, - 'metric', metric, - 'dev', self.parent.name, 'table', table)) - - def test_del_gateway(self): - gateway = '192.168.45.100' - table = 14 - self.route_cmd.delete_gateway(gateway, table) - self._assert_sudo([], - ('del', 'default', 'via', gateway, - 'dev', self.parent.name, 'table', table)) - - def test_get_gateway(self): - test_cases = [{'sample': GATEWAY_SAMPLE1, - 'expected': {'gateway': '10.35.19.254', - 'metric': 100}}, - {'sample': GATEWAY_SAMPLE2, - 'expected': {'gateway': '10.35.19.254', - 'metric': 100}}, - {'sample': GATEWAY_SAMPLE3, - 'expected': None}, - {'sample': GATEWAY_SAMPLE4, - 'expected': {'gateway': '10.35.19.254'}}, - {'sample': GATEWAY_SAMPLE5, - 'expected': {'gateway': '192.168.99.1'}}, - {'sample': GATEWAY_SAMPLE6, - 'expected': {'gateway': '192.168.99.1', - 'metric': 100}}] - for test_case in test_cases: - self.parent._run = mock.Mock(return_value=test_case['sample']) - self.assertEqual(self.route_cmd.get_gateway(), - test_case['expected']) - - def test_pullup_route(self): - # interface is not the first in the list - requires - # deleting and creating existing entries - output = [DEVICE_ROUTE_SAMPLE, SUBNET_SAMPLE1] - - def pullup_side_effect(self, *args): - result = output.pop(0) - return result - - self.parent._run = mock.Mock(side_effect=pullup_side_effect) - self.route_cmd.pullup_route('tap1d7888a7-10') - self._assert_sudo([], ('del', '10.0.0.0/24', 'dev', 'qr-23380d11-d2')) - self._assert_sudo([], ('append', '10.0.0.0/24', 'proto', 'kernel', - 'src', '10.0.0.1', 'dev', 'qr-23380d11-d2')) - - def test_pullup_route_first(self): - # interface is first in the list - no changes - output = [DEVICE_ROUTE_SAMPLE, SUBNET_SAMPLE2] - - def pullup_side_effect(self, *args): - result = output.pop(0) - return result - - self.parent._run = mock.Mock(side_effect=pullup_side_effect) - self.route_cmd.pullup_route('tap1d7888a7-10') - # Check two calls - device get and subnet get - self.assertEqual(len(self.parent._run.mock_calls), 2) - - def test_add_route(self): - cidr = '192.168.45.100/24' - ip = '10.0.0.1' - table = 14 - self.route_cmd.add_route(cidr, ip, table) - self._assert_sudo([], - ('replace', cidr, 'via', ip, - 'dev', self.parent.name, 'table', table)) - - def test_delete_route(self): - cidr = '192.168.45.100/24' - ip = '10.0.0.1' - table = 14 - self.route_cmd.delete_route(cidr, ip, table) - self._assert_sudo([], - ('del', cidr, 'via', ip, - 'dev', self.parent.name, 'table', table)) - - -class TestIpNetnsCommand(TestIPCmdBase): - def setUp(self): - super(TestIpNetnsCommand, self).setUp() - self.command = 'netns' - self.netns_cmd = ip_lib.IpNetnsCommand(self.parent) - - def test_add_namespace(self): - ns = self.netns_cmd.add('ns') - self._assert_sudo([], ('add', 'ns'), force_root_namespace=True) - self.assertEqual(ns.namespace, 'ns') - - def test_delete_namespace(self): - with mock.patch('neutron.agent.linux.utils.execute'): - self.netns_cmd.delete('ns') - self._assert_sudo([], ('delete', 'ns'), force_root_namespace=True) - - def test_namespace_exists(self): - retval = '\n'.join(NETNS_SAMPLE) - # need another instance to avoid mocking - netns_cmd = ip_lib.IpNetnsCommand(ip_lib.SubProcessBase()) - with mock.patch('neutron.agent.linux.utils.execute') as execute: - execute.return_value = retval - self.assertTrue( - netns_cmd.exists('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb')) - execute.assert_called_once_with(['ip', '-o', 'netns', 'list'], - root_helper=None) - - def test_namespace_doest_not_exist(self): - retval = '\n'.join(NETNS_SAMPLE) - # need another instance to avoid mocking - netns_cmd = ip_lib.IpNetnsCommand(ip_lib.SubProcessBase()) - with mock.patch('neutron.agent.linux.utils.execute') as execute: - execute.return_value = retval - self.assertFalse( - netns_cmd.exists('bbbbbbbb-1111-2222-3333-bbbbbbbbbbbb')) - execute.assert_called_once_with(['ip', '-o', 'netns', 'list'], - root_helper=None) - - def test_execute(self): - self.parent.namespace = 'ns' - with mock.patch('neutron.agent.linux.utils.execute') as execute: - self.netns_cmd.execute(['ip', 'link', 'list']) - execute.assert_called_once_with(['ip', 'netns', 'exec', 'ns', 'ip', - 'link', 'list'], - root_helper='sudo', - check_exit_code=True) - - def test_execute_env_var_prepend(self): - self.parent.namespace = 'ns' - with mock.patch('neutron.agent.linux.utils.execute') as execute: - env = dict(FOO=1, BAR=2) - self.netns_cmd.execute(['ip', 'link', 'list'], env) - execute.assert_called_once_with( - ['ip', 'netns', 'exec', 'ns', 'env', 'FOO=1', 'BAR=2', - 'ip', 'link', 'list'], - root_helper='sudo', check_exit_code=True) - - -class TestDeviceExists(base.BaseTestCase): - def test_device_exists(self): - with mock.patch.object(ip_lib.IPDevice, '_execute') as _execute: - _execute.return_value = LINK_SAMPLE[1] - self.assertTrue(ip_lib.device_exists('eth0')) - _execute.assert_called_once_with('o', 'link', ('show', 'eth0')) - - def test_device_does_not_exist(self): - with mock.patch.object(ip_lib.IPDevice, '_execute') as _execute: - _execute.return_value = '' - _execute.side_effect = RuntimeError - self.assertFalse(ip_lib.device_exists('eth0')) - - def test_ensure_device_is_ready(self): - ip_lib_mock = mock.Mock() - with mock.patch.object(ip_lib, 'IPDevice', return_value=ip_lib_mock): - self.assertTrue(ip_lib.ensure_device_is_ready("eth0")) - self.assertTrue(ip_lib_mock.link.set_up.called) - ip_lib_mock.reset_mock() - # device doesn't exists - ip_lib_mock.link.set_up.side_effect = RuntimeError - self.assertFalse(ip_lib.ensure_device_is_ready("eth0")) - - -class TestIpNeighCommand(TestIPCmdBase): - def setUp(self): - super(TestIpNeighCommand, self).setUp() - self.parent.name = 'tap0' - self.command = 'neigh' - self.neigh_cmd = ip_lib.IpNeighCommand(self.parent) - - def test_add_entry(self): - self.neigh_cmd.add(4, '192.168.45.100', 'cc:dd:ee:ff:ab:cd') - self._assert_sudo([4], ('replace', '192.168.45.100', 'lladdr', - 'cc:dd:ee:ff:ab:cd', 'nud', 'permanent', - 'dev', 'tap0')) - - def test_delete_entry(self): - self.neigh_cmd.delete(4, '192.168.45.100', 'cc:dd:ee:ff:ab:cd') - self._assert_sudo([4], ('del', '192.168.45.100', 'lladdr', - 'cc:dd:ee:ff:ab:cd', 'dev', 'tap0')) diff --git a/neutron/tests/unit/test_metadata_agent.py b/neutron/tests/unit/test_metadata_agent.py deleted file mode 100644 index 872adaef3..000000000 --- a/neutron/tests/unit/test_metadata_agent.py +++ /dev/null @@ -1,581 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost - -import contextlib -import socket - -import mock -import testtools -import webob - -from neutron.agent.metadata import agent -from neutron.common import constants -from neutron.common import utils -from neutron.tests import base - - -class FakeConf(object): - admin_user = 'neutron' - admin_password = 'password' - admin_tenant_name = 'tenant' - auth_url = 'http://127.0.0.1' - auth_strategy = 'keystone' - auth_region = 'region' - auth_insecure = False - auth_ca_cert = None - endpoint_type = 'adminURL' - nova_metadata_ip = '9.9.9.9' - nova_metadata_port = 8775 - metadata_proxy_shared_secret = 'secret' - nova_metadata_protocol = 'http' - nova_metadata_insecure = True - nova_client_cert = 'nova_cert' - nova_client_priv_key = 'nova_priv_key' - cache_url = '' - - -class FakeConfCache(FakeConf): - cache_url = 'memory://?default_ttl=5' - - -class TestMetadataProxyHandlerCache(base.BaseTestCase): - fake_conf = FakeConfCache - - def setUp(self): - super(TestMetadataProxyHandlerCache, self).setUp() - self.qclient_p = mock.patch('neutronclient.v2_0.client.Client') - self.qclient = self.qclient_p.start() - - self.log_p = mock.patch.object(agent, 'LOG') - self.log = self.log_p.start() - - self.handler = agent.MetadataProxyHandler(self.fake_conf) - - def test_call(self): - req = mock.Mock() - with mock.patch.object(self.handler, - '_get_instance_and_tenant_id') as get_ids: - get_ids.return_value = ('instance_id', 'tenant_id') - with mock.patch.object(self.handler, '_proxy_request') as proxy: - proxy.return_value = 'value' - - retval = self.handler(req) - self.assertEqual(retval, 'value') - - def test_call_no_instance_match(self): - req = mock.Mock() - with mock.patch.object(self.handler, - '_get_instance_and_tenant_id') as get_ids: - get_ids.return_value = None, None - retval = self.handler(req) - self.assertIsInstance(retval, webob.exc.HTTPNotFound) - - def test_call_internal_server_error(self): - req = mock.Mock() - with mock.patch.object(self.handler, - '_get_instance_and_tenant_id') as get_ids: - get_ids.side_effect = Exception - retval = self.handler(req) - self.assertIsInstance(retval, webob.exc.HTTPInternalServerError) - self.assertEqual(len(self.log.mock_calls), 2) - - def test_get_router_networks(self): - router_id = 'router-id' - expected = ('network_id1', 'network_id2') - ports = {'ports': [{'network_id': 'network_id1', 'something': 42}, - {'network_id': 'network_id2', - 'something_else': 32}], - 'not_used': [1, 2, 3]} - mock_list_ports = self.qclient.return_value.list_ports - mock_list_ports.return_value = ports - networks = self.handler._get_router_networks(router_id) - mock_list_ports.assert_called_once_with( - device_id=router_id, - device_owner=constants.DEVICE_OWNER_ROUTER_INTF) - self.assertEqual(expected, networks) - - def _test_get_router_networks_twice_helper(self): - router_id = 'router-id' - ports = {'ports': [{'network_id': 'network_id1', 'something': 42}], - 'not_used': [1, 2, 3]} - expected_networks = ('network_id1',) - with mock.patch( - 'neutron.openstack.common.timeutils.utcnow_ts', return_value=0): - mock_list_ports = self.qclient.return_value.list_ports - mock_list_ports.return_value = ports - networks = self.handler._get_router_networks(router_id) - mock_list_ports.assert_called_once_with( - device_id=router_id, - device_owner=constants.DEVICE_OWNER_ROUTER_INTF) - self.assertEqual(expected_networks, networks) - networks = self.handler._get_router_networks(router_id) - - def test_get_router_networks_twice(self): - self._test_get_router_networks_twice_helper() - self.assertEqual( - 1, self.qclient.return_value.list_ports.call_count) - - def test_get_ports_for_remote_address(self): - remote_address = 'remote_address' - networks = 'networks' - fixed_ips = ["ip_address=%s" % remote_address] - ports = self.handler._get_ports_for_remote_address(remote_address, - networks) - mock_list_ports = self.qclient.return_value.list_ports - mock_list_ports.assert_called_once_with( - network_id=networks, fixed_ips=fixed_ips) - self.assertEqual(mock_list_ports.return_value.__getitem__('ports'), - ports) - - def _get_ports_for_remote_address_cache_hit_helper(self): - remote_address = 'remote_address' - networks = ('net1', 'net2') - fixed_ips = ["ip_address=%s" % remote_address] - ports = self.handler._get_ports_for_remote_address(remote_address, - networks) - mock_list_ports = self.qclient.return_value.list_ports - mock_list_ports.assert_called_once_with( - network_id=networks, fixed_ips=fixed_ips) - self.assertEqual( - mock_list_ports.return_value.__getitem__('ports'), ports) - self.assertEqual(1, mock_list_ports.call_count) - self.handler._get_ports_for_remote_address(remote_address, - networks) - - def test_get_ports_for_remote_address_cache_hit(self): - self._get_ports_for_remote_address_cache_hit_helper() - self.assertEqual( - 1, self.qclient.return_value.list_ports.call_count) - - def test_get_ports_network_id(self): - network_id = 'network-id' - router_id = 'router-id' - remote_address = 'remote-address' - expected = ['port1'] - networks = (network_id,) - with contextlib.nested( - mock.patch.object(self.handler, '_get_ports_for_remote_address'), - mock.patch.object(self.handler, '_get_router_networks') - ) as (mock_get_ip_addr, mock_get_router_networks): - mock_get_ip_addr.return_value = expected - ports = self.handler._get_ports(remote_address, network_id, - router_id) - mock_get_ip_addr.assert_called_once_with(remote_address, - networks) - self.assertFalse(mock_get_router_networks.called) - self.assertEqual(expected, ports) - - def test_get_ports_router_id(self): - router_id = 'router-id' - remote_address = 'remote-address' - expected = ['port1'] - networks = ('network1', 'network2') - with contextlib.nested( - mock.patch.object(self.handler, - '_get_ports_for_remote_address', - return_value=expected), - mock.patch.object(self.handler, - '_get_router_networks', - return_value=networks) - ) as (mock_get_ip_addr, mock_get_router_networks): - ports = self.handler._get_ports(remote_address, - router_id=router_id) - mock_get_router_networks.called_once_with(router_id) - mock_get_ip_addr.assert_called_once_with(remote_address, networks) - self.assertEqual(expected, ports) - - def test_get_ports_no_id(self): - self.assertRaises(TypeError, self.handler._get_ports, 'remote_address') - - def _get_instance_and_tenant_id_helper(self, headers, list_ports_retval, - networks=None, router_id=None): - remote_address = '192.168.1.1' - headers['X-Forwarded-For'] = remote_address - req = mock.Mock(headers=headers) - - def mock_list_ports(*args, **kwargs): - return {'ports': list_ports_retval.pop(0)} - - self.qclient.return_value.list_ports.side_effect = mock_list_ports - instance_id, tenant_id = self.handler._get_instance_and_tenant_id(req) - new_qclient_call = mock.call( - username=FakeConf.admin_user, - tenant_name=FakeConf.admin_tenant_name, - region_name=FakeConf.auth_region, - auth_url=FakeConf.auth_url, - password=FakeConf.admin_password, - auth_strategy=FakeConf.auth_strategy, - token=None, - insecure=FakeConf.auth_insecure, - ca_cert=FakeConf.auth_ca_cert, - endpoint_url=None, - endpoint_type=FakeConf.endpoint_type) - expected = [new_qclient_call] - - if router_id: - expected.extend([ - new_qclient_call, - mock.call().list_ports( - device_id=router_id, - device_owner=constants.DEVICE_OWNER_ROUTER_INTF - ) - ]) - - expected.extend([ - new_qclient_call, - mock.call().list_ports( - network_id=networks or tuple(), - fixed_ips=['ip_address=192.168.1.1']) - ]) - - self.qclient.assert_has_calls(expected) - - return (instance_id, tenant_id) - - def test_get_instance_id_router_id(self): - router_id = 'the_id' - headers = { - 'X-Neutron-Router-ID': router_id - } - - networks = ('net1', 'net2') - ports = [ - [{'network_id': 'net1'}, {'network_id': 'net2'}], - [{'device_id': 'device_id', 'tenant_id': 'tenant_id'}] - ] - - self.assertEqual( - self._get_instance_and_tenant_id_helper(headers, ports, - networks=networks, - router_id=router_id), - ('device_id', 'tenant_id') - ) - - def test_get_instance_id_router_id_no_match(self): - router_id = 'the_id' - headers = { - 'X-Neutron-Router-ID': router_id - } - - networks = ('net1', 'net2') - ports = [ - [{'network_id': 'net1'}, {'network_id': 'net2'}], - [] - ] - self.assertEqual( - self._get_instance_and_tenant_id_helper(headers, ports, - networks=networks, - router_id=router_id), - (None, None) - ) - - def test_get_instance_id_network_id(self): - network_id = 'the_id' - headers = { - 'X-Neutron-Network-ID': network_id - } - - ports = [ - [{'device_id': 'device_id', - 'tenant_id': 'tenant_id'}] - ] - - self.assertEqual( - self._get_instance_and_tenant_id_helper(headers, ports, - networks=('the_id',)), - ('device_id', 'tenant_id') - ) - - def test_get_instance_id_network_id_no_match(self): - network_id = 'the_id' - headers = { - 'X-Neutron-Network-ID': network_id - } - - ports = [[]] - - self.assertEqual( - self._get_instance_and_tenant_id_helper(headers, ports, - networks=('the_id',)), - (None, None) - ) - - def _proxy_request_test_helper(self, response_code=200, method='GET'): - hdrs = {'X-Forwarded-For': '8.8.8.8'} - body = 'body' - - req = mock.Mock(path_info='/the_path', query_string='', headers=hdrs, - method=method, body=body) - resp = mock.MagicMock(status=response_code) - req.response = resp - with mock.patch.object(self.handler, '_sign_instance_id') as sign: - sign.return_value = 'signed' - with mock.patch('httplib2.Http') as mock_http: - resp.__getitem__.return_value = "text/plain" - mock_http.return_value.request.return_value = (resp, 'content') - - retval = self.handler._proxy_request('the_id', 'tenant_id', - req) - mock_http.assert_called_once_with( - ca_certs=None, disable_ssl_certificate_validation=True) - mock_http.assert_has_calls([ - mock.call().add_certificate( - FakeConf.nova_client_priv_key, - FakeConf.nova_client_cert, - "%s:%s" % (FakeConf.nova_metadata_ip, - FakeConf.nova_metadata_port) - ), - mock.call().request( - 'http://9.9.9.9:8775/the_path', - method=method, - headers={ - 'X-Forwarded-For': '8.8.8.8', - 'X-Instance-ID-Signature': 'signed', - 'X-Instance-ID': 'the_id', - 'X-Tenant-ID': 'tenant_id' - }, - body=body - )] - ) - - return retval - - def test_proxy_request_post(self): - response = self._proxy_request_test_helper(method='POST') - self.assertEqual(response.content_type, "text/plain") - self.assertEqual(response.body, 'content') - - def test_proxy_request_200(self): - response = self._proxy_request_test_helper(200) - self.assertEqual(response.content_type, "text/plain") - self.assertEqual(response.body, 'content') - - def test_proxy_request_403(self): - self.assertIsInstance(self._proxy_request_test_helper(403), - webob.exc.HTTPForbidden) - - def test_proxy_request_404(self): - self.assertIsInstance(self._proxy_request_test_helper(404), - webob.exc.HTTPNotFound) - - def test_proxy_request_409(self): - self.assertIsInstance(self._proxy_request_test_helper(409), - webob.exc.HTTPConflict) - - def test_proxy_request_500(self): - self.assertIsInstance(self._proxy_request_test_helper(500), - webob.exc.HTTPInternalServerError) - - def test_proxy_request_other_code(self): - with testtools.ExpectedException(Exception): - self._proxy_request_test_helper(302) - - def test_sign_instance_id(self): - self.assertEqual( - self.handler._sign_instance_id('foo'), - '773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4' - ) - - -class TestMetadataProxyHandlerNoCache(TestMetadataProxyHandlerCache): - fake_conf = FakeConf - - def test_get_router_networks_twice(self): - self._test_get_router_networks_twice_helper() - self.assertEqual( - 2, self.qclient.return_value.list_ports.call_count) - - def test_get_ports_for_remote_address_cache_hit(self): - self._get_ports_for_remote_address_cache_hit_helper() - self.assertEqual( - 2, self.qclient.return_value.list_ports.call_count) - - -class TestUnixDomainHttpProtocol(base.BaseTestCase): - def test_init_empty_client(self): - u = agent.UnixDomainHttpProtocol(mock.Mock(), '', mock.Mock()) - self.assertEqual(u.client_address, ('', 0)) - - def test_init_with_client(self): - u = agent.UnixDomainHttpProtocol(mock.Mock(), 'foo', mock.Mock()) - self.assertEqual(u.client_address, 'foo') - - -class TestUnixDomainWSGIServer(base.BaseTestCase): - def setUp(self): - super(TestUnixDomainWSGIServer, self).setUp() - self.eventlet_p = mock.patch.object(agent, 'eventlet') - self.eventlet = self.eventlet_p.start() - self.server = agent.UnixDomainWSGIServer('test') - - def test_start(self): - mock_app = mock.Mock() - with mock.patch.object(self.server, 'pool') as pool: - self.server.start(mock_app, '/the/path', workers=0, backlog=128) - self.eventlet.assert_has_calls([ - mock.call.listen( - '/the/path', - family=socket.AF_UNIX, - backlog=128 - )] - ) - pool.spawn_n.assert_called_once_with( - self.server._run, - mock_app, - self.eventlet.listen.return_value - ) - - @mock.patch('neutron.openstack.common.service.ProcessLauncher') - def test_start_multiple_workers(self, process_launcher): - launcher = process_launcher.return_value - - mock_app = mock.Mock() - self.server.start(mock_app, '/the/path', workers=2, backlog=128) - launcher.running = True - launcher.launch_service.assert_called_once_with(self.server._server, - workers=2) - - self.server.stop() - self.assertFalse(launcher.running) - - self.server.wait() - launcher.wait.assert_called_once_with() - - def test_run(self): - with mock.patch.object(agent, 'logging') as logging: - self.server._run('app', 'sock') - - self.eventlet.wsgi.server.assert_called_once_with( - 'sock', - 'app', - protocol=agent.UnixDomainHttpProtocol, - log=mock.ANY, - custom_pool=self.server.pool - ) - self.assertTrue(len(logging.mock_calls)) - - -class TestUnixDomainMetadataProxy(base.BaseTestCase): - def setUp(self): - super(TestUnixDomainMetadataProxy, self).setUp() - self.cfg_p = mock.patch.object(agent, 'cfg') - self.cfg = self.cfg_p.start() - looping_call_p = mock.patch( - 'neutron.openstack.common.loopingcall.FixedIntervalLoopingCall') - self.looping_mock = looping_call_p.start() - self.cfg.CONF.metadata_proxy_socket = '/the/path' - self.cfg.CONF.metadata_workers = 0 - self.cfg.CONF.metadata_backlog = 128 - - def test_init_doesnot_exists(self): - with mock.patch('os.path.isdir') as isdir: - with mock.patch('os.makedirs') as makedirs: - isdir.return_value = False - agent.UnixDomainMetadataProxy(mock.Mock()) - - isdir.assert_called_once_with('/the') - makedirs.assert_called_once_with('/the', 0o755) - - def test_init_exists(self): - with mock.patch('os.path.isdir') as isdir: - with mock.patch('os.unlink') as unlink: - isdir.return_value = True - agent.UnixDomainMetadataProxy(mock.Mock()) - - isdir.assert_called_once_with('/the') - unlink.assert_called_once_with('/the/path') - - def test_init_exists_unlink_no_file(self): - with mock.patch('os.path.isdir') as isdir: - with mock.patch('os.unlink') as unlink: - with mock.patch('os.path.exists') as exists: - isdir.return_value = True - exists.return_value = False - unlink.side_effect = OSError - - agent.UnixDomainMetadataProxy(mock.Mock()) - - isdir.assert_called_once_with('/the') - unlink.assert_called_once_with('/the/path') - exists.assert_called_once_with('/the/path') - - def test_init_exists_unlink_fails_file_still_exists(self): - with mock.patch('os.path.isdir') as isdir: - with mock.patch('os.unlink') as unlink: - with mock.patch('os.path.exists') as exists: - isdir.return_value = True - exists.return_value = True - unlink.side_effect = OSError - - with testtools.ExpectedException(OSError): - agent.UnixDomainMetadataProxy(mock.Mock()) - - isdir.assert_called_once_with('/the') - unlink.assert_called_once_with('/the/path') - exists.assert_called_once_with('/the/path') - - def test_run(self): - with mock.patch.object(agent, 'MetadataProxyHandler') as handler: - with mock.patch.object(agent, 'UnixDomainWSGIServer') as server: - with mock.patch('os.path.isdir') as isdir: - with mock.patch('os.makedirs') as makedirs: - isdir.return_value = False - - p = agent.UnixDomainMetadataProxy(self.cfg.CONF) - p.run() - - isdir.assert_called_once_with('/the') - makedirs.assert_called_once_with('/the', 0o755) - server.assert_has_calls([ - mock.call('neutron-metadata-agent'), - mock.call().start(handler.return_value, - '/the/path', workers=0, - backlog=128), - mock.call().wait()] - ) - - def test_main(self): - with mock.patch.object(agent, 'UnixDomainMetadataProxy') as proxy: - with mock.patch.object(agent, 'config') as config: - with mock.patch.object(agent, 'cfg') as cfg: - with mock.patch.object(utils, 'cfg'): - agent.main() - - self.assertTrue(config.setup_logging.called) - proxy.assert_has_calls([ - mock.call(cfg.CONF), - mock.call().run()] - ) - - def test_init_state_reporting(self): - with mock.patch('os.makedirs'): - proxy = agent.UnixDomainMetadataProxy(mock.Mock()) - self.looping_mock.assert_called_once_with(proxy._report_state) - self.looping_mock.return_value.start.assert_called_once_with( - interval=mock.ANY) - - def test_report_state(self): - with mock.patch('neutron.agent.rpc.PluginReportStateAPI') as state_api: - with mock.patch('os.makedirs'): - proxy = agent.UnixDomainMetadataProxy(mock.Mock()) - self.assertTrue(proxy.agent_state['start_flag']) - proxy._report_state() - self.assertNotIn('start_flag', proxy.agent_state) - state_api_inst = state_api.return_value - state_api_inst.report_state.assert_called_once_with( - proxy.context, proxy.agent_state, use_call=True) diff --git a/neutron/tests/unit/test_metadata_namespace_proxy.py b/neutron/tests/unit/test_metadata_namespace_proxy.py deleted file mode 100644 index 416a113b3..000000000 --- a/neutron/tests/unit/test_metadata_namespace_proxy.py +++ /dev/null @@ -1,353 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012 New Dream Network, LLC (DreamHost) -# -# 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. -# -# @author: Mark McClain, DreamHost - -import socket - -import mock -import testtools -import webob - -from neutron.agent.metadata import namespace_proxy as ns_proxy -from neutron.common import utils -from neutron.tests import base - - -class FakeConf(object): - admin_user = 'neutron' - admin_password = 'password' - admin_tenant_name = 'tenant' - auth_url = 'http://127.0.0.1' - auth_strategy = 'keystone' - auth_region = 'region' - nova_metadata_ip = '9.9.9.9' - nova_metadata_port = 8775 - metadata_proxy_shared_secret = 'secret' - - -class TestUnixDomainHttpConnection(base.BaseTestCase): - def test_connect(self): - with mock.patch.object(ns_proxy, 'cfg') as cfg: - cfg.CONF.metadata_proxy_socket = '/the/path' - with mock.patch('socket.socket') as socket_create: - conn = ns_proxy.UnixDomainHTTPConnection('169.254.169.254', - timeout=3) - - conn.connect() - - socket_create.assert_has_calls([ - mock.call(socket.AF_UNIX, socket.SOCK_STREAM), - mock.call().settimeout(3), - mock.call().connect('/the/path')] - ) - self.assertEqual(conn.timeout, 3) - - -class TestNetworkMetadataProxyHandler(base.BaseTestCase): - def setUp(self): - super(TestNetworkMetadataProxyHandler, self).setUp() - self.log_p = mock.patch.object(ns_proxy, 'LOG') - self.log = self.log_p.start() - - self.handler = ns_proxy.NetworkMetadataProxyHandler('router_id') - - def test_call(self): - req = mock.Mock(headers={}) - with mock.patch.object(self.handler, '_proxy_request') as proxy_req: - proxy_req.return_value = 'value' - - retval = self.handler(req) - self.assertEqual(retval, 'value') - proxy_req.assert_called_once_with(req.remote_addr, - req.method, - req.path_info, - req.query_string, - req.body) - - def test_no_argument_passed_to_init(self): - with testtools.ExpectedException(ValueError): - ns_proxy.NetworkMetadataProxyHandler() - - def test_call_internal_server_error(self): - req = mock.Mock(headers={}) - with mock.patch.object(self.handler, '_proxy_request') as proxy_req: - proxy_req.side_effect = Exception - retval = self.handler(req) - self.assertIsInstance(retval, webob.exc.HTTPInternalServerError) - self.assertEqual(len(self.log.mock_calls), 2) - self.assertTrue(proxy_req.called) - - def test_proxy_request_router_200(self): - self.handler.router_id = 'router_id' - - resp = mock.MagicMock(status=200) - with mock.patch('httplib2.Http') as mock_http: - resp.__getitem__.return_value = "text/plain" - mock_http.return_value.request.return_value = (resp, 'content') - - retval = self.handler._proxy_request('192.168.1.1', - 'GET', - '/latest/meta-data', - '', - '') - - mock_http.assert_has_calls([ - mock.call().request( - 'http://169.254.169.254/latest/meta-data', - method='GET', - headers={ - 'X-Forwarded-For': '192.168.1.1', - 'X-Neutron-Router-ID': 'router_id' - }, - connection_type=ns_proxy.UnixDomainHTTPConnection, - body='' - )] - ) - - self.assertEqual(retval.headers['Content-Type'], 'text/plain') - self.assertEqual(retval.body, 'content') - - def test_proxy_request_network_200(self): - self.handler.network_id = 'network_id' - - resp = mock.MagicMock(status=200) - with mock.patch('httplib2.Http') as mock_http: - resp.__getitem__.return_value = "application/json" - mock_http.return_value.request.return_value = (resp, '{}') - - retval = self.handler._proxy_request('192.168.1.1', - 'GET', - '/latest/meta-data', - '', - '') - - mock_http.assert_has_calls([ - mock.call().request( - 'http://169.254.169.254/latest/meta-data', - method='GET', - headers={ - 'X-Forwarded-For': '192.168.1.1', - 'X-Neutron-Network-ID': 'network_id' - }, - connection_type=ns_proxy.UnixDomainHTTPConnection, - body='' - )] - ) - - self.assertEqual(retval.headers['Content-Type'], - 'application/json') - self.assertEqual(retval.body, '{}') - - def test_proxy_request_network_404(self): - self.handler.network_id = 'network_id' - - resp = mock.Mock(status=404) - with mock.patch('httplib2.Http') as mock_http: - mock_http.return_value.request.return_value = (resp, '') - - retval = self.handler._proxy_request('192.168.1.1', - 'GET', - '/latest/meta-data', - '', - '') - - mock_http.assert_has_calls([ - mock.call().request( - 'http://169.254.169.254/latest/meta-data', - method='GET', - headers={ - 'X-Forwarded-For': '192.168.1.1', - 'X-Neutron-Network-ID': 'network_id' - }, - connection_type=ns_proxy.UnixDomainHTTPConnection, - body='' - )] - ) - - self.assertIsInstance(retval, webob.exc.HTTPNotFound) - - def test_proxy_request_network_409(self): - self.handler.network_id = 'network_id' - - resp = mock.Mock(status=409) - with mock.patch('httplib2.Http') as mock_http: - mock_http.return_value.request.return_value = (resp, '') - - retval = self.handler._proxy_request('192.168.1.1', - 'POST', - '/latest/meta-data', - '', - '') - - mock_http.assert_has_calls([ - mock.call().request( - 'http://169.254.169.254/latest/meta-data', - method='POST', - headers={ - 'X-Forwarded-For': '192.168.1.1', - 'X-Neutron-Network-ID': 'network_id' - }, - connection_type=ns_proxy.UnixDomainHTTPConnection, - body='' - )] - ) - - self.assertIsInstance(retval, webob.exc.HTTPConflict) - - def test_proxy_request_network_500(self): - self.handler.network_id = 'network_id' - - resp = mock.Mock(status=500) - with mock.patch('httplib2.Http') as mock_http: - mock_http.return_value.request.return_value = (resp, '') - - retval = self.handler._proxy_request('192.168.1.1', - 'GET', - '/latest/meta-data', - '', - '') - - mock_http.assert_has_calls([ - mock.call().request( - 'http://169.254.169.254/latest/meta-data', - method='GET', - headers={ - 'X-Forwarded-For': '192.168.1.1', - 'X-Neutron-Network-ID': 'network_id' - }, - connection_type=ns_proxy.UnixDomainHTTPConnection, - body='' - )] - ) - - self.assertIsInstance(retval, webob.exc.HTTPInternalServerError) - - def test_proxy_request_network_418(self): - self.handler.network_id = 'network_id' - - resp = mock.Mock(status=418) - with mock.patch('httplib2.Http') as mock_http: - mock_http.return_value.request.return_value = (resp, '') - - with testtools.ExpectedException(Exception): - self.handler._proxy_request('192.168.1.1', - 'GET', - '/latest/meta-data', - '', - '') - - mock_http.assert_has_calls([ - mock.call().request( - 'http://169.254.169.254/latest/meta-data', - method='GET', - headers={ - 'X-Forwarded-For': '192.168.1.1', - 'X-Neutron-Network-ID': 'network_id' - }, - connection_type=ns_proxy.UnixDomainHTTPConnection, - body='' - )] - ) - - def test_proxy_request_network_exception(self): - self.handler.network_id = 'network_id' - - mock.Mock(status=500) - with mock.patch('httplib2.Http') as mock_http: - mock_http.return_value.request.side_effect = Exception - - with testtools.ExpectedException(Exception): - self.handler._proxy_request('192.168.1.1', - 'GET', - '/latest/meta-data', - '', - '') - - mock_http.assert_has_calls([ - mock.call().request( - 'http://169.254.169.254/latest/meta-data', - method='GET', - headers={ - 'X-Forwarded-For': '192.168.1.1', - 'X-Neutron-Network-ID': 'network_id' - }, - connection_type=ns_proxy.UnixDomainHTTPConnection, - body='' - )] - ) - - -class TestProxyDaemon(base.BaseTestCase): - def test_init(self): - with mock.patch('neutron.agent.linux.daemon.Pidfile'): - pd = ns_proxy.ProxyDaemon('pidfile', 9697, 'net_id', 'router_id') - self.assertEqual(pd.router_id, 'router_id') - self.assertEqual(pd.network_id, 'net_id') - - def test_run(self): - with mock.patch('neutron.agent.linux.daemon.Pidfile'): - with mock.patch('neutron.wsgi.Server') as Server: - pd = ns_proxy.ProxyDaemon('pidfile', 9697, 'net_id', - 'router_id') - pd.run() - Server.assert_has_calls([ - mock.call('neutron-network-metadata-proxy'), - mock.call().start(mock.ANY, 9697), - mock.call().wait()] - ) - - def test_main(self): - with mock.patch.object(ns_proxy, 'ProxyDaemon') as daemon: - with mock.patch.object(ns_proxy, 'config') as config: - with mock.patch.object(ns_proxy, 'cfg') as cfg: - with mock.patch.object(utils, 'cfg') as utils_cfg: - cfg.CONF.router_id = 'router_id' - cfg.CONF.network_id = None - cfg.CONF.metadata_port = 9697 - cfg.CONF.pid_file = 'pidfile' - cfg.CONF.daemonize = True - utils_cfg.CONF.log_opt_values.return_value = None - ns_proxy.main() - - self.assertTrue(config.setup_logging.called) - daemon.assert_has_calls([ - mock.call('pidfile', 9697, - router_id='router_id', - network_id=None), - mock.call().start()] - ) - - def test_main_dont_fork(self): - with mock.patch.object(ns_proxy, 'ProxyDaemon') as daemon: - with mock.patch.object(ns_proxy, 'config') as config: - with mock.patch.object(ns_proxy, 'cfg') as cfg: - with mock.patch.object(utils, 'cfg') as utils_cfg: - cfg.CONF.router_id = 'router_id' - cfg.CONF.network_id = None - cfg.CONF.metadata_port = 9697 - cfg.CONF.pid_file = 'pidfile' - cfg.CONF.daemonize = False - utils_cfg.CONF.log_opt_values.return_value = None - ns_proxy.main() - - self.assertTrue(config.setup_logging.called) - daemon.assert_has_calls([ - mock.call('pidfile', 9697, - router_id='router_id', - network_id=None), - mock.call().run()] - ) diff --git a/neutron/tests/unit/test_neutron_manager.py b/neutron/tests/unit/test_neutron_manager.py deleted file mode 100644 index 4a8eb0e6d..000000000 --- a/neutron/tests/unit/test_neutron_manager.py +++ /dev/null @@ -1,146 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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 types - -import fixtures - -from oslo.config import cfg - -from neutron import manager -from neutron.openstack.common import log as logging -from neutron.plugins.common import constants -from neutron.tests import base -from neutron.tests.unit import dummy_plugin - - -LOG = logging.getLogger(__name__) -DB_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2' - - -class MultiServiceCorePlugin(object): - supported_extension_aliases = ['lbaas', 'dummy'] - - -class CorePluginWithAgentNotifiers(object): - agent_notifiers = {'l3': 'l3_agent_notifier', - 'dhcp': 'dhcp_agent_notifier'} - - -class NeutronManagerTestCase(base.BaseTestCase): - - def setUp(self): - super(NeutronManagerTestCase, self).setUp() - self.config_parse() - self.setup_coreplugin() - self.useFixture( - fixtures.MonkeyPatch('neutron.manager.NeutronManager._instance')) - - def test_service_plugin_is_loaded(self): - cfg.CONF.set_override("core_plugin", DB_PLUGIN_KLASS) - cfg.CONF.set_override("service_plugins", - ["neutron.tests.unit.dummy_plugin." - "DummyServicePlugin"]) - mgr = manager.NeutronManager.get_instance() - plugin = mgr.get_service_plugins()[constants.DUMMY] - - self.assertTrue( - isinstance(plugin, - (dummy_plugin.DummyServicePlugin, types.ClassType)), - "loaded plugin should be of type neutronDummyPlugin") - - def test_service_plugin_by_name_is_loaded(self): - cfg.CONF.set_override("core_plugin", DB_PLUGIN_KLASS) - cfg.CONF.set_override("service_plugins", ["dummy"]) - mgr = manager.NeutronManager.get_instance() - plugin = mgr.get_service_plugins()[constants.DUMMY] - - self.assertTrue( - isinstance(plugin, - (dummy_plugin.DummyServicePlugin, types.ClassType)), - "loaded plugin should be of type neutronDummyPlugin") - - def test_multiple_plugins_specified_for_service_type(self): - cfg.CONF.set_override("service_plugins", - ["neutron.tests.unit.dummy_plugin." - "DummyServicePlugin", - "neutron.tests.unit.dummy_plugin." - "DummyServicePlugin"]) - cfg.CONF.set_override("core_plugin", DB_PLUGIN_KLASS) - self.assertRaises(ValueError, manager.NeutronManager.get_instance) - - def test_multiple_plugins_by_name_specified_for_service_type(self): - cfg.CONF.set_override("service_plugins", ["dummy", "dummy"]) - cfg.CONF.set_override("core_plugin", DB_PLUGIN_KLASS) - self.assertRaises(ValueError, manager.NeutronManager.get_instance) - - def test_multiple_plugins_mixed_specified_for_service_type(self): - cfg.CONF.set_override("service_plugins", - ["neutron.tests.unit.dummy_plugin." - "DummyServicePlugin", "dummy"]) - cfg.CONF.set_override("core_plugin", DB_PLUGIN_KLASS) - self.assertRaises(ValueError, manager.NeutronManager.get_instance) - - def test_service_plugin_conflicts_with_core_plugin(self): - cfg.CONF.set_override("service_plugins", - ["neutron.tests.unit.dummy_plugin." - "DummyServicePlugin"]) - cfg.CONF.set_override("core_plugin", - "neutron.tests.unit.test_neutron_manager." - "MultiServiceCorePlugin") - self.assertRaises(ValueError, manager.NeutronManager.get_instance) - - def test_core_plugin_supports_services(self): - cfg.CONF.set_override("core_plugin", - "neutron.tests.unit.test_neutron_manager." - "MultiServiceCorePlugin") - mgr = manager.NeutronManager.get_instance() - svc_plugins = mgr.get_service_plugins() - self.assertEqual(3, len(svc_plugins)) - self.assertIn(constants.CORE, svc_plugins.keys()) - self.assertIn(constants.LOADBALANCER, svc_plugins.keys()) - self.assertIn(constants.DUMMY, svc_plugins.keys()) - - def test_post_plugin_validation(self): - cfg.CONF.import_opt('dhcp_agents_per_network', - 'neutron.db.agentschedulers_db') - - self.assertIsNone(manager.validate_post_plugin_load()) - cfg.CONF.set_override('dhcp_agents_per_network', 2) - self.assertIsNone(manager.validate_post_plugin_load()) - cfg.CONF.set_override('dhcp_agents_per_network', 0) - self.assertIsNotNone(manager.validate_post_plugin_load()) - cfg.CONF.set_override('dhcp_agents_per_network', -1) - self.assertIsNotNone(manager.validate_post_plugin_load()) - - def test_pre_plugin_validation(self): - self.assertIsNotNone(manager.validate_pre_plugin_load()) - cfg.CONF.set_override('core_plugin', 'dummy.plugin') - self.assertIsNone(manager.validate_pre_plugin_load()) - - def test_manager_gathers_agent_notifiers_from_service_plugins(self): - cfg.CONF.set_override("service_plugins", - ["neutron.tests.unit.dummy_plugin." - "DummyServicePlugin"]) - cfg.CONF.set_override("core_plugin", - "neutron.tests.unit.test_neutron_manager." - "CorePluginWithAgentNotifiers") - expected = {'l3': 'l3_agent_notifier', - 'dhcp': 'dhcp_agent_notifier', - 'dummy': 'dummy_agent_notifier'} - core_plugin = manager.NeutronManager.get_plugin() - self.assertEqual(expected, core_plugin.agent_notifiers) diff --git a/neutron/tests/unit/test_provider_configuration.py b/neutron/tests/unit/test_provider_configuration.py deleted file mode 100644 index 17fb41fcd..000000000 --- a/neutron/tests/unit/test_provider_configuration.py +++ /dev/null @@ -1,201 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 VMware, Inc. All Rights Reserved. -# -# 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. - -from oslo.config import cfg - -from neutron.common import exceptions as n_exc - -from neutron.plugins.common import constants -from neutron.services import provider_configuration as provconf -from neutron.tests import base - - -class ParseServiceProviderConfigurationTestCase(base.BaseTestCase): - def test_default_service_provider_configuration(self): - providers = cfg.CONF.service_providers.service_provider - self.assertEqual(providers, []) - - def test_parse_single_service_provider_opt(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path'], - 'service_providers') - expected = {'service_type': constants.LOADBALANCER, - 'name': 'lbaas', - 'driver': 'driver_path', - 'default': False} - res = provconf.parse_service_provider_opt() - self.assertEqual(len(res), 1) - self.assertEqual(res, [expected]) - - def test_parse_single_default_service_provider_opt(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path:default'], - 'service_providers') - expected = {'service_type': constants.LOADBALANCER, - 'name': 'lbaas', - 'driver': 'driver_path', - 'default': True} - res = provconf.parse_service_provider_opt() - self.assertEqual(len(res), 1) - self.assertEqual(res, [expected]) - - def test_parse_multi_service_provider_opt(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - constants.LOADBALANCER + ':name1:path1', - constants.LOADBALANCER + - ':name2:path2:default'], - 'service_providers') - expected = {'service_type': constants.LOADBALANCER, - 'name': 'lbaas', - 'driver': 'driver_path', - 'default': False} - res = provconf.parse_service_provider_opt() - self.assertEqual(len(res), 3) - self.assertEqual(res, [expected, - {'service_type': constants.LOADBALANCER, - 'name': 'name1', - 'driver': 'path1', - 'default': False}, - {'service_type': constants.LOADBALANCER, - 'name': 'name2', - 'driver': 'path2', - 'default': True}]) - - def test_parse_service_provider_opt_not_allowed_raises(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - 'svc_type:name1:path1'], - 'service_providers') - self.assertRaises(n_exc.Invalid, provconf.parse_service_provider_opt) - - def test_parse_service_provider_invalid_format(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - 'svc_type:name1:path1:def'], - 'service_providers') - self.assertRaises(n_exc.Invalid, provconf.parse_service_provider_opt) - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':', - 'svc_type:name1:path1:def'], - 'service_providers') - self.assertRaises(n_exc.Invalid, provconf.parse_service_provider_opt) - - def test_parse_service_provider_name_too_long(self): - name = 'a' * 256 - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':' + name + ':driver_path', - 'svc_type:name1:path1:def'], - 'service_providers') - self.assertRaises(n_exc.Invalid, provconf.parse_service_provider_opt) - - -class ProviderConfigurationTestCase(base.BaseTestCase): - def setUp(self): - super(ProviderConfigurationTestCase, self).setUp() - - def test_ensure_driver_unique(self): - pconf = provconf.ProviderConfiguration([]) - pconf.providers[('svctype', 'name')] = {'driver': 'driver', - 'default': True} - self.assertRaises(n_exc.Invalid, - pconf._ensure_driver_unique, 'driver') - self.assertIsNone(pconf._ensure_driver_unique('another_driver1')) - - def test_ensure_default_unique(self): - pconf = provconf.ProviderConfiguration([]) - pconf.providers[('svctype', 'name')] = {'driver': 'driver', - 'default': True} - self.assertRaises(n_exc.Invalid, - pconf._ensure_default_unique, - 'svctype', True) - self.assertIsNone(pconf._ensure_default_unique('svctype', False)) - self.assertIsNone(pconf._ensure_default_unique('svctype1', True)) - self.assertIsNone(pconf._ensure_default_unique('svctype1', False)) - - def test_add_provider(self): - pconf = provconf.ProviderConfiguration([]) - prov = {'service_type': constants.LOADBALANCER, - 'name': 'name', - 'driver': 'path', - 'default': False} - pconf.add_provider(prov) - self.assertEqual(len(pconf.providers), 1) - self.assertEqual(pconf.providers.keys(), - [(constants.LOADBALANCER, 'name')]) - self.assertEqual(pconf.providers.values(), - [{'driver': 'path', 'default': False}]) - - def test_add_duplicate_provider(self): - pconf = provconf.ProviderConfiguration([]) - prov = {'service_type': constants.LOADBALANCER, - 'name': 'name', - 'driver': 'path', - 'default': False} - pconf.add_provider(prov) - self.assertRaises(n_exc.Invalid, pconf.add_provider, prov) - self.assertEqual(len(pconf.providers), 1) - - def test_get_service_providers(self): - provs = [{'service_type': constants.LOADBALANCER, - 'name': 'name', - 'driver': 'path', - 'default': False}, - {'service_type': constants.LOADBALANCER, - 'name': 'name2', - 'driver': 'path2', - 'default': False}, - {'service_type': 'st2', - 'name': 'name', - 'driver': 'driver', - 'default': True - }, - {'service_type': 'st3', - 'name': 'name2', - 'driver': 'driver2', - 'default': True}] - pconf = provconf.ProviderConfiguration(provs) - for prov in provs: - p = pconf.get_service_providers( - filters={'name': [prov['name']], - 'service_type': prov['service_type']} - ) - self.assertEqual(p, [prov]) - - def test_get_service_providers_with_fields(self): - provs = [{'service_type': constants.LOADBALANCER, - 'name': 'name', - 'driver': 'path', - 'default': False}, - {'service_type': constants.LOADBALANCER, - 'name': 'name2', - 'driver': 'path2', - 'default': False}] - pconf = provconf.ProviderConfiguration(provs) - for prov in provs: - p = pconf.get_service_providers( - filters={'name': [prov['name']], - 'service_type': prov['service_type']}, - fields=['name'] - ) - self.assertEqual(p, [{'name': prov['name']}]) diff --git a/neutron/tests/unit/test_quota_ext.py b/neutron/tests/unit/test_quota_ext.py deleted file mode 100644 index c95e4d3e0..000000000 --- a/neutron/tests/unit/test_quota_ext.py +++ /dev/null @@ -1,432 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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 sys - -import mock -from oslo.config import cfg -import testtools -import webtest - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.common import config -from neutron.common import exceptions -from neutron import context -from neutron.db import api as db -from neutron.db import quota_db -from neutron import quota -from neutron.tests import base -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import testlib_api - -TARGET_PLUGIN = ('neutron.plugins.linuxbridge.lb_neutron_plugin' - '.LinuxBridgePluginV2') - -_get_path = test_api_v2._get_path - - -class QuotaExtensionTestCase(testlib_api.WebTestCase): - - def setUp(self): - super(QuotaExtensionTestCase, self).setUp() - # Ensure existing ExtensionManager is not used - extensions.PluginAwareExtensionManager._instance = None - - # Save the global RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - - # Create the default configurations - self.config_parse() - - # Update the plugin and extensions path - self.setup_coreplugin(TARGET_PLUGIN) - cfg.CONF.set_override( - 'quota_items', - ['network', 'subnet', 'port', 'extra1'], - group='QUOTAS') - quota.QUOTAS = quota.QuotaEngine() - quota.register_resources_from_config() - self._plugin_patcher = mock.patch(TARGET_PLUGIN, autospec=True) - self.plugin = self._plugin_patcher.start() - self.plugin.return_value.supported_extension_aliases = ['quotas'] - # QUOTAS will register the items in conf when starting - # extra1 here is added later, so have to do it manually - quota.QUOTAS.register_resource_by_name('extra1') - ext_mgr = extensions.PluginAwareExtensionManager.get_instance() - db.configure_db() - app = config.load_paste_app('extensions_test_app') - ext_middleware = extensions.ExtensionMiddleware(app, ext_mgr=ext_mgr) - self.api = webtest.TestApp(ext_middleware) - - def tearDown(self): - self.api = None - self.plugin = None - db.clear_db() - - # Restore the global RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - super(QuotaExtensionTestCase, self).tearDown() - - -class QuotaExtensionDbTestCase(QuotaExtensionTestCase): - fmt = 'json' - - def setUp(self): - cfg.CONF.set_override( - 'quota_driver', - 'neutron.db.quota_db.DbQuotaDriver', - group='QUOTAS') - super(QuotaExtensionDbTestCase, self).setUp() - - def test_quotas_loaded_right(self): - res = self.api.get(_get_path('quotas', fmt=self.fmt)) - quota = self.deserialize(res) - self.assertEqual([], quota['quotas']) - self.assertEqual(200, res.status_int) - - def test_quotas_default_values(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - quota = self.deserialize(res) - self.assertEqual(10, quota['quota']['network']) - self.assertEqual(10, quota['quota']['subnet']) - self.assertEqual(50, quota['quota']['port']) - self.assertEqual(-1, quota['quota']['extra1']) - - def test_show_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', - is_admin=True)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - self.assertEqual(200, res.status_int) - quota = self.deserialize(res) - self.assertEqual(10, quota['quota']['network']) - self.assertEqual(10, quota['quota']['subnet']) - self.assertEqual(50, quota['quota']['port']) - - def test_show_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', - is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env, expect_errors=True) - self.assertEqual(403, res.status_int) - - def test_show_quotas_with_owner_tenant(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - self.assertEqual(200, res.status_int) - quota = self.deserialize(res) - self.assertEqual(10, quota['quota']['network']) - self.assertEqual(10, quota['quota']['subnet']) - self.assertEqual(50, quota['quota']['port']) - - def test_list_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - res = self.api.get(_get_path('quotas', fmt=self.fmt), - extra_environ=env) - self.assertEqual(200, res.status_int) - quota = self.deserialize(res) - self.assertEqual([], quota['quotas']) - - def test_list_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=False)} - res = self.api.get(_get_path('quotas', fmt=self.fmt), - extra_environ=env, expect_errors=True) - self.assertEqual(403, res.status_int) - - def test_update_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=False)} - quotas = {'quota': {'network': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env, - expect_errors=True) - self.assertEqual(403, res.status_int) - - def test_update_quotas_with_non_integer_returns_400(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - quotas = {'quota': {'network': 'abc'}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env, - expect_errors=True) - self.assertEqual(400, res.status_int) - - def test_update_quotas_with_negative_integer_returns_400(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - quotas = {'quota': {'network': -2}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env, - expect_errors=True) - self.assertEqual(400, res.status_int) - - def test_update_quotas_to_unlimited(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - quotas = {'quota': {'network': -1}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env, - expect_errors=False) - self.assertEqual(200, res.status_int) - - def test_update_quotas_exceeding_current_limit(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - quotas = {'quota': {'network': 120}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env, - expect_errors=False) - self.assertEqual(200, res.status_int) - - def test_update_quotas_with_non_support_resource_returns_400(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - quotas = {'quota': {'abc': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env, - expect_errors=True) - self.assertEqual(400, res.status_int) - - def test_update_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', - is_admin=True)} - quotas = {'quota': {'network': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env) - self.assertEqual(200, res.status_int) - env2 = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env2) - quota = self.deserialize(res) - self.assertEqual(100, quota['quota']['network']) - self.assertEqual(10, quota['quota']['subnet']) - self.assertEqual(50, quota['quota']['port']) - - def test_update_attributes(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', - is_admin=True)} - quotas = {'quota': {'extra1': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), extra_environ=env) - self.assertEqual(200, res.status_int) - env2 = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env2) - quota = self.deserialize(res) - self.assertEqual(100, quota['quota']['extra1']) - - def test_delete_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', - is_admin=True)} - res = self.api.delete(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - self.assertEqual(204, res.status_int) - - def test_delete_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=False)} - res = self.api.delete(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env, expect_errors=True) - self.assertEqual(403, res.status_int) - - def test_quotas_loaded_bad_returns_404(self): - try: - res = self.api.get(_get_path('quotas'), expect_errors=True) - self.assertEqual(404, res.status_int) - except Exception: - pass - - def test_quotas_limit_check(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - quotas = {'quota': {'network': 5}} - res = self.api.put(_get_path('quotas', id=tenant_id, - fmt=self.fmt), - self.serialize(quotas), extra_environ=env) - self.assertEqual(200, res.status_int) - quota.QUOTAS.limit_check(context.Context('', tenant_id), - tenant_id, - network=4) - - def test_quotas_limit_check_with_invalid_quota_value(self): - tenant_id = 'tenant_id1' - with testtools.ExpectedException(exceptions.InvalidQuotaValue): - quota.QUOTAS.limit_check(context.Context('', tenant_id), - tenant_id, - network=-2) - - def test_quotas_get_tenant_from_request_context(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=True)} - res = self.api.get(_get_path('quotas/tenant', fmt=self.fmt), - extra_environ=env) - self.assertEqual(200, res.status_int) - quota = self.deserialize(res) - self.assertEqual(quota['tenant']['tenant_id'], tenant_id) - - def test_quotas_get_tenant_from_empty_request_context_returns_400(self): - env = {'neutron.context': context.Context('', '', - is_admin=True)} - res = self.api.get(_get_path('quotas/tenant', fmt=self.fmt), - extra_environ=env, expect_errors=True) - self.assertEqual(400, res.status_int) - - -class QuotaExtensionDbTestCaseXML(QuotaExtensionDbTestCase): - fmt = 'xml' - - -class QuotaExtensionCfgTestCase(QuotaExtensionTestCase): - fmt = 'json' - - def setUp(self): - cfg.CONF.set_override( - 'quota_driver', - 'neutron.quota.ConfDriver', - group='QUOTAS') - super(QuotaExtensionCfgTestCase, self).setUp() - - def test_quotas_default_values(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - quota = self.deserialize(res) - self.assertEqual(10, quota['quota']['network']) - self.assertEqual(10, quota['quota']['subnet']) - self.assertEqual(50, quota['quota']['port']) - self.assertEqual(-1, quota['quota']['extra1']) - - def test_show_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', - is_admin=True)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env) - self.assertEqual(200, res.status_int) - - def test_show_quotas_without_admin_forbidden(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', - is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env, expect_errors=True) - self.assertEqual(403, res.status_int) - - def test_update_quotas_forbidden(self): - tenant_id = 'tenant_id1' - quotas = {'quota': {'network': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), - self.serialize(quotas), - expect_errors=True) - self.assertEqual(403, res.status_int) - - def test_delete_quotas_forbidden(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, - is_admin=False)} - res = self.api.delete(_get_path('quotas', id=tenant_id, fmt=self.fmt), - extra_environ=env, expect_errors=True) - self.assertEqual(403, res.status_int) - - -class QuotaExtensionCfgTestCaseXML(QuotaExtensionCfgTestCase): - fmt = 'xml' - - -class TestDbQuotaDriver(base.BaseTestCase): - """Test for neutron.db.quota_db.DbQuotaDriver.""" - - def test_get_tenant_quotas_arg(self): - """Call neutron.db.quota_db.DbQuotaDriver._get_quotas.""" - - driver = quota_db.DbQuotaDriver() - ctx = context.Context('', 'bar') - - foo_quotas = {'network': 5} - default_quotas = {'network': 10} - target_tenant = 'foo' - - with mock.patch.object(quota_db.DbQuotaDriver, - 'get_tenant_quotas', - return_value=foo_quotas) as get_tenant_quotas: - - quotas = driver._get_quotas(ctx, - target_tenant, - default_quotas, - ['network']) - - self.assertEqual(quotas, foo_quotas) - get_tenant_quotas.assert_called_once_with(ctx, - default_quotas, - target_tenant) - - -class TestQuotaDriverLoad(base.BaseTestCase): - def setUp(self): - super(TestQuotaDriverLoad, self).setUp() - # Make sure QuotaEngine is reinitialized in each test. - quota.QUOTAS._driver = None - - def _test_quota_driver(self, cfg_driver, loaded_driver, - with_quota_db_module=True): - cfg.CONF.set_override('quota_driver', cfg_driver, group='QUOTAS') - with mock.patch.dict(sys.modules, {}): - if (not with_quota_db_module and - 'neutron.db.quota_db' in sys.modules): - del sys.modules['neutron.db.quota_db'] - driver = quota.QUOTAS.get_driver() - self.assertEqual(loaded_driver, driver.__class__.__name__) - - def test_quota_db_driver_with_quotas_table(self): - self._test_quota_driver('neutron.db.quota_db.DbQuotaDriver', - 'DbQuotaDriver', True) - - def test_quota_db_driver_fallback_conf_driver(self): - self._test_quota_driver('neutron.db.quota_db.DbQuotaDriver', - 'ConfDriver', False) - - def test_quota_conf_driver(self): - self._test_quota_driver('neutron.quota.ConfDriver', - 'ConfDriver', True) diff --git a/neutron/tests/unit/test_routerserviceinsertion.py b/neutron/tests/unit/test_routerserviceinsertion.py deleted file mode 100644 index d84d0db6e..000000000 --- a/neutron/tests/unit/test_routerserviceinsertion.py +++ /dev/null @@ -1,490 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 VMware, Inc. All Rights Reserved. -# -# 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. - -from oslo.config import cfg -import webob.exc as webexc - -import neutron -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.api.v2 import router -from neutron.common import config -from neutron import context as q_context -from neutron.db import api as db -from neutron.db import db_base_plugin_v2 -from neutron.db import l3_db -from neutron.db.loadbalancer import loadbalancer_db as lb_db -from neutron.db import routedserviceinsertion_db as rsi_db -from neutron.db import routerservicetype_db as rst_db -from neutron.db import servicetype_db as st_db -from neutron.extensions import routedserviceinsertion as rsi -from neutron.extensions import routerservicetype as rst -from neutron.plugins.common import constants -from neutron.tests import base -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import testlib_api -from neutron import wsgi - -_uuid = test_api_v2._uuid -_get_path = test_api_v2._get_path -extensions_path = ':'.join(neutron.extensions.__path__) - - -class RouterServiceInsertionTestPlugin( - rst_db.RouterServiceTypeDbMixin, - rsi_db.RoutedServiceInsertionDbMixin, - st_db.ServiceTypeManager, - lb_db.LoadBalancerPluginDb, - l3_db.L3_NAT_db_mixin, - db_base_plugin_v2.NeutronDbPluginV2): - - supported_extension_aliases = [ - "router", "router-service-type", "routed-service-insertion", - "service-type", "lbaas" - ] - - def create_router(self, context, router): - with context.session.begin(subtransactions=True): - r = super(RouterServiceInsertionTestPlugin, self).create_router( - context, router) - service_type_id = router['router'].get(rst.SERVICE_TYPE_ID) - if service_type_id is not None: - r[rst.SERVICE_TYPE_ID] = service_type_id - self._process_create_router_service_type_id( - context, r) - return r - - def get_router(self, context, id, fields=None): - with context.session.begin(subtransactions=True): - r = super(RouterServiceInsertionTestPlugin, self).get_router( - context, id, fields) - rsbind = self._get_router_service_type_id_binding(context, id) - if rsbind: - r[rst.SERVICE_TYPE_ID] = rsbind['service_type_id'] - return r - - def delete_router(self, context, id): - with context.session.begin(subtransactions=True): - super(RouterServiceInsertionTestPlugin, self).delete_router( - context, id) - rsbind = self._get_router_service_type_id_binding(context, id) - if rsbind: - raise Exception('Router service-type binding is not deleted') - - def create_resource(self, res, context, resource, model): - with context.session.begin(subtransactions=True): - method_name = "create_{0}".format(res) - method = getattr(super(RouterServiceInsertionTestPlugin, self), - method_name) - o = method(context, resource) - router_id = resource[res].get(rsi.ROUTER_ID) - if router_id is not None: - o[rsi.ROUTER_ID] = router_id - self._process_create_resource_router_id( - context, o, model) - return o - - def get_resource(self, res, context, id, fields, model): - method_name = "get_{0}".format(res) - method = getattr(super(RouterServiceInsertionTestPlugin, self), - method_name) - o = method(context, id, fields) - if fields is None or rsi.ROUTER_ID in fields: - rsbind = self._get_resource_router_id_binding( - context, model, id) - if rsbind: - o[rsi.ROUTER_ID] = rsbind['router_id'] - return o - - def delete_resource(self, res, context, id, model): - method_name = "delete_{0}".format(res) - with context.session.begin(subtransactions=True): - method = getattr(super(RouterServiceInsertionTestPlugin, self), - method_name) - method(context, id) - self._delete_resource_router_id_binding(context, id, model) - if self._get_resource_router_id_binding(context, model, id): - raise Exception("{0}-router binding is not deleted".format(res)) - - def create_pool(self, context, pool): - return self.create_resource('pool', context, pool, lb_db.Pool) - - def get_pool(self, context, id, fields=None): - return self.get_resource('pool', context, id, fields, lb_db.Pool) - - def delete_pool(self, context, id): - return self.delete_resource('pool', context, id, lb_db.Pool) - - def create_health_monitor(self, context, health_monitor): - return self.create_resource('health_monitor', context, health_monitor, - lb_db.HealthMonitor) - - def get_health_monitor(self, context, id, fields=None): - return self.get_resource('health_monitor', context, id, fields, - lb_db.HealthMonitor) - - def delete_health_monitor(self, context, id): - return self.delete_resource('health_monitor', context, id, - lb_db.HealthMonitor) - - def create_vip(self, context, vip): - return self.create_resource('vip', context, vip, lb_db.Vip) - - def get_vip(self, context, id, fields=None): - return self.get_resource( - 'vip', context, id, fields, lb_db.Vip) - - def delete_vip(self, context, id): - return self.delete_resource('vip', context, id, lb_db.Vip) - - def stats(self, context, pool_id): - pass - - -class RouterServiceInsertionTestCase(base.BaseTestCase): - def setUp(self): - super(RouterServiceInsertionTestCase, self).setUp() - plugin = ( - "neutron.tests.unit.test_routerserviceinsertion." - "RouterServiceInsertionTestPlugin" - ) - - # point config file to: neutron/tests/etc/neutron.conf.test - self.config_parse() - - #just stubbing core plugin with LoadBalancer plugin - self.setup_coreplugin(plugin) - cfg.CONF.set_override('service_plugins', []) - cfg.CONF.set_override('quota_router', -1, group='QUOTAS') - - # Ensure existing ExtensionManager is not used - - ext_mgr = extensions.PluginAwareExtensionManager( - extensions_path, - {constants.LOADBALANCER: RouterServiceInsertionTestPlugin()} - ) - extensions.PluginAwareExtensionManager._instance = ext_mgr - router.APIRouter() - - app = config.load_paste_app('extensions_test_app') - self._api = extensions.ExtensionMiddleware(app, ext_mgr=ext_mgr) - - self._tenant_id = "8c70909f-b081-452d-872b-df48e6c355d1" - - self._service_type_id = _uuid() - - self._setup_core_resources() - - # FIXME (markmcclain): The test setup makes it difficult to add core - # via the api. In the interim we'll create directly using the plugin with - # the side effect of polluting the fixture database until tearDown. - - def tearDown(self): - self.api = None - db.clear_db() - super(RouterServiceInsertionTestCase, self).tearDown() - - def _setup_core_resources(self): - core_plugin = neutron.manager.NeutronManager.get_plugin() - - self._network = core_plugin.create_network( - q_context.get_admin_context(), - { - 'network': - { - 'tenant_id': self._tenant_id, - 'name': 'test net', - 'admin_state_up': True, - 'shared': False, - } - } - ) - - self._subnet = core_plugin.create_subnet( - q_context.get_admin_context(), - { - 'subnet': - { - 'network_id': self._network['id'], - 'name': 'test subnet', - 'cidr': '192.168.1.0/24', - 'ip_version': 4, - 'gateway_ip': '192.168.1.1', - 'allocation_pools': attributes.ATTR_NOT_SPECIFIED, - 'dns_nameservers': attributes.ATTR_NOT_SPECIFIED, - 'host_routes': attributes.ATTR_NOT_SPECIFIED, - 'enable_dhcp': True, - } - } - ) - - self._subnet_id = self._subnet['id'] - - def _do_request(self, method, path, data=None, params=None, action=None): - content_type = 'application/json' - body = None - if data is not None: # empty dict is valid - body = wsgi.Serializer().serialize(data, content_type) - - req = testlib_api.create_request( - path, body, content_type, - method, query_string=params) - res = req.get_response(self._api) - if res.status_code >= 400: - raise webexc.HTTPClientError(detail=res.body, code=res.status_code) - if res.status_code != webexc.HTTPNoContent.code: - return res.json - - def _router_create(self, service_type_id=None): - data = { - "router": { - "tenant_id": self._tenant_id, - "name": "test", - "admin_state_up": True, - "service_type_id": service_type_id, - } - } - - res = self._do_request('POST', _get_path('routers'), data) - return res['router'] - - def test_router_create_no_service_type_id(self): - router = self._router_create() - self.assertIsNone(router.get('service_type_id')) - - def test_router_create_with_service_type_id(self): - router = self._router_create(self._service_type_id) - self.assertEqual(router['service_type_id'], self._service_type_id) - - def test_router_get(self): - router = self._router_create(self._service_type_id) - res = self._do_request('GET', - _get_path('routers/{0}'.format(router['id']))) - self.assertEqual(res['router']['service_type_id'], - self._service_type_id) - - def _test_router_update(self, update_service_type_id): - router = self._router_create(self._service_type_id) - router_id = router['id'] - new_name = _uuid() - data = { - "router": { - "name": new_name, - "admin_state_up": router['admin_state_up'], - } - } - if update_service_type_id: - data["router"]["service_type_id"] = _uuid() - with testlib_api.ExpectedException( - webexc.HTTPClientError) as ctx_manager: - res = self._do_request( - 'PUT', _get_path('routers/{0}'.format(router_id)), data) - self.assertEqual(ctx_manager.exception.code, 400) - else: - res = self._do_request( - 'PUT', _get_path('routers/{0}'.format(router_id)), data) - res = self._do_request( - 'GET', _get_path('routers/{0}'.format(router['id']))) - self.assertEqual(res['router']['name'], new_name) - - def test_router_update_with_service_type_id(self): - self._test_router_update(True) - - def test_router_update_without_service_type_id(self): - self._test_router_update(False) - - def test_router_delete(self): - router = self._router_create(self._service_type_id) - self._do_request( - 'DELETE', _get_path('routers/{0}'.format(router['id']))) - - def _test_lb_setup(self): - router = self._router_create(self._service_type_id) - self._router_id = router['id'] - - def _test_pool_setup(self): - self._test_lb_setup() - - def _test_health_monitor_setup(self): - self._test_lb_setup() - - def _test_vip_setup(self): - self._test_pool_setup() - pool = self._pool_create(self._router_id) - self._pool_id = pool['id'] - - def _create_resource(self, res, data): - resp = self._do_request('POST', _get_path('lb/{0}s'.format(res)), data) - return resp[res] - - def _pool_create(self, router_id=None): - data = { - "pool": { - "tenant_id": self._tenant_id, - "name": "test", - "protocol": "HTTP", - "subnet_id": self._subnet_id, - "lb_method": "ROUND_ROBIN", - "router_id": router_id - } - } - - return self._create_resource('pool', data) - - def _pool_update_attrs(self, pool): - uattr = {} - fields = [ - 'name', 'description', 'lb_method', - 'health_monitors', 'admin_state_up' - ] - for field in fields: - uattr[field] = pool[field] - return uattr - - def _health_monitor_create(self, router_id=None): - data = { - "health_monitor": { - "tenant_id": self._tenant_id, - "type": "HTTP", - "delay": 1, - "timeout": 1, - "max_retries": 1, - "router_id": router_id - } - } - - return self._create_resource('health_monitor', data) - - def _health_monitor_update_attrs(self, hm): - uattr = {} - fields = ['delay', 'timeout', 'max_retries'] - for field in fields: - uattr[field] = hm[field] - return uattr - - def _vip_create(self, router_id=None): - data = { - "vip": { - "tenant_id": self._tenant_id, - "name": "test", - "protocol": "HTTP", - "protocol_port": 80, - "subnet_id": self._subnet_id, - "pool_id": self._pool_id, - "address": "192.168.1.102", - "connection_limit": 100, - "admin_state_up": True, - "router_id": router_id - } - } - - return self._create_resource('vip', data) - - def _vip_update_attrs(self, vip): - uattr = {} - fields = [ - 'name', 'description', 'pool_id', 'connection_limit', - 'admin_state_up' - ] - for field in fields: - uattr[field] = vip[field] - return uattr - - def _test_resource_create(self, res): - getattr(self, "_test_{0}_setup".format(res))() - obj = getattr(self, "_{0}_create".format(res))(self._router_id) - self.assertEqual(obj['router_id'], self._router_id) - - def _test_resource_update(self, res, update_router_id, - update_attr, update_value): - getattr(self, "_test_{0}_setup".format(res))() - obj = getattr(self, "_{0}_create".format(res))(self._router_id) - uattrs = getattr(self, "_{0}_update_attrs".format(res))(obj) - uattrs[update_attr] = update_value - data = {res: uattrs} - if update_router_id: - uattrs['router_id'] = self._router_id - with testlib_api.ExpectedException( - webexc.HTTPClientError) as ctx_manager: - self._do_request( - 'PUT', - _get_path('lb/{0}s/{1}'.format(res, obj['id'])), data) - self.assertEqual(ctx_manager.exception.code, 400) - else: - self._do_request( - 'PUT', - _get_path('lb/{0}s/{1}'.format(res, obj['id'])), data) - updated = self._do_request( - 'GET', - _get_path('lb/{0}s/{1}'.format(res, obj['id']))) - self.assertEqual(updated[res][update_attr], update_value) - - def _test_resource_delete(self, res, with_router_id): - getattr(self, "_test_{0}_setup".format(res))() - - func = getattr(self, "_{0}_create".format(res)) - - if with_router_id: - obj = func(self._router_id) - else: - obj = func() - self._do_request( - 'DELETE', _get_path('lb/{0}s/{1}'.format(res, obj['id']))) - - def test_pool_create(self): - self._test_resource_create('pool') - - def test_pool_update_with_router_id(self): - self._test_resource_update('pool', True, 'name', _uuid()) - - def test_pool_update_without_router_id(self): - self._test_resource_update('pool', False, 'name', _uuid()) - - def test_pool_delete_with_router_id(self): - self._test_resource_delete('pool', True) - - def test_pool_delete_without_router_id(self): - self._test_resource_delete('pool', False) - - def test_health_monitor_create(self): - self._test_resource_create('health_monitor') - - def test_health_monitor_update_with_router_id(self): - self._test_resource_update('health_monitor', True, 'timeout', 2) - - def test_health_monitor_update_without_router_id(self): - self._test_resource_update('health_monitor', False, 'timeout', 2) - - def test_health_monitor_delete_with_router_id(self): - self._test_resource_delete('health_monitor', True) - - def test_health_monitor_delete_without_router_id(self): - self._test_resource_delete('health_monitor', False) - - def test_vip_create(self): - self._test_resource_create('vip') - - def test_vip_update_with_router_id(self): - self._test_resource_update('vip', True, 'name', _uuid()) - - def test_vip_update_without_router_id(self): - self._test_resource_update('vip', False, 'name', _uuid()) - - def test_vip_delete_with_router_id(self): - self._test_resource_delete('vip', True) - - def test_vip_delete_without_router_id(self): - self._test_resource_delete('vip', False) diff --git a/neutron/tests/unit/test_security_groups_rpc.py b/neutron/tests/unit/test_security_groups_rpc.py deleted file mode 100644 index 12b6f6ee9..000000000 --- a/neutron/tests/unit/test_security_groups_rpc.py +++ /dev/null @@ -1,2047 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2012, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# 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 contextlib - -import mock -from oslo.config import cfg -from testtools import matchers -import webob.exc - -from neutron.agent.common import config -from neutron.agent import firewall as firewall_base -from neutron.agent.linux import iptables_manager -from neutron.agent import rpc as agent_rpc -from neutron.agent import securitygroups_rpc as sg_rpc -from neutron.common import constants as const -from neutron.common import ipv6_utils as ipv6 -from neutron.common import rpc_compat -from neutron import context -from neutron.db import securitygroups_rpc_base as sg_db_rpc -from neutron.extensions import allowedaddresspairs as addr_pair -from neutron.extensions import securitygroup as ext_sg -from neutron import manager -from neutron.tests import base -from neutron.tests.unit import test_extension_security_group as test_sg - - -FAKE_PREFIX = {const.IPv4: '10.0.0.0/24', - const.IPv6: '2001:db8::/64'} -FAKE_IP = {const.IPv4: '10.0.0.1', - const.IPv6: 'fe80::1', - 'IPv6_GLOBAL': '2001:0db8::1', - 'IPv6_LLA': 'fe80::123'} - - -class FakeSGCallback(sg_db_rpc.SecurityGroupServerRpcCallbackMixin): - def get_port_from_device(self, device): - device = self.devices.get(device) - if device: - device['security_group_rules'] = [] - device['security_group_source_groups'] = [] - device['fixed_ips'] = [ip['ip_address'] - for ip in device['fixed_ips']] - return device - - -class SGServerRpcCallBackMixinTestCase(test_sg.SecurityGroupDBTestCase): - def setUp(self, plugin=None): - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - super(SGServerRpcCallBackMixinTestCase, self).setUp(plugin) - self.rpc = FakeSGCallback() - - def test_security_group_rules_for_devices_ipv4_ingress(self): - fake_prefix = FAKE_PREFIX[const.IPv4] - with self.network() as n: - with contextlib.nested(self.subnet(n), - self.security_group()) as (subnet_v4, - sg1): - sg1_id = sg1['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_TCP, '22', - '22') - rule2 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_TCP, '23', - '23', fake_prefix) - rules = { - 'security_group_rules': [rule1['security_group_rule'], - rule2['security_group_rule']]} - res = self._create_security_group_rule(self.fmt, rules) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - res1 = self._create_port( - self.fmt, n['network']['id'], - security_groups=[sg1_id]) - ports_rest1 = self.deserialize(self.fmt, res1) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv4, - 'port_range_max': 22, - 'security_group_id': sg1_id, - 'port_range_min': 22}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv4, - 'port_range_max': 23, 'security_group_id': sg1_id, - 'port_range_min': 23, - 'source_ip_prefix': fake_prefix}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - - def test_security_group_rules_for_devices_ipv4_ingress_addr_pair(self): - plugin_obj = manager.NeutronManager.get_plugin() - if ('allowed-address-pairs' - not in plugin_obj.supported_extension_aliases): - self.skipTest("Test depeneds on allowed-address-pairs extension") - fake_prefix = FAKE_PREFIX['IPv4'] - with self.network() as n: - with contextlib.nested(self.subnet(n), - self.security_group()) as (subnet_v4, - sg1): - sg1_id = sg1['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'ingress', 'tcp', '22', - '22') - rule2 = self._build_security_group_rule( - sg1_id, - 'ingress', 'tcp', '23', - '23', fake_prefix) - rules = { - 'security_group_rules': [rule1['security_group_rule'], - rule2['security_group_rule']]} - res = self._create_security_group_rule(self.fmt, rules) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, 201) - address_pairs = [{'mac_address': '00:00:00:00:00:01', - 'ip_address': '10.0.0.0/24'}, - {'mac_address': '00:00:00:00:00:01', - 'ip_address': '11.0.0.1'}] - res1 = self._create_port( - self.fmt, n['network']['id'], - security_groups=[sg1_id], - arg_list=(addr_pair.ADDRESS_PAIRS,), - allowed_address_pairs=address_pairs) - ports_rest1 = self.deserialize(self.fmt, res1) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': 'IPv4', - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': 'IPv6', - 'security_group_id': sg1_id}, - {'direction': 'ingress', - 'protocol': 'tcp', 'ethertype': 'IPv4', - 'port_range_max': 22, - 'security_group_id': sg1_id, - 'port_range_min': 22}, - {'direction': 'ingress', 'protocol': 'tcp', - 'ethertype': 'IPv4', - 'port_range_max': 23, 'security_group_id': sg1_id, - 'port_range_min': 23, - 'source_ip_prefix': fake_prefix}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self.assertEqual(port_rpc['allowed_address_pairs'], - address_pairs) - self._delete('ports', port_id1) - - def test_security_group_rules_for_devices_ipv4_egress(self): - fake_prefix = FAKE_PREFIX[const.IPv4] - with self.network() as n: - with contextlib.nested(self.subnet(n), - self.security_group()) as (subnet_v4, - sg1): - sg1_id = sg1['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'egress', const.PROTO_NAME_TCP, '22', - '22') - rule2 = self._build_security_group_rule( - sg1_id, - 'egress', const.PROTO_NAME_UDP, '23', - '23', fake_prefix) - rules = { - 'security_group_rules': [rule1['security_group_rule'], - rule2['security_group_rule']]} - res = self._create_security_group_rule(self.fmt, rules) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - res1 = self._create_port( - self.fmt, n['network']['id'], - security_groups=[sg1_id]) - ports_rest1 = self.deserialize(self.fmt, res1) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'egress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv4, - 'port_range_max': 22, - 'security_group_id': sg1_id, - 'port_range_min': 22}, - {'direction': 'egress', - 'protocol': const.PROTO_NAME_UDP, - 'ethertype': const.IPv4, - 'port_range_max': 23, 'security_group_id': sg1_id, - 'port_range_min': 23, - 'dest_ip_prefix': fake_prefix}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - - def test_security_group_rules_for_devices_ipv4_source_group(self): - - with self.network() as n: - with contextlib.nested(self.subnet(n), - self.security_group(), - self.security_group()) as (subnet_v4, - sg1, - sg2): - sg1_id = sg1['security_group']['id'] - sg2_id = sg2['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_TCP, '24', - '25', remote_group_id=sg2['security_group']['id']) - rules = { - 'security_group_rules': [rule1['security_group_rule']]} - res = self._create_security_group_rule(self.fmt, rules) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - res1 = self._create_port( - self.fmt, n['network']['id'], - security_groups=[sg1_id, - sg2_id]) - ports_rest1 = self.deserialize(self.fmt, res1) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - - res2 = self._create_port( - self.fmt, n['network']['id'], - security_groups=[sg2_id]) - ports_rest2 = self.deserialize(self.fmt, res2) - port_id2 = ports_rest2['port']['id'] - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg2_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg2_id}, - {'direction': u'ingress', - 'source_ip_prefix': u'10.0.0.3/32', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv4, - 'port_range_max': 25, 'port_range_min': 24, - 'remote_group_id': sg2_id, - 'security_group_id': sg1_id}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - self._delete('ports', port_id2) - - def test_security_group_rules_for_devices_ipv6_ingress(self): - fake_prefix = FAKE_PREFIX[const.IPv6] - fake_gateway = FAKE_IP[const.IPv6] - with self.network() as n: - with contextlib.nested(self.subnet(n, - gateway_ip=fake_gateway, - cidr=fake_prefix, - ip_version=6), - self.security_group()) as (subnet_v6, - sg1): - sg1_id = sg1['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_TCP, '22', - '22', - ethertype=const.IPv6) - rule2 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_UDP, '23', - '23', fake_prefix, - ethertype=const.IPv6) - rules = { - 'security_group_rules': [rule1['security_group_rule'], - rule2['security_group_rule']]} - res = self._create_security_group_rule(self.fmt, rules) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - - res1 = self._create_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], - security_groups=[sg1_id]) - ports_rest1 = self.deserialize(self.fmt, res1) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv6, - 'port_range_max': 22, - 'security_group_id': sg1_id, - 'port_range_min': 22}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_UDP, - 'ethertype': const.IPv6, - 'port_range_max': 23, - 'security_group_id': sg1_id, - 'port_range_min': 23, - 'source_ip_prefix': fake_prefix}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_ICMP_V6, - 'ethertype': const.IPv6, - 'source_ip_prefix': fake_gateway, - 'source_port_range_min': const.ICMPV6_TYPE_RA}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - - def test_security_group_ra_rules_for_devices_ipv6_gateway_global(self): - fake_prefix = FAKE_PREFIX[const.IPv6] - fake_gateway = FAKE_IP['IPv6_GLOBAL'] - with self.network() as n: - with contextlib.nested(self.subnet(n, - gateway_ip=fake_gateway, - cidr=fake_prefix, - ip_version=6, - ipv6_ra_mode=const.IPV6_SLAAC), - self.security_group()) as (subnet_v6, - sg1): - sg1_id = sg1['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_TCP, '22', - '22', - ethertype=const.IPv6) - rules = { - 'security_group_rules': [rule1['security_group_rule']]} - self._make_security_group_rule(self.fmt, rules) - - # Create gateway port - gateway_res = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id'], - 'ip_address': fake_gateway}], - device_owner='network:router_interface') - gateway_mac = gateway_res['port']['mac_address'] - gateway_port_id = gateway_res['port']['id'] - gateway_lla_ip = str(ipv6.get_ipv6_addr_by_EUI64( - const.IPV6_LLA_PREFIX, - gateway_mac)) - - ports_rest1 = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], - security_groups=[sg1_id]) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv6, - 'port_range_max': 22, - 'security_group_id': sg1_id, - 'port_range_min': 22}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_ICMP_V6, - 'ethertype': const.IPv6, - 'source_ip_prefix': gateway_lla_ip, - 'source_port_range_min': const.ICMPV6_TYPE_RA}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - # Note(xuhanp): remove gateway port's fixed_ips or gateway port - # deletion will be prevented. - data = {'port': {'fixed_ips': []}} - req = self.new_update_request('ports', data, gateway_port_id) - self.deserialize(self.fmt, req.get_response(self.api)) - self._delete('ports', gateway_port_id) - - def test_security_group_rule_for_device_ipv6_multi_router_interfaces(self): - fake_prefix = FAKE_PREFIX[const.IPv6] - fake_gateway = FAKE_IP['IPv6_GLOBAL'] - with self.network() as n: - with contextlib.nested(self.subnet(n, - gateway_ip=fake_gateway, - cidr=fake_prefix, - ip_version=6, - ipv6_ra_mode=const.IPV6_SLAAC), - self.security_group()) as (subnet_v6, - sg1): - sg1_id = sg1['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_TCP, '22', - '22', - ethertype=const.IPv6) - rules = { - 'security_group_rules': [rule1['security_group_rule']]} - self._make_security_group_rule(self.fmt, rules) - - # Create gateway port - gateway_res = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id'], - 'ip_address': fake_gateway}], - device_owner='network:router_interface') - gateway_mac = gateway_res['port']['mac_address'] - gateway_port_id = gateway_res['port']['id'] - gateway_lla_ip = str(ipv6.get_ipv6_addr_by_EUI64( - const.IPV6_LLA_PREFIX, - gateway_mac)) - # Create another router interface port - interface_res = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], - device_owner='network:router_interface') - interface_port_id = interface_res['port']['id'] - - ports_rest1 = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], - security_groups=[sg1_id]) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv6, - 'port_range_max': 22, - 'security_group_id': sg1_id, - 'port_range_min': 22}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_ICMP_V6, - 'ethertype': const.IPv6, - 'source_ip_prefix': gateway_lla_ip, - 'source_port_range_min': const.ICMPV6_TYPE_RA}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - data = {'port': {'fixed_ips': []}} - req = self.new_update_request('ports', data, gateway_port_id) - self.deserialize(self.fmt, req.get_response(self.api)) - req = self.new_update_request('ports', data, interface_port_id) - self.deserialize(self.fmt, req.get_response(self.api)) - self._delete('ports', gateway_port_id) - self._delete('ports', interface_port_id) - - def test_security_group_ra_rules_for_devices_ipv6_gateway_lla(self): - fake_prefix = FAKE_PREFIX[const.IPv6] - fake_gateway = FAKE_IP['IPv6_LLA'] - with self.network() as n: - with contextlib.nested(self.subnet(n, - gateway_ip=fake_gateway, - cidr=fake_prefix, - ip_version=6, - ipv6_ra_mode=const.IPV6_SLAAC), - self.security_group()) as (subnet_v6, - sg1): - sg1_id = sg1['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_TCP, '22', - '22', - ethertype=const.IPv6) - rules = { - 'security_group_rules': [rule1['security_group_rule']]} - self._make_security_group_rule(self.fmt, rules) - - ports_rest1 = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], - security_groups=[sg1_id]) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv6, - 'port_range_max': 22, - 'security_group_id': sg1_id, - 'port_range_min': 22}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_ICMP_V6, - 'ethertype': const.IPv6, - 'source_ip_prefix': fake_gateway, - 'source_port_range_min': const.ICMPV6_TYPE_RA}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - - def test_security_group_ra_rules_for_devices_ipv6_no_gateway_port(self): - fake_prefix = FAKE_PREFIX[const.IPv6] - with self.network() as n: - with contextlib.nested(self.subnet(n, - gateway_ip=None, - cidr=fake_prefix, - ip_version=6, - ipv6_ra_mode=const.IPV6_SLAAC), - self.security_group()) as (subnet_v6, - sg1): - sg1_id = sg1['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_TCP, '22', - '22', - ethertype=const.IPv6) - rules = { - 'security_group_rules': [rule1['security_group_rule']]} - self._make_security_group_rule(self.fmt, rules) - - ports_rest1 = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], - security_groups=[sg1_id]) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv6, - 'port_range_max': 22, - 'security_group_id': sg1_id, - 'port_range_min': 22}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - - def test_security_group_rules_for_devices_ipv6_egress(self): - fake_prefix = FAKE_PREFIX[const.IPv6] - fake_gateway = FAKE_IP[const.IPv6] - with self.network() as n: - with contextlib.nested(self.subnet(n, - gateway_ip=fake_gateway, - cidr=fake_prefix, - ip_version=6), - self.security_group()) as (subnet_v6, - sg1): - sg1_id = sg1['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'egress', const.PROTO_NAME_TCP, '22', - '22', - ethertype=const.IPv6) - rule2 = self._build_security_group_rule( - sg1_id, - 'egress', const.PROTO_NAME_UDP, '23', - '23', fake_prefix, - ethertype=const.IPv6) - rules = { - 'security_group_rules': [rule1['security_group_rule'], - rule2['security_group_rule']]} - self._make_security_group_rule(self.fmt, rules) - - ports_rest1 = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], - security_groups=[sg1_id]) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'egress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv6, - 'port_range_max': 22, - 'security_group_id': sg1_id, - 'port_range_min': 22}, - {'direction': 'egress', - 'protocol': const.PROTO_NAME_UDP, - 'ethertype': const.IPv6, - 'port_range_max': 23, - 'security_group_id': sg1_id, - 'port_range_min': 23, - 'dest_ip_prefix': fake_prefix}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_ICMP_V6, - 'ethertype': const.IPv6, - 'source_ip_prefix': fake_gateway, - 'source_port_range_min': const.ICMPV6_TYPE_RA}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - - def test_security_group_rules_for_devices_ipv6_source_group(self): - fake_prefix = FAKE_PREFIX[const.IPv6] - fake_gateway = FAKE_IP[const.IPv6] - with self.network() as n: - with contextlib.nested(self.subnet(n, - gateway_ip=fake_gateway, - cidr=fake_prefix, - ip_version=6), - self.security_group(), - self.security_group()) as (subnet_v6, - sg1, - sg2): - sg1_id = sg1['security_group']['id'] - sg2_id = sg2['security_group']['id'] - rule1 = self._build_security_group_rule( - sg1_id, - 'ingress', const.PROTO_NAME_TCP, '24', - '25', - ethertype=const.IPv6, - remote_group_id=sg2['security_group']['id']) - rules = { - 'security_group_rules': [rule1['security_group_rule']]} - self._make_security_group_rule(self.fmt, rules) - - ports_rest1 = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], - security_groups=[sg1_id, - sg2_id]) - port_id1 = ports_rest1['port']['id'] - self.rpc.devices = {port_id1: ports_rest1['port']} - devices = [port_id1, 'no_exist_device'] - - ports_rest2 = self._make_port( - self.fmt, n['network']['id'], - fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}], - security_groups=[sg2_id]) - port_id2 = ports_rest2['port']['id'] - - ctx = context.get_admin_context() - ports_rpc = self.rpc.security_group_rules_for_devices( - ctx, devices=devices) - port_rpc = ports_rpc[port_id1] - expected = [{'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg1_id}, - {'direction': 'egress', 'ethertype': const.IPv4, - 'security_group_id': sg2_id}, - {'direction': 'egress', 'ethertype': const.IPv6, - 'security_group_id': sg2_id}, - {'direction': 'ingress', - 'source_ip_prefix': '2001:db8::2/128', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv6, - 'port_range_max': 25, 'port_range_min': 24, - 'remote_group_id': sg2_id, - 'security_group_id': sg1_id}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_ICMP_V6, - 'ethertype': const.IPv6, - 'source_ip_prefix': fake_gateway, - 'source_port_range_min': const.ICMPV6_TYPE_RA}, - ] - self.assertEqual(port_rpc['security_group_rules'], - expected) - self._delete('ports', port_id1) - self._delete('ports', port_id2) - - -class SGServerRpcCallBackMixinTestCaseXML(SGServerRpcCallBackMixinTestCase): - fmt = 'xml' - - -class SGAgentRpcCallBackMixinTestCase(base.BaseTestCase): - def setUp(self): - super(SGAgentRpcCallBackMixinTestCase, self).setUp() - self.rpc = sg_rpc.SecurityGroupAgentRpcCallbackMixin() - self.rpc.sg_agent = mock.Mock() - - def test_security_groups_rule_updated(self): - self.rpc.security_groups_rule_updated(None, - security_groups=['fake_sgid']) - self.rpc.sg_agent.assert_has_calls( - [mock.call.security_groups_rule_updated(['fake_sgid'])]) - - def test_security_groups_member_updated(self): - self.rpc.security_groups_member_updated(None, - security_groups=['fake_sgid']) - self.rpc.sg_agent.assert_has_calls( - [mock.call.security_groups_member_updated(['fake_sgid'])]) - - def test_security_groups_provider_updated(self): - self.rpc.security_groups_provider_updated(None) - self.rpc.sg_agent.assert_has_calls( - [mock.call.security_groups_provider_updated()]) - - -class SecurityGroupAgentRpcTestCaseForNoneDriver(base.BaseTestCase): - def test_init_firewall_with_none_driver(self): - cfg.CONF.set_override( - 'enable_security_group', False, - group='SECURITYGROUP') - agent = sg_rpc.SecurityGroupAgentRpcMixin() - agent.init_firewall() - self.assertEqual(agent.firewall.__class__.__name__, - 'NoopFirewallDriver') - - -class SecurityGroupAgentRpcTestCase(base.BaseTestCase): - def setUp(self, defer_refresh_firewall=False): - super(SecurityGroupAgentRpcTestCase, self).setUp() - cfg.CONF.set_default('firewall_driver', - 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - self.agent = sg_rpc.SecurityGroupAgentRpcMixin() - self.agent.context = None - mock.patch('neutron.agent.linux.iptables_manager').start() - self.agent.root_helper = 'sudo' - self.agent.init_firewall(defer_refresh_firewall=defer_refresh_firewall) - self.firewall = mock.Mock() - firewall_object = firewall_base.FirewallDriver() - self.firewall.defer_apply.side_effect = firewall_object.defer_apply - self.agent.firewall = self.firewall - rpc = mock.Mock() - self.agent.plugin_rpc = rpc - self.fake_device = {'device': 'fake_device', - 'security_groups': ['fake_sgid1', 'fake_sgid2'], - 'security_group_source_groups': ['fake_sgid2'], - 'security_group_rules': [{'security_group_id': - 'fake_sgid1', - 'remote_group_id': - 'fake_sgid2'}]} - fake_devices = {'fake_device': self.fake_device} - self.firewall.ports = fake_devices - rpc.security_group_rules_for_devices.return_value = fake_devices - - def test_prepare_and_remove_devices_filter(self): - self.agent.prepare_devices_filter(['fake_device']) - self.agent.remove_devices_filter(['fake_device']) - # ignore device which is not filtered - self.firewall.assert_has_calls([mock.call.defer_apply(), - mock.call.prepare_port_filter( - self.fake_device), - mock.call.defer_apply(), - mock.call.remove_port_filter( - self.fake_device), - ]) - - def test_security_groups_rule_updated(self): - self.agent.refresh_firewall = mock.Mock() - self.agent.prepare_devices_filter(['fake_port_id']) - self.agent.security_groups_rule_updated(['fake_sgid1', 'fake_sgid3']) - self.agent.refresh_firewall.assert_has_calls( - [mock.call.refresh_firewall([self.fake_device['device']])]) - - def test_security_groups_rule_not_updated(self): - self.agent.refresh_firewall = mock.Mock() - self.agent.prepare_devices_filter(['fake_port_id']) - self.agent.security_groups_rule_updated(['fake_sgid3', 'fake_sgid4']) - self.agent.refresh_firewall.assert_has_calls([]) - - def test_security_groups_member_updated(self): - self.agent.refresh_firewall = mock.Mock() - self.agent.prepare_devices_filter(['fake_port_id']) - self.agent.security_groups_member_updated(['fake_sgid2', 'fake_sgid3']) - self.agent.refresh_firewall.assert_has_calls( - [mock.call.refresh_firewall([self.fake_device['device']])]) - - def test_security_groups_member_not_updated(self): - self.agent.refresh_firewall = mock.Mock() - self.agent.prepare_devices_filter(['fake_port_id']) - self.agent.security_groups_member_updated(['fake_sgid3', 'fake_sgid4']) - self.agent.refresh_firewall.assert_has_calls([]) - - def test_security_groups_provider_updated(self): - self.agent.refresh_firewall = mock.Mock() - self.agent.security_groups_provider_updated() - self.agent.refresh_firewall.assert_has_calls( - [mock.call.refresh_firewall()]) - - def test_refresh_firewall(self): - self.agent.prepare_devices_filter(['fake_port_id']) - self.agent.refresh_firewall() - calls = [mock.call.defer_apply(), - mock.call.prepare_port_filter(self.fake_device), - mock.call.defer_apply(), - mock.call.update_port_filter(self.fake_device)] - self.firewall.assert_has_calls(calls) - - def test_refresh_firewall_devices(self): - self.agent.prepare_devices_filter(['fake_port_id']) - self.agent.refresh_firewall([self.fake_device]) - calls = [mock.call.defer_apply(), - mock.call.prepare_port_filter(self.fake_device), - mock.call.defer_apply(), - mock.call.update_port_filter(self.fake_device)] - self.firewall.assert_has_calls(calls) - - def test_refresh_firewall_none(self): - self.agent.refresh_firewall([]) - self.firewall.assert_has_calls([]) - - -class SecurityGroupAgentRpcWithDeferredRefreshTestCase( - SecurityGroupAgentRpcTestCase): - - def setUp(self): - super(SecurityGroupAgentRpcWithDeferredRefreshTestCase, self).setUp( - defer_refresh_firewall=True) - - @contextlib.contextmanager - def add_fake_device(self, device, sec_groups, source_sec_groups=None): - fake_device = {'device': device, - 'security_groups': sec_groups, - 'security_group_source_groups': source_sec_groups or [], - 'security_group_rules': [{'security_group_id': - 'fake_sgid1', - 'remote_group_id': - 'fake_sgid2'}]} - self.firewall.ports[device] = fake_device - yield - del self.firewall.ports[device] - - def test_security_groups_rule_updated(self): - self.agent.security_groups_rule_updated(['fake_sgid1', 'fake_sgid3']) - self.assertIn('fake_device', self.agent.devices_to_refilter) - - def test_multiple_security_groups_rule_updated_same_port(self): - with self.add_fake_device(device='fake_device_2', - sec_groups=['fake_sgidX']): - self.agent.refresh_firewall = mock.Mock() - self.agent.security_groups_rule_updated(['fake_sgid1']) - self.agent.security_groups_rule_updated(['fake_sgid2']) - self.assertIn('fake_device', self.agent.devices_to_refilter) - self.assertNotIn('fake_device_2', self.agent.devices_to_refilter) - - def test_security_groups_rule_updated_multiple_ports(self): - with self.add_fake_device(device='fake_device_2', - sec_groups=['fake_sgid2']): - self.agent.refresh_firewall = mock.Mock() - self.agent.security_groups_rule_updated(['fake_sgid1', - 'fake_sgid2']) - self.assertIn('fake_device', self.agent.devices_to_refilter) - self.assertIn('fake_device_2', self.agent.devices_to_refilter) - - def test_multiple_security_groups_rule_updated_multiple_ports(self): - with self.add_fake_device(device='fake_device_2', - sec_groups=['fake_sgid2']): - self.agent.refresh_firewall = mock.Mock() - self.agent.security_groups_rule_updated(['fake_sgid1']) - self.agent.security_groups_rule_updated(['fake_sgid2']) - self.assertIn('fake_device', self.agent.devices_to_refilter) - self.assertIn('fake_device_2', self.agent.devices_to_refilter) - - def test_security_groups_member_updated(self): - self.agent.security_groups_member_updated(['fake_sgid2', 'fake_sgid3']) - self.assertIn('fake_device', self.agent.devices_to_refilter) - - def test_multiple_security_groups_member_updated_same_port(self): - with self.add_fake_device(device='fake_device_2', - sec_groups=['fake_sgid1', 'fake_sgid1B'], - source_sec_groups=['fake_sgidX']): - self.agent.refresh_firewall = mock.Mock() - self.agent.security_groups_member_updated(['fake_sgid1', - 'fake_sgid3']) - self.agent.security_groups_member_updated(['fake_sgid2', - 'fake_sgid3']) - self.assertIn('fake_device', self.agent.devices_to_refilter) - self.assertNotIn('fake_device_2', self.agent.devices_to_refilter) - - def test_security_groups_member_updated_multiple_ports(self): - with self.add_fake_device(device='fake_device_2', - sec_groups=['fake_sgid1', 'fake_sgid1B'], - source_sec_groups=['fake_sgid2']): - self.agent.security_groups_member_updated(['fake_sgid2']) - self.assertIn('fake_device', self.agent.devices_to_refilter) - self.assertIn('fake_device_2', self.agent.devices_to_refilter) - - def test_multiple_security_groups_member_updated_multiple_ports(self): - with self.add_fake_device(device='fake_device_2', - sec_groups=['fake_sgid1', 'fake_sgid1B'], - source_sec_groups=['fake_sgid1B']): - self.agent.security_groups_member_updated(['fake_sgid1B']) - self.agent.security_groups_member_updated(['fake_sgid2']) - self.assertIn('fake_device', self.agent.devices_to_refilter) - self.assertIn('fake_device_2', self.agent.devices_to_refilter) - - def test_security_groups_provider_updated(self): - self.agent.security_groups_provider_updated() - self.assertTrue(self.agent.global_refresh_firewall) - - def test_setup_port_filters_new_ports_only(self): - self.agent.prepare_devices_filter = mock.Mock() - self.agent.refresh_firewall = mock.Mock() - self.agent.devices_to_refilter = set() - self.agent.global_refresh_firewall = False - self.agent.setup_port_filters(set(['fake_new_device']), set()) - self.assertFalse(self.agent.devices_to_refilter) - self.assertFalse(self.agent.global_refresh_firewall) - self.agent.prepare_devices_filter.assert_called_once_with( - set(['fake_new_device'])) - self.assertFalse(self.agent.refresh_firewall.called) - - def test_setup_port_filters_updated_ports_only(self): - self.agent.prepare_devices_filter = mock.Mock() - self.agent.refresh_firewall = mock.Mock() - self.agent.devices_to_refilter = set() - self.agent.global_refresh_firewall = False - self.agent.setup_port_filters(set(), set(['fake_updated_device'])) - self.assertFalse(self.agent.devices_to_refilter) - self.assertFalse(self.agent.global_refresh_firewall) - self.agent.refresh_firewall.assert_called_once_with( - set(['fake_updated_device'])) - self.assertFalse(self.agent.prepare_devices_filter.called) - - def test_setup_port_filter_new_and_updated_ports(self): - self.agent.prepare_devices_filter = mock.Mock() - self.agent.refresh_firewall = mock.Mock() - self.agent.devices_to_refilter = set() - self.agent.global_refresh_firewall = False - self.agent.setup_port_filters(set(['fake_new_device']), - set(['fake_updated_device'])) - self.assertFalse(self.agent.devices_to_refilter) - self.assertFalse(self.agent.global_refresh_firewall) - self.agent.prepare_devices_filter.assert_called_once_with( - set(['fake_new_device'])) - self.agent.refresh_firewall.assert_called_once_with( - set(['fake_updated_device'])) - - def test_setup_port_filters_sg_updates_only(self): - self.agent.prepare_devices_filter = mock.Mock() - self.agent.refresh_firewall = mock.Mock() - self.agent.devices_to_refilter = set(['fake_device']) - self.agent.global_refresh_firewall = False - self.agent.setup_port_filters(set(), set()) - self.assertFalse(self.agent.devices_to_refilter) - self.assertFalse(self.agent.global_refresh_firewall) - self.agent.refresh_firewall.assert_called_once_with( - set(['fake_device'])) - self.assertFalse(self.agent.prepare_devices_filter.called) - - def test_setup_port_filters_sg_updates_and_new_ports(self): - self.agent.prepare_devices_filter = mock.Mock() - self.agent.refresh_firewall = mock.Mock() - self.agent.devices_to_refilter = set(['fake_device']) - self.agent.global_refresh_firewall = False - self.agent.setup_port_filters(set(['fake_new_device']), set()) - self.assertFalse(self.agent.devices_to_refilter) - self.assertFalse(self.agent.global_refresh_firewall) - self.agent.prepare_devices_filter.assert_called_once_with( - set(['fake_new_device'])) - self.agent.refresh_firewall.assert_called_once_with( - set(['fake_device'])) - - def test_setup_port_filters_sg_updates_and_updated_ports(self): - self.agent.prepare_devices_filter = mock.Mock() - self.agent.refresh_firewall = mock.Mock() - self.agent.devices_to_refilter = set(['fake_device', 'fake_device_2']) - self.agent.global_refresh_firewall = False - self.agent.setup_port_filters( - set(), set(['fake_device', 'fake_updated_device'])) - self.assertFalse(self.agent.devices_to_refilter) - self.assertFalse(self.agent.global_refresh_firewall) - self.agent.refresh_firewall.assert_called_once_with( - set(['fake_device', 'fake_device_2', 'fake_updated_device'])) - self.assertFalse(self.agent.prepare_devices_filter.called) - - def test_setup_port_filters_all_updates(self): - self.agent.prepare_devices_filter = mock.Mock() - self.agent.refresh_firewall = mock.Mock() - self.agent.devices_to_refilter = set(['fake_device', 'fake_device_2']) - self.agent.global_refresh_firewall = False - self.agent.setup_port_filters( - set(['fake_new_device']), - set(['fake_device', 'fake_updated_device'])) - self.assertFalse(self.agent.devices_to_refilter) - self.assertFalse(self.agent.global_refresh_firewall) - self.agent.prepare_devices_filter.assert_called_once_with( - set(['fake_new_device'])) - self.agent.refresh_firewall.assert_called_once_with( - set(['fake_device', 'fake_device_2', 'fake_updated_device'])) - - def test_setup_port_filters_no_update(self): - self.agent.prepare_devices_filter = mock.Mock() - self.agent.refresh_firewall = mock.Mock() - self.agent.devices_to_refilter = set() - self.agent.global_refresh_firewall = False - self.agent.setup_port_filters(set(), set()) - self.assertFalse(self.agent.devices_to_refilter) - self.assertFalse(self.agent.global_refresh_firewall) - self.assertFalse(self.agent.refresh_firewall.called) - self.assertFalse(self.agent.prepare_devices_filter.called) - - def test_setup_port_filters_with_global_refresh(self): - self.agent.prepare_devices_filter = mock.Mock() - self.agent.refresh_firewall = mock.Mock() - self.agent.devices_to_refilter = set() - self.agent.global_refresh_firewall = True - self.agent.setup_port_filters(set(), set()) - self.assertFalse(self.agent.devices_to_refilter) - self.assertFalse(self.agent.global_refresh_firewall) - self.agent.refresh_firewall.assert_called_once_with() - self.assertFalse(self.agent.prepare_devices_filter.called) - - -class FakeSGRpcApi(agent_rpc.PluginApi, - sg_rpc.SecurityGroupServerRpcApiMixin): - pass - - -class SecurityGroupServerRpcApiTestCase(base.BaseTestCase): - def setUp(self): - super(SecurityGroupServerRpcApiTestCase, self).setUp() - self.rpc = FakeSGRpcApi('fake_topic') - self.rpc.call = mock.Mock() - - def test_security_group_rules_for_devices(self): - self.rpc.security_group_rules_for_devices(None, ['fake_device']) - self.rpc.call.assert_has_calls( - [mock.call(None, - {'args': - {'devices': ['fake_device']}, - 'method': 'security_group_rules_for_devices', - 'namespace': None}, - version=sg_rpc.SG_RPC_VERSION, - topic='fake_topic')]) - - -class FakeSGNotifierAPI(rpc_compat.RpcProxy, - sg_rpc.SecurityGroupAgentRpcApiMixin): - pass - - -class SecurityGroupAgentRpcApiTestCase(base.BaseTestCase): - def setUp(self): - super(SecurityGroupAgentRpcApiTestCase, self).setUp() - self.notifier = FakeSGNotifierAPI(topic='fake', - default_version='1.0') - self.notifier.fanout_cast = mock.Mock() - - def test_security_groups_rule_updated(self): - self.notifier.security_groups_rule_updated( - None, security_groups=['fake_sgid']) - self.notifier.fanout_cast.assert_has_calls( - [mock.call(None, - {'args': - {'security_groups': ['fake_sgid']}, - 'method': 'security_groups_rule_updated', - 'namespace': None}, - version=sg_rpc.SG_RPC_VERSION, - topic='fake-security_group-update')]) - - def test_security_groups_member_updated(self): - self.notifier.security_groups_member_updated( - None, security_groups=['fake_sgid']) - self.notifier.fanout_cast.assert_has_calls( - [mock.call(None, - {'args': - {'security_groups': ['fake_sgid']}, - 'method': 'security_groups_member_updated', - 'namespace': None}, - version=sg_rpc.SG_RPC_VERSION, - topic='fake-security_group-update')]) - - def test_security_groups_rule_not_updated(self): - self.notifier.security_groups_rule_updated( - None, security_groups=[]) - self.assertEqual(False, self.notifier.fanout_cast.called) - - def test_security_groups_member_not_updated(self): - self.notifier.security_groups_member_updated( - None, security_groups=[]) - self.assertEqual(False, self.notifier.fanout_cast.called) - -#Note(nati) bn -> binary_name -# id -> device_id - -PHYSDEV_MOD = '-m physdev' -PHYSDEV_IS_BRIDGED = '--physdev-is-bridged' - -IPTABLES_ARG = {'bn': iptables_manager.binary_name, - 'physdev_mod': PHYSDEV_MOD, - 'physdev_is_bridged': PHYSDEV_IS_BRIDGED} - -CHAINS_NAT = 'OUTPUT|POSTROUTING|PREROUTING|float-snat|snat' -IPTABLES_ARG['chains'] = CHAINS_NAT - -IPTABLES_NAT = """# Generated by iptables_manager -*nat -:neutron-postrouting-bottom - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A PREROUTING -j %(bn)s-PREROUTING -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING -[0:0] -A POSTROUTING -j neutron-postrouting-bottom -[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat -[0:0] -A %(bn)s-snat -j %(bn)s-float-snat -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - -CHAINS_EMPTY = 'FORWARD|INPUT|OUTPUT|local|sg-chain|sg-fallback' -CHAINS_1 = CHAINS_EMPTY + '|i_port1|o_port1|s_port1' -CHAINS_2 = CHAINS_1 + '|i_port2|o_port2|s_port2' - -IPTABLES_ARG['chains'] = CHAINS_1 - -IPTABLES_FILTER_1 = """# Generated by iptables_manager -*filter -:neutron-filter-top - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A FORWARD -j neutron-filter-top -[0:0] -A OUTPUT -j neutron-filter-top -[0:0] -A neutron-filter-top -j %(bn)s-local -[0:0] -A INPUT -j %(bn)s-INPUT -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A FORWARD -j %(bn)s-FORWARD -[0:0] -A %(bn)s-sg-fallback -j DROP -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-i_port1 -[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port1 -s 10.0.0.2 -p udp -m udp --sport 67 --dport 68 -j \ -RETURN -[0:0] -A %(bn)s-i_port1 -p tcp -m tcp --dport 22 -j RETURN -[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-s_port1 -m mac --mac-source 12:34:56:78:9a:bc -s 10.0.0.3 -j \ -RETURN -[0:0] -A %(bn)s-s_port1 -j DROP -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 68 --dport 67 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-s_port1 -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 67 --dport 68 -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port1 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-sg-chain -j ACCEPT -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - - -IPTABLES_FILTER_1_2 = """# Generated by iptables_manager -*filter -:neutron-filter-top - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A FORWARD -j neutron-filter-top -[0:0] -A OUTPUT -j neutron-filter-top -[0:0] -A neutron-filter-top -j %(bn)s-local -[0:0] -A INPUT -j %(bn)s-INPUT -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A FORWARD -j %(bn)s-FORWARD -[0:0] -A %(bn)s-sg-fallback -j DROP -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-i_port1 -[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port1 -s 10.0.0.2 -p udp -m udp --sport 67 --dport 68 -j \ -RETURN -[0:0] -A %(bn)s-i_port1 -p tcp -m tcp --dport 22 -j RETURN -[0:0] -A %(bn)s-i_port1 -s 10.0.0.4 -j RETURN -[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-s_port1 -m mac --mac-source 12:34:56:78:9a:bc -s 10.0.0.3 -j \ -RETURN -[0:0] -A %(bn)s-s_port1 -j DROP -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 68 --dport 67 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-s_port1 -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 67 --dport 68 -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port1 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-sg-chain -j ACCEPT -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - -IPTABLES_ARG['chains'] = CHAINS_2 - -IPTABLES_FILTER_2 = """# Generated by iptables_manager -*filter -:neutron-filter-top - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A FORWARD -j neutron-filter-top -[0:0] -A OUTPUT -j neutron-filter-top -[0:0] -A neutron-filter-top -j %(bn)s-local -[0:0] -A INPUT -j %(bn)s-INPUT -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A FORWARD -j %(bn)s-FORWARD -[0:0] -A %(bn)s-sg-fallback -j DROP -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-i_port1 -[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port1 -s 10.0.0.2 -p udp -m udp --sport 67 --dport 68 -j \ -RETURN -[0:0] -A %(bn)s-i_port1 -p tcp -m tcp --dport 22 -j RETURN -[0:0] -A %(bn)s-i_port1 -s 10.0.0.4 -j RETURN -[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-s_port1 -m mac --mac-source 12:34:56:78:9a:bc -s 10.0.0.3 \ --j RETURN -[0:0] -A %(bn)s-s_port1 -j DROP -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 68 --dport 67 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-s_port1 -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 67 --dport 68 -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port1 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-i_port2 -[0:0] -A %(bn)s-i_port2 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port2 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port2 -s 10.0.0.2 -p udp -m udp --sport 67 --dport 68 -j \ -RETURN -[0:0] -A %(bn)s-i_port2 -p tcp -m tcp --dport 22 -j RETURN -[0:0] -A %(bn)s-i_port2 -s 10.0.0.3 -j RETURN -[0:0] -A %(bn)s-i_port2 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-o_port2 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-o_port2 -[0:0] -A %(bn)s-s_port2 -m mac --mac-source 12:34:56:78:9a:bd -s 10.0.0.4 \ --j RETURN -[0:0] -A %(bn)s-s_port2 -j DROP -[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 68 --dport 67 -j RETURN -[0:0] -A %(bn)s-o_port2 -j %(bn)s-s_port2 -[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 67 --dport 68 -j DROP -[0:0] -A %(bn)s-o_port2 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port2 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port2 -j RETURN -[0:0] -A %(bn)s-o_port2 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-sg-chain -j ACCEPT -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - -IPTABLES_FILTER_2_2 = """# Generated by iptables_manager -*filter -:neutron-filter-top - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A FORWARD -j neutron-filter-top -[0:0] -A OUTPUT -j neutron-filter-top -[0:0] -A neutron-filter-top -j %(bn)s-local -[0:0] -A INPUT -j %(bn)s-INPUT -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A FORWARD -j %(bn)s-FORWARD -[0:0] -A %(bn)s-sg-fallback -j DROP -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-i_port1 -[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port1 -s 10.0.0.2 -p udp -m udp --sport 67 --dport 68 -j \ -RETURN -[0:0] -A %(bn)s-i_port1 -p tcp -m tcp --dport 22 -j RETURN -[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-s_port1 -m mac --mac-source 12:34:56:78:9a:bc -s 10.0.0.3 -j \ -RETURN -[0:0] -A %(bn)s-s_port1 -j DROP -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 68 --dport 67 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-s_port1 -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 67 --dport 68 -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port1 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-i_port2 -[0:0] -A %(bn)s-i_port2 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port2 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port2 -s 10.0.0.2 -p udp -m udp --sport 67 --dport 68 -j \ -RETURN -[0:0] -A %(bn)s-i_port2 -p tcp -m tcp --dport 22 -j RETURN -[0:0] -A %(bn)s-i_port2 -s 10.0.0.3 -j RETURN -[0:0] -A %(bn)s-i_port2 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-o_port2 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-o_port2 -[0:0] -A %(bn)s-s_port2 -m mac --mac-source 12:34:56:78:9a:bd -s 10.0.0.4 -j \ -RETURN -[0:0] -A %(bn)s-s_port2 -j DROP -[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 68 --dport 67 -j RETURN -[0:0] -A %(bn)s-o_port2 -j %(bn)s-s_port2 -[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 67 --dport 68 -j DROP -[0:0] -A %(bn)s-o_port2 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port2 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port2 -j RETURN -[0:0] -A %(bn)s-o_port2 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-sg-chain -j ACCEPT -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - -IPTABLES_FILTER_2_3 = """# Generated by iptables_manager -*filter -:neutron-filter-top - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A FORWARD -j neutron-filter-top -[0:0] -A OUTPUT -j neutron-filter-top -[0:0] -A neutron-filter-top -j %(bn)s-local -[0:0] -A INPUT -j %(bn)s-INPUT -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A FORWARD -j %(bn)s-FORWARD -[0:0] -A %(bn)s-sg-fallback -j DROP -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-i_port1 -[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port1 -s 10.0.0.2 -p udp -m udp --sport 67 --dport 68 -j \ -RETURN -[0:0] -A %(bn)s-i_port1 -p tcp -m tcp --dport 22 -j RETURN -[0:0] -A %(bn)s-i_port1 -s 10.0.0.4 -j RETURN -[0:0] -A %(bn)s-i_port1 -p icmp -j RETURN -[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-s_port1 -m mac --mac-source 12:34:56:78:9a:bc -s 10.0.0.3 -j \ -RETURN -[0:0] -A %(bn)s-s_port1 -j DROP -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 68 --dport 67 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-s_port1 -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 67 --dport 68 -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port1 -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-i_port2 -[0:0] -A %(bn)s-i_port2 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port2 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port2 -s 10.0.0.2 -p udp -m udp --sport 67 --dport 68 -j \ -RETURN -[0:0] -A %(bn)s-i_port2 -p tcp -m tcp --dport 22 -j RETURN -[0:0] -A %(bn)s-i_port2 -s 10.0.0.3 -j RETURN -[0:0] -A %(bn)s-i_port2 -p icmp -j RETURN -[0:0] -A %(bn)s-i_port2 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-o_port2 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-o_port2 -[0:0] -A %(bn)s-s_port2 -m mac --mac-source 12:34:56:78:9a:bd -s 10.0.0.4 -j \ -RETURN -[0:0] -A %(bn)s-s_port2 -j DROP -[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 68 --dport 67 -j RETURN -[0:0] -A %(bn)s-o_port2 -j %(bn)s-s_port2 -[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 67 --dport 68 -j DROP -[0:0] -A %(bn)s-o_port2 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port2 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port2 -j RETURN -[0:0] -A %(bn)s-o_port2 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-sg-chain -j ACCEPT -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - - -IPTABLES_ARG['chains'] = CHAINS_EMPTY -IPTABLES_FILTER_EMPTY = """# Generated by iptables_manager -*filter -:neutron-filter-top - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A FORWARD -j neutron-filter-top -[0:0] -A OUTPUT -j neutron-filter-top -[0:0] -A neutron-filter-top -j %(bn)s-local -[0:0] -A INPUT -j %(bn)s-INPUT -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A FORWARD -j %(bn)s-FORWARD -[0:0] -A %(bn)s-sg-fallback -j DROP -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - -IPTABLES_ARG['chains'] = CHAINS_1 -IPTABLES_FILTER_V6_1 = """# Generated by iptables_manager -*filter -:neutron-filter-top - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A FORWARD -j neutron-filter-top -[0:0] -A OUTPUT -j neutron-filter-top -[0:0] -A neutron-filter-top -j %(bn)s-local -[0:0] -A INPUT -j %(bn)s-INPUT -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A FORWARD -j %(bn)s-FORWARD -[0:0] -A %(bn)s-sg-fallback -j DROP -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-i_port1 -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 130 -j RETURN -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 131 -j RETURN -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 132 -j RETURN -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 135 -j RETURN -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 136 -j RETURN -[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-o_port1 -p icmpv6 -j RETURN -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 546 --dport 547 -j RETURN -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 547 --dport 546 -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-sg-chain -j ACCEPT -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - - -IPTABLES_ARG['chains'] = CHAINS_2 - -IPTABLES_FILTER_V6_2 = """# Generated by iptables_manager -*filter -:neutron-filter-top - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A FORWARD -j neutron-filter-top -[0:0] -A OUTPUT -j neutron-filter-top -[0:0] -A neutron-filter-top -j %(bn)s-local -[0:0] -A INPUT -j %(bn)s-INPUT -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A FORWARD -j %(bn)s-FORWARD -[0:0] -A %(bn)s-sg-fallback -j DROP -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-i_port1 -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 130 -j RETURN -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 131 -j RETURN -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 132 -j RETURN -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 135 -j RETURN -[0:0] -A %(bn)s-i_port1 -p icmpv6 --icmpv6-type 136 -j RETURN -[0:0] -A %(bn)s-i_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ -%(physdev_is_bridged)s -j %(bn)s-o_port1 -[0:0] -A %(bn)s-o_port1 -p icmpv6 -j RETURN -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 546 --dport 547 -j RETURN -[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 547 --dport 546 -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-INGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-INGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-i_port2 -[0:0] -A %(bn)s-i_port2 -p icmpv6 --icmpv6-type 130 -j RETURN -[0:0] -A %(bn)s-i_port2 -p icmpv6 --icmpv6-type 131 -j RETURN -[0:0] -A %(bn)s-i_port2 -p icmpv6 --icmpv6-type 132 -j RETURN -[0:0] -A %(bn)s-i_port2 -p icmpv6 --icmpv6-type 135 -j RETURN -[0:0] -A %(bn)s-i_port2 -p icmpv6 --icmpv6-type 136 -j RETURN -[0:0] -A %(bn)s-i_port2 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-i_port2 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-i_port2 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-FORWARD %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-sg-chain -[0:0] -A %(bn)s-sg-chain %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-o_port2 -[0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port2 \ -%(physdev_is_bridged)s -j %(bn)s-o_port2 -[0:0] -A %(bn)s-o_port2 -p icmpv6 -j RETURN -[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 546 --dport 547 -j RETURN -[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 547 --dport 546 -j DROP -[0:0] -A %(bn)s-o_port2 -m state --state INVALID -j DROP -[0:0] -A %(bn)s-o_port2 -m state --state RELATED,ESTABLISHED -j RETURN -[0:0] -A %(bn)s-o_port2 -j %(bn)s-sg-fallback -[0:0] -A %(bn)s-sg-chain -j ACCEPT -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - -IPTABLES_ARG['chains'] = CHAINS_EMPTY -IPTABLES_FILTER_V6_EMPTY = """# Generated by iptables_manager -*filter -:neutron-filter-top - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -:%(bn)s-(%(chains)s) - [0:0] -[0:0] -A FORWARD -j neutron-filter-top -[0:0] -A OUTPUT -j neutron-filter-top -[0:0] -A neutron-filter-top -j %(bn)s-local -[0:0] -A INPUT -j %(bn)s-INPUT -[0:0] -A OUTPUT -j %(bn)s-OUTPUT -[0:0] -A FORWARD -j %(bn)s-FORWARD -[0:0] -A %(bn)s-sg-fallback -j DROP -COMMIT -# Completed by iptables_manager -""" % IPTABLES_ARG - -FIREWALL_BASE_PACKAGE = 'neutron.agent.linux.iptables_firewall.' -FIREWALL_IPTABLES_DRIVER = FIREWALL_BASE_PACKAGE + 'IptablesFirewallDriver' -FIREWALL_HYBRID_DRIVER = (FIREWALL_BASE_PACKAGE + - 'OVSHybridIptablesFirewallDriver') -FIREWALL_NOOP_DRIVER = 'neutron.agent.firewall.NoopFirewallDriver' - - -def set_firewall_driver(firewall_driver): - cfg.CONF.set_override('firewall_driver', firewall_driver, - group='SECURITYGROUP') - - -class TestSecurityGroupAgentWithIptables(base.BaseTestCase): - FIREWALL_DRIVER = FIREWALL_IPTABLES_DRIVER - PHYSDEV_INGRESS = 'physdev-out' - PHYSDEV_EGRESS = 'physdev-in' - - def setUp(self, defer_refresh_firewall=False): - super(TestSecurityGroupAgentWithIptables, self).setUp() - config.register_root_helper(cfg.CONF) - cfg.CONF.set_override( - 'lock_path', - '$state_path/lock') - cfg.CONF.set_override( - 'firewall_driver', - self.FIREWALL_DRIVER, - group='SECURITYGROUP') - - self.agent = sg_rpc.SecurityGroupAgentRpcMixin() - self.agent.context = None - - self.root_helper = 'sudo' - self.agent.root_helper = 'sudo' - self.agent.init_firewall(defer_refresh_firewall=defer_refresh_firewall) - - self.iptables = self.agent.firewall.iptables - self.iptables_execute = mock.patch.object(self.iptables, - "execute").start() - self.iptables_execute_return_values = [] - self.expected_call_count = 0 - self.expected_calls = [] - self.expected_process_inputs = [] - self.iptables_execute.side_effect = self.iptables_execute_return_values - - self.rpc = mock.Mock() - self.agent.plugin_rpc = self.rpc - rule1 = [{'direction': 'ingress', - 'protocol': const.PROTO_NAME_UDP, - 'ethertype': const.IPv4, - 'source_ip_prefix': '10.0.0.2', - 'source_port_range_min': 67, - 'source_port_range_max': 67, - 'port_range_min': 68, - 'port_range_max': 68}, - {'direction': 'ingress', - 'protocol': const.PROTO_NAME_TCP, - 'ethertype': const.IPv4, - 'port_range_min': 22, - 'port_range_max': 22}, - {'direction': 'egress', - 'ethertype': const.IPv4}] - rule2 = rule1[:] - rule2 += [{'direction': 'ingress', - 'source_ip_prefix': '10.0.0.4', - 'ethertype': const.IPv4}] - rule3 = rule2[:] - rule3 += [{'direction': 'ingress', - 'protocol': const.PROTO_NAME_ICMP, - 'ethertype': const.IPv4}] - rule4 = rule1[:] - rule4 += [{'direction': 'ingress', - 'source_ip_prefix': '10.0.0.3', - 'ethertype': const.IPv4}] - rule5 = rule4[:] - rule5 += [{'direction': 'ingress', - 'protocol': const.PROTO_NAME_ICMP, - 'ethertype': const.IPv4}] - self.devices1 = {'tap_port1': self._device('tap_port1', - '10.0.0.3', - '12:34:56:78:9a:bc', - rule1)} - self.devices2 = {'tap_port1': self._device('tap_port1', - '10.0.0.3', - '12:34:56:78:9a:bc', - rule2), - 'tap_port2': self._device('tap_port2', - '10.0.0.4', - '12:34:56:78:9a:bd', - rule4)} - self.devices3 = {'tap_port1': self._device('tap_port1', - '10.0.0.3', - '12:34:56:78:9a:bc', - rule3), - 'tap_port2': self._device('tap_port2', - '10.0.0.4', - '12:34:56:78:9a:bd', - rule5)} - - def _device(self, device, ip, mac_address, rule): - return {'device': device, - 'fixed_ips': [ip], - 'mac_address': mac_address, - 'security_groups': ['security_group1'], - 'security_group_rules': rule, - 'security_group_source_groups': [ - 'security_group1']} - - def _regex(self, value): - value = value.replace('physdev-INGRESS', self.PHYSDEV_INGRESS) - value = value.replace('physdev-EGRESS', self.PHYSDEV_EGRESS) - value = value.replace('\n', '\\n') - value = value.replace('[', '\[') - value = value.replace(']', '\]') - value = value.replace('*', '\*') - return value - - def _register_mock_call(self, *args, **kwargs): - return_value = kwargs.pop('return_value', None) - self.iptables_execute_return_values.append(return_value) - - has_process_input = 'process_input' in kwargs - process_input = kwargs.get('process_input') - self.expected_process_inputs.append((has_process_input, process_input)) - - if has_process_input: - kwargs['process_input'] = mock.ANY - self.expected_calls.append(mock.call(*args, **kwargs)) - self.expected_call_count += 1 - - def _verify_mock_calls(self): - self.assertEqual(self.expected_call_count, - self.iptables_execute.call_count) - self.iptables_execute.assert_has_calls(self.expected_calls) - - for i, expected in enumerate(self.expected_process_inputs): - check, expected_regex = expected - if not check: - continue - # The second or later arguments of self.iptables.execute - # are keyword parameter, so keyword argument is extracted by [1] - kwargs = self.iptables_execute.call_args_list[i][1] - self.assertThat(kwargs['process_input'], - matchers.MatchesRegex(expected_regex)) - - def _replay_iptables(self, v4_filter, v6_filter): - self._register_mock_call( - ['iptables-save', '-c'], - root_helper=self.root_helper, - return_value='') - self._register_mock_call( - ['iptables-restore', '-c'], - process_input=self._regex(IPTABLES_NAT + v4_filter), - root_helper=self.root_helper, - return_value='') - self._register_mock_call( - ['ip6tables-save', '-c'], - root_helper=self.root_helper, - return_value='') - self._register_mock_call( - ['ip6tables-restore', '-c'], - process_input=self._regex(v6_filter), - root_helper=self.root_helper, - return_value='') - - def test_prepare_remove_port(self): - self.rpc.security_group_rules_for_devices.return_value = self.devices1 - self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1) - self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY) - - self.agent.prepare_devices_filter(['tap_port1']) - self.agent.remove_devices_filter(['tap_port1']) - - self._verify_mock_calls() - - def test_security_group_member_updated(self): - self.rpc.security_group_rules_for_devices.return_value = self.devices1 - self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1) - self._replay_iptables(IPTABLES_FILTER_1_2, IPTABLES_FILTER_V6_1) - self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2) - self._replay_iptables(IPTABLES_FILTER_2_2, IPTABLES_FILTER_V6_2) - self._replay_iptables(IPTABLES_FILTER_1, IPTABLES_FILTER_V6_1) - self._replay_iptables(IPTABLES_FILTER_EMPTY, IPTABLES_FILTER_V6_EMPTY) - - self.agent.prepare_devices_filter(['tap_port1']) - self.rpc.security_group_rules_for_devices.return_value = self.devices2 - self.agent.security_groups_member_updated(['security_group1']) - self.agent.prepare_devices_filter(['tap_port2']) - self.rpc.security_group_rules_for_devices.return_value = self.devices1 - self.agent.security_groups_member_updated(['security_group1']) - self.agent.remove_devices_filter(['tap_port2']) - self.agent.remove_devices_filter(['tap_port1']) - - self._verify_mock_calls() - - def test_security_group_rule_updated(self): - self.rpc.security_group_rules_for_devices.return_value = self.devices2 - self._replay_iptables(IPTABLES_FILTER_2, IPTABLES_FILTER_V6_2) - self._replay_iptables(IPTABLES_FILTER_2_3, IPTABLES_FILTER_V6_2) - - self.agent.prepare_devices_filter(['tap_port1', 'tap_port3']) - self.rpc.security_group_rules_for_devices.return_value = self.devices3 - self.agent.security_groups_rule_updated(['security_group1']) - - self._verify_mock_calls() - - -class SGNotificationTestMixin(): - def test_security_group_rule_updated(self): - name = 'webservers' - description = 'my webservers' - with self.security_group(name, description) as sg: - with self.security_group(name, description) as sg2: - security_group_id = sg['security_group']['id'] - direction = "ingress" - remote_group_id = sg2['security_group']['id'] - protocol = const.PROTO_NAME_TCP - port_range_min = 88 - port_range_max = 88 - with self.security_group_rule(security_group_id, direction, - protocol, port_range_min, - port_range_max, - remote_group_id=remote_group_id - ): - pass - self.notifier.assert_has_calls( - [mock.call.security_groups_rule_updated(mock.ANY, - [security_group_id]), - mock.call.security_groups_rule_updated(mock.ANY, - [security_group_id])]) - - def test_security_group_member_updated(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - security_group_id = sg['security_group']['id'] - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - - data = {'port': {'fixed_ips': port['port']['fixed_ips'], - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: - [security_group_id]}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - self.assertEqual(res['port'][ext_sg.SECURITYGROUPS][0], - security_group_id) - self._delete('ports', port['port']['id']) - self.notifier.assert_has_calls( - [mock.call.security_groups_member_updated( - mock.ANY, [mock.ANY])]) - - -class TestSecurityGroupAgentWithOVSIptables( - TestSecurityGroupAgentWithIptables): - - FIREWALL_DRIVER = FIREWALL_HYBRID_DRIVER - - def _regex(self, value): - #Note(nati): tap is prefixed on the device - # in the OVSHybridIptablesFirewallDriver - - value = value.replace('tap_port', 'taptap_port') - value = value.replace('o_port', 'otap_port') - value = value.replace('i_port', 'itap_port') - value = value.replace('s_port', 'stap_port') - return super( - TestSecurityGroupAgentWithOVSIptables, - self)._regex(value) - - -class TestSecurityGroupExtensionControl(base.BaseTestCase): - def test_disable_security_group_extension_by_config(self): - cfg.CONF.set_override( - 'enable_security_group', False, - group='SECURITYGROUP') - exp_aliases = ['dummy1', 'dummy2'] - ext_aliases = ['dummy1', 'security-group', 'dummy2'] - sg_rpc.disable_security_group_extension_by_config(ext_aliases) - self.assertEqual(ext_aliases, exp_aliases) - - def test_enable_security_group_extension_by_config(self): - cfg.CONF.set_override( - 'enable_security_group', True, - group='SECURITYGROUP') - exp_aliases = ['dummy1', 'security-group', 'dummy2'] - ext_aliases = ['dummy1', 'security-group', 'dummy2'] - sg_rpc.disable_security_group_extension_by_config(ext_aliases) - self.assertEqual(ext_aliases, exp_aliases) - - def test_is_invalid_drvier_combination_sg_enabled(self): - cfg.CONF.set_override( - 'enable_security_group', True, - group='SECURITYGROUP') - cfg.CONF.set_override( - 'firewall_driver', 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - self.assertFalse(sg_rpc._is_valid_driver_combination()) - - def test_is_invalid_drvier_combination_sg_enabled_with_none(self): - cfg.CONF.set_override( - 'enable_security_group', True, - group='SECURITYGROUP') - cfg.CONF.set_override( - 'firewall_driver', None, - group='SECURITYGROUP') - self.assertFalse(sg_rpc._is_valid_driver_combination()) - - def test_is_invalid_drvier_combination_sg_disabled(self): - cfg.CONF.set_override( - 'enable_security_group', False, - group='SECURITYGROUP') - cfg.CONF.set_override( - 'firewall_driver', 'NonNoopDriver', - group='SECURITYGROUP') - self.assertFalse(sg_rpc._is_valid_driver_combination()) - - def test_is_valid_drvier_combination_sg_enabled(self): - cfg.CONF.set_override( - 'enable_security_group', True, - group='SECURITYGROUP') - cfg.CONF.set_override( - 'firewall_driver', 'NonNoopDriver', - group='SECURITYGROUP') - self.assertTrue(sg_rpc._is_valid_driver_combination()) - - def test_is_valid_drvier_combination_sg_disabled(self): - cfg.CONF.set_override( - 'enable_security_group', False, - group='SECURITYGROUP') - cfg.CONF.set_override( - 'firewall_driver', 'neutron.agent.firewall.NoopFirewallDriver', - group='SECURITYGROUP') - self.assertTrue(sg_rpc._is_valid_driver_combination()) - - def test_is_valid_drvier_combination_sg_disabled_with_none(self): - cfg.CONF.set_override( - 'enable_security_group', False, - group='SECURITYGROUP') - cfg.CONF.set_override( - 'firewall_driver', None, - group='SECURITYGROUP') - self.assertTrue(sg_rpc._is_valid_driver_combination()) diff --git a/neutron/tests/unit/test_servicetype.py b/neutron/tests/unit/test_servicetype.py deleted file mode 100644 index 135c87b0b..000000000 --- a/neutron/tests/unit/test_servicetype.py +++ /dev/null @@ -1,241 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2012 OpenStack Foundation. -# All Rights Reserved. -# -# 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. -# -# @author: Salvatore Orlando, VMware -# - -import logging - -import mock -from oslo.config import cfg -import webob.exc as webexc -import webtest - -from neutron.api import extensions -from neutron.common import exceptions as n_exc -from neutron import context -from neutron.db import api as db_api -from neutron.db import servicetype_db as st_db -from neutron.extensions import servicetype -from neutron.plugins.common import constants -from neutron.services import provider_configuration as provconf -from neutron.tests import base -from neutron.tests.unit import dummy_plugin as dp -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import test_extensions -from neutron.tests.unit import testlib_api - - -LOG = logging.getLogger(__name__) -DEFAULT_SERVICE_DEFS = [{'service_class': constants.DUMMY, - 'plugin': dp.DUMMY_PLUGIN_NAME}] - -_uuid = test_api_v2._uuid -_get_path = test_api_v2._get_path - - -class ServiceTypeManagerTestCase(base.BaseTestCase): - def setUp(self): - super(ServiceTypeManagerTestCase, self).setUp() - st_db.ServiceTypeManager._instance = None - self.manager = st_db.ServiceTypeManager.get_instance() - self.ctx = context.get_admin_context() - - def test_service_provider_driver_not_unique(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver'], - 'service_providers') - prov = {'service_type': constants.LOADBALANCER, - 'name': 'name2', - 'driver': 'driver', - 'default': False} - self.manager._load_conf() - self.assertRaises( - n_exc.Invalid, self.manager.conf.add_provider, prov) - - def test_get_service_providers(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - constants.DUMMY + ':dummy:dummy_dr'], - 'service_providers') - ctx = context.get_admin_context() - provconf.parse_service_provider_opt() - self.manager._load_conf() - res = self.manager.get_service_providers(ctx) - self.assertEqual(len(res), 2) - - res = self.manager.get_service_providers( - ctx, - filters=dict(service_type=[constants.DUMMY]) - ) - self.assertEqual(len(res), 1) - - res = self.manager.get_service_providers( - ctx, - filters=dict(service_type=[constants.LOADBALANCER]) - ) - self.assertEqual(len(res), 1) - - def test_multiple_default_providers_specified_for_service(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas1:driver_path:default', - constants.LOADBALANCER + - ':lbaas2:driver_path:default'], - 'service_providers') - self.assertRaises(n_exc.Invalid, self.manager._load_conf) - - def test_get_default_provider(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas1:driver_path:default', - constants.DUMMY + - ':lbaas2:driver_path2'], - 'service_providers') - self.manager._load_conf() - # can pass None as a context - p = self.manager.get_default_service_provider(None, - constants.LOADBALANCER) - self.assertEqual(p, {'service_type': constants.LOADBALANCER, - 'name': 'lbaas1', - 'driver': 'driver_path', - 'default': True}) - - self.assertRaises( - provconf.DefaultServiceProviderNotFound, - self.manager.get_default_service_provider, - None, constants.DUMMY - ) - - def test_add_resource_association(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas1:driver_path:default', - constants.DUMMY + - ':lbaas2:driver_path2'], - 'service_providers') - self.manager._load_conf() - ctx = context.get_admin_context() - self.manager.add_resource_association(ctx, - constants.LOADBALANCER, - 'lbaas1', '123-123') - self.assertEqual(ctx.session. - query(st_db.ProviderResourceAssociation).count(), - 1) - assoc = ctx.session.query(st_db.ProviderResourceAssociation).one() - ctx.session.delete(assoc) - - def test_invalid_resource_association(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas1:driver_path:default', - constants.DUMMY + - ':lbaas2:driver_path2'], - 'service_providers') - self.manager._load_conf() - ctx = context.get_admin_context() - self.assertRaises(provconf.ServiceProviderNotFound, - self.manager.add_resource_association, - ctx, 'BLABLA_svc', 'name', '123-123') - - -class TestServiceTypeExtensionManager(object): - """Mock extensions manager.""" - def get_resources(self): - return (servicetype.Servicetype.get_resources() + - dp.Dummy.get_resources()) - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class ServiceTypeExtensionTestCaseBase(testlib_api.WebTestCase): - fmt = 'json' - - def setUp(self): - # This is needed because otherwise a failure will occur due to - # nonexisting core_plugin - self.setup_coreplugin(test_db_plugin.DB_PLUGIN_KLASS) - - cfg.CONF.set_override('service_plugins', - ["%s.%s" % (dp.__name__, - dp.DummyServicePlugin.__name__)]) - # Ensure existing ExtensionManager is not used - extensions.PluginAwareExtensionManager._instance = None - ext_mgr = TestServiceTypeExtensionManager() - self.ext_mdw = test_extensions.setup_extensions_middleware(ext_mgr) - self.api = webtest.TestApp(self.ext_mdw) - self.resource_name = servicetype.RESOURCE_NAME.replace('-', '_') - super(ServiceTypeExtensionTestCaseBase, self).setUp() - - -class ServiceTypeExtensionTestCase(ServiceTypeExtensionTestCaseBase): - - def setUp(self): - self._patcher = mock.patch( - "neutron.db.servicetype_db.ServiceTypeManager", - autospec=True) - self.mock_mgr = self._patcher.start() - self.mock_mgr.get_instance.return_value = self.mock_mgr.return_value - super(ServiceTypeExtensionTestCase, self).setUp() - - def test_service_provider_list(self): - instance = self.mock_mgr.return_value - - res = self.api.get(_get_path('service-providers', fmt=self.fmt)) - - instance.get_service_providers.assert_called_with(mock.ANY, - filters={}, - fields=[]) - self.assertEqual(res.status_int, webexc.HTTPOk.code) - - -class ServiceTypeExtensionTestCaseXML(ServiceTypeExtensionTestCase): - fmt = 'xml' - - -class ServiceTypeManagerExtTestCase(ServiceTypeExtensionTestCaseBase): - """Tests ServiceTypemanager as a public API.""" - def setUp(self): - # Blank out service type manager instance - st_db.ServiceTypeManager._instance = None - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - constants.DUMMY + ':dummy:dummy_dr'], - 'service_providers') - self.addCleanup(db_api.clear_db) - super(ServiceTypeManagerExtTestCase, self).setUp() - - def _list_service_providers(self): - return self.api.get(_get_path('service-providers', fmt=self.fmt)) - - def test_list_service_providers(self): - res = self._list_service_providers() - self.assertEqual(res.status_int, webexc.HTTPOk.code) - data = self.deserialize(res) - self.assertIn('service_providers', data) - self.assertEqual(len(data['service_providers']), 2) - - -class ServiceTypeManagerExtTestCaseXML(ServiceTypeManagerExtTestCase): - fmt = 'xml' diff --git a/neutron/tests/unit/vmware/__init__.py b/neutron/tests/unit/vmware/__init__.py deleted file mode 100644 index df9667860..000000000 --- a/neutron/tests/unit/vmware/__init__.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2013 OpenStack Foundation. -# -# All Rights Reserved. -# -# 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 os - -from neutron.plugins.vmware.api_client import client as nsx_client -from neutron.plugins.vmware.api_client import eventlet_client -from neutron.plugins.vmware import extensions -import neutron.plugins.vmware.plugin as neutron_plugin -from neutron.plugins.vmware.vshield.common import VcnsApiClient as vcnsapi -from neutron.plugins.vmware.vshield import vcns -import neutron.plugins.vmware.vshield.vcns_driver as vcnsdriver - - -plugin = neutron_plugin.NsxPlugin -service_plugin = neutron_plugin.NsxServicePlugin -api_client = nsx_client.NsxApiClient -evt_client = eventlet_client.EventletApiClient -vcns_class = vcns.Vcns -vcns_driver = vcnsdriver.VcnsDriver -vcns_api_helper = vcnsapi.VcnsApiHelper - -STUBS_PATH = os.path.join(os.path.dirname(__file__), 'etc') -NSXEXT_PATH = os.path.dirname(extensions.__file__) -NSXAPI_NAME = '%s.%s' % (api_client.__module__, api_client.__name__) -PLUGIN_NAME = '%s.%s' % (plugin.__module__, plugin.__name__) -SERVICE_PLUGIN_NAME = '%s.%s' % (service_plugin.__module__, - service_plugin.__name__) -CLIENT_NAME = '%s.%s' % (evt_client.__module__, evt_client.__name__) -VCNS_NAME = '%s.%s' % (vcns_class.__module__, vcns_class.__name__) -VCNS_DRIVER_NAME = '%s.%s' % (vcns_driver.__module__, vcns_driver.__name__) -VCNSAPI_NAME = '%s.%s' % (vcns_api_helper.__module__, vcns_api_helper.__name__) - - -def get_fake_conf(filename): - return os.path.join(STUBS_PATH, filename) - - -def nsx_method(method_name, module_name='nsxlib'): - return '%s.%s.%s' % ('neutron.plugins.vmware', module_name, method_name) diff --git a/neutron/tests/unit/vmware/apiclient/__init__.py b/neutron/tests/unit/vmware/apiclient/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/vmware/apiclient/fake.py b/neutron/tests/unit/vmware/apiclient/fake.py deleted file mode 100644 index eb1f62f49..000000000 --- a/neutron/tests/unit/vmware/apiclient/fake.py +++ /dev/null @@ -1,660 +0,0 @@ -# Copyright 2012 VMware, Inc. -# -# 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 six.moves.urllib.parse as urlparse - -from neutron.openstack.common import jsonutils as json -from neutron.openstack.common import log as logging -from neutron.openstack.common import uuidutils -from neutron.plugins.vmware.api_client import exception as api_exc - - -LOG = logging.getLogger(__name__) -MAX_NAME_LEN = 40 - - -def _validate_name(name): - if name and len(name) > MAX_NAME_LEN: - raise Exception("Logical switch name exceeds %d characters", - MAX_NAME_LEN) - - -def _validate_resource(body): - _validate_name(body.get('display_name')) - - -class FakeClient: - - LSWITCH_RESOURCE = 'lswitch' - LPORT_RESOURCE = 'lport' - LROUTER_RESOURCE = 'lrouter' - NAT_RESOURCE = 'nat' - LQUEUE_RESOURCE = 'lqueue' - SECPROF_RESOURCE = 'securityprofile' - LSWITCH_STATUS = 'lswitchstatus' - LROUTER_STATUS = 'lrouterstatus' - LSWITCH_LPORT_RESOURCE = 'lswitch_lport' - LROUTER_LPORT_RESOURCE = 'lrouter_lport' - LROUTER_NAT_RESOURCE = 'lrouter_nat' - LSWITCH_LPORT_STATUS = 'lswitch_lportstatus' - LSWITCH_LPORT_ATT = 'lswitch_lportattachment' - LROUTER_LPORT_STATUS = 'lrouter_lportstatus' - LROUTER_LPORT_ATT = 'lrouter_lportattachment' - GWSERVICE_RESOURCE = 'gatewayservice' - - RESOURCES = [LSWITCH_RESOURCE, LROUTER_RESOURCE, LQUEUE_RESOURCE, - LPORT_RESOURCE, NAT_RESOURCE, SECPROF_RESOURCE, - GWSERVICE_RESOURCE] - - FAKE_GET_RESPONSES = { - LSWITCH_RESOURCE: "fake_get_lswitch.json", - LSWITCH_LPORT_RESOURCE: "fake_get_lswitch_lport.json", - LSWITCH_LPORT_STATUS: "fake_get_lswitch_lport_status.json", - LSWITCH_LPORT_ATT: "fake_get_lswitch_lport_att.json", - LROUTER_RESOURCE: "fake_get_lrouter.json", - LROUTER_LPORT_RESOURCE: "fake_get_lrouter_lport.json", - LROUTER_LPORT_STATUS: "fake_get_lrouter_lport_status.json", - LROUTER_LPORT_ATT: "fake_get_lrouter_lport_att.json", - LROUTER_STATUS: "fake_get_lrouter_status.json", - LROUTER_NAT_RESOURCE: "fake_get_lrouter_nat.json", - SECPROF_RESOURCE: "fake_get_security_profile.json", - LQUEUE_RESOURCE: "fake_get_lqueue.json", - GWSERVICE_RESOURCE: "fake_get_gwservice.json" - } - - FAKE_POST_RESPONSES = { - LSWITCH_RESOURCE: "fake_post_lswitch.json", - LROUTER_RESOURCE: "fake_post_lrouter.json", - LSWITCH_LPORT_RESOURCE: "fake_post_lswitch_lport.json", - LROUTER_LPORT_RESOURCE: "fake_post_lrouter_lport.json", - LROUTER_NAT_RESOURCE: "fake_post_lrouter_nat.json", - SECPROF_RESOURCE: "fake_post_security_profile.json", - LQUEUE_RESOURCE: "fake_post_lqueue.json", - GWSERVICE_RESOURCE: "fake_post_gwservice.json" - } - - FAKE_PUT_RESPONSES = { - LSWITCH_RESOURCE: "fake_post_lswitch.json", - LROUTER_RESOURCE: "fake_post_lrouter.json", - LSWITCH_LPORT_RESOURCE: "fake_post_lswitch_lport.json", - LROUTER_LPORT_RESOURCE: "fake_post_lrouter_lport.json", - LROUTER_NAT_RESOURCE: "fake_post_lrouter_nat.json", - LSWITCH_LPORT_ATT: "fake_put_lswitch_lport_att.json", - LROUTER_LPORT_ATT: "fake_put_lrouter_lport_att.json", - SECPROF_RESOURCE: "fake_post_security_profile.json", - LQUEUE_RESOURCE: "fake_post_lqueue.json", - GWSERVICE_RESOURCE: "fake_post_gwservice.json" - } - - MANAGED_RELATIONS = { - LSWITCH_RESOURCE: [], - LROUTER_RESOURCE: [], - LSWITCH_LPORT_RESOURCE: ['LogicalPortAttachment'], - LROUTER_LPORT_RESOURCE: ['LogicalPortAttachment'], - } - - _validators = { - LSWITCH_RESOURCE: _validate_resource, - LSWITCH_LPORT_RESOURCE: _validate_resource, - LROUTER_LPORT_RESOURCE: _validate_resource, - SECPROF_RESOURCE: _validate_resource, - LQUEUE_RESOURCE: _validate_resource, - GWSERVICE_RESOURCE: _validate_resource - } - - def __init__(self, fake_files_path): - self.fake_files_path = fake_files_path - self._fake_lswitch_dict = {} - self._fake_lrouter_dict = {} - self._fake_lswitch_lport_dict = {} - self._fake_lrouter_lport_dict = {} - self._fake_lrouter_nat_dict = {} - self._fake_lswitch_lportstatus_dict = {} - self._fake_lrouter_lportstatus_dict = {} - self._fake_securityprofile_dict = {} - self._fake_lqueue_dict = {} - self._fake_gatewayservice_dict = {} - - def _get_tag(self, resource, scope): - tags = [tag['tag'] for tag in resource['tags'] - if tag['scope'] == scope] - return len(tags) > 0 and tags[0] - - def _get_filters(self, querystring): - if not querystring: - return (None, None, None, None) - params = urlparse.parse_qs(querystring) - tag_filter = None - attr_filter = None - if 'tag' in params and 'tag_scope' in params: - tag_filter = {'scope': params['tag_scope'][0], - 'tag': params['tag'][0]} - elif 'uuid' in params: - attr_filter = {'uuid': params['uuid'][0]} - # Handle page length and page cursor parameter - page_len = params.get('_page_length') - page_cursor = params.get('_page_cursor') - if page_len: - page_len = int(page_len[0]) - else: - # Explicitly set it to None (avoid 0 or empty list) - page_len = None - return (tag_filter, attr_filter, page_len, page_cursor) - - def _add_lswitch(self, body): - fake_lswitch = json.loads(body) - fake_lswitch['uuid'] = uuidutils.generate_uuid() - self._fake_lswitch_dict[fake_lswitch['uuid']] = fake_lswitch - # put the tenant_id and the zone_uuid in the main dict - # for simplyfying templating - zone_uuid = fake_lswitch['transport_zones'][0]['zone_uuid'] - fake_lswitch['zone_uuid'] = zone_uuid - fake_lswitch['tenant_id'] = self._get_tag(fake_lswitch, 'os_tid') - fake_lswitch['lport_count'] = 0 - # set status value - fake_lswitch['status'] = 'true' - return fake_lswitch - - def _build_lrouter(self, body, uuid=None): - fake_lrouter = json.loads(body) - if uuid: - fake_lrouter['uuid'] = uuid - fake_lrouter['tenant_id'] = self._get_tag(fake_lrouter, 'os_tid') - default_nexthop = fake_lrouter['routing_config'].get( - 'default_route_next_hop') - if default_nexthop: - fake_lrouter['default_next_hop'] = default_nexthop.get( - 'gateway_ip_address', '0.0.0.0') - else: - fake_lrouter['default_next_hop'] = '0.0.0.0' - # NOTE(salv-orlando): We won't make the Fake NSX API client - # aware of NSX version. The long term plan is to replace it - # with behavioral mocking of NSX API requests - if 'distributed' not in fake_lrouter: - fake_lrouter['distributed'] = False - distributed_json = ('"distributed": %s,' % - str(fake_lrouter['distributed']).lower()) - fake_lrouter['distributed_json'] = distributed_json - return fake_lrouter - - def _add_lrouter(self, body): - fake_lrouter = self._build_lrouter(body, - uuidutils.generate_uuid()) - self._fake_lrouter_dict[fake_lrouter['uuid']] = fake_lrouter - fake_lrouter['lport_count'] = 0 - # set status value - fake_lrouter['status'] = 'true' - return fake_lrouter - - def _add_lqueue(self, body): - fake_lqueue = json.loads(body) - fake_lqueue['uuid'] = uuidutils.generate_uuid() - self._fake_lqueue_dict[fake_lqueue['uuid']] = fake_lqueue - return fake_lqueue - - def _add_lswitch_lport(self, body, ls_uuid): - fake_lport = json.loads(body) - new_uuid = uuidutils.generate_uuid() - fake_lport['uuid'] = new_uuid - # put the tenant_id and the ls_uuid in the main dict - # for simplyfying templating - fake_lport['ls_uuid'] = ls_uuid - fake_lport['tenant_id'] = self._get_tag(fake_lport, 'os_tid') - fake_lport['neutron_port_id'] = self._get_tag(fake_lport, - 'q_port_id') - fake_lport['neutron_device_id'] = self._get_tag(fake_lport, 'vm_id') - fake_lport['att_type'] = "NoAttachment" - fake_lport['att_info_json'] = '' - self._fake_lswitch_lport_dict[fake_lport['uuid']] = fake_lport - - fake_lswitch = self._fake_lswitch_dict[ls_uuid] - fake_lswitch['lport_count'] += 1 - fake_lport_status = fake_lport.copy() - fake_lport_status['ls_tenant_id'] = fake_lswitch['tenant_id'] - fake_lport_status['ls_uuid'] = fake_lswitch['uuid'] - fake_lport_status['ls_name'] = fake_lswitch['display_name'] - fake_lport_status['ls_zone_uuid'] = fake_lswitch['zone_uuid'] - # set status value - fake_lport['status'] = 'true' - self._fake_lswitch_lportstatus_dict[new_uuid] = fake_lport_status - return fake_lport - - def _build_lrouter_lport(self, body, new_uuid=None, lr_uuid=None): - fake_lport = json.loads(body) - if new_uuid: - fake_lport['uuid'] = new_uuid - # put the tenant_id and the le_uuid in the main dict - # for simplyfying templating - if lr_uuid: - fake_lport['lr_uuid'] = lr_uuid - fake_lport['tenant_id'] = self._get_tag(fake_lport, 'os_tid') - fake_lport['neutron_port_id'] = self._get_tag(fake_lport, - 'q_port_id') - # replace ip_address with its json dump - if 'ip_addresses' in fake_lport: - ip_addresses_json = json.dumps(fake_lport['ip_addresses']) - fake_lport['ip_addresses_json'] = ip_addresses_json - return fake_lport - - def _add_lrouter_lport(self, body, lr_uuid): - new_uuid = uuidutils.generate_uuid() - fake_lport = self._build_lrouter_lport(body, new_uuid, lr_uuid) - self._fake_lrouter_lport_dict[fake_lport['uuid']] = fake_lport - try: - fake_lrouter = self._fake_lrouter_dict[lr_uuid] - except KeyError: - raise api_exc.ResourceNotFound() - fake_lrouter['lport_count'] += 1 - fake_lport_status = fake_lport.copy() - fake_lport_status['lr_tenant_id'] = fake_lrouter['tenant_id'] - fake_lport_status['lr_uuid'] = fake_lrouter['uuid'] - fake_lport_status['lr_name'] = fake_lrouter['display_name'] - self._fake_lrouter_lportstatus_dict[new_uuid] = fake_lport_status - return fake_lport - - def _add_securityprofile(self, body): - fake_securityprofile = json.loads(body) - fake_securityprofile['uuid'] = uuidutils.generate_uuid() - fake_securityprofile['tenant_id'] = self._get_tag( - fake_securityprofile, 'os_tid') - - fake_securityprofile['nova_spid'] = self._get_tag(fake_securityprofile, - 'nova_spid') - self._fake_securityprofile_dict[fake_securityprofile['uuid']] = ( - fake_securityprofile) - return fake_securityprofile - - def _add_lrouter_nat(self, body, lr_uuid): - fake_nat = json.loads(body) - new_uuid = uuidutils.generate_uuid() - fake_nat['uuid'] = new_uuid - fake_nat['lr_uuid'] = lr_uuid - self._fake_lrouter_nat_dict[fake_nat['uuid']] = fake_nat - if 'match' in fake_nat: - match_json = json.dumps(fake_nat['match']) - fake_nat['match_json'] = match_json - return fake_nat - - def _add_gatewayservice(self, body): - fake_gwservice = json.loads(body) - fake_gwservice['uuid'] = str(uuidutils.generate_uuid()) - fake_gwservice['tenant_id'] = self._get_tag( - fake_gwservice, 'os_tid') - # FIXME(salvatore-orlando): For simplicity we're managing only a - # single device. Extend the fake client for supporting multiple devices - first_gw = fake_gwservice['gateways'][0] - fake_gwservice['transport_node_uuid'] = first_gw['transport_node_uuid'] - fake_gwservice['device_id'] = first_gw['device_id'] - self._fake_gatewayservice_dict[fake_gwservice['uuid']] = ( - fake_gwservice) - return fake_gwservice - - def _build_relation(self, src, dst, resource_type, relation): - if relation not in self.MANAGED_RELATIONS[resource_type]: - return # Relation is not desired in output - if not '_relations' in src or not src['_relations'].get(relation): - return # Item does not have relation - relation_data = src['_relations'].get(relation) - dst_relations = dst.get('_relations', {}) - dst_relations[relation] = relation_data - dst['_relations'] = dst_relations - - def _fill_attachment(self, att_data, ls_uuid=None, - lr_uuid=None, lp_uuid=None): - new_data = att_data.copy() - for k in ('ls_uuid', 'lr_uuid', 'lp_uuid'): - if locals().get(k): - new_data[k] = locals()[k] - - def populate_field(field_name): - if field_name in att_data: - new_data['%s_field' % field_name] = ('"%s" : "%s",' - % (field_name, - att_data[field_name])) - del new_data[field_name] - else: - new_data['%s_field' % field_name] = "" - - for field in ['vif_uuid', 'peer_port_href', 'vlan_id', - 'peer_port_uuid', 'l3_gateway_service_uuid']: - populate_field(field) - return new_data - - def _get_resource_type(self, path): - """Get resource type. - - Identifies resource type and relevant uuids in the uri - - /ws.v1/lswitch/xxx - /ws.v1/lswitch/xxx/status - /ws.v1/lswitch/xxx/lport/yyy - /ws.v1/lswitch/xxx/lport/yyy/status - /ws.v1/lrouter/zzz - /ws.v1/lrouter/zzz/status - /ws.v1/lrouter/zzz/lport/www - /ws.v1/lrouter/zzz/lport/www/status - /ws.v1/lqueue/xxx - """ - # The first element will always be 'ws.v1' - so we just discard it - uri_split = path.split('/')[1:] - # parse uri_split backwards - suffix = "" - idx = len(uri_split) - 1 - if 'status' in uri_split[idx]: - suffix = "status" - idx = idx - 1 - elif 'attachment' in uri_split[idx]: - suffix = "attachment" - idx = idx - 1 - # then check if we have an uuid - uuids = [] - if uri_split[idx].replace('-', '') not in self.RESOURCES: - uuids.append(uri_split[idx]) - idx = idx - 1 - resource_type = "%s%s" % (uri_split[idx], suffix) - if idx > 1: - uuids.insert(0, uri_split[idx - 1]) - resource_type = "%s_%s" % (uri_split[idx - 2], resource_type) - return (resource_type.replace('-', ''), uuids) - - def _list(self, resource_type, response_file, - parent_uuid=None, query=None, relations=None): - (tag_filter, attr_filter, - page_len, page_cursor) = self._get_filters(query) - # result_count attribute in response should appear only when - # page_cursor is not specified - do_result_count = not page_cursor - with open("%s/%s" % (self.fake_files_path, response_file)) as f: - response_template = f.read() - res_dict = getattr(self, '_fake_%s_dict' % resource_type) - if parent_uuid == '*': - parent_uuid = None - # NSX raises ResourceNotFound if lswitch doesn't exist and is not * - elif not res_dict and resource_type == self.LSWITCH_LPORT_RESOURCE: - raise api_exc.ResourceNotFound() - - def _attr_match(res_uuid): - if not attr_filter: - return True - item = res_dict[res_uuid] - for (attr, value) in attr_filter.iteritems(): - if item.get(attr) != value: - return False - return True - - def _tag_match(res_uuid): - if not tag_filter: - return True - return any([x['scope'] == tag_filter['scope'] and - x['tag'] == tag_filter['tag'] - for x in res_dict[res_uuid]['tags']]) - - def _lswitch_match(res_uuid): - # verify that the switch exist - if parent_uuid and not parent_uuid in self._fake_lswitch_dict: - raise Exception(_("lswitch:%s not found") % parent_uuid) - if (not parent_uuid - or res_dict[res_uuid].get('ls_uuid') == parent_uuid): - return True - return False - - def _lrouter_match(res_uuid): - # verify that the router exist - if parent_uuid and not parent_uuid in self._fake_lrouter_dict: - raise Exception(_("lrouter:%s not found") % parent_uuid) - if (not parent_uuid or - res_dict[res_uuid].get('lr_uuid') == parent_uuid): - return True - return False - - def _cursor_match(res_uuid, page_cursor): - if not page_cursor: - return True - if page_cursor == res_uuid: - # always return True once page_cursor has been found - page_cursor = None - return True - return False - - def _build_item(resource): - item = json.loads(response_template % resource) - if relations: - for relation in relations: - self._build_relation(resource, item, - resource_type, relation) - return item - - for item in res_dict.itervalues(): - if 'tags' in item: - item['tags_json'] = json.dumps(item['tags']) - if resource_type in (self.LSWITCH_LPORT_RESOURCE, - self.LSWITCH_LPORT_ATT, - self.LSWITCH_LPORT_STATUS): - parent_func = _lswitch_match - elif resource_type in (self.LROUTER_LPORT_RESOURCE, - self.LROUTER_LPORT_ATT, - self.LROUTER_NAT_RESOURCE, - self.LROUTER_LPORT_STATUS): - parent_func = _lrouter_match - else: - parent_func = lambda x: True - - items = [_build_item(res_dict[res_uuid]) - for res_uuid in res_dict - if (parent_func(res_uuid) and - _tag_match(res_uuid) and - _attr_match(res_uuid) and - _cursor_match(res_uuid, page_cursor))] - # Rather inefficient, but hey this is just a mock! - next_cursor = None - total_items = len(items) - if page_len: - try: - next_cursor = items[page_len]['uuid'] - except IndexError: - next_cursor = None - items = items[:page_len] - response_dict = {'results': items} - if next_cursor: - response_dict['page_cursor'] = next_cursor - if do_result_count: - response_dict['result_count'] = total_items - return json.dumps(response_dict) - - def _show(self, resource_type, response_file, - uuid1, uuid2=None, relations=None): - target_uuid = uuid2 or uuid1 - if resource_type.endswith('attachment'): - resource_type = resource_type[:resource_type.index('attachment')] - with open("%s/%s" % (self.fake_files_path, response_file)) as f: - response_template = f.read() - res_dict = getattr(self, '_fake_%s_dict' % resource_type) - for item in res_dict.itervalues(): - if 'tags' in item: - item['tags_json'] = json.dumps(item['tags']) - - # replace sec prof rules with their json dump - def jsonify_rules(rule_key): - if rule_key in item: - rules_json = json.dumps(item[rule_key]) - item['%s_json' % rule_key] = rules_json - jsonify_rules('logical_port_egress_rules') - jsonify_rules('logical_port_ingress_rules') - - items = [json.loads(response_template % res_dict[res_uuid]) - for res_uuid in res_dict if res_uuid == target_uuid] - if items: - return json.dumps(items[0]) - raise api_exc.ResourceNotFound() - - def handle_get(self, url): - #TODO(salvatore-orlando): handle field selection - parsedurl = urlparse.urlparse(url) - (res_type, uuids) = self._get_resource_type(parsedurl.path) - relations = urlparse.parse_qs(parsedurl.query).get('relations') - response_file = self.FAKE_GET_RESPONSES.get(res_type) - if not response_file: - raise api_exc.NsxApiException() - if 'lport' in res_type or 'nat' in res_type: - if len(uuids) > 1: - return self._show(res_type, response_file, uuids[0], - uuids[1], relations=relations) - else: - return self._list(res_type, response_file, uuids[0], - query=parsedurl.query, relations=relations) - elif ('lswitch' in res_type or - 'lrouter' in res_type or - self.SECPROF_RESOURCE in res_type or - self.LQUEUE_RESOURCE in res_type or - 'gatewayservice' in res_type): - LOG.debug("UUIDS:%s", uuids) - if uuids: - return self._show(res_type, response_file, uuids[0], - relations=relations) - else: - return self._list(res_type, response_file, - query=parsedurl.query, - relations=relations) - else: - raise Exception("unknown resource:%s" % res_type) - - def handle_post(self, url, body): - parsedurl = urlparse.urlparse(url) - (res_type, uuids) = self._get_resource_type(parsedurl.path) - response_file = self.FAKE_POST_RESPONSES.get(res_type) - if not response_file: - raise Exception("resource not found") - with open("%s/%s" % (self.fake_files_path, response_file)) as f: - response_template = f.read() - add_resource = getattr(self, '_add_%s' % res_type) - body_json = json.loads(body) - val_func = self._validators.get(res_type) - if val_func: - val_func(body_json) - args = [body] - if uuids: - args.append(uuids[0]) - response = response_template % add_resource(*args) - return response - - def handle_put(self, url, body): - parsedurl = urlparse.urlparse(url) - (res_type, uuids) = self._get_resource_type(parsedurl.path) - response_file = self.FAKE_PUT_RESPONSES.get(res_type) - if not response_file: - raise Exception("resource not found") - with open("%s/%s" % (self.fake_files_path, response_file)) as f: - response_template = f.read() - # Manage attachment operations - is_attachment = False - if res_type.endswith('attachment'): - is_attachment = True - res_type = res_type[:res_type.index('attachment')] - res_dict = getattr(self, '_fake_%s_dict' % res_type) - body_json = json.loads(body) - val_func = self._validators.get(res_type) - if val_func: - val_func(body_json) - try: - resource = res_dict[uuids[-1]] - except KeyError: - raise api_exc.ResourceNotFound() - if not is_attachment: - edit_resource = getattr(self, '_build_%s' % res_type, None) - if edit_resource: - body_json = edit_resource(body) - resource.update(body_json) - else: - relations = resource.get("_relations", {}) - body_2 = json.loads(body) - resource['att_type'] = body_2['type'] - relations['LogicalPortAttachment'] = body_2 - resource['_relations'] = relations - if body_2['type'] == "PatchAttachment": - # We need to do a trick here - if self.LROUTER_RESOURCE in res_type: - res_type_2 = res_type.replace(self.LROUTER_RESOURCE, - self.LSWITCH_RESOURCE) - elif self.LSWITCH_RESOURCE in res_type: - res_type_2 = res_type.replace(self.LSWITCH_RESOURCE, - self.LROUTER_RESOURCE) - res_dict_2 = getattr(self, '_fake_%s_dict' % res_type_2) - body_2['peer_port_uuid'] = uuids[-1] - resource_2 = res_dict_2[json.loads(body)['peer_port_uuid']] - relations_2 = resource_2.get("_relations") - if not relations_2: - relations_2 = {} - relations_2['LogicalPortAttachment'] = body_2 - resource_2['_relations'] = relations_2 - resource['peer_port_uuid'] = body_2['peer_port_uuid'] - resource['att_info_json'] = ( - "\"peer_port_uuid\": \"%s\"," % - resource_2['uuid']) - resource_2['att_info_json'] = ( - "\"peer_port_uuid\": \"%s\"," % - body_2['peer_port_uuid']) - elif body_2['type'] == "L3GatewayAttachment": - resource['attachment_gwsvc_uuid'] = ( - body_2['l3_gateway_service_uuid']) - resource['vlan_id'] = body_2.get('vlan_id') - elif body_2['type'] == "L2GatewayAttachment": - resource['attachment_gwsvc_uuid'] = ( - body_2['l2_gateway_service_uuid']) - elif body_2['type'] == "VifAttachment": - resource['vif_uuid'] = body_2['vif_uuid'] - resource['att_info_json'] = ( - "\"vif_uuid\": \"%s\"," % body_2['vif_uuid']) - - if not is_attachment: - response = response_template % resource - else: - if res_type == self.LROUTER_LPORT_RESOURCE: - lr_uuid = uuids[0] - ls_uuid = None - elif res_type == self.LSWITCH_LPORT_RESOURCE: - ls_uuid = uuids[0] - lr_uuid = None - lp_uuid = uuids[1] - response = response_template % self._fill_attachment( - json.loads(body), ls_uuid, lr_uuid, lp_uuid) - return response - - def handle_delete(self, url): - parsedurl = urlparse.urlparse(url) - (res_type, uuids) = self._get_resource_type(parsedurl.path) - response_file = self.FAKE_PUT_RESPONSES.get(res_type) - if not response_file: - raise Exception("resource not found") - res_dict = getattr(self, '_fake_%s_dict' % res_type) - try: - del res_dict[uuids[-1]] - except KeyError: - raise api_exc.ResourceNotFound() - return "" - - def fake_request(self, *args, **kwargs): - method = args[0] - handler = getattr(self, "handle_%s" % method.lower()) - return handler(*args[1:]) - - def reset_all(self): - self._fake_lswitch_dict.clear() - self._fake_lrouter_dict.clear() - self._fake_lswitch_lport_dict.clear() - self._fake_lrouter_lport_dict.clear() - self._fake_lswitch_lportstatus_dict.clear() - self._fake_lrouter_lportstatus_dict.clear() - self._fake_lqueue_dict.clear() - self._fake_securityprofile_dict.clear() - self._fake_gatewayservice_dict.clear() diff --git a/neutron/tests/unit/vmware/apiclient/test_api_common.py b/neutron/tests/unit/vmware/apiclient/test_api_common.py deleted file mode 100644 index 5ea40d0d8..000000000 --- a/neutron/tests/unit/vmware/apiclient/test_api_common.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2011 VMware, Inc. -# -# All Rights Reserved -# -# 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 httplib - -from neutron.plugins.vmware import api_client -from neutron.tests import base - - -class ApiCommonTest(base.BaseTestCase): - - def test_ctrl_conn_to_str(self): - conn = httplib.HTTPSConnection('localhost', 4242, timeout=0) - self.assertTrue( - api_client.ctrl_conn_to_str(conn) == 'https://localhost:4242') - - conn = httplib.HTTPConnection('localhost', 4242, timeout=0) - self.assertTrue( - api_client.ctrl_conn_to_str(conn) == 'http://localhost:4242') - - self.assertRaises(TypeError, api_client.ctrl_conn_to_str, - ('not an httplib.HTTPSConnection')) diff --git a/neutron/tests/unit/vmware/apiclient/test_api_eventlet_request.py b/neutron/tests/unit/vmware/apiclient/test_api_eventlet_request.py deleted file mode 100644 index b3e036909..000000000 --- a/neutron/tests/unit/vmware/apiclient/test_api_eventlet_request.py +++ /dev/null @@ -1,331 +0,0 @@ -# Copyright (C) 2009-2012 VMware, Inc. All Rights Reserved. -# -# 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 httplib -import logging -import new -import random - -import eventlet -from eventlet.green import urllib2 -import mock - -from neutron.plugins.vmware.api_client import eventlet_client as client -from neutron.plugins.vmware.api_client import eventlet_request as request -from neutron.tests import base -from neutron.tests.unit import vmware - - -logging.basicConfig(level=logging.DEBUG) -LOG = logging.getLogger("test_api_request_eventlet") - - -REQUEST_TIMEOUT = 1 - - -def fetch(url): - return urllib2.urlopen(url).read() - - -class ApiRequestEventletTest(base.BaseTestCase): - - def setUp(self): - - super(ApiRequestEventletTest, self).setUp() - self.client = client.EventletApiClient( - [("127.0.0.1", 4401, True)], "admin", "admin") - self.url = "/ws.v1/_debug" - self.req = request.EventletApiRequest(self.client, self.url) - - def tearDown(self): - self.client = None - self.req = None - super(ApiRequestEventletTest, self).tearDown() - - def test_construct_eventlet_api_request(self): - e = request.EventletApiRequest(self.client, self.url) - self.assertIsNotNone(e) - - def test_apirequest_spawn(self): - def x(id): - eventlet.greenthread.sleep(random.random()) - LOG.info('spawned: %d' % id) - - for i in range(10): - request.EventletApiRequest._spawn(x, i) - - def test_apirequest_start(self): - for i in range(10): - a = request.EventletApiRequest( - self.client, self.url, request_timeout=0.1) - a._handle_request = mock.Mock() - a.start() - eventlet.greenthread.sleep(0.1) - logging.info('_handle_request called: %s' % - a._handle_request.called) - request.EventletApiRequest.joinall() - - def test_join_with_handle_request(self): - self.req._handle_request = mock.Mock() - self.req.start() - self.req.join() - self.assertTrue(self.req._handle_request.called) - - def test_join_without_handle_request(self): - self.req._handle_request = mock.Mock() - self.req.join() - self.assertFalse(self.req._handle_request.called) - - def test_copy(self): - req = self.req.copy() - for att in [ - '_api_client', '_url', '_method', '_body', '_headers', - '_http_timeout', '_request_timeout', '_retries', - '_redirects', '_auto_login']: - self.assertTrue(getattr(req, att) is getattr(self.req, att)) - - def test_request_error(self): - self.assertIsNone(self.req.request_error) - - def test_run_and_handle_request(self): - self.req._request_timeout = None - self.req._handle_request = mock.Mock() - self.req.start() - self.req.join() - self.assertTrue(self.req._handle_request.called) - - def test_run_and_timeout(self): - def my_handle_request(self): - LOG.info('my_handle_request() self: %s' % self) - LOG.info('my_handle_request() dir(self): %s' % dir(self)) - eventlet.greenthread.sleep(REQUEST_TIMEOUT * 2) - - self.req._request_timeout = REQUEST_TIMEOUT - self.req._handle_request = new.instancemethod( - my_handle_request, self.req, request.EventletApiRequest) - self.req.start() - self.assertIsNone(self.req.join()) - - def prep_issue_request(self): - mysock = mock.Mock() - mysock.gettimeout.return_value = 4242 - - myresponse = mock.Mock() - myresponse.read.return_value = 'body' - myresponse.getheaders.return_value = 'headers' - myresponse.status = httplib.MOVED_PERMANENTLY - - myconn = mock.Mock() - myconn.request.return_value = None - myconn.sock = mysock - myconn.getresponse.return_value = myresponse - myconn.__str__ = mock.Mock() - myconn.__str__.return_value = 'myconn string' - - req = self.req - req._redirect_params = mock.Mock() - req._redirect_params.return_value = (myconn, 'url') - req._request_str = mock.Mock() - req._request_str.return_value = 'http://cool/cool' - - client = self.client - client.need_login = False - client._auto_login = False - client._auth_cookie = False - client.acquire_connection = mock.Mock() - client.acquire_connection.return_value = myconn - client.release_connection = mock.Mock() - - return (mysock, myresponse, myconn) - - def test_issue_request_trigger_exception(self): - (mysock, myresponse, myconn) = self.prep_issue_request() - self.client.acquire_connection.return_value = None - - self.req._issue_request() - self.assertIsInstance(self.req._request_error, Exception) - self.assertTrue(self.client.acquire_connection.called) - - def test_issue_request_handle_none_sock(self): - (mysock, myresponse, myconn) = self.prep_issue_request() - myconn.sock = None - self.req.start() - self.assertIsNone(self.req.join()) - self.assertTrue(self.client.acquire_connection.called) - - def test_issue_request_exceed_maximum_retries(self): - (mysock, myresponse, myconn) = self.prep_issue_request() - self.req.start() - self.assertIsNone(self.req.join()) - self.assertTrue(self.client.acquire_connection.called) - - def test_issue_request_trigger_non_redirect(self): - (mysock, myresponse, myconn) = self.prep_issue_request() - myresponse.status = httplib.OK - self.req.start() - self.assertIsNone(self.req.join()) - self.assertTrue(self.client.acquire_connection.called) - - def test_issue_request_trigger_internal_server_error(self): - (mysock, myresponse, myconn) = self.prep_issue_request() - self.req._redirect_params.return_value = (myconn, None) - self.req.start() - self.assertIsNone(self.req.join()) - self.assertTrue(self.client.acquire_connection.called) - - def test_redirect_params_break_on_location(self): - myconn = mock.Mock() - (conn, retval) = self.req._redirect_params( - myconn, [('location', None)]) - self.assertIsNone(retval) - - def test_redirect_params_parse_a_url(self): - myconn = mock.Mock() - (conn, retval) = self.req._redirect_params( - myconn, [('location', '/path/a/b/c')]) - self.assertIsNotNone(retval) - - def test_redirect_params_invalid_redirect_location(self): - myconn = mock.Mock() - (conn, retval) = self.req._redirect_params( - myconn, [('location', '+path/a/b/c')]) - self.assertIsNone(retval) - - def test_redirect_params_invalid_scheme(self): - myconn = mock.Mock() - (conn, retval) = self.req._redirect_params( - myconn, [('location', 'invalidscheme://hostname:1/path')]) - self.assertIsNone(retval) - - def test_redirect_params_setup_https_with_cooki(self): - with mock.patch(vmware.CLIENT_NAME) as mock_client: - api_client = mock_client.return_value - self.req._api_client = api_client - myconn = mock.Mock() - (conn, retval) = self.req._redirect_params( - myconn, [('location', 'https://host:1/path')]) - - self.assertIsNotNone(retval) - self.assertTrue(api_client.acquire_redirect_connection.called) - - def test_redirect_params_setup_htttps_and_query(self): - with mock.patch(vmware.CLIENT_NAME) as mock_client: - api_client = mock_client.return_value - self.req._api_client = api_client - myconn = mock.Mock() - (conn, retval) = self.req._redirect_params(myconn, [ - ('location', 'https://host:1/path?q=1')]) - - self.assertIsNotNone(retval) - self.assertTrue(api_client.acquire_redirect_connection.called) - - def test_redirect_params_setup_https_connection_no_cookie(self): - with mock.patch(vmware.CLIENT_NAME) as mock_client: - api_client = mock_client.return_value - self.req._api_client = api_client - myconn = mock.Mock() - (conn, retval) = self.req._redirect_params(myconn, [ - ('location', 'https://host:1/path')]) - - self.assertIsNotNone(retval) - self.assertTrue(api_client.acquire_redirect_connection.called) - - def test_redirect_params_setup_https_and_query_no_cookie(self): - with mock.patch(vmware.CLIENT_NAME) as mock_client: - api_client = mock_client.return_value - self.req._api_client = api_client - myconn = mock.Mock() - (conn, retval) = self.req._redirect_params( - myconn, [('location', 'https://host:1/path?q=1')]) - self.assertIsNotNone(retval) - self.assertTrue(api_client.acquire_redirect_connection.called) - - def test_redirect_params_path_only_with_query(self): - with mock.patch(vmware.CLIENT_NAME) as mock_client: - api_client = mock_client.return_value - api_client.wait_for_login.return_value = None - api_client.auth_cookie = None - api_client.acquire_connection.return_value = True - myconn = mock.Mock() - (conn, retval) = self.req._redirect_params(myconn, [ - ('location', '/path?q=1')]) - self.assertIsNotNone(retval) - - def test_handle_request_auto_login(self): - self.req._auto_login = True - self.req._api_client = mock.Mock() - self.req._api_client.need_login = True - self.req._request_str = mock.Mock() - self.req._request_str.return_value = 'http://cool/cool' - self.req.spawn = mock.Mock() - self.req._handle_request() - - def test_handle_request_auto_login_unauth(self): - self.req._auto_login = True - self.req._api_client = mock.Mock() - self.req._api_client.need_login = True - self.req._request_str = mock.Mock() - self.req._request_str.return_value = 'http://cool/cool' - - import socket - resp = httplib.HTTPResponse(socket.socket()) - resp.status = httplib.UNAUTHORIZED - mywaiter = mock.Mock() - mywaiter.wait = mock.Mock() - mywaiter.wait.return_value = resp - self.req.spawn = mock.Mock(return_value=mywaiter) - self.req._handle_request() - - def test_construct_eventlet_login_request(self): - r = request.LoginRequestEventlet(self.client, 'user', 'password') - self.assertIsNotNone(r) - - def test_session_cookie_session_cookie_retrieval(self): - r = request.LoginRequestEventlet(self.client, 'user', 'password') - r.successful = mock.Mock() - r.successful.return_value = True - r.value = mock.Mock() - r.value.get_header = mock.Mock() - r.value.get_header.return_value = 'cool' - self.assertIsNotNone(r.session_cookie()) - - def test_session_cookie_not_retrieved(self): - r = request.LoginRequestEventlet(self.client, 'user', 'password') - r.successful = mock.Mock() - r.successful.return_value = False - r.value = mock.Mock() - r.value.get_header = mock.Mock() - r.value.get_header.return_value = 'cool' - self.assertIsNone(r.session_cookie()) - - def test_construct_eventlet_get_api_providers_request(self): - r = request.GetApiProvidersRequestEventlet(self.client) - self.assertIsNotNone(r) - - def test_api_providers_none_api_providers(self): - r = request.GetApiProvidersRequestEventlet(self.client) - r.successful = mock.Mock(return_value=False) - self.assertIsNone(r.api_providers()) - - def test_api_providers_non_none_api_providers(self): - r = request.GetApiProvidersRequestEventlet(self.client) - r.value = mock.Mock() - r.value.body = """{ - "results": [ - { "roles": [ - { "role": "api_provider", - "listen_addr": "pssl:1.1.1.1:1" }]}]}""" - r.successful = mock.Mock(return_value=True) - LOG.info('%s' % r.api_providers()) - self.assertIsNotNone(r.api_providers()) diff --git a/neutron/tests/unit/vmware/db/__init__.py b/neutron/tests/unit/vmware/db/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/vmware/db/test_lsn_db.py b/neutron/tests/unit/vmware/db/test_lsn_db.py deleted file mode 100644 index 34641de53..000000000 --- a/neutron/tests/unit/vmware/db/test_lsn_db.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright 2014 VMware, Inc. -# -# 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. - -from sqlalchemy import orm - -from neutron import context -from neutron.db import api as db -from neutron.plugins.vmware.common import exceptions as p_exc -from neutron.plugins.vmware.dbexts import lsn_db -from neutron.tests import base - - -class LSNTestCase(base.BaseTestCase): - - def setUp(self): - super(LSNTestCase, self).setUp() - db.configure_db() - self.ctx = context.get_admin_context() - self.addCleanup(db.clear_db) - self.net_id = 'foo_network_id' - self.lsn_id = 'foo_lsn_id' - self.lsn_port_id = 'foo_port_id' - self.subnet_id = 'foo_subnet_id' - self.mac_addr = 'aa:bb:cc:dd:ee:ff' - - def test_lsn_add(self): - lsn_db.lsn_add(self.ctx, self.net_id, self.lsn_id) - lsn = (self.ctx.session.query(lsn_db.Lsn). - filter_by(lsn_id=self.lsn_id).one()) - self.assertEqual(self.lsn_id, lsn.lsn_id) - - def test_lsn_remove(self): - lsn_db.lsn_add(self.ctx, self.net_id, self.lsn_id) - lsn_db.lsn_remove(self.ctx, self.lsn_id) - q = self.ctx.session.query(lsn_db.Lsn).filter_by(lsn_id=self.lsn_id) - self.assertRaises(orm.exc.NoResultFound, q.one) - - def test_lsn_remove_for_network(self): - lsn_db.lsn_add(self.ctx, self.net_id, self.lsn_id) - lsn_db.lsn_remove_for_network(self.ctx, self.net_id) - q = self.ctx.session.query(lsn_db.Lsn).filter_by(lsn_id=self.lsn_id) - self.assertRaises(orm.exc.NoResultFound, q.one) - - def test_lsn_get_for_network(self): - result = lsn_db.lsn_get_for_network(self.ctx, self.net_id, - raise_on_err=False) - self.assertIsNone(result) - - def test_lsn_get_for_network_raise_not_found(self): - self.assertRaises(p_exc.LsnNotFound, - lsn_db.lsn_get_for_network, - self.ctx, self.net_id) - - def test_lsn_port_add(self): - lsn_db.lsn_add(self.ctx, self.net_id, self.lsn_id) - lsn_db.lsn_port_add_for_lsn(self.ctx, self.lsn_port_id, - self.subnet_id, self.mac_addr, self.lsn_id) - result = (self.ctx.session.query(lsn_db.LsnPort). - filter_by(lsn_port_id=self.lsn_port_id).one()) - self.assertEqual(self.lsn_port_id, result.lsn_port_id) - - def test_lsn_port_get_for_mac(self): - lsn_db.lsn_add(self.ctx, self.net_id, self.lsn_id) - lsn_db.lsn_port_add_for_lsn(self.ctx, self.lsn_port_id, - self.subnet_id, self.mac_addr, self.lsn_id) - result = lsn_db.lsn_port_get_for_mac(self.ctx, self.mac_addr) - self.assertEqual(self.mac_addr, result.mac_addr) - - def test_lsn_port_get_for_mac_raise_not_found(self): - self.assertRaises(p_exc.LsnPortNotFound, - lsn_db.lsn_port_get_for_mac, - self.ctx, self.mac_addr) - - def test_lsn_port_get_for_subnet(self): - lsn_db.lsn_add(self.ctx, self.net_id, self.lsn_id) - lsn_db.lsn_port_add_for_lsn(self.ctx, self.lsn_port_id, - self.subnet_id, self.mac_addr, self.lsn_id) - result = lsn_db.lsn_port_get_for_subnet(self.ctx, self.subnet_id) - self.assertEqual(self.subnet_id, result.sub_id) - - def test_lsn_port_get_for_subnet_raise_not_found(self): - self.assertRaises(p_exc.LsnPortNotFound, - lsn_db.lsn_port_get_for_subnet, - self.ctx, self.mac_addr) - - def test_lsn_port_remove(self): - lsn_db.lsn_add(self.ctx, self.net_id, self.lsn_id) - lsn_db.lsn_port_remove(self.ctx, self.lsn_port_id) - q = (self.ctx.session.query(lsn_db.LsnPort). - filter_by(lsn_port_id=self.lsn_port_id)) - self.assertRaises(orm.exc.NoResultFound, q.one) diff --git a/neutron/tests/unit/vmware/db/test_nsx_db.py b/neutron/tests/unit/vmware/db/test_nsx_db.py deleted file mode 100644 index 722e22a76..000000000 --- a/neutron/tests/unit/vmware/db/test_nsx_db.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2013 VMware, Inc. -# -# 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. - -from neutron import context -from neutron.db import api as db -from neutron.db import models_v2 -from neutron.openstack.common.db import exception as d_exc -from neutron.plugins.vmware.dbexts import db as nsx_db -from neutron.plugins.vmware.dbexts import models -from neutron.tests import base - - -class NsxDBTestCase(base.BaseTestCase): - - def setUp(self): - super(NsxDBTestCase, self).setUp() - db.configure_db() - self.ctx = context.get_admin_context() - self.addCleanup(db.clear_db) - - def _setup_neutron_network_and_port(self, network_id, port_id): - with self.ctx.session.begin(subtransactions=True): - self.ctx.session.add(models_v2.Network(id=network_id)) - port = models_v2.Port(id=port_id, - network_id=network_id, - mac_address='foo_mac_address', - admin_state_up=True, - status='ACTIVE', - device_id='', - device_owner='') - self.ctx.session.add(port) - - def test_add_neutron_nsx_port_mapping_handle_duplicate_constraint(self): - neutron_net_id = 'foo_neutron_network_id' - neutron_port_id = 'foo_neutron_port_id' - nsx_port_id = 'foo_nsx_port_id' - nsx_switch_id = 'foo_nsx_switch_id' - self._setup_neutron_network_and_port(neutron_net_id, neutron_port_id) - - nsx_db.add_neutron_nsx_port_mapping( - self.ctx.session, neutron_port_id, nsx_switch_id, nsx_port_id) - # Call the method twice to trigger a db duplicate constraint error - nsx_db.add_neutron_nsx_port_mapping( - self.ctx.session, neutron_port_id, nsx_switch_id, nsx_port_id) - result = (self.ctx.session.query(models.NeutronNsxPortMapping). - filter_by(neutron_id=neutron_port_id).one()) - self.assertEqual(nsx_port_id, result.nsx_port_id) - self.assertEqual(neutron_port_id, result.neutron_id) - - def test_add_neutron_nsx_port_mapping_raise_on_duplicate_constraint(self): - neutron_net_id = 'foo_neutron_network_id' - neutron_port_id = 'foo_neutron_port_id' - nsx_port_id_1 = 'foo_nsx_port_id_1' - nsx_port_id_2 = 'foo_nsx_port_id_2' - nsx_switch_id = 'foo_nsx_switch_id' - self._setup_neutron_network_and_port(neutron_net_id, neutron_port_id) - - nsx_db.add_neutron_nsx_port_mapping( - self.ctx.session, neutron_port_id, nsx_switch_id, nsx_port_id_1) - # Call the method twice to trigger a db duplicate constraint error, - # this time with a different nsx port id! - self.assertRaises(d_exc.DBDuplicateEntry, - nsx_db.add_neutron_nsx_port_mapping, - self.ctx.session, neutron_port_id, - nsx_switch_id, nsx_port_id_2) - - def test_add_neutron_nsx_port_mapping_raise_integrity_constraint(self): - neutron_port_id = 'foo_neutron_port_id' - nsx_port_id = 'foo_nsx_port_id' - nsx_switch_id = 'foo_nsx_switch_id' - self.assertRaises(d_exc.DBError, - nsx_db.add_neutron_nsx_port_mapping, - self.ctx.session, neutron_port_id, - nsx_switch_id, nsx_port_id) diff --git a/neutron/tests/unit/vmware/etc/fake_get_gwservice.json b/neutron/tests/unit/vmware/etc/fake_get_gwservice.json deleted file mode 100644 index 5c8f9a376..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_gwservice.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "display_name": "%(display_name)s", - "_href": "/ws.v1/gateway-service/%(uuid)s", - "tags": %(tags_json)s, - "_schema": "/ws.v1/schema/L2GatewayServiceConfig", - "gateways": [ - { - "transport_node_uuid": "%(transport_node_uuid)s", - "type": "L2Gateway", - "device_id": "%(device_id)s" - } - ], - "type": "L2GatewayServiceConfig", - "uuid": "%(uuid)s" -} diff --git a/neutron/tests/unit/vmware/etc/fake_get_lqueue.json b/neutron/tests/unit/vmware/etc/fake_get_lqueue.json deleted file mode 100644 index 414945bb6..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_lqueue.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "display_name": "%(display_name)s", - "uuid": "%(uuid)s", - "type": "LogicalSwitchConfig", - "_schema": "/ws.v1/schema/LogicalQueueConfig", - "dscp": "%(dscp)s", - "max_bandwidth_rate": "%(max_bandwidth_rate)s", - "min_bandwidth_rate": "%(min_bandwidth_rate)s", - "qos_marking": "%(qos_marking)s", - "_href": "/ws.v1/lqueue/%(uuid)s" -} diff --git a/neutron/tests/unit/vmware/etc/fake_get_lrouter.json b/neutron/tests/unit/vmware/etc/fake_get_lrouter.json deleted file mode 100644 index 9425ad654..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_lrouter.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "display_name": "%(display_name)s", - %(distributed_json)s - "uuid": "%(uuid)s", - "tags": %(tags_json)s, - "routing_config": { - "type": "SingleDefaultRouteImplicitRoutingConfig", - "_schema": "/ws.v1/schema/SingleDefaultRouteImplicitRoutingConfig", - "default_route_next_hop": { - "type": "RouterNextHop", - "_schema": "/ws.v1/schema/RouterNextHop", - "gateway_ip_address": "%(default_next_hop)s" - } - }, - "_schema": "/ws.v1/schema/LogicalRouterConfig", - "_relations": { - "LogicalRouterStatus": { - "_href": "/ws.v1/lrouter/%(uuid)s/status", - "lport_admin_up_count": %(lport_count)d, - "_schema": "/ws.v1/schema/LogicalRouterStatus", - "lport_count": %(lport_count)d, - "fabric_status": %(status)s, - "type": "LogicalRouterStatus", - "lport_link_up_count": %(lport_count)d - } - }, - "type": "LogicalRouterConfig", - "_href": "/ws.v1/lrouter/%(uuid)s" -} \ No newline at end of file diff --git a/neutron/tests/unit/vmware/etc/fake_get_lrouter_lport.json b/neutron/tests/unit/vmware/etc/fake_get_lrouter_lport.json deleted file mode 100644 index df9fcbea7..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_lrouter_lport.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "display_name": "%(display_name)s", - "admin_status_enabled": "%(admin_status_enabled)s", - "_href": "/ws.v1/lrouter/%(lr_uuid)s/lport/%(uuid)s", - "tags": - [{"scope": "q_port_id", "tag": "%(neutron_port_id)s"}, - {"scope": "os_tid", "tag": "%(tenant_id)s"}], - "ip_addresses": %(ip_addresses_json)s, - "_schema": "/ws.v1/schema/LogicalRouterPortConfig", - "type": "LogicalRouterPortConfig", - "uuid": "%(uuid)s" -} diff --git a/neutron/tests/unit/vmware/etc/fake_get_lrouter_lport_att.json b/neutron/tests/unit/vmware/etc/fake_get_lrouter_lport_att.json deleted file mode 100644 index bc5723d11..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_lrouter_lport_att.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "LogicalPortAttachment": - { - %(peer_port_href_field)s - %(peer_port_uuid_field)s - %(l3_gateway_service_uuid_field)s - %(vlan_id)s - "type": "%(type)s", - "schema": "/ws.v1/schema/%(type)s" - } -} \ No newline at end of file diff --git a/neutron/tests/unit/vmware/etc/fake_get_lrouter_nat.json b/neutron/tests/unit/vmware/etc/fake_get_lrouter_nat.json deleted file mode 100644 index 5f7c8baac..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_lrouter_nat.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "_href": "/ws.v1/lrouter/%(lr_uuid)s/nat/%(uuid)s", - "type": "%(type)s", - "match": %(match_json)s, - "uuid": "%(uuid)s" -} \ No newline at end of file diff --git a/neutron/tests/unit/vmware/etc/fake_get_lswitch.json b/neutron/tests/unit/vmware/etc/fake_get_lswitch.json deleted file mode 100644 index a55d508c7..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_lswitch.json +++ /dev/null @@ -1,12 +0,0 @@ -{"display_name": "%(display_name)s", - "_href": "/ws.v1/lswitch/%(uuid)s", - "_schema": "/ws.v1/schema/LogicalSwitchConfig", - "_relations": {"LogicalSwitchStatus": - {"fabric_status": %(status)s, - "type": "LogicalSwitchStatus", - "lport_count": %(lport_count)d, - "_href": "/ws.v1/lswitch/%(uuid)s/status", - "_schema": "/ws.v1/schema/LogicalSwitchStatus"}}, - "type": "LogicalSwitchConfig", - "tags": %(tags_json)s, - "uuid": "%(uuid)s"} diff --git a/neutron/tests/unit/vmware/etc/fake_get_lswitch_lport.json b/neutron/tests/unit/vmware/etc/fake_get_lswitch_lport.json deleted file mode 100644 index 3e5cb90c2..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_lswitch_lport.json +++ /dev/null @@ -1,28 +0,0 @@ -{"display_name": "%(display_name)s", - "_relations": - {"LogicalPortStatus": - {"type": "LogicalSwitchPortStatus", - "admin_status_enabled": true, - "fabric_status_up": %(status)s, - "link_status_up": %(status)s, - "_href": "/ws.v1/lswitch/%(ls_uuid)s/lport/%(uuid)s/status", - "_schema": "/ws.v1/schema/LogicalSwitchPortStatus"}, - "LogicalSwitchConfig": - {"uuid": "%(ls_uuid)s"}, - "LogicalPortAttachment": - { - "type": "%(att_type)s", - %(att_info_json)s - "schema": "/ws.v1/schema/%(att_type)s" - } - }, - "tags": - [{"scope": "q_port_id", "tag": "%(neutron_port_id)s"}, - {"scope": "vm_id", "tag": "%(neutron_device_id)s"}, - {"scope": "os_tid", "tag": "%(tenant_id)s"}], - "uuid": "%(uuid)s", - "admin_status_enabled": "%(admin_status_enabled)s", - "type": "LogicalSwitchPortConfig", - "_schema": "/ws.v1/schema/LogicalSwitchPortConfig", - "_href": "/ws.v1/lswitch/%(ls_uuid)s/lport/%(uuid)s" - } diff --git a/neutron/tests/unit/vmware/etc/fake_get_lswitch_lport_att.json b/neutron/tests/unit/vmware/etc/fake_get_lswitch_lport_att.json deleted file mode 100644 index cd1788b02..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_lswitch_lport_att.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "LogicalPortAttachment": - { - "type": "%(att_type)s", - "schema": "/ws.v1/schema/%(att_type)s" - } -} \ No newline at end of file diff --git a/neutron/tests/unit/vmware/etc/fake_get_lswitch_lport_status.json b/neutron/tests/unit/vmware/etc/fake_get_lswitch_lport_status.json deleted file mode 100644 index 0df7971b0..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_lswitch_lport_status.json +++ /dev/null @@ -1,23 +0,0 @@ -{"_href": "/ws.v1/lswitch/%(ls_uuid)s/lport/%(uuid)s", - "lswitch": - {"display_name": "%(ls_name)s", - "uuid": "%(ls_uuid)s", - "tags": [ - {"scope": "os_tid", - "tag": "%(ls_tenant_id)s"} - ], - "type": "LogicalSwitchConfig", - "_schema": "/ws.v1/schema/LogicalSwitchConfig", - "port_isolation_enabled": false, - "transport_zones": [ - {"zone_uuid": "%(ls_zone_uuid)s", - "transport_type": "stt"} - ], - "_href": "/ws.v1/lswitch/%(ls_uuid)s"}, - "link_status_up": false, - "_schema": "/ws.v1/schema/LogicalSwitchPortStatus", - "admin_status_enabled": true, - "fabric_status_up": true, - "link_status_up": true, - "type": "LogicalSwitchPortStatus" -} diff --git a/neutron/tests/unit/vmware/etc/fake_get_security_profile.json b/neutron/tests/unit/vmware/etc/fake_get_security_profile.json deleted file mode 100644 index 898e4937b..000000000 --- a/neutron/tests/unit/vmware/etc/fake_get_security_profile.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "display_name": "%(display_name)s", - "_href": "/ws.v1/security-profile/%(uuid)s", - "tags": [{"scope": "os_tid", "tag": "%(tenant_id)s"}, - {"scope": "nova_spid", "tag": "%(nova_spid)s"}], - "logical_port_egress_rules": %(logical_port_egress_rules_json)s, - "_schema": "/ws.v1/schema/SecurityProfileConfig", - "logical_port_ingress_rules": %(logical_port_ingress_rules_json)s, - "uuid": "%(uuid)s" -} diff --git a/neutron/tests/unit/vmware/etc/fake_post_gwservice.json b/neutron/tests/unit/vmware/etc/fake_post_gwservice.json deleted file mode 100644 index 72292fddc..000000000 --- a/neutron/tests/unit/vmware/etc/fake_post_gwservice.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "display_name": "%(display_name)s", - "tags": [{"scope": "os_tid", "tag": "%(tenant_id)s"}], - "gateways": [ - { - "transport_node_uuid": "%(transport_node_uuid)s", - "device_id": "%(device_id)s", - "type": "L2Gateway" - } - ], - "type": "L2GatewayServiceConfig", - "uuid": "%(uuid)s" -} diff --git a/neutron/tests/unit/vmware/etc/fake_post_lqueue.json b/neutron/tests/unit/vmware/etc/fake_post_lqueue.json deleted file mode 100644 index 414945bb6..000000000 --- a/neutron/tests/unit/vmware/etc/fake_post_lqueue.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "display_name": "%(display_name)s", - "uuid": "%(uuid)s", - "type": "LogicalSwitchConfig", - "_schema": "/ws.v1/schema/LogicalQueueConfig", - "dscp": "%(dscp)s", - "max_bandwidth_rate": "%(max_bandwidth_rate)s", - "min_bandwidth_rate": "%(min_bandwidth_rate)s", - "qos_marking": "%(qos_marking)s", - "_href": "/ws.v1/lqueue/%(uuid)s" -} diff --git a/neutron/tests/unit/vmware/etc/fake_post_lrouter.json b/neutron/tests/unit/vmware/etc/fake_post_lrouter.json deleted file mode 100644 index dbe2811b0..000000000 --- a/neutron/tests/unit/vmware/etc/fake_post_lrouter.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "display_name": "%(display_name)s", - %(distributed_json)s - "uuid": "%(uuid)s", - "tags": [ - { - "scope": "os_tid", - "tag": "%(tenant_id)s" - } - ], - "routing_config": { - "type": "SingleDefaultRouteImplicitRoutingConfig", - "_schema": "/ws.v1/schema/SingleDefaultRouteImplicitRoutingConfig", - "default_route_next_hop": { - "type": "RouterNextHop", - "_schema": "/ws.v1/schema/RouterNextHop", - "gateway_ip_address": "%(default_next_hop)s" - } - }, - "_schema": "/ws.v1/schema/LogicalRouterConfig", - "type": "LogicalRouterConfig", - "_href": "/ws.v1/lrouter/%(uuid)s" -} \ No newline at end of file diff --git a/neutron/tests/unit/vmware/etc/fake_post_lrouter_lport.json b/neutron/tests/unit/vmware/etc/fake_post_lrouter_lport.json deleted file mode 100644 index bcb13ae07..000000000 --- a/neutron/tests/unit/vmware/etc/fake_post_lrouter_lport.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "display_name": "%(display_name)s", - "_href": "/ws.v1/lrouter/%(lr_uuid)s/lport/%(uuid)s", - "_schema": "/ws.v1/schema/LogicalRouterPortConfig", - "mac_address": "00:00:00:00:00:00", - "admin_status_enabled": true, - "ip_addresses": %(ip_addresses_json)s, - "type": "LogicalRouterPortConfig", - "uuid": "%(uuid)s" -} \ No newline at end of file diff --git a/neutron/tests/unit/vmware/etc/fake_post_lrouter_nat.json b/neutron/tests/unit/vmware/etc/fake_post_lrouter_nat.json deleted file mode 100644 index 5f7c8baac..000000000 --- a/neutron/tests/unit/vmware/etc/fake_post_lrouter_nat.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "_href": "/ws.v1/lrouter/%(lr_uuid)s/nat/%(uuid)s", - "type": "%(type)s", - "match": %(match_json)s, - "uuid": "%(uuid)s" -} \ No newline at end of file diff --git a/neutron/tests/unit/vmware/etc/fake_post_lswitch.json b/neutron/tests/unit/vmware/etc/fake_post_lswitch.json deleted file mode 100644 index 7d8f9e38c..000000000 --- a/neutron/tests/unit/vmware/etc/fake_post_lswitch.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "display_name": "%(display_name)s", - "uuid": "%(uuid)s", - "tags": [{"scope": "os_tid", "tag": "%(tenant_id)s"}], - "type": "LogicalSwitchConfig", - "_schema": "/ws.v1/schema/LogicalSwitchConfig", - "port_isolation_enabled": false, - "transport_zones": [ - {"zone_uuid": "%(zone_uuid)s", - "transport_type": "stt"}], - "_href": "/ws.v1/lswitch/%(uuid)s" -} diff --git a/neutron/tests/unit/vmware/etc/fake_post_lswitch_lport.json b/neutron/tests/unit/vmware/etc/fake_post_lswitch_lport.json deleted file mode 100644 index cc8decf26..000000000 --- a/neutron/tests/unit/vmware/etc/fake_post_lswitch_lport.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "display_name": "%(uuid)s", - "_href": "/ws.v1/lswitch/%(ls_uuid)s/lport/%(uuid)s", - "security_profiles": [], - "tags": - [{"scope": "q_port_id", "tag": "%(neutron_port_id)s"}, - {"scope": "vm_id", "tag": "%(neutron_device_id)s"}, - {"scope": "os_tid", "tag": "%(tenant_id)s"}], - "portno": 1, - "queue_uuid": null, - "_schema": "/ws.v1/schema/LogicalSwitchPortConfig", - "mirror_targets": [], - "allowed_address_pairs": [], - "admin_status_enabled": true, - "type": "LogicalSwitchPortConfig", - "uuid": "%(uuid)s" -} diff --git a/neutron/tests/unit/vmware/etc/fake_post_security_profile.json b/neutron/tests/unit/vmware/etc/fake_post_security_profile.json deleted file mode 100644 index 594da3310..000000000 --- a/neutron/tests/unit/vmware/etc/fake_post_security_profile.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "display_name": "%(display_name)s", - "_href": "/ws.v1/security-profile/%(uuid)s", - "tags": [{"scope": "os_tid", "tag": "%(tenant_id)s"}, - {"scope": "nova_spid", "tag": "%(nova_spid)s"}], - "logical_port_egress_rules": [], - "_schema": "/ws.v1/schema/SecurityProfileConfig", - "logical_port_ingress_rules": [], - "uuid": "%(uuid)s" -} diff --git a/neutron/tests/unit/vmware/etc/fake_put_lrouter_lport_att.json b/neutron/tests/unit/vmware/etc/fake_put_lrouter_lport_att.json deleted file mode 100644 index c58fa41c7..000000000 --- a/neutron/tests/unit/vmware/etc/fake_put_lrouter_lport_att.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "LogicalPortAttachment": - { - %(peer_port_href_field)s - %(peer_port_uuid_field)s - %(l3_gateway_service_uuid_field)s - %(vlan_id_field)s - "_href": "/ws.v1/lrouter/%(lr_uuid)s/lport/%(lp_uuid)s/attachment", - "type": "%(type)s", - "schema": "/ws.v1/schema/%(type)s" - } -} \ No newline at end of file diff --git a/neutron/tests/unit/vmware/etc/fake_put_lswitch_lport_att.json b/neutron/tests/unit/vmware/etc/fake_put_lswitch_lport_att.json deleted file mode 100644 index dd0daa336..000000000 --- a/neutron/tests/unit/vmware/etc/fake_put_lswitch_lport_att.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "LogicalPortAttachment": - { - %(peer_port_href_field)s - %(peer_port_uuid_field)s - %(vif_uuid_field)s - "_href": "/ws.v1/lswitch/%(ls_uuid)s/lport/%(lp_uuid)s/attachment", - "type": "%(type)s", - "schema": "/ws.v1/schema/%(type)s" - } -} \ No newline at end of file diff --git a/neutron/tests/unit/vmware/etc/neutron.conf.test b/neutron/tests/unit/vmware/etc/neutron.conf.test deleted file mode 100644 index 9eff4405d..000000000 --- a/neutron/tests/unit/vmware/etc/neutron.conf.test +++ /dev/null @@ -1,26 +0,0 @@ -[DEFAULT] -# Show more verbose log output (sets INFO log level output) -verbose = True - -# Show debugging output in logs (sets DEBUG log level output) -debug = False - -# Address to bind the API server -bind_host = 0.0.0.0 - -# Port the bind the API server to -bind_port = 9696 - -# MISSING Path to the extensions -# api_extensions_path = - -# Paste configuration file -api_paste_config = api-paste.ini.test - -# The messaging module to use, defaults to kombu. -rpc_backend = neutron.openstack.common.rpc.impl_fake - -lock_path = $state_path/lock - -[database] -connection = 'sqlite://' diff --git a/neutron/tests/unit/vmware/etc/nsx.ini.agentless.test b/neutron/tests/unit/vmware/etc/nsx.ini.agentless.test deleted file mode 100644 index ee129f1d1..000000000 --- a/neutron/tests/unit/vmware/etc/nsx.ini.agentless.test +++ /dev/null @@ -1,17 +0,0 @@ -[DEFAULT] -default_tz_uuid = fake_tz_uuid -nova_zone_id = whatever -nsx_controllers = fake_1, fake_2 -nsx_user = foo -nsx_password = bar -default_l3_gw_service_uuid = whatever -default_l2_gw_service_uuid = whatever -default_service_cluster_uuid = whatever -default_interface_name = whatever -req_timeout = 14 -http_timeout = 13 -redirects = 12 -retries = 11 - -[NSX] -agent_mode = agentless diff --git a/neutron/tests/unit/vmware/etc/nsx.ini.basic.test b/neutron/tests/unit/vmware/etc/nsx.ini.basic.test deleted file mode 100644 index c8fb9886e..000000000 --- a/neutron/tests/unit/vmware/etc/nsx.ini.basic.test +++ /dev/null @@ -1,5 +0,0 @@ -[DEFAULT] -default_tz_uuid = fake_tz_uuid -nsx_controllers=fake_1,fake_2 -nsx_user=foo -nsx_password=bar diff --git a/neutron/tests/unit/vmware/etc/nsx.ini.combined.test b/neutron/tests/unit/vmware/etc/nsx.ini.combined.test deleted file mode 100644 index 2a6f8307c..000000000 --- a/neutron/tests/unit/vmware/etc/nsx.ini.combined.test +++ /dev/null @@ -1,17 +0,0 @@ -[DEFAULT] -default_tz_uuid = fake_tz_uuid -nova_zone_id = whatever -nsx_controllers = fake_1, fake_2 -nsx_user = foo -nsx_password = bar -default_l3_gw_service_uuid = whatever -default_l2_gw_service_uuid = whatever -default_service_cluster_uuid = whatever -default_interface_name = whatever -req_timeout = 14 -http_timeout = 13 -redirects = 12 -retries = 11 - -[NSX] -agent_mode = combined diff --git a/neutron/tests/unit/vmware/etc/nsx.ini.full.test b/neutron/tests/unit/vmware/etc/nsx.ini.full.test deleted file mode 100644 index 7ca29bd42..000000000 --- a/neutron/tests/unit/vmware/etc/nsx.ini.full.test +++ /dev/null @@ -1,13 +0,0 @@ -[DEFAULT] -default_tz_uuid = fake_tz_uuid -nova_zone_id = whatever -nsx_controllers = fake_1, fake_2 -nsx_user = foo -nsx_password = bar -default_l3_gw_service_uuid = whatever -default_l2_gw_service_uuid = whatever -default_interface_name = whatever -req_timeout = 14 -http_timeout = 13 -redirects = 12 -retries = 11 diff --git a/neutron/tests/unit/vmware/etc/nsx.ini.test b/neutron/tests/unit/vmware/etc/nsx.ini.test deleted file mode 100644 index 1bb959be3..000000000 --- a/neutron/tests/unit/vmware/etc/nsx.ini.test +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -default_tz_uuid = fake_tz_uuid -nsx_controllers=fake_1, fake_2 -nsx_user=foo -nsx_password=bar -default_l3_gw_service_uuid = whatever -default_l2_gw_service_uuid = whatever diff --git a/neutron/tests/unit/vmware/etc/nvp.ini.full.test b/neutron/tests/unit/vmware/etc/nvp.ini.full.test deleted file mode 100644 index 500cc0eed..000000000 --- a/neutron/tests/unit/vmware/etc/nvp.ini.full.test +++ /dev/null @@ -1,13 +0,0 @@ -[DEFAULT] -default_tz_uuid = fake_tz_uuid -nova_zone_id = whatever -nvp_controllers = fake_1, fake_2 -nvp_user = foo -nvp_password = bar -default_l3_gw_service_uuid = whatever -default_l2_gw_service_uuid = whatever -default_interface_name = whatever -req_timeout = 4 -http_timeout = 3 -redirects = 2 -retries = 2 diff --git a/neutron/tests/unit/vmware/etc/vcns.ini.test b/neutron/tests/unit/vmware/etc/vcns.ini.test deleted file mode 100644 index 38b3361ed..000000000 --- a/neutron/tests/unit/vmware/etc/vcns.ini.test +++ /dev/null @@ -1,9 +0,0 @@ -[vcns] -manager_uri = https://fake-host -user = fake-user -passwordd = fake-password -datacenter_moid = fake-moid -resource_pool_id = fake-resgroup -datastore_id = fake-datastore -external_network = fake-ext-net -task_status_check_interval = 100 diff --git a/neutron/tests/unit/vmware/extensions/__init__.py b/neutron/tests/unit/vmware/extensions/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/vmware/extensions/test_addresspairs.py b/neutron/tests/unit/vmware/extensions/test_addresspairs.py deleted file mode 100644 index be30b5bc4..000000000 --- a/neutron/tests/unit/vmware/extensions/test_addresspairs.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation. -# All Rights Reserved. -# -# 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. - -from neutron.tests.unit import test_extension_allowedaddresspairs as ext_pairs -from neutron.tests.unit.vmware import test_nsx_plugin - - -class TestAllowedAddressPairs(test_nsx_plugin.NsxPluginV2TestCase, - ext_pairs.TestAllowedAddressPairs): - pass diff --git a/neutron/tests/unit/vmware/extensions/test_maclearning.py b/neutron/tests/unit/vmware/extensions/test_maclearning.py deleted file mode 100644 index 70d65731a..000000000 --- a/neutron/tests/unit/vmware/extensions/test_maclearning.py +++ /dev/null @@ -1,139 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# All Rights Reserved. -# -# 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 contextlib -import mock - -from oslo.config import cfg - -from neutron.api.v2 import attributes -from neutron.common import test_lib -from neutron import context -from neutron.extensions import agent -from neutron.plugins.vmware.api_client import version -from neutron.plugins.vmware.common import sync -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.apiclient import fake - - -class MacLearningExtensionManager(object): - - def get_resources(self): - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - agent.RESOURCE_ATTRIBUTE_MAP) - return agent.Agent.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class MacLearningDBTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - fmt = 'json' - - def setUp(self): - self.adminContext = context.get_admin_context() - test_lib.test_config['config_files'] = [ - vmware.get_fake_conf('nsx.ini.full.test')] - cfg.CONF.set_override('api_extensions_path', vmware.NSXEXT_PATH) - # Save the original RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - ext_mgr = MacLearningExtensionManager() - # mock api client - self.fc = fake.FakeClient(vmware.STUBS_PATH) - self.mock_nsx = mock.patch(vmware.NSXAPI_NAME, autospec=True) - instance = self.mock_nsx.start() - # Avoid runs of the synchronizer looping call - patch_sync = mock.patch.object(sync, '_start_loopingcall') - patch_sync.start() - - # Emulate tests against NSX 2.x - instance.return_value.get_version.return_value = version.Version("3.0") - instance.return_value.request.side_effect = self.fc.fake_request - cfg.CONF.set_override('metadata_mode', None, 'NSX') - self.addCleanup(self.fc.reset_all) - self.addCleanup(self.restore_resource_attribute_map) - super(MacLearningDBTestCase, self).setUp(plugin=vmware.PLUGIN_NAME, - ext_mgr=ext_mgr) - - def restore_resource_attribute_map(self): - # Restore the original RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - - def test_create_with_mac_learning(self): - with self.port(arg_list=('mac_learning_enabled',), - mac_learning_enabled=True) as port: - # Validate create operation response - self.assertEqual(True, port['port']['mac_learning_enabled']) - # Verify that db operation successfully set mac learning state - req = self.new_show_request('ports', port['port']['id'], self.fmt) - sport = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(True, sport['port']['mac_learning_enabled']) - - def test_create_and_show_port_without_mac_learning(self): - with self.port() as port: - req = self.new_show_request('ports', port['port']['id'], self.fmt) - sport = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertNotIn('mac_learning_enabled', sport['port']) - - def test_update_port_with_mac_learning(self): - with self.port(arg_list=('mac_learning_enabled',), - mac_learning_enabled=False) as port: - data = {'port': {'mac_learning_enabled': True}} - req = self.new_update_request('ports', data, port['port']['id']) - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(True, res['port']['mac_learning_enabled']) - - def test_update_preexisting_port_with_mac_learning(self): - with self.port() as port: - req = self.new_show_request('ports', port['port']['id'], self.fmt) - sport = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertNotIn('mac_learning_enabled', sport['port']) - data = {'port': {'mac_learning_enabled': True}} - req = self.new_update_request('ports', data, port['port']['id']) - # Validate update operation response - res = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(True, res['port']['mac_learning_enabled']) - # Verify that db operation successfully updated mac learning state - req = self.new_show_request('ports', port['port']['id'], self.fmt) - sport = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual(True, sport['port']['mac_learning_enabled']) - - def test_list_ports(self): - # for this test we need to enable overlapping ips - cfg.CONF.set_default('allow_overlapping_ips', True) - with contextlib.nested(self.port(arg_list=('mac_learning_enabled',), - mac_learning_enabled=True), - self.port(arg_list=('mac_learning_enabled',), - mac_learning_enabled=True), - self.port(arg_list=('mac_learning_enabled',), - mac_learning_enabled=True)): - for port in self._list('ports')['ports']: - self.assertEqual(True, port['mac_learning_enabled']) - - def test_show_port(self): - with self.port(arg_list=('mac_learning_enabled',), - mac_learning_enabled=True) as p: - port_res = self._show('ports', p['port']['id'])['port'] - self.assertEqual(True, port_res['mac_learning_enabled']) diff --git a/neutron/tests/unit/vmware/extensions/test_networkgw.py b/neutron/tests/unit/vmware/extensions/test_networkgw.py deleted file mode 100644 index ac4caaee7..000000000 --- a/neutron/tests/unit/vmware/extensions/test_networkgw.py +++ /dev/null @@ -1,1074 +0,0 @@ -# Copyright 2012 VMware, Inc. All rights reserved. -# -# 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 contextlib -import mock - -from oslo.config import cfg -from webob import exc -import webtest - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron import context -from neutron.db import api as db_api -from neutron.db import db_base_plugin_v2 -from neutron import manager -from neutron.plugins.vmware.api_client import exception as api_exc -from neutron.plugins.vmware.common import exceptions as nsx_exc -from neutron.plugins.vmware.dbexts import networkgw_db -from neutron.plugins.vmware.extensions import networkgw -from neutron.plugins.vmware import nsxlib -from neutron.plugins.vmware.nsxlib import l2gateway as l2gwlib -from neutron import quota -from neutron.tests import base -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import test_db_plugin -from neutron.tests.unit import test_extensions -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware import test_nsx_plugin - -_uuid = test_api_v2._uuid -_get_path = test_api_v2._get_path - - -class TestExtensionManager(object): - - def get_resources(self): - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - networkgw.RESOURCE_ATTRIBUTE_MAP) - return networkgw.Networkgw.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class NetworkGatewayExtensionTestCase(base.BaseTestCase): - - def setUp(self): - super(NetworkGatewayExtensionTestCase, self).setUp() - plugin = '%s.%s' % (networkgw.__name__, - networkgw.NetworkGatewayPluginBase.__name__) - self._gw_resource = networkgw.GATEWAY_RESOURCE_NAME - self._dev_resource = networkgw.DEVICE_RESOURCE_NAME - - # Ensure existing ExtensionManager is not used - extensions.PluginAwareExtensionManager._instance = None - - # Create the default configurations - self.config_parse() - - # Update the plugin and extensions path - self.setup_coreplugin(plugin) - - _plugin_patcher = mock.patch(plugin, autospec=True) - self.plugin = _plugin_patcher.start() - - # Instantiate mock plugin and enable extensions - manager.NeutronManager.get_plugin().supported_extension_aliases = ( - [networkgw.EXT_ALIAS]) - ext_mgr = TestExtensionManager() - extensions.PluginAwareExtensionManager._instance = ext_mgr - self.ext_mdw = test_extensions.setup_extensions_middleware(ext_mgr) - self.api = webtest.TestApp(self.ext_mdw) - - quota.QUOTAS._driver = None - cfg.CONF.set_override('quota_driver', 'neutron.quota.ConfDriver', - group='QUOTAS') - - def test_network_gateway_create(self): - nw_gw_id = _uuid() - data = {self._gw_resource: {'name': 'nw-gw', - 'tenant_id': _uuid(), - 'devices': [{'id': _uuid(), - 'interface_name': 'xxx'}]}} - return_value = data[self._gw_resource].copy() - return_value.update({'id': nw_gw_id}) - instance = self.plugin.return_value - instance.create_network_gateway.return_value = return_value - res = self.api.post_json(_get_path(networkgw.NETWORK_GATEWAYS), data) - instance.create_network_gateway.assert_called_with( - mock.ANY, network_gateway=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - self.assertIn(self._gw_resource, res.json) - nw_gw = res.json[self._gw_resource] - self.assertEqual(nw_gw['id'], nw_gw_id) - - def _test_network_gateway_create_with_error( - self, data, error_code=exc.HTTPBadRequest.code): - res = self.api.post_json(_get_path(networkgw.NETWORK_GATEWAYS), data, - expect_errors=True) - self.assertEqual(res.status_int, error_code) - - def test_network_gateway_create_invalid_device_spec(self): - data = {self._gw_resource: {'name': 'nw-gw', - 'tenant_id': _uuid(), - 'devices': [{'id': _uuid(), - 'invalid': 'xxx'}]}} - self._test_network_gateway_create_with_error(data) - - def test_network_gateway_create_extra_attr_in_device_spec(self): - data = {self._gw_resource: {'name': 'nw-gw', - 'tenant_id': _uuid(), - 'devices': - [{'id': _uuid(), - 'interface_name': 'xxx', - 'extra_attr': 'onetoomany'}]}} - self._test_network_gateway_create_with_error(data) - - def test_network_gateway_update(self): - nw_gw_name = 'updated' - data = {self._gw_resource: {'name': nw_gw_name}} - nw_gw_id = _uuid() - return_value = {'id': nw_gw_id, - 'name': nw_gw_name} - - instance = self.plugin.return_value - instance.update_network_gateway.return_value = return_value - res = self.api.put_json( - _get_path('%s/%s' % (networkgw.NETWORK_GATEWAYS, nw_gw_id)), data) - instance.update_network_gateway.assert_called_with( - mock.ANY, nw_gw_id, network_gateway=data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - self.assertIn(self._gw_resource, res.json) - nw_gw = res.json[self._gw_resource] - self.assertEqual(nw_gw['id'], nw_gw_id) - self.assertEqual(nw_gw['name'], nw_gw_name) - - def test_network_gateway_delete(self): - nw_gw_id = _uuid() - instance = self.plugin.return_value - res = self.api.delete(_get_path('%s/%s' % (networkgw.NETWORK_GATEWAYS, - nw_gw_id))) - - instance.delete_network_gateway.assert_called_with(mock.ANY, - nw_gw_id) - self.assertEqual(res.status_int, exc.HTTPNoContent.code) - - def test_network_gateway_get(self): - nw_gw_id = _uuid() - return_value = {self._gw_resource: {'name': 'test', - 'devices': - [{'id': _uuid(), - 'interface_name': 'xxx'}], - 'id': nw_gw_id}} - instance = self.plugin.return_value - instance.get_network_gateway.return_value = return_value - - res = self.api.get(_get_path('%s/%s' % (networkgw.NETWORK_GATEWAYS, - nw_gw_id))) - - instance.get_network_gateway.assert_called_with(mock.ANY, - nw_gw_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_network_gateway_list(self): - nw_gw_id = _uuid() - return_value = [{self._gw_resource: {'name': 'test', - 'devices': - [{'id': _uuid(), - 'interface_name': 'xxx'}], - 'id': nw_gw_id}}] - instance = self.plugin.return_value - instance.get_network_gateways.return_value = return_value - - res = self.api.get(_get_path(networkgw.NETWORK_GATEWAYS)) - - instance.get_network_gateways.assert_called_with(mock.ANY, - fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_network_gateway_connect(self): - nw_gw_id = _uuid() - nw_id = _uuid() - gw_port_id = _uuid() - mapping_data = {'network_id': nw_id, - 'segmentation_type': 'vlan', - 'segmentation_id': '999'} - return_value = {'connection_info': { - 'network_gateway_id': nw_gw_id, - 'port_id': gw_port_id, - 'network_id': nw_id}} - instance = self.plugin.return_value - instance.connect_network.return_value = return_value - res = self.api.put_json(_get_path('%s/%s/connect_network' % - (networkgw.NETWORK_GATEWAYS, - nw_gw_id)), - mapping_data) - instance.connect_network.assert_called_with(mock.ANY, - nw_gw_id, - mapping_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - nw_conn_res = res.json['connection_info'] - self.assertEqual(nw_conn_res['port_id'], gw_port_id) - self.assertEqual(nw_conn_res['network_id'], nw_id) - - def test_network_gateway_disconnect(self): - nw_gw_id = _uuid() - nw_id = _uuid() - mapping_data = {'network_id': nw_id} - instance = self.plugin.return_value - res = self.api.put_json(_get_path('%s/%s/disconnect_network' % - (networkgw.NETWORK_GATEWAYS, - nw_gw_id)), - mapping_data) - instance.disconnect_network.assert_called_with(mock.ANY, - nw_gw_id, - mapping_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_gateway_device_get(self): - gw_dev_id = _uuid() - return_value = {self._dev_resource: {'name': 'test', - 'connector_type': 'stt', - 'connector_ip': '1.1.1.1', - 'id': gw_dev_id}} - instance = self.plugin.return_value - instance.get_gateway_device.return_value = return_value - - res = self.api.get(_get_path('%s/%s' % (networkgw.GATEWAY_DEVICES, - gw_dev_id))) - - instance.get_gateway_device.assert_called_with(mock.ANY, - gw_dev_id, - fields=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_gateway_device_list(self): - gw_dev_id = _uuid() - return_value = [{self._dev_resource: {'name': 'test', - 'connector_type': 'stt', - 'connector_ip': '1.1.1.1', - 'id': gw_dev_id}}] - instance = self.plugin.return_value - instance.get_gateway_devices.return_value = return_value - - res = self.api.get(_get_path(networkgw.GATEWAY_DEVICES)) - - instance.get_gateway_devices.assert_called_with(mock.ANY, - fields=mock.ANY, - filters=mock.ANY) - self.assertEqual(res.status_int, exc.HTTPOk.code) - - def test_gateway_device_create(self): - gw_dev_id = _uuid() - data = {self._dev_resource: {'name': 'test-dev', - 'tenant_id': _uuid(), - 'client_certificate': 'xyz', - 'connector_type': 'stt', - 'connector_ip': '1.1.1.1'}} - return_value = data[self._dev_resource].copy() - return_value.update({'id': gw_dev_id}) - instance = self.plugin.return_value - instance.create_gateway_device.return_value = return_value - res = self.api.post_json(_get_path(networkgw.GATEWAY_DEVICES), data) - instance.create_gateway_device.assert_called_with( - mock.ANY, gateway_device=data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - self.assertIn(self._dev_resource, res.json) - gw_dev = res.json[self._dev_resource] - self.assertEqual(gw_dev['id'], gw_dev_id) - - def _test_gateway_device_create_with_error( - self, data, error_code=exc.HTTPBadRequest.code): - res = self.api.post_json(_get_path(networkgw.GATEWAY_DEVICES), data, - expect_errors=True) - self.assertEqual(res.status_int, error_code) - - def test_gateway_device_create_invalid_connector_type(self): - data = {self._gw_resource: {'name': 'test-dev', - 'client_certificate': 'xyz', - 'tenant_id': _uuid(), - 'connector_type': 'invalid', - 'connector_ip': '1.1.1.1'}} - self._test_gateway_device_create_with_error(data) - - def test_gateway_device_create_invalid_connector_ip(self): - data = {self._gw_resource: {'name': 'test-dev', - 'client_certificate': 'xyz', - 'tenant_id': _uuid(), - 'connector_type': 'stt', - 'connector_ip': 'invalid'}} - self._test_gateway_device_create_with_error(data) - - def test_gateway_device_create_extra_attr_in_device_spec(self): - data = {self._gw_resource: {'name': 'test-dev', - 'client_certificate': 'xyz', - 'tenant_id': _uuid(), - 'alien_attribute': 'E.T.', - 'connector_type': 'stt', - 'connector_ip': '1.1.1.1'}} - self._test_gateway_device_create_with_error(data) - - def test_gateway_device_update(self): - gw_dev_name = 'updated' - data = {self._dev_resource: {'name': gw_dev_name}} - gw_dev_id = _uuid() - return_value = {'id': gw_dev_id, - 'name': gw_dev_name} - - instance = self.plugin.return_value - instance.update_gateway_device.return_value = return_value - res = self.api.put_json( - _get_path('%s/%s' % (networkgw.GATEWAY_DEVICES, gw_dev_id)), data) - instance.update_gateway_device.assert_called_with( - mock.ANY, gw_dev_id, gateway_device=data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - self.assertIn(self._dev_resource, res.json) - gw_dev = res.json[self._dev_resource] - self.assertEqual(gw_dev['id'], gw_dev_id) - self.assertEqual(gw_dev['name'], gw_dev_name) - - def test_gateway_device_delete(self): - gw_dev_id = _uuid() - instance = self.plugin.return_value - res = self.api.delete(_get_path('%s/%s' % (networkgw.GATEWAY_DEVICES, - gw_dev_id))) - instance.delete_gateway_device.assert_called_with(mock.ANY, gw_dev_id) - self.assertEqual(res.status_int, exc.HTTPNoContent.code) - - -class NetworkGatewayDbTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - """Unit tests for Network Gateway DB support.""" - - def setUp(self, plugin=None, ext_mgr=None): - if not plugin: - plugin = '%s.%s' % (__name__, TestNetworkGatewayPlugin.__name__) - if not ext_mgr: - ext_mgr = TestExtensionManager() - self.gw_resource = networkgw.GATEWAY_RESOURCE_NAME - self.dev_resource = networkgw.DEVICE_RESOURCE_NAME - - super(NetworkGatewayDbTestCase, self).setUp(plugin=plugin, - ext_mgr=ext_mgr) - - def _create_network_gateway(self, fmt, tenant_id, name=None, - devices=None, arg_list=None, **kwargs): - data = {self.gw_resource: {'tenant_id': tenant_id, - 'devices': devices}} - if name: - data[self.gw_resource]['name'] = name - for arg in arg_list or (): - # Arg must be present and not empty - if arg in kwargs and kwargs[arg]: - data[self.gw_resource][arg] = kwargs[arg] - nw_gw_req = self.new_create_request(networkgw.NETWORK_GATEWAYS, - data, fmt) - if (kwargs.get('set_context') and tenant_id): - # create a specific auth context for this request - nw_gw_req.environ['neutron.context'] = context.Context( - '', tenant_id) - return nw_gw_req.get_response(self.ext_api) - - @contextlib.contextmanager - def _network_gateway(self, name='gw1', devices=None, - fmt='json', tenant_id=_uuid()): - device = None - if not devices: - device_res = self._create_gateway_device( - fmt, tenant_id, 'stt', '1.1.1.1', 'xxxxxx', - name='whatever') - if device_res.status_int >= 400: - raise exc.HTTPClientError(code=device_res.status_int) - device = self.deserialize(fmt, device_res) - devices = [{'id': device[self.dev_resource]['id'], - 'interface_name': 'xyz'}] - - res = self._create_network_gateway(fmt, tenant_id, name=name, - devices=devices) - if res.status_int >= 400: - raise exc.HTTPClientError(code=res.status_int) - network_gateway = self.deserialize(fmt, res) - yield network_gateway - - self._delete(networkgw.NETWORK_GATEWAYS, - network_gateway[self.gw_resource]['id']) - if device: - self._delete(networkgw.GATEWAY_DEVICES, - device[self.dev_resource]['id']) - - def _create_gateway_device(self, fmt, tenant_id, - connector_type, connector_ip, - client_certificate, name=None, - set_context=False): - data = {self.dev_resource: {'tenant_id': tenant_id, - 'connector_type': connector_type, - 'connector_ip': connector_ip, - 'client_certificate': client_certificate}} - if name: - data[self.dev_resource]['name'] = name - gw_dev_req = self.new_create_request(networkgw.GATEWAY_DEVICES, - data, fmt) - if (set_context and tenant_id): - # create a specific auth context for this request - gw_dev_req.environ['neutron.context'] = context.Context( - '', tenant_id) - return gw_dev_req.get_response(self.ext_api) - - def _update_gateway_device(self, fmt, gateway_device_id, - connector_type=None, connector_ip=None, - client_certificate=None, name=None, - set_context=False, tenant_id=None): - data = {self.dev_resource: {}} - if connector_type: - data[self.dev_resource]['connector_type'] = connector_type - if connector_ip: - data[self.dev_resource]['connector_ip'] = connector_ip - if client_certificate: - data[self.dev_resource]['client_certificate'] = client_certificate - if name: - data[self.dev_resource]['name'] = name - gw_dev_req = self.new_update_request(networkgw.GATEWAY_DEVICES, - data, gateway_device_id, fmt) - if (set_context and tenant_id): - # create a specific auth context for this request - gw_dev_req.environ['neutron.context'] = context.Context( - '', tenant_id) - return gw_dev_req.get_response(self.ext_api) - - @contextlib.contextmanager - def _gateway_device(self, name='gw_dev', - connector_type='stt', - connector_ip='1.1.1.1', - client_certificate='xxxxxxxxxxxxxxx', - fmt='json', tenant_id=_uuid()): - res = self._create_gateway_device( - fmt, - tenant_id, - connector_type=connector_type, - connector_ip=connector_ip, - client_certificate=client_certificate, - name=name) - if res.status_int >= 400: - raise exc.HTTPClientError(code=res.status_int) - gateway_device = self.deserialize(fmt, res) - yield gateway_device - - self._delete(networkgw.GATEWAY_DEVICES, - gateway_device[self.dev_resource]['id']) - - def _gateway_action(self, action, network_gateway_id, network_id, - segmentation_type, segmentation_id=None, - expected_status=exc.HTTPOk.code): - connection_data = {'network_id': network_id, - 'segmentation_type': segmentation_type} - if segmentation_id: - connection_data['segmentation_id'] = segmentation_id - - req = self.new_action_request(networkgw.NETWORK_GATEWAYS, - connection_data, - network_gateway_id, - "%s_network" % action) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, expected_status) - return self.deserialize('json', res) - - def _test_connect_and_disconnect_network(self, segmentation_type, - segmentation_id=None): - with self._network_gateway() as gw: - with self.network() as net: - body = self._gateway_action('connect', - gw[self.gw_resource]['id'], - net['network']['id'], - segmentation_type, - segmentation_id) - self.assertIn('connection_info', body) - connection_info = body['connection_info'] - for attr in ('network_id', 'port_id', - 'network_gateway_id'): - self.assertIn(attr, connection_info) - # fetch port and confirm device_id - gw_port_id = connection_info['port_id'] - port_body = self._show('ports', gw_port_id) - self.assertEqual(port_body['port']['device_id'], - gw[self.gw_resource]['id']) - # Clean up - otherwise delete will fail - body = self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net['network']['id'], - segmentation_type, - segmentation_id) - # Check associated port has been deleted too - body = self._show('ports', gw_port_id, - expected_code=exc.HTTPNotFound.code) - - def test_create_network_gateway(self): - tenant_id = _uuid() - with contextlib.nested( - self._gateway_device(name='dev_1', - tenant_id=tenant_id), - self._gateway_device(name='dev_2', - tenant_id=tenant_id)) as (dev_1, dev_2): - name = 'test-gw' - dev_1_id = dev_1[self.dev_resource]['id'] - dev_2_id = dev_2[self.dev_resource]['id'] - devices = [{'id': dev_1_id, 'interface_name': 'xxx'}, - {'id': dev_2_id, 'interface_name': 'yyy'}] - keys = [('devices', devices), ('name', name)] - with self._network_gateway(name=name, - devices=devices, - tenant_id=tenant_id) as gw: - for k, v in keys: - self.assertEqual(gw[self.gw_resource][k], v) - - def test_create_network_gateway_no_interface_name(self): - tenant_id = _uuid() - with self._gateway_device(tenant_id=tenant_id) as dev: - name = 'test-gw' - devices = [{'id': dev[self.dev_resource]['id']}] - exp_devices = devices - exp_devices[0]['interface_name'] = 'breth0' - keys = [('devices', exp_devices), ('name', name)] - with self._network_gateway(name=name, - devices=devices, - tenant_id=tenant_id) as gw: - for k, v in keys: - self.assertEqual(gw[self.gw_resource][k], v) - - def test_create_network_gateway_not_owned_device_raises_404(self): - # Create a device with a different tenant identifier - with self._gateway_device(name='dev', tenant_id=_uuid()) as dev: - name = 'test-gw' - dev_id = dev[self.dev_resource]['id'] - devices = [{'id': dev_id, 'interface_name': 'xxx'}] - res = self._create_network_gateway( - 'json', _uuid(), name=name, devices=devices) - self.assertEqual(404, res.status_int) - - def test_delete_network_gateway(self): - tenant_id = _uuid() - with self._gateway_device(tenant_id=tenant_id) as dev: - name = 'test-gw' - device_id = dev[self.dev_resource]['id'] - devices = [{'id': device_id, - 'interface_name': 'xxx'}] - with self._network_gateway(name=name, - devices=devices, - tenant_id=tenant_id) as gw: - # Nothing to do here - just let the gateway go - gw_id = gw[self.gw_resource]['id'] - # Verify nothing left on db - session = db_api.get_session() - dev_query = session.query( - networkgw_db.NetworkGatewayDevice).filter( - networkgw_db.NetworkGatewayDevice.id == device_id) - self.assertIsNone(dev_query.first()) - gw_query = session.query(networkgw_db.NetworkGateway).filter( - networkgw_db.NetworkGateway.id == gw_id) - self.assertIsNone(gw_query.first()) - - def test_update_network_gateway(self): - with self._network_gateway() as gw: - data = {self.gw_resource: {'name': 'new_name'}} - req = self.new_update_request(networkgw.NETWORK_GATEWAYS, - data, - gw[self.gw_resource]['id']) - res = self.deserialize('json', req.get_response(self.ext_api)) - self.assertEqual(res[self.gw_resource]['name'], - data[self.gw_resource]['name']) - - def test_get_network_gateway(self): - with self._network_gateway(name='test-gw') as gw: - req = self.new_show_request(networkgw.NETWORK_GATEWAYS, - gw[self.gw_resource]['id']) - res = self.deserialize('json', req.get_response(self.ext_api)) - self.assertEqual(res[self.gw_resource]['name'], - gw[self.gw_resource]['name']) - - def test_list_network_gateways(self): - with self._network_gateway(name='test-gw-1') as gw1: - with self._network_gateway(name='test_gw_2') as gw2: - req = self.new_list_request(networkgw.NETWORK_GATEWAYS) - res = self.deserialize('json', req.get_response(self.ext_api)) - key = self.gw_resource + 's' - self.assertEqual(len(res[key]), 2) - self.assertEqual(res[key][0]['name'], - gw1[self.gw_resource]['name']) - self.assertEqual(res[key][1]['name'], - gw2[self.gw_resource]['name']) - - def _test_list_network_gateway_with_multiple_connections( - self, expected_gateways=1): - with self._network_gateway() as gw: - with self.network() as net_1: - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 777) - req = self.new_list_request(networkgw.NETWORK_GATEWAYS) - res = self.deserialize('json', req.get_response(self.ext_api)) - key = self.gw_resource + 's' - self.assertEqual(len(res[key]), expected_gateways) - for item in res[key]: - self.assertIn('ports', item) - if item['id'] == gw[self.gw_resource]['id']: - gw_ports = item['ports'] - self.assertEqual(len(gw_ports), 2) - segmentation_ids = [555, 777] - for gw_port in gw_ports: - self.assertEqual('vlan', gw_port['segmentation_type']) - self.assertIn(gw_port['segmentation_id'], segmentation_ids) - segmentation_ids.remove(gw_port['segmentation_id']) - # Required cleanup - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 777) - - def test_list_network_gateway_with_multiple_connections(self): - self._test_list_network_gateway_with_multiple_connections() - - def test_connect_and_disconnect_network(self): - self._test_connect_and_disconnect_network('flat') - - def test_connect_and_disconnect_network_no_seg_type(self): - self._test_connect_and_disconnect_network(None) - - def test_connect_and_disconnect_network_with_segmentation_id(self): - self._test_connect_and_disconnect_network('vlan', 999) - - def test_connect_network_multiple_times(self): - with self._network_gateway() as gw: - with self.network() as net_1: - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 777) - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 777) - - def test_connect_network_multiple_gateways(self): - with self._network_gateway() as gw_1: - with self._network_gateway() as gw_2: - with self.network() as net_1: - self._gateway_action('connect', - gw_1[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('connect', - gw_2[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('disconnect', - gw_1[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('disconnect', - gw_2[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - - def test_connect_network_mapping_in_use_returns_409(self): - with self._network_gateway() as gw: - with self.network() as net_1: - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - with self.network() as net_2: - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_2['network']['id'], - 'vlan', 555, - expected_status=exc.HTTPConflict.code) - # Clean up - otherwise delete will fail - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - - def test_connect_invalid_network_returns_400(self): - with self._network_gateway() as gw: - self._gateway_action('connect', - gw[self.gw_resource]['id'], - 'hohoho', - 'vlan', 555, - expected_status=exc.HTTPBadRequest.code) - - def test_connect_unspecified_network_returns_400(self): - with self._network_gateway() as gw: - self._gateway_action('connect', - gw[self.gw_resource]['id'], - None, - 'vlan', 555, - expected_status=exc.HTTPBadRequest.code) - - def test_disconnect_network_ambiguous_returns_409(self): - with self._network_gateway() as gw: - with self.network() as net_1: - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 777) - # This should raise - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', - expected_status=exc.HTTPConflict.code) - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 777) - - def test_delete_active_gateway_port_returns_409(self): - with self._network_gateway() as gw: - with self.network() as net_1: - body = self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - # fetch port id and try to delete it - gw_port_id = body['connection_info']['port_id'] - self._delete('ports', gw_port_id, - expected_code=exc.HTTPConflict.code) - body = self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - - def test_delete_network_gateway_active_connections_returns_409(self): - with self._network_gateway() as gw: - with self.network() as net_1: - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'flat') - self._delete(networkgw.NETWORK_GATEWAYS, - gw[self.gw_resource]['id'], - expected_code=exc.HTTPConflict.code) - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'flat') - - def test_disconnect_non_existing_connection_returns_404(self): - with self._network_gateway() as gw: - with self.network() as net_1: - self._gateway_action('connect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 999, - expected_status=exc.HTTPNotFound.code) - self._gateway_action('disconnect', - gw[self.gw_resource]['id'], - net_1['network']['id'], - 'vlan', 555) - - def test_create_gateway_device( - self, expected_status=networkgw_db.STATUS_UNKNOWN): - with self._gateway_device(name='test-dev', - connector_type='stt', - connector_ip='1.1.1.1', - client_certificate='xyz') as dev: - self.assertEqual(dev[self.dev_resource]['name'], 'test-dev') - self.assertEqual(dev[self.dev_resource]['connector_type'], 'stt') - self.assertEqual(dev[self.dev_resource]['connector_ip'], '1.1.1.1') - self.assertEqual(dev[self.dev_resource]['status'], expected_status) - - def test_list_gateway_devices(self): - with contextlib.nested( - self._gateway_device(name='test-dev-1', - connector_type='stt', - connector_ip='1.1.1.1', - client_certificate='xyz'), - self._gateway_device(name='test-dev-2', - connector_type='stt', - connector_ip='2.2.2.2', - client_certificate='qwe')) as (dev_1, dev_2): - req = self.new_list_request(networkgw.GATEWAY_DEVICES) - res = self.deserialize('json', req.get_response(self.ext_api)) - devices = res[networkgw.GATEWAY_DEVICES.replace('-', '_')] - self.assertEqual(len(devices), 2) - dev_1 = devices[0] - dev_2 = devices[1] - self.assertEqual(dev_1['name'], 'test-dev-1') - self.assertEqual(dev_2['name'], 'test-dev-2') - - def test_get_gateway_device( - self, expected_status=networkgw_db.STATUS_UNKNOWN): - with self._gateway_device(name='test-dev', - connector_type='stt', - connector_ip='1.1.1.1', - client_certificate='xyz') as dev: - req = self.new_show_request(networkgw.GATEWAY_DEVICES, - dev[self.dev_resource]['id']) - res = self.deserialize('json', req.get_response(self.ext_api)) - self.assertEqual(res[self.dev_resource]['name'], 'test-dev') - self.assertEqual(res[self.dev_resource]['connector_type'], 'stt') - self.assertEqual(res[self.dev_resource]['connector_ip'], '1.1.1.1') - self.assertEqual(res[self.dev_resource]['status'], expected_status) - - def test_update_gateway_device( - self, expected_status=networkgw_db.STATUS_UNKNOWN): - with self._gateway_device(name='test-dev', - connector_type='stt', - connector_ip='1.1.1.1', - client_certificate='xyz') as dev: - self._update_gateway_device('json', dev[self.dev_resource]['id'], - connector_type='stt', - connector_ip='2.2.2.2', - name='test-dev-upd') - req = self.new_show_request(networkgw.GATEWAY_DEVICES, - dev[self.dev_resource]['id']) - res = self.deserialize('json', req.get_response(self.ext_api)) - - self.assertEqual(res[self.dev_resource]['name'], 'test-dev-upd') - self.assertEqual(res[self.dev_resource]['connector_type'], 'stt') - self.assertEqual(res[self.dev_resource]['connector_ip'], '2.2.2.2') - self.assertEqual(res[self.dev_resource]['status'], expected_status) - - def test_delete_gateway_device(self): - with self._gateway_device(name='test-dev', - connector_type='stt', - connector_ip='1.1.1.1', - client_certificate='xyz') as dev: - # Nothing to do here - just note the device id - dev_id = dev[self.dev_resource]['id'] - # Verify nothing left on db - session = db_api.get_session() - dev_query = session.query(networkgw_db.NetworkGatewayDevice) - dev_query.filter(networkgw_db.NetworkGatewayDevice.id == dev_id) - self.assertIsNone(dev_query.first()) - - -class TestNetworkGateway(test_nsx_plugin.NsxPluginV2TestCase, - NetworkGatewayDbTestCase): - - def setUp(self, plugin=vmware.PLUGIN_NAME, ext_mgr=None): - cfg.CONF.set_override('api_extensions_path', vmware.NSXEXT_PATH) - # Mock l2gwlib calls for gateway devices since this resource is not - # mocked through the fake NSX API client - create_gw_dev_patcher = mock.patch.object( - l2gwlib, 'create_gateway_device') - update_gw_dev_patcher = mock.patch.object( - l2gwlib, 'update_gateway_device') - delete_gw_dev_patcher = mock.patch.object( - l2gwlib, 'delete_gateway_device') - get_gw_dev_status_patcher = mock.patch.object( - l2gwlib, 'get_gateway_device_status') - get_gw_dev_statuses_patcher = mock.patch.object( - l2gwlib, 'get_gateway_devices_status') - self.mock_create_gw_dev = create_gw_dev_patcher.start() - self.mock_create_gw_dev.return_value = {'uuid': 'callejon'} - self.mock_update_gw_dev = update_gw_dev_patcher.start() - delete_gw_dev_patcher.start() - self.mock_get_gw_dev_status = get_gw_dev_status_patcher.start() - get_gw_dev_statuses = get_gw_dev_statuses_patcher.start() - get_gw_dev_statuses.return_value = {} - - super(TestNetworkGateway, - self).setUp(plugin=plugin, ext_mgr=ext_mgr) - - def test_create_network_gateway_name_exceeds_40_chars(self): - name = 'this_is_a_gateway_whose_name_is_longer_than_40_chars' - with self._network_gateway(name=name) as nw_gw: - # Assert Neutron name is not truncated - self.assertEqual(nw_gw[self.gw_resource]['name'], name) - - def test_update_network_gateway_with_name_calls_backend(self): - with mock.patch.object( - nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw: - with self._network_gateway(name='cavani') as nw_gw: - nw_gw_id = nw_gw[self.gw_resource]['id'] - self._update(networkgw.NETWORK_GATEWAYS, nw_gw_id, - {self.gw_resource: {'name': 'higuain'}}) - mock_update_gw.assert_called_once_with( - mock.ANY, nw_gw_id, 'higuain') - - def test_update_network_gateway_without_name_does_not_call_backend(self): - with mock.patch.object( - nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw: - with self._network_gateway(name='something') as nw_gw: - nw_gw_id = nw_gw[self.gw_resource]['id'] - self._update(networkgw.NETWORK_GATEWAYS, nw_gw_id, - {self.gw_resource: {}}) - self.assertEqual(mock_update_gw.call_count, 0) - - def test_update_network_gateway_name_exceeds_40_chars(self): - new_name = 'this_is_a_gateway_whose_name_is_longer_than_40_chars' - with self._network_gateway(name='something') as nw_gw: - nw_gw_id = nw_gw[self.gw_resource]['id'] - self._update(networkgw.NETWORK_GATEWAYS, nw_gw_id, - {self.gw_resource: {'name': new_name}}) - req = self.new_show_request(networkgw.NETWORK_GATEWAYS, - nw_gw_id) - res = self.deserialize('json', req.get_response(self.ext_api)) - # Assert Neutron name is not truncated - self.assertEqual(new_name, res[self.gw_resource]['name']) - # Assert NSX name is truncated - self.assertEqual( - new_name[:40], - self.fc._fake_gatewayservice_dict[nw_gw_id]['display_name']) - - def test_create_network_gateway_nsx_error_returns_500(self): - def raise_nsx_api_exc(*args, **kwargs): - raise api_exc.NsxApiException - - with mock.patch.object(nsxlib.l2gateway, - 'create_l2_gw_service', - new=raise_nsx_api_exc): - with self._gateway_device() as dev: - res = self._create_network_gateway( - self.fmt, 'xxx', name='yyy', - devices=[{'id': dev[self.dev_resource]['id']}]) - self.assertEqual(500, res.status_int) - - def test_create_network_gateway_nsx_error_returns_409(self): - with mock.patch.object(nsxlib.l2gateway, - 'create_l2_gw_service', - side_effect=api_exc.Conflict): - with self._gateway_device() as dev: - res = self._create_network_gateway( - self.fmt, 'xxx', name='yyy', - devices=[{'id': dev[self.dev_resource]['id']}]) - self.assertEqual(409, res.status_int) - - def test_list_network_gateways(self): - with self._network_gateway(name='test-gw-1') as gw1: - with self._network_gateway(name='test_gw_2') as gw2: - req = self.new_list_request(networkgw.NETWORK_GATEWAYS) - res = self.deserialize('json', req.get_response(self.ext_api)) - # Ensure we always get the list in the same order - gateways = sorted( - res[self.gw_resource + 's'], key=lambda k: k['name']) - self.assertEqual(len(gateways), 3) - # We expect the default gateway too - self.assertEqual(gateways[0]['default'], True) - self.assertEqual(gateways[1]['name'], - gw1[self.gw_resource]['name']) - self.assertEqual(gateways[2]['name'], - gw2[self.gw_resource]['name']) - - def test_list_network_gateway_with_multiple_connections(self): - self._test_list_network_gateway_with_multiple_connections( - expected_gateways=2) - - def test_show_network_gateway_nsx_error_returns_404(self): - invalid_id = 'b5afd4a9-eb71-4af7-a082-8fc625a35b61' - req = self.new_show_request(networkgw.NETWORK_GATEWAYS, invalid_id) - res = req.get_response(self.ext_api) - self.assertEqual(exc.HTTPNotFound.code, res.status_int) - - def test_create_gateway_device(self): - self.mock_get_gw_dev_status.return_value = True - super(TestNetworkGateway, self).test_create_gateway_device( - expected_status=networkgw_db.STATUS_ACTIVE) - - def test_create_gateway_device_status_down(self): - self.mock_get_gw_dev_status.return_value = False - super(TestNetworkGateway, self).test_create_gateway_device( - expected_status=networkgw_db.STATUS_DOWN) - - def test_create_gateway_device_invalid_cert_returns_400(self): - self.mock_create_gw_dev.side_effect = ( - nsx_exc.InvalidSecurityCertificate) - res = self._create_gateway_device( - 'json', - _uuid(), - connector_type='stt', - connector_ip='1.1.1.1', - client_certificate='invalid_certificate', - name='whatever') - self.assertEqual(res.status_int, 400) - - def test_get_gateway_device(self): - self.mock_get_gw_dev_status.return_value = True - super(TestNetworkGateway, self).test_get_gateway_device( - expected_status=networkgw_db.STATUS_ACTIVE) - - def test_get_gateway_device_status_down(self): - self.mock_get_gw_dev_status.return_value = False - super(TestNetworkGateway, self).test_get_gateway_device( - expected_status=networkgw_db.STATUS_DOWN) - - def test_update_gateway_device(self): - self.mock_get_gw_dev_status.return_value = True - super(TestNetworkGateway, self).test_update_gateway_device( - expected_status=networkgw_db.STATUS_ACTIVE) - - def test_update_gateway_device_status_down(self): - self.mock_get_gw_dev_status.return_value = False - super(TestNetworkGateway, self).test_update_gateway_device( - expected_status=networkgw_db.STATUS_DOWN) - - def test_update_gateway_device_invalid_cert_returns_400(self): - with self._gateway_device( - name='whaterver', - connector_type='stt', - connector_ip='1.1.1.1', - client_certificate='iminvalidbutiitdoesnotmatter') as dev: - self.mock_update_gw_dev.side_effect = ( - nsx_exc.InvalidSecurityCertificate) - res = self._update_gateway_device( - 'json', - dev[self.dev_resource]['id'], - client_certificate='invalid_certificate') - self.assertEqual(res.status_int, 400) - - -class TestNetworkGatewayPlugin(db_base_plugin_v2.NeutronDbPluginV2, - networkgw_db.NetworkGatewayMixin): - """Simple plugin class for testing db support for network gateway ext.""" - - supported_extension_aliases = ["network-gateway"] - - def __init__(self, **args): - super(TestNetworkGatewayPlugin, self).__init__(**args) - extensions.append_api_extensions_path([vmware.NSXEXT_PATH]) - - def delete_port(self, context, id, nw_gw_port_check=True): - if nw_gw_port_check: - port = self._get_port(context, id) - self.prevent_network_gateway_port_deletion(context, port) - super(TestNetworkGatewayPlugin, self).delete_port(context, id) diff --git a/neutron/tests/unit/vmware/extensions/test_portsecurity.py b/neutron/tests/unit/vmware/extensions/test_portsecurity.py deleted file mode 100644 index 6b07b39c6..000000000 --- a/neutron/tests/unit/vmware/extensions/test_portsecurity.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation. -# All Rights Reserved. -# -# 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 neutron.common import test_lib -from neutron.plugins.vmware.common import sync -from neutron.tests.unit import test_extension_portsecurity as psec -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.apiclient import fake - - -class PortSecurityTestCase(psec.PortSecurityDBTestCase): - - def setUp(self): - test_lib.test_config['config_files'] = [ - vmware.get_fake_conf('nsx.ini.test')] - # mock api client - self.fc = fake.FakeClient(vmware.STUBS_PATH) - self.mock_nsx = mock.patch(vmware.NSXAPI_NAME, autospec=True) - instance = self.mock_nsx.start() - instance.return_value.login.return_value = "the_cookie" - # Avoid runs of the synchronizer looping call - patch_sync = mock.patch.object(sync, '_start_loopingcall') - patch_sync.start() - - instance.return_value.request.side_effect = self.fc.fake_request - super(PortSecurityTestCase, self).setUp(vmware.PLUGIN_NAME) - self.addCleanup(self.fc.reset_all) - self.addCleanup(self.mock_nsx.stop) - self.addCleanup(patch_sync.stop) - - -class TestPortSecurity(PortSecurityTestCase, psec.TestPortSecurity): - pass diff --git a/neutron/tests/unit/vmware/extensions/test_providernet.py b/neutron/tests/unit/vmware/extensions/test_providernet.py deleted file mode 100644 index f6057f145..000000000 --- a/neutron/tests/unit/vmware/extensions/test_providernet.py +++ /dev/null @@ -1,163 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation. -# All Rights Reserved. -# -# 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. - -from oslo.config import cfg - -from neutron.extensions import multiprovidernet as mpnet -from neutron.extensions import providernet as pnet -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware import test_nsx_plugin - - -class TestProvidernet(test_nsx_plugin.NsxPluginV2TestCase): - - def test_create_provider_network_default_physical_net(self): - data = {'network': {'name': 'net1', - 'admin_state_up': True, - 'tenant_id': 'admin', - pnet.NETWORK_TYPE: 'vlan', - pnet.SEGMENTATION_ID: 411}} - network_req = self.new_create_request('networks', data, self.fmt) - net = self.deserialize(self.fmt, network_req.get_response(self.api)) - self.assertEqual(net['network'][pnet.NETWORK_TYPE], 'vlan') - self.assertEqual(net['network'][pnet.SEGMENTATION_ID], 411) - - def test_create_provider_network(self): - data = {'network': {'name': 'net1', - 'admin_state_up': True, - 'tenant_id': 'admin', - pnet.NETWORK_TYPE: 'vlan', - pnet.SEGMENTATION_ID: 411, - pnet.PHYSICAL_NETWORK: 'physnet1'}} - network_req = self.new_create_request('networks', data, self.fmt) - net = self.deserialize(self.fmt, network_req.get_response(self.api)) - self.assertEqual(net['network'][pnet.NETWORK_TYPE], 'vlan') - self.assertEqual(net['network'][pnet.SEGMENTATION_ID], 411) - self.assertEqual(net['network'][pnet.PHYSICAL_NETWORK], 'physnet1') - - -class TestMultiProviderNetworks(test_nsx_plugin.NsxPluginV2TestCase): - - def setUp(self, plugin=None): - cfg.CONF.set_override('api_extensions_path', vmware.NSXEXT_PATH) - super(TestMultiProviderNetworks, self).setUp() - - def test_create_network_provider(self): - data = {'network': {'name': 'net1', - pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1, - 'tenant_id': 'tenant_one'}} - network_req = self.new_create_request('networks', data) - network = self.deserialize(self.fmt, - network_req.get_response(self.api)) - self.assertEqual(network['network'][pnet.NETWORK_TYPE], 'vlan') - self.assertEqual(network['network'][pnet.PHYSICAL_NETWORK], 'physnet1') - self.assertEqual(network['network'][pnet.SEGMENTATION_ID], 1) - self.assertNotIn(mpnet.SEGMENTS, network['network']) - - def test_create_network_provider_flat(self): - data = {'network': {'name': 'net1', - pnet.NETWORK_TYPE: 'flat', - pnet.PHYSICAL_NETWORK: 'physnet1', - 'tenant_id': 'tenant_one'}} - network_req = self.new_create_request('networks', data) - network = self.deserialize(self.fmt, - network_req.get_response(self.api)) - self.assertEqual('flat', network['network'][pnet.NETWORK_TYPE]) - self.assertEqual('physnet1', network['network'][pnet.PHYSICAL_NETWORK]) - self.assertEqual(0, network['network'][pnet.SEGMENTATION_ID]) - self.assertNotIn(mpnet.SEGMENTS, network['network']) - - def test_create_network_single_multiple_provider(self): - data = {'network': {'name': 'net1', - mpnet.SEGMENTS: - [{pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}], - 'tenant_id': 'tenant_one'}} - net_req = self.new_create_request('networks', data) - network = self.deserialize(self.fmt, net_req.get_response(self.api)) - for provider_field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID]: - self.assertNotIn(provider_field, network['network']) - tz = network['network'][mpnet.SEGMENTS][0] - self.assertEqual(tz[pnet.NETWORK_TYPE], 'vlan') - self.assertEqual(tz[pnet.PHYSICAL_NETWORK], 'physnet1') - self.assertEqual(tz[pnet.SEGMENTATION_ID], 1) - - # Tests get_network() - net_req = self.new_show_request('networks', network['network']['id']) - network = self.deserialize(self.fmt, net_req.get_response(self.api)) - tz = network['network'][mpnet.SEGMENTS][0] - self.assertEqual(tz[pnet.NETWORK_TYPE], 'vlan') - self.assertEqual(tz[pnet.PHYSICAL_NETWORK], 'physnet1') - self.assertEqual(tz[pnet.SEGMENTATION_ID], 1) - - def test_create_network_multprovider(self): - data = {'network': {'name': 'net1', - mpnet.SEGMENTS: - [{pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}, - {pnet.NETWORK_TYPE: 'stt', - pnet.PHYSICAL_NETWORK: 'physnet1'}], - 'tenant_id': 'tenant_one'}} - network_req = self.new_create_request('networks', data) - network = self.deserialize(self.fmt, - network_req.get_response(self.api)) - tz = network['network'][mpnet.SEGMENTS] - for tz in data['network'][mpnet.SEGMENTS]: - for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID]: - self.assertEqual(tz.get(field), tz.get(field)) - - # Tests get_network() - net_req = self.new_show_request('networks', network['network']['id']) - network = self.deserialize(self.fmt, net_req.get_response(self.api)) - tz = network['network'][mpnet.SEGMENTS] - for tz in data['network'][mpnet.SEGMENTS]: - for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID]: - self.assertEqual(tz.get(field), tz.get(field)) - - def test_create_network_with_provider_and_multiprovider_fail(self): - data = {'network': {'name': 'net1', - mpnet.SEGMENTS: - [{pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}], - pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1, - 'tenant_id': 'tenant_one'}} - - network_req = self.new_create_request('networks', data) - res = network_req.get_response(self.api) - self.assertEqual(res.status_int, 400) - - def test_create_network_duplicate_segments(self): - data = {'network': {'name': 'net1', - mpnet.SEGMENTS: - [{pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}, - {pnet.NETWORK_TYPE: 'vlan', - pnet.PHYSICAL_NETWORK: 'physnet1', - pnet.SEGMENTATION_ID: 1}], - 'tenant_id': 'tenant_one'}} - network_req = self.new_create_request('networks', data) - res = network_req.get_response(self.api) - self.assertEqual(res.status_int, 400) diff --git a/neutron/tests/unit/vmware/extensions/test_qosqueues.py b/neutron/tests/unit/vmware/extensions/test_qosqueues.py deleted file mode 100644 index 53e82f52f..000000000 --- a/neutron/tests/unit/vmware/extensions/test_qosqueues.py +++ /dev/null @@ -1,273 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation. -# All Rights Reserved. -# -# 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 contextlib - -import mock -from oslo.config import cfg -import webob.exc - -from neutron import context -from neutron.plugins.vmware.dbexts import qos_db -from neutron.plugins.vmware.extensions import qos as ext_qos -from neutron.plugins.vmware import nsxlib -from neutron.tests.unit import test_extensions -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware import test_nsx_plugin - - -class QoSTestExtensionManager(object): - - def get_resources(self): - return ext_qos.Qos.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class TestQoSQueue(test_nsx_plugin.NsxPluginV2TestCase): - - def setUp(self, plugin=None): - cfg.CONF.set_override('api_extensions_path', vmware.NSXEXT_PATH) - super(TestQoSQueue, self).setUp() - ext_mgr = QoSTestExtensionManager() - self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr) - - def _create_qos_queue(self, fmt, body, **kwargs): - qos_queue = self.new_create_request('qos-queues', body) - if (kwargs.get('set_context') and 'tenant_id' in kwargs): - # create a specific auth context for this request - qos_queue.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - - return qos_queue.get_response(self.ext_api) - - @contextlib.contextmanager - def qos_queue(self, name='foo', min='0', max='10', - qos_marking=None, dscp='0', default=None, no_delete=False): - - body = {'qos_queue': {'tenant_id': 'tenant', - 'name': name, - 'min': min, - 'max': max}} - - if qos_marking: - body['qos_queue']['qos_marking'] = qos_marking - if dscp: - body['qos_queue']['dscp'] = dscp - if default: - body['qos_queue']['default'] = default - res = self._create_qos_queue('json', body) - qos_queue = self.deserialize('json', res) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - - yield qos_queue - - if not no_delete: - self._delete('qos-queues', - qos_queue['qos_queue']['id']) - - def test_create_qos_queue(self): - with self.qos_queue(name='fake_lqueue', min=34, max=44, - qos_marking='untrusted', default=False) as q: - self.assertEqual(q['qos_queue']['name'], 'fake_lqueue') - self.assertEqual(q['qos_queue']['min'], 34) - self.assertEqual(q['qos_queue']['max'], 44) - self.assertEqual(q['qos_queue']['qos_marking'], 'untrusted') - self.assertFalse(q['qos_queue']['default']) - - def test_create_trusted_qos_queue(self): - with mock.patch.object(qos_db.LOG, 'info') as log: - with mock.patch.object(nsxlib, 'do_request', - return_value={"uuid": "fake_queue"}): - with self.qos_queue(name='fake_lqueue', min=34, max=44, - qos_marking='trusted', default=False) as q: - self.assertIsNone(q['qos_queue']['dscp']) - self.assertTrue(log.called) - - def test_create_qos_queue_name_exceeds_40_chars(self): - name = 'this_is_a_queue_whose_name_is_longer_than_40_chars' - with self.qos_queue(name=name) as queue: - # Assert Neutron name is not truncated - self.assertEqual(queue['qos_queue']['name'], name) - - def test_create_qos_queue_default(self): - with self.qos_queue(default=True) as q: - self.assertTrue(q['qos_queue']['default']) - - def test_create_qos_queue_two_default_queues_fail(self): - with self.qos_queue(default=True): - body = {'qos_queue': {'tenant_id': 'tenant', - 'name': 'second_default_queue', - 'default': True}} - res = self._create_qos_queue('json', body) - self.assertEqual(res.status_int, 409) - - def test_create_port_with_queue(self): - with self.qos_queue(default=True) as q1: - res = self._create_network('json', 'net1', True, - arg_list=(ext_qos.QUEUE,), - queue_id=q1['qos_queue']['id']) - net1 = self.deserialize('json', res) - self.assertEqual(net1['network'][ext_qos.QUEUE], - q1['qos_queue']['id']) - device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1" - with self.port(device_id=device_id, do_delete=False) as p: - self.assertEqual(len(p['port'][ext_qos.QUEUE]), 36) - - def test_create_shared_queue_networks(self): - with self.qos_queue(default=True, no_delete=True) as q1: - res = self._create_network('json', 'net1', True, - arg_list=(ext_qos.QUEUE,), - queue_id=q1['qos_queue']['id']) - net1 = self.deserialize('json', res) - self.assertEqual(net1['network'][ext_qos.QUEUE], - q1['qos_queue']['id']) - res = self._create_network('json', 'net2', True, - arg_list=(ext_qos.QUEUE,), - queue_id=q1['qos_queue']['id']) - net2 = self.deserialize('json', res) - self.assertEqual(net1['network'][ext_qos.QUEUE], - q1['qos_queue']['id']) - device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1" - res = self._create_port('json', net1['network']['id'], - device_id=device_id) - port1 = self.deserialize('json', res) - res = self._create_port('json', net2['network']['id'], - device_id=device_id) - port2 = self.deserialize('json', res) - self.assertEqual(port1['port'][ext_qos.QUEUE], - port2['port'][ext_qos.QUEUE]) - - self._delete('ports', port1['port']['id']) - self._delete('ports', port2['port']['id']) - - def test_remove_queue_in_use_fail(self): - with self.qos_queue(no_delete=True) as q1: - res = self._create_network('json', 'net1', True, - arg_list=(ext_qos.QUEUE,), - queue_id=q1['qos_queue']['id']) - net1 = self.deserialize('json', res) - device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1" - res = self._create_port('json', net1['network']['id'], - device_id=device_id) - port = self.deserialize('json', res) - self._delete('qos-queues', port['port'][ext_qos.QUEUE], 409) - - def test_update_network_new_queue(self): - with self.qos_queue() as q1: - res = self._create_network('json', 'net1', True, - arg_list=(ext_qos.QUEUE,), - queue_id=q1['qos_queue']['id']) - net1 = self.deserialize('json', res) - with self.qos_queue() as new_q: - data = {'network': {ext_qos.QUEUE: new_q['qos_queue']['id']}} - req = self.new_update_request('networks', data, - net1['network']['id']) - res = req.get_response(self.api) - net1 = self.deserialize('json', res) - self.assertEqual(net1['network'][ext_qos.QUEUE], - new_q['qos_queue']['id']) - - def test_update_port_adding_device_id(self): - with self.qos_queue(no_delete=True) as q1: - res = self._create_network('json', 'net1', True, - arg_list=(ext_qos.QUEUE,), - queue_id=q1['qos_queue']['id']) - net1 = self.deserialize('json', res) - device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1" - res = self._create_port('json', net1['network']['id']) - port = self.deserialize('json', res) - self.assertIsNone(port['port'][ext_qos.QUEUE]) - - data = {'port': {'device_id': device_id}} - req = self.new_update_request('ports', data, - port['port']['id']) - - res = req.get_response(self.api) - port = self.deserialize('json', res) - self.assertEqual(len(port['port'][ext_qos.QUEUE]), 36) - - def test_get_port_with_qos_not_admin(self): - body = {'qos_queue': {'tenant_id': 'not_admin', - 'name': 'foo', 'min': 20, 'max': 20}} - res = self._create_qos_queue('json', body, tenant_id='not_admin') - q1 = self.deserialize('json', res) - res = self._create_network('json', 'net1', True, - arg_list=(ext_qos.QUEUE, 'tenant_id',), - queue_id=q1['qos_queue']['id'], - tenant_id="not_admin") - net1 = self.deserialize('json', res) - self.assertEqual(len(net1['network'][ext_qos.QUEUE]), 36) - res = self._create_port('json', net1['network']['id'], - tenant_id='not_admin', set_context=True) - - port = self.deserialize('json', res) - self.assertNotIn(ext_qos.QUEUE, port['port']) - - def test_dscp_value_out_of_range(self): - body = {'qos_queue': {'tenant_id': 'admin', 'dscp': '64', - 'name': 'foo', 'min': 20, 'max': 20}} - res = self._create_qos_queue('json', body) - self.assertEqual(res.status_int, 400) - - def test_non_admin_cannot_create_queue(self): - body = {'qos_queue': {'tenant_id': 'not_admin', - 'name': 'foo', 'min': 20, 'max': 20}} - res = self._create_qos_queue('json', body, tenant_id='not_admin', - set_context=True) - self.assertEqual(res.status_int, 403) - - def test_update_port_non_admin_does_not_show_queue_id(self): - body = {'qos_queue': {'tenant_id': 'not_admin', - 'name': 'foo', 'min': 20, 'max': 20}} - res = self._create_qos_queue('json', body, tenant_id='not_admin') - q1 = self.deserialize('json', res) - res = self._create_network('json', 'net1', True, - arg_list=(ext_qos.QUEUE,), - tenant_id='not_admin', - queue_id=q1['qos_queue']['id']) - - net1 = self.deserialize('json', res) - res = self._create_port('json', net1['network']['id'], - tenant_id='not_admin', set_context=True) - port = self.deserialize('json', res) - device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1" - data = {'port': {'device_id': device_id}} - neutron_context = context.Context('', 'not_admin') - port = self._update('ports', port['port']['id'], data, - neutron_context=neutron_context) - self.assertNotIn(ext_qos.QUEUE, port['port']) - - def test_rxtx_factor(self): - with self.qos_queue(max=10) as q1: - - res = self._create_network('json', 'net1', True, - arg_list=(ext_qos.QUEUE,), - queue_id=q1['qos_queue']['id']) - net1 = self.deserialize('json', res) - res = self._create_port('json', net1['network']['id'], - arg_list=(ext_qos.RXTX_FACTOR,), - rxtx_factor=2, device_id='1') - port = self.deserialize('json', res) - req = self.new_show_request('qos-queues', - port['port'][ext_qos.QUEUE]) - res = req.get_response(self.ext_api) - queue = self.deserialize('json', res) - self.assertEqual(queue['qos_queue']['max'], 20) diff --git a/neutron/tests/unit/vmware/nsxlib/__init__.py b/neutron/tests/unit/vmware/nsxlib/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/vmware/nsxlib/base.py b/neutron/tests/unit/vmware/nsxlib/base.py deleted file mode 100644 index 8856c00c3..000000000 --- a/neutron/tests/unit/vmware/nsxlib/base.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# 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 neutron.plugins.vmware.api_client import client -from neutron.plugins.vmware.api_client import exception -from neutron.plugins.vmware.api_client import version -from neutron.plugins.vmware.common import config # noqa -from neutron.plugins.vmware import nsx_cluster as cluster -from neutron.tests import base -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.apiclient import fake - -_uuid = test_api_v2._uuid - - -class NsxlibTestCase(base.BaseTestCase): - - def setUp(self): - self.fc = fake.FakeClient(vmware.STUBS_PATH) - self.mock_nsxapi = mock.patch(vmware.NSXAPI_NAME, autospec=True) - instance = self.mock_nsxapi.start() - instance.return_value.login.return_value = "the_cookie" - fake_version = getattr(self, 'fake_version', "3.0") - instance.return_value.get_version.return_value = ( - version.Version(fake_version)) - - instance.return_value.request.side_effect = self.fc.fake_request - self.fake_cluster = cluster.NSXCluster( - name='fake-cluster', nsx_controllers=['1.1.1.1:999'], - default_tz_uuid=_uuid(), nsx_user='foo', nsx_password='bar') - self.fake_cluster.api_client = client.NsxApiClient( - ('1.1.1.1', '999', True), - self.fake_cluster.nsx_user, self.fake_cluster.nsx_password, - self.fake_cluster.req_timeout, self.fake_cluster.http_timeout, - self.fake_cluster.retries, self.fake_cluster.redirects) - - super(NsxlibTestCase, self).setUp() - self.addCleanup(self.fc.reset_all) - - def _build_tag_dict(self, tags): - # This syntax is needed for python 2.6 compatibility - return dict((t['scope'], t['tag']) for t in tags) - - -class NsxlibNegativeBaseTestCase(base.BaseTestCase): - - def setUp(self): - self.fc = fake.FakeClient(vmware.STUBS_PATH) - self.mock_nsxapi = mock.patch(vmware.NSXAPI_NAME, autospec=True) - instance = self.mock_nsxapi.start() - instance.return_value.login.return_value = "the_cookie" - # Choose 3.0, but the version is irrelevant for the aim of - # these tests as calls are throwing up errors anyway - fake_version = getattr(self, 'fake_version', "3.0") - instance.return_value.get_version.return_value = ( - version.Version(fake_version)) - - def _faulty_request(*args, **kwargs): - raise exception.NsxApiException - - instance.return_value.request.side_effect = _faulty_request - self.fake_cluster = cluster.NSXCluster( - name='fake-cluster', nsx_controllers=['1.1.1.1:999'], - default_tz_uuid=_uuid(), nsx_user='foo', nsx_password='bar') - self.fake_cluster.api_client = client.NsxApiClient( - ('1.1.1.1', '999', True), - self.fake_cluster.nsx_user, self.fake_cluster.nsx_password, - self.fake_cluster.req_timeout, self.fake_cluster.http_timeout, - self.fake_cluster.retries, self.fake_cluster.redirects) - - super(NsxlibNegativeBaseTestCase, self).setUp() - self.addCleanup(self.fc.reset_all) diff --git a/neutron/tests/unit/vmware/nsxlib/test_l2gateway.py b/neutron/tests/unit/vmware/nsxlib/test_l2gateway.py deleted file mode 100644 index 477233d6f..000000000 --- a/neutron/tests/unit/vmware/nsxlib/test_l2gateway.py +++ /dev/null @@ -1,296 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# 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 neutron.openstack.common import jsonutils -from neutron.plugins.vmware.api_client import exception -from neutron.plugins.vmware.common import utils as nsx_utils -from neutron.plugins.vmware import nsxlib -from neutron.plugins.vmware.nsxlib import l2gateway as l2gwlib -from neutron.plugins.vmware.nsxlib import switch as switchlib -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit.vmware.nsxlib import base - -_uuid = test_api_v2._uuid - - -class L2GatewayNegativeTestCase(base.NsxlibNegativeBaseTestCase): - - def test_create_l2_gw_service_on_failure(self): - self.assertRaises(exception.NsxApiException, - l2gwlib.create_l2_gw_service, - self.fake_cluster, - 'fake-tenant', - 'fake-gateway', - [{'id': _uuid(), - 'interface_name': 'xxx'}]) - - def test_delete_l2_gw_service_on_failure(self): - self.assertRaises(exception.NsxApiException, - l2gwlib.delete_l2_gw_service, - self.fake_cluster, - 'fake-gateway') - - def test_get_l2_gw_service_on_failure(self): - self.assertRaises(exception.NsxApiException, - l2gwlib.get_l2_gw_service, - self.fake_cluster, - 'fake-gateway') - - def test_update_l2_gw_service_on_failure(self): - self.assertRaises(exception.NsxApiException, - l2gwlib.update_l2_gw_service, - self.fake_cluster, - 'fake-gateway', - 'pluto') - - -class L2GatewayTestCase(base.NsxlibTestCase): - - def _create_gw_service(self, node_uuid, display_name, - tenant_id='fake_tenant'): - return l2gwlib.create_l2_gw_service(self.fake_cluster, - tenant_id, - display_name, - [{'id': node_uuid, - 'interface_name': 'xxx'}]) - - def test_create_l2_gw_service(self): - display_name = 'fake-gateway' - node_uuid = _uuid() - response = self._create_gw_service(node_uuid, display_name) - self.assertEqual(response.get('type'), 'L2GatewayServiceConfig') - self.assertEqual(response.get('display_name'), display_name) - gateways = response.get('gateways', []) - self.assertEqual(len(gateways), 1) - self.assertEqual(gateways[0]['type'], 'L2Gateway') - self.assertEqual(gateways[0]['device_id'], 'xxx') - self.assertEqual(gateways[0]['transport_node_uuid'], node_uuid) - - def test_update_l2_gw_service(self): - display_name = 'fake-gateway' - new_display_name = 'still-fake-gateway' - node_uuid = _uuid() - res1 = self._create_gw_service(node_uuid, display_name) - gw_id = res1['uuid'] - res2 = l2gwlib.update_l2_gw_service( - self.fake_cluster, gw_id, new_display_name) - self.assertEqual(res2['display_name'], new_display_name) - - def test_get_l2_gw_service(self): - display_name = 'fake-gateway' - node_uuid = _uuid() - gw_id = self._create_gw_service(node_uuid, display_name)['uuid'] - response = l2gwlib.get_l2_gw_service(self.fake_cluster, gw_id) - self.assertEqual(response.get('type'), 'L2GatewayServiceConfig') - self.assertEqual(response.get('display_name'), display_name) - self.assertEqual(response.get('uuid'), gw_id) - - def test_list_l2_gw_service(self): - gw_ids = [] - for name in ('fake-1', 'fake-2'): - gw_ids.append(self._create_gw_service(_uuid(), name)['uuid']) - results = l2gwlib.get_l2_gw_services(self.fake_cluster) - self.assertEqual(len(results), 2) - self.assertEqual(sorted(gw_ids), sorted([r['uuid'] for r in results])) - - def test_list_l2_gw_service_by_tenant(self): - gw_ids = [self._create_gw_service( - _uuid(), name, tenant_id=name)['uuid'] - for name in ('fake-1', 'fake-2')] - results = l2gwlib.get_l2_gw_services(self.fake_cluster, - tenant_id='fake-1') - self.assertEqual(len(results), 1) - self.assertEqual(results[0]['uuid'], gw_ids[0]) - - def test_delete_l2_gw_service(self): - display_name = 'fake-gateway' - node_uuid = _uuid() - gw_id = self._create_gw_service(node_uuid, display_name)['uuid'] - l2gwlib.delete_l2_gw_service(self.fake_cluster, gw_id) - results = l2gwlib.get_l2_gw_services(self.fake_cluster) - self.assertEqual(len(results), 0) - - def test_plug_l2_gw_port_attachment(self): - tenant_id = 'pippo' - node_uuid = _uuid() - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - lswitch = switchlib.create_lswitch( - self.fake_cluster, _uuid(), tenant_id, - 'fake-switch', transport_zones_config) - gw_id = self._create_gw_service(node_uuid, 'fake-gw')['uuid'] - lport = switchlib.create_lport( - self.fake_cluster, lswitch['uuid'], tenant_id, _uuid(), - 'fake-gw-port', gw_id, True) - l2gwlib.plug_l2_gw_service( - self.fake_cluster, lswitch['uuid'], - lport['uuid'], gw_id) - uri = nsxlib._build_uri_path(switchlib.LSWITCHPORT_RESOURCE, - lport['uuid'], - lswitch['uuid'], - is_attachment=True) - resp_obj = nsxlib.do_request("GET", uri, - cluster=self.fake_cluster) - self.assertIn('LogicalPortAttachment', resp_obj) - self.assertEqual(resp_obj['LogicalPortAttachment']['type'], - 'L2GatewayAttachment') - - def _create_expected_req_body(self, display_name, neutron_id, - connector_type, connector_ip, - client_certificate): - body = { - "display_name": display_name, - "tags": [{"tag": neutron_id, "scope": "q_gw_dev_id"}, - {"tag": 'fake_tenant', "scope": "os_tid"}, - {"tag": nsx_utils.NEUTRON_VERSION, - "scope": "quantum"}], - "transport_connectors": [ - {"transport_zone_uuid": 'fake_tz_uuid', - "ip_address": connector_ip, - "type": '%sConnector' % connector_type}], - "admin_status_enabled": True - } - if client_certificate: - body["credential"] = { - "client_certificate": { - "pem_encoded": client_certificate}, - "type": "SecurityCertificateCredential"} - return body - - def test_create_gw_device(self): - # NOTE(salv-orlando): This unit test mocks backend calls rather than - # leveraging the fake NSX API client - display_name = 'fake-device' - neutron_id = 'whatever' - connector_type = 'stt' - connector_ip = '1.1.1.1' - client_certificate = 'this_should_be_a_certificate' - with mock.patch.object(nsxlib, 'do_request') as request_mock: - expected_req_body = self._create_expected_req_body( - display_name, neutron_id, connector_type.upper(), - connector_ip, client_certificate) - l2gwlib.create_gateway_device( - self.fake_cluster, 'fake_tenant', display_name, neutron_id, - 'fake_tz_uuid', connector_type, connector_ip, - client_certificate) - request_mock.assert_called_once_with( - "POST", - "/ws.v1/transport-node", - jsonutils.dumps(expected_req_body), - cluster=self.fake_cluster) - - def test_update_gw_device(self): - # NOTE(salv-orlando): This unit test mocks backend calls rather than - # leveraging the fake NSX API client - display_name = 'fake-device' - neutron_id = 'whatever' - connector_type = 'stt' - connector_ip = '1.1.1.1' - client_certificate = 'this_should_be_a_certificate' - with mock.patch.object(nsxlib, 'do_request') as request_mock: - expected_req_body = self._create_expected_req_body( - display_name, neutron_id, connector_type.upper(), - connector_ip, client_certificate) - l2gwlib.update_gateway_device( - self.fake_cluster, 'whatever', 'fake_tenant', - display_name, neutron_id, - 'fake_tz_uuid', connector_type, connector_ip, - client_certificate) - - request_mock.assert_called_once_with( - "PUT", - "/ws.v1/transport-node/whatever", - jsonutils.dumps(expected_req_body), - cluster=self.fake_cluster) - - def test_update_gw_device_without_certificate(self): - # NOTE(salv-orlando): This unit test mocks backend calls rather than - # leveraging the fake NSX API client - display_name = 'fake-device' - neutron_id = 'whatever' - connector_type = 'stt' - connector_ip = '1.1.1.1' - with mock.patch.object(nsxlib, 'do_request') as request_mock: - expected_req_body = self._create_expected_req_body( - display_name, neutron_id, connector_type.upper(), - connector_ip, None) - l2gwlib.update_gateway_device( - self.fake_cluster, 'whatever', 'fake_tenant', - display_name, neutron_id, - 'fake_tz_uuid', connector_type, connector_ip, - client_certificate=None) - - request_mock.assert_called_once_with( - "PUT", - "/ws.v1/transport-node/whatever", - jsonutils.dumps(expected_req_body), - cluster=self.fake_cluster) - - def test_get_gw_device_status(self): - # NOTE(salv-orlando): This unit test mocks backend calls rather than - # leveraging the fake NSX API client - with mock.patch.object(nsxlib, 'do_request') as request_mock: - l2gwlib.get_gateway_device_status(self.fake_cluster, 'whatever') - request_mock.assert_called_once_with( - "GET", - "/ws.v1/transport-node/whatever/status", - cluster=self.fake_cluster) - - def test_get_gw_devices_status(self): - # NOTE(salv-orlando): This unit test mocks backend calls rather than - # leveraging the fake NSX API client - with mock.patch.object(nsxlib, 'do_request') as request_mock: - request_mock.return_value = { - 'results': [], - 'page_cursor': None, - 'result_count': 0} - l2gwlib.get_gateway_devices_status(self.fake_cluster) - request_mock.assert_called_once_with( - "GET", - ("/ws.v1/transport-node?fields=uuid,tags&" - "relations=TransportNodeStatus&" - "_page_length=1000&tag_scope=quantum"), - cluster=self.fake_cluster) - - def test_get_gw_devices_status_filter_by_tenant(self): - # NOTE(salv-orlando): This unit test mocks backend calls rather than - # leveraging the fake NSX API client - with mock.patch.object(nsxlib, 'do_request') as request_mock: - request_mock.return_value = { - 'results': [], - 'page_cursor': None, - 'result_count': 0} - l2gwlib.get_gateway_devices_status(self.fake_cluster, - tenant_id='ssc_napoli') - request_mock.assert_called_once_with( - "GET", - ("/ws.v1/transport-node?fields=uuid,tags&" - "relations=TransportNodeStatus&" - "tag_scope=os_tid&tag=ssc_napoli&" - "_page_length=1000&tag_scope=quantum"), - cluster=self.fake_cluster) - - def test_delete_gw_device(self): - # NOTE(salv-orlando): This unit test mocks backend calls rather than - # leveraging the fake NSX API client - with mock.patch.object(nsxlib, 'do_request') as request_mock: - l2gwlib.delete_gateway_device(self.fake_cluster, 'whatever') - request_mock.assert_called_once_with( - "DELETE", - "/ws.v1/transport-node/whatever", - cluster=self.fake_cluster) diff --git a/neutron/tests/unit/vmware/nsxlib/test_lsn.py b/neutron/tests/unit/vmware/nsxlib/test_lsn.py deleted file mode 100644 index 41c50b6c3..000000000 --- a/neutron/tests/unit/vmware/nsxlib/test_lsn.py +++ /dev/null @@ -1,370 +0,0 @@ -# Copyright 2013 VMware, Inc. -# -# 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 neutron.common import exceptions -from neutron.openstack.common import jsonutils as json -from neutron.plugins.vmware.api_client import exception as api_exc -from neutron.plugins.vmware.common import exceptions as nsx_exc -from neutron.plugins.vmware.common import utils -from neutron.plugins.vmware.nsxlib import lsn as lsnlib -from neutron.tests import base - - -class LSNTestCase(base.BaseTestCase): - - def setUp(self): - super(LSNTestCase, self).setUp() - self.mock_request_p = mock.patch( - 'neutron.plugins.vmware.nsxlib.do_request') - self.mock_request = self.mock_request_p.start() - self.cluster = mock.Mock() - self.cluster.default_service_cluster_uuid = 'foo' - - def test_service_cluster_None(self): - self.mock_request.return_value = None - expected = lsnlib.service_cluster_exists(None, None) - self.assertFalse(expected) - - def test_service_cluster_found(self): - self.mock_request.return_value = { - "results": [ - { - "_href": "/ws.v1/service-cluster/foo_uuid", - "display_name": "foo_name", - "uuid": "foo_uuid", - "tags": [], - "_schema": "/ws.v1/schema/ServiceClusterConfig", - "gateways": [] - } - ], - "result_count": 1 - } - expected = lsnlib.service_cluster_exists(None, 'foo_uuid') - self.assertTrue(expected) - - def test_service_cluster_not_found(self): - self.mock_request.side_effect = exceptions.NotFound() - expected = lsnlib.service_cluster_exists(None, 'foo_uuid') - self.assertFalse(expected) - - def test_lsn_for_network_create(self): - net_id = "foo_network_id" - tags = utils.get_tags(n_network_id=net_id) - obj = {"edge_cluster_uuid": "foo", "tags": tags} - lsnlib.lsn_for_network_create(self.cluster, net_id) - self.mock_request.assert_called_once_with( - "POST", "/ws.v1/lservices-node", - json.dumps(obj), cluster=self.cluster) - - def test_lsn_for_network_get(self): - net_id = "foo_network_id" - lsn_id = "foo_lsn_id" - self.mock_request.return_value = { - "results": [{"uuid": "foo_lsn_id"}], - "result_count": 1 - } - result = lsnlib.lsn_for_network_get(self.cluster, net_id) - self.assertEqual(lsn_id, result) - self.mock_request.assert_called_once_with( - "GET", - ("/ws.v1/lservices-node?fields=uuid&tag_scope=" - "n_network_id&tag=%s" % net_id), - cluster=self.cluster) - - def test_lsn_for_network_get_none(self): - net_id = "foo_network_id" - self.mock_request.return_value = { - "results": [{"uuid": "foo_lsn_id1"}, {"uuid": "foo_lsn_id2"}], - "result_count": 2 - } - result = lsnlib.lsn_for_network_get(self.cluster, net_id) - self.assertIsNone(result) - - def test_lsn_for_network_get_raise_not_found(self): - net_id = "foo_network_id" - self.mock_request.return_value = { - "results": [], "result_count": 0 - } - self.assertRaises(exceptions.NotFound, - lsnlib.lsn_for_network_get, - self.cluster, net_id) - - def test_lsn_delete(self): - lsn_id = "foo_id" - lsnlib.lsn_delete(self.cluster, lsn_id) - self.mock_request.assert_called_once_with( - "DELETE", - "/ws.v1/lservices-node/%s" % lsn_id, cluster=self.cluster) - - def _test_lsn_port_host_entries_update(self, lsn_type, hosts_data): - lsn_id = 'foo_lsn_id' - lsn_port_id = 'foo_lsn_port_id' - lsnlib.lsn_port_host_entries_update( - self.cluster, lsn_id, lsn_port_id, lsn_type, hosts_data) - self.mock_request.assert_called_once_with( - 'PUT', - '/ws.v1/lservices-node/%s/lport/%s/%s' % (lsn_id, - lsn_port_id, - lsn_type), - json.dumps({'hosts': hosts_data}), - cluster=self.cluster) - - def test_lsn_port_dhcp_entries_update(self): - hosts_data = [{"ip_address": "11.22.33.44", - "mac_address": "aa:bb:cc:dd:ee:ff"}, - {"ip_address": "44.33.22.11", - "mac_address": "ff:ee:dd:cc:bb:aa"}] - self._test_lsn_port_host_entries_update("dhcp", hosts_data) - - def test_lsn_port_metadata_entries_update(self): - hosts_data = [{"ip_address": "11.22.33.44", - "device_id": "foo_vm_uuid"}] - self._test_lsn_port_host_entries_update("metadata-proxy", hosts_data) - - def test_lsn_port_create(self): - port_data = { - "ip_address": "1.2.3.0/24", - "mac_address": "aa:bb:cc:dd:ee:ff", - "subnet_id": "foo_subnet_id" - } - port_id = "foo_port_id" - self.mock_request.return_value = {"uuid": port_id} - lsn_id = "foo_lsn_id" - result = lsnlib.lsn_port_create(self.cluster, lsn_id, port_data) - self.assertEqual(result, port_id) - tags = utils.get_tags(n_subnet_id=port_data["subnet_id"], - n_mac_address=port_data["mac_address"]) - port_obj = { - "ip_address": port_data["ip_address"], - "mac_address": port_data["mac_address"], - "type": "LogicalServicesNodePortConfig", - "tags": tags - } - self.mock_request.assert_called_once_with( - "POST", "/ws.v1/lservices-node/%s/lport" % lsn_id, - json.dumps(port_obj), cluster=self.cluster) - - def test_lsn_port_delete(self): - lsn_id = "foo_lsn_id" - lsn_port_id = "foo_port_id" - lsnlib.lsn_port_delete(self.cluster, lsn_id, lsn_port_id) - self.mock_request.assert_called_once_with( - "DELETE", - "/ws.v1/lservices-node/%s/lport/%s" % (lsn_id, lsn_port_id), - cluster=self.cluster) - - def test_lsn_port_get_with_filters(self): - lsn_id = "foo_lsn_id" - port_id = "foo_port_id" - filters = {"tag": "foo_tag", "tag_scope": "foo_scope"} - self.mock_request.return_value = { - "results": [{"uuid": port_id}], - "result_count": 1 - } - result = lsnlib._lsn_port_get(self.cluster, lsn_id, filters) - self.assertEqual(result, port_id) - self.mock_request.assert_called_once_with( - "GET", - ("/ws.v1/lservices-node/%s/lport?fields=uuid&tag_scope=%s&" - "tag=%s" % (lsn_id, filters["tag_scope"], filters["tag"])), - cluster=self.cluster) - - def test_lsn_port_get_with_filters_return_none(self): - self.mock_request.return_value = { - "results": [{"uuid": "foo1"}, {"uuid": "foo2"}], - "result_count": 2 - } - result = lsnlib._lsn_port_get(self.cluster, "lsn_id", None) - self.assertIsNone(result) - - def test_lsn_port_get_with_filters_raises_not_found(self): - self.mock_request.return_value = {"results": [], "result_count": 0} - self.assertRaises(exceptions.NotFound, - lsnlib._lsn_port_get, - self.cluster, "lsn_id", None) - - def test_lsn_port_info_get(self): - self.mock_request.return_value = { - "tags": [ - {"scope": "n_mac_address", "tag": "fa:16:3e:27:fd:a0"}, - {"scope": "n_subnet_id", "tag": "foo_subnet_id"}, - ], - "mac_address": "aa:bb:cc:dd:ee:ff", - "ip_address": "0.0.0.0/0", - "uuid": "foo_lsn_port_id" - } - result = lsnlib.lsn_port_info_get( - self.cluster, 'foo_lsn_id', 'foo_lsn_port_id') - self.mock_request.assert_called_once_with( - 'GET', '/ws.v1/lservices-node/foo_lsn_id/lport/foo_lsn_port_id', - cluster=self.cluster) - self.assertIn('subnet_id', result) - self.assertIn('mac_address', result) - - def test_lsn_port_info_get_raise_not_found(self): - self.mock_request.side_effect = exceptions.NotFound - self.assertRaises(exceptions.NotFound, - lsnlib.lsn_port_info_get, - self.cluster, mock.ANY, mock.ANY) - - def test_lsn_port_plug_network(self): - lsn_id = "foo_lsn_id" - lsn_port_id = "foo_lsn_port_id" - lswitch_port_id = "foo_lswitch_port_id" - lsnlib.lsn_port_plug_network( - self.cluster, lsn_id, lsn_port_id, lswitch_port_id) - self.mock_request.assert_called_once_with( - "PUT", - ("/ws.v1/lservices-node/%s/lport/%s/" - "attachment") % (lsn_id, lsn_port_id), - json.dumps({"peer_port_uuid": lswitch_port_id, - "type": "PatchAttachment"}), - cluster=self.cluster) - - def test_lsn_port_plug_network_raise_conflict(self): - lsn_id = "foo_lsn_id" - lsn_port_id = "foo_lsn_port_id" - lswitch_port_id = "foo_lswitch_port_id" - self.mock_request.side_effect = api_exc.Conflict - self.assertRaises( - nsx_exc.LsnConfigurationConflict, - lsnlib.lsn_port_plug_network, - self.cluster, lsn_id, lsn_port_id, lswitch_port_id) - - def _test_lsn_port_dhcp_configure( - self, lsn_id, lsn_port_id, is_enabled, opts): - lsnlib.lsn_port_dhcp_configure( - self.cluster, lsn_id, lsn_port_id, is_enabled, opts) - opt_array = [ - {"name": key, "value": val} - for key, val in opts.iteritems() - ] - self.mock_request.assert_has_calls([ - mock.call("PUT", "/ws.v1/lservices-node/%s/dhcp" % lsn_id, - json.dumps({"enabled": is_enabled}), - cluster=self.cluster), - mock.call("PUT", - ("/ws.v1/lservices-node/%s/" - "lport/%s/dhcp") % (lsn_id, lsn_port_id), - json.dumps({"options": opt_array}), - cluster=self.cluster) - ]) - - def test_lsn_port_dhcp_configure_empty_opts(self): - lsn_id = "foo_lsn_id" - lsn_port_id = "foo_lsn_port_id" - is_enabled = False - opts = {} - self._test_lsn_port_dhcp_configure( - lsn_id, lsn_port_id, is_enabled, opts) - - def test_lsn_port_dhcp_configure_with_opts(self): - lsn_id = "foo_lsn_id" - lsn_port_id = "foo_lsn_port_id" - is_enabled = True - opts = {"opt1": "val1", "opt2": "val2"} - self._test_lsn_port_dhcp_configure( - lsn_id, lsn_port_id, is_enabled, opts) - - def _test_lsn_metadata_configure( - self, lsn_id, is_enabled, opts, expected_opts): - lsnlib.lsn_metadata_configure( - self.cluster, lsn_id, is_enabled, opts) - lsn_obj = {"enabled": is_enabled} - lsn_obj.update(expected_opts) - self.mock_request.assert_has_calls([ - mock.call("PUT", - "/ws.v1/lservices-node/%s/metadata-proxy" % lsn_id, - json.dumps(lsn_obj), - cluster=self.cluster), - ]) - - def test_lsn_port_metadata_configure_empty_secret(self): - lsn_id = "foo_lsn_id" - is_enabled = True - opts = { - "metadata_server_ip": "1.2.3.4", - "metadata_server_port": "8775" - } - expected_opts = { - "metadata_server_ip": "1.2.3.4", - "metadata_server_port": "8775", - } - self._test_lsn_metadata_configure( - lsn_id, is_enabled, opts, expected_opts) - - def test_lsn_metadata_configure_with_secret(self): - lsn_id = "foo_lsn_id" - is_enabled = True - opts = { - "metadata_server_ip": "1.2.3.4", - "metadata_server_port": "8775", - "metadata_proxy_shared_secret": "foo_secret" - } - expected_opts = { - "metadata_server_ip": "1.2.3.4", - "metadata_server_port": "8775", - "options": [{ - "name": "metadata_proxy_shared_secret", - "value": "foo_secret" - }] - } - self._test_lsn_metadata_configure( - lsn_id, is_enabled, opts, expected_opts) - - def _test_lsn_port_host_action( - self, lsn_port_action_func, extra_action, action, host): - lsn_id = "foo_lsn_id" - lsn_port_id = "foo_lsn_port_id" - lsn_port_action_func(self.cluster, lsn_id, lsn_port_id, host) - self.mock_request.assert_called_once_with( - "POST", - ("/ws.v1/lservices-node/%s/lport/" - "%s/%s?action=%s") % (lsn_id, lsn_port_id, extra_action, action), - json.dumps(host), cluster=self.cluster) - - def test_lsn_port_dhcp_host_add(self): - host = { - "ip_address": "1.2.3.4", - "mac_address": "aa:bb:cc:dd:ee:ff" - } - self._test_lsn_port_host_action( - lsnlib.lsn_port_dhcp_host_add, "dhcp", "add_host", host) - - def test_lsn_port_dhcp_host_remove(self): - host = { - "ip_address": "1.2.3.4", - "mac_address": "aa:bb:cc:dd:ee:ff" - } - self._test_lsn_port_host_action( - lsnlib.lsn_port_dhcp_host_remove, "dhcp", "remove_host", host) - - def test_lsn_port_metadata_host_add(self): - host = { - "ip_address": "1.2.3.4", - "instance_id": "foo_instance_id" - } - self._test_lsn_port_host_action(lsnlib.lsn_port_metadata_host_add, - "metadata-proxy", "add_host", host) - - def test_lsn_port_metadata_host_remove(self): - host = { - "ip_address": "1.2.3.4", - "instance_id": "foo_instance_id" - } - self._test_lsn_port_host_action(lsnlib.lsn_port_metadata_host_remove, - "metadata-proxy", "remove_host", host) diff --git a/neutron/tests/unit/vmware/nsxlib/test_queue.py b/neutron/tests/unit/vmware/nsxlib/test_queue.py deleted file mode 100644 index 1d7e2ea56..000000000 --- a/neutron/tests/unit/vmware/nsxlib/test_queue.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# 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 neutron.common import exceptions -from neutron.plugins.vmware.api_client import exception as api_exc -from neutron.plugins.vmware import nsxlib -from neutron.plugins.vmware.nsxlib import queue as queuelib -from neutron.tests.unit.vmware.nsxlib import base - - -class TestLogicalQueueLib(base.NsxlibTestCase): - - def setUp(self): - super(TestLogicalQueueLib, self).setUp() - self.fake_queue = { - 'name': 'fake_queue', - 'min': 0, 'max': 256, - 'dscp': 0, 'qos_marking': False - } - - def test_create_and_get_lqueue(self): - queue_id = queuelib.create_lqueue( - self.fake_cluster, self.fake_queue) - queue_res = nsxlib.do_request( - 'GET', - nsxlib._build_uri_path('lqueue', resource_id=queue_id), - cluster=self.fake_cluster) - self.assertEqual(queue_id, queue_res['uuid']) - self.assertEqual('fake_queue', queue_res['display_name']) - - def test_create_lqueue_nsx_error_raises(self): - def raise_nsx_exc(*args, **kwargs): - raise api_exc.NsxApiException() - - with mock.patch.object(nsxlib, 'do_request', new=raise_nsx_exc): - self.assertRaises( - exceptions.NeutronException, queuelib.create_lqueue, - self.fake_cluster, self.fake_queue) - - def test_delete_lqueue(self): - queue_id = queuelib.create_lqueue( - self.fake_cluster, self.fake_queue) - queuelib.delete_lqueue(self.fake_cluster, queue_id) - self.assertRaises(exceptions.NotFound, - nsxlib.do_request, - 'GET', - nsxlib._build_uri_path( - 'lqueue', resource_id=queue_id), - cluster=self.fake_cluster) - - def test_delete_non_existing_lqueue_raises(self): - self.assertRaises(exceptions.NeutronException, - queuelib.delete_lqueue, - self.fake_cluster, 'whatever') diff --git a/neutron/tests/unit/vmware/nsxlib/test_router.py b/neutron/tests/unit/vmware/nsxlib/test_router.py deleted file mode 100644 index 6d4063fe5..000000000 --- a/neutron/tests/unit/vmware/nsxlib/test_router.py +++ /dev/null @@ -1,922 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# 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 oslo.config import cfg - -from neutron.common import exceptions -from neutron.openstack.common import uuidutils -from neutron.plugins.vmware.api_client import exception as api_exc -from neutron.plugins.vmware.api_client import version as version_module -from neutron.plugins.vmware.common import exceptions as nsx_exc -from neutron.plugins.vmware.common import utils -from neutron.plugins.vmware import nsxlib -from neutron.plugins.vmware.nsxlib import router as routerlib -from neutron.plugins.vmware.nsxlib import switch as switchlib -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit.vmware.nsxlib import base - -_uuid = test_api_v2._uuid - - -class TestNatRules(base.NsxlibTestCase): - - def _test_create_lrouter_dnat_rule(self, version): - with mock.patch.object(self.fake_cluster.api_client, - 'get_version', - new=lambda: version_module.Version(version)): - tenant_id = 'pippo' - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - tenant_id, - 'fake_router', - '192.168.0.1') - nat_rule = routerlib.create_lrouter_dnat_rule( - self.fake_cluster, lrouter['uuid'], '10.0.0.99', - match_criteria={'destination_ip_addresses': - '192.168.0.5'}) - uri = nsxlib._build_uri_path(routerlib.LROUTERNAT_RESOURCE, - nat_rule['uuid'], - lrouter['uuid']) - resp_obj = nsxlib.do_request("GET", uri, cluster=self.fake_cluster) - self.assertEqual('DestinationNatRule', resp_obj['type']) - self.assertEqual('192.168.0.5', - resp_obj['match']['destination_ip_addresses']) - - def test_create_lrouter_dnat_rule_v2(self): - self._test_create_lrouter_dnat_rule('2.9') - - def test_create_lrouter_dnat_rule_v31(self): - self._test_create_lrouter_dnat_rule('3.1') - - -class TestExplicitLRouters(base.NsxlibTestCase): - - def setUp(self): - self.fake_version = '3.2' - super(TestExplicitLRouters, self).setUp() - - def _get_lrouter(self, tenant_id, router_name, router_id, relations=None): - schema = '/ws.v1/schema/RoutingTableRoutingConfig' - - router = {'display_name': router_name, - 'uuid': router_id, - 'tags': utils.get_tags(os_tid=tenant_id), - 'distributed': False, - 'routing_config': {'type': 'RoutingTableRoutingConfig', - '_schema': schema}, - '_schema': schema, - 'nat_synchronization_enabled': True, - 'replication_mode': 'service', - 'type': 'LogicalRouterConfig', - '_href': '/ws.v1/lrouter/%s' % router_id, } - if relations: - router['_relations'] = relations - return router - - def _get_single_route(self, router_id, route_id='fake_route_id_0', - prefix='0.0.0.0/0', next_hop_ip='1.1.1.1'): - return {'protocol': 'static', - '_href': '/ws.v1/lrouter/%s/rib/%s' % (router_id, route_id), - 'prefix': prefix, - '_schema': '/ws.v1/schema/RoutingTableEntry', - 'next_hop_ip': next_hop_ip, - 'action': 'accept', - 'uuid': route_id} - - def test_prepare_body_with_implicit_routing_config(self): - router_name = 'fake_router_name' - tenant_id = 'fake_tenant_id' - neutron_router_id = 'pipita_higuain' - router_type = 'SingleDefaultRouteImplicitRoutingConfig' - route_config = { - 'default_route_next_hop': {'gateway_ip_address': 'fake_address', - 'type': 'RouterNextHop'}, } - body = routerlib._prepare_lrouter_body(router_name, neutron_router_id, - tenant_id, router_type, - **route_config) - expected = {'display_name': 'fake_router_name', - 'routing_config': { - 'default_route_next_hop': - {'gateway_ip_address': 'fake_address', - 'type': 'RouterNextHop'}, - 'type': 'SingleDefaultRouteImplicitRoutingConfig'}, - 'tags': utils.get_tags(os_tid='fake_tenant_id', - q_router_id='pipita_higuain'), - 'type': 'LogicalRouterConfig', - 'replication_mode': cfg.CONF.NSX.replication_mode} - self.assertEqual(expected, body) - - def test_prepare_body_without_routing_config(self): - router_name = 'fake_router_name' - tenant_id = 'fake_tenant_id' - neutron_router_id = 'marekiaro_hamsik' - router_type = 'RoutingTableRoutingConfig' - body = routerlib._prepare_lrouter_body(router_name, neutron_router_id, - tenant_id, router_type) - expected = {'display_name': 'fake_router_name', - 'routing_config': {'type': 'RoutingTableRoutingConfig'}, - 'tags': utils.get_tags(os_tid='fake_tenant_id', - q_router_id='marekiaro_hamsik'), - 'type': 'LogicalRouterConfig', - 'replication_mode': cfg.CONF.NSX.replication_mode} - self.assertEqual(expected, body) - - def test_get_lrouter(self): - tenant_id = 'fake_tenant_id' - router_name = 'fake_router_name' - router_id = 'fake_router_id' - relations = { - 'LogicalRouterStatus': - {'_href': '/ws.v1/lrouter/%s/status' % router_id, - 'lport_admin_up_count': 1, - '_schema': '/ws.v1/schema/LogicalRouterStatus', - 'lport_count': 1, - 'fabric_status': True, - 'type': 'LogicalRouterStatus', - 'lport_link_up_count': 0, }, } - - with mock.patch.object(nsxlib, 'do_request', - return_value=self._get_lrouter(tenant_id, - router_name, - router_id, - relations)): - lrouter = routerlib.get_lrouter(self.fake_cluster, router_id) - self.assertTrue( - lrouter['_relations']['LogicalRouterStatus']['fabric_status']) - - def test_create_lrouter(self): - tenant_id = 'fake_tenant_id' - router_name = 'fake_router_name' - router_id = 'fake_router_id' - nexthop_ip = '10.0.0.1' - with mock.patch.object( - nsxlib, 'do_request', - return_value=self._get_lrouter(tenant_id, - router_name, - router_id)): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - tenant_id, - router_name, nexthop_ip) - self.assertEqual(lrouter['routing_config']['type'], - 'RoutingTableRoutingConfig') - self.assertNotIn('default_route_next_hop', - lrouter['routing_config']) - - def test_update_lrouter_with_no_routes(self): - router_id = 'fake_router_id' - new_routes = [{"nexthop": "10.0.0.2", - "destination": "169.254.169.0/30"}, ] - - nsx_routes = [self._get_single_route(router_id)] - with mock.patch.object(routerlib, 'get_explicit_routes_lrouter', - return_value=nsx_routes): - with mock.patch.object(routerlib, 'create_explicit_route_lrouter', - return_value='fake_uuid'): - old_routes = routerlib.update_explicit_routes_lrouter( - self.fake_cluster, router_id, new_routes) - self.assertEqual(old_routes, nsx_routes) - - def test_update_lrouter_with_no_routes_raise_nsx_exception(self): - router_id = 'fake_router_id' - new_routes = [{"nexthop": "10.0.0.2", - "destination": "169.254.169.0/30"}, ] - - nsx_routes = [self._get_single_route(router_id)] - with mock.patch.object(routerlib, 'get_explicit_routes_lrouter', - return_value=nsx_routes): - with mock.patch.object(routerlib, 'create_explicit_route_lrouter', - side_effect=api_exc.NsxApiException): - self.assertRaises(api_exc.NsxApiException, - routerlib.update_explicit_routes_lrouter, - self.fake_cluster, router_id, new_routes) - - def test_update_lrouter_with_routes(self): - router_id = 'fake_router_id' - new_routes = [{"next_hop_ip": "10.0.0.2", - "prefix": "169.254.169.0/30"}, ] - - nsx_routes = [self._get_single_route(router_id), - self._get_single_route(router_id, 'fake_route_id_1', - '0.0.0.1/24', '10.0.0.3'), - self._get_single_route(router_id, 'fake_route_id_2', - '0.0.0.2/24', '10.0.0.4'), ] - - with mock.patch.object(routerlib, 'get_explicit_routes_lrouter', - return_value=nsx_routes): - with mock.patch.object(routerlib, 'delete_explicit_route_lrouter', - return_value=None): - with mock.patch.object(routerlib, - 'create_explicit_route_lrouter', - return_value='fake_uuid'): - old_routes = routerlib.update_explicit_routes_lrouter( - self.fake_cluster, router_id, new_routes) - self.assertEqual(old_routes, nsx_routes) - - def test_update_lrouter_with_routes_raises_nsx_expception(self): - router_id = 'fake_router_id' - new_routes = [{"nexthop": "10.0.0.2", - "destination": "169.254.169.0/30"}, ] - - nsx_routes = [self._get_single_route(router_id), - self._get_single_route(router_id, 'fake_route_id_1', - '0.0.0.1/24', '10.0.0.3'), - self._get_single_route(router_id, 'fake_route_id_2', - '0.0.0.2/24', '10.0.0.4'), ] - - with mock.patch.object(routerlib, 'get_explicit_routes_lrouter', - return_value=nsx_routes): - with mock.patch.object(routerlib, 'delete_explicit_route_lrouter', - side_effect=api_exc.NsxApiException): - with mock.patch.object( - routerlib, 'create_explicit_route_lrouter', - return_value='fake_uuid'): - self.assertRaises( - api_exc.NsxApiException, - routerlib.update_explicit_routes_lrouter, - self.fake_cluster, router_id, new_routes) - - -class RouterNegativeTestCase(base.NsxlibNegativeBaseTestCase): - - def test_create_lrouter_on_failure(self): - self.assertRaises(api_exc.NsxApiException, - routerlib.create_lrouter, - self.fake_cluster, - uuidutils.generate_uuid(), - 'pluto', - 'fake_router', - 'my_hop') - - def test_delete_lrouter_on_failure(self): - self.assertRaises(api_exc.NsxApiException, - routerlib.delete_lrouter, - self.fake_cluster, - 'fake_router') - - def test_get_lrouter_on_failure(self): - self.assertRaises(api_exc.NsxApiException, - routerlib.get_lrouter, - self.fake_cluster, - 'fake_router') - - def test_update_lrouter_on_failure(self): - self.assertRaises(api_exc.NsxApiException, - routerlib.update_lrouter, - self.fake_cluster, - 'fake_router', - 'pluto', - 'new_hop') - - -class TestLogicalRouters(base.NsxlibTestCase): - - def _verify_lrouter(self, res_lrouter, - expected_uuid, - expected_display_name, - expected_nexthop, - expected_tenant_id, - expected_neutron_id=None, - expected_distributed=None): - self.assertEqual(res_lrouter['uuid'], expected_uuid) - nexthop = (res_lrouter['routing_config'] - ['default_route_next_hop']['gateway_ip_address']) - self.assertEqual(nexthop, expected_nexthop) - router_tags = self._build_tag_dict(res_lrouter['tags']) - self.assertIn('os_tid', router_tags) - self.assertEqual(res_lrouter['display_name'], expected_display_name) - self.assertEqual(expected_tenant_id, router_tags['os_tid']) - if expected_distributed is not None: - self.assertEqual(expected_distributed, - res_lrouter['distributed']) - if expected_neutron_id: - self.assertIn('q_router_id', router_tags) - self.assertEqual(expected_neutron_id, router_tags['q_router_id']) - - def test_get_lrouters(self): - lrouter_uuids = [routerlib.create_lrouter( - self.fake_cluster, 'whatever', 'pippo', 'fake-lrouter-%s' % k, - '10.0.0.1')['uuid'] for k in range(3)] - routers = routerlib.get_lrouters(self.fake_cluster, 'pippo') - for router in routers: - self.assertIn(router['uuid'], lrouter_uuids) - - def _create_lrouter(self, version, neutron_id=None, distributed=None): - with mock.patch.object( - self.fake_cluster.api_client, 'get_version', - return_value=version_module.Version(version)): - if not neutron_id: - neutron_id = uuidutils.generate_uuid() - lrouter = routerlib.create_lrouter( - self.fake_cluster, neutron_id, 'pippo', - 'fake-lrouter', '10.0.0.1', distributed=distributed) - return routerlib.get_lrouter(self.fake_cluster, - lrouter['uuid']) - - def test_create_and_get_lrouter_v30(self): - neutron_id = uuidutils.generate_uuid() - res_lrouter = self._create_lrouter('3.0', neutron_id=neutron_id) - self._verify_lrouter(res_lrouter, res_lrouter['uuid'], - 'fake-lrouter', '10.0.0.1', 'pippo', - expected_neutron_id=neutron_id) - - def test_create_and_get_lrouter_v31_centralized(self): - neutron_id = uuidutils.generate_uuid() - res_lrouter = self._create_lrouter('3.1', neutron_id=neutron_id, - distributed=False) - self._verify_lrouter(res_lrouter, res_lrouter['uuid'], - 'fake-lrouter', '10.0.0.1', 'pippo', - expected_neutron_id=neutron_id, - expected_distributed=False) - - def test_create_and_get_lrouter_v31_distributed(self): - neutron_id = uuidutils.generate_uuid() - res_lrouter = self._create_lrouter('3.1', neutron_id=neutron_id, - distributed=True) - self._verify_lrouter(res_lrouter, res_lrouter['uuid'], - 'fake-lrouter', '10.0.0.1', 'pippo', - expected_neutron_id=neutron_id, - expected_distributed=True) - - def test_create_and_get_lrouter_name_exceeds_40chars(self): - neutron_id = uuidutils.generate_uuid() - display_name = '*' * 50 - lrouter = routerlib.create_lrouter(self.fake_cluster, - neutron_id, - 'pippo', - display_name, - '10.0.0.1') - res_lrouter = routerlib.get_lrouter(self.fake_cluster, - lrouter['uuid']) - self._verify_lrouter(res_lrouter, lrouter['uuid'], - '*' * 40, '10.0.0.1', 'pippo', - expected_neutron_id=neutron_id) - - def _test_version_dependent_update_lrouter(self, version): - def foo(*args, **kwargs): - return version - - foo_func_dict = { - 'update_lrouter': { - 2: {-1: foo}, - 3: {-1: foo, 2: foo} - } - } - - with mock.patch.object(self.fake_cluster.api_client, - 'get_version', - return_value=version_module.Version(version)): - with mock.patch.dict(routerlib.ROUTER_FUNC_DICT, - foo_func_dict, clear=True): - return routerlib.update_lrouter( - self.fake_cluster, 'foo_router_id', 'foo_router_name', - 'foo_nexthop', routes={'foo_destination': 'foo_address'}) - - def test_version_dependent_update_lrouter_old_versions(self): - self.assertRaises(nsx_exc.InvalidVersion, - self._test_version_dependent_update_lrouter, - "2.9") - self.assertRaises(nsx_exc.InvalidVersion, - self._test_version_dependent_update_lrouter, - "3.0") - self.assertRaises(nsx_exc.InvalidVersion, - self._test_version_dependent_update_lrouter, - "3.1") - - def test_version_dependent_update_lrouter_new_versions(self): - self.assertEqual("3.2", - self._test_version_dependent_update_lrouter("3.2")) - self.assertEqual("4.0", - self._test_version_dependent_update_lrouter("4.0")) - self.assertEqual("4.1", - self._test_version_dependent_update_lrouter("4.1")) - - def test_update_lrouter_no_nexthop(self): - neutron_id = uuidutils.generate_uuid() - lrouter = routerlib.create_lrouter(self.fake_cluster, - neutron_id, - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter = routerlib.update_lrouter(self.fake_cluster, - lrouter['uuid'], - 'new_name', - None) - res_lrouter = routerlib.get_lrouter(self.fake_cluster, - lrouter['uuid']) - self._verify_lrouter(res_lrouter, lrouter['uuid'], - 'new_name', '10.0.0.1', 'pippo', - expected_neutron_id=neutron_id) - - def test_update_lrouter(self): - neutron_id = uuidutils.generate_uuid() - lrouter = routerlib.create_lrouter(self.fake_cluster, - neutron_id, - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter = routerlib.update_lrouter(self.fake_cluster, - lrouter['uuid'], - 'new_name', - '192.168.0.1') - res_lrouter = routerlib.get_lrouter(self.fake_cluster, - lrouter['uuid']) - self._verify_lrouter(res_lrouter, lrouter['uuid'], - 'new_name', '192.168.0.1', 'pippo', - expected_neutron_id=neutron_id) - - def test_update_nonexistent_lrouter_raises(self): - self.assertRaises(exceptions.NotFound, - routerlib.update_lrouter, - self.fake_cluster, - 'whatever', - 'foo', '9.9.9.9') - - def test_delete_lrouter(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - routerlib.delete_lrouter(self.fake_cluster, lrouter['uuid']) - self.assertRaises(exceptions.NotFound, - routerlib.get_lrouter, - self.fake_cluster, - lrouter['uuid']) - - def test_query_lrouter_ports(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - router_port_uuids = [routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', - 'qp_id_%s' % k, 'port-%s' % k, True, - ['192.168.0.%s' % k], '00:11:22:33:44:55')['uuid'] - for k in range(3)] - ports = routerlib.query_lrouter_lports( - self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(ports), 3) - for res_port in ports: - self.assertIn(res_port['uuid'], router_port_uuids) - - def test_query_lrouter_lports_nonexistent_lrouter_raises(self): - self.assertRaises( - exceptions.NotFound, routerlib.create_router_lport, - self.fake_cluster, 'booo', 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') - - def test_create_and_get_lrouter_port(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') - ports = routerlib.query_lrouter_lports( - self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(ports), 1) - res_port = ports[0] - port_tags = self._build_tag_dict(res_port['tags']) - self.assertEqual(['192.168.0.1'], res_port['ip_addresses']) - self.assertIn('os_tid', port_tags) - self.assertIn('q_port_id', port_tags) - self.assertEqual('pippo', port_tags['os_tid']) - self.assertEqual('neutron_port_id', port_tags['q_port_id']) - - def test_create_lrouter_port_nonexistent_router_raises(self): - self.assertRaises( - exceptions.NotFound, routerlib.create_router_lport, - self.fake_cluster, 'booo', 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') - - def test_update_lrouter_port(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') - routerlib.update_router_lport( - self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'], - 'pippo', 'another_port_id', 'name', False, - ['192.168.0.1', '10.10.10.254']) - - ports = routerlib.query_lrouter_lports( - self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(ports), 1) - res_port = ports[0] - port_tags = self._build_tag_dict(res_port['tags']) - self.assertEqual(['192.168.0.1', '10.10.10.254'], - res_port['ip_addresses']) - self.assertEqual('False', res_port['admin_status_enabled']) - self.assertIn('os_tid', port_tags) - self.assertIn('q_port_id', port_tags) - self.assertEqual('pippo', port_tags['os_tid']) - self.assertEqual('another_port_id', port_tags['q_port_id']) - - def test_update_lrouter_port_nonexistent_router_raises(self): - self.assertRaises( - exceptions.NotFound, routerlib.update_router_lport, - self.fake_cluster, 'boo-router', 'boo-port', 'pippo', - 'neutron_port_id', 'name', True, ['192.168.0.1']) - - def test_update_lrouter_port_nonexistent_port_raises(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - self.assertRaises( - exceptions.NotFound, routerlib.update_router_lport, - self.fake_cluster, lrouter['uuid'], 'boo-port', 'pippo', - 'neutron_port_id', 'name', True, ['192.168.0.1']) - - def test_delete_lrouter_port(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'x', 'y', True, [], - '00:11:22:33:44:55') - ports = routerlib.query_lrouter_lports( - self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(ports), 1) - routerlib.delete_router_lport(self.fake_cluster, lrouter['uuid'], - lrouter_port['uuid']) - ports = routerlib.query_lrouter_lports( - self.fake_cluster, lrouter['uuid']) - self.assertFalse(len(ports)) - - def test_delete_lrouter_port_nonexistent_router_raises(self): - self.assertRaises(exceptions.NotFound, - routerlib.delete_router_lport, - self.fake_cluster, 'xyz', 'abc') - - def test_delete_lrouter_port_nonexistent_port_raises(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - self.assertRaises(exceptions.NotFound, - routerlib.delete_router_lport, - self.fake_cluster, lrouter['uuid'], 'abc') - - def test_delete_peer_lrouter_port(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'x', 'y', True, [], - '00:11:22:33:44:55') - - def fakegetport(*args, **kwargs): - return {'_relations': {'LogicalPortAttachment': - {'peer_port_uuid': lrouter_port['uuid']}}} - # mock get_port - with mock.patch.object(switchlib, 'get_port', new=fakegetport): - routerlib.delete_peer_router_lport(self.fake_cluster, - lrouter_port['uuid'], - 'whatwever', 'whatever') - - def test_update_lrouter_port_ips_add_only(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') - routerlib.update_lrouter_port_ips( - self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'], - ['10.10.10.254'], []) - ports = routerlib.query_lrouter_lports( - self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(ports), 1) - res_port = ports[0] - self.assertEqual(['10.10.10.254', '192.168.0.1'], - res_port['ip_addresses']) - - def test_update_lrouter_port_ips_remove_only(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1', '10.10.10.254'], - '00:11:22:33:44:55') - routerlib.update_lrouter_port_ips( - self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'], - [], ['10.10.10.254']) - ports = routerlib.query_lrouter_lports( - self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(ports), 1) - res_port = ports[0] - self.assertEqual(['192.168.0.1'], res_port['ip_addresses']) - - def test_update_lrouter_port_ips_add_and_remove(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') - routerlib.update_lrouter_port_ips( - self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'], - ['10.10.10.254'], ['192.168.0.1']) - ports = routerlib.query_lrouter_lports( - self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(ports), 1) - res_port = ports[0] - self.assertEqual(['10.10.10.254'], res_port['ip_addresses']) - - def test_update_lrouter_port_ips_nonexistent_router_raises(self): - self.assertRaises( - nsx_exc.NsxPluginException, routerlib.update_lrouter_port_ips, - self.fake_cluster, 'boo-router', 'boo-port', [], []) - - def test_update_lrouter_port_ips_nsx_exception_raises(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') - - def raise_nsx_exc(*args, **kwargs): - raise api_exc.NsxApiException() - - with mock.patch.object(nsxlib, 'do_request', new=raise_nsx_exc): - self.assertRaises( - nsx_exc.NsxPluginException, routerlib.update_lrouter_port_ips, - self.fake_cluster, lrouter['uuid'], - lrouter_port['uuid'], [], []) - - def test_plug_lrouter_port_patch_attachment(self): - tenant_id = 'pippo' - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - lswitch = switchlib.create_lswitch(self.fake_cluster, - _uuid(), - tenant_id, 'fake-switch', - transport_zones_config) - lport = switchlib.create_lport(self.fake_cluster, lswitch['uuid'], - tenant_id, 'xyz', - 'name', 'device_id', True) - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - tenant_id, - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55:66') - result = routerlib.plug_router_port_attachment( - self.fake_cluster, lrouter['uuid'], - lrouter_port['uuid'], - lport['uuid'], 'PatchAttachment') - self.assertEqual(lport['uuid'], - result['LogicalPortAttachment']['peer_port_uuid']) - - def test_plug_lrouter_port_l3_gw_attachment(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55:66') - result = routerlib.plug_router_port_attachment( - self.fake_cluster, lrouter['uuid'], - lrouter_port['uuid'], - 'gw_att', 'L3GatewayAttachment') - self.assertEqual( - 'gw_att', - result['LogicalPortAttachment']['l3_gateway_service_uuid']) - - def test_plug_lrouter_port_l3_gw_attachment_with_vlan(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') - result = routerlib.plug_router_port_attachment( - self.fake_cluster, lrouter['uuid'], - lrouter_port['uuid'], - 'gw_att', 'L3GatewayAttachment', 123) - self.assertEqual( - 'gw_att', - result['LogicalPortAttachment']['l3_gateway_service_uuid']) - self.assertEqual( - '123', - result['LogicalPortAttachment']['vlan_id']) - - def test_plug_lrouter_port_invalid_attachment_type_raises(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - lrouter_port = routerlib.create_router_lport( - self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id', - 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') - self.assertRaises(nsx_exc.InvalidAttachmentType, - routerlib.plug_router_port_attachment, - self.fake_cluster, lrouter['uuid'], - lrouter_port['uuid'], 'gw_att', 'BadType') - - def _test_create_router_snat_rule(self, version): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - with mock.patch.object(self.fake_cluster.api_client, - 'get_version', - new=lambda: version_module.Version(version)): - routerlib.create_lrouter_snat_rule( - self.fake_cluster, lrouter['uuid'], - '10.0.0.2', '10.0.0.2', order=200, - match_criteria={'source_ip_addresses': '192.168.0.24'}) - rules = routerlib.query_nat_rules( - self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 1) - - def test_create_router_snat_rule_v3(self): - self._test_create_router_snat_rule('3.0') - - def test_create_router_snat_rule_v2(self): - self._test_create_router_snat_rule('2.0') - - def _test_create_router_dnat_rule(self, version, dest_port=None): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - with mock.patch.object(self.fake_cluster.api_client, - 'get_version', - return_value=version_module.Version(version)): - routerlib.create_lrouter_dnat_rule( - self.fake_cluster, lrouter['uuid'], '192.168.0.2', order=200, - dest_port=dest_port, - match_criteria={'destination_ip_addresses': '10.0.0.3'}) - rules = routerlib.query_nat_rules( - self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 1) - - def test_create_router_dnat_rule_v3(self): - self._test_create_router_dnat_rule('3.0') - - def test_create_router_dnat_rule_v2(self): - self._test_create_router_dnat_rule('2.0') - - def test_create_router_dnat_rule_v2_with_destination_port(self): - self._test_create_router_dnat_rule('2.0', 8080) - - def test_create_router_dnat_rule_v3_with_destination_port(self): - self._test_create_router_dnat_rule('3.0', 8080) - - def test_create_router_snat_rule_invalid_match_keys_raises(self): - # In this case the version does not make a difference - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - - with mock.patch.object(self.fake_cluster.api_client, - 'get_version', - new=lambda: '2.0'): - self.assertRaises(AttributeError, - routerlib.create_lrouter_snat_rule, - self.fake_cluster, lrouter['uuid'], - '10.0.0.2', '10.0.0.2', order=200, - match_criteria={'foo': 'bar'}) - - def _test_create_router_nosnat_rule(self, version, expected=1): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - with mock.patch.object(self.fake_cluster.api_client, - 'get_version', - new=lambda: version_module.Version(version)): - routerlib.create_lrouter_nosnat_rule( - self.fake_cluster, lrouter['uuid'], - order=100, - match_criteria={'destination_ip_addresses': '192.168.0.0/24'}) - rules = routerlib.query_nat_rules( - self.fake_cluster, lrouter['uuid']) - # NoSNAT rules do not exist in V2 - self.assertEqual(len(rules), expected) - - def test_create_router_nosnat_rule_v2(self): - self._test_create_router_nosnat_rule('2.0', expected=0) - - def test_create_router_nosnat_rule_v3(self): - self._test_create_router_nosnat_rule('3.0') - - def _prepare_nat_rules_for_delete_tests(self): - lrouter = routerlib.create_lrouter(self.fake_cluster, - uuidutils.generate_uuid(), - 'pippo', - 'fake-lrouter', - '10.0.0.1') - # v2 or v3 makes no difference for this test - with mock.patch.object(self.fake_cluster.api_client, - 'get_version', - new=lambda: version_module.Version('2.0')): - routerlib.create_lrouter_snat_rule( - self.fake_cluster, lrouter['uuid'], - '10.0.0.2', '10.0.0.2', order=220, - match_criteria={'source_ip_addresses': '192.168.0.0/24'}) - routerlib.create_lrouter_snat_rule( - self.fake_cluster, lrouter['uuid'], - '10.0.0.3', '10.0.0.3', order=200, - match_criteria={'source_ip_addresses': '192.168.0.2/32'}) - routerlib.create_lrouter_dnat_rule( - self.fake_cluster, lrouter['uuid'], '192.168.0.2', order=200, - match_criteria={'destination_ip_addresses': '10.0.0.3'}) - return lrouter - - def test_delete_router_nat_rules_by_match_on_destination_ip(self): - lrouter = self._prepare_nat_rules_for_delete_tests() - rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 3) - routerlib.delete_nat_rules_by_match( - self.fake_cluster, lrouter['uuid'], 'DestinationNatRule', 1, 1, - destination_ip_addresses='10.0.0.3') - rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 2) - - def test_delete_router_nat_rules_by_match_on_source_ip(self): - lrouter = self._prepare_nat_rules_for_delete_tests() - rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 3) - routerlib.delete_nat_rules_by_match( - self.fake_cluster, lrouter['uuid'], 'SourceNatRule', 1, 1, - source_ip_addresses='192.168.0.2/32') - rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 2) - - def test_delete_router_nat_rules_by_match_no_match_expected(self): - lrouter = self._prepare_nat_rules_for_delete_tests() - rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 3) - routerlib.delete_nat_rules_by_match( - self.fake_cluster, lrouter['uuid'], 'SomeWeirdType', 0) - rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 3) - routerlib.delete_nat_rules_by_match( - self.fake_cluster, lrouter['uuid'], 'DestinationNatRule', 0, - destination_ip_addresses='99.99.99.99') - rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 3) - - def test_delete_router_nat_rules_by_match_no_match_raises(self): - lrouter = self._prepare_nat_rules_for_delete_tests() - rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid']) - self.assertEqual(len(rules), 3) - self.assertRaises( - nsx_exc.NatRuleMismatch, - routerlib.delete_nat_rules_by_match, - self.fake_cluster, lrouter['uuid'], - 'SomeWeirdType', 1, 1) diff --git a/neutron/tests/unit/vmware/nsxlib/test_secgroup.py b/neutron/tests/unit/vmware/nsxlib/test_secgroup.py deleted file mode 100644 index fb2574ff4..000000000 --- a/neutron/tests/unit/vmware/nsxlib/test_secgroup.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# 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. -# - -from neutron.common import exceptions -from neutron.plugins.vmware import nsxlib -from neutron.plugins.vmware.nsxlib import secgroup as secgrouplib -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit.vmware.nsxlib import base - -_uuid = test_api_v2._uuid - - -class SecurityProfileTestCase(base.NsxlibTestCase): - - def test_create_and_get_security_profile(self): - sec_prof = secgrouplib.create_security_profile( - self.fake_cluster, _uuid(), 'pippo', {'name': 'test'}) - sec_prof_res = nsxlib.do_request( - secgrouplib.HTTP_GET, - nsxlib._build_uri_path('security-profile', - resource_id=sec_prof['uuid']), - cluster=self.fake_cluster) - self.assertEqual(sec_prof['uuid'], sec_prof_res['uuid']) - # Check for builtin rules - self.assertEqual(len(sec_prof_res['logical_port_egress_rules']), 1) - self.assertEqual(len(sec_prof_res['logical_port_ingress_rules']), 2) - - def test_create_and_get_default_security_profile(self): - sec_prof = secgrouplib.create_security_profile( - self.fake_cluster, _uuid(), 'pippo', {'name': 'default'}) - sec_prof_res = nsxlib.do_request( - secgrouplib.HTTP_GET, - nsxlib._build_uri_path('security-profile', - resource_id=sec_prof['uuid']), - cluster=self.fake_cluster) - self.assertEqual(sec_prof['uuid'], sec_prof_res['uuid']) - # Check for builtin rules - self.assertEqual(len(sec_prof_res['logical_port_egress_rules']), 3) - self.assertEqual(len(sec_prof_res['logical_port_ingress_rules']), 2) - - def test_update_security_profile_raise_not_found(self): - self.assertRaises(exceptions.NotFound, - secgrouplib.update_security_profile, - self.fake_cluster, - _uuid(), 'tatore_magno(the great)') - - def test_update_security_profile(self): - tenant_id = 'foo_tenant_uuid' - secgroup_id = 'foo_secgroup_uuid' - old_sec_prof = secgrouplib.create_security_profile( - self.fake_cluster, tenant_id, secgroup_id, - {'name': 'tatore_magno'}) - new_sec_prof = secgrouplib.update_security_profile( - self.fake_cluster, old_sec_prof['uuid'], 'aaron_magno') - self.assertEqual('aaron_magno', new_sec_prof['display_name']) - - def test_update_security_profile_rules(self): - sec_prof = secgrouplib.create_security_profile( - self.fake_cluster, _uuid(), 'pippo', {'name': 'test'}) - ingress_rule = {'ethertype': 'IPv4'} - egress_rule = {'ethertype': 'IPv4', 'profile_uuid': 'xyz'} - new_rules = {'logical_port_egress_rules': [egress_rule], - 'logical_port_ingress_rules': [ingress_rule]} - secgrouplib.update_security_group_rules( - self.fake_cluster, sec_prof['uuid'], new_rules) - sec_prof_res = nsxlib.do_request( - nsxlib.HTTP_GET, - nsxlib._build_uri_path('security-profile', - resource_id=sec_prof['uuid']), - cluster=self.fake_cluster) - self.assertEqual(sec_prof['uuid'], sec_prof_res['uuid']) - # Check for builtin rules - self.assertEqual(len(sec_prof_res['logical_port_egress_rules']), 2) - self.assertIn(egress_rule, - sec_prof_res['logical_port_egress_rules']) - self.assertEqual(len(sec_prof_res['logical_port_ingress_rules']), 1) - self.assertIn(ingress_rule, - sec_prof_res['logical_port_ingress_rules']) - - def test_update_security_profile_rules_noingress(self): - sec_prof = secgrouplib.create_security_profile( - self.fake_cluster, _uuid(), 'pippo', {'name': 'test'}) - hidden_ingress_rule = {'ethertype': 'IPv4', - 'ip_prefix': '127.0.0.1/32'} - egress_rule = {'ethertype': 'IPv4', 'profile_uuid': 'xyz'} - new_rules = {'logical_port_egress_rules': [egress_rule], - 'logical_port_ingress_rules': []} - secgrouplib.update_security_group_rules( - self.fake_cluster, sec_prof['uuid'], new_rules) - sec_prof_res = nsxlib.do_request( - nsxlib.HTTP_GET, - nsxlib._build_uri_path('security-profile', - resource_id=sec_prof['uuid']), - cluster=self.fake_cluster) - self.assertEqual(sec_prof['uuid'], sec_prof_res['uuid']) - # Check for builtin rules - self.assertEqual(len(sec_prof_res['logical_port_egress_rules']), 2) - self.assertIn(egress_rule, - sec_prof_res['logical_port_egress_rules']) - self.assertEqual(len(sec_prof_res['logical_port_ingress_rules']), 1) - self.assertIn(hidden_ingress_rule, - sec_prof_res['logical_port_ingress_rules']) - - def test_update_non_existing_securityprofile_raises(self): - self.assertRaises(exceptions.NeutronException, - secgrouplib.update_security_group_rules, - self.fake_cluster, 'whatever', - {'logical_port_egress_rules': [], - 'logical_port_ingress_rules': []}) - - def test_delete_security_profile(self): - sec_prof = secgrouplib.create_security_profile( - self.fake_cluster, _uuid(), 'pippo', {'name': 'test'}) - secgrouplib.delete_security_profile( - self.fake_cluster, sec_prof['uuid']) - self.assertRaises(exceptions.NotFound, - nsxlib.do_request, - nsxlib.HTTP_GET, - nsxlib._build_uri_path( - 'security-profile', - resource_id=sec_prof['uuid']), - cluster=self.fake_cluster) - - def test_delete_non_existing_securityprofile_raises(self): - self.assertRaises(exceptions.NeutronException, - secgrouplib.delete_security_profile, - self.fake_cluster, 'whatever') diff --git a/neutron/tests/unit/vmware/nsxlib/test_switch.py b/neutron/tests/unit/vmware/nsxlib/test_switch.py deleted file mode 100644 index db8c5af98..000000000 --- a/neutron/tests/unit/vmware/nsxlib/test_switch.py +++ /dev/null @@ -1,314 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# 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 hashlib -import mock - -from neutron.common import constants -from neutron.common import exceptions -from neutron.plugins.vmware.common import utils -from neutron.plugins.vmware.nsxlib import switch as switchlib -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit.vmware.nsxlib import base - -_uuid = test_api_v2._uuid - - -class LogicalSwitchesTestCase(base.NsxlibTestCase): - - def test_create_and_get_lswitches_single(self): - tenant_id = 'pippo' - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - lswitch = switchlib.create_lswitch(self.fake_cluster, - _uuid(), - tenant_id, - 'fake-switch', - transport_zones_config) - res_lswitch = switchlib.get_lswitches(self.fake_cluster, - lswitch['uuid']) - self.assertEqual(len(res_lswitch), 1) - self.assertEqual(res_lswitch[0]['uuid'], - lswitch['uuid']) - - def test_create_and_get_lswitches_single_name_exceeds_40_chars(self): - tenant_id = 'pippo' - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - lswitch = switchlib.create_lswitch(self.fake_cluster, - tenant_id, - _uuid(), - '*' * 50, - transport_zones_config) - res_lswitch = switchlib.get_lswitches(self.fake_cluster, - lswitch['uuid']) - self.assertEqual(len(res_lswitch), 1) - self.assertEqual(res_lswitch[0]['uuid'], lswitch['uuid']) - self.assertEqual(res_lswitch[0]['display_name'], '*' * 40) - - def test_create_and_get_lswitches_multiple(self): - tenant_id = 'pippo' - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - network_id = _uuid() - main_lswitch = switchlib.create_lswitch( - self.fake_cluster, network_id, - tenant_id, 'fake-switch', transport_zones_config, - tags=[{'scope': 'multi_lswitch', 'tag': 'True'}]) - # Create secondary lswitch - second_lswitch = switchlib.create_lswitch( - self.fake_cluster, network_id, - tenant_id, 'fake-switch-2', transport_zones_config) - res_lswitch = switchlib.get_lswitches(self.fake_cluster, - network_id) - self.assertEqual(len(res_lswitch), 2) - switch_uuids = [ls['uuid'] for ls in res_lswitch] - self.assertIn(main_lswitch['uuid'], switch_uuids) - self.assertIn(second_lswitch['uuid'], switch_uuids) - for ls in res_lswitch: - if ls['uuid'] == main_lswitch['uuid']: - main_ls = ls - else: - second_ls = ls - main_ls_tags = self._build_tag_dict(main_ls['tags']) - second_ls_tags = self._build_tag_dict(second_ls['tags']) - self.assertIn('multi_lswitch', main_ls_tags) - self.assertNotIn('multi_lswitch', second_ls_tags) - self.assertIn('quantum_net_id', main_ls_tags) - self.assertIn('quantum_net_id', second_ls_tags) - self.assertEqual(main_ls_tags['quantum_net_id'], - network_id) - self.assertEqual(second_ls_tags['quantum_net_id'], - network_id) - - def _test_update_lswitch(self, tenant_id, name, tags): - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - lswitch = switchlib.create_lswitch(self.fake_cluster, - _uuid(), - 'pippo', - 'fake-switch', - transport_zones_config) - switchlib.update_lswitch(self.fake_cluster, lswitch['uuid'], - name, tenant_id=tenant_id, tags=tags) - res_lswitch = switchlib.get_lswitches(self.fake_cluster, - lswitch['uuid']) - self.assertEqual(len(res_lswitch), 1) - self.assertEqual(res_lswitch[0]['display_name'], name) - if not tags: - # no need to validate tags - return - switch_tags = self._build_tag_dict(res_lswitch[0]['tags']) - for tag in tags: - self.assertIn(tag['scope'], switch_tags) - self.assertEqual(tag['tag'], switch_tags[tag['scope']]) - - def test_update_lswitch(self): - self._test_update_lswitch(None, 'new-name', - [{'scope': 'new_tag', 'tag': 'xxx'}]) - - def test_update_lswitch_no_tags(self): - self._test_update_lswitch(None, 'new-name', None) - - def test_update_lswitch_tenant_id(self): - self._test_update_lswitch('whatever', 'new-name', None) - - def test_update_non_existing_lswitch_raises(self): - self.assertRaises(exceptions.NetworkNotFound, - switchlib.update_lswitch, - self.fake_cluster, 'whatever', - 'foo', 'bar') - - def test_delete_networks(self): - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - lswitch = switchlib.create_lswitch(self.fake_cluster, - _uuid(), - 'pippo', - 'fake-switch', - transport_zones_config) - switchlib.delete_networks(self.fake_cluster, lswitch['uuid'], - [lswitch['uuid']]) - self.assertRaises(exceptions.NotFound, - switchlib.get_lswitches, - self.fake_cluster, - lswitch['uuid']) - - def test_delete_non_existing_lswitch_raises(self): - self.assertRaises(exceptions.NetworkNotFound, - switchlib.delete_networks, - self.fake_cluster, 'whatever', ['whatever']) - - -class LogicalPortsTestCase(base.NsxlibTestCase): - - def _create_switch_and_port(self, tenant_id='pippo', - neutron_port_id='whatever', - name='name', device_id='device_id'): - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - lswitch = switchlib.create_lswitch(self.fake_cluster, - _uuid(), tenant_id, 'fake-switch', - transport_zones_config) - lport = switchlib.create_lport(self.fake_cluster, lswitch['uuid'], - tenant_id, neutron_port_id, - name, device_id, True) - return lswitch, lport - - def test_create_and_get_port(self): - lswitch, lport = self._create_switch_and_port() - lport_res = switchlib.get_port(self.fake_cluster, - lswitch['uuid'], lport['uuid']) - self.assertEqual(lport['uuid'], lport_res['uuid']) - # Try again with relation - lport_res = switchlib.get_port(self.fake_cluster, - lswitch['uuid'], lport['uuid'], - relations='LogicalPortStatus') - self.assertEqual(lport['uuid'], lport_res['uuid']) - - def test_plug_interface(self): - lswitch, lport = self._create_switch_and_port() - switchlib.plug_vif_interface(self.fake_cluster, lswitch['uuid'], - lport['uuid'], 'VifAttachment', 'fake') - lport_res = switchlib.get_port(self.fake_cluster, - lswitch['uuid'], lport['uuid']) - self.assertEqual(lport['uuid'], lport_res['uuid']) - - def test_get_port_by_tag(self): - lswitch, lport = self._create_switch_and_port() - lport2 = switchlib.get_port_by_neutron_tag(self.fake_cluster, - lswitch['uuid'], - 'whatever') - self.assertIsNotNone(lport2) - self.assertEqual(lport['uuid'], lport2['uuid']) - - def test_get_port_by_tag_not_found_with_switch_id_raises_not_found(self): - tenant_id = 'pippo' - neutron_port_id = 'whatever' - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - lswitch = switchlib.create_lswitch( - self.fake_cluster, tenant_id, _uuid(), - 'fake-switch', transport_zones_config) - self.assertRaises(exceptions.NotFound, - switchlib.get_port_by_neutron_tag, - self.fake_cluster, lswitch['uuid'], - neutron_port_id) - - def test_get_port_by_tag_not_find_wildcard_lswitch_returns_none(self): - tenant_id = 'pippo' - neutron_port_id = 'whatever' - transport_zones_config = [{'zone_uuid': _uuid(), - 'transport_type': 'stt'}] - switchlib.create_lswitch( - self.fake_cluster, tenant_id, _uuid(), - 'fake-switch', transport_zones_config) - lport = switchlib.get_port_by_neutron_tag( - self.fake_cluster, '*', neutron_port_id) - self.assertIsNone(lport) - - def test_get_port_status(self): - lswitch, lport = self._create_switch_and_port() - status = switchlib.get_port_status( - self.fake_cluster, lswitch['uuid'], lport['uuid']) - self.assertEqual(constants.PORT_STATUS_ACTIVE, status) - - def test_get_port_status_non_existent_raises(self): - self.assertRaises(exceptions.PortNotFoundOnNetwork, - switchlib.get_port_status, - self.fake_cluster, - 'boo', 'boo') - - def test_update_port(self): - lswitch, lport = self._create_switch_and_port() - switchlib.update_port( - self.fake_cluster, lswitch['uuid'], lport['uuid'], - 'neutron_port_id', 'pippo2', 'new_name', 'device_id', False) - lport_res = switchlib.get_port(self.fake_cluster, - lswitch['uuid'], lport['uuid']) - self.assertEqual(lport['uuid'], lport_res['uuid']) - self.assertEqual('new_name', lport_res['display_name']) - self.assertEqual('False', lport_res['admin_status_enabled']) - port_tags = self._build_tag_dict(lport_res['tags']) - self.assertIn('os_tid', port_tags) - self.assertIn('q_port_id', port_tags) - self.assertIn('vm_id', port_tags) - - def test_create_port_device_id_less_than_40_chars(self): - lswitch, lport = self._create_switch_and_port() - lport_res = switchlib.get_port(self.fake_cluster, - lswitch['uuid'], lport['uuid']) - port_tags = self._build_tag_dict(lport_res['tags']) - self.assertEqual('device_id', port_tags['vm_id']) - - def test_create_port_device_id_more_than_40_chars(self): - dev_id = "this_is_a_very_long_device_id_with_lots_of_characters" - lswitch, lport = self._create_switch_and_port(device_id=dev_id) - lport_res = switchlib.get_port(self.fake_cluster, - lswitch['uuid'], lport['uuid']) - port_tags = self._build_tag_dict(lport_res['tags']) - self.assertNotEqual(len(dev_id), len(port_tags['vm_id'])) - - def test_get_ports_with_obsolete_and_new_vm_id_tag(self): - def obsolete(device_id, obfuscate=False): - return hashlib.sha1(device_id).hexdigest() - - with mock.patch.object(utils, 'device_id_to_vm_id', new=obsolete): - dev_id1 = "short-dev-id-1" - _, lport1 = self._create_switch_and_port(device_id=dev_id1) - dev_id2 = "short-dev-id-2" - _, lport2 = self._create_switch_and_port(device_id=dev_id2) - - lports = switchlib.get_ports(self.fake_cluster, None, [dev_id1]) - port_tags = self._build_tag_dict(lports['whatever']['tags']) - self.assertNotEqual(dev_id1, port_tags['vm_id']) - - lports = switchlib.get_ports(self.fake_cluster, None, [dev_id2]) - port_tags = self._build_tag_dict(lports['whatever']['tags']) - self.assertEqual(dev_id2, port_tags['vm_id']) - - def test_update_non_existent_port_raises(self): - self.assertRaises(exceptions.PortNotFoundOnNetwork, - switchlib.update_port, self.fake_cluster, - 'boo', 'boo', 'boo', 'boo', 'boo', 'boo', False) - - def test_delete_port(self): - lswitch, lport = self._create_switch_and_port() - switchlib.delete_port(self.fake_cluster, - lswitch['uuid'], lport['uuid']) - self.assertRaises(exceptions.PortNotFoundOnNetwork, - switchlib.get_port, self.fake_cluster, - lswitch['uuid'], lport['uuid']) - - def test_delete_non_existent_port_raises(self): - lswitch = self._create_switch_and_port()[0] - self.assertRaises(exceptions.PortNotFoundOnNetwork, - switchlib.delete_port, self.fake_cluster, - lswitch['uuid'], 'bad_port_uuid') - - def test_query_lswitch_ports(self): - lswitch, lport = self._create_switch_and_port() - switch_port_uuids = [ - switchlib.create_lport( - self.fake_cluster, lswitch['uuid'], 'pippo', 'qportid-%s' % k, - 'port-%s' % k, 'deviceid-%s' % k, True)['uuid'] - for k in range(2)] - switch_port_uuids.append(lport['uuid']) - ports = switchlib.query_lswitch_lports( - self.fake_cluster, lswitch['uuid']) - self.assertEqual(len(ports), 3) - for res_port in ports: - self.assertIn(res_port['uuid'], switch_port_uuids) diff --git a/neutron/tests/unit/vmware/nsxlib/test_versioning.py b/neutron/tests/unit/vmware/nsxlib/test_versioning.py deleted file mode 100644 index a50f94283..000000000 --- a/neutron/tests/unit/vmware/nsxlib/test_versioning.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# 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. -# - -from neutron.plugins.vmware.api_client import exception -from neutron.plugins.vmware.api_client import version as version_module -from neutron.plugins.vmware.nsxlib import router as routerlib -from neutron.plugins.vmware.nsxlib import versioning -from neutron.tests import base - - -class TestVersioning(base.BaseTestCase): - - def test_function_handling_missing_minor(self): - version = version_module.Version('2.0') - function = versioning.get_function_by_version( - routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version) - self.assertEqual(routerlib.create_implicit_routing_lrouter, - function) - - def test_function_handling_with_both_major_and_minor(self): - version = version_module.Version('3.2') - function = versioning.get_function_by_version( - routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version) - self.assertEqual(routerlib.create_explicit_routing_lrouter, - function) - - def test_function_handling_with_newer_major(self): - version = version_module.Version('5.2') - function = versioning.get_function_by_version( - routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version) - self.assertEqual(routerlib.create_explicit_routing_lrouter, - function) - - def test_function_handling_with_obsolete_major(self): - version = version_module.Version('1.2') - self.assertRaises(NotImplementedError, - versioning.get_function_by_version, - routerlib.ROUTER_FUNC_DICT, - 'create_lrouter', version) - - def test_function_handling_with_unknown_version(self): - self.assertRaises(exception.ServiceUnavailable, - versioning.get_function_by_version, - routerlib.ROUTER_FUNC_DICT, - 'create_lrouter', None) diff --git a/neutron/tests/unit/vmware/test_agent_scheduler.py b/neutron/tests/unit/vmware/test_agent_scheduler.py deleted file mode 100644 index 6d1193454..000000000 --- a/neutron/tests/unit/vmware/test_agent_scheduler.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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 oslo.config import cfg - -from neutron.common import constants -from neutron.common import test_lib -from neutron.plugins.vmware.common import sync -from neutron.plugins.vmware.dhcp_meta import rpc -from neutron.tests.unit.openvswitch import test_agent_scheduler as test_base -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.apiclient import fake - - -class DhcpAgentNotifierTestCase(test_base.OvsDhcpAgentNotifierTestCase): - plugin_str = vmware.PLUGIN_NAME - - def setUp(self): - test_lib.test_config['config_files'] = [ - vmware.get_fake_conf('nsx.ini.full.test')] - - # mock api client - self.fc = fake.FakeClient(vmware.STUBS_PATH) - self.mock_nsx_api = mock.patch(vmware.NSXAPI_NAME, autospec=True) - instance = self.mock_nsx_api.start() - # Avoid runs of the synchronizer looping call - patch_sync = mock.patch.object(sync, '_start_loopingcall') - patch_sync.start() - - # Emulate tests against NSX 2.x - instance.return_value.get_version.return_value = "2.999" - instance.return_value.request.side_effect = self.fc.fake_request - super(DhcpAgentNotifierTestCase, self).setUp() - self.addCleanup(self.fc.reset_all) - self.addCleanup(patch_sync.stop) - self.addCleanup(self.mock_nsx_api.stop) - - def _test_gateway_subnet_notification(self, gateway='10.0.0.1'): - cfg.CONF.set_override('metadata_mode', 'dhcp_host_route', 'NSX') - hosts = ['hosta'] - with mock.patch.object(rpc.LOG, 'info') as mock_log: - net, subnet, port = self._network_port_create( - hosts, gateway=gateway, owner=constants.DEVICE_OWNER_DHCP) - self.assertEqual(subnet['subnet']['gateway_ip'], gateway) - called = 1 if gateway is None else 0 - self.assertEqual(called, mock_log.call_count) - - def test_gatewayless_subnet_notification(self): - self._test_gateway_subnet_notification(gateway=None) - - def test_subnet_with_gateway_notification(self): - self._test_gateway_subnet_notification() diff --git a/neutron/tests/unit/vmware/test_dhcpmeta.py b/neutron/tests/unit/vmware/test_dhcpmeta.py deleted file mode 100644 index 23c4a86cf..000000000 --- a/neutron/tests/unit/vmware/test_dhcpmeta.py +++ /dev/null @@ -1,1429 +0,0 @@ -# Copyright 2013 VMware, Inc. -# -# 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 oslo.config import cfg - -from neutron.common import constants as n_consts -from neutron.common import exceptions as n_exc -from neutron import context -from neutron.db import api as db -from neutron.plugins.vmware.api_client import exception -from neutron.plugins.vmware.common import exceptions as p_exc -from neutron.plugins.vmware.dbexts import lsn_db -from neutron.plugins.vmware.dhcp_meta import constants -from neutron.plugins.vmware.dhcp_meta import lsnmanager as lsn_man -from neutron.plugins.vmware.dhcp_meta import migration as mig_man -from neutron.plugins.vmware.dhcp_meta import nsx -from neutron.plugins.vmware.dhcp_meta import rpc -from neutron.tests import base - - -class DhcpMetadataBuilderTestCase(base.BaseTestCase): - - def setUp(self): - super(DhcpMetadataBuilderTestCase, self).setUp() - self.builder = mig_man.DhcpMetadataBuilder(mock.Mock(), mock.Mock()) - self.network_id = 'foo_network_id' - self.subnet_id = 'foo_subnet_id' - self.router_id = 'foo_router_id' - - def test_dhcp_agent_get_all(self): - expected = [] - self.builder.plugin.list_dhcp_agents_hosting_network.return_value = ( - {'agents': expected}) - agents = self.builder.dhcp_agent_get_all(mock.ANY, self.network_id) - self.assertEqual(expected, agents) - - def test_dhcp_port_get_all(self): - expected = [] - self.builder.plugin.get_ports.return_value = expected - ports = self.builder.dhcp_port_get_all(mock.ANY, self.network_id) - self.assertEqual(expected, ports) - - def test_router_id_get(self): - port = { - 'device_id': self.router_id, - 'network_id': self.network_id, - 'fixed_ips': [{'subnet_id': self.subnet_id}] - } - subnet = { - 'id': self.subnet_id, - 'network_id': self.network_id - } - self.builder.plugin.get_ports.return_value = [port] - result = self.builder.router_id_get(context, subnet) - self.assertEqual(self.router_id, result) - - def test_router_id_get_none_subnet(self): - self.assertIsNone(self.builder.router_id_get(mock.ANY, None)) - - def test_router_id_get_none_no_router(self): - self.builder.plugin.get_ports.return_value = [] - subnet = {'network_id': self.network_id} - self.assertIsNone(self.builder.router_id_get(mock.ANY, subnet)) - - def test_metadata_deallocate(self): - self.builder.metadata_deallocate( - mock.ANY, self.router_id, self.subnet_id) - self.assertTrue(self.builder.plugin.remove_router_interface.call_count) - - def test_metadata_allocate(self): - self.builder.metadata_allocate( - mock.ANY, self.router_id, self.subnet_id) - self.assertTrue(self.builder.plugin.add_router_interface.call_count) - - def test_dhcp_deallocate(self): - agents = [{'id': 'foo_agent_id'}] - ports = [{'id': 'foo_port_id'}] - self.builder.dhcp_deallocate(mock.ANY, self.network_id, agents, ports) - self.assertTrue( - self.builder.plugin.remove_network_from_dhcp_agent.call_count) - self.assertTrue(self.builder.plugin.delete_port.call_count) - - def _test_dhcp_allocate(self, subnet, expected_notify_count): - with mock.patch.object(mig_man.nsx, 'handle_network_dhcp_access') as f: - self.builder.dhcp_allocate(mock.ANY, self.network_id, subnet) - self.assertTrue(f.call_count) - self.assertEqual(expected_notify_count, - self.builder.notifier.notify.call_count) - - def test_dhcp_allocate(self): - subnet = {'network_id': self.network_id, 'id': self.subnet_id} - self._test_dhcp_allocate(subnet, 2) - - def test_dhcp_allocate_none_subnet(self): - self._test_dhcp_allocate(None, 0) - - -class MigrationManagerTestCase(base.BaseTestCase): - - def setUp(self): - super(MigrationManagerTestCase, self).setUp() - self.manager = mig_man.MigrationManager(mock.Mock(), - mock.Mock(), - mock.Mock()) - self.network_id = 'foo_network_id' - self.router_id = 'foo_router_id' - self.subnet_id = 'foo_subnet_id' - self.mock_builder_p = mock.patch.object(self.manager, 'builder') - self.mock_builder = self.mock_builder_p.start() - - def _test_validate(self, lsn_exists=False, ext_net=False, subnets=None): - network = {'router:external': ext_net} - self.manager.manager.lsn_exists.return_value = lsn_exists - self.manager.plugin.get_network.return_value = network - self.manager.plugin.get_subnets.return_value = subnets - result = self.manager.validate(mock.ANY, self.network_id) - if len(subnets): - self.assertEqual(subnets[0], result) - else: - self.assertIsNone(result) - - def test_validate_no_subnets(self): - self._test_validate(subnets=[]) - - def test_validate_with_one_subnet(self): - self._test_validate(subnets=[{'cidr': '0.0.0.0/0'}]) - - def test_validate_raise_conflict_many_subnets(self): - self.assertRaises(p_exc.LsnMigrationConflict, - self._test_validate, - subnets=[{'id': 'sub1'}, {'id': 'sub2'}]) - - def test_validate_raise_conflict_lsn_exists(self): - self.assertRaises(p_exc.LsnMigrationConflict, - self._test_validate, - lsn_exists=True) - - def test_validate_raise_badrequest_external_net(self): - self.assertRaises(n_exc.BadRequest, - self._test_validate, - ext_net=True) - - def test_validate_raise_badrequest_metadata_net(self): - self.assertRaises(n_exc.BadRequest, - self._test_validate, - ext_net=False, - subnets=[{'cidr': rpc.METADATA_SUBNET_CIDR}]) - - def _test_migrate(self, router, subnet, expected_calls): - self.mock_builder.router_id_get.return_value = router - self.manager.migrate(mock.ANY, self.network_id, subnet) - # testing the exact the order of calls is important - self.assertEqual(expected_calls, self.mock_builder.mock_calls) - - def test_migrate(self): - subnet = { - 'id': self.subnet_id, - 'network_id': self.network_id - } - call_sequence = [ - mock.call.router_id_get(mock.ANY, subnet), - mock.call.metadata_deallocate( - mock.ANY, self.router_id, self.subnet_id), - mock.call.dhcp_agent_get_all(mock.ANY, self.network_id), - mock.call.dhcp_port_get_all(mock.ANY, self.network_id), - mock.call.dhcp_deallocate( - mock.ANY, self.network_id, mock.ANY, mock.ANY), - mock.call.dhcp_allocate(mock.ANY, self.network_id, subnet), - mock.call.metadata_allocate( - mock.ANY, self.router_id, self.subnet_id) - ] - self._test_migrate(self.router_id, subnet, call_sequence) - - def test_migrate_no_router_uplink(self): - subnet = { - 'id': self.subnet_id, - 'network_id': self.network_id - } - call_sequence = [ - mock.call.router_id_get(mock.ANY, subnet), - mock.call.dhcp_agent_get_all(mock.ANY, self.network_id), - mock.call.dhcp_port_get_all(mock.ANY, self.network_id), - mock.call.dhcp_deallocate( - mock.ANY, self.network_id, mock.ANY, mock.ANY), - mock.call.dhcp_allocate(mock.ANY, self.network_id, subnet), - ] - self._test_migrate(None, subnet, call_sequence) - - def test_migrate_no_subnet(self): - call_sequence = [ - mock.call.router_id_get(mock.ANY, None), - mock.call.dhcp_allocate(mock.ANY, self.network_id, None), - ] - self._test_migrate(None, None, call_sequence) - - def _test_report(self, lsn_attrs, expected): - self.manager.manager.lsn_port_get.return_value = lsn_attrs - report = self.manager.report(mock.ANY, self.network_id, self.subnet_id) - self.assertEqual(expected, report) - - def test_report_for_lsn(self): - self._test_report(('foo_lsn_id', 'foo_lsn_port_id'), - {'ports': ['foo_lsn_port_id'], - 'services': ['foo_lsn_id'], 'type': 'lsn'}) - - def test_report_for_lsn_without_lsn_port(self): - self._test_report(('foo_lsn_id', None), - {'ports': [], - 'services': ['foo_lsn_id'], 'type': 'lsn'}) - - def _test_report_for_lsn_without_subnet(self, validated_subnet): - with mock.patch.object(self.manager.plugin, 'get_subnets', - return_value=validated_subnet): - self.manager.manager.lsn_port_get.return_value = ( - ('foo_lsn_id', 'foo_lsn_port_id')) - report = self.manager.report(context, self.network_id) - expected = { - 'ports': ['foo_lsn_port_id'] if validated_subnet else [], - 'services': ['foo_lsn_id'], 'type': 'lsn' - } - self.assertEqual(expected, report) - - def test_report_for_lsn_without_subnet_subnet_found(self): - self._test_report_for_lsn_without_subnet([{'id': self.subnet_id}]) - - def test_report_for_lsn_without_subnet_subnet_not_found(self): - self.manager.manager.lsn_get.return_value = 'foo_lsn_id' - self._test_report_for_lsn_without_subnet(None) - - def test_report_for_dhcp_agent(self): - self.manager.manager.lsn_port_get.return_value = (None, None) - self.mock_builder.dhcp_agent_get_all.return_value = ( - [{'id': 'foo_agent_id'}]) - self.mock_builder.dhcp_port_get_all.return_value = ( - [{'id': 'foo_dhcp_port_id'}]) - result = self.manager.report(mock.ANY, self.network_id, self.subnet_id) - expected = { - 'ports': ['foo_dhcp_port_id'], - 'services': ['foo_agent_id'], - 'type': 'agent' - } - self.assertEqual(expected, result) - - -class LsnManagerTestCase(base.BaseTestCase): - - def setUp(self): - super(LsnManagerTestCase, self).setUp() - self.net_id = 'foo_network_id' - self.sub_id = 'foo_subnet_id' - self.port_id = 'foo_port_id' - self.lsn_id = 'foo_lsn_id' - self.mac = 'aa:bb:cc:dd:ee:ff' - self.switch_id = 'foo_switch_id' - self.lsn_port_id = 'foo_lsn_port_id' - self.tenant_id = 'foo_tenant_id' - self.manager = lsn_man.LsnManager(mock.Mock()) - self.context = context.get_admin_context() - self.mock_lsn_api_p = mock.patch.object(lsn_man, 'lsn_api') - self.mock_lsn_api = self.mock_lsn_api_p.start() - self.mock_nsx_utils_p = mock.patch.object(lsn_man, 'nsx_utils') - self.mock_nsx_utils = self.mock_nsx_utils_p.start() - nsx.register_dhcp_opts(cfg) - nsx.register_metadata_opts(cfg) - - def test_lsn_get(self): - self.mock_lsn_api.lsn_for_network_get.return_value = self.lsn_id - expected = self.manager.lsn_get(mock.ANY, self.net_id) - self.mock_lsn_api.lsn_for_network_get.assert_called_once_with( - mock.ANY, self.net_id) - self.assertEqual(expected, self.lsn_id) - - def _test_lsn_get_raise_not_found_with_exc(self, exc): - self.mock_lsn_api.lsn_for_network_get.side_effect = exc - self.assertRaises(p_exc.LsnNotFound, - self.manager.lsn_get, - mock.ANY, self.net_id) - self.mock_lsn_api.lsn_for_network_get.assert_called_once_with( - mock.ANY, self.net_id) - - def test_lsn_get_raise_not_found_with_not_found(self): - self._test_lsn_get_raise_not_found_with_exc(n_exc.NotFound) - - def test_lsn_get_raise_not_found_with_api_error(self): - self._test_lsn_get_raise_not_found_with_exc(exception.NsxApiException) - - def _test_lsn_get_silent_raise_with_exc(self, exc): - self.mock_lsn_api.lsn_for_network_get.side_effect = exc - expected = self.manager.lsn_get( - mock.ANY, self.net_id, raise_on_err=False) - self.mock_lsn_api.lsn_for_network_get.assert_called_once_with( - mock.ANY, self.net_id) - self.assertIsNone(expected) - - def test_lsn_get_silent_raise_with_not_found(self): - self._test_lsn_get_silent_raise_with_exc(n_exc.NotFound) - - def test_lsn_get_silent_raise_with_api_error(self): - self._test_lsn_get_silent_raise_with_exc(exception.NsxApiException) - - def test_lsn_create(self): - self.mock_lsn_api.lsn_for_network_create.return_value = self.lsn_id - self.manager.lsn_create(mock.ANY, self.net_id) - self.mock_lsn_api.lsn_for_network_create.assert_called_once_with( - mock.ANY, self.net_id) - - def test_lsn_create_raise_api_error(self): - self.mock_lsn_api.lsn_for_network_create.side_effect = ( - exception.NsxApiException) - self.assertRaises(p_exc.NsxPluginException, - self.manager.lsn_create, - mock.ANY, self.net_id) - self.mock_lsn_api.lsn_for_network_create.assert_called_once_with( - mock.ANY, self.net_id) - - def test_lsn_delete(self): - self.manager.lsn_delete(mock.ANY, self.lsn_id) - self.mock_lsn_api.lsn_delete.assert_called_once_with( - mock.ANY, self.lsn_id) - - def _test_lsn_delete_with_exc(self, exc): - self.mock_lsn_api.lsn_delete.side_effect = exc - self.manager.lsn_delete(mock.ANY, self.lsn_id) - self.mock_lsn_api.lsn_delete.assert_called_once_with( - mock.ANY, self.lsn_id) - - def test_lsn_delete_with_not_found(self): - self._test_lsn_delete_with_exc(n_exc.NotFound) - - def test_lsn_delete_api_exception(self): - self._test_lsn_delete_with_exc(exception.NsxApiException) - - def test_lsn_delete_by_network(self): - self.mock_lsn_api.lsn_for_network_get.return_value = self.lsn_id - with mock.patch.object(self.manager, 'lsn_delete') as f: - self.manager.lsn_delete_by_network(mock.ANY, self.net_id) - self.mock_lsn_api.lsn_for_network_get.assert_called_once_with( - mock.ANY, self.net_id) - f.assert_called_once_with(mock.ANY, self.lsn_id) - - def _test_lsn_delete_by_network_with_exc(self, exc): - self.mock_lsn_api.lsn_for_network_get.side_effect = exc - with mock.patch.object(lsn_man.LOG, 'warn') as l: - self.manager.lsn_delete_by_network(mock.ANY, self.net_id) - self.assertEqual(1, l.call_count) - - def test_lsn_delete_by_network_with_not_found(self): - self._test_lsn_delete_by_network_with_exc(n_exc.NotFound) - - def test_lsn_delete_by_network_with_not_api_error(self): - self._test_lsn_delete_by_network_with_exc(exception.NsxApiException) - - def test_lsn_port_get(self): - self.mock_lsn_api.lsn_port_by_subnet_get.return_value = ( - self.lsn_port_id) - with mock.patch.object( - self.manager, 'lsn_get', return_value=self.lsn_id): - expected = self.manager.lsn_port_get( - mock.ANY, self.net_id, self.sub_id) - self.assertEqual(expected, (self.lsn_id, self.lsn_port_id)) - - def test_lsn_port_get_lsn_not_found_on_raise(self): - with mock.patch.object( - self.manager, 'lsn_get', - side_effect=p_exc.LsnNotFound(entity='network', - entity_id=self.net_id)): - self.assertRaises(p_exc.LsnNotFound, - self.manager.lsn_port_get, - mock.ANY, self.net_id, self.sub_id) - - def test_lsn_port_get_lsn_not_found_silent_raise(self): - with mock.patch.object(self.manager, 'lsn_get', return_value=None): - expected = self.manager.lsn_port_get( - mock.ANY, self.net_id, self.sub_id, raise_on_err=False) - self.assertEqual(expected, (None, None)) - - def test_lsn_port_get_port_not_found_on_raise(self): - self.mock_lsn_api.lsn_port_by_subnet_get.side_effect = n_exc.NotFound - with mock.patch.object( - self.manager, 'lsn_get', return_value=self.lsn_id): - self.assertRaises(p_exc.LsnPortNotFound, - self.manager.lsn_port_get, - mock.ANY, self.net_id, self.sub_id) - - def test_lsn_port_get_port_not_found_silent_raise(self): - self.mock_lsn_api.lsn_port_by_subnet_get.side_effect = n_exc.NotFound - with mock.patch.object( - self.manager, 'lsn_get', return_value=self.lsn_id): - expected = self.manager.lsn_port_get( - mock.ANY, self.net_id, self.sub_id, raise_on_err=False) - self.assertEqual(expected, (self.lsn_id, None)) - - def test_lsn_port_create(self): - self.mock_lsn_api.lsn_port_create.return_value = self.lsn_port_id - expected = self.manager.lsn_port_create(mock.ANY, mock.ANY, mock.ANY) - self.assertEqual(expected, self.lsn_port_id) - - def _test_lsn_port_create_with_exc(self, exc, expected): - self.mock_lsn_api.lsn_port_create.side_effect = exc - self.assertRaises(expected, - self.manager.lsn_port_create, - mock.ANY, mock.ANY, mock.ANY) - - def test_lsn_port_create_with_not_found(self): - self._test_lsn_port_create_with_exc(n_exc.NotFound, p_exc.LsnNotFound) - - def test_lsn_port_create_api_exception(self): - self._test_lsn_port_create_with_exc(exception.NsxApiException, - p_exc.NsxPluginException) - - def test_lsn_port_delete(self): - self.manager.lsn_port_delete(mock.ANY, mock.ANY, mock.ANY) - self.assertEqual(1, self.mock_lsn_api.lsn_port_delete.call_count) - - def _test_lsn_port_delete_with_exc(self, exc): - self.mock_lsn_api.lsn_port_delete.side_effect = exc - with mock.patch.object(lsn_man.LOG, 'warn') as l: - self.manager.lsn_port_delete(mock.ANY, mock.ANY, mock.ANY) - self.assertEqual(1, self.mock_lsn_api.lsn_port_delete.call_count) - self.assertEqual(1, l.call_count) - - def test_lsn_port_delete_with_not_found(self): - self._test_lsn_port_delete_with_exc(n_exc.NotFound) - - def test_lsn_port_delete_api_exception(self): - self._test_lsn_port_delete_with_exc(exception.NsxApiException) - - def _test_lsn_port_dhcp_setup(self, ret_val, sub): - self.mock_nsx_utils.get_nsx_switch_ids.return_value = [self.switch_id] - self.mock_lsn_api.lsn_port_create.return_value = self.lsn_port_id - with mock.patch.object( - self.manager, 'lsn_get', return_value=self.lsn_id): - with mock.patch.object(lsn_man.switch_api, - 'get_port_by_neutron_tag'): - expected = self.manager.lsn_port_dhcp_setup( - mock.Mock(), mock.ANY, mock.ANY, - mock.ANY, subnet_config=sub) - self.assertEqual( - 1, self.mock_lsn_api.lsn_port_create.call_count) - self.assertEqual( - 1, self.mock_lsn_api.lsn_port_plug_network.call_count) - self.assertEqual(expected, ret_val) - - def test_lsn_port_dhcp_setup(self): - self._test_lsn_port_dhcp_setup((self.lsn_id, self.lsn_port_id), None) - - def test_lsn_port_dhcp_setup_with_config(self): - with mock.patch.object(self.manager, 'lsn_port_dhcp_configure') as f: - self._test_lsn_port_dhcp_setup(None, mock.ANY) - self.assertEqual(1, f.call_count) - - def test_lsn_port_dhcp_setup_with_not_found(self): - self.mock_nsx_utils.get_nsx_switch_ids.return_value = [self.switch_id] - with mock.patch.object(lsn_man.switch_api, - 'get_port_by_neutron_tag') as f: - f.side_effect = n_exc.NotFound - self.assertRaises(p_exc.PortConfigurationError, - self.manager.lsn_port_dhcp_setup, - mock.Mock(), mock.ANY, mock.ANY, mock.ANY) - - def test_lsn_port_dhcp_setup_with_conflict(self): - self.mock_lsn_api.lsn_port_plug_network.side_effect = ( - p_exc.LsnConfigurationConflict(lsn_id=self.lsn_id)) - self.mock_nsx_utils.get_nsx_switch_ids.return_value = [self.switch_id] - with mock.patch.object(lsn_man.switch_api, 'get_port_by_neutron_tag'): - with mock.patch.object(self.manager, 'lsn_port_delete') as g: - self.assertRaises(p_exc.PortConfigurationError, - self.manager.lsn_port_dhcp_setup, - mock.Mock(), mock.ANY, mock.ANY, mock.ANY) - self.assertEqual(1, g.call_count) - - def _test_lsn_port_dhcp_configure_with_subnet( - self, expected, dns=None, gw=None, routes=None): - subnet = { - 'enable_dhcp': True, - 'dns_nameservers': dns or [], - 'gateway_ip': gw, - 'host_routes': routes - } - self.manager.lsn_port_dhcp_configure(mock.ANY, self.lsn_id, - self.lsn_port_id, subnet) - self.mock_lsn_api.lsn_port_dhcp_configure.assert_called_once_with( - mock.ANY, self.lsn_id, self.lsn_port_id, subnet['enable_dhcp'], - expected) - - def test_lsn_port_dhcp_configure(self): - expected = { - 'routers': '127.0.0.1', - 'default_lease_time': cfg.CONF.NSX_DHCP.default_lease_time, - 'domain_name': cfg.CONF.NSX_DHCP.domain_name - } - self._test_lsn_port_dhcp_configure_with_subnet( - expected, dns=[], gw='127.0.0.1', routes=[]) - - def test_lsn_port_dhcp_configure_gatewayless(self): - expected = { - 'default_lease_time': cfg.CONF.NSX_DHCP.default_lease_time, - 'domain_name': cfg.CONF.NSX_DHCP.domain_name - } - self._test_lsn_port_dhcp_configure_with_subnet(expected, gw=None) - - def test_lsn_port_dhcp_configure_with_extra_dns_servers(self): - expected = { - 'default_lease_time': cfg.CONF.NSX_DHCP.default_lease_time, - 'domain_name_servers': '8.8.8.8,9.9.9.9', - 'domain_name': cfg.CONF.NSX_DHCP.domain_name - } - self._test_lsn_port_dhcp_configure_with_subnet( - expected, dns=['8.8.8.8', '9.9.9.9']) - - def test_lsn_port_dhcp_configure_with_host_routes(self): - expected = { - 'default_lease_time': cfg.CONF.NSX_DHCP.default_lease_time, - 'domain_name': cfg.CONF.NSX_DHCP.domain_name, - 'classless_static_routes': '8.8.8.8,9.9.9.9' - } - self._test_lsn_port_dhcp_configure_with_subnet( - expected, routes=['8.8.8.8', '9.9.9.9']) - - def _test_lsn_metadata_configure(self, is_enabled): - with mock.patch.object(self.manager, 'lsn_port_dispose') as f: - self.manager.plugin.get_subnet.return_value = ( - {'network_id': self.net_id}) - self.manager.lsn_metadata_configure(mock.ANY, - self.sub_id, is_enabled) - expected = { - 'metadata_server_port': 8775, - 'metadata_server_ip': '127.0.0.1', - 'metadata_proxy_shared_secret': '' - } - self.mock_lsn_api.lsn_metadata_configure.assert_called_once_with( - mock.ANY, mock.ANY, is_enabled, expected) - if is_enabled: - self.assertEqual( - 1, self.mock_lsn_api.lsn_port_by_subnet_get.call_count) - else: - self.assertEqual(1, f.call_count) - - def test_lsn_metadata_configure_enabled(self): - self._test_lsn_metadata_configure(True) - - def test_lsn_metadata_configure_disabled(self): - self._test_lsn_metadata_configure(False) - - def test_lsn_metadata_configure_not_found(self): - self.mock_lsn_api.lsn_metadata_configure.side_effect = ( - p_exc.LsnNotFound(entity='lsn', entity_id=self.lsn_id)) - self.manager.plugin.get_subnet.return_value = ( - {'network_id': self.net_id}) - self.assertRaises(p_exc.NsxPluginException, - self.manager.lsn_metadata_configure, - mock.ANY, self.sub_id, True) - - def test_lsn_port_metadata_setup(self): - subnet = { - 'cidr': '0.0.0.0/0', - 'id': self.sub_id, - 'network_id': self.net_id, - 'tenant_id': self.tenant_id - } - expected_data = { - 'subnet_id': subnet['id'], - 'ip_address': subnet['cidr'], - 'mac_address': constants.METADATA_MAC - } - self.mock_nsx_utils.get_nsx_switch_ids.return_value = [self.switch_id] - with mock.patch.object(lsn_man.switch_api, 'create_lport') as f: - with mock.patch.object(self.manager, 'lsn_port_create') as g: - f.return_value = {'uuid': self.port_id} - self.manager.lsn_port_metadata_setup( - self.context, self.lsn_id, subnet) - (self.mock_lsn_api.lsn_port_plug_network. - assert_called_once_with(mock.ANY, self.lsn_id, - mock.ANY, self.port_id)) - g.assert_called_once_with( - self.context, self.lsn_id, expected_data) - - def test_lsn_port_metadata_setup_raise_not_found(self): - subnet = { - 'cidr': '0.0.0.0/0', - 'id': self.sub_id, - 'network_id': self.net_id, - 'tenant_id': self.tenant_id - } - self.mock_nsx_utils.get_nsx_switch_ids.return_value = [self.switch_id] - with mock.patch.object(lsn_man.switch_api, 'create_lport') as f: - f.side_effect = n_exc.NotFound - self.assertRaises(p_exc.PortConfigurationError, - self.manager.lsn_port_metadata_setup, - mock.Mock(), self.lsn_id, subnet) - - def test_lsn_port_metadata_setup_raise_conflict(self): - subnet = { - 'cidr': '0.0.0.0/0', - 'id': self.sub_id, - 'network_id': self.net_id, - 'tenant_id': self.tenant_id - } - self.mock_nsx_utils.get_nsx_switch_ids.return_value = [self.switch_id] - with mock.patch.object(lsn_man.switch_api, 'create_lport') as f: - with mock.patch.object(lsn_man.switch_api, 'delete_port') as g: - f.return_value = {'uuid': self.port_id} - self.mock_lsn_api.lsn_port_plug_network.side_effect = ( - p_exc.LsnConfigurationConflict(lsn_id=self.lsn_id)) - self.assertRaises(p_exc.PortConfigurationError, - self.manager.lsn_port_metadata_setup, - mock.Mock(), self.lsn_id, subnet) - self.assertEqual(1, - self.mock_lsn_api.lsn_port_delete.call_count) - self.assertEqual(1, g.call_count) - - def _test_lsn_port_dispose_with_values(self, lsn_id, lsn_port_id, count): - with mock.patch.object(self.manager, - 'lsn_port_get_by_mac', - return_value=(lsn_id, lsn_port_id)): - self.manager.lsn_port_dispose(mock.ANY, self.net_id, self.mac) - self.assertEqual(count, - self.mock_lsn_api.lsn_port_delete.call_count) - - def test_lsn_port_dispose(self): - self._test_lsn_port_dispose_with_values( - self.lsn_id, self.lsn_port_id, 1) - - def test_lsn_port_dispose_meta_mac(self): - self.mac = constants.METADATA_MAC - with mock.patch.object(lsn_man.switch_api, - 'get_port_by_neutron_tag') as f: - with mock.patch.object(lsn_man.switch_api, 'delete_port') as g: - f.return_value = {'uuid': self.port_id} - self._test_lsn_port_dispose_with_values( - self.lsn_id, self.lsn_port_id, 1) - f.assert_called_once_with( - mock.ANY, self.net_id, constants.METADATA_PORT_ID) - g.assert_called_once_with(mock.ANY, self.net_id, self.port_id) - - def test_lsn_port_dispose_lsn_not_found(self): - self._test_lsn_port_dispose_with_values(None, None, 0) - - def test_lsn_port_dispose_lsn_port_not_found(self): - self._test_lsn_port_dispose_with_values(self.lsn_id, None, 0) - - def test_lsn_port_dispose_api_error(self): - self.mock_lsn_api.lsn_port_delete.side_effect = ( - exception.NsxApiException) - with mock.patch.object(lsn_man.LOG, 'warn') as l: - self.manager.lsn_port_dispose(mock.ANY, self.net_id, self.mac) - self.assertEqual(1, l.call_count) - - def test_lsn_port_host_conf(self): - with mock.patch.object(self.manager, - 'lsn_port_get', - return_value=(self.lsn_id, self.lsn_port_id)): - f = mock.Mock() - self.manager._lsn_port_host_conf(mock.ANY, self.net_id, - self.sub_id, mock.ANY, f) - self.assertEqual(1, f.call_count) - - def test_lsn_port_host_conf_lsn_port_not_found(self): - with mock.patch.object( - self.manager, 'lsn_port_get', return_value=(None, None)) as f: - self.manager._lsn_port_host_conf( - mock.ANY, self.net_id, self.sub_id, mock.ANY, mock.Mock()) - self.assertEqual(1, f.call_count) - - def _test_lsn_port_update(self, dhcp=None, meta=None): - self.manager.lsn_port_update( - mock.ANY, self.net_id, self.sub_id, dhcp, meta) - count = 1 if dhcp else 0 - count = count + 1 if meta else count - self.assertEqual(count, (self.mock_lsn_api. - lsn_port_host_entries_update.call_count)) - - def test_lsn_port_update(self): - self._test_lsn_port_update() - - def test_lsn_port_update_dhcp_meta(self): - self._test_lsn_port_update(mock.ANY, mock.ANY) - - def test_lsn_port_update_dhcp_and_nometa(self): - self._test_lsn_port_update(mock.ANY, None) - - def test_lsn_port_update_nodhcp_and_nmeta(self): - self._test_lsn_port_update(None, mock.ANY) - - def test_lsn_port_update_raise_error(self): - self.mock_lsn_api.lsn_port_host_entries_update.side_effect = ( - exception.NsxApiException) - self.assertRaises(p_exc.PortConfigurationError, - self.manager.lsn_port_update, - mock.ANY, mock.ANY, mock.ANY, mock.ANY) - - -class PersistentLsnManagerTestCase(base.BaseTestCase): - - def setUp(self): - super(PersistentLsnManagerTestCase, self).setUp() - self.net_id = 'foo_network_id' - self.sub_id = 'foo_subnet_id' - self.port_id = 'foo_port_id' - self.lsn_id = 'foo_lsn_id' - self.mac = 'aa:bb:cc:dd:ee:ff' - self.lsn_port_id = 'foo_lsn_port_id' - self.tenant_id = 'foo_tenant_id' - db.configure_db() - nsx.register_dhcp_opts(cfg) - nsx.register_metadata_opts(cfg) - lsn_man.register_lsn_opts(cfg) - self.manager = lsn_man.PersistentLsnManager(mock.Mock()) - self.context = context.get_admin_context() - self.mock_lsn_api_p = mock.patch.object(lsn_man, 'lsn_api') - self.mock_lsn_api = self.mock_lsn_api_p.start() - self.addCleanup(db.clear_db) - - def test_lsn_get(self): - lsn_db.lsn_add(self.context, self.net_id, self.lsn_id) - result = self.manager.lsn_get(self.context, self.net_id) - self.assertEqual(self.lsn_id, result) - - def test_lsn_get_raise_not_found(self): - self.assertRaises(p_exc.LsnNotFound, - self.manager.lsn_get, self.context, self.net_id) - - def test_lsn_get_silent_not_found(self): - result = self.manager.lsn_get( - self.context, self.net_id, raise_on_err=False) - self.assertIsNone(result) - - def test_lsn_get_sync_on_missing(self): - cfg.CONF.set_override('sync_on_missing_data', True, 'NSX_LSN') - self.manager = lsn_man.PersistentLsnManager(mock.Mock()) - with mock.patch.object(self.manager, 'lsn_save') as f: - self.manager.lsn_get(self.context, self.net_id, raise_on_err=True) - self.assertTrue(self.mock_lsn_api.lsn_for_network_get.call_count) - self.assertTrue(f.call_count) - - def test_lsn_save(self): - self.manager.lsn_save(self.context, self.net_id, self.lsn_id) - result = self.manager.lsn_get(self.context, self.net_id) - self.assertEqual(self.lsn_id, result) - - def test_lsn_create(self): - self.mock_lsn_api.lsn_for_network_create.return_value = self.lsn_id - with mock.patch.object(self.manager, 'lsn_save') as f: - result = self.manager.lsn_create(self.context, self.net_id) - self.assertTrue( - self.mock_lsn_api.lsn_for_network_create.call_count) - self.assertTrue(f.call_count) - self.assertEqual(self.lsn_id, result) - - def test_lsn_create_failure(self): - with mock.patch.object( - self.manager, 'lsn_save', - side_effect=p_exc.NsxPluginException(err_msg='')): - self.assertRaises(p_exc.NsxPluginException, - self.manager.lsn_create, - self.context, self.net_id) - self.assertTrue(self.mock_lsn_api.lsn_delete.call_count) - - def test_lsn_delete(self): - self.mock_lsn_api.lsn_for_network_create.return_value = self.lsn_id - self.manager.lsn_create(self.context, self.net_id) - self.manager.lsn_delete(self.context, self.lsn_id) - self.assertIsNone(self.manager.lsn_get( - self.context, self.net_id, raise_on_err=False)) - - def test_lsn_delete_not_existent(self): - self.manager.lsn_delete(self.context, self.lsn_id) - self.assertTrue(self.mock_lsn_api.lsn_delete.call_count) - - def test_lsn_port_get(self): - lsn_db.lsn_add(self.context, self.net_id, self.lsn_id) - lsn_db.lsn_port_add_for_lsn(self.context, self.lsn_port_id, - self.sub_id, self.mac, self.lsn_id) - res = self.manager.lsn_port_get(self.context, self.net_id, self.sub_id) - self.assertEqual((self.lsn_id, self.lsn_port_id), res) - - def test_lsn_port_get_raise_not_found(self): - self.assertRaises(p_exc.LsnPortNotFound, - self.manager.lsn_port_get, - self.context, self.net_id, self.sub_id) - - def test_lsn_port_get_silent_not_found(self): - result = self.manager.lsn_port_get( - self.context, self.net_id, self.sub_id, raise_on_err=False) - self.assertEqual((None, None), result) - - def test_lsn_port_get_sync_on_missing(self): - return - cfg.CONF.set_override('sync_on_missing_data', True, 'NSX_LSN') - self.manager = lsn_man.PersistentLsnManager(mock.Mock()) - self.mock_lsn_api.lsn_for_network_get.return_value = self.lsn_id - self.mock_lsn_api.lsn_port_by_subnet_get.return_value = ( - self.lsn_id, self.lsn_port_id) - with mock.patch.object(self.manager, 'lsn_save') as f: - with mock.patch.object(self.manager, 'lsn_port_save') as g: - self.manager.lsn_port_get( - self.context, self.net_id, self.sub_id) - self.assertTrue( - self.mock_lsn_api.lsn_port_by_subnet_get.call_count) - self.assertTrue( - self.mock_lsn_api.lsn_port_info_get.call_count) - self.assertTrue(f.call_count) - self.assertTrue(g.call_count) - - def test_lsn_port_get_by_mac(self): - lsn_db.lsn_add(self.context, self.net_id, self.lsn_id) - lsn_db.lsn_port_add_for_lsn(self.context, self.lsn_port_id, - self.sub_id, self.mac, self.lsn_id) - res = self.manager.lsn_port_get_by_mac( - self.context, self.net_id, self.mac) - self.assertEqual((self.lsn_id, self.lsn_port_id), res) - - def test_lsn_port_get_by_mac_raise_not_found(self): - self.assertRaises(p_exc.LsnPortNotFound, - self.manager.lsn_port_get_by_mac, - self.context, self.net_id, self.sub_id) - - def test_lsn_port_get_by_mac_silent_not_found(self): - result = self.manager.lsn_port_get_by_mac( - self.context, self.net_id, self.sub_id, raise_on_err=False) - self.assertEqual((None, None), result) - - def test_lsn_port_create(self): - lsn_db.lsn_add(self.context, self.net_id, self.lsn_id) - self.mock_lsn_api.lsn_port_create.return_value = self.lsn_port_id - subnet = {'subnet_id': self.sub_id, 'mac_address': self.mac} - with mock.patch.object(self.manager, 'lsn_port_save') as f: - result = self.manager.lsn_port_create( - self.context, self.net_id, subnet) - self.assertTrue( - self.mock_lsn_api.lsn_port_create.call_count) - self.assertTrue(f.call_count) - self.assertEqual(self.lsn_port_id, result) - - def test_lsn_port_create_failure(self): - subnet = {'subnet_id': self.sub_id, 'mac_address': self.mac} - with mock.patch.object( - self.manager, 'lsn_port_save', - side_effect=p_exc.NsxPluginException(err_msg='')): - self.assertRaises(p_exc.NsxPluginException, - self.manager.lsn_port_create, - self.context, self.net_id, subnet) - self.assertTrue(self.mock_lsn_api.lsn_port_delete.call_count) - - def test_lsn_port_delete(self): - lsn_db.lsn_add(self.context, self.net_id, self.lsn_id) - lsn_db.lsn_port_add_for_lsn(self.context, self.lsn_port_id, - self.sub_id, self.mac, self.lsn_id) - self.manager.lsn_port_delete( - self.context, self.lsn_id, self.lsn_port_id) - self.assertEqual((None, None), self.manager.lsn_port_get( - self.context, self.lsn_id, self.sub_id, raise_on_err=False)) - - def test_lsn_port_delete_not_existent(self): - self.manager.lsn_port_delete( - self.context, self.lsn_id, self.lsn_port_id) - self.assertTrue(self.mock_lsn_api.lsn_port_delete.call_count) - - def test_lsn_port_save(self): - self.manager.lsn_save(self.context, self.net_id, self.lsn_id) - self.manager.lsn_port_save(self.context, self.lsn_port_id, - self.sub_id, self.mac, self.lsn_id) - result = self.manager.lsn_port_get( - self.context, self.net_id, self.sub_id, raise_on_err=False) - self.assertEqual((self.lsn_id, self.lsn_port_id), result) - - -class DhcpAgentNotifyAPITestCase(base.BaseTestCase): - - def setUp(self): - super(DhcpAgentNotifyAPITestCase, self).setUp() - self.notifier = nsx.DhcpAgentNotifyAPI(mock.Mock(), mock.Mock()) - self.plugin = self.notifier.plugin - self.lsn_manager = self.notifier.lsn_manager - - def _test_notify_port_update( - self, ports, expected_count, expected_args=None): - port = { - 'id': 'foo_port_id', - 'network_id': 'foo_network_id', - 'fixed_ips': [{'subnet_id': 'foo_subnet_id'}] - } - self.notifier.plugin.get_ports.return_value = ports - self.notifier.notify(mock.ANY, {'port': port}, 'port.update.end') - self.lsn_manager.lsn_port_update.assert_has_calls(expected_args) - - def test_notify_ports_update_no_ports(self): - self._test_notify_port_update(None, 0, []) - self._test_notify_port_update([], 0, []) - - def test_notify_ports_update_one_port(self): - ports = [{ - 'fixed_ips': [{'subnet_id': 'foo_subnet_id', - 'ip_address': '1.2.3.4'}], - 'device_id': 'foo_device_id', - 'device_owner': 'foo_device_owner', - 'mac_address': 'fa:16:3e:da:1d:46' - }] - call_args = mock.call( - mock.ANY, 'foo_network_id', 'foo_subnet_id', - dhcp=[{'ip_address': '1.2.3.4', - 'mac_address': 'fa:16:3e:da:1d:46'}], - meta=[{'instance_id': 'foo_device_id', - 'ip_address': '1.2.3.4'}]) - self._test_notify_port_update(ports, 1, call_args) - - def test_notify_ports_update_ports_with_empty_device_id(self): - ports = [{ - 'fixed_ips': [{'subnet_id': 'foo_subnet_id', - 'ip_address': '1.2.3.4'}], - 'device_id': '', - 'device_owner': 'foo_device_owner', - 'mac_address': 'fa:16:3e:da:1d:46' - }] - call_args = mock.call( - mock.ANY, 'foo_network_id', 'foo_subnet_id', - dhcp=[{'ip_address': '1.2.3.4', - 'mac_address': 'fa:16:3e:da:1d:46'}], - meta=[] - ) - self._test_notify_port_update(ports, 1, call_args) - - def test_notify_ports_update_ports_with_no_fixed_ips(self): - ports = [{ - 'fixed_ips': [], - 'device_id': 'foo_device_id', - 'device_owner': 'foo_device_owner', - 'mac_address': 'fa:16:3e:da:1d:46' - }] - call_args = mock.call( - mock.ANY, 'foo_network_id', 'foo_subnet_id', dhcp=[], meta=[]) - self._test_notify_port_update(ports, 1, call_args) - - def test_notify_ports_update_ports_with_no_fixed_ips_and_no_device(self): - ports = [{ - 'fixed_ips': [], - 'device_id': '', - 'device_owner': 'foo_device_owner', - 'mac_address': 'fa:16:3e:da:1d:46' - }] - call_args = mock.call( - mock.ANY, 'foo_network_id', 'foo_subnet_id', dhcp=[], meta=[]) - self._test_notify_port_update(ports, 0, call_args) - - def test_notify_ports_update_with_special_ports(self): - ports = [{'fixed_ips': [], - 'device_id': '', - 'device_owner': n_consts.DEVICE_OWNER_DHCP, - 'mac_address': 'fa:16:3e:da:1d:46'}, - {'fixed_ips': [{'subnet_id': 'foo_subnet_id', - 'ip_address': '1.2.3.4'}], - 'device_id': 'foo_device_id', - 'device_owner': n_consts.DEVICE_OWNER_ROUTER_GW, - 'mac_address': 'fa:16:3e:da:1d:46'}] - call_args = mock.call( - mock.ANY, 'foo_network_id', 'foo_subnet_id', dhcp=[], meta=[]) - self._test_notify_port_update(ports, 0, call_args) - - def test_notify_ports_update_many_ports(self): - ports = [{'fixed_ips': [], - 'device_id': '', - 'device_owner': 'foo_device_owner', - 'mac_address': 'fa:16:3e:da:1d:46'}, - {'fixed_ips': [{'subnet_id': 'foo_subnet_id', - 'ip_address': '1.2.3.4'}], - 'device_id': 'foo_device_id', - 'device_owner': 'foo_device_owner', - 'mac_address': 'fa:16:3e:da:1d:46'}] - call_args = mock.call( - mock.ANY, 'foo_network_id', 'foo_subnet_id', - dhcp=[{'ip_address': '1.2.3.4', - 'mac_address': 'fa:16:3e:da:1d:46'}], - meta=[{'instance_id': 'foo_device_id', - 'ip_address': '1.2.3.4'}]) - self._test_notify_port_update(ports, 1, call_args) - - def _test_notify_subnet_action(self, action): - with mock.patch.object(self.notifier, '_subnet_%s' % action) as f: - self.notifier._handle_subnet_dhcp_access[action] = f - subnet = {'subnet': mock.ANY} - self.notifier.notify( - mock.ANY, subnet, 'subnet.%s.end' % action) - f.assert_called_once_with(mock.ANY, subnet) - - def test_notify_subnet_create(self): - self._test_notify_subnet_action('create') - - def test_notify_subnet_update(self): - self._test_notify_subnet_action('update') - - def test_notify_subnet_delete(self): - self._test_notify_subnet_action('delete') - - def _test_subnet_create(self, enable_dhcp, exc=None, - exc_obj=None, call_notify=True): - subnet = { - 'id': 'foo_subnet_id', - 'enable_dhcp': enable_dhcp, - 'network_id': 'foo_network_id', - 'tenant_id': 'foo_tenant_id', - 'cidr': '0.0.0.0/0' - } - if exc: - self.plugin.create_port.side_effect = exc_obj or exc - self.assertRaises(exc, - self.notifier.notify, - mock.ANY, - {'subnet': subnet}, - 'subnet.create.end') - self.plugin.delete_subnet.assert_called_with( - mock.ANY, subnet['id']) - else: - if call_notify: - self.notifier.notify( - mock.ANY, {'subnet': subnet}, 'subnet.create.end') - if enable_dhcp: - dhcp_port = { - 'name': '', - 'admin_state_up': True, - 'network_id': 'foo_network_id', - 'tenant_id': 'foo_tenant_id', - 'device_owner': n_consts.DEVICE_OWNER_DHCP, - 'mac_address': mock.ANY, - 'fixed_ips': [{'subnet_id': 'foo_subnet_id'}], - 'device_id': '' - } - self.plugin.create_port.assert_called_once_with( - mock.ANY, {'port': dhcp_port}) - else: - self.assertEqual(0, self.plugin.create_port.call_count) - - def test_subnet_create_enabled_dhcp(self): - self._test_subnet_create(True) - - def test_subnet_create_disabled_dhcp(self): - self._test_subnet_create(False) - - def test_subnet_create_raise_port_config_error(self): - with mock.patch.object(nsx.db_base_plugin_v2.NeutronDbPluginV2, - 'delete_port') as d: - self._test_subnet_create( - True, - exc=n_exc.Conflict, - exc_obj=p_exc.PortConfigurationError(lsn_id='foo_lsn_id', - net_id='foo_net_id', - port_id='foo_port_id')) - d.assert_called_once_with(self.plugin, mock.ANY, 'foo_port_id') - - def test_subnet_update(self): - subnet = { - 'id': 'foo_subnet_id', - 'network_id': 'foo_network_id', - } - self.lsn_manager.lsn_port_get.return_value = ('foo_lsn_id', - 'foo_lsn_port_id') - self.notifier.notify( - mock.ANY, {'subnet': subnet}, 'subnet.update.end') - self.lsn_manager.lsn_port_dhcp_configure.assert_called_once_with( - mock.ANY, 'foo_lsn_id', 'foo_lsn_port_id', subnet) - - def test_subnet_update_raise_lsn_not_found(self): - subnet = { - 'id': 'foo_subnet_id', - 'network_id': 'foo_network_id', - } - self.lsn_manager.lsn_port_get.side_effect = ( - p_exc.LsnNotFound(entity='network', - entity_id=subnet['network_id'])) - self.assertRaises(p_exc.LsnNotFound, - self.notifier.notify, - mock.ANY, {'subnet': subnet}, 'subnet.update.end') - - def _test_subnet_update_lsn_port_not_found(self, dhcp_port): - subnet = { - 'id': 'foo_subnet_id', - 'enable_dhcp': True, - 'network_id': 'foo_network_id', - 'tenant_id': 'foo_tenant_id' - } - self.lsn_manager.lsn_port_get.side_effect = ( - p_exc.LsnPortNotFound(lsn_id='foo_lsn_id', - entity='subnet', - entity_id=subnet['id'])) - self.notifier.plugin.get_ports.return_value = dhcp_port - count = 0 if dhcp_port is None else 1 - with mock.patch.object(nsx, 'handle_port_dhcp_access') as h: - self.notifier.notify( - mock.ANY, {'subnet': subnet}, 'subnet.update.end') - self.assertEqual(count, h.call_count) - if not dhcp_port: - self._test_subnet_create(enable_dhcp=True, - exc=None, call_notify=False) - - def test_subnet_update_lsn_port_not_found_without_dhcp_port(self): - self._test_subnet_update_lsn_port_not_found(None) - - def test_subnet_update_lsn_port_not_found_with_dhcp_port(self): - self._test_subnet_update_lsn_port_not_found([mock.ANY]) - - def _test_subnet_delete(self, ports=None): - subnet = { - 'id': 'foo_subnet_id', - 'network_id': 'foo_network_id', - 'cidr': '0.0.0.0/0' - } - self.plugin.get_ports.return_value = ports - self.notifier.notify(mock.ANY, {'subnet': subnet}, 'subnet.delete.end') - filters = { - 'network_id': [subnet['network_id']], - 'device_owner': [n_consts.DEVICE_OWNER_DHCP] - } - self.plugin.get_ports.assert_called_once_with( - mock.ANY, filters=filters) - if ports: - self.plugin.delete_port.assert_called_once_with( - mock.ANY, ports[0]['id']) - else: - self.assertEqual(0, self.plugin.delete_port.call_count) - - def test_subnet_delete_enabled_dhcp_no_ports(self): - self._test_subnet_delete() - - def test_subnet_delete_enabled_dhcp_with_dhcp_port(self): - self._test_subnet_delete([{'id': 'foo_port_id'}]) - - -class DhcpTestCase(base.BaseTestCase): - - def setUp(self): - super(DhcpTestCase, self).setUp() - self.plugin = mock.Mock() - self.plugin.lsn_manager = mock.Mock() - - def test_handle_create_network(self): - network = {'id': 'foo_network_id'} - nsx.handle_network_dhcp_access( - self.plugin, mock.ANY, network, 'create_network') - self.plugin.lsn_manager.lsn_create.assert_called_once_with( - mock.ANY, network['id']) - - def test_handle_create_network_router_external(self): - network = {'id': 'foo_network_id', 'router:external': True} - nsx.handle_network_dhcp_access( - self.plugin, mock.ANY, network, 'create_network') - self.assertFalse(self.plugin.lsn_manager.lsn_create.call_count) - - def test_handle_delete_network(self): - network_id = 'foo_network_id' - self.plugin.lsn_manager.lsn_delete_by_network.return_value = ( - 'foo_lsn_id') - nsx.handle_network_dhcp_access( - self.plugin, mock.ANY, network_id, 'delete_network') - self.plugin.lsn_manager.lsn_delete_by_network.assert_called_once_with( - mock.ANY, 'foo_network_id') - - def _test_handle_create_dhcp_owner_port(self, exc=None): - subnet = { - 'cidr': '0.0.0.0/0', - 'id': 'foo_subnet_id' - } - port = { - 'id': 'foo_port_id', - 'device_owner': n_consts.DEVICE_OWNER_DHCP, - 'mac_address': 'aa:bb:cc:dd:ee:ff', - 'network_id': 'foo_network_id', - 'fixed_ips': [{'subnet_id': subnet['id']}] - } - expected_data = { - 'subnet_id': subnet['id'], - 'ip_address': subnet['cidr'], - 'mac_address': port['mac_address'] - } - self.plugin.get_subnet.return_value = subnet - if exc is None: - nsx.handle_port_dhcp_access( - self.plugin, mock.ANY, port, 'create_port') - (self.plugin.lsn_manager.lsn_port_dhcp_setup. - assert_called_once_with(mock.ANY, port['network_id'], - port['id'], expected_data, subnet)) - else: - self.plugin.lsn_manager.lsn_port_dhcp_setup.side_effect = exc - self.assertRaises(n_exc.NeutronException, - nsx.handle_port_dhcp_access, - self.plugin, mock.ANY, port, 'create_port') - - def test_handle_create_dhcp_owner_port(self): - self._test_handle_create_dhcp_owner_port() - - def test_handle_create_dhcp_owner_port_raise_port_config_error(self): - config_error = p_exc.PortConfigurationError(lsn_id='foo_lsn_id', - net_id='foo_net_id', - port_id='foo_port_id') - self._test_handle_create_dhcp_owner_port(exc=config_error) - - def test_handle_delete_dhcp_owner_port(self): - port = { - 'id': 'foo_port_id', - 'device_owner': n_consts.DEVICE_OWNER_DHCP, - 'network_id': 'foo_network_id', - 'fixed_ips': [], - 'mac_address': 'aa:bb:cc:dd:ee:ff' - } - nsx.handle_port_dhcp_access(self.plugin, mock.ANY, port, 'delete_port') - self.plugin.lsn_manager.lsn_port_dispose.assert_called_once_with( - mock.ANY, port['network_id'], port['mac_address']) - - def _test_handle_user_port(self, action, handler): - port = { - 'id': 'foo_port_id', - 'device_owner': 'foo_device_owner', - 'network_id': 'foo_network_id', - 'mac_address': 'aa:bb:cc:dd:ee:ff', - 'fixed_ips': [{'subnet_id': 'foo_subnet_id', - 'ip_address': '1.2.3.4'}] - } - expected_data = { - 'ip_address': '1.2.3.4', - 'mac_address': 'aa:bb:cc:dd:ee:ff' - } - self.plugin.get_subnet.return_value = {'enable_dhcp': True} - nsx.handle_port_dhcp_access(self.plugin, mock.ANY, port, action) - handler.assert_called_once_with( - mock.ANY, port['network_id'], 'foo_subnet_id', expected_data) - - def test_handle_create_user_port(self): - self._test_handle_user_port( - 'create_port', self.plugin.lsn_manager.lsn_port_dhcp_host_add) - - def test_handle_delete_user_port(self): - self._test_handle_user_port( - 'delete_port', self.plugin.lsn_manager.lsn_port_dhcp_host_remove) - - def _test_handle_user_port_disabled_dhcp(self, action, handler): - port = { - 'id': 'foo_port_id', - 'device_owner': 'foo_device_owner', - 'network_id': 'foo_network_id', - 'mac_address': 'aa:bb:cc:dd:ee:ff', - 'fixed_ips': [{'subnet_id': 'foo_subnet_id', - 'ip_address': '1.2.3.4'}] - } - self.plugin.get_subnet.return_value = {'enable_dhcp': False} - nsx.handle_port_dhcp_access(self.plugin, mock.ANY, port, action) - self.assertEqual(0, handler.call_count) - - def test_handle_create_user_port_disabled_dhcp(self): - self._test_handle_user_port_disabled_dhcp( - 'create_port', self.plugin.lsn_manager.lsn_port_dhcp_host_add) - - def test_handle_delete_user_port_disabled_dhcp(self): - self._test_handle_user_port_disabled_dhcp( - 'delete_port', self.plugin.lsn_manager.lsn_port_dhcp_host_remove) - - def _test_handle_user_port_no_fixed_ips(self, action, handler): - port = { - 'id': 'foo_port_id', - 'device_owner': 'foo_device_owner', - 'network_id': 'foo_network_id', - 'fixed_ips': [] - } - nsx.handle_port_dhcp_access(self.plugin, mock.ANY, port, action) - self.assertEqual(0, handler.call_count) - - def test_handle_create_user_port_no_fixed_ips(self): - self._test_handle_user_port_no_fixed_ips( - 'create_port', self.plugin.lsn_manager.lsn_port_dhcp_host_add) - - def test_handle_delete_user_port_no_fixed_ips(self): - self._test_handle_user_port_no_fixed_ips( - 'delete_port', self.plugin.lsn_manager.lsn_port_dhcp_host_remove) - - -class MetadataTestCase(base.BaseTestCase): - - def setUp(self): - super(MetadataTestCase, self).setUp() - self.plugin = mock.Mock() - self.plugin.lsn_manager = mock.Mock() - - def _test_handle_port_metadata_access_special_owners( - self, owner, dev_id='foo_device_id', ips=None): - port = { - 'id': 'foo_port_id', - 'device_owner': owner, - 'device_id': dev_id, - 'fixed_ips': ips or [] - } - nsx.handle_port_metadata_access(self.plugin, mock.ANY, port, mock.ANY) - self.assertFalse( - self.plugin.lsn_manager.lsn_port_meta_host_add.call_count) - self.assertFalse( - self.plugin.lsn_manager.lsn_port_meta_host_remove.call_count) - - def test_handle_port_metadata_access_external_network(self): - port = { - 'id': 'foo_port_id', - 'device_owner': 'foo_device_owner', - 'device_id': 'foo_device_id', - 'network_id': 'foo_network_id', - 'fixed_ips': [{'subnet_id': 'foo_subnet'}] - } - self.plugin.get_network.return_value = {'router:external': True} - nsx.handle_port_metadata_access(self.plugin, mock.ANY, port, mock.ANY) - self.assertFalse( - self.plugin.lsn_manager.lsn_port_meta_host_add.call_count) - self.assertFalse( - self.plugin.lsn_manager.lsn_port_meta_host_remove.call_count) - - def test_handle_port_metadata_access_dhcp_port(self): - self._test_handle_port_metadata_access_special_owners( - n_consts.DEVICE_OWNER_DHCP, [{'subnet_id': 'foo_subnet'}]) - - def test_handle_port_metadata_access_router_port(self): - self._test_handle_port_metadata_access_special_owners( - n_consts.DEVICE_OWNER_ROUTER_INTF, [{'subnet_id': 'foo_subnet'}]) - - def test_handle_port_metadata_access_no_device_id(self): - self._test_handle_port_metadata_access_special_owners( - n_consts.DEVICE_OWNER_DHCP, '') - - def test_handle_port_metadata_access_no_fixed_ips(self): - self._test_handle_port_metadata_access_special_owners( - 'foo', 'foo', None) - - def _test_handle_port_metadata_access(self, is_delete, raise_exc=False): - port = { - 'id': 'foo_port_id', - 'device_owner': 'foo_device_id', - 'network_id': 'foo_network_id', - 'device_id': 'foo_device_id', - 'tenant_id': 'foo_tenant_id', - 'fixed_ips': [ - {'subnet_id': 'foo_subnet_id', 'ip_address': '1.2.3.4'} - ] - } - meta = { - 'instance_id': port['device_id'], - 'tenant_id': port['tenant_id'], - 'ip_address': port['fixed_ips'][0]['ip_address'] - } - self.plugin.get_network.return_value = {'router:external': False} - if is_delete: - mock_func = self.plugin.lsn_manager.lsn_port_meta_host_remove - else: - mock_func = self.plugin.lsn_manager.lsn_port_meta_host_add - if raise_exc: - mock_func.side_effect = p_exc.PortConfigurationError( - lsn_id='foo_lsn_id', net_id='foo_net_id', port_id=None) - with mock.patch.object(nsx.db_base_plugin_v2.NeutronDbPluginV2, - 'delete_port') as d: - self.assertRaises(p_exc.PortConfigurationError, - nsx.handle_port_metadata_access, - self.plugin, mock.ANY, port, - is_delete=is_delete) - if not is_delete: - d.assert_called_once_with(mock.ANY, mock.ANY, port['id']) - else: - self.assertFalse(d.call_count) - else: - nsx.handle_port_metadata_access( - self.plugin, mock.ANY, port, is_delete=is_delete) - mock_func.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY, meta) - - def test_handle_port_metadata_access_on_delete_true(self): - self._test_handle_port_metadata_access(True) - - def test_handle_port_metadata_access_on_delete_false(self): - self._test_handle_port_metadata_access(False) - - def test_handle_port_metadata_access_on_delete_true_raise(self): - self._test_handle_port_metadata_access(True, raise_exc=True) - - def test_handle_port_metadata_access_on_delete_false_raise(self): - self._test_handle_port_metadata_access(False, raise_exc=True) - - def _test_handle_router_metadata_access( - self, is_port_found, raise_exc=False): - subnet = { - 'id': 'foo_subnet_id', - 'network_id': 'foo_network_id' - } - interface = { - 'subnet_id': subnet['id'], - 'port_id': 'foo_port_id' - } - mock_func = self.plugin.lsn_manager.lsn_metadata_configure - if not is_port_found: - self.plugin.get_port.side_effect = n_exc.NotFound - if raise_exc: - with mock.patch.object(nsx.l3_db.L3_NAT_db_mixin, - 'remove_router_interface') as d: - mock_func.side_effect = p_exc.NsxPluginException(err_msg='') - self.assertRaises(p_exc.NsxPluginException, - nsx.handle_router_metadata_access, - self.plugin, mock.ANY, 'foo_router_id', - interface) - d.assert_called_once_with(mock.ANY, mock.ANY, 'foo_router_id', - interface) - else: - nsx.handle_router_metadata_access( - self.plugin, mock.ANY, 'foo_router_id', interface) - mock_func.assert_called_once_with( - mock.ANY, subnet['id'], is_port_found) - - def test_handle_router_metadata_access_add_interface(self): - self._test_handle_router_metadata_access(True) - - def test_handle_router_metadata_access_delete_interface(self): - self._test_handle_router_metadata_access(False) - - def test_handle_router_metadata_access_raise_error_on_add(self): - self._test_handle_router_metadata_access(True, raise_exc=True) - - def test_handle_router_metadata_access_raise_error_on_delete(self): - self._test_handle_router_metadata_access(True, raise_exc=False) diff --git a/neutron/tests/unit/vmware/test_nsx_opts.py b/neutron/tests/unit/vmware/test_nsx_opts.py deleted file mode 100644 index 6bdfc3408..000000000 --- a/neutron/tests/unit/vmware/test_nsx_opts.py +++ /dev/null @@ -1,253 +0,0 @@ -# Copyright 2013 VMware, Inc. -# -# 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 fixtures - -import mock -from oslo.config import cfg - -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron.plugins.vmware.api_client import client -from neutron.plugins.vmware.api_client import version -from neutron.plugins.vmware.common import config # noqa -from neutron.plugins.vmware.common import exceptions -from neutron.plugins.vmware.common import sync -from neutron.plugins.vmware import nsx_cluster -from neutron.plugins.vmware.nsxlib import lsn as lsnlib -from neutron.tests import base -from neutron.tests.unit import vmware - -BASE_CONF_PATH = vmware.get_fake_conf('neutron.conf.test') -NSX_INI_PATH = vmware.get_fake_conf('nsx.ini.basic.test') -NSX_INI_FULL_PATH = vmware.get_fake_conf('nsx.ini.full.test') -NSX_INI_AGENTLESS_PATH = vmware.get_fake_conf('nsx.ini.agentless.test') -NSX_INI_COMBINED_PATH = vmware.get_fake_conf('nsx.ini.combined.test') -NVP_INI_DEPR_PATH = vmware.get_fake_conf('nvp.ini.full.test') - - -class NSXClusterTest(base.BaseTestCase): - - cluster_opts = {'default_tz_uuid': uuidutils.generate_uuid(), - 'default_l2_gw_service_uuid': uuidutils.generate_uuid(), - 'default_l2_gw_service_uuid': uuidutils.generate_uuid(), - 'nsx_user': 'foo', - 'nsx_password': 'bar', - 'req_timeout': 45, - 'http_timeout': 25, - 'retries': 7, - 'redirects': 23, - 'default_interface_name': 'baz', - 'nsx_controllers': ['1.1.1.1:443']} - - def test_create_cluster(self): - cluster = nsx_cluster.NSXCluster(**self.cluster_opts) - for (k, v) in self.cluster_opts.iteritems(): - self.assertEqual(v, getattr(cluster, k)) - - def test_create_cluster_default_port(self): - opts = self.cluster_opts.copy() - opts['nsx_controllers'] = ['1.1.1.1'] - cluster = nsx_cluster.NSXCluster(**opts) - for (k, v) in self.cluster_opts.iteritems(): - self.assertEqual(v, getattr(cluster, k)) - - def test_create_cluster_missing_required_attribute_raises(self): - opts = self.cluster_opts.copy() - opts.pop('default_tz_uuid') - self.assertRaises(exceptions.InvalidClusterConfiguration, - nsx_cluster.NSXCluster, **opts) - - -class ConfigurationTest(base.BaseTestCase): - - def setUp(self): - super(ConfigurationTest, self).setUp() - self.useFixture(fixtures.MonkeyPatch( - 'neutron.manager.NeutronManager._instance', - None)) - # Avoid runs of the synchronizer looping call - patch_sync = mock.patch.object(sync, '_start_loopingcall') - patch_sync.start() - - def _assert_required_options(self, cluster): - self.assertEqual(cluster.nsx_controllers, ['fake_1:443', 'fake_2:443']) - self.assertEqual(cluster.default_tz_uuid, 'fake_tz_uuid') - self.assertEqual(cluster.nsx_user, 'foo') - self.assertEqual(cluster.nsx_password, 'bar') - - def _assert_extra_options(self, cluster): - self.assertEqual(14, cluster.req_timeout) - self.assertEqual(13, cluster.http_timeout) - self.assertEqual(12, cluster.redirects) - self.assertEqual(11, cluster.retries) - self.assertEqual('whatever', cluster.default_l2_gw_service_uuid) - self.assertEqual('whatever', cluster.default_l3_gw_service_uuid) - self.assertEqual('whatever', cluster.default_interface_name) - - def test_load_plugin_with_full_options(self): - self.config_parse(args=['--config-file', BASE_CONF_PATH, - '--config-file', NSX_INI_FULL_PATH]) - cfg.CONF.set_override('core_plugin', vmware.PLUGIN_NAME) - plugin = manager.NeutronManager().get_plugin() - cluster = plugin.cluster - self._assert_required_options(cluster) - self._assert_extra_options(cluster) - - def test_load_plugin_with_required_options_only(self): - self.config_parse(args=['--config-file', BASE_CONF_PATH, - '--config-file', NSX_INI_PATH]) - cfg.CONF.set_override('core_plugin', vmware.PLUGIN_NAME) - plugin = manager.NeutronManager().get_plugin() - self._assert_required_options(plugin.cluster) - - def test_defaults(self): - self.assertEqual(5000, cfg.CONF.NSX.max_lp_per_bridged_ls) - self.assertEqual(256, cfg.CONF.NSX.max_lp_per_overlay_ls) - self.assertEqual(10, cfg.CONF.NSX.concurrent_connections) - self.assertEqual('access_network', cfg.CONF.NSX.metadata_mode) - self.assertEqual('stt', cfg.CONF.NSX.default_transport_type) - self.assertEqual('service', cfg.CONF.NSX.replication_mode) - - self.assertIsNone(cfg.CONF.default_tz_uuid) - self.assertEqual('admin', cfg.CONF.nsx_user) - self.assertEqual('admin', cfg.CONF.nsx_password) - self.assertEqual(30, cfg.CONF.req_timeout) - self.assertEqual(30, cfg.CONF.http_timeout) - self.assertEqual(2, cfg.CONF.retries) - self.assertEqual(2, cfg.CONF.redirects) - self.assertIsNone(cfg.CONF.nsx_controllers) - self.assertIsNone(cfg.CONF.default_l3_gw_service_uuid) - self.assertIsNone(cfg.CONF.default_l2_gw_service_uuid) - self.assertEqual('breth0', cfg.CONF.default_interface_name) - - def test_load_api_extensions(self): - self.config_parse(args=['--config-file', BASE_CONF_PATH, - '--config-file', NSX_INI_FULL_PATH]) - cfg.CONF.set_override('core_plugin', vmware.PLUGIN_NAME) - # Load the configuration, and initialize the plugin - manager.NeutronManager().get_plugin() - self.assertIn('extensions', cfg.CONF.api_extensions_path) - - def test_agentless_extensions(self): - self.config_parse(args=['--config-file', BASE_CONF_PATH, - '--config-file', NSX_INI_AGENTLESS_PATH]) - cfg.CONF.set_override('core_plugin', vmware.PLUGIN_NAME) - self.assertEqual(config.AgentModes.AGENTLESS, - cfg.CONF.NSX.agent_mode) - # The version returned from NSX does not really matter here - with mock.patch.object(client.NsxApiClient, - 'get_version', - return_value=version.Version("9.9")): - with mock.patch.object(lsnlib, - 'service_cluster_exists', - return_value=True): - plugin = manager.NeutronManager().get_plugin() - self.assertNotIn('agent', - plugin.supported_extension_aliases) - self.assertNotIn('dhcp_agent_scheduler', - plugin.supported_extension_aliases) - self.assertNotIn('lsn', - plugin.supported_extension_aliases) - - def test_agentless_extensions_version_fail(self): - self.config_parse(args=['--config-file', BASE_CONF_PATH, - '--config-file', NSX_INI_AGENTLESS_PATH]) - cfg.CONF.set_override('core_plugin', vmware.PLUGIN_NAME) - self.assertEqual(config.AgentModes.AGENTLESS, - cfg.CONF.NSX.agent_mode) - with mock.patch.object(client.NsxApiClient, - 'get_version', - return_value=version.Version("3.2")): - self.assertRaises(exceptions.NsxPluginException, - manager.NeutronManager) - - def test_agentless_extensions_unmet_deps_fail(self): - self.config_parse(args=['--config-file', BASE_CONF_PATH, - '--config-file', NSX_INI_AGENTLESS_PATH]) - cfg.CONF.set_override('core_plugin', vmware.PLUGIN_NAME) - self.assertEqual(config.AgentModes.AGENTLESS, - cfg.CONF.NSX.agent_mode) - with mock.patch.object(client.NsxApiClient, - 'get_version', - return_value=version.Version("3.2")): - with mock.patch.object(lsnlib, - 'service_cluster_exists', - return_value=False): - self.assertRaises(exceptions.NsxPluginException, - manager.NeutronManager) - - def test_agent_extensions(self): - self.config_parse(args=['--config-file', BASE_CONF_PATH, - '--config-file', NSX_INI_FULL_PATH]) - cfg.CONF.set_override('core_plugin', vmware.PLUGIN_NAME) - self.assertEqual(config.AgentModes.AGENT, - cfg.CONF.NSX.agent_mode) - plugin = manager.NeutronManager().get_plugin() - self.assertIn('agent', - plugin.supported_extension_aliases) - self.assertIn('dhcp_agent_scheduler', - plugin.supported_extension_aliases) - - def test_combined_extensions(self): - self.config_parse(args=['--config-file', BASE_CONF_PATH, - '--config-file', NSX_INI_COMBINED_PATH]) - cfg.CONF.set_override('core_plugin', vmware.PLUGIN_NAME) - self.assertEqual(config.AgentModes.COMBINED, - cfg.CONF.NSX.agent_mode) - with mock.patch.object(client.NsxApiClient, - 'get_version', - return_value=version.Version("4.2")): - with mock.patch.object(lsnlib, - 'service_cluster_exists', - return_value=True): - plugin = manager.NeutronManager().get_plugin() - self.assertIn('agent', - plugin.supported_extension_aliases) - self.assertIn('dhcp_agent_scheduler', - plugin.supported_extension_aliases) - self.assertIn('lsn', - plugin.supported_extension_aliases) - - -class OldNVPConfigurationTest(base.BaseTestCase): - - def setUp(self): - super(OldNVPConfigurationTest, self).setUp() - self.useFixture(fixtures.MonkeyPatch( - 'neutron.manager.NeutronManager._instance', - None)) - # Avoid runs of the synchronizer looping call - patch_sync = mock.patch.object(sync, '_start_loopingcall') - patch_sync.start() - - def _assert_required_options(self, cluster): - self.assertEqual(cluster.nsx_controllers, ['fake_1:443', 'fake_2:443']) - self.assertEqual(cluster.nsx_user, 'foo') - self.assertEqual(cluster.nsx_password, 'bar') - self.assertEqual(cluster.default_tz_uuid, 'fake_tz_uuid') - - def test_load_plugin_with_deprecated_options(self): - self.config_parse(args=['--config-file', BASE_CONF_PATH, - '--config-file', NVP_INI_DEPR_PATH]) - cfg.CONF.set_override('core_plugin', vmware.PLUGIN_NAME) - plugin = manager.NeutronManager().get_plugin() - cluster = plugin.cluster - # Verify old nvp_* params have been fully parsed - self._assert_required_options(cluster) - self.assertEqual(4, cluster.req_timeout) - self.assertEqual(3, cluster.http_timeout) - self.assertEqual(2, cluster.retries) - self.assertEqual(2, cluster.redirects) diff --git a/neutron/tests/unit/vmware/test_nsx_plugin.py b/neutron/tests/unit/vmware/test_nsx_plugin.py deleted file mode 100644 index 4b99bd734..000000000 --- a/neutron/tests/unit/vmware/test_nsx_plugin.py +++ /dev/null @@ -1,1181 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# 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 contextlib - -import mock -import netaddr -from oslo.config import cfg -from sqlalchemy import exc as sql_exc -import webob.exc - -from neutron.api.v2 import attributes -from neutron.common import constants -from neutron.common import exceptions as ntn_exc -import neutron.common.test_lib as test_lib -from neutron import context -from neutron.extensions import external_net -from neutron.extensions import l3 -from neutron.extensions import l3_ext_gw_mode -from neutron.extensions import portbindings -from neutron.extensions import providernet as pnet -from neutron.extensions import securitygroup as secgrp -from neutron import manager -from neutron.openstack.common.db import exception as db_exc -from neutron.openstack.common import log -from neutron.openstack.common import uuidutils -from neutron.plugins.vmware.api_client import exception as api_exc -from neutron.plugins.vmware.api_client import version as version_module -from neutron.plugins.vmware.common import exceptions as nsx_exc -from neutron.plugins.vmware.common import sync -from neutron.plugins.vmware.common import utils -from neutron.plugins.vmware.dbexts import db as nsx_db -from neutron.plugins.vmware.extensions import distributedrouter as dist_router -from neutron.plugins.vmware import nsxlib -from neutron.tests.unit import _test_extension_portbindings as test_bindings -import neutron.tests.unit.test_db_plugin as test_plugin -import neutron.tests.unit.test_extension_ext_gw_mode as test_ext_gw_mode -import neutron.tests.unit.test_extension_security_group as ext_sg -import neutron.tests.unit.test_l3_plugin as test_l3_plugin -from neutron.tests.unit import testlib_api -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.apiclient import fake - -LOG = log.getLogger(__name__) - - -class NsxPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - - def _create_network(self, fmt, name, admin_state_up, - arg_list=None, providernet_args=None, **kwargs): - data = {'network': {'name': name, - 'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id}} - # Fix to allow the router:external attribute and any other - # attributes containing a colon to be passed with - # a double underscore instead - kwargs = dict((k.replace('__', ':'), v) for k, v in kwargs.items()) - if external_net.EXTERNAL in kwargs: - arg_list = (external_net.EXTERNAL, ) + (arg_list or ()) - - attrs = kwargs - if providernet_args: - attrs.update(providernet_args) - for arg in (('admin_state_up', 'tenant_id', 'shared') + - (arg_list or ())): - # Arg must be present and not empty - if arg in kwargs and kwargs[arg]: - data['network'][arg] = kwargs[arg] - network_req = self.new_create_request('networks', data, fmt) - if (kwargs.get('set_context') and 'tenant_id' in kwargs): - # create a specific auth context for this request - network_req.environ['neutron.context'] = context.Context( - '', kwargs['tenant_id']) - return network_req.get_response(self.api) - - def setUp(self, - plugin=vmware.PLUGIN_NAME, - ext_mgr=None, - service_plugins=None): - test_lib.test_config['config_files'] = [ - vmware.get_fake_conf('nsx.ini.test')] - # mock api client - self.fc = fake.FakeClient(vmware.STUBS_PATH) - self.mock_nsx = mock.patch(vmware.NSXAPI_NAME, autospec=True) - self.mock_instance = self.mock_nsx.start() - # Avoid runs of the synchronizer looping call - patch_sync = mock.patch.object(sync, '_start_loopingcall') - patch_sync.start() - - # Emulate tests against NSX 2.x - self.mock_instance.return_value.get_version.return_value = ( - version_module.Version("2.9")) - self.mock_instance.return_value.request.side_effect = ( - self.fc.fake_request) - super(NsxPluginV2TestCase, self).setUp(plugin=plugin, - ext_mgr=ext_mgr) - # Newly created port's status is always 'DOWN' till NSX wires them. - self.port_create_status = constants.PORT_STATUS_DOWN - cfg.CONF.set_override('metadata_mode', None, 'NSX') - self.addCleanup(self.fc.reset_all) - - -class TestBasicGet(test_plugin.TestBasicGet, NsxPluginV2TestCase): - pass - - -class TestV2HTTPResponse(test_plugin.TestV2HTTPResponse, NsxPluginV2TestCase): - pass - - -class TestPortsV2(NsxPluginV2TestCase, - test_plugin.TestPortsV2, - test_bindings.PortBindingsTestCase, - test_bindings.PortBindingsHostTestCaseMixin): - - VIF_TYPE = portbindings.VIF_TYPE_OVS - HAS_PORT_FILTER = True - - def test_exhaust_ports_overlay_network(self): - cfg.CONF.set_override('max_lp_per_overlay_ls', 1, group='NSX') - with self.network(name='testnet', - arg_list=(pnet.NETWORK_TYPE, - pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID)) as net: - with self.subnet(network=net) as sub: - with self.port(subnet=sub): - # creating another port should see an exception - self._create_port('json', net['network']['id'], 400) - - def test_exhaust_ports_bridged_network(self): - cfg.CONF.set_override('max_lp_per_bridged_ls', 1, group="NSX") - providernet_args = {pnet.NETWORK_TYPE: 'flat', - pnet.PHYSICAL_NETWORK: 'tzuuid'} - with self.network(name='testnet', - providernet_args=providernet_args, - arg_list=(pnet.NETWORK_TYPE, - pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID)) as net: - with self.subnet(network=net) as sub: - with self.port(subnet=sub): - with self.port(subnet=sub): - plugin = manager.NeutronManager.get_plugin() - ls = nsxlib.switch.get_lswitches(plugin.cluster, - net['network']['id']) - self.assertEqual(len(ls), 2) - - def test_update_port_delete_ip(self): - # This test case overrides the default because the nsx plugin - # implements port_security/security groups and it is not allowed - # to remove an ip address from a port unless the security group - # is first removed. - with self.subnet() as subnet: - with self.port(subnet=subnet) as port: - data = {'port': {'admin_state_up': False, - 'fixed_ips': [], - secgrp.SECURITYGROUPS: []}} - req = self.new_update_request('ports', - data, port['port']['id']) - res = self.deserialize('json', req.get_response(self.api)) - self.assertEqual(res['port']['admin_state_up'], - data['port']['admin_state_up']) - self.assertEqual(res['port']['fixed_ips'], - data['port']['fixed_ips']) - - def test_create_port_name_exceeds_40_chars(self): - name = 'this_is_a_port_whose_name_is_longer_than_40_chars' - with self.port(name=name) as port: - # Assert the neutron name is not truncated - self.assertEqual(name, port['port']['name']) - - def _verify_no_orphan_left(self, net_id): - # Verify no port exists on net - # ie: cleanup on db was successful - query_params = "network_id=%s" % net_id - self._test_list_resources('port', [], - query_params=query_params) - # Also verify no orphan port was left on nsx - # no port should be there at all - self.assertFalse(self.fc._fake_lswitch_lport_dict) - - def test_create_port_nsx_error_no_orphan_left(self): - with mock.patch.object(nsxlib.switch, 'create_lport', - side_effect=api_exc.NsxApiException): - with self.network() as net: - net_id = net['network']['id'] - self._create_port(self.fmt, net_id, - webob.exc.HTTPInternalServerError.code) - self._verify_no_orphan_left(net_id) - - def test_create_port_neutron_error_no_orphan_left(self): - with mock.patch.object(nsx_db, 'add_neutron_nsx_port_mapping', - side_effect=ntn_exc.NeutronException): - with self.network() as net: - net_id = net['network']['id'] - self._create_port(self.fmt, net_id, - webob.exc.HTTPInternalServerError.code) - self._verify_no_orphan_left(net_id) - - def test_create_port_db_error_no_orphan_left(self): - db_exception = db_exc.DBError( - inner_exception=sql_exc.IntegrityError(mock.ANY, - mock.ANY, - mock.ANY)) - with mock.patch.object(nsx_db, 'add_neutron_nsx_port_mapping', - side_effect=db_exception): - with self.network() as net: - with self.port(device_owner=constants.DEVICE_OWNER_DHCP): - self._verify_no_orphan_left(net['network']['id']) - - def test_create_port_maintenance_returns_503(self): - with self.network() as net: - with mock.patch.object(nsxlib, 'do_request', - side_effect=nsx_exc.MaintenanceInProgress): - data = {'port': {'network_id': net['network']['id'], - 'admin_state_up': False, - 'fixed_ips': [], - 'tenant_id': self._tenant_id}} - plugin = manager.NeutronManager.get_plugin() - with mock.patch.object(plugin, 'get_network', - return_value=net['network']): - port_req = self.new_create_request('ports', data, self.fmt) - res = port_req.get_response(self.api) - self.assertEqual(webob.exc.HTTPServiceUnavailable.code, - res.status_int) - - -class TestNetworksV2(test_plugin.TestNetworksV2, NsxPluginV2TestCase): - - def _test_create_bridge_network(self, vlan_id=0): - net_type = vlan_id and 'vlan' or 'flat' - name = 'bridge_net' - expected = [('subnets', []), ('name', name), ('admin_state_up', True), - ('status', 'ACTIVE'), ('shared', False), - (pnet.NETWORK_TYPE, net_type), - (pnet.PHYSICAL_NETWORK, 'tzuuid'), - (pnet.SEGMENTATION_ID, vlan_id)] - providernet_args = {pnet.NETWORK_TYPE: net_type, - pnet.PHYSICAL_NETWORK: 'tzuuid'} - if vlan_id: - providernet_args[pnet.SEGMENTATION_ID] = vlan_id - with self.network(name=name, - providernet_args=providernet_args, - arg_list=(pnet.NETWORK_TYPE, - pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID)) as net: - for k, v in expected: - self.assertEqual(net['network'][k], v) - - def test_create_bridge_network(self): - self._test_create_bridge_network() - - def test_create_bridge_vlan_network(self): - self._test_create_bridge_network(vlan_id=123) - - def test_create_bridge_vlan_network_outofrange_returns_400(self): - with testlib_api.ExpectedException( - webob.exc.HTTPClientError) as ctx_manager: - self._test_create_bridge_network(vlan_id=5000) - self.assertEqual(ctx_manager.exception.code, 400) - - def test_list_networks_filter_by_id(self): - # We add this unit test to cover some logic specific to the - # nsx plugin - with contextlib.nested(self.network(name='net1'), - self.network(name='net2')) as (net1, net2): - query_params = 'id=%s' % net1['network']['id'] - self._test_list_resources('network', [net1], - query_params=query_params) - query_params += '&id=%s' % net2['network']['id'] - self._test_list_resources('network', [net1, net2], - query_params=query_params) - - def test_delete_network_after_removing_subet(self): - gateway_ip = '10.0.0.1' - cidr = '10.0.0.0/24' - fmt = 'json' - # Create new network - res = self._create_network(fmt=fmt, name='net', - admin_state_up=True) - network = self.deserialize(fmt, res) - subnet = self._make_subnet(fmt, network, gateway_ip, - cidr, ip_version=4) - req = self.new_delete_request('subnets', subnet['subnet']['id']) - sub_del_res = req.get_response(self.api) - self.assertEqual(sub_del_res.status_int, 204) - req = self.new_delete_request('networks', network['network']['id']) - net_del_res = req.get_response(self.api) - self.assertEqual(net_del_res.status_int, 204) - - def test_list_networks_with_shared(self): - with self.network(name='net1'): - with self.network(name='net2', shared=True): - req = self.new_list_request('networks') - res = self.deserialize('json', req.get_response(self.api)) - self.assertEqual(len(res['networks']), 2) - req_2 = self.new_list_request('networks') - req_2.environ['neutron.context'] = context.Context('', - 'somebody') - res = self.deserialize('json', req_2.get_response(self.api)) - # tenant must see a single network - self.assertEqual(len(res['networks']), 1) - - def test_create_network_name_exceeds_40_chars(self): - name = 'this_is_a_network_whose_name_is_longer_than_40_chars' - with self.network(name=name) as net: - # Assert neutron name is not truncated - self.assertEqual(net['network']['name'], name) - - def test_create_network_maintenance_returns_503(self): - data = {'network': {'name': 'foo', - 'admin_state_up': True, - 'tenant_id': self._tenant_id}} - with mock.patch.object(nsxlib, 'do_request', - side_effect=nsx_exc.MaintenanceInProgress): - net_req = self.new_create_request('networks', data, self.fmt) - res = net_req.get_response(self.api) - self.assertEqual(webob.exc.HTTPServiceUnavailable.code, - res.status_int) - - def test_update_network_with_admin_false(self): - data = {'network': {'admin_state_up': False}} - with self.network() as net: - plugin = manager.NeutronManager.get_plugin() - self.assertRaises(NotImplementedError, - plugin.update_network, - context.get_admin_context(), - net['network']['id'], data) - - def test_update_network_with_name_calls_nsx(self): - with mock.patch.object( - nsxlib.switch, 'update_lswitch') as update_lswitch_mock: - # don't worry about deleting this network, do not use - # context manager - ctx = context.get_admin_context() - plugin = manager.NeutronManager.get_plugin() - net = plugin.create_network( - ctx, {'network': {'name': 'xxx', - 'admin_state_up': True, - 'shared': False, - 'port_security_enabled': True}}) - plugin.update_network(ctx, net['id'], - {'network': {'name': 'yyy'}}) - update_lswitch_mock.assert_called_once_with( - mock.ANY, mock.ANY, 'yyy') - - -class SecurityGroupsTestCase(ext_sg.SecurityGroupDBTestCase): - - def setUp(self): - test_lib.test_config['config_files'] = [ - vmware.get_fake_conf('nsx.ini.test')] - # mock nsx api client - self.fc = fake.FakeClient(vmware.STUBS_PATH) - self.mock_nsx = mock.patch(vmware.NSXAPI_NAME, autospec=True) - instance = self.mock_nsx.start() - instance.return_value.login.return_value = "the_cookie" - # Avoid runs of the synchronizer looping call - patch_sync = mock.patch.object(sync, '_start_loopingcall') - patch_sync.start() - - instance.return_value.request.side_effect = self.fc.fake_request - super(SecurityGroupsTestCase, self).setUp(vmware.PLUGIN_NAME) - - -class TestSecurityGroup(ext_sg.TestSecurityGroups, SecurityGroupsTestCase): - - def test_create_security_group_name_exceeds_40_chars(self): - name = 'this_is_a_secgroup_whose_name_is_longer_than_40_chars' - with self.security_group(name=name) as sg: - # Assert Neutron name is not truncated - self.assertEqual(sg['security_group']['name'], name) - - def test_create_security_group_rule_bad_input(self): - name = 'foo security group' - description = 'foo description' - with self.security_group(name, description) as sg: - security_group_id = sg['security_group']['id'] - protocol = 200 - min_range = 32 - max_range = 4343 - rule = self._build_security_group_rule( - security_group_id, 'ingress', protocol, - min_range, max_range) - res = self._create_security_group_rule(self.fmt, rule) - self.deserialize(self.fmt, res) - self.assertEqual(res.status_int, 400) - - -class TestL3ExtensionManager(object): - - def get_resources(self): - # Simulate extension of L3 attribute map - # First apply attribute extensions - for key in l3.RESOURCE_ATTRIBUTE_MAP.keys(): - l3.RESOURCE_ATTRIBUTE_MAP[key].update( - l3_ext_gw_mode.EXTENDED_ATTRIBUTES_2_0.get(key, {})) - l3.RESOURCE_ATTRIBUTE_MAP[key].update( - dist_router.EXTENDED_ATTRIBUTES_2_0.get(key, {})) - # Finally add l3 resources to the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - l3.RESOURCE_ATTRIBUTE_MAP) - return l3.L3.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class TestL3SecGrpExtensionManager(TestL3ExtensionManager): - """A fake extension manager for L3 and Security Group extensions. - - Includes also NSX specific L3 attributes. - """ - - def get_resources(self): - resources = super(TestL3SecGrpExtensionManager, - self).get_resources() - resources.extend(secgrp.Securitygroup.get_resources()) - return resources - - -def backup_l3_attribute_map(): - """Return a backup of the original l3 attribute map.""" - return dict((res, attrs.copy()) for - (res, attrs) in l3.RESOURCE_ATTRIBUTE_MAP.iteritems()) - - -def restore_l3_attribute_map(map_to_restore): - """Ensure changes made by fake ext mgrs are reverted.""" - l3.RESOURCE_ATTRIBUTE_MAP = map_to_restore - - -class L3NatTest(test_l3_plugin.L3BaseForIntTests, NsxPluginV2TestCase): - - def _restore_l3_attribute_map(self): - l3.RESOURCE_ATTRIBUTE_MAP = self._l3_attribute_map_bk - - def setUp(self, plugin=vmware.PLUGIN_NAME, ext_mgr=None, - service_plugins=None): - self._l3_attribute_map_bk = {} - for item in l3.RESOURCE_ATTRIBUTE_MAP: - self._l3_attribute_map_bk[item] = ( - l3.RESOURCE_ATTRIBUTE_MAP[item].copy()) - cfg.CONF.set_override('api_extensions_path', vmware.NSXEXT_PATH) - l3_attribute_map_bk = backup_l3_attribute_map() - self.addCleanup(restore_l3_attribute_map, l3_attribute_map_bk) - ext_mgr = ext_mgr or TestL3ExtensionManager() - super(L3NatTest, self).setUp( - plugin=plugin, ext_mgr=ext_mgr, service_plugins=service_plugins) - plugin_instance = manager.NeutronManager.get_plugin() - self._plugin_name = "%s.%s" % ( - plugin_instance.__module__, - plugin_instance.__class__.__name__) - self._plugin_class = plugin_instance.__class__ - - def _create_l3_ext_network(self, vlan_id=None): - name = 'l3_ext_net' - net_type = utils.NetworkTypes.L3_EXT - providernet_args = {pnet.NETWORK_TYPE: net_type, - pnet.PHYSICAL_NETWORK: 'l3_gw_uuid'} - if vlan_id: - providernet_args[pnet.SEGMENTATION_ID] = vlan_id - return self.network(name=name, - router__external=True, - providernet_args=providernet_args, - arg_list=(pnet.NETWORK_TYPE, - pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID)) - - -class TestL3NatTestCase(L3NatTest, - test_l3_plugin.L3NatDBIntTestCase, - NsxPluginV2TestCase): - - def _test_create_l3_ext_network(self, vlan_id=0): - name = 'l3_ext_net' - net_type = utils.NetworkTypes.L3_EXT - expected = [('subnets', []), ('name', name), ('admin_state_up', True), - ('status', 'ACTIVE'), ('shared', False), - (external_net.EXTERNAL, True), - (pnet.NETWORK_TYPE, net_type), - (pnet.PHYSICAL_NETWORK, 'l3_gw_uuid'), - (pnet.SEGMENTATION_ID, vlan_id)] - with self._create_l3_ext_network(vlan_id) as net: - for k, v in expected: - self.assertEqual(net['network'][k], v) - - def _nsx_validate_ext_gw(self, router_id, l3_gw_uuid, vlan_id): - """Verify data on fake NSX API client in order to validate - plugin did set them properly - """ - # First find the NSX router ID - ctx = context.get_admin_context() - nsx_router_id = nsx_db.get_nsx_router_id(ctx.session, router_id) - ports = [port for port in self.fc._fake_lrouter_lport_dict.values() - if (port['lr_uuid'] == nsx_router_id and - port['att_type'] == "L3GatewayAttachment")] - self.assertEqual(len(ports), 1) - self.assertEqual(ports[0]['attachment_gwsvc_uuid'], l3_gw_uuid) - self.assertEqual(ports[0].get('vlan_id'), vlan_id) - - def test_create_l3_ext_network_without_vlan(self): - self._test_create_l3_ext_network() - - def _test_router_create_with_gwinfo_and_l3_ext_net(self, vlan_id=None, - validate_ext_gw=True): - with self._create_l3_ext_network(vlan_id) as net: - with self.subnet(network=net) as s: - data = {'router': {'tenant_id': 'whatever'}} - data['router']['name'] = 'router1' - data['router']['external_gateway_info'] = { - 'network_id': s['subnet']['network_id']} - router_req = self.new_create_request('routers', data, - self.fmt) - try: - res = router_req.get_response(self.ext_api) - router = self.deserialize(self.fmt, res) - self.assertEqual( - s['subnet']['network_id'], - (router['router']['external_gateway_info'] - ['network_id'])) - if validate_ext_gw: - self._nsx_validate_ext_gw(router['router']['id'], - 'l3_gw_uuid', vlan_id) - finally: - self._delete('routers', router['router']['id']) - - def test_router_create_with_gwinfo_and_l3_ext_net(self): - self._test_router_create_with_gwinfo_and_l3_ext_net() - - def test_router_create_with_gwinfo_and_l3_ext_net_with_vlan(self): - self._test_router_create_with_gwinfo_and_l3_ext_net(444) - - def _test_router_create_with_distributed(self, dist_input, dist_expected, - version='3.1', return_code=201): - self.mock_instance.return_value.get_version.return_value = ( - version_module.Version(version)) - - data = {'tenant_id': 'whatever'} - data['name'] = 'router1' - data['distributed'] = dist_input - router_req = self.new_create_request( - 'routers', {'router': data}, self.fmt) - try: - res = router_req.get_response(self.ext_api) - self.assertEqual(return_code, res.status_int) - if res.status_int == 201: - router = self.deserialize(self.fmt, res) - self.assertIn('distributed', router['router']) - self.assertEqual(dist_expected, - router['router']['distributed']) - finally: - if res.status_int == 201: - self._delete('routers', router['router']['id']) - - def test_router_create_distributed_with_3_1(self): - self._test_router_create_with_distributed(True, True) - - def test_router_create_distributed_with_new_nsx_versions(self): - with mock.patch.object(nsxlib.router, 'create_explicit_route_lrouter'): - self._test_router_create_with_distributed(True, True, '3.2') - self._test_router_create_with_distributed(True, True, '4.0') - self._test_router_create_with_distributed(True, True, '4.1') - - def test_router_create_not_distributed(self): - self._test_router_create_with_distributed(False, False) - - def test_router_create_distributed_unspecified(self): - self._test_router_create_with_distributed(None, False) - - def test_router_create_distributed_returns_400(self): - self._test_router_create_with_distributed(True, None, '3.0', 400) - - def test_router_create_on_obsolete_platform(self): - - def obsolete_response(*args, **kwargs): - response = (nsxlib.router. - _create_implicit_routing_lrouter(*args, **kwargs)) - response.pop('distributed') - return response - - with mock.patch.object( - nsxlib.router, 'create_lrouter', new=obsolete_response): - self._test_router_create_with_distributed(None, False, '2.2') - - def _create_router_with_gw_info_for_test(self, subnet): - data = {'router': {'tenant_id': 'whatever', - 'name': 'router1', - 'external_gateway_info': - {'network_id': subnet['subnet']['network_id']}}} - router_req = self.new_create_request( - 'routers', data, self.fmt) - return router_req.get_response(self.ext_api) - - def test_router_create_nsx_error_returns_500(self, vlan_id=None): - with mock.patch.object(nsxlib.router, - 'create_router_lport', - side_effect=api_exc.NsxApiException): - with self._create_l3_ext_network(vlan_id) as net: - with self.subnet(network=net) as s: - res = self._create_router_with_gw_info_for_test(s) - self.assertEqual( - webob.exc.HTTPInternalServerError.code, - res.status_int) - - def test_router_add_gateway_invalid_network_returns_404(self): - # NOTE(salv-orlando): This unit test has been overriden - # as the nsx plugin support the ext_gw_mode extension - # which mandates a uuid for the external network identifier - with self.router() as r: - self._add_external_gateway_to_router( - r['router']['id'], - uuidutils.generate_uuid(), - expected_code=webob.exc.HTTPNotFound.code) - - def _verify_router_rollback(self): - # Check that nothing is left on DB - # TODO(salv-orlando): Verify whehter this is thread-safe - # w.r.t. sqllite and parallel testing - self._test_list_resources('router', []) - # Check that router is not in NSX - self.assertFalse(self.fc._fake_lrouter_dict) - - def test_router_create_with_gw_info_neutron_fail_does_rollback(self): - # Simulate get subnet error while building list of ips with prefix - with mock.patch.object(self._plugin_class, - '_build_ip_address_list', - side_effect=ntn_exc.SubnetNotFound( - subnet_id='xxx')): - with self._create_l3_ext_network() as net: - with self.subnet(network=net) as s: - res = self._create_router_with_gw_info_for_test(s) - self.assertEqual( - webob.exc.HTTPNotFound.code, - res.status_int) - self._verify_router_rollback() - - def test_router_create_with_gw_info_nsx_fail_does_rollback(self): - # Simulate error while fetching nsx router gw port - with mock.patch.object(self._plugin_class, - '_find_router_gw_port', - side_effect=api_exc.NsxApiException): - with self._create_l3_ext_network() as net: - with self.subnet(network=net) as s: - res = self._create_router_with_gw_info_for_test(s) - self.assertEqual( - webob.exc.HTTPInternalServerError.code, - res.status_int) - self._verify_router_rollback() - - def _test_router_update_gateway_on_l3_ext_net(self, vlan_id=None, - validate_ext_gw=True): - with self.router() as r: - with self.subnet() as s1: - with self._create_l3_ext_network(vlan_id) as net: - with self.subnet(network=net) as s2: - self._set_net_external(s1['subnet']['network_id']) - try: - self._add_external_gateway_to_router( - r['router']['id'], - s1['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - net_id = (body['router'] - ['external_gateway_info']['network_id']) - self.assertEqual(net_id, - s1['subnet']['network_id']) - # Plug network with external mapping - self._set_net_external(s2['subnet']['network_id']) - self._add_external_gateway_to_router( - r['router']['id'], - s2['subnet']['network_id']) - body = self._show('routers', r['router']['id']) - net_id = (body['router'] - ['external_gateway_info']['network_id']) - self.assertEqual(net_id, - s2['subnet']['network_id']) - if validate_ext_gw: - self._nsx_validate_ext_gw( - body['router']['id'], - 'l3_gw_uuid', vlan_id) - finally: - # Cleanup - self._remove_external_gateway_from_router( - r['router']['id'], - s2['subnet']['network_id']) - - def test_router_update_gateway_on_l3_ext_net(self): - self._test_router_update_gateway_on_l3_ext_net() - - def test_router_update_gateway_on_l3_ext_net_with_vlan(self): - self._test_router_update_gateway_on_l3_ext_net(444) - - def test_router_list_by_tenant_id(self): - with contextlib.nested(self.router(tenant_id='custom'), - self.router(), - self.router() - ) as routers: - self._test_list_resources('router', [routers[0]], - query_params="tenant_id=custom") - - def test_create_l3_ext_network_with_vlan(self): - self._test_create_l3_ext_network(666) - - def test_floatingip_with_assoc_fails(self): - self._test_floatingip_with_assoc_fails(self._plugin_name) - - def test_floatingip_with_invalid_create_port(self): - self._test_floatingip_with_invalid_create_port(self._plugin_name) - - def _metadata_setup(self): - cfg.CONF.set_override('metadata_mode', 'access_network', 'NSX') - - def _metadata_teardown(self): - cfg.CONF.set_override('metadata_mode', None, 'NSX') - - def test_create_router_name_exceeds_40_chars(self): - name = 'this_is_a_router_whose_name_is_longer_than_40_chars' - with self.router(name=name) as rtr: - # Assert Neutron name is not truncated - self.assertEqual(rtr['router']['name'], name) - - def test_router_add_interface_subnet_with_metadata_access(self): - self._metadata_setup() - self.test_router_add_interface_subnet() - self._metadata_teardown() - - def test_router_add_interface_port_with_metadata_access(self): - self._metadata_setup() - self.test_router_add_interface_port() - self._metadata_teardown() - - def test_router_add_interface_dupsubnet_returns_400_with_metadata(self): - self._metadata_setup() - self.test_router_add_interface_dup_subnet1_returns_400() - self._metadata_teardown() - - def test_router_add_interface_overlapped_cidr_returns_400_with(self): - self._metadata_setup() - self.test_router_add_interface_overlapped_cidr_returns_400() - self._metadata_teardown() - - def test_router_remove_interface_inuse_returns_409_with_metadata(self): - self._metadata_setup() - self.test_router_remove_interface_inuse_returns_409() - self._metadata_teardown() - - def test_router_remove_iface_wrong_sub_returns_400_with_metadata(self): - self._metadata_setup() - self.test_router_remove_interface_wrong_subnet_returns_400() - self._metadata_teardown() - - def test_router_delete_with_metadata_access(self): - self._metadata_setup() - self.test_router_delete() - self._metadata_teardown() - - def test_router_delete_with_port_existed_returns_409_with_metadata(self): - self._metadata_setup() - self.test_router_delete_with_port_existed_returns_409() - self._metadata_teardown() - - def test_metadatata_network_created_with_router_interface_add(self): - self._metadata_setup() - with mock.patch.object(self._plugin_class, 'schedule_network') as f: - with self.router() as r: - with self.subnet() as s: - self._router_interface_action('add', - r['router']['id'], - s['subnet']['id'], - None) - r_ports = self._list('ports')['ports'] - self.assertEqual(len(r_ports), 2) - ips = [] - for port in r_ports: - ips.extend([netaddr.IPAddress(fixed_ip['ip_address']) - for fixed_ip in port['fixed_ips']]) - meta_cidr = netaddr.IPNetwork('169.254.0.0/16') - self.assertTrue(any([ip in meta_cidr for ip in ips])) - # Needed to avoid 409 - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None) - # Verify that the metadata network gets scheduled first, so that - # an active dhcp agent can pick it up - expected_meta_net = { - 'status': 'ACTIVE', - 'subnets': [], - 'name': 'meta-%s' % r['router']['id'], - 'admin_state_up': True, - 'tenant_id': '', - 'port_security_enabled': False, - 'shared': False, - 'id': mock.ANY - } - f.assert_called_once_with(mock.ANY, expected_meta_net) - self._metadata_teardown() - - def test_metadata_network_create_rollback_on_create_subnet_failure(self): - self._metadata_setup() - with self.router() as r: - with self.subnet() as s: - # Raise a NeutronException (eg: NotFound) - with mock.patch.object(self._plugin_class, - 'create_subnet', - side_effect=ntn_exc.NotFound): - self._router_interface_action( - 'add', r['router']['id'], s['subnet']['id'], None) - # Ensure metadata network was removed - nets = self._list('networks')['networks'] - self.assertEqual(len(nets), 1) - # Needed to avoid 409 - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None) - self._metadata_teardown() - - def test_metadata_network_create_rollback_on_add_rtr_iface_failure(self): - self._metadata_setup() - with self.router() as r: - with self.subnet() as s: - # Raise a NeutronException when adding metadata subnet - # to router - # save function being mocked - real_func = self._plugin_class.add_router_interface - plugin_instance = manager.NeutronManager.get_plugin() - - def side_effect(*args): - if args[-1]['subnet_id'] == s['subnet']['id']: - # do the real thing - return real_func(plugin_instance, *args) - # otherwise raise - raise api_exc.NsxApiException() - - with mock.patch.object(self._plugin_class, - 'add_router_interface', - side_effect=side_effect): - self._router_interface_action( - 'add', r['router']['id'], s['subnet']['id'], None) - # Ensure metadata network was removed - nets = self._list('networks')['networks'] - self.assertEqual(len(nets), 1) - # Needed to avoid 409 - self._router_interface_action('remove', - r['router']['id'], - s['subnet']['id'], - None) - self._metadata_teardown() - - def test_metadata_network_removed_with_router_interface_remove(self): - self._metadata_setup() - with self.router() as r: - with self.subnet() as s: - self._router_interface_action('add', r['router']['id'], - s['subnet']['id'], None) - subnets = self._list('subnets')['subnets'] - self.assertEqual(len(subnets), 2) - meta_cidr = netaddr.IPNetwork('169.254.0.0/16') - for subnet in subnets: - cidr = netaddr.IPNetwork(subnet['cidr']) - if meta_cidr == cidr or meta_cidr in cidr.supernet(16): - meta_sub_id = subnet['id'] - meta_net_id = subnet['network_id'] - ports = self._list( - 'ports', - query_params='network_id=%s' % meta_net_id)['ports'] - self.assertEqual(len(ports), 1) - meta_port_id = ports[0]['id'] - self._router_interface_action('remove', r['router']['id'], - s['subnet']['id'], None) - self._show('networks', meta_net_id, - webob.exc.HTTPNotFound.code) - self._show('ports', meta_port_id, - webob.exc.HTTPNotFound.code) - self._show('subnets', meta_sub_id, - webob.exc.HTTPNotFound.code) - self._metadata_teardown() - - def test_metadata_network_remove_rollback_on_failure(self): - self._metadata_setup() - with self.router() as r: - with self.subnet() as s: - self._router_interface_action('add', r['router']['id'], - s['subnet']['id'], None) - networks = self._list('networks')['networks'] - for network in networks: - if network['id'] != s['subnet']['network_id']: - meta_net_id = network['id'] - ports = self._list( - 'ports', - query_params='network_id=%s' % meta_net_id)['ports'] - meta_port_id = ports[0]['id'] - # Raise a NeutronException when removing - # metadata subnet from router - # save function being mocked - real_func = self._plugin_class.remove_router_interface - plugin_instance = manager.NeutronManager.get_plugin() - - def side_effect(*args): - if args[-1].get('subnet_id') == s['subnet']['id']: - # do the real thing - return real_func(plugin_instance, *args) - # otherwise raise - raise api_exc.NsxApiException() - - with mock.patch.object(self._plugin_class, - 'remove_router_interface', - side_effect=side_effect): - self._router_interface_action('remove', r['router']['id'], - s['subnet']['id'], None) - # Metadata network and subnet should still be there - self._show('networks', meta_net_id, - webob.exc.HTTPOk.code) - self._show('ports', meta_port_id, - webob.exc.HTTPOk.code) - self._metadata_teardown() - - def test_metadata_dhcp_host_route(self): - cfg.CONF.set_override('metadata_mode', 'dhcp_host_route', 'NSX') - subnets = self._list('subnets')['subnets'] - with self.subnet() as s: - with self.port(subnet=s, device_id='1234', - device_owner=constants.DEVICE_OWNER_DHCP): - subnets = self._list('subnets')['subnets'] - self.assertEqual(len(subnets), 1) - self.assertEqual(subnets[0]['host_routes'][0]['nexthop'], - '10.0.0.2') - self.assertEqual(subnets[0]['host_routes'][0]['destination'], - '169.254.169.254/32') - - subnets = self._list('subnets')['subnets'] - # Test that route is deleted after dhcp port is removed - self.assertEqual(len(subnets[0]['host_routes']), 0) - - def test_floatingip_disassociate(self): - with self.port() as p: - private_sub = {'subnet': {'id': - p['port']['fixed_ips'][0]['subnet_id']}} - with self.floatingip_no_assoc(private_sub) as fip: - port_id = p['port']['id'] - body = self._update('floatingips', fip['floatingip']['id'], - {'floatingip': {'port_id': port_id}}) - self.assertEqual(body['floatingip']['port_id'], port_id) - # Disassociate - body = self._update('floatingips', fip['floatingip']['id'], - {'floatingip': {'port_id': None}}) - body = self._show('floatingips', fip['floatingip']['id']) - self.assertIsNone(body['floatingip']['port_id']) - self.assertIsNone(body['floatingip']['fixed_ip_address']) - - def test_create_router_maintenance_returns_503(self): - with self._create_l3_ext_network() as net: - with self.subnet(network=net) as s: - with mock.patch.object( - nsxlib, - 'do_request', - side_effect=nsx_exc.MaintenanceInProgress): - data = {'router': {'tenant_id': 'whatever'}} - data['router']['name'] = 'router1' - data['router']['external_gateway_info'] = { - 'network_id': s['subnet']['network_id']} - router_req = self.new_create_request( - 'routers', data, self.fmt) - res = router_req.get_response(self.ext_api) - self.assertEqual(webob.exc.HTTPServiceUnavailable.code, - res.status_int) - - -class ExtGwModeTestCase(NsxPluginV2TestCase, - test_ext_gw_mode.ExtGwModeIntTestCase): - pass - - -class NeutronNsxOutOfSync(NsxPluginV2TestCase, - test_l3_plugin.L3NatTestCaseMixin, - ext_sg.SecurityGroupsTestCase): - - def setUp(self): - l3_attribute_map_bk = backup_l3_attribute_map() - self.addCleanup(restore_l3_attribute_map, l3_attribute_map_bk) - super(NeutronNsxOutOfSync, self).setUp( - ext_mgr=TestL3SecGrpExtensionManager()) - - def test_delete_network_not_in_nsx(self): - res = self._create_network('json', 'net1', True) - net1 = self.deserialize('json', res) - self.fc._fake_lswitch_dict.clear() - req = self.new_delete_request('networks', net1['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 204) - - def test_show_network_not_in_nsx(self): - res = self._create_network('json', 'net1', True) - net = self.deserialize('json', res) - self.fc._fake_lswitch_dict.clear() - req = self.new_show_request('networks', net['network']['id'], - fields=['id', 'status']) - net = self.deserialize('json', req.get_response(self.api)) - self.assertEqual(net['network']['status'], - constants.NET_STATUS_ERROR) - - def test_delete_port_not_in_nsx(self): - res = self._create_network('json', 'net1', True) - net1 = self.deserialize('json', res) - res = self._create_port('json', net1['network']['id']) - port = self.deserialize('json', res) - self.fc._fake_lswitch_lport_dict.clear() - req = self.new_delete_request('ports', port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 204) - - def test_show_port_not_in_nsx(self): - res = self._create_network('json', 'net1', True) - net1 = self.deserialize('json', res) - res = self._create_port('json', net1['network']['id']) - port = self.deserialize('json', res) - self.fc._fake_lswitch_lport_dict.clear() - self.fc._fake_lswitch_lportstatus_dict.clear() - req = self.new_show_request('ports', port['port']['id'], - fields=['id', 'status']) - net = self.deserialize('json', req.get_response(self.api)) - self.assertEqual(net['port']['status'], - constants.PORT_STATUS_ERROR) - - def test_create_port_on_network_not_in_nsx(self): - res = self._create_network('json', 'net1', True) - net1 = self.deserialize('json', res) - self.fc._fake_lswitch_dict.clear() - res = self._create_port('json', net1['network']['id']) - port = self.deserialize('json', res) - self.assertEqual(port['port']['status'], constants.PORT_STATUS_ERROR) - - def test_update_port_not_in_nsx(self): - res = self._create_network('json', 'net1', True) - net1 = self.deserialize('json', res) - res = self._create_port('json', net1['network']['id']) - port = self.deserialize('json', res) - self.fc._fake_lswitch_lport_dict.clear() - data = {'port': {'name': 'error_port'}} - req = self.new_update_request('ports', data, port['port']['id']) - port = self.deserialize('json', req.get_response(self.api)) - self.assertEqual(port['port']['status'], constants.PORT_STATUS_ERROR) - self.assertEqual(port['port']['name'], 'error_port') - - def test_delete_port_and_network_not_in_nsx(self): - res = self._create_network('json', 'net1', True) - net1 = self.deserialize('json', res) - res = self._create_port('json', net1['network']['id']) - port = self.deserialize('json', res) - self.fc._fake_lswitch_dict.clear() - self.fc._fake_lswitch_lport_dict.clear() - req = self.new_delete_request('ports', port['port']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 204) - req = self.new_delete_request('networks', net1['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 204) - - def test_delete_router_not_in_nsx(self): - res = self._create_router('json', 'tenant') - router = self.deserialize('json', res) - self.fc._fake_lrouter_dict.clear() - req = self.new_delete_request('routers', router['router']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - - def test_show_router_not_in_nsx(self): - res = self._create_router('json', 'tenant') - router = self.deserialize('json', res) - self.fc._fake_lrouter_dict.clear() - req = self.new_show_request('routers', router['router']['id'], - fields=['id', 'status']) - router = self.deserialize('json', req.get_response(self.ext_api)) - self.assertEqual(router['router']['status'], - constants.NET_STATUS_ERROR) - - def _create_network_and_subnet(self, cidr, external=False): - net_res = self._create_network('json', 'ext_net', True) - net = self.deserialize('json', net_res) - net_id = net['network']['id'] - if external: - self._update('networks', net_id, - {'network': {external_net.EXTERNAL: True}}) - sub_res = self._create_subnet('json', net_id, cidr) - sub = self.deserialize('json', sub_res) - return net_id, sub['subnet']['id'] - - def test_clear_gateway_nat_rule_not_in_nsx(self): - # Create external network and subnet - ext_net_id = self._create_network_and_subnet('1.1.1.0/24', True)[0] - # Create internal network and subnet - int_sub_id = self._create_network_and_subnet('10.0.0.0/24')[1] - res = self._create_router('json', 'tenant') - router = self.deserialize('json', res) - # Add interface to router (needed to generate NAT rule) - req = self.new_action_request( - 'routers', - {'subnet_id': int_sub_id}, - router['router']['id'], - "add_router_interface") - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 200) - # Set gateway for router - req = self.new_update_request( - 'routers', - {'router': {'external_gateway_info': - {'network_id': ext_net_id}}}, - router['router']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 200) - # Delete NAT rule from NSX, clear gateway - # and verify operation still succeeds - self.fc._fake_lrouter_nat_dict.clear() - req = self.new_update_request( - 'routers', - {'router': {'external_gateway_info': {}}}, - router['router']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 200) - - def test_remove_router_interface_not_in_nsx(self): - # Create internal network and subnet - int_sub_id = self._create_network_and_subnet('10.0.0.0/24')[1] - res = self._create_router('json', 'tenant') - router = self.deserialize('json', res) - # Add interface to router (needed to generate NAT rule) - req = self.new_action_request( - 'routers', - {'subnet_id': int_sub_id}, - router['router']['id'], - "add_router_interface") - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 200) - self.fc._fake_lrouter_dict.clear() - req = self.new_action_request( - 'routers', - {'subnet_id': int_sub_id}, - router['router']['id'], - "remove_router_interface") - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 200) - - def test_update_router_not_in_nsx(self): - res = self._create_router('json', 'tenant') - router = self.deserialize('json', res) - self.fc._fake_lrouter_dict.clear() - req = self.new_update_request( - 'routers', - {'router': {'name': 'goo'}}, - router['router']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 500) - req = self.new_show_request('routers', router['router']['id']) - router = self.deserialize('json', req.get_response(self.ext_api)) - self.assertEqual(router['router']['status'], - constants.NET_STATUS_ERROR) - - def test_delete_security_group_not_in_nsx(self): - res = self._create_security_group('json', 'name', 'desc') - sec_group = self.deserialize('json', res) - self.fc._fake_securityprofile_dict.clear() - req = self.new_delete_request( - 'security-groups', - sec_group['security_group']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) diff --git a/neutron/tests/unit/vmware/test_nsx_sync.py b/neutron/tests/unit/vmware/test_nsx_sync.py deleted file mode 100644 index 67c2fdd44..000000000 --- a/neutron/tests/unit/vmware/test_nsx_sync.py +++ /dev/null @@ -1,712 +0,0 @@ -# Copyright 2013 VMware, Inc. -# All Rights Reserved -# -# 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 contextlib -import time - -import mock -from oslo.config import cfg - -from neutron.api.v2 import attributes as attr -from neutron.common import constants -from neutron.common import exceptions as n_exc -from neutron import context -from neutron.extensions import l3 -from neutron.openstack.common import jsonutils as json -from neutron.openstack.common import log -from neutron.plugins.vmware.api_client import client -from neutron.plugins.vmware.api_client import exception as api_exc -from neutron.plugins.vmware.api_client import version -from neutron.plugins.vmware.common import sync -from neutron.plugins.vmware.dbexts import db -from neutron.plugins.vmware import nsx_cluster as cluster -from neutron.plugins.vmware import nsxlib -from neutron.plugins.vmware import plugin -from neutron.tests import base -from neutron.tests.unit import test_api_v2 -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.apiclient import fake - -LOG = log.getLogger(__name__) - -_uuid = test_api_v2._uuid -LSWITCHES = [{'uuid': _uuid(), 'name': 'ls-1'}, - {'uuid': _uuid(), 'name': 'ls-2'}] -LSWITCHPORTS = [{'uuid': _uuid(), 'name': 'lp-1'}, - {'uuid': _uuid(), 'name': 'lp-2'}] -LROUTERS = [{'uuid': _uuid(), 'name': 'lr-1'}, - {'uuid': _uuid(), 'name': 'lr-2'}] - - -class CacheTestCase(base.BaseTestCase): - """Test suite providing coverage for the Cache class.""" - - def setUp(self): - self.nsx_cache = sync.NsxCache() - for lswitch in LSWITCHES: - self.nsx_cache._uuid_dict_mappings[lswitch['uuid']] = ( - self.nsx_cache._lswitches) - self.nsx_cache._lswitches[lswitch['uuid']] = ( - {'data': lswitch, - 'hash': hash(json.dumps(lswitch))}) - for lswitchport in LSWITCHPORTS: - self.nsx_cache._uuid_dict_mappings[lswitchport['uuid']] = ( - self.nsx_cache._lswitchports) - self.nsx_cache._lswitchports[lswitchport['uuid']] = ( - {'data': lswitchport, - 'hash': hash(json.dumps(lswitchport))}) - for lrouter in LROUTERS: - self.nsx_cache._uuid_dict_mappings[lrouter['uuid']] = ( - self.nsx_cache._lrouters) - self.nsx_cache._lrouters[lrouter['uuid']] = ( - {'data': lrouter, - 'hash': hash(json.dumps(lrouter))}) - super(CacheTestCase, self).setUp() - - def test_get_lswitches(self): - ls_uuids = self.nsx_cache.get_lswitches() - self.assertEqual(set(ls_uuids), - set([ls['uuid'] for ls in LSWITCHES])) - - def test_get_lswitchports(self): - lp_uuids = self.nsx_cache.get_lswitchports() - self.assertEqual(set(lp_uuids), - set([lp['uuid'] for lp in LSWITCHPORTS])) - - def test_get_lrouters(self): - lr_uuids = self.nsx_cache.get_lrouters() - self.assertEqual(set(lr_uuids), - set([lr['uuid'] for lr in LROUTERS])) - - def test_get_lswitches_changed_only(self): - ls_uuids = self.nsx_cache.get_lswitches(changed_only=True) - self.assertEqual(0, len(ls_uuids)) - - def test_get_lswitchports_changed_only(self): - lp_uuids = self.nsx_cache.get_lswitchports(changed_only=True) - self.assertEqual(0, len(lp_uuids)) - - def test_get_lrouters_changed_only(self): - lr_uuids = self.nsx_cache.get_lrouters(changed_only=True) - self.assertEqual(0, len(lr_uuids)) - - def _verify_update(self, new_resource, changed=True, hit=True): - cached_resource = self.nsx_cache[new_resource['uuid']] - self.assertEqual(new_resource, cached_resource['data']) - self.assertEqual(hit, cached_resource.get('hit', False)) - self.assertEqual(changed, - cached_resource.get('changed', False)) - - def test_update_lswitch_new_item(self): - new_switch_uuid = _uuid() - new_switch = {'uuid': new_switch_uuid, 'name': 'new_switch'} - self.nsx_cache.update_lswitch(new_switch) - self.assertIn(new_switch_uuid, self.nsx_cache._lswitches.keys()) - self._verify_update(new_switch) - - def test_update_lswitch_existing_item(self): - switch = LSWITCHES[0] - switch['name'] = 'new_name' - self.nsx_cache.update_lswitch(switch) - self.assertIn(switch['uuid'], self.nsx_cache._lswitches.keys()) - self._verify_update(switch) - - def test_update_lswitchport_new_item(self): - new_switchport_uuid = _uuid() - new_switchport = {'uuid': new_switchport_uuid, - 'name': 'new_switchport'} - self.nsx_cache.update_lswitchport(new_switchport) - self.assertIn(new_switchport_uuid, - self.nsx_cache._lswitchports.keys()) - self._verify_update(new_switchport) - - def test_update_lswitchport_existing_item(self): - switchport = LSWITCHPORTS[0] - switchport['name'] = 'new_name' - self.nsx_cache.update_lswitchport(switchport) - self.assertIn(switchport['uuid'], - self.nsx_cache._lswitchports.keys()) - self._verify_update(switchport) - - def test_update_lrouter_new_item(self): - new_router_uuid = _uuid() - new_router = {'uuid': new_router_uuid, - 'name': 'new_router'} - self.nsx_cache.update_lrouter(new_router) - self.assertIn(new_router_uuid, - self.nsx_cache._lrouters.keys()) - self._verify_update(new_router) - - def test_update_lrouter_existing_item(self): - router = LROUTERS[0] - router['name'] = 'new_name' - self.nsx_cache.update_lrouter(router) - self.assertIn(router['uuid'], - self.nsx_cache._lrouters.keys()) - self._verify_update(router) - - def test_process_updates_initial(self): - # Clear cache content to simulate first-time filling - self.nsx_cache._lswitches.clear() - self.nsx_cache._lswitchports.clear() - self.nsx_cache._lrouters.clear() - self.nsx_cache.process_updates(LSWITCHES, LROUTERS, LSWITCHPORTS) - for resource in LSWITCHES + LROUTERS + LSWITCHPORTS: - self._verify_update(resource) - - def test_process_updates_no_change(self): - self.nsx_cache.process_updates(LSWITCHES, LROUTERS, LSWITCHPORTS) - for resource in LSWITCHES + LROUTERS + LSWITCHPORTS: - self._verify_update(resource, changed=False) - - def test_process_updates_with_changes(self): - LSWITCHES[0]['name'] = 'altered' - self.nsx_cache.process_updates(LSWITCHES, LROUTERS, LSWITCHPORTS) - for resource in LSWITCHES + LROUTERS + LSWITCHPORTS: - changed = (True if resource['uuid'] == LSWITCHES[0]['uuid'] - else False) - self._verify_update(resource, changed=changed) - - def _test_process_updates_with_removals(self): - lswitches = LSWITCHES[:] - lswitch = lswitches.pop() - self.nsx_cache.process_updates(lswitches, LROUTERS, LSWITCHPORTS) - for resource in LSWITCHES + LROUTERS + LSWITCHPORTS: - hit = (False if resource['uuid'] == lswitch['uuid'] - else True) - self._verify_update(resource, changed=False, hit=hit) - return (lswitch, lswitches) - - def test_process_updates_with_removals(self): - self._test_process_updates_with_removals() - - def test_process_updates_cleanup_after_delete(self): - deleted_lswitch, lswitches = self._test_process_updates_with_removals() - self.nsx_cache.process_deletes() - self.nsx_cache.process_updates(lswitches, LROUTERS, LSWITCHPORTS) - self.assertNotIn(deleted_lswitch['uuid'], self.nsx_cache._lswitches) - - def _verify_delete(self, resource, deleted=True, hit=True): - cached_resource = self.nsx_cache[resource['uuid']] - data_field = 'data_bk' if deleted else 'data' - self.assertEqual(resource, cached_resource[data_field]) - self.assertEqual(hit, cached_resource.get('hit', False)) - self.assertEqual(deleted, - cached_resource.get('changed', False)) - - def _set_hit(self, resources, uuid_to_delete=None): - for resource in resources: - if resource['data']['uuid'] != uuid_to_delete: - resource['hit'] = True - - def test_process_deletes_no_change(self): - # Mark all resources as hit - self._set_hit(self.nsx_cache._lswitches.values()) - self._set_hit(self.nsx_cache._lswitchports.values()) - self._set_hit(self.nsx_cache._lrouters.values()) - self.nsx_cache.process_deletes() - for resource in LSWITCHES + LROUTERS + LSWITCHPORTS: - self._verify_delete(resource, hit=False, deleted=False) - - def test_process_deletes_with_removals(self): - # Mark all resources but one as hit - uuid_to_delete = LSWITCHPORTS[0]['uuid'] - self._set_hit(self.nsx_cache._lswitches.values(), - uuid_to_delete) - self._set_hit(self.nsx_cache._lswitchports.values(), - uuid_to_delete) - self._set_hit(self.nsx_cache._lrouters.values(), - uuid_to_delete) - self.nsx_cache.process_deletes() - for resource in LSWITCHES + LROUTERS + LSWITCHPORTS: - deleted = resource['uuid'] == uuid_to_delete - self._verify_delete(resource, hit=False, deleted=deleted) - - -class SyncLoopingCallTestCase(base.BaseTestCase): - - def test_looping_calls(self): - # Avoid runs of the synchronization process - just start - # the looping call - with mock.patch.object( - sync.NsxSynchronizer, '_synchronize_state', return_value=0.01): - synchronizer = sync.NsxSynchronizer(mock.ANY, mock.ANY, - 100, 0, 0) - time.sleep(0.03) - # stop looping call before asserting - synchronizer._sync_looping_call.stop() - # Just verify the looping call has been called, trying - # to assess the exact number of calls would be unreliable - self.assertTrue(synchronizer._synchronize_state.call_count) - - -class SyncTestCase(base.BaseTestCase): - - def setUp(self): - # mock api client - self.fc = fake.FakeClient(vmware.STUBS_PATH) - mock_api = mock.patch(vmware.NSXAPI_NAME, autospec=True) - # Avoid runs of the synchronizer looping call - # These unit tests will excplicitly invoke synchronization - patch_sync = mock.patch.object(sync, '_start_loopingcall') - self.mock_api = mock_api.start() - patch_sync.start() - self.mock_api.return_value.login.return_value = "the_cookie" - # Emulate tests against NSX 3.x - self.mock_api.return_value.get_version.return_value = ( - version.Version("3.1")) - - self.mock_api.return_value.request.side_effect = self.fc.fake_request - self.fake_cluster = cluster.NSXCluster( - name='fake-cluster', nsx_controllers=['1.1.1.1:999'], - default_tz_uuid=_uuid(), nsx_user='foo', nsx_password='bar') - self.fake_cluster.api_client = client.NsxApiClient( - ('1.1.1.1', '999', True), - self.fake_cluster.nsx_user, self.fake_cluster.nsx_password, - request_timeout=self.fake_cluster.req_timeout, - http_timeout=self.fake_cluster.http_timeout, - retries=self.fake_cluster.retries, - redirects=self.fake_cluster.redirects) - # Instantiate Neutron plugin - # and setup needed config variables - args = ['--config-file', vmware.get_fake_conf('neutron.conf.test'), - '--config-file', vmware.get_fake_conf('nsx.ini.test')] - self.config_parse(args=args) - cfg.CONF.set_override('allow_overlapping_ips', True) - self._plugin = plugin.NsxPlugin() - # Mock neutron manager plugin load functions to speed up tests - mock_nm_get_plugin = mock.patch('neutron.manager.NeutronManager.' - 'get_plugin') - mock_nm_get_service_plugins = mock.patch( - 'neutron.manager.NeutronManager.get_service_plugins') - self.mock_nm_get_plugin = mock_nm_get_plugin.start() - self.mock_nm_get_plugin.return_value = self._plugin - mock_nm_get_service_plugins.start() - super(SyncTestCase, self).setUp() - self.addCleanup(self.fc.reset_all) - - @contextlib.contextmanager - def _populate_data(self, ctx, net_size=2, port_size=2, router_size=2): - - def network(idx): - return {'network': {'name': 'net-%s' % idx, - 'admin_state_up': True, - 'shared': False, - 'port_security_enabled': True, - 'tenant_id': 'foo'}} - - def subnet(idx, net_id): - return {'subnet': - {'cidr': '10.10.%s.0/24' % idx, - 'name': 'sub-%s' % idx, - 'gateway_ip': attr.ATTR_NOT_SPECIFIED, - 'allocation_pools': attr.ATTR_NOT_SPECIFIED, - 'ip_version': 4, - 'dns_nameservers': attr.ATTR_NOT_SPECIFIED, - 'host_routes': attr.ATTR_NOT_SPECIFIED, - 'enable_dhcp': True, - 'network_id': net_id, - 'tenant_id': 'foo'}} - - def port(idx, net_id): - return {'port': {'network_id': net_id, - 'name': 'port-%s' % idx, - 'admin_state_up': True, - 'device_id': 'miao', - 'device_owner': 'bau', - 'fixed_ips': attr.ATTR_NOT_SPECIFIED, - 'mac_address': attr.ATTR_NOT_SPECIFIED, - 'tenant_id': 'foo'}} - - def router(idx): - # Use random uuids as names - return {'router': {'name': 'rtr-%s' % idx, - 'admin_state_up': True, - 'tenant_id': 'foo'}} - - networks = [] - ports = [] - routers = [] - for i in range(net_size): - net = self._plugin.create_network(ctx, network(i)) - networks.append(net) - self._plugin.create_subnet(ctx, subnet(i, net['id'])) - for j in range(port_size): - ports.append(self._plugin.create_port( - ctx, port("%s-%s" % (i, j), net['id']))) - for i in range(router_size): - routers.append(self._plugin.create_router(ctx, router(i))) - # Do not return anything as the user does need the actual - # data created - yield - - # Remove everything - for router in routers: - self._plugin.delete_router(ctx, router['id']) - for port in ports: - self._plugin.delete_port(ctx, port['id']) - # This will remove networks and subnets - for network in networks: - self._plugin.delete_network(ctx, network['id']) - - def _get_tag_dict(self, tags): - return dict((tag['scope'], tag['tag']) for tag in tags) - - def _test_sync(self, exp_net_status, - exp_port_status, exp_router_status, - action_callback=None, sp=None): - ls_uuid = self.fc._fake_lswitch_dict.keys()[0] - neutron_net_id = self._get_tag_dict( - self.fc._fake_lswitch_dict[ls_uuid]['tags'])['quantum_net_id'] - lp_uuid = self.fc._fake_lswitch_lport_dict.keys()[0] - neutron_port_id = self._get_tag_dict( - self.fc._fake_lswitch_lport_dict[lp_uuid]['tags'])['q_port_id'] - lr_uuid = self.fc._fake_lrouter_dict.keys()[0] - neutron_rtr_id = self._get_tag_dict( - self.fc._fake_lrouter_dict[lr_uuid]['tags'])['q_router_id'] - if action_callback: - action_callback(ls_uuid, lp_uuid, lr_uuid) - # Make chunk big enough to read everything - if not sp: - sp = sync.SyncParameters(100) - self._plugin._synchronizer._synchronize_state(sp) - # Verify element is in expected status - # TODO(salv-orlando): Verify status for all elements - ctx = context.get_admin_context() - neutron_net = self._plugin.get_network(ctx, neutron_net_id) - neutron_port = self._plugin.get_port(ctx, neutron_port_id) - neutron_rtr = self._plugin.get_router(ctx, neutron_rtr_id) - self.assertEqual(exp_net_status, neutron_net['status']) - self.assertEqual(exp_port_status, neutron_port['status']) - self.assertEqual(exp_router_status, neutron_rtr['status']) - - def _action_callback_status_down(self, ls_uuid, lp_uuid, lr_uuid): - self.fc._fake_lswitch_dict[ls_uuid]['status'] = 'false' - self.fc._fake_lswitch_lport_dict[lp_uuid]['status'] = 'false' - self.fc._fake_lrouter_dict[lr_uuid]['status'] = 'false' - - def test_initial_sync(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - self._test_sync( - constants.NET_STATUS_ACTIVE, - constants.PORT_STATUS_ACTIVE, - constants.NET_STATUS_ACTIVE) - - def test_initial_sync_with_resources_down(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - self._test_sync( - constants.NET_STATUS_DOWN, constants.PORT_STATUS_DOWN, - constants.NET_STATUS_DOWN, self._action_callback_status_down) - - def test_resync_with_resources_down(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - sp = sync.SyncParameters(100) - self._plugin._synchronizer._synchronize_state(sp) - # Ensure the synchronizer performs a resync - sp.init_sync_performed = True - self._test_sync( - constants.NET_STATUS_DOWN, constants.PORT_STATUS_DOWN, - constants.NET_STATUS_DOWN, self._action_callback_status_down, - sp=sp) - - def _action_callback_del_resource(self, ls_uuid, lp_uuid, lr_uuid): - del self.fc._fake_lswitch_dict[ls_uuid] - del self.fc._fake_lswitch_lport_dict[lp_uuid] - del self.fc._fake_lrouter_dict[lr_uuid] - - def test_initial_sync_with_resources_removed(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - self._test_sync( - constants.NET_STATUS_ERROR, constants.PORT_STATUS_ERROR, - constants.NET_STATUS_ERROR, self._action_callback_del_resource) - - def test_resync_with_resources_removed(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - sp = sync.SyncParameters(100) - self._plugin._synchronizer._synchronize_state(sp) - # Ensure the synchronizer performs a resync - sp.init_sync_performed = True - self._test_sync( - constants.NET_STATUS_ERROR, constants.PORT_STATUS_ERROR, - constants.NET_STATUS_ERROR, self._action_callback_del_resource, - sp=sp) - - def _test_sync_with_chunk_larger_maxpagesize( - self, net_size, port_size, router_size, chunk_size, exp_calls): - ctx = context.get_admin_context() - real_func = nsxlib.get_single_query_page - sp = sync.SyncParameters(chunk_size) - with self._populate_data(ctx, net_size=net_size, - port_size=port_size, - router_size=router_size): - with mock.patch.object(sync, 'MAX_PAGE_SIZE', 15): - # The following mock is just for counting calls, - # but we will still run the actual function - with mock.patch.object( - nsxlib, 'get_single_query_page', - side_effect=real_func) as mock_get_page: - self._test_sync( - constants.NET_STATUS_ACTIVE, - constants.PORT_STATUS_ACTIVE, - constants.NET_STATUS_ACTIVE, - sp=sp) - # As each resource type does not exceed the maximum page size, - # the method should be called once for each resource type - self.assertEqual(exp_calls, mock_get_page.call_count) - - def test_sync_chunk_larger_maxpagesize_no_multiple_requests(self): - # total resource size = 20 - # total size for each resource does not exceed max page size (15) - self._test_sync_with_chunk_larger_maxpagesize( - net_size=5, port_size=2, router_size=5, - chunk_size=20, exp_calls=3) - - def test_sync_chunk_larger_maxpagesize_triggers_multiple_requests(self): - # total resource size = 48 - # total size for each resource does exceed max page size (15) - self._test_sync_with_chunk_larger_maxpagesize( - net_size=16, port_size=1, router_size=16, - chunk_size=48, exp_calls=6) - - def test_sync_multi_chunk(self): - # The fake NSX API client cannot be used for this test - ctx = context.get_admin_context() - # Generate 4 networks, 1 port per network, and 4 routers - with self._populate_data(ctx, net_size=4, port_size=1, router_size=4): - fake_lswitches = json.loads( - self.fc.handle_get('/ws.v1/lswitch'))['results'] - fake_lrouters = json.loads( - self.fc.handle_get('/ws.v1/lrouter'))['results'] - fake_lswitchports = json.loads( - self.fc.handle_get('/ws.v1/lswitch/*/lport'))['results'] - return_values = [ - # Chunk 0 - lswitches - (fake_lswitches, None, 4), - # Chunk 0 - lrouters - (fake_lrouters[:2], 'xxx', 4), - # Chunk 0 - lports (size only) - ([], 'start', 4), - # Chunk 1 - lrouters (2 more) (lswitches are skipped) - (fake_lrouters[2:], None, None), - # Chunk 1 - lports - (fake_lswitchports, None, 4)] - - def fake_fetch_data(*args, **kwargs): - return return_values.pop(0) - - # 2 Chunks, with 6 resources each. - # 1st chunk lswitches and lrouters - # 2nd chunk lrouters and lports - # Mock _fetch_data - with mock.patch.object( - self._plugin._synchronizer, '_fetch_data', - side_effect=fake_fetch_data): - sp = sync.SyncParameters(6) - - def do_chunk(chunk_idx, ls_cursor, lr_cursor, lp_cursor): - self._plugin._synchronizer._synchronize_state(sp) - self.assertEqual(chunk_idx, sp.current_chunk) - self.assertEqual(ls_cursor, sp.ls_cursor) - self.assertEqual(lr_cursor, sp.lr_cursor) - self.assertEqual(lp_cursor, sp.lp_cursor) - - # check 1st chunk - do_chunk(1, None, 'xxx', 'start') - # check 2nd chunk - do_chunk(0, None, None, None) - # Chunk size should have stayed the same - self.assertEqual(sp.chunk_size, 6) - - def test_synchronize_network(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a network down to verify synchronization - ls_uuid = self.fc._fake_lswitch_dict.keys()[0] - q_net_id = self._get_tag_dict( - self.fc._fake_lswitch_dict[ls_uuid]['tags'])['quantum_net_id'] - self.fc._fake_lswitch_dict[ls_uuid]['status'] = 'false' - q_net_data = self._plugin._get_network(ctx, q_net_id) - self._plugin._synchronizer.synchronize_network(ctx, q_net_data) - # Reload from db - q_nets = self._plugin.get_networks(ctx) - for q_net in q_nets: - if q_net['id'] == q_net_id: - exp_status = constants.NET_STATUS_DOWN - else: - exp_status = constants.NET_STATUS_ACTIVE - self.assertEqual(exp_status, q_net['status']) - - def test_synchronize_network_not_found_in_db_no_raise(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a network down to verify synchronization - ls_uuid = self.fc._fake_lswitch_dict.keys()[0] - q_net_id = self._get_tag_dict( - self.fc._fake_lswitch_dict[ls_uuid]['tags'])['quantum_net_id'] - self.fc._fake_lswitch_dict[ls_uuid]['status'] = 'false' - q_net_data = self._plugin._get_network(ctx, q_net_id) - with mock.patch.object(self._plugin, - '_get_network') as _get_network: - _get_network.side_effect = n_exc.NetworkNotFound( - net_id=q_net_data['id']) - self._plugin._synchronizer.synchronize_network(ctx, q_net_data) - - def test_synchronize_network_on_get(self): - cfg.CONF.set_override('always_read_status', True, 'NSX_SYNC') - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a network down to verify punctual synchronization - ls_uuid = self.fc._fake_lswitch_dict.keys()[0] - q_net_id = self._get_tag_dict( - self.fc._fake_lswitch_dict[ls_uuid]['tags'])['quantum_net_id'] - self.fc._fake_lswitch_dict[ls_uuid]['status'] = 'false' - q_net_data = self._plugin.get_network(ctx, q_net_id) - self.assertEqual(constants.NET_STATUS_DOWN, q_net_data['status']) - - def test_synchronize_port_not_found_in_db_no_raise(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a port down to verify synchronization - lp_uuid = self.fc._fake_lswitch_lport_dict.keys()[0] - lport = self.fc._fake_lswitch_lport_dict[lp_uuid] - q_port_id = self._get_tag_dict(lport['tags'])['q_port_id'] - lport['status'] = 'true' - q_port_data = self._plugin._get_port(ctx, q_port_id) - with mock.patch.object(self._plugin, - '_get_port') as _get_port: - _get_port.side_effect = n_exc.PortNotFound( - port_id=q_port_data['id']) - self._plugin._synchronizer.synchronize_port(ctx, q_port_data) - - def test_synchronize_port(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a port down to verify synchronization - lp_uuid = self.fc._fake_lswitch_lport_dict.keys()[0] - lport = self.fc._fake_lswitch_lport_dict[lp_uuid] - q_port_id = self._get_tag_dict(lport['tags'])['q_port_id'] - lport['status'] = 'true' - q_port_data = self._plugin._get_port(ctx, q_port_id) - self._plugin._synchronizer.synchronize_port(ctx, q_port_data) - # Reload from db - q_ports = self._plugin.get_ports(ctx) - for q_port in q_ports: - if q_port['id'] == q_port_id: - exp_status = constants.PORT_STATUS_ACTIVE - else: - exp_status = constants.PORT_STATUS_DOWN - self.assertEqual(exp_status, q_port['status']) - - def test_synchronize_port_on_get(self): - cfg.CONF.set_override('always_read_status', True, 'NSX_SYNC') - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a port down to verify punctual synchronization - lp_uuid = self.fc._fake_lswitch_lport_dict.keys()[0] - lport = self.fc._fake_lswitch_lport_dict[lp_uuid] - q_port_id = self._get_tag_dict(lport['tags'])['q_port_id'] - lport['status'] = 'false' - q_port_data = self._plugin.get_port(ctx, q_port_id) - self.assertEqual(constants.PORT_STATUS_DOWN, - q_port_data['status']) - - def test_synchronize_routernot_found_in_db_no_raise(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a router down to verify synchronization - lr_uuid = self.fc._fake_lrouter_dict.keys()[0] - q_rtr_id = self._get_tag_dict( - self.fc._fake_lrouter_dict[lr_uuid]['tags'])['q_router_id'] - self.fc._fake_lrouter_dict[lr_uuid]['status'] = 'false' - q_rtr_data = self._plugin._get_router(ctx, q_rtr_id) - with mock.patch.object(self._plugin, - '_get_router') as _get_router: - _get_router.side_effect = l3.RouterNotFound( - router_id=q_rtr_data['id']) - self._plugin._synchronizer.synchronize_router(ctx, q_rtr_data) - - def test_synchronize_router(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a router down to verify synchronization - lr_uuid = self.fc._fake_lrouter_dict.keys()[0] - q_rtr_id = self._get_tag_dict( - self.fc._fake_lrouter_dict[lr_uuid]['tags'])['q_router_id'] - self.fc._fake_lrouter_dict[lr_uuid]['status'] = 'false' - q_rtr_data = self._plugin._get_router(ctx, q_rtr_id) - self._plugin._synchronizer.synchronize_router(ctx, q_rtr_data) - # Reload from db - q_routers = self._plugin.get_routers(ctx) - for q_rtr in q_routers: - if q_rtr['id'] == q_rtr_id: - exp_status = constants.NET_STATUS_DOWN - else: - exp_status = constants.NET_STATUS_ACTIVE - self.assertEqual(exp_status, q_rtr['status']) - - def test_synchronize_router_nsx_mapping_not_found(self): - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a router down to verify synchronization - lr_uuid = self.fc._fake_lrouter_dict.keys()[0] - q_rtr_id = self._get_tag_dict( - self.fc._fake_lrouter_dict[lr_uuid]['tags'])['q_router_id'] - self.fc._fake_lrouter_dict[lr_uuid]['status'] = 'false' - q_rtr_data = self._plugin._get_router(ctx, q_rtr_id) - - # delete router mapping from db. - db.delete_neutron_nsx_router_mapping(ctx.session, q_rtr_id) - # pop router from fake nsx client - router_data = self.fc._fake_lrouter_dict.pop(lr_uuid) - - self._plugin._synchronizer.synchronize_router(ctx, q_rtr_data) - # Reload from db - q_routers = self._plugin.get_routers(ctx) - for q_rtr in q_routers: - if q_rtr['id'] == q_rtr_id: - exp_status = constants.NET_STATUS_ERROR - else: - exp_status = constants.NET_STATUS_ACTIVE - self.assertEqual(exp_status, q_rtr['status']) - # put the router database since we don't handle missing - # router data in the fake nsx api_client - self.fc._fake_lrouter_dict[lr_uuid] = router_data - - def test_synchronize_router_on_get(self): - cfg.CONF.set_override('always_read_status', True, 'NSX_SYNC') - ctx = context.get_admin_context() - with self._populate_data(ctx): - # Put a router down to verify punctual synchronization - lr_uuid = self.fc._fake_lrouter_dict.keys()[0] - q_rtr_id = self._get_tag_dict( - self.fc._fake_lrouter_dict[lr_uuid]['tags'])['q_router_id'] - self.fc._fake_lrouter_dict[lr_uuid]['status'] = 'false' - q_rtr_data = self._plugin.get_router(ctx, q_rtr_id) - self.assertEqual(constants.NET_STATUS_DOWN, q_rtr_data['status']) - - def test_sync_nsx_failure_backoff(self): - self.mock_api.return_value.request.side_effect = api_exc.RequestTimeout - # chunk size won't matter here - sp = sync.SyncParameters(999) - for i in range(10): - self.assertEqual( - min(64, 2 ** i), - self._plugin._synchronizer._synchronize_state(sp)) diff --git a/neutron/tests/unit/vmware/test_nsx_utils.py b/neutron/tests/unit/vmware/test_nsx_utils.py deleted file mode 100644 index 2144154ab..000000000 --- a/neutron/tests/unit/vmware/test_nsx_utils.py +++ /dev/null @@ -1,325 +0,0 @@ -# Copyright (c) 2013 VMware. -# -# 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 neutron.db import api as db_api -from neutron.openstack.common import uuidutils -from neutron.plugins.vmware.api_client import exception as api_exc -from neutron.plugins.vmware.common import exceptions as nsx_exc -from neutron.plugins.vmware.common import nsx_utils -from neutron.plugins.vmware.common import utils -from neutron.plugins.vmware import nsxlib -from neutron.tests import base -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.nsxlib import base as nsx_base - - -class NsxUtilsTestCase(base.BaseTestCase): - - def _mock_port_mapping_db_calls(self, ret_value): - # Mock relevant db calls - # This will allow for avoiding setting up the plugin - # for creating db entries - mock.patch(vmware.nsx_method('get_nsx_switch_and_port_id', - module_name='dbexts.db'), - return_value=ret_value).start() - mock.patch(vmware.nsx_method('add_neutron_nsx_port_mapping', - module_name='dbexts.db')).start() - mock.patch(vmware.nsx_method('delete_neutron_nsx_port_mapping', - module_name='dbexts.db')).start() - - def _mock_network_mapping_db_calls(self, ret_value): - # Mock relevant db calls - # This will allow for avoiding setting up the plugin - # for creating db entries - mock.patch(vmware.nsx_method('get_nsx_switch_ids', - module_name='dbexts.db'), - return_value=ret_value).start() - mock.patch(vmware.nsx_method('add_neutron_nsx_network_mapping', - module_name='dbexts.db')).start() - - def _mock_router_mapping_db_calls(self, ret_value): - # Mock relevant db calls - # This will allow for avoiding setting up the plugin - # for creating db entries - mock.patch(vmware.nsx_method('get_nsx_router_id', - module_name='dbexts.db'), - return_value=ret_value).start() - mock.patch(vmware.nsx_method('add_neutron_nsx_router_mapping', - module_name='dbexts.db')).start() - - def _verify_get_nsx_switch_and_port_id(self, exp_ls_uuid, exp_lp_uuid): - # The nsxlib and db calls are mocked, therefore the cluster - # and the neutron_port_id parameters can be set to None - ls_uuid, lp_uuid = nsx_utils.get_nsx_switch_and_port_id( - db_api.get_session(), None, None) - self.assertEqual(exp_ls_uuid, ls_uuid) - self.assertEqual(exp_lp_uuid, lp_uuid) - - def _verify_get_nsx_switch_ids(self, exp_ls_uuids): - # The nsxlib and db calls are mocked, therefore the cluster - # and the neutron_router_id parameters can be set to None - ls_uuids = nsx_utils.get_nsx_switch_ids( - db_api.get_session(), None, None) - for ls_uuid in ls_uuids or []: - self.assertIn(ls_uuid, exp_ls_uuids) - exp_ls_uuids.remove(ls_uuid) - self.assertFalse(exp_ls_uuids) - - def _verify_get_nsx_router_id(self, exp_lr_uuid): - # The nsxlib and db calls are mocked, therefore the cluster - # and the neutron_router_id parameters can be set to None - lr_uuid = nsx_utils.get_nsx_router_id(db_api.get_session(), None, None) - self.assertEqual(exp_lr_uuid, lr_uuid) - - def test_get_nsx_switch_and_port_id_from_db_mappings(self): - # This test is representative of the 'standard' case in which both the - # switch and the port mappings were stored in the neutron db - exp_ls_uuid = uuidutils.generate_uuid() - exp_lp_uuid = uuidutils.generate_uuid() - ret_value = exp_ls_uuid, exp_lp_uuid - self._mock_port_mapping_db_calls(ret_value) - self._verify_get_nsx_switch_and_port_id(exp_ls_uuid, exp_lp_uuid) - - def test_get_nsx_switch_and_port_id_only_port_db_mapping(self): - # This test is representative of the case in which a port with a nsx - # db mapping in the havana db was upgraded to icehouse - exp_ls_uuid = uuidutils.generate_uuid() - exp_lp_uuid = uuidutils.generate_uuid() - ret_value = None, exp_lp_uuid - self._mock_port_mapping_db_calls(ret_value) - with mock.patch(vmware.nsx_method('query_lswitch_lports', - module_name='nsxlib.switch'), - return_value=[{'uuid': exp_lp_uuid, - '_relations': { - 'LogicalSwitchConfig': { - 'uuid': exp_ls_uuid} - }}]): - self._verify_get_nsx_switch_and_port_id(exp_ls_uuid, exp_lp_uuid) - - def test_get_nsx_switch_and_port_id_no_db_mapping(self): - # This test is representative of the case where db mappings where not - # found for a given port identifier - exp_ls_uuid = uuidutils.generate_uuid() - exp_lp_uuid = uuidutils.generate_uuid() - ret_value = None, None - self._mock_port_mapping_db_calls(ret_value) - with mock.patch(vmware.nsx_method('query_lswitch_lports', - module_name='nsxlib.switch'), - return_value=[{'uuid': exp_lp_uuid, - '_relations': { - 'LogicalSwitchConfig': { - 'uuid': exp_ls_uuid} - }}]): - self._verify_get_nsx_switch_and_port_id(exp_ls_uuid, exp_lp_uuid) - - def test_get_nsx_switch_and_port_id_no_mappings_returns_none(self): - # This test verifies that the function return (None, None) if the - # mappings are not found both in the db and the backend - ret_value = None, None - self._mock_port_mapping_db_calls(ret_value) - with mock.patch(vmware.nsx_method('query_lswitch_lports', - module_name='nsxlib.switch'), - return_value=[]): - self._verify_get_nsx_switch_and_port_id(None, None) - - def test_get_nsx_switch_ids_from_db_mappings(self): - # This test is representative of the 'standard' case in which the - # lswitch mappings were stored in the neutron db - exp_ls_uuids = [uuidutils.generate_uuid()] - self._mock_network_mapping_db_calls(exp_ls_uuids) - self._verify_get_nsx_switch_ids(exp_ls_uuids) - - def test_get_nsx_switch_ids_no_db_mapping(self): - # This test is representative of the case where db mappings where not - # found for a given network identifier - exp_ls_uuids = [uuidutils.generate_uuid()] - self._mock_network_mapping_db_calls(None) - with mock.patch(vmware.nsx_method('get_lswitches', - module_name='nsxlib.switch'), - return_value=[{'uuid': uuid} - for uuid in exp_ls_uuids]): - self._verify_get_nsx_switch_ids(exp_ls_uuids) - - def test_get_nsx_switch_ids_no_mapping_returns_None(self): - # This test verifies that the function returns None if the mappings - # are not found both in the db and in the backend - self._mock_network_mapping_db_calls(None) - with mock.patch(vmware.nsx_method('get_lswitches', - module_name='nsxlib.switch'), - return_value=[]): - self._verify_get_nsx_switch_ids(None) - - def test_get_nsx_router_id_from_db_mappings(self): - # This test is representative of the 'standard' case in which the - # router mapping was stored in the neutron db - exp_lr_uuid = uuidutils.generate_uuid() - self._mock_router_mapping_db_calls(exp_lr_uuid) - self._verify_get_nsx_router_id(exp_lr_uuid) - - def test_get_nsx_router_id_no_db_mapping(self): - # This test is representative of the case where db mappings where not - # found for a given port identifier - exp_lr_uuid = uuidutils.generate_uuid() - self._mock_router_mapping_db_calls(None) - with mock.patch(vmware.nsx_method('query_lrouters', - module_name='nsxlib.router'), - return_value=[{'uuid': exp_lr_uuid}]): - self._verify_get_nsx_router_id(exp_lr_uuid) - - def test_get_nsx_router_id_no_mapping_returns_None(self): - # This test verifies that the function returns None if the mapping - # are not found both in the db and in the backend - self._mock_router_mapping_db_calls(None) - with mock.patch(vmware.nsx_method('query_lrouters', - module_name='nsxlib.router'), - return_value=[]): - self._verify_get_nsx_router_id(None) - - def test_check_and_truncate_name_with_none(self): - name = None - result = utils.check_and_truncate(name) - self.assertEqual('', result) - - def test_check_and_truncate_name_with_short_name(self): - name = 'foo_port_name' - result = utils.check_and_truncate(name) - self.assertEqual(name, result) - - def test_check_and_truncate_name_long_name(self): - name = 'this_is_a_port_whose_name_is_longer_than_40_chars' - result = utils.check_and_truncate(name) - self.assertEqual(len(result), utils.MAX_DISPLAY_NAME_LEN) - - def test_build_uri_path_plain(self): - result = nsxlib._build_uri_path('RESOURCE') - self.assertEqual("%s/%s" % (nsxlib.URI_PREFIX, 'RESOURCE'), result) - - def test_build_uri_path_with_field(self): - result = nsxlib._build_uri_path('RESOURCE', fields='uuid') - expected = "%s/%s?fields=uuid" % (nsxlib.URI_PREFIX, 'RESOURCE') - self.assertEqual(expected, result) - - def test_build_uri_path_with_filters(self): - filters = {"tag": 'foo', "tag_scope": "scope_foo"} - result = nsxlib._build_uri_path('RESOURCE', filters=filters) - expected = ( - "%s/%s?tag_scope=scope_foo&tag=foo" % - (nsxlib.URI_PREFIX, 'RESOURCE')) - self.assertEqual(expected, result) - - def test_build_uri_path_with_resource_id(self): - res = 'RESOURCE' - res_id = 'resource_id' - result = nsxlib._build_uri_path(res, resource_id=res_id) - expected = "%s/%s/%s" % (nsxlib.URI_PREFIX, res, res_id) - self.assertEqual(expected, result) - - def test_build_uri_path_with_parent_and_resource_id(self): - parent_res = 'RESOURCE_PARENT' - child_res = 'RESOURCE_CHILD' - res = '%s/%s' % (child_res, parent_res) - par_id = 'parent_resource_id' - res_id = 'resource_id' - result = nsxlib._build_uri_path( - res, parent_resource_id=par_id, resource_id=res_id) - expected = ("%s/%s/%s/%s/%s" % - (nsxlib.URI_PREFIX, parent_res, par_id, child_res, res_id)) - self.assertEqual(expected, result) - - def test_build_uri_path_with_attachment(self): - parent_res = 'RESOURCE_PARENT' - child_res = 'RESOURCE_CHILD' - res = '%s/%s' % (child_res, parent_res) - par_id = 'parent_resource_id' - res_id = 'resource_id' - result = nsxlib._build_uri_path(res, parent_resource_id=par_id, - resource_id=res_id, is_attachment=True) - expected = ("%s/%s/%s/%s/%s/%s" % - (nsxlib.URI_PREFIX, parent_res, - par_id, child_res, res_id, 'attachment')) - self.assertEqual(expected, result) - - def test_build_uri_path_with_extra_action(self): - parent_res = 'RESOURCE_PARENT' - child_res = 'RESOURCE_CHILD' - res = '%s/%s' % (child_res, parent_res) - par_id = 'parent_resource_id' - res_id = 'resource_id' - result = nsxlib._build_uri_path(res, parent_resource_id=par_id, - resource_id=res_id, extra_action='doh') - expected = ("%s/%s/%s/%s/%s/%s" % - (nsxlib.URI_PREFIX, parent_res, - par_id, child_res, res_id, 'doh')) - self.assertEqual(expected, result) - - def _mock_sec_group_mapping_db_calls(self, ret_value): - mock.patch(vmware.nsx_method('get_nsx_security_group_id', - module_name='dbexts.db'), - return_value=ret_value).start() - mock.patch(vmware.nsx_method('add_neutron_nsx_security_group_mapping', - module_name='dbexts.db')).start() - - def _verify_get_nsx_sec_profile_id(self, exp_sec_prof_uuid): - # The nsxlib and db calls are mocked, therefore the cluster - # and the neutron_id parameters can be set to None - sec_prof_uuid = nsx_utils.get_nsx_security_group_id( - db_api.get_session(), None, None) - self.assertEqual(exp_sec_prof_uuid, sec_prof_uuid) - - def test_get_nsx_sec_profile_id_from_db_mappings(self): - # This test is representative of the 'standard' case in which the - # security group mapping was stored in the neutron db - exp_sec_prof_uuid = uuidutils.generate_uuid() - self._mock_sec_group_mapping_db_calls(exp_sec_prof_uuid) - self._verify_get_nsx_sec_profile_id(exp_sec_prof_uuid) - - def test_get_nsx_sec_profile_id_no_db_mapping(self): - # This test is representative of the case where db mappings where not - # found for a given security profile identifier - exp_sec_prof_uuid = uuidutils.generate_uuid() - self._mock_sec_group_mapping_db_calls(None) - with mock.patch(vmware.nsx_method('query_security_profiles', - module_name='nsxlib.secgroup'), - return_value=[{'uuid': exp_sec_prof_uuid}]): - self._verify_get_nsx_sec_profile_id(exp_sec_prof_uuid) - - def test_get_nsx_sec_profile_id_no_mapping_returns_None(self): - # This test verifies that the function returns None if the mapping - # are not found both in the db and in the backend - self._mock_sec_group_mapping_db_calls(None) - with mock.patch(vmware.nsx_method('query_security_profiles', - module_name='nsxlib.secgroup'), - return_value=[]): - self._verify_get_nsx_sec_profile_id(None) - - -class ClusterManagementTestCase(nsx_base.NsxlibTestCase): - - def test_cluster_in_readonly_mode(self): - with mock.patch.object(self.fake_cluster.api_client, - 'request', - side_effect=api_exc.ReadOnlyMode): - self.assertRaises(nsx_exc.MaintenanceInProgress, - nsxlib.do_request, cluster=self.fake_cluster) - - def test_cluster_method_not_implemented(self): - self.assertRaises(api_exc.NsxApiException, - nsxlib.do_request, - nsxlib.HTTP_GET, - nsxlib._build_uri_path('MY_FAKE_RESOURCE', - resource_id='foo'), - cluster=self.fake_cluster) diff --git a/neutron/tests/unit/vmware/vshield/__init__.py b/neutron/tests/unit/vmware/vshield/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/vmware/vshield/fake_vcns.py b/neutron/tests/unit/vmware/vshield/fake_vcns.py deleted file mode 100644 index 2c9aa6162..000000000 --- a/neutron/tests/unit/vmware/vshield/fake_vcns.py +++ /dev/null @@ -1,600 +0,0 @@ -# Copyright 2013 VMware, Inc -# -# 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 copy - -from neutron.openstack.common import jsonutils as json -from neutron.openstack.common import uuidutils -from neutron.plugins.vmware.vshield.common import exceptions - - -class FakeVcns(object): - - errors = { - 303: exceptions.ResourceRedirect, - 400: exceptions.RequestBad, - 403: exceptions.Forbidden, - 404: exceptions.ResourceNotFound, - 415: exceptions.MediaTypeUnsupport, - 503: exceptions.ServiceUnavailable - } - - def __init__(self, unique_router_name=True): - self._jobs = {} - self._job_idx = 0 - self._edges = {} - self._edge_idx = 0 - self._lswitches = {} - self._unique_router_name = unique_router_name - self._fake_nsx_api = None - self.fake_firewall_dict = {} - self.temp_firewall = { - "firewallRules": { - "firewallRules": [] - } - } - self.fake_ipsecvpn_dict = {} - self.temp_ipsecvpn = { - 'featureType': "ipsec_4.0", - 'enabled': True, - 'sites': {'sites': []}} - self._fake_virtualservers_dict = {} - self._fake_pools_dict = {} - self._fake_monitors_dict = {} - self._fake_app_profiles_dict = {} - self._fake_loadbalancer_config = {} - - def set_fake_nsx_api(self, fake_nsx_api): - self._fake_nsx_api = fake_nsx_api - - def _validate_edge_name(self, name): - for edge_id, edge in self._edges.iteritems(): - if edge['name'] == name: - return False - return True - - def deploy_edge(self, request): - if (self._unique_router_name and - not self._validate_edge_name(request['name'])): - header = { - 'status': 400 - } - msg = ('Edge name should be unique for tenant. Edge %s ' - 'already exists for default tenant.') % request['name'] - response = { - 'details': msg, - 'errorCode': 10085, - 'rootCauseString': None, - 'moduleName': 'vShield Edge', - 'errorData': None - } - return (header, json.dumps(response)) - - self._job_idx = self._job_idx + 1 - job_id = "jobdata-%d" % self._job_idx - self._edge_idx = self._edge_idx + 1 - edge_id = "edge-%d" % self._edge_idx - self._jobs[job_id] = edge_id - self._edges[edge_id] = { - 'name': request['name'], - 'request': request, - 'nat_rules': None, - 'nat_rule_id': 0 - } - header = { - 'status': 200, - 'location': 'https://host/api/4.0/jobs/%s' % job_id - } - response = '' - return (header, response) - - def get_edge_id(self, job_id): - if job_id not in self._jobs: - raise Exception(_("Job %s does not nexist") % job_id) - - header = { - 'status': 200 - } - response = { - 'edgeId': self._jobs[job_id] - } - return (header, response) - - def get_edge_deploy_status(self, edge_id): - if edge_id not in self._edges: - raise Exception(_("Edge %s does not exist") % edge_id) - header = { - 'status': 200, - } - response = { - 'systemStatus': 'good' - } - return (header, response) - - def delete_edge(self, edge_id): - if edge_id not in self._edges: - raise Exception(_("Edge %s does not exist") % edge_id) - del self._edges[edge_id] - header = { - 'status': 200 - } - response = '' - return (header, response) - - def update_interface(self, edge_id, vnic): - header = { - 'status': 200 - } - response = '' - return (header, response) - - def get_nat_config(self, edge_id): - if edge_id not in self._edges: - raise Exception(_("Edge %s does not exist") % edge_id) - edge = self._edges[edge_id] - rules = edge['nat_rules'] - if rules is None: - rules = { - 'rules': { - 'natRulesDtos': [] - }, - 'version': 1 - } - header = { - 'status': 200 - } - rules['version'] = 1 - return (header, rules) - - def update_nat_config(self, edge_id, nat): - if edge_id not in self._edges: - raise Exception(_("Edge %s does not exist") % edge_id) - edge = self._edges[edge_id] - max_rule_id = edge['nat_rule_id'] - rules = copy.deepcopy(nat) - for rule in rules['rules']['natRulesDtos']: - rule_id = rule.get('ruleId', 0) - if rule_id > max_rule_id: - max_rule_id = rule_id - for rule in rules['rules']['natRulesDtos']: - if 'ruleId' not in rule: - max_rule_id = max_rule_id + 1 - rule['ruleId'] = max_rule_id - edge['nat_rules'] = rules - edge['nat_rule_id'] = max_rule_id - header = { - 'status': 200 - } - response = '' - return (header, response) - - def delete_nat_rule(self, edge_id, rule_id): - if edge_id not in self._edges: - raise Exception(_("Edge %s does not exist") % edge_id) - - edge = self._edges[edge_id] - rules = edge['nat_rules'] - rule_to_delete = None - for rule in rules['rules']['natRulesDtos']: - if rule_id == rule['ruleId']: - rule_to_delete = rule - break - if rule_to_delete is None: - raise Exception(_("Rule id %d doest not exist") % rule_id) - - rules['rules']['natRulesDtos'].remove(rule_to_delete) - - header = { - 'status': 200 - } - response = '' - return (header, response) - - def get_edge_status(self, edge_id): - if edge_id not in self._edges: - raise Exception(_("Edge %s does not exist") % edge_id) - - header = { - 'status': 200 - } - response = { - 'edgeStatus': 'GREEN' - } - return (header, response) - - def get_edges(self): - header = { - 'status': 200 - } - edges = [] - for edge_id in self._edges: - edges.append({ - 'id': edge_id, - 'edgeStatus': 'GREEN' - }) - response = { - 'edgePage': { - 'data': edges - } - } - return (header, response) - - def update_routes(self, edge_id, routes): - header = { - 'status': 200 - } - response = '' - return (header, response) - - def create_lswitch(self, lsconfig): - # The lswitch is created via VCNS API so the fake nsx_api will not - # see it. Added to fake nsx_api here. - if self._fake_nsx_api: - lswitch = self._fake_nsx_api._add_lswitch(json.dumps(lsconfig)) - else: - lswitch = lsconfig - lswitch['uuid'] = uuidutils.generate_uuid() - self._lswitches[lswitch['uuid']] = lswitch - header = { - 'status': 200 - } - lswitch['_href'] = '/api/ws.v1/lswitch/%s' % lswitch['uuid'] - return (header, lswitch) - - def delete_lswitch(self, id): - if id not in self._lswitches: - raise Exception(_("Lswitch %s does not exist") % id) - del self._lswitches[id] - if self._fake_nsx_api: - # TODO(fank): fix the hack - del self._fake_nsx_api._fake_lswitch_dict[id] - header = { - 'status': 200 - } - response = '' - return (header, response) - - def update_firewall(self, edge_id, fw_req): - self.fake_firewall_dict[edge_id] = fw_req - rules = self.fake_firewall_dict[edge_id][ - 'firewallRules']['firewallRules'] - index = 10 - for rule in rules: - rule['ruleId'] = index - index += 10 - header = {'status': 204} - response = "" - return self.return_helper(header, response) - - def delete_firewall(self, edge_id): - header = {'status': 404} - if edge_id in self.fake_firewall_dict: - header = {'status': 204} - del self.fake_firewall_dict[edge_id] - response = "" - return self.return_helper(header, response) - - def update_firewall_rule(self, edge_id, vcns_rule_id, fwr_req): - if edge_id not in self.fake_firewall_dict: - raise Exception(_("Edge %s does not exist") % edge_id) - header = {'status': 404} - rules = self.fake_firewall_dict[edge_id][ - 'firewallRules']['firewallRules'] - for rule in rules: - if rule['ruleId'] == int(vcns_rule_id): - header['status'] = 204 - rule.update(fwr_req) - break - response = "" - return self.return_helper(header, response) - - def delete_firewall_rule(self, edge_id, vcns_rule_id): - if edge_id not in self.fake_firewall_dict: - raise Exception(_("Edge %s does not exist") % edge_id) - header = {'status': 404} - rules = self.fake_firewall_dict[edge_id][ - 'firewallRules']['firewallRules'] - for index in range(len(rules)): - if rules[index]['ruleId'] == int(vcns_rule_id): - header['status'] = 204 - del rules[index] - break - response = "" - return self.return_helper(header, response) - - def add_firewall_rule_above(self, edge_id, ref_vcns_rule_id, fwr_req): - if edge_id not in self.fake_firewall_dict: - raise Exception(_("Edge %s does not exist") % edge_id) - header = {'status': 404} - rules = self.fake_firewall_dict[edge_id][ - 'firewallRules']['firewallRules'] - pre = 0 - for index in range(len(rules)): - if rules[index]['ruleId'] == int(ref_vcns_rule_id): - rules.insert(index, fwr_req) - rules[index]['ruleId'] = (int(ref_vcns_rule_id) + pre) / 2 - header = { - 'status': 204, - 'location': "https://host/api/4.0/edges/edge_id/firewall" - "/config/rules/%s" % rules[index]['ruleId']} - break - pre = int(rules[index]['ruleId']) - response = "" - return self.return_helper(header, response) - - def add_firewall_rule(self, edge_id, fwr_req): - if edge_id not in self.fake_firewall_dict: - self.fake_firewall_dict[edge_id] = self.temp_firewall - rules = self.fake_firewall_dict[edge_id][ - 'firewallRules']['firewallRules'] - rules.append(fwr_req) - index = len(rules) - rules[index - 1]['ruleId'] = index * 10 - header = { - 'status': 204, - 'location': "https://host/api/4.0/edges/edge_id/firewall" - "/config/rules/%s" % rules[index - 1]['ruleId']} - response = "" - return self.return_helper(header, response) - - def get_firewall(self, edge_id): - if edge_id not in self.fake_firewall_dict: - self.fake_firewall_dict[edge_id] = self.temp_firewall - header = {'status': 204} - response = self.fake_firewall_dict[edge_id] - return self.return_helper(header, response) - - def get_firewall_rule(self, edge_id, vcns_rule_id): - if edge_id not in self.fake_firewall_dict: - raise Exception(_("Edge %s does not exist") % edge_id) - header = {'status': 404} - response = "" - rules = self.fake_firewall_dict[edge_id][ - 'firewallRules']['firewallRules'] - for rule in rules: - if rule['ruleId'] == int(vcns_rule_id): - header['status'] = 204 - response = rule - break - return self.return_helper(header, response) - - def is_name_unique(self, objs_dict, name): - return name not in [obj_dict['name'] - for obj_dict in objs_dict.values()] - - def create_vip(self, edge_id, vip_new): - header = {'status': 403} - response = "" - if not self._fake_virtualservers_dict.get(edge_id): - self._fake_virtualservers_dict[edge_id] = {} - if not self.is_name_unique(self._fake_virtualservers_dict[edge_id], - vip_new['name']): - return self.return_helper(header, response) - vip_vseid = uuidutils.generate_uuid() - self._fake_virtualservers_dict[edge_id][vip_vseid] = vip_new - header = { - 'status': 204, - 'location': "https://host/api/4.0/edges/edge_id" - "/loadbalancer/config/%s" % vip_vseid} - return self.return_helper(header, response) - - def get_vip(self, edge_id, vip_vseid): - header = {'status': 404} - response = "" - if not self._fake_virtualservers_dict.get(edge_id) or ( - not self._fake_virtualservers_dict[edge_id].get(vip_vseid)): - return self.return_helper(header, response) - header = {'status': 204} - response = self._fake_virtualservers_dict[edge_id][vip_vseid] - return self.return_helper(header, response) - - def update_vip(self, edge_id, vip_vseid, vip_new): - header = {'status': 404} - response = "" - if not self._fake_virtualservers_dict.get(edge_id) or ( - not self._fake_virtualservers_dict[edge_id].get(vip_vseid)): - return self.return_helper(header, response) - header = {'status': 204} - self._fake_virtualservers_dict[edge_id][vip_vseid].update( - vip_new) - return self.return_helper(header, response) - - def delete_vip(self, edge_id, vip_vseid): - header = {'status': 404} - response = "" - if not self._fake_virtualservers_dict.get(edge_id) or ( - not self._fake_virtualservers_dict[edge_id].get(vip_vseid)): - return self.return_helper(header, response) - header = {'status': 204} - del self._fake_virtualservers_dict[edge_id][vip_vseid] - return self.return_helper(header, response) - - def create_pool(self, edge_id, pool_new): - header = {'status': 403} - response = "" - if not self._fake_pools_dict.get(edge_id): - self._fake_pools_dict[edge_id] = {} - if not self.is_name_unique(self._fake_pools_dict[edge_id], - pool_new['name']): - return self.return_helper(header, response) - pool_vseid = uuidutils.generate_uuid() - self._fake_pools_dict[edge_id][pool_vseid] = pool_new - header = { - 'status': 204, - 'location': "https://host/api/4.0/edges/edge_id" - "/loadbalancer/config/%s" % pool_vseid} - return self.return_helper(header, response) - - def get_pool(self, edge_id, pool_vseid): - header = {'status': 404} - response = "" - if not self._fake_pools_dict.get(edge_id) or ( - not self._fake_pools_dict[edge_id].get(pool_vseid)): - return self.return_helper(header, response) - header = {'status': 204} - response = self._fake_pools_dict[edge_id][pool_vseid] - return self.return_helper(header, response) - - def update_pool(self, edge_id, pool_vseid, pool_new): - header = {'status': 404} - response = "" - if not self._fake_pools_dict.get(edge_id) or ( - not self._fake_pools_dict[edge_id].get(pool_vseid)): - return self.return_helper(header, response) - header = {'status': 204} - self._fake_pools_dict[edge_id][pool_vseid].update( - pool_new) - return self.return_helper(header, response) - - def delete_pool(self, edge_id, pool_vseid): - header = {'status': 404} - response = "" - if not self._fake_pools_dict.get(edge_id) or ( - not self._fake_pools_dict[edge_id].get(pool_vseid)): - return self.return_helper(header, response) - header = {'status': 204} - del self._fake_pools_dict[edge_id][pool_vseid] - return self.return_helper(header, response) - - def create_health_monitor(self, edge_id, monitor_new): - if not self._fake_monitors_dict.get(edge_id): - self._fake_monitors_dict[edge_id] = {} - monitor_vseid = uuidutils.generate_uuid() - self._fake_monitors_dict[edge_id][monitor_vseid] = monitor_new - header = { - 'status': 204, - 'location': "https://host/api/4.0/edges/edge_id" - "/loadbalancer/config/%s" % monitor_vseid} - response = "" - return self.return_helper(header, response) - - def get_health_monitor(self, edge_id, monitor_vseid): - header = {'status': 404} - response = "" - if not self._fake_monitors_dict.get(edge_id) or ( - not self._fake_monitors_dict[edge_id].get(monitor_vseid)): - return self.return_helper(header, response) - header = {'status': 204} - response = self._fake_monitors_dict[edge_id][monitor_vseid] - return self.return_helper(header, response) - - def update_health_monitor(self, edge_id, monitor_vseid, monitor_new): - header = {'status': 404} - response = "" - if not self._fake_monitors_dict.get(edge_id) or ( - not self._fake_monitors_dict[edge_id].get(monitor_vseid)): - return self.return_helper(header, response) - header = {'status': 204} - self._fake_monitors_dict[edge_id][monitor_vseid].update( - monitor_new) - return self.return_helper(header, response) - - def delete_health_monitor(self, edge_id, monitor_vseid): - header = {'status': 404} - response = "" - if not self._fake_monitors_dict.get(edge_id) or ( - not self._fake_monitors_dict[edge_id].get(monitor_vseid)): - return self.return_helper(header, response) - header = {'status': 204} - del self._fake_monitors_dict[edge_id][monitor_vseid] - return self.return_helper(header, response) - - def create_app_profile(self, edge_id, app_profile): - if not self._fake_app_profiles_dict.get(edge_id): - self._fake_app_profiles_dict[edge_id] = {} - app_profileid = uuidutils.generate_uuid() - self._fake_app_profiles_dict[edge_id][app_profileid] = app_profile - header = { - 'status': 204, - 'location': "https://host/api/4.0/edges/edge_id" - "/loadbalancer/config/%s" % app_profileid} - response = "" - return self.return_helper(header, response) - - def update_app_profile(self, edge_id, app_profileid, app_profile): - header = {'status': 404} - response = "" - if not self._fake_app_profiles_dict.get(edge_id) or ( - not self._fake_app_profiles_dict[edge_id].get(app_profileid)): - return self.return_helper(header, response) - header = {'status': 204} - self._fake_app_profiles_dict[edge_id][app_profileid].update( - app_profile) - return self.return_helper(header, response) - - def delete_app_profile(self, edge_id, app_profileid): - header = {'status': 404} - response = "" - if not self._fake_app_profiles_dict.get(edge_id) or ( - not self._fake_app_profiles_dict[edge_id].get(app_profileid)): - return self.return_helper(header, response) - header = {'status': 204} - del self._fake_app_profiles_dict[edge_id][app_profileid] - return self.return_helper(header, response) - - def get_loadbalancer_config(self, edge_id): - header = {'status': 204} - response = {'config': False} - if self._fake_loadbalancer_config[edge_id]: - response['config'] = self._fake_loadbalancer_config[edge_id] - return self.return_helper(header, response) - - def update_ipsec_config(self, edge_id, ipsec_config): - self.fake_ipsecvpn_dict[edge_id] = ipsec_config - header = {'status': 204} - response = "" - return self.return_helper(header, response) - - def delete_ipsec_config(self, edge_id): - header = {'status': 404} - if edge_id in self.fake_ipsecvpn_dict: - header = {'status': 204} - del self.fake_ipsecvpn_dict[edge_id] - response = "" - return self.return_helper(header, response) - - def get_ipsec_config(self, edge_id): - if edge_id not in self.fake_ipsecvpn_dict: - self.fake_ipsecvpn_dict[edge_id] = self.temp_ipsecvpn - header = {'status': 204} - response = self.fake_ipsecvpn_dict[edge_id] - return self.return_helper(header, response) - - def enable_service_loadbalancer(self, edge_id, config): - header = {'status': 204} - response = "" - self._fake_loadbalancer_config[edge_id] = True - return self.return_helper(header, response) - - def return_helper(self, header, response): - status = int(header['status']) - if 200 <= status <= 300: - return (header, response) - if status in self.errors: - cls = self.errors[status] - else: - cls = exceptions.VcnsApiException - raise cls( - status=status, header=header, uri='fake_url', response=response) - - def reset_all(self): - self._jobs.clear() - self._edges.clear() - self._lswitches.clear() - self.fake_firewall_dict = {} - self._fake_virtualservers_dict = {} - self._fake_pools_dict = {} - self._fake_monitors_dict = {} - self._fake_app_profiles_dict = {} - self._fake_loadbalancer_config = {} diff --git a/neutron/tests/unit/vmware/vshield/test_edge_router.py b/neutron/tests/unit/vmware/vshield/test_edge_router.py deleted file mode 100644 index e19de2502..000000000 --- a/neutron/tests/unit/vmware/vshield/test_edge_router.py +++ /dev/null @@ -1,308 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 copy - -from eventlet import greenthread -import mock -from oslo.config import cfg - -from neutron.api.v2 import attributes -from neutron import context -from neutron.db import l3_db -from neutron.extensions import l3 -from neutron import manager as n_manager -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants as service_constants -from neutron.plugins.vmware.common import utils -from neutron.plugins.vmware.plugins import service as nsp -from neutron.tests import base -from neutron.tests.unit import test_l3_plugin -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware import test_nsx_plugin -from neutron.tests.unit.vmware.vshield import fake_vcns - -_uuid = uuidutils.generate_uuid - - -class ServiceRouterTestExtensionManager(object): - - def get_resources(self): - # If l3 resources have been loaded and updated by main API - # router, update the map in the l3 extension so it will load - # the same attributes as the API router - l3_attr_map = copy.deepcopy(l3.RESOURCE_ATTRIBUTE_MAP) - for res in l3.RESOURCE_ATTRIBUTE_MAP.keys(): - attr_info = attributes.RESOURCE_ATTRIBUTE_MAP.get(res) - if attr_info: - l3.RESOURCE_ATTRIBUTE_MAP[res] = attr_info - resources = l3.L3.get_resources() - # restore the original resources once the controllers are created - l3.RESOURCE_ATTRIBUTE_MAP = l3_attr_map - - return resources - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class ServiceRouterTest(test_nsx_plugin.L3NatTest, - test_l3_plugin.L3NatTestCaseMixin): - - def vcns_patch(self): - instance = self.mock_vcns.start() - self.vcns_instance = instance - instance.return_value.deploy_edge.side_effect = self.fc2.deploy_edge - instance.return_value.get_edge_id.side_effect = self.fc2.get_edge_id - instance.return_value.get_edge_deploy_status.side_effect = ( - self.fc2.get_edge_deploy_status) - instance.return_value.delete_edge.side_effect = self.fc2.delete_edge - instance.return_value.update_interface.side_effect = ( - self.fc2.update_interface) - instance.return_value.get_nat_config.side_effect = ( - self.fc2.get_nat_config) - instance.return_value.update_nat_config.side_effect = ( - self.fc2.update_nat_config) - instance.return_value.delete_nat_rule.side_effect = ( - self.fc2.delete_nat_rule) - instance.return_value.get_edge_status.side_effect = ( - self.fc2.get_edge_status) - instance.return_value.get_edges.side_effect = self.fc2.get_edges - instance.return_value.update_routes.side_effect = ( - self.fc2.update_routes) - instance.return_value.create_lswitch.side_effect = ( - self.fc2.create_lswitch) - instance.return_value.delete_lswitch.side_effect = ( - self.fc2.delete_lswitch) - instance.return_value.get_loadbalancer_config.side_effect = ( - self.fc2.get_loadbalancer_config) - instance.return_value.enable_service_loadbalancer.side_effect = ( - self.fc2.enable_service_loadbalancer) - - def setUp(self, ext_mgr=None, service_plugins=None): - cfg.CONF.set_override('api_extensions_path', vmware.NSXEXT_PATH) - cfg.CONF.set_override('task_status_check_interval', 200, group="vcns") - - # vcns does not support duplicated router name, ignore router name - # validation for unit-test cases - self.fc2 = fake_vcns.FakeVcns(unique_router_name=False) - self.mock_vcns = mock.patch(vmware.VCNS_NAME, autospec=True) - self.vcns_patch() - mock_proxy = mock.patch( - "%s.%s" % (vmware.SERVICE_PLUGIN_NAME, - '_set_create_lswitch_proxy')) - mock_proxy.start() - - ext_mgr = ext_mgr or ServiceRouterTestExtensionManager() - super(ServiceRouterTest, self).setUp( - plugin=vmware.SERVICE_PLUGIN_NAME, - service_plugins=service_plugins, - ext_mgr=ext_mgr) - - self.fc2.set_fake_nsx_api(self.fc) - self.addCleanup(self.fc2.reset_all) - - def tearDown(self): - plugin = n_manager.NeutronManager.get_plugin() - manager = plugin.vcns_driver.task_manager - # wait max ~10 seconds for all tasks to be finished - for i in range(100): - if not manager.has_pending_task(): - break - greenthread.sleep(0.1) - if manager.has_pending_task(): - manager.show_pending_tasks() - raise Exception(_("Tasks not completed")) - manager.stop() - # Ensure the manager thread has been stopped - self.assertIsNone(manager._thread) - super(ServiceRouterTest, self).tearDown() - - def _create_router(self, fmt, tenant_id, name=None, - admin_state_up=None, set_context=False, - arg_list=None, **kwargs): - data = {'router': {'tenant_id': tenant_id}} - if name: - data['router']['name'] = name - if admin_state_up: - data['router']['admin_state_up'] = admin_state_up - for arg in (('admin_state_up', 'tenant_id') + (arg_list or ())): - # Arg must be present - if arg in kwargs: - data['router'][arg] = kwargs[arg] - if data['router'].get('service_router') is None: - data['router']['service_router'] = True - router_req = self.new_create_request('routers', data, fmt) - if set_context and tenant_id: - # create a specific auth context for this request - router_req.environ['neutron.context'] = context.Context( - '', tenant_id) - - return router_req.get_response(self.ext_api) - - def _create_and_get_router(self, active_set=True, **kwargs): - """Create advanced service router for services.""" - req = self._create_router(self.fmt, self._tenant_id, **kwargs) - res = self.deserialize(self.fmt, req) - router_id = res['router']['id'] - # manually set router status ACTIVE to pass through the router check, - # else mimic router creation ERROR condition. - status = (service_constants.ACTIVE if active_set - else service_constants.ERROR) - self.plugin._resource_set_status( - context.get_admin_context(), - l3_db.Router, - router_id, - status) - return router_id - - -class ServiceRouterTestCase(ServiceRouterTest, - test_nsx_plugin.TestL3NatTestCase): - - def test_router_create(self): - name = 'router1' - tenant_id = _uuid() - expected_value = [('name', name), ('tenant_id', tenant_id), - ('admin_state_up', True), - ('external_gateway_info', None), - ('service_router', True)] - with self.router(name=name, admin_state_up=True, - tenant_id=tenant_id) as router: - expected_value_1 = expected_value + [('status', 'PENDING_CREATE')] - for k, v in expected_value_1: - self.assertEqual(router['router'][k], v) - - # wait max ~10 seconds for router status update - for i in range(20): - greenthread.sleep(0.5) - res = self._show('routers', router['router']['id']) - if res['router']['status'] == 'ACTIVE': - break - expected_value_2 = expected_value + [('status', 'ACTIVE')] - for k, v in expected_value_2: - self.assertEqual(res['router'][k], v) - - # check an integration lswitch is created - lswitch_name = "%s-ls" % name - for lswitch_id, lswitch in self.fc2._lswitches.iteritems(): - if lswitch['display_name'] == lswitch_name: - break - else: - self.fail("Integration lswitch not found") - - # check an integration lswitch is deleted - lswitch_name = "%s-ls" % name - for lswitch_id, lswitch in self.fc2._lswitches.iteritems(): - if lswitch['display_name'] == lswitch_name: - self.fail("Integration switch is not deleted") - - def test_router_delete_after_plugin_restart(self): - name = 'router1' - tenant_id = _uuid() - with self.router(name=name, admin_state_up=True, - tenant_id=tenant_id): - # clear router type cache to mimic plugin restart - plugin = n_manager.NeutronManager.get_plugin() - plugin._router_type = {} - - # check an integration lswitch is deleted - lswitch_name = "%s-ls" % name - for lswitch_id, lswitch in self.fc2._lswitches.iteritems(): - if lswitch['display_name'] == lswitch_name: - self.fail("Integration switch is not deleted") - - def test_router_show(self): - name = 'router1' - tenant_id = _uuid() - expected_value = [('name', name), ('tenant_id', tenant_id), - ('admin_state_up', True), - ('status', 'PENDING_CREATE'), - ('external_gateway_info', None), - ('service_router', True)] - with self.router(name='router1', admin_state_up=True, - tenant_id=tenant_id) as router: - res = self._show('routers', router['router']['id']) - for k, v in expected_value: - self.assertEqual(res['router'][k], v) - - def _test_router_create_with_gwinfo_and_l3_ext_net(self, vlan_id=None): - super(ServiceRouterTestCase, - self)._test_router_create_with_gwinfo_and_l3_ext_net( - vlan_id, validate_ext_gw=False) - - def _test_router_update_gateway_on_l3_ext_net(self, vlan_id=None): - super(ServiceRouterTestCase, - self)._test_router_update_gateway_on_l3_ext_net( - vlan_id, validate_ext_gw=False) - - -class TestProxyCreateLswitch(base.BaseTestCase): - def setUp(self): - super(TestProxyCreateLswitch, self).setUp() - self.tenant_id = "foo_tenant" - self.display_name = "foo_network" - self.tz_config = [ - {'zone_uuid': 'foo_zone', - 'transport_type': 'stt'} - ] - self.tags = utils.get_tags(quantum_net_id='foo_id', - os_tid=self.tenant_id) - self.cluster = None - - def test_create_lswitch_with_basic_args(self): - result = nsp._process_base_create_lswitch_args(self.cluster, - 'foo_id', - self.tenant_id, - self.display_name, - self.tz_config) - self.assertEqual(self.display_name, result[0]) - self.assertEqual(self.tz_config, result[1]) - self.assertEqual(sorted(self.tags), sorted(result[2])) - - def test_create_lswitch_with_shared_as_kwarg(self): - result = nsp._process_base_create_lswitch_args(self.cluster, - 'foo_id', - self.tenant_id, - self.display_name, - self.tz_config, - shared=True) - expected = self.tags + [{'scope': 'shared', 'tag': 'true'}] - self.assertEqual(sorted(expected), sorted(result[2])) - - def test_create_lswitch_with_shared_as_arg(self): - result = nsp._process_base_create_lswitch_args(self.cluster, - 'foo_id', - self.tenant_id, - self.display_name, - self.tz_config, - True) - additional_tags = [{'scope': 'shared', 'tag': 'true'}] - expected = self.tags + additional_tags - self.assertEqual(sorted(expected), sorted(result[2])) - - def test_create_lswitch_with_additional_tags(self): - more_tags = [{'scope': 'foo_scope', 'tag': 'foo_tag'}] - result = nsp._process_base_create_lswitch_args(self.cluster, - 'foo_id', - self.tenant_id, - self.display_name, - self.tz_config, - tags=more_tags) - expected = self.tags + more_tags - self.assertEqual(sorted(expected), sorted(result[2])) diff --git a/neutron/tests/unit/vmware/vshield/test_firewall_driver.py b/neutron/tests/unit/vmware/vshield/test_firewall_driver.py deleted file mode 100644 index 0002ab97d..000000000 --- a/neutron/tests/unit/vmware/vshield/test_firewall_driver.py +++ /dev/null @@ -1,375 +0,0 @@ -# Copyright 2013 VMware, Inc -# -# 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 contextlib -import mock -import webob.exc - -from neutron import context -from neutron.db.firewall import firewall_db -from neutron.openstack.common import uuidutils -from neutron.plugins.vmware.vshield.common import exceptions as vcns_exc -from neutron.plugins.vmware.vshield import vcns_driver -from neutron.tests.unit.db.firewall import test_db_firewall -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.vshield import fake_vcns - - -_uuid = uuidutils.generate_uuid - -VSE_ID = 'edge-1' -ROUTER_ID = '42f95450-5cc9-44e4-a744-1320e592a9d5' - -VCNS_CONFIG_FILE = vmware.get_fake_conf("vcns.ini.test") - - -class VcnsDriverTestCase(test_db_firewall.FirewallPluginDbTestCase, - firewall_db.Firewall_db_mixin): - - def vcns_firewall_patch(self): - instance = self.mock_vcns.start() - instance.return_value.update_firewall.side_effect = ( - self.fc2.update_firewall) - instance.return_value.delete_firewall.side_effect = ( - self.fc2.delete_firewall) - instance.return_value.update_firewall_rule.side_effect = ( - self.fc2.update_firewall_rule) - instance.return_value.delete_firewall_rule.side_effect = ( - self.fc2.delete_firewall_rule) - instance.return_value.add_firewall_rule_above.side_effect = ( - self.fc2.add_firewall_rule_above) - instance.return_value.add_firewall_rule.side_effect = ( - self.fc2.add_firewall_rule) - instance.return_value.get_firewall.side_effect = ( - self.fc2.get_firewall) - instance.return_value.get_firewall_rule.side_effect = ( - self.fc2.get_firewall_rule) - - def setUp(self): - - self.config_parse(args=['--config-file', VCNS_CONFIG_FILE]) - # mock vcns - self.fc2 = fake_vcns.FakeVcns(unique_router_name=False) - self.mock_vcns = mock.patch(vmware.VCNS_NAME, autospec=True) - self.vcns_firewall_patch() - - self.driver = vcns_driver.VcnsDriver(mock.Mock()) - - super(VcnsDriverTestCase, self).setUp() - self.addCleanup(self.fc2.reset_all) - self.addCleanup(self.mock_vcns.stop) - - self.tenant_id = _uuid() - self.subnet_id = _uuid() - - -class TestEdgeFwDriver(VcnsDriverTestCase): - - def _make_firewall_dict_with_rules(self, context, firewall_id): - fw = self.get_firewall(context, firewall_id) - fw_policy_id = fw['firewall_policy_id'] - if fw_policy_id: - firewall_policy_db = self._get_firewall_policy( - context, fw_policy_id) - fw['firewall_rule_list'] = [ - self._make_firewall_rule_dict(fw_rule_db) - for fw_rule_db in firewall_policy_db['firewall_rules'] - ] - - return fw - - def _compare_firewall_rule_lists(self, firewall_policy_id, - list1, list2): - for r1, r2 in zip(list1, list2): - rule = r1['firewall_rule'] - rule['firewall_policy_id'] = firewall_policy_id - for k in rule: - self.assertEqual(rule[k], r2[k]) - - def test_create_and_get_firewall(self): - ctx = context.get_admin_context() - name = 'firewall' - with contextlib.nested(self.firewall_rule(name='fwr1', - no_delete=True), - self.firewall_rule(name='fwr2', - no_delete=True), - self.firewall_rule(name='fwr3', - no_delete=True)) as fr: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - with self.firewall_policy(firewall_rules=fw_rule_ids, - no_delete=True) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name=name, - firewall_policy_id=fwp_id) as firewall: - fw_create = firewall['firewall'] - fw_expect = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - self.driver.update_firewall(ctx, VSE_ID, fw_expect) - fw_get = self.driver.get_firewall(ctx, VSE_ID) - self._compare_firewall_rule_lists( - fwp_id, fw_get['firewall_rule_list'], - fw_expect['firewall_rule_list']) - - def test_update_firewall_with_rules(self): - ctx = context.get_admin_context() - name = 'new_firewall' - with contextlib.nested(self.firewall_rule(name='fwr1', - no_delete=True), - self.firewall_rule(name='fwr2', - no_delete=True), - self.firewall_rule(name='fwr3', - no_delete=True)) as fr: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - with self.firewall_policy(firewall_rules=fw_rule_ids, - no_delete=True) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name=name, - firewall_policy_id=fwp_id) as firewall: - fw_create = firewall['firewall'] - fw_create = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - self.driver.update_firewall(ctx, VSE_ID, fw_create) - - data = {'firewall_rule': {'name': name, - 'source_port': '10:20', - 'destination_port': '30:40'}} - self.new_update_request('firewall_rules', data, - fr[0]['firewall_rule']['id']) - fw_expect = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - self.driver.update_firewall(ctx, VSE_ID, fw_expect) - - fw_get = self.driver.get_firewall( - ctx, VSE_ID) - self._compare_firewall_rule_lists( - fwp_id, fw_get['firewall_rule_list'], - fw_expect['firewall_rule_list']) - - def test_delete_firewall(self): - ctx = context.get_admin_context() - name = 'firewall' - with contextlib.nested(self.firewall_rule(name='fwr1', - no_delete=True), - self.firewall_rule(name='fwr2', - no_delete=True), - self.firewall_rule(name='fwr3', - no_delete=True)) as fr: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - with self.firewall_policy(firewall_rules=fw_rule_ids, - no_delete=True) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name=name, - firewall_policy_id=fwp_id) as firewall: - fw_create = firewall['firewall'] - fw_expect = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - self.driver.update_firewall(ctx, VSE_ID, fw_expect) - self.driver.delete_firewall(ctx, VSE_ID) - fw_get = self.driver.get_firewall( - ctx, VSE_ID) - self.assertFalse(fw_get['firewall_rule_list']) - - def test_update_firewall_rule(self): - ctx = context.get_admin_context() - name = 'new_firewall' - with contextlib.nested(self.firewall_rule(name='fwr1', - no_delete=True)) as fr: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - with self.firewall_policy(firewall_rules=fw_rule_ids, - no_delete=True) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name=name, - firewall_policy_id=fwp_id) as firewall: - fw_create = firewall['firewall'] - fw_create = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - self.driver.update_firewall(ctx, VSE_ID, fw_create) - - data = {'firewall_rule': {'name': name, - 'source_port': '10:20', - 'destination_port': '30:40'}} - req = self.new_update_request( - 'firewall_rules', data, - fr[0]['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - rule_expect = res['firewall_rule'] - rule_expect['edge_id'] = VSE_ID - self.driver.update_firewall_rule( - ctx, rule_expect['id'], VSE_ID, rule_expect) - rule_get = self.driver.get_firewall_rule( - ctx, rule_expect['id'], VSE_ID) - for k, v in rule_get['firewall_rule'].items(): - self.assertEqual(rule_expect[k], v) - - def test_delete_firewall_rule(self): - ctx = context.get_admin_context() - name = 'new_firewall' - with contextlib.nested(self.firewall_rule(name='fwr1', - no_delete=True), - self.firewall_rule(name='fwr2', - no_delete=True)) as fr: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - with self.firewall_policy(firewall_rules=fw_rule_ids, - no_delete=True) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name=name, - firewall_policy_id=fwp_id) as firewall: - fw_create = firewall['firewall'] - fw_create = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - self.driver.update_firewall(ctx, VSE_ID, fw_create) - - fr[0]['firewall_rule']['edge_id'] = VSE_ID - self.driver.delete_firewall_rule( - ctx, fr[0]['firewall_rule']['id'], - VSE_ID) - self.assertRaises(vcns_exc.VcnsNotFound, - self.driver.get_firewall_rule, - ctx, fr[0]['firewall_rule']['id'], - VSE_ID) - - def test_insert_rule(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id) as firewall: - fw_create = firewall['firewall'] - fw_create = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - self.driver.update_firewall(ctx, VSE_ID, fw_create) - with contextlib.nested(self.firewall_rule(name='fwr0', - no_delete=True), - self.firewall_rule(name='fwr1', - no_delete=True), - self.firewall_rule(name='fwr2', - no_delete=True), - self.firewall_rule(name='fwr3', - no_delete=True), - self.firewall_rule(name='fwr4', - no_delete=True), - self.firewall_rule(name='fwr5', - no_delete=True), - self.firewall_rule( - name='fwr6', - no_delete=True)) as fwr: - # test insert when rule list is empty - fwr0_id = fwr[0]['firewall_rule']['id'] - self._rule_action('insert', fwp_id, fwr0_id, - insert_before=None, - insert_after=None, - expected_code=webob.exc.HTTPOk.code) - fw_update = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - self.driver.update_firewall(ctx, VSE_ID, fw_update) - # test insert at top of list above existing rule - fwr1_id = fwr[1]['firewall_rule']['id'] - self._rule_action('insert', fwp_id, fwr1_id, - insert_before=fwr0_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code) - - fw_expect = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - - rule_info = {'firewall_rule_id': fwr1_id, - 'insert_before': fwr0_id, - 'insert_after': None} - rule = fwr[1]['firewall_rule'] - self.driver.insert_rule(ctx, rule_info, VSE_ID, rule) - fw_get = self.driver.get_firewall( - ctx, VSE_ID) - self._compare_firewall_rule_lists( - fwp_id, fw_get['firewall_rule_list'], - fw_expect['firewall_rule_list']) - # test insert at bottom of list - fwr2_id = fwr[2]['firewall_rule']['id'] - self._rule_action('insert', fwp_id, fwr2_id, - insert_before=None, - insert_after=fwr0_id, - expected_code=webob.exc.HTTPOk.code) - fw_expect = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - - rule_info = {'firewall_rule_id': fwr2_id, - 'insert_before': None, - 'insert_after': fwr0_id} - rule = fwr[2]['firewall_rule'] - self.driver.insert_rule(ctx, rule_info, VSE_ID, rule) - fw_get = self.driver.get_firewall( - ctx, VSE_ID) - self._compare_firewall_rule_lists( - fwp_id, fw_get['firewall_rule_list'], - fw_expect['firewall_rule_list']) - # test insert in the middle of the list using - # insert_before - fwr3_id = fwr[3]['firewall_rule']['id'] - self._rule_action('insert', fwp_id, fwr3_id, - insert_before=fwr2_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code) - fw_expect = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - - rule_info = {'firewall_rule_id': fwr3_id, - 'insert_before': fwr2_id, - 'insert_after': None} - rule = fwr[3]['firewall_rule'] - self.driver.insert_rule(ctx, rule_info, VSE_ID, rule) - fw_get = self.driver.get_firewall( - ctx, VSE_ID) - self._compare_firewall_rule_lists( - fwp_id, fw_get['firewall_rule_list'], - fw_expect['firewall_rule_list']) - # test insert in the middle of the list using - # insert_after - fwr4_id = fwr[4]['firewall_rule']['id'] - self._rule_action('insert', fwp_id, fwr4_id, - insert_before=None, - insert_after=fwr3_id, - expected_code=webob.exc.HTTPOk.code) - fw_expect = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - - rule_info = {'firewall_rule_id': fwr4_id, - 'insert_before': None, - 'insert_after': fwr3_id} - rule = fwr[4]['firewall_rule'] - self.driver.insert_rule(ctx, rule_info, VSE_ID, rule) - fw_get = self.driver.get_firewall( - ctx, VSE_ID) - self._compare_firewall_rule_lists( - fwp_id, fw_get['firewall_rule_list'], - fw_expect['firewall_rule_list']) - # test insert when both insert_before and - # insert_after are set - fwr5_id = fwr[5]['firewall_rule']['id'] - self._rule_action('insert', fwp_id, fwr5_id, - insert_before=fwr4_id, - insert_after=fwr4_id, - expected_code=webob.exc.HTTPOk.code) - fw_expect = self._make_firewall_dict_with_rules( - ctx, fw_create['id']) - - rule_info = {'firewall_rule_id': fwr5_id, - 'insert_before': fwr4_id, - 'insert_after': fwr4_id} - rule = fwr[5]['firewall_rule'] - self.driver.insert_rule(ctx, rule_info, VSE_ID, rule) - fw_get = self.driver.get_firewall( - ctx, VSE_ID) - self._compare_firewall_rule_lists( - fwp_id, fw_get['firewall_rule_list'], - fw_expect['firewall_rule_list']) diff --git a/neutron/tests/unit/vmware/vshield/test_fwaas_plugin.py b/neutron/tests/unit/vmware/vshield/test_fwaas_plugin.py deleted file mode 100644 index 282e4a80f..000000000 --- a/neutron/tests/unit/vmware/vshield/test_fwaas_plugin.py +++ /dev/null @@ -1,697 +0,0 @@ -# Copyright 2013 VMware, Inc -# All Rights Reserved -# -# 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 contextlib -import copy -import webob.exc - -from neutron.api.v2 import attributes -from neutron import context -from neutron.extensions import firewall -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron.plugins.common import constants as const -from neutron.tests.unit.db.firewall import test_db_firewall -from neutron.tests.unit.vmware.vshield import test_edge_router - -_uuid = uuidutils.generate_uuid - -FW_PLUGIN_CLASS = "neutron.plugins.vmware.plugin.NsxServicePlugin" - - -class FirewallTestExtensionManager( - test_edge_router.ServiceRouterTestExtensionManager): - - def get_resources(self): - # If l3 resources have been loaded and updated by main API - # router, update the map in the l3 extension so it will load - # the same attributes as the API router - resources = super(FirewallTestExtensionManager, self).get_resources() - firewall_attr_map = copy.deepcopy(firewall.RESOURCE_ATTRIBUTE_MAP) - for res in firewall.RESOURCE_ATTRIBUTE_MAP.keys(): - attr_info = attributes.RESOURCE_ATTRIBUTE_MAP.get(res) - if attr_info: - firewall.RESOURCE_ATTRIBUTE_MAP[res] = attr_info - fw_resources = firewall.Firewall.get_resources() - # restore the original resources once the controllers are created - firewall.RESOURCE_ATTRIBUTE_MAP = firewall_attr_map - - resources.extend(fw_resources) - - return resources - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class FirewallPluginTestCase(test_db_firewall.FirewallPluginDbTestCase, - test_edge_router.ServiceRouterTest): - - def vcns_firewall_patch(self): - self.vcns_instance.return_value.update_firewall.side_effect = ( - self.fc2.update_firewall) - self.vcns_instance.return_value.delete_firewall.side_effect = ( - self.fc2.delete_firewall) - self.vcns_instance.return_value.update_firewall_rule.side_effect = ( - self.fc2.update_firewall_rule) - self.vcns_instance.return_value.delete_firewall_rule.side_effect = ( - self.fc2.delete_firewall_rule) - self.vcns_instance.return_value.add_firewall_rule_above.side_effect = ( - self.fc2.add_firewall_rule_above) - self.vcns_instance.return_value.add_firewall_rule.side_effect = ( - self.fc2.add_firewall_rule) - self.vcns_instance.return_value.get_firewall.side_effect = ( - self.fc2.get_firewall) - self.vcns_instance.return_value.get_firewall_rule.side_effect = ( - self.fc2.get_firewall_rule) - - def setUp(self): - # Save the global RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - - super(FirewallPluginTestCase, self).setUp( - ext_mgr=FirewallTestExtensionManager(), - fw_plugin=FW_PLUGIN_CLASS) - self.vcns_firewall_patch() - self.plugin = manager.NeutronManager.get_plugin() - - def tearDown(self): - super(FirewallPluginTestCase, self).tearDown() - # Restore the global RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - self.ext_api = None - self.plugin = None - - def _create_firewall(self, fmt, name, description, firewall_policy_id, - admin_state_up=True, expected_res_status=None, - **kwargs): - data = {'firewall': {'name': name, - 'description': description, - 'firewall_policy_id': firewall_policy_id, - 'router_id': kwargs.get('router_id'), - 'admin_state_up': admin_state_up, - 'tenant_id': self._tenant_id}} - - firewall_req = self.new_create_request('firewalls', data, fmt) - firewall_res = firewall_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(firewall_res.status_int, expected_res_status) - - return firewall_res - - def test_create_firewall(self): - name = "new_fw" - attrs = self._get_test_firewall_attrs(name) - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - attrs['router_id'] = self._create_and_get_router() - with self.firewall(name=name, - firewall_policy_id=fwp_id, - router_id=attrs['router_id'], - admin_state_up= - test_db_firewall.ADMIN_STATE_UP, - expected_res_status=201) as fw: - attrs = self._replace_firewall_status( - attrs, const.PENDING_CREATE, const.ACTIVE) - for k, v in attrs.iteritems(): - self.assertEqual(fw['firewall'][k], v) - - def test_create_firewall_without_policy(self, **kwargs): - name = "new_fw" - attrs = self._get_test_firewall_attrs(name) - if 'router_id' in kwargs: - attrs['router_id'] = kwargs.pop('router_id') - else: - attrs['router_id'] = self._create_and_get_router() - - with self.firewall(name=name, - router_id=attrs['router_id'], - admin_state_up= - test_db_firewall.ADMIN_STATE_UP, - **kwargs) as fw: - attrs = self._replace_firewall_status( - attrs, const.PENDING_CREATE, const.ACTIVE) - for k, v in attrs.iteritems(): - self.assertEqual(fw['firewall'][k], v) - - def test_create_firewall_with_invalid_router(self): - name = "new_fw" - attrs = self._get_test_firewall_attrs(name) - attrs['router_id'] = self._create_and_get_router() - self.assertRaises(webob.exc.HTTPClientError, - self.test_create_firewall_without_policy, - router_id=None) - self.assertRaises(webob.exc.HTTPClientError, - self.test_create_firewall_without_policy, - router_id='invalid_id') - - router_id = self._create_and_get_router( - arg_list=('service_router',), service_router=False) - self.assertRaises(webob.exc.HTTPClientError, - self.test_create_firewall_without_policy, - router_id=router_id) - - router_id = self._create_and_get_router(active_set=False) - self.assertRaises(webob.exc.HTTPClientError, - self.test_create_firewall_without_policy, - router_id=router_id) - - def test_update_firewall(self): - name = "new_fw" - attrs = self._get_test_firewall_attrs(name) - attrs['router_id'] = self._create_and_get_router() - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - firewall_policy_id=fwp_id, router_id=attrs['router_id'], - admin_state_up=test_db_firewall.ADMIN_STATE_UP) as fw: - fw_id = fw['firewall']['id'] - new_data = {'firewall': {'name': name}} - req = self.new_update_request('firewalls', new_data, fw_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 200) - res_json = self.deserialize( - self.fmt, res) - attrs = self._replace_firewall_status( - attrs, const.PENDING_CREATE, const.ACTIVE) - for k, v in attrs.iteritems(): - self.assertEqual(res_json['firewall'][k], v) - - def test_delete_firewall(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall( - firewall_policy_id=fwp_id, - router_id=self._create_and_get_router(), - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - no_delete=True) as fw: - fw_id = fw['firewall']['id'] - with ctx.session.begin(subtransactions=True): - req = self.new_delete_request('firewalls', fw_id) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - self.assertRaises( - firewall.FirewallNotFound, - self.plugin.get_firewall, ctx, fw_id) - - def test_delete_router_in_use_by_fwservice(self): - router_id = self._create_and_get_router() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name='fw', - firewall_policy_id=fwp_id, - router_id=router_id, - admin_state_up= - test_db_firewall.ADMIN_STATE_UP, - expected_res_status=201): - self._delete('routers', router_id, - expected_code=webob.exc.HTTPConflict.code) - - def test_show_firewall(self): - name = "firewall1" - attrs = self._get_test_firewall_attrs(name) - attrs['router_id'] = self._create_and_get_router() - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - name=name, - firewall_policy_id=fwp_id, router_id=attrs['router_id'], - admin_state_up=test_db_firewall.ADMIN_STATE_UP) as firewall: - - req = self.new_show_request('firewalls', - firewall['firewall']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs = self._replace_firewall_status( - attrs, const.PENDING_CREATE, const.ACTIVE) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall'][k], v) - - def test_list_firewalls(self): - keys_list = [] - for i in range(3): - keys_list.append({'name': "fw" + str(i), - 'router_id': self._create_and_get_router(), - 'admin_state_up': True, - 'status': "ACTIVE"}) - - with contextlib.nested( - self.firewall( - name='fw0', router_id=keys_list[0]['router_id'], - admin_state_up=True, description='fw'), - self.firewall( - name='fw1', router_id=keys_list[1]['router_id'], - admin_state_up=True, description='fw'), - self.firewall( - name='fw2', router_id=keys_list[2]['router_id'], - admin_state_up=True, description='fw'), - ) as (fw1, fw2, fw3): - self._test_list_resources( - 'firewall', (fw1, fw2, fw3), - query_params='description=fw') - - req = self.new_list_request('firewalls') - res = self.deserialize( - self.fmt, req.get_response(self.ext_api)) - self.assertEqual(len(res['firewalls']), 3) - for index in range(len(res['firewalls'])): - for k, v in keys_list[index].items(): - self.assertEqual(res['firewalls'][index][k], v) - - def test_create_firewall_with_rules(self): - ctx = context.get_admin_context() - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as fr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request( - 'firewall_policies', data, fwp_id) - req.get_response(self.ext_api) - attrs = self._get_test_firewall_attrs() - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - firewall_policy_id=fwp_id, - router_id=self._create_and_get_router(), - admin_state_up=test_db_firewall.ADMIN_STATE_UP) as fw: - rule_list = ( - self.plugin._make_firewall_rule_list_by_policy_id( - ctx, fw['firewall']['firewall_policy_id'])) - self._compare_firewall_rule_lists( - fwp_id, fr, rule_list) - - def test_update_firewall_policy_with_no_firewall(self): - name = "new_firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name) - - with self.firewall_policy(shared=test_db_firewall.SHARED, - firewall_rules=None, - audited=test_db_firewall.AUDITED) as fwp: - data = {'firewall_policy': {'name': name}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_policy'][k], v) - - def test_update_firewall_policy_with_firewall(self): - name = "new_firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name) - - with self.firewall_policy(shared=test_db_firewall.SHARED, - firewall_rules=None, - audited=test_db_firewall.AUDITED) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - router_id=self._create_and_get_router(), - admin_state_up= - test_db_firewall.ADMIN_STATE_UP): - data = {'firewall_policy': {'name': name}} - req = self.new_update_request( - 'firewall_policies', data, fwp['firewall_policy']['id']) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_policy'][k], v) - - def test_update_firewall_rule_with_no_firewall(self): - name = "new_firewall_rule1" - attrs = self._get_test_firewall_rule_attrs(name) - - attrs['source_port'] = '10:20' - attrs['destination_port'] = '30:40' - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'source_port': '10:20', - 'destination_port': '30:40'}} - req = self.new_update_request( - 'firewall_rules', data, fwr['firewall_rule']['id']) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - attrs['source_port'] = '10000' - attrs['destination_port'] = '80' - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'source_port': 10000, - 'destination_port': 80}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - attrs['source_port'] = None - attrs['destination_port'] = None - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'source_port': None, - 'destination_port': None}} - req = self.new_update_request( - 'firewall_rules', data, fwr['firewall_rule']['id']) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api)) - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - def test_update_firewall_rule_with_firewall(self): - name = "new_firewall_rule1" - attrs = self._get_test_firewall_rule_attrs(name) - with self.firewall_rule() as fwr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall(firewall_policy_id=fwp_id, - router_id=self._create_and_get_router(), - admin_state_up= - test_db_firewall.ADMIN_STATE_UP): - fwr_id = fwr['firewall_rule']['id'] - data = {'firewall_policy': {'firewall_rules': [fwr_id]}} - req = self.new_update_request( - 'firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - data = {'firewall_rule': {'name': name}} - req = self.new_update_request( - 'firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api)) - attrs['firewall_policy_id'] = fwp_id - for k, v in attrs.iteritems(): - self.assertEqual(res['firewall_rule'][k], v) - - def test_insert_rule_with_no_firewall(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with contextlib.nested(self.firewall_rule(name='fwr0'), - self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3'), - self.firewall_rule(name='fwr4'), - self.firewall_rule(name='fwr5'), - self.firewall_rule(name='fwr6')) as fwr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - # test insert when rule list is empty - fwr0_id = fwr[0]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr0_id) - self._rule_action('insert', fwp_id, fwr0_id, - insert_before=None, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert at top of rule list, insert_before and - # insert_after not provided - fwr1_id = fwr[1]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr1_id) - insert_data = {'firewall_rule_id': fwr1_id} - self._rule_action('insert', fwp_id, fwr0_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs, body_data=insert_data) - # test insert at top of list above existing rule - fwr2_id = fwr[2]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr2_id) - self._rule_action('insert', fwp_id, fwr2_id, - insert_before=fwr1_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert at bottom of list - fwr3_id = fwr[3]['firewall_rule']['id'] - attrs['firewall_rules'].append(fwr3_id) - self._rule_action('insert', fwp_id, fwr3_id, - insert_before=None, - insert_after=fwr0_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert in the middle of the list using - # insert_before - fwr4_id = fwr[4]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr4_id) - self._rule_action('insert', fwp_id, fwr4_id, - insert_before=fwr1_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert in the middle of the list using - # insert_after - fwr5_id = fwr[5]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr5_id) - self._rule_action('insert', fwp_id, fwr5_id, - insert_before=None, - insert_after=fwr2_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert when both insert_before and - # insert_after are set - fwr6_id = fwr[6]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr6_id) - self._rule_action('insert', fwp_id, fwr6_id, - insert_before=fwr5_id, - insert_after=fwr5_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - - def test_insert_rule_with_firewall(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with contextlib.nested(self.firewall_rule(name='fwr0'), - self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3'), - self.firewall_rule(name='fwr4'), - self.firewall_rule(name='fwr5'), - self.firewall_rule(name='fwr6')) as fwr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - with self.firewall(router_id=self._create_and_get_router(), - firewall_policy_id=fwp_id) as fw: - # test insert when rule list is empty - fwr0_id = fwr[0]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr0_id) - attrs['firewall_list'].insert(0, fw['firewall']['id']) - self._rule_action('insert', fwp_id, fwr0_id, - insert_before=None, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert at top of rule list, insert_before and - # insert_after not provided - fwr1_id = fwr[1]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr1_id) - insert_data = {'firewall_rule_id': fwr1_id} - self._rule_action( - 'insert', fwp_id, fwr0_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs, body_data=insert_data) - # test insert at top of list above existing rule - fwr2_id = fwr[2]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr2_id) - self._rule_action('insert', fwp_id, fwr2_id, - insert_before=fwr1_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert at bottom of list - fwr3_id = fwr[3]['firewall_rule']['id'] - attrs['firewall_rules'].append(fwr3_id) - self._rule_action('insert', fwp_id, fwr3_id, - insert_before=None, - insert_after=fwr0_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert in the middle of the list using - # insert_before - fwr4_id = fwr[4]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr4_id) - self._rule_action('insert', fwp_id, fwr4_id, - insert_before=fwr1_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert in the middle of the list using - # insert_after - fwr5_id = fwr[5]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr5_id) - self._rule_action('insert', fwp_id, fwr5_id, - insert_before=None, - insert_after=fwr2_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert when both insert_before and - # insert_after are set - fwr6_id = fwr[6]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr6_id) - self._rule_action('insert', fwp_id, fwr6_id, - insert_before=fwr5_id, - insert_after=fwr5_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - - def test_remove_rule_with_no_firewall(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as fr1: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr1] - attrs['firewall_rules'] = fw_rule_ids[:] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - # test removing a rule from a policy that does not exist - self._rule_action('remove', '123', fw_rule_ids[1], - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None) - # test removing a rule in the middle of the list - attrs['firewall_rules'].remove(fw_rule_ids[1]) - self._rule_action('remove', fwp_id, fw_rule_ids[1], - expected_body=attrs) - # test removing a rule at the top of the list - attrs['firewall_rules'].remove(fw_rule_ids[0]) - self._rule_action('remove', fwp_id, fw_rule_ids[0], - expected_body=attrs) - # test removing remaining rule in the list - attrs['firewall_rules'].remove(fw_rule_ids[2]) - self._rule_action('remove', fwp_id, fw_rule_ids[2], - expected_body=attrs) - # test removing rule that is not associated with the policy - self._rule_action('remove', fwp_id, fw_rule_ids[2], - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None) - - def test_remove_rule_with_firewall(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - with self.firewall(router_id=self._create_and_get_router(), - firewall_policy_id=fwp_id) as fw: - attrs['firewall_list'].insert(0, fw['firewall']['id']) - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as fr1: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr1] - attrs['firewall_rules'] = fw_rule_ids[:] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request( - 'firewall_policies', data, fwp_id) - req.get_response(self.ext_api) - # test removing a rule from a policy that does not exist - self._rule_action( - 'remove', '123', - fw_rule_ids[1], - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None) - # test removing a rule in the middle of the list - attrs['firewall_rules'].remove(fw_rule_ids[1]) - self._rule_action('remove', fwp_id, fw_rule_ids[1], - expected_body=attrs) - # test removing a rule at the top of the list - attrs['firewall_rules'].remove(fw_rule_ids[0]) - self._rule_action('remove', fwp_id, fw_rule_ids[0], - expected_body=attrs) - # test removing remaining rule in the list - attrs['firewall_rules'].remove(fw_rule_ids[2]) - self._rule_action('remove', fwp_id, fw_rule_ids[2], - expected_body=attrs) - # test removing rule that is not - #associated with the policy - self._rule_action( - 'remove', fwp_id, fw_rule_ids[2], - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None) - - def test_remove_rule_with_firewalls(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - with contextlib.nested( - self.firewall(router_id=self._create_and_get_router(), - firewall_policy_id=fwp_id), - self.firewall(router_id=self._create_and_get_router(), - firewall_policy_id=fwp_id)) as (fw1, fw2): - attrs['firewall_list'].insert(0, fw1['firewall']['id']) - attrs['firewall_list'].insert(1, fw2['firewall']['id']) - with contextlib.nested(self.firewall_rule(name='fwr1'), - self.firewall_rule(name='fwr2'), - self.firewall_rule(name='fwr3')) as fr1: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr1] - attrs['firewall_rules'] = fw_rule_ids[:] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request( - 'firewall_policies', data, fwp_id) - req.get_response(self.ext_api) - # test removing a rule from a policy that does not exist - self._rule_action( - 'remove', '123', - fw_rule_ids[1], - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None) - # test removing a rule in the middle of the list - attrs['firewall_rules'].remove(fw_rule_ids[1]) - self._rule_action('remove', fwp_id, fw_rule_ids[1], - expected_body=attrs) - # test removing a rule at the top of the list - attrs['firewall_rules'].remove(fw_rule_ids[0]) - self._rule_action('remove', fwp_id, fw_rule_ids[0], - expected_body=attrs) - # test removing remaining rule in the list - attrs['firewall_rules'].remove(fw_rule_ids[2]) - self._rule_action('remove', fwp_id, fw_rule_ids[2], - expected_body=attrs) - # test removing rule that is not - #associated with the policy - self._rule_action( - 'remove', fwp_id, fw_rule_ids[2], - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None) diff --git a/neutron/tests/unit/vmware/vshield/test_lbaas_plugin.py b/neutron/tests/unit/vmware/vshield/test_lbaas_plugin.py deleted file mode 100644 index fdb0be434..000000000 --- a/neutron/tests/unit/vmware/vshield/test_lbaas_plugin.py +++ /dev/null @@ -1,532 +0,0 @@ -# Copyright 2013 VMware, Inc -# -# 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 contextlib - -import testtools -from webob import exc as web_exc - -from neutron.api.v2 import attributes -from neutron import context -from neutron.extensions import loadbalancer as lb -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron.tests.unit.db.loadbalancer import test_db_loadbalancer -from neutron.tests.unit.vmware.vshield import test_edge_router - -_uuid = uuidutils.generate_uuid - -LBAAS_PLUGIN_CLASS = "neutron.plugins.vmware.plugin.NsxServicePlugin" - - -class LoadBalancerTestExtensionManager( - test_edge_router.ServiceRouterTestExtensionManager): - - def get_resources(self): - # If l3 resources have been loaded and updated by main API - # router, update the map in the l3 extension so it will load - # the same attributes as the API router - resources = super(LoadBalancerTestExtensionManager, - self).get_resources() - lb_attr_map = lb.RESOURCE_ATTRIBUTE_MAP.copy() - for res in lb.RESOURCE_ATTRIBUTE_MAP.keys(): - attr_info = attributes.RESOURCE_ATTRIBUTE_MAP.get(res) - if attr_info: - lb.RESOURCE_ATTRIBUTE_MAP[res] = attr_info - lb_resources = lb.Loadbalancer.get_resources() - # restore the original resources once the controllers are created - lb.RESOURCE_ATTRIBUTE_MAP = lb_attr_map - resources.extend(lb_resources) - return resources - - -class TestLoadbalancerPlugin( - test_db_loadbalancer.LoadBalancerPluginDbTestCase, - test_edge_router.ServiceRouterTest): - - def vcns_loadbalancer_patch(self): - instance = self.vcns_instance - instance.return_value.create_vip.side_effect = ( - self.fc2.create_vip) - instance.return_value.get_vip.side_effect = ( - self.fc2.get_vip) - instance.return_value.update_vip.side_effect = ( - self.fc2.update_vip) - instance.return_value.delete_vip.side_effect = ( - self.fc2.delete_vip) - instance.return_value.create_pool.side_effect = ( - self.fc2.create_pool) - instance.return_value.get_pool.side_effect = ( - self.fc2.get_pool) - instance.return_value.update_pool.side_effect = ( - self.fc2.update_pool) - instance.return_value.delete_pool.side_effect = ( - self.fc2.delete_pool) - instance.return_value.create_health_monitor.side_effect = ( - self.fc2.create_health_monitor) - instance.return_value.get_health_monitor.side_effect = ( - self.fc2.get_health_monitor) - instance.return_value.update_health_monitor.side_effect = ( - self.fc2.update_health_monitor) - instance.return_value.delete_health_monitor.side_effect = ( - self.fc2.delete_health_monitor) - instance.return_value.create_app_profile.side_effect = ( - self.fc2.create_app_profile) - instance.return_value.update_app_profile.side_effect = ( - self.fc2.update_app_profile) - instance.return_value.delete_app_profile.side_effect = ( - self.fc2.delete_app_profile) - - def setUp(self): - # Save the global RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems(): - self.saved_attr_map[resource] = attrs.copy() - - super(TestLoadbalancerPlugin, self).setUp( - ext_mgr=LoadBalancerTestExtensionManager(), - lb_plugin=LBAAS_PLUGIN_CLASS) - self.vcns_loadbalancer_patch() - self.plugin = manager.NeutronManager.get_plugin() - - def tearDown(self): - super(TestLoadbalancerPlugin, self).tearDown() - # Restore the global RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - self.ext_api = None - self.plugin = None - - def _get_vip_optional_args(self): - args = super(TestLoadbalancerPlugin, self)._get_vip_optional_args() - return args + ('router_id',) - - def test_update_healthmonitor(self): - keys = [('type', "TCP"), - ('tenant_id', self._tenant_id), - ('delay', 20), - ('timeout', 20), - ('max_retries', 2), - ('admin_state_up', False)] - - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool() - ) as (subnet, health_mon, pool): - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - with self.vip( - router_id=self._create_and_get_router(), - pool=pool, subnet=subnet): - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - health_mon, pool['pool']['id'] - ) - data = {'health_monitor': {'delay': 20, - 'timeout': 20, - 'max_retries': 2, - 'admin_state_up': False}} - req = self.new_update_request( - "health_monitors", - data, - health_mon['health_monitor']['id']) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['health_monitor'][k], v) - - def test_create_vip(self, **kwargs): - expected = { - 'name': 'vip1', - 'description': '', - 'protocol_port': 80, - 'protocol': 'HTTP', - 'connection_limit': -1, - 'admin_state_up': True, - 'status': 'ACTIVE', - 'tenant_id': self._tenant_id, - } - if 'router_id' in kwargs: - expected['router_id'] = kwargs.pop('router_id') - else: - expected['router_id'] = self._create_and_get_router() - - expected.update(kwargs) - - name = expected['name'] - - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool() - ) as (subnet, monitor, pool): - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - expected['pool_id'] = pool['pool']['id'] - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool['pool']['id'] - ) - with self.vip( - router_id=expected['router_id'], name=name, - pool=pool, subnet=subnet, **kwargs) as vip: - for k in ('id', 'address', 'port_id', 'pool_id'): - self.assertTrue(vip['vip'].get(k, None)) - self.assertEqual( - dict((k, v) - for k, v in vip['vip'].items() if k in expected), - expected - ) - - def test_create_vip_with_invalid_router(self): - self.assertRaises( - web_exc.HTTPClientError, - self.test_create_vip, router_id=None) - self.assertRaises( - web_exc.HTTPClientError, - self.test_create_vip, router_id='invalid_router_id') - router_id = self._create_and_get_router( - arg_list=('service_router',), service_router=False) - self.assertRaises( - web_exc.HTTPClientError, - self.test_create_vip, router_id=router_id) - router_id = self._create_and_get_router(active_set=False) - self.assertRaises( - web_exc.HTTPClientError, - self.test_create_vip, router_id=router_id) - - def test_create_vip_with_session_persistence(self): - self.test_create_vip(session_persistence={'type': 'HTTP_COOKIE'}) - - def test_create_vip_with_invalid_persistence_method(self): - with testtools.ExpectedException(web_exc.HTTPClientError): - self.test_create_vip( - protocol='TCP', - session_persistence={'type': 'HTTP_COOKIE'}) - - def test_create_vips_with_same_names(self): - new_router_id = self._create_and_get_router() - with self.subnet() as subnet: - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - with contextlib.nested( - self.vip( - name='vip', - router_id=new_router_id, - subnet=subnet, protocol_port=80), - self.vip( - name='vip', - router_id=new_router_id, - subnet=subnet, protocol_port=81), - self.vip( - name='vip', - router_id=new_router_id, - subnet=subnet, protocol_port=82), - ) as (vip1, vip2, vip3): - req = self.new_list_request('vips') - res = self.deserialize( - self.fmt, req.get_response(self.ext_api)) - for index in range(len(res['vips'])): - self.assertEqual(res['vips'][index]['name'], 'vip') - - def test_update_vip(self): - name = 'new_vip' - router_id = self._create_and_get_router() - keys = [('router_id', router_id), - ('name', name), - ('address', "10.0.0.2"), - ('protocol_port', 80), - ('connection_limit', 100), - ('admin_state_up', False), - ('status', 'ACTIVE')] - - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool() - ) as (subnet, monitor, pool): - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool['pool']['id'] - ) - with self.vip( - router_id=router_id, name=name, - pool=pool, subnet=subnet) as vip: - keys.append(('subnet_id', vip['vip']['subnet_id'])) - data = {'vip': {'name': name, - 'connection_limit': 100, - 'session_persistence': - {'type': "APP_COOKIE", - 'cookie_name': "jesssionId"}, - 'admin_state_up': False}} - req = self.new_update_request( - 'vips', data, vip['vip']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['vip'][k], v) - - def test_delete_vip(self): - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool() - ) as (subnet, monitor, pool): - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool['pool']['id'] - ) - with self.vip( - router_id=self._create_and_get_router(), - pool=pool, subnet=subnet, no_delete=True) as vip: - req = self.new_delete_request('vips', vip['vip']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - - def test_delete_router_in_use_by_lbservice(self): - router_id = self._create_and_get_router() - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool() - ) as (subnet, monitor, pool): - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool['pool']['id'] - ) - with self.vip( - router_id=router_id, - pool=pool, subnet=subnet): - self._delete('routers', router_id, - expected_code=web_exc.HTTPConflict.code) - - def test_show_vip(self): - router_id = self._create_and_get_router() - name = "vip_show" - keys = [('name', name), - ('protocol_port', 80), - ('protocol', 'HTTP'), - ('connection_limit', -1), - ('admin_state_up', True), - ('status', 'ACTIVE'), - ('router_id', router_id)] - - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool() - ) as (subnet, monitor, pool): - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool['pool']['id'] - ) - with self.vip( - router_id=router_id, name=name, - pool=pool, subnet=subnet) as vip: - req = self.new_show_request('vips', - vip['vip']['id']) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api)) - for k, v in keys: - self.assertEqual(res['vip'][k], v) - - def test_list_vips(self): - keys_list = [] - for i in range(3): - keys_list.append({'name': "vip" + str(i), - 'router_id': self._create_and_get_router(), - 'protocol_port': 80 + i, - 'protocol': "HTTP", - 'status': "ACTIVE", - 'admin_state_up': True}) - - with self.subnet() as subnet: - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - with contextlib.nested( - self.vip( - router_id=keys_list[0]['router_id'], name='vip0', - subnet=subnet, protocol_port=80), - self.vip( - router_id=keys_list[1]['router_id'], name='vip1', - subnet=subnet, protocol_port=81), - self.vip( - router_id=keys_list[2]['router_id'], name='vip2', - subnet=subnet, protocol_port=82), - ) as (vip1, vip2, vip3): - self._test_list_with_sort( - 'vip', - (vip1, vip3, vip2), - [('protocol_port', 'asc'), ('name', 'desc')] - ) - req = self.new_list_request('vips') - res = self.deserialize( - self.fmt, req.get_response(self.ext_api)) - self.assertEqual(len(res['vips']), 3) - for index in range(len(res['vips'])): - for k, v in keys_list[index].items(): - self.assertEqual(res['vips'][index][k], v) - - def test_update_pool(self): - data = {'pool': {'name': "new_pool", - 'admin_state_up': False}} - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool() - ) as (subnet, monitor, pool): - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool['pool']['id'] - ) - with self.vip( - router_id=self._create_and_get_router(), - pool=pool, subnet=subnet): - req = self.new_update_request( - 'pools', data, pool['pool']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in data['pool'].items(): - self.assertEqual(res['pool'][k], v) - - def test_create_member(self): - router_id = self._create_and_get_router() - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool() - ) as (subnet, monitor, pool): - pool_id = pool['pool']['id'] - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool['pool']['id'] - ) - with self.vip( - router_id=router_id, - pool=pool, subnet=subnet): - with contextlib.nested( - self.member(address='192.168.1.100', - protocol_port=80, - pool_id=pool_id), - self.member(router_id=router_id, - address='192.168.1.101', - protocol_port=80, - pool_id=pool_id)) as (member1, member2): - req = self.new_show_request('pools', - pool_id, - fmt=self.fmt) - pool_update = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - self.assertIn(member1['member']['id'], - pool_update['pool']['members']) - self.assertIn(member2['member']['id'], - pool_update['pool']['members']) - - def _show_pool(self, pool_id): - req = self.new_show_request('pools', pool_id, fmt=self.fmt) - res = req.get_response(self.ext_api) - self.assertEqual(web_exc.HTTPOk.code, res.status_int) - return self.deserialize(self.fmt, res) - - def test_update_member(self): - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool(name="pool1"), - self.pool(name="pool2") - ) as (subnet, monitor, pool1, pool2): - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool1['pool']['id'] - ) - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool2['pool']['id'] - ) - with self.vip( - router_id=self._create_and_get_router(), - pool=pool1, subnet=subnet): - keys = [('address', "192.168.1.100"), - ('tenant_id', self._tenant_id), - ('protocol_port', 80), - ('weight', 10), - ('pool_id', pool2['pool']['id']), - ('admin_state_up', False), - ('status', 'ACTIVE')] - with self.member( - pool_id=pool1['pool']['id']) as member: - - pool1_update = self._show_pool(pool1['pool']['id']) - self.assertEqual(len(pool1_update['pool']['members']), 1) - pool2_update = self._show_pool(pool2['pool']['id']) - self.assertEqual(len(pool1_update['pool']['members']), 1) - self.assertFalse(pool2_update['pool']['members']) - - data = {'member': {'pool_id': pool2['pool']['id'], - 'weight': 10, - 'admin_state_up': False}} - req = self.new_update_request('members', - data, - member['member']['id']) - raw_res = req.get_response(self.ext_api) - self.assertEqual(web_exc.HTTPOk.code, raw_res.status_int) - res = self.deserialize(self.fmt, raw_res) - for k, v in keys: - self.assertEqual(res['member'][k], v) - pool1_update = self._show_pool(pool1['pool']['id']) - pool2_update = self._show_pool(pool2['pool']['id']) - self.assertEqual(len(pool2_update['pool']['members']), 1) - self.assertFalse(pool1_update['pool']['members']) - - def test_delete_member(self): - with contextlib.nested( - self.subnet(), - self.health_monitor(), - self.pool() - ) as (subnet, monitor, pool): - pool_id = pool['pool']['id'] - net_id = subnet['subnet']['network_id'] - self._set_net_external(net_id) - self.plugin.create_pool_health_monitor( - context.get_admin_context(), - monitor, pool['pool']['id'] - ) - with self.vip( - router_id=self._create_and_get_router(), - pool=pool, subnet=subnet): - with self.member(pool_id=pool_id, - no_delete=True) as member: - req = self.new_delete_request('members', - member['member']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - pool_update = self._show_pool(pool['pool']['id']) - self.assertFalse(pool_update['pool']['members']) diff --git a/neutron/tests/unit/vmware/vshield/test_loadbalancer_driver.py b/neutron/tests/unit/vmware/vshield/test_loadbalancer_driver.py deleted file mode 100644 index 27027f38c..000000000 --- a/neutron/tests/unit/vmware/vshield/test_loadbalancer_driver.py +++ /dev/null @@ -1,340 +0,0 @@ -# Copyright 2013 VMware, Inc -# -# 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. -# -# @author: linb, VMware - -import mock - -from neutron import context -from neutron.openstack.common import uuidutils -from neutron.plugins.vmware.dbexts import vcns_db -from neutron.plugins.vmware.vshield.common import exceptions as vcns_exc -from neutron.plugins.vmware.vshield import vcns_driver -from neutron.services.loadbalancer import constants as lb_constants -from neutron.tests.unit.db.loadbalancer import test_db_loadbalancer -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.vshield import fake_vcns - -_uuid = uuidutils.generate_uuid - -VSE_ID = 'edge-1' -POOL_MAP_INFO = { - 'pool_id': None, - 'edge_id': VSE_ID, - 'pool_vseid': 'pool-1'} - -VCNS_CONFIG_FILE = vmware.get_fake_conf("vcns.ini.test") - - -class VcnsDriverTestCase(test_db_loadbalancer.LoadBalancerPluginDbTestCase): - - def vcns_loadbalancer_patch(self): - instance = self.mock_vcns.start() - instance.return_value.create_vip.side_effect = ( - self.fc2.create_vip) - instance.return_value.get_vip.side_effect = ( - self.fc2.get_vip) - instance.return_value.update_vip.side_effect = ( - self.fc2.update_vip) - instance.return_value.delete_vip.side_effect = ( - self.fc2.delete_vip) - instance.return_value.create_pool.side_effect = ( - self.fc2.create_pool) - instance.return_value.get_pool.side_effect = ( - self.fc2.get_pool) - instance.return_value.update_pool.side_effect = ( - self.fc2.update_pool) - instance.return_value.delete_pool.side_effect = ( - self.fc2.delete_pool) - instance.return_value.create_health_monitor.side_effect = ( - self.fc2.create_health_monitor) - instance.return_value.get_health_monitor.side_effect = ( - self.fc2.get_health_monitor) - instance.return_value.update_health_monitor.side_effect = ( - self.fc2.update_health_monitor) - instance.return_value.delete_health_monitor.side_effect = ( - self.fc2.delete_health_monitor) - instance.return_value.create_app_profile.side_effect = ( - self.fc2.create_app_profile) - instance.return_value.update_app_profile.side_effect = ( - self.fc2.update_app_profile) - instance.return_value.delete_app_profile.side_effect = ( - self.fc2.delete_app_profile) - self.pool_id = None - self.vip_id = None - - def setUp(self): - - self.config_parse(args=['--config-file', VCNS_CONFIG_FILE]) - # mock vcns - self.fc2 = fake_vcns.FakeVcns(unique_router_name=False) - self.mock_vcns = mock.patch(vmware.VCNS_NAME, autospec=True) - self.vcns_loadbalancer_patch() - - self.driver = vcns_driver.VcnsDriver(mock.Mock()) - - super(VcnsDriverTestCase, self).setUp() - self.addCleanup(self.fc2.reset_all) - self.addCleanup(self.mock_vcns.stop) - - def tearDown(self): - super(VcnsDriverTestCase, self).tearDown() - - -class TestEdgeLbDriver(VcnsDriverTestCase): - - def test_create_and_get_vip(self): - ctx = context.get_admin_context() - with self.pool(no_delete=True) as pool: - self.pool_id = pool['pool']['id'] - POOL_MAP_INFO['pool_id'] = pool['pool']['id'] - vcns_db.add_vcns_edge_pool_binding(ctx.session, POOL_MAP_INFO) - with self.vip(pool=pool) as res: - vip_create = res['vip'] - self.driver.create_vip(ctx, VSE_ID, vip_create) - vip_get = self.driver.get_vip(ctx, vip_create['id']) - for k, v in vip_get.iteritems(): - self.assertEqual(vip_create[k], v) - - def test_create_two_vips_with_same_name(self): - ctx = context.get_admin_context() - with self.pool(no_delete=True) as pool: - self.pool_id = pool['pool']['id'] - POOL_MAP_INFO['pool_id'] = pool['pool']['id'] - vcns_db.add_vcns_edge_pool_binding(ctx.session, POOL_MAP_INFO) - with self.vip(pool=pool) as res: - vip_create = res['vip'] - self.driver.create_vip(ctx, VSE_ID, vip_create) - self.assertRaises(vcns_exc.Forbidden, - self.driver.create_vip, - ctx, VSE_ID, vip_create) - - def test_convert_app_profile(self): - app_profile_name = 'app_profile_name' - sess_persist1 = {'type': "SOURCE_IP"} - sess_persist2 = {'type': "HTTP_COOKIE"} - sess_persist3 = {'type': "APP_COOKIE", - 'cookie_name': "app_cookie_name"} - # protocol is HTTP and type is SOURCE_IP - expect_vcns_app_profile1 = { - 'insertXForwardedFor': False, - 'name': app_profile_name, - 'serverSslEnabled': False, - 'sslPassthrough': False, - 'template': lb_constants.PROTOCOL_HTTP, - 'persistence': {'method': 'sourceip'}} - vcns_app_profile = self.driver._convert_app_profile( - app_profile_name, sess_persist1, lb_constants.PROTOCOL_HTTP) - for k, v in expect_vcns_app_profile1.iteritems(): - self.assertEqual(vcns_app_profile[k], v) - # protocol is HTTP and type is HTTP_COOKIE and APP_COOKIE - expect_vcns_app_profile2 = { - 'insertXForwardedFor': False, - 'name': app_profile_name, - 'serverSslEnabled': False, - 'sslPassthrough': False, - 'template': lb_constants.PROTOCOL_HTTP, - 'persistence': {'method': 'cookie', - 'cookieName': 'default_cookie_name', - 'cookieMode': 'insert'}} - vcns_app_profile = self.driver._convert_app_profile( - app_profile_name, sess_persist2, lb_constants.PROTOCOL_HTTP) - for k, v in expect_vcns_app_profile2.iteritems(): - self.assertEqual(vcns_app_profile[k], v) - expect_vcns_app_profile3 = { - 'insertXForwardedFor': False, - 'name': app_profile_name, - 'serverSslEnabled': False, - 'sslPassthrough': False, - 'template': lb_constants.PROTOCOL_HTTP, - 'persistence': {'method': 'cookie', - 'cookieName': sess_persist3['cookie_name'], - 'cookieMode': 'app'}} - vcns_app_profile = self.driver._convert_app_profile( - app_profile_name, sess_persist3, lb_constants.PROTOCOL_HTTP) - for k, v in expect_vcns_app_profile3.iteritems(): - self.assertEqual(vcns_app_profile[k], v) - # protocol is HTTPS and type is SOURCE_IP - expect_vcns_app_profile1 = { - 'insertXForwardedFor': False, - 'name': app_profile_name, - 'serverSslEnabled': False, - 'sslPassthrough': True, - 'template': lb_constants.PROTOCOL_HTTPS, - 'persistence': {'method': 'sourceip'}} - vcns_app_profile = self.driver._convert_app_profile( - app_profile_name, sess_persist1, lb_constants.PROTOCOL_HTTPS) - for k, v in expect_vcns_app_profile1.iteritems(): - self.assertEqual(vcns_app_profile[k], v) - # protocol is HTTPS, and type isn't SOURCE_IP - self.assertRaises(vcns_exc.VcnsBadRequest, - self.driver._convert_app_profile, - app_profile_name, - sess_persist2, lb_constants.PROTOCOL_HTTPS) - self.assertRaises(vcns_exc.VcnsBadRequest, - self.driver._convert_app_profile, - app_profile_name, - sess_persist3, lb_constants.PROTOCOL_HTTPS) - # protocol is TCP and type is SOURCE_IP - expect_vcns_app_profile1 = { - 'insertXForwardedFor': False, - 'name': app_profile_name, - 'serverSslEnabled': False, - 'sslPassthrough': False, - 'template': lb_constants.PROTOCOL_TCP, - 'persistence': {'method': 'sourceip'}} - vcns_app_profile = self.driver._convert_app_profile( - app_profile_name, sess_persist1, lb_constants.PROTOCOL_TCP) - for k, v in expect_vcns_app_profile1.iteritems(): - self.assertEqual(vcns_app_profile[k], v) - # protocol is TCP, and type isn't SOURCE_IP - self.assertRaises(vcns_exc.VcnsBadRequest, - self.driver._convert_app_profile, - app_profile_name, - sess_persist2, lb_constants.PROTOCOL_TCP) - self.assertRaises(vcns_exc.VcnsBadRequest, - self.driver._convert_app_profile, - app_profile_name, - sess_persist3, lb_constants.PROTOCOL_TCP) - - def test_update_vip(self): - ctx = context.get_admin_context() - with self.pool(no_delete=True) as pool: - self.pool_id = pool['pool']['id'] - POOL_MAP_INFO['pool_id'] = pool['pool']['id'] - vcns_db.add_vcns_edge_pool_binding(ctx.session, POOL_MAP_INFO) - with self.vip(pool=pool) as res: - vip_create = res['vip'] - self.driver.create_vip(ctx, VSE_ID, vip_create) - vip_update = {'id': vip_create['id'], - 'pool_id': pool['pool']['id'], - 'name': 'update_name', - 'description': 'description', - 'address': 'update_address', - 'port_id': 'update_port_id', - 'protocol_port': 'protocol_port', - 'protocol': 'update_protocol'} - self.driver.update_vip(ctx, vip_update) - vip_get = self.driver.get_vip(ctx, vip_create['id']) - for k, v in vip_get.iteritems(): - if k in vip_update: - self.assertEqual(vip_update[k], v) - - def test_delete_vip(self): - ctx = context.get_admin_context() - with self.pool(no_delete=True) as pool: - self.pool_id = pool['pool']['id'] - POOL_MAP_INFO['pool_id'] = pool['pool']['id'] - vcns_db.add_vcns_edge_pool_binding(ctx.session, POOL_MAP_INFO) - with self.vip(pool=pool) as res: - vip_create = res['vip'] - self.driver.create_vip(ctx, VSE_ID, vip_create) - self.driver.delete_vip(ctx, vip_create['id']) - self.assertRaises(vcns_exc.VcnsNotFound, - self.driver.get_vip, - ctx, - vip_create['id']) - - #Test Pool Operation - def test_create_and_get_pool(self): - ctx = context.get_admin_context() - with self.pool(no_delete=True) as p: - self.pool_id = p['pool']['id'] - pool_create = p['pool'] - self.driver.create_pool(ctx, VSE_ID, pool_create, []) - pool_get = self.driver.get_pool(ctx, pool_create['id'], VSE_ID) - for k, v in pool_get.iteritems(): - self.assertEqual(pool_create[k], v) - - def test_create_two_pools_with_same_name(self): - ctx = context.get_admin_context() - with self.pool(no_delete=True) as p: - self.pool_id = p['pool']['id'] - pool_create = p['pool'] - self.driver.create_pool(ctx, VSE_ID, pool_create, []) - self.assertRaises(vcns_exc.Forbidden, - self.driver.create_pool, - ctx, VSE_ID, pool_create, []) - - def test_update_pool(self): - ctx = context.get_admin_context() - with self.pool(no_delete=True) as p: - self.pool_id = p['pool']['id'] - pool_create = p['pool'] - self.driver.create_pool(ctx, VSE_ID, pool_create, []) - pool_update = {'id': pool_create['id'], - 'lb_method': 'lb_method', - 'name': 'update_name', - 'members': [], - 'health_monitors': []} - self.driver.update_pool(ctx, VSE_ID, pool_update, []) - pool_get = self.driver.get_pool(ctx, pool_create['id'], VSE_ID) - for k, v in pool_get.iteritems(): - if k in pool_update: - self.assertEqual(pool_update[k], v) - - def test_delete_pool(self): - ctx = context.get_admin_context() - with self.pool(no_delete=True) as p: - self.pool_id = p['pool']['id'] - pool_create = p['pool'] - self.driver.create_pool(ctx, VSE_ID, pool_create, []) - self.driver.delete_pool(ctx, pool_create['id'], VSE_ID) - self.assertRaises(vcns_exc.VcnsNotFound, - self.driver.get_pool, - ctx, - pool_create['id'], - VSE_ID) - - def test_create_and_get_monitor(self): - ctx = context.get_admin_context() - with self.health_monitor(no_delete=True) as m: - monitor_create = m['health_monitor'] - self.driver.create_health_monitor(ctx, VSE_ID, monitor_create) - monitor_get = self.driver.get_health_monitor( - ctx, monitor_create['id'], VSE_ID) - for k, v in monitor_get.iteritems(): - self.assertEqual(monitor_create[k], v) - - def test_update_health_monitor(self): - ctx = context.get_admin_context() - with self.health_monitor(no_delete=True) as m: - monitor_create = m['health_monitor'] - self.driver.create_health_monitor( - ctx, VSE_ID, monitor_create) - monitor_update = {'id': monitor_create['id'], - 'delay': 'new_delay', - 'timeout': "new_timeout", - 'type': 'type', - 'max_retries': "max_retries"} - self.driver.update_health_monitor( - ctx, VSE_ID, monitor_create, monitor_update) - monitor_get = self.driver.get_health_monitor( - ctx, monitor_create['id'], VSE_ID) - for k, v in monitor_get.iteritems(): - if k in monitor_update: - self.assertEqual(monitor_update[k], v) - - def test_delete_health_monitor(self): - ctx = context.get_admin_context() - with self.health_monitor(no_delete=True) as m: - monitor_create = m['health_monitor'] - self.driver.create_health_monitor(ctx, VSE_ID, monitor_create) - self.driver.delete_health_monitor( - ctx, monitor_create['id'], VSE_ID) - self.assertRaises(vcns_exc.VcnsNotFound, - self.driver.get_health_monitor, - ctx, - monitor_create['id'], - VSE_ID) diff --git a/neutron/tests/unit/vmware/vshield/test_vcns_driver.py b/neutron/tests/unit/vmware/vshield/test_vcns_driver.py deleted file mode 100644 index c0451715f..000000000 --- a/neutron/tests/unit/vmware/vshield/test_vcns_driver.py +++ /dev/null @@ -1,587 +0,0 @@ -# Copyright 2013 OpenStack Foundation. -# -# 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. - -from eventlet import greenthread -import mock - -from neutron.plugins.vmware.vshield.common import constants as vcns_const -from neutron.plugins.vmware.vshield.tasks import constants as ts_const -from neutron.plugins.vmware.vshield.tasks import tasks as ts -from neutron.plugins.vmware.vshield import vcns_driver -from neutron.tests import base -from neutron.tests.unit import vmware -from neutron.tests.unit.vmware.vshield import fake_vcns - -VCNS_CONFIG_FILE = vmware.get_fake_conf("vcns.ini.test") - -ts.TaskManager.set_default_interval(100) - - -class VcnsDriverTaskManagerTestCase(base.BaseTestCase): - - def setUp(self): - super(VcnsDriverTaskManagerTestCase, self).setUp() - self.manager = ts.TaskManager() - self.manager.start(100) - - def tearDown(self): - self.manager.stop() - # Task manager should not leave running threads around - # if _thread is None it means it was killed in stop() - self.assertIsNone(self.manager._thread) - super(VcnsDriverTaskManagerTestCase, self).tearDown() - - def _test_task_manager_task_process_state(self, sync_exec=False): - def _task_failed(task, reason): - task.userdata['result'] = False - task.userdata['error'] = reason - - def _check_state(task, exp_state): - if not task.userdata.get('result', True): - return False - - state = task.userdata['state'] - if state != exp_state: - msg = "state %d expect %d" % ( - state, exp_state) - _task_failed(task, msg) - return False - - task.userdata['state'] = state + 1 - return True - - def _exec(task): - if not _check_state(task, 1): - return ts_const.TaskStatus.ERROR - - if task.userdata['sync_exec']: - return ts_const.TaskStatus.COMPLETED - else: - return ts_const.TaskStatus.PENDING - - def _status(task): - if task.userdata['sync_exec']: - _task_failed(task, "_status callback triggered") - - state = task.userdata['state'] - if state == 3: - _check_state(task, 3) - return ts_const.TaskStatus.PENDING - else: - _check_state(task, 4) - return ts_const.TaskStatus.COMPLETED - - def _result(task): - if task.userdata['sync_exec']: - exp_state = 3 - else: - exp_state = 5 - - _check_state(task, exp_state) - - def _start_monitor(task): - _check_state(task, 0) - - def _executed_monitor(task): - _check_state(task, 2) - - def _result_monitor(task): - if task.userdata['sync_exec']: - exp_state = 4 - else: - exp_state = 6 - - if _check_state(task, exp_state): - task.userdata['result'] = True - else: - task.userdata['result'] = False - - userdata = { - 'state': 0, - 'sync_exec': sync_exec - } - task = ts.Task('name', 'res', _exec, _status, _result, userdata) - task.add_start_monitor(_start_monitor) - task.add_executed_monitor(_executed_monitor) - task.add_result_monitor(_result_monitor) - - self.manager.add(task) - - task.wait(ts_const.TaskState.RESULT) - - self.assertTrue(userdata['result']) - - def test_task_manager_task_sync_exec_process_state(self): - self._test_task_manager_task_process_state(sync_exec=True) - - def test_task_manager_task_async_exec_process_state(self): - self._test_task_manager_task_process_state(sync_exec=False) - - def test_task_manager_task_ordered_process(self): - def _task_failed(task, reason): - task.userdata['result'] = False - task.userdata['error'] = reason - - def _exec(task): - task.userdata['executed'] = True - return ts_const.TaskStatus.PENDING - - def _status(task): - return ts_const.TaskStatus.COMPLETED - - def _result(task): - next_task = task.userdata.get('next') - if next_task: - if next_task.userdata.get('executed'): - _task_failed(next_task, "executed premature") - if task.userdata.get('result', True): - task.userdata['result'] = True - - tasks = [] - prev = None - last_task = None - for i in range(5): - name = "name-%d" % i - task = ts.Task(name, 'res', _exec, _status, _result, {}) - tasks.append(task) - if prev: - prev.userdata['next'] = task - prev = task - last_task = task - - for task in tasks: - self.manager.add(task) - - last_task.wait(ts_const.TaskState.RESULT) - - for task in tasks: - self.assertTrue(task.userdata['result']) - - def test_task_manager_task_parallel_process(self): - tasks = [] - - def _exec(task): - task.userdata['executed'] = True - return ts_const.TaskStatus.PENDING - - def _status(task): - for t in tasks: - if not t.userdata.get('executed'): - t.userdata['resut'] = False - return ts_const.TaskStatus.COMPLETED - - def _result(task): - if (task.userdata.get('result') is None and - task.status == ts_const.TaskStatus.COMPLETED): - task.userdata['result'] = True - else: - task.userdata['result'] = False - - for i in range(5): - name = "name-%d" % i - res = 'resource-%d' % i - task = ts.Task(name, res, _exec, _status, _result, {}) - tasks.append(task) - self.manager.add(task) - - for task in tasks: - task.wait(ts_const.TaskState.RESULT) - self.assertTrue(task.userdata['result']) - - def _test_task_manager_stop(self, exec_wait=False, result_wait=False, - stop_wait=0): - def _exec(task): - if exec_wait: - greenthread.sleep(0.01) - return ts_const.TaskStatus.PENDING - - def _status(task): - greenthread.sleep(0.01) - return ts_const.TaskStatus.PENDING - - def _result(task): - if result_wait: - greenthread.sleep(0) - pass - - manager = ts.TaskManager().start(100) - manager.stop() - # Task manager should not leave running threads around - # if _thread is None it means it was killed in stop() - self.assertIsNone(manager._thread) - manager.start(100) - - alltasks = {} - for i in range(100): - res = 'res-%d' % i - tasks = [] - for i in range(100): - task = ts.Task('name', res, _exec, _status, _result) - manager.add(task) - tasks.append(task) - alltasks[res] = tasks - - greenthread.sleep(stop_wait) - manager.stop() - # Task manager should not leave running threads around - # if _thread is None it means it was killed in stop() - self.assertIsNone(manager._thread) - - for res, tasks in alltasks.iteritems(): - for task in tasks: - self.assertEqual(task.status, ts_const.TaskStatus.ABORT) - - def test_task_manager_stop_1(self): - self._test_task_manager_stop(True, True, 0) - - def test_task_manager_stop_2(self): - self._test_task_manager_stop(True, True, 1) - - def test_task_manager_stop_3(self): - self._test_task_manager_stop(False, False, 0) - - def test_task_manager_stop_4(self): - self._test_task_manager_stop(False, False, 1) - - def test_task_pending_task(self): - def _exec(task): - task.userdata['executing'] = True - while not task.userdata['tested']: - greenthread.sleep(0) - task.userdata['executing'] = False - return ts_const.TaskStatus.COMPLETED - - userdata = { - 'executing': False, - 'tested': False - } - manager = ts.TaskManager().start(100) - task = ts.Task('name', 'res', _exec, userdata=userdata) - manager.add(task) - - while not userdata['executing']: - greenthread.sleep(0) - self.assertTrue(manager.has_pending_task()) - - userdata['tested'] = True - while userdata['executing']: - greenthread.sleep(0) - self.assertFalse(manager.has_pending_task()) - - -class VcnsDriverTestCase(base.BaseTestCase): - - def vcns_patch(self): - instance = self.mock_vcns.start() - instance.return_value.deploy_edge.side_effect = self.fc.deploy_edge - instance.return_value.get_edge_id.side_effect = self.fc.get_edge_id - instance.return_value.get_edge_deploy_status.side_effect = ( - self.fc.get_edge_deploy_status) - instance.return_value.delete_edge.side_effect = self.fc.delete_edge - instance.return_value.update_interface.side_effect = ( - self.fc.update_interface) - instance.return_value.get_nat_config.side_effect = ( - self.fc.get_nat_config) - instance.return_value.update_nat_config.side_effect = ( - self.fc.update_nat_config) - instance.return_value.delete_nat_rule.side_effect = ( - self.fc.delete_nat_rule) - instance.return_value.get_edge_status.side_effect = ( - self.fc.get_edge_status) - instance.return_value.get_edges.side_effect = self.fc.get_edges - instance.return_value.update_routes.side_effect = ( - self.fc.update_routes) - instance.return_value.create_lswitch.side_effect = ( - self.fc.create_lswitch) - instance.return_value.delete_lswitch.side_effect = ( - self.fc.delete_lswitch) - - def setUp(self): - super(VcnsDriverTestCase, self).setUp() - - self.config_parse(args=['--config-file', VCNS_CONFIG_FILE]) - - self.fc = fake_vcns.FakeVcns() - self.mock_vcns = mock.patch(vmware.VCNS_NAME, autospec=True) - self.vcns_patch() - - self.addCleanup(self.fc.reset_all) - - self.vcns_driver = vcns_driver.VcnsDriver(self) - - self.edge_id = None - self.result = None - - def tearDown(self): - self.vcns_driver.task_manager.stop() - # Task manager should not leave running threads around - # if _thread is None it means it was killed in stop() - self.assertIsNone(self.vcns_driver.task_manager._thread) - super(VcnsDriverTestCase, self).tearDown() - - def _deploy_edge(self): - task = self.vcns_driver.deploy_edge( - 'router-id', 'myedge', 'internal-network', {}, wait_for_exec=True) - self.assertEqual(self.edge_id, 'edge-1') - task.wait(ts_const.TaskState.RESULT) - return task - - def edge_deploy_started(self, task): - self.edge_id = task.userdata['edge_id'] - - def edge_deploy_result(self, task): - if task.status == ts_const.TaskStatus.COMPLETED: - task.userdata['jobdata']['edge_deploy_result'] = True - - def edge_delete_result(self, task): - if task.status == ts_const.TaskStatus.COMPLETED: - task.userdata['jobdata']['edge_delete_result'] = True - - def snat_create_result(self, task): - if task.status == ts_const.TaskStatus.COMPLETED: - task.userdata['jobdata']['snat_create_result'] = True - - def snat_delete_result(self, task): - if task.status == ts_const.TaskStatus.COMPLETED: - task.userdata['jobdata']['snat_delete_result'] = True - - def dnat_create_result(self, task): - if task.status == ts_const.TaskStatus.COMPLETED: - task.userdata['jobdata']['dnat_create_result'] = True - - def dnat_delete_result(self, task): - if task.status == ts_const.TaskStatus.COMPLETED: - task.userdata['jobdata']['dnat_delete_result'] = True - - def nat_update_result(self, task): - if task.status == ts_const.TaskStatus.COMPLETED: - task.userdata['jobdata']['nat_update_result'] = True - - def routes_update_result(self, task): - if task.status == ts_const.TaskStatus.COMPLETED: - task.userdata['jobdata']['routes_update_result'] = True - - def interface_update_result(self, task): - if task.status == ts_const.TaskStatus.COMPLETED: - task.userdata['jobdata']['interface_update_result'] = True - - def test_deploy_edge(self): - jobdata = {} - task = self.vcns_driver.deploy_edge( - 'router-id', 'myedge', 'internal-network', jobdata=jobdata, - wait_for_exec=True) - self.assertEqual(self.edge_id, 'edge-1') - task.wait(ts_const.TaskState.RESULT) - self.assertEqual(task.status, ts_const.TaskStatus.COMPLETED) - self.assertTrue(jobdata.get('edge_deploy_result')) - - def test_deploy_edge_fail(self): - task1 = self.vcns_driver.deploy_edge( - 'router-1', 'myedge', 'internal-network', {}, wait_for_exec=True) - task2 = self.vcns_driver.deploy_edge( - 'router-2', 'myedge', 'internal-network', {}, wait_for_exec=True) - task1.wait(ts_const.TaskState.RESULT) - task2.wait(ts_const.TaskState.RESULT) - self.assertEqual(task2.status, ts_const.TaskStatus.ERROR) - - def test_get_edge_status(self): - self._deploy_edge() - status = self.vcns_driver.get_edge_status(self.edge_id) - self.assertEqual(status, vcns_const.RouterStatus.ROUTER_STATUS_ACTIVE) - - def test_get_edges(self): - self._deploy_edge() - edges = self.vcns_driver.get_edges_statuses() - found = False - for edge_id, status in edges.iteritems(): - if edge_id == self.edge_id: - found = True - break - self.assertTrue(found) - - def _create_nat_rule(self, edge_id, action, org, translated): - jobdata = {} - if action == 'snat': - task = self.vcns_driver.create_snat_rule( - 'router-id', edge_id, org, translated, jobdata=jobdata) - key = 'snat_create_result' - else: - task = self.vcns_driver.create_dnat_rule( - 'router-id', edge_id, org, translated, jobdata=jobdata) - key = 'dnat_create_result' - task.wait(ts_const.TaskState.RESULT) - self.assertTrue(jobdata.get(key)) - - def _delete_nat_rule(self, edge_id, action, addr): - jobdata = {} - if action == 'snat': - task = self.vcns_driver.delete_snat_rule( - 'router-id', edge_id, addr, jobdata=jobdata) - key = 'snat_delete_result' - else: - task = self.vcns_driver.delete_dnat_rule( - 'router-id', edge_id, addr, jobdata=jobdata) - key = 'dnat_delete_result' - task.wait(ts_const.TaskState.RESULT) - self.assertTrue(jobdata.get(key)) - - def _test_create_nat_rule(self, action): - self._deploy_edge() - addr = '192.168.1.1' - translated = '10.0.0.1' - self._create_nat_rule(self.edge_id, action, addr, translated) - - natcfg = self.vcns_driver.get_nat_config(self.edge_id) - for rule in natcfg['rules']['natRulesDtos']: - if (rule['originalAddress'] == addr and - rule['translatedAddress'] == translated and - rule['action'] == action): - break - else: - self.assertTrue(False) - - def _test_delete_nat_rule(self, action): - self._deploy_edge() - addr = '192.168.1.1' - translated = '10.0.0.1' - self._create_nat_rule(self.edge_id, action, addr, translated) - if action == 'snat': - self._delete_nat_rule(self.edge_id, action, addr) - else: - self._delete_nat_rule(self.edge_id, action, translated) - natcfg = self.vcns_driver.get_nat_config(self.edge_id) - for rule in natcfg['rules']['natRulesDtos']: - if (rule['originalAddress'] == addr and - rule['translatedAddress'] == translated and - rule['action'] == action): - self.assertTrue(False) - break - - def test_create_snat_rule(self): - self._test_create_nat_rule('snat') - - def test_delete_snat_rule(self): - self._test_delete_nat_rule('snat') - - def test_create_dnat_rule(self): - self._test_create_nat_rule('dnat') - - def test_delete_dnat_rule(self): - self._test_delete_nat_rule('dnat') - - def test_update_nat_rules(self): - self._deploy_edge() - jobdata = {} - snats = [{ - 'src': '192.168.1.0/24', - 'translated': '10.0.0.1' - }, { - 'src': '192.168.2.0/24', - 'translated': '10.0.0.2' - }, { - 'src': '192.168.3.0/24', - 'translated': '10.0.0.3' - } - ] - dnats = [{ - 'dst': '100.0.0.4', - 'translated': '192.168.1.1' - }, { - 'dst': '100.0.0.5', - 'translated': '192.168.2.1' - } - ] - task = self.vcns_driver.update_nat_rules( - 'router-id', self.edge_id, snats, dnats, jobdata=jobdata) - task.wait(ts_const.TaskState.RESULT) - self.assertTrue(jobdata.get('nat_update_result')) - - natcfg = self.vcns_driver.get_nat_config(self.edge_id) - rules = natcfg['rules']['natRulesDtos'] - self.assertEqual(len(rules), 2 * len(dnats) + len(snats)) - self.natEquals(rules[0], dnats[0]) - self.natEquals(rules[1], self.snat_for_dnat(dnats[0])) - self.natEquals(rules[2], dnats[1]) - self.natEquals(rules[3], self.snat_for_dnat(dnats[1])) - self.natEquals(rules[4], snats[0]) - self.natEquals(rules[5], snats[1]) - self.natEquals(rules[6], snats[2]) - - def snat_for_dnat(self, dnat): - return { - 'src': dnat['translated'], - 'translated': dnat['dst'] - } - - def natEquals(self, rule, exp): - addr = exp.get('src') - if not addr: - addr = exp.get('dst') - - self.assertEqual(rule['originalAddress'], addr) - self.assertEqual(rule['translatedAddress'], exp['translated']) - - def test_update_routes(self): - self._deploy_edge() - jobdata = {} - routes = [{ - 'cidr': '192.168.1.0/24', - 'nexthop': '169.254.2.1' - }, { - 'cidr': '192.168.2.0/24', - 'nexthop': '169.254.2.1' - }, { - 'cidr': '192.168.3.0/24', - 'nexthop': '169.254.2.1' - } - ] - task = self.vcns_driver.update_routes( - 'router-id', self.edge_id, '10.0.0.1', routes, jobdata=jobdata) - task.wait(ts_const.TaskState.RESULT) - self.assertTrue(jobdata.get('routes_update_result')) - - def test_update_interface(self): - self._deploy_edge() - jobdata = {} - task = self.vcns_driver.update_interface( - 'router-id', self.edge_id, vcns_const.EXTERNAL_VNIC_INDEX, - 'network-id', address='100.0.0.3', netmask='255.255.255.0', - jobdata=jobdata) - task.wait(ts_const.TaskState.RESULT) - self.assertTrue(jobdata.get('interface_update_result')) - - def test_delete_edge(self): - self._deploy_edge() - jobdata = {} - task = self.vcns_driver.delete_edge( - 'router-id', self.edge_id, jobdata=jobdata) - task.wait(ts_const.TaskState.RESULT) - self.assertTrue(jobdata.get('edge_delete_result')) - - def test_create_lswitch(self): - tz_config = [{ - 'transport_zone_uuid': 'tz-uuid' - }] - lswitch = self.vcns_driver.create_lswitch('lswitch', tz_config) - self.assertEqual(lswitch['display_name'], 'lswitch') - self.assertEqual(lswitch['type'], 'LogicalSwitchConfig') - self.assertIn('uuid', lswitch) - - def test_delete_lswitch(self): - tz_config = { - 'transport_zone_uuid': 'tz-uuid' - } - lswitch = self.vcns_driver.create_lswitch('lswitch', tz_config) - self.vcns_driver.delete_lswitch(lswitch['uuid']) diff --git a/neutron/tests/unit/vmware/vshield/test_vpnaas_plugin.py b/neutron/tests/unit/vmware/vshield/test_vpnaas_plugin.py deleted file mode 100644 index 7ef1a5445..000000000 --- a/neutron/tests/unit/vmware/vshield/test_vpnaas_plugin.py +++ /dev/null @@ -1,417 +0,0 @@ -# Copyright 2014 VMware, Inc -# -# 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 contextlib -import copy - -import webob.exc - -from neutron.api.v2 import attributes -from neutron.db.vpn import vpn_db -from neutron.extensions import vpnaas -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron.tests.unit.db.vpn import test_db_vpnaas -from neutron.tests.unit.vmware.vshield import test_edge_router - -_uuid = uuidutils.generate_uuid - - -class VPNTestExtensionManager( - test_edge_router.ServiceRouterTestExtensionManager): - - def get_resources(self): - # If l3 resources have been loaded and updated by main API - # router, update the map in the l3 extension so it will load - # the same attributes as the API router - resources = super(VPNTestExtensionManager, self).get_resources() - vpn_attr_map = copy.deepcopy(vpnaas.RESOURCE_ATTRIBUTE_MAP) - for res in vpnaas.RESOURCE_ATTRIBUTE_MAP.keys(): - attr_info = attributes.RESOURCE_ATTRIBUTE_MAP.get(res) - if attr_info: - vpnaas.RESOURCE_ATTRIBUTE_MAP[res] = attr_info - vpn_resources = vpnaas.Vpnaas.get_resources() - # restore the original resources once the controllers are created - vpnaas.RESOURCE_ATTRIBUTE_MAP = vpn_attr_map - resources.extend(vpn_resources) - return resources - - -class TestVpnPlugin(test_db_vpnaas.VPNTestMixin, - test_edge_router.ServiceRouterTest): - - def vcns_vpn_patch(self): - instance = self.vcns_instance - instance.return_value.update_ipsec_config.side_effect = ( - self.fc2.update_ipsec_config) - instance.return_value.get_ipsec_config.side_effect = ( - self.fc2.get_ipsec_config) - instance.return_value.delete_ipsec_config.side_effect = ( - self.fc2.delete_ipsec_config) - - def setUp(self): - # Save the global RESOURCE_ATTRIBUTE_MAP - self.saved_attr_map = {} - for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.items(): - self.saved_attr_map[resource] = attrs.copy() - - super(TestVpnPlugin, self).setUp(ext_mgr=VPNTestExtensionManager()) - self.vcns_vpn_patch() - self.plugin = manager.NeutronManager.get_plugin() - self.router_id = None - - def tearDown(self): - super(TestVpnPlugin, self).tearDown() - # Restore the global RESOURCE_ATTRIBUTE_MAP - attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map - self.ext_api = None - self.plugin = None - - @contextlib.contextmanager - def router(self, vlan_id=None, do_delete=True, **kwargs): - with self._create_l3_ext_network(vlan_id) as net: - with self.subnet(cidr='100.0.0.0/24', network=net) as s: - router_id = self._create_and_get_router(**kwargs) - self._add_external_gateway_to_router( - router_id, s['subnet']['network_id']) - router = self._show('routers', router_id) - yield router - if do_delete: - self._remove_external_gateway_from_router( - router_id, s['subnet']['network_id']) - self._delete('routers', router_id) - - def test_create_vpnservice(self, **extras): - """Test case to create a vpnservice.""" - description = 'my-vpn-service' - expected = {'name': 'vpnservice1', - 'description': 'my-vpn-service', - 'admin_state_up': True, - 'status': 'ACTIVE', - 'tenant_id': self._tenant_id, } - - expected.update(extras) - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - expected['router_id'] = router['router']['id'] - expected['subnet_id'] = subnet['subnet']['id'] - name = expected['name'] - with self.vpnservice(name=name, - subnet=subnet, - router=router, - description=description, - **extras) as vpnservice: - self.assertEqual(dict((k, v) for k, v in - vpnservice['vpnservice'].items() - if k in expected), - expected) - - def test_create_vpnservices_with_same_router(self, **extras): - """Test case to create two vpnservices with same router.""" - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - with self.vpnservice(name='vpnservice1', - subnet=subnet, - router=router): - res = self._create_vpnservice( - 'json', 'vpnservice2', True, - router_id=(router['router']['id']), - subnet_id=(subnet['subnet']['id'])) - self.assertEqual( - res.status_int, webob.exc.HTTPConflict.code) - - def test_create_vpnservice_with_invalid_router(self): - """Test case to create vpnservices with invalid router.""" - with self.subnet(cidr='10.2.0.0/24') as subnet: - with contextlib.nested( - self.router(arg_list=('service_router',), - service_router=False), - self.router(active_set=False)) as (r1, r2): - res = self._create_vpnservice( - 'json', 'vpnservice', True, - router_id='invalid_id', - subnet_id=(subnet['subnet']['id'])) - self.assertEqual( - res.status_int, webob.exc.HTTPBadRequest.code) - res = self._create_vpnservice( - 'json', 'vpnservice', True, - router_id=r1['router']['id'], - subnet_id=(subnet['subnet']['id'])) - self.assertEqual( - res.status_int, webob.exc.HTTPBadRequest.code) - res = self._create_vpnservice( - 'json', 'vpnservice', True, - router_id=r2['router']['id'], - subnet_id=(subnet['subnet']['id'])) - self.assertEqual( - res.status_int, - webob.exc.HTTPServiceUnavailable.code) - - def test_update_vpnservice(self): - """Test case to update a vpnservice.""" - name = 'new_vpnservice1' - expected = [('name', name)] - with contextlib.nested( - self.subnet(cidr='10.2.0.0/24'), - self.router()) as (subnet, router): - with self.vpnservice(name=name, - subnet=subnet, - router=router) as vpnservice: - expected.append(('subnet_id', - vpnservice['vpnservice']['subnet_id'])) - expected.append(('router_id', - vpnservice['vpnservice']['router_id'])) - data = {'vpnservice': {'name': name, - 'admin_state_up': False}} - expected.append(('admin_state_up', False)) - self._set_active(vpn_db.VPNService, - vpnservice['vpnservice']['id']) - req = self.new_update_request( - 'vpnservices', - data, - vpnservice['vpnservice']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in expected: - self.assertEqual(res['vpnservice'][k], v) - - def test_delete_vpnservice(self): - """Test case to delete a vpnservice.""" - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - with self.vpnservice(name='vpnservice', - subnet=subnet, - router=router, - no_delete=True) as vpnservice: - req = self.new_delete_request( - 'vpnservices', vpnservice['vpnservice']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - - def test_delete_router_in_use_by_vpnservice(self): - """Test delete router in use by vpn service.""" - with self.subnet(cidr='10.2.0.0/24') as subnet: - with self.router() as router: - with self.vpnservice(subnet=subnet, - router=router): - self._delete('routers', router['router']['id'], - expected_code=webob.exc.HTTPConflict.code) - - def _test_create_ipsec_site_connection(self, key_overrides=None, - ike_key_overrides=None, - ipsec_key_overrides=None, - setup_overrides=None, - expected_status_int=200): - """Create ipsec_site_connection and check results.""" - params = {'ikename': 'ikepolicy1', - 'ipsecname': 'ipsecpolicy1', - 'vpnsname': 'vpnservice1', - 'subnet_cidr': '10.2.0.0/24', - 'subnet_version': 4} - if setup_overrides: - params.update(setup_overrides) - expected = {'name': 'connection1', - 'description': 'my-ipsec-connection', - 'peer_address': '192.168.1.10', - 'peer_id': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'], - 'initiator': 'bi-directional', - 'mtu': 1500, - 'tenant_id': self._tenant_id, - 'psk': 'abcd', - 'status': 'ACTIVE', - 'admin_state_up': True} - if key_overrides: - expected.update(key_overrides) - - ike_expected = {'name': params['ikename'], - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'ike_version': 'v1', - 'pfs': 'group5'} - if ike_key_overrides: - ike_expected.update(ike_key_overrides) - - ipsec_expected = {'name': params['ipsecname'], - 'auth_algorithm': 'sha1', - 'encryption_algorithm': 'aes-128', - 'pfs': 'group5'} - if ipsec_key_overrides: - ipsec_expected.update(ipsec_key_overrides) - - dpd = {'action': 'hold', - 'interval': 40, - 'timeout': 120} - with contextlib.nested( - self.ikepolicy(self.fmt, ike_expected['name'], - ike_expected['auth_algorithm'], - ike_expected['encryption_algorithm'], - ike_version=ike_expected['ike_version'], - pfs=ike_expected['pfs']), - self.ipsecpolicy(self.fmt, ipsec_expected['name'], - ipsec_expected['auth_algorithm'], - ipsec_expected['encryption_algorithm'], - pfs=ipsec_expected['pfs']), - self.subnet(cidr=params['subnet_cidr'], - ip_version=params['subnet_version']), - self.router()) as ( - ikepolicy, ipsecpolicy, subnet, router): - with self.vpnservice(name=params['vpnsname'], subnet=subnet, - router=router) as vpnservice1: - expected['ikepolicy_id'] = ikepolicy['ikepolicy']['id'] - expected['ipsecpolicy_id'] = ( - ipsecpolicy['ipsecpolicy']['id'] - ) - expected['vpnservice_id'] = ( - vpnservice1['vpnservice']['id'] - ) - try: - with self.ipsec_site_connection( - self.fmt, - expected['name'], - expected['peer_address'], - expected['peer_id'], - expected['peer_cidrs'], - expected['mtu'], - expected['psk'], - expected['initiator'], - dpd['action'], - dpd['interval'], - dpd['timeout'], - vpnservice1, - ikepolicy, - ipsecpolicy, - expected['admin_state_up'], - description=expected['description'] - ) as ipsec_site_connection: - if expected_status_int != 200: - self.fail("Expected failure on create") - self._check_ipsec_site_connection( - ipsec_site_connection['ipsec_site_connection'], - expected, - dpd) - except webob.exc.HTTPClientError as ce: - self.assertEqual(ce.code, expected_status_int) - - def test_create_ipsec_site_connection(self, **extras): - """Test case to create an ipsec_site_connection.""" - self._test_create_ipsec_site_connection(key_overrides=extras) - - def test_create_ipsec_site_connection_invalid_ikepolicy(self): - self._test_create_ipsec_site_connection( - ike_key_overrides={'ike_version': 'v2'}, - expected_status_int=400) - - def test_create_ipsec_site_connection_invalid_ipsecpolicy(self): - self._test_create_ipsec_site_connection( - ipsec_key_overrides={'encryption_algorithm': 'aes-192'}, - expected_status_int=400) - self._test_create_ipsec_site_connection( - ipsec_key_overrides={'pfs': 'group14'}, - expected_status_int=400) - - def _test_update_ipsec_site_connection(self, - update={'name': 'new name'}, - overrides=None, - expected_status_int=200): - """Creates and then updates ipsec_site_connection.""" - expected = {'name': 'new_ipsec_site_connection', - 'ikename': 'ikepolicy1', - 'ipsecname': 'ipsecpolicy1', - 'vpnsname': 'vpnservice1', - 'description': 'my-ipsec-connection', - 'peer_address': '192.168.1.10', - 'peer_id': '192.168.1.10', - 'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'], - 'initiator': 'bi-directional', - 'mtu': 1500, - 'tenant_id': self._tenant_id, - 'psk': 'abcd', - 'status': 'ACTIVE', - 'admin_state_up': True, - 'action': 'hold', - 'interval': 40, - 'timeout': 120, - 'subnet_cidr': '10.2.0.0/24', - 'subnet_version': 4, - 'make_active': True} - if overrides: - expected.update(overrides) - - with contextlib.nested( - self.ikepolicy(name=expected['ikename']), - self.ipsecpolicy(name=expected['ipsecname']), - self.subnet(cidr=expected['subnet_cidr'], - ip_version=expected['subnet_version']), - self.router() - ) as (ikepolicy, ipsecpolicy, subnet, router): - with self.vpnservice(name=expected['vpnsname'], subnet=subnet, - router=router) as vpnservice1: - expected['vpnservice_id'] = vpnservice1['vpnservice']['id'] - expected['ikepolicy_id'] = ikepolicy['ikepolicy']['id'] - expected['ipsecpolicy_id'] = ipsecpolicy['ipsecpolicy']['id'] - with self.ipsec_site_connection( - self.fmt, - expected['name'], - expected['peer_address'], - expected['peer_id'], - expected['peer_cidrs'], - expected['mtu'], - expected['psk'], - expected['initiator'], - expected['action'], - expected['interval'], - expected['timeout'], - vpnservice1, - ikepolicy, - ipsecpolicy, - expected['admin_state_up'], - description=expected['description'] - ) as ipsec_site_connection: - data = {'ipsec_site_connection': update} - if expected.get('make_active'): - self._set_active( - vpn_db.IPsecSiteConnection, - (ipsec_site_connection['ipsec_site_connection'] - ['id'])) - req = self.new_update_request( - 'ipsec-site-connections', - data, - ipsec_site_connection['ipsec_site_connection']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(expected_status_int, res.status_int) - if expected_status_int == 200: - res_dict = self.deserialize(self.fmt, res) - for k, v in update.items(): - self.assertEqual( - res_dict['ipsec_site_connection'][k], v) - - def test_update_ipsec_site_connection(self): - """Test case for valid updates to IPSec site connection.""" - dpd = {'action': 'hold', - 'interval': 40, - 'timeout': 120} - self._test_update_ipsec_site_connection(update={'dpd': dpd}) - self._test_update_ipsec_site_connection(update={'mtu': 2000}) - - def test_delete_ipsec_site_connection(self): - """Test case to delete a ipsec_site_connection.""" - with self.ipsec_site_connection( - no_delete=True) as ipsec_site_connection: - req = self.new_delete_request( - 'ipsec-site-connections', - ipsec_site_connection['ipsec_site_connection']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204)