From 28cd5bbe1a6d00f539ed3bf6b01e96aabd2e0fd5 Mon Sep 17 00:00:00 2001 From: Liping Mao Date: Wed, 17 Aug 2016 21:15:35 +0800 Subject: [PATCH] Add UT for update MTU in port binding Change-Id: Ia37ec055842aca9f5014e9e2b24093d9b57236c5 Partial-bug: #1613528 --- kuryr/lib/config.py | 2 +- kuryr/tests/unit/base.py | 91 ++++++++++++++++++++++++++++++++ kuryr/tests/unit/test_binding.py | 89 +++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 kuryr/tests/unit/test_binding.py diff --git a/kuryr/lib/config.py b/kuryr/lib/config.py index 9a44c048..38c3a2ef 100644 --- a/kuryr/lib/config.py +++ b/kuryr/lib/config.py @@ -25,7 +25,7 @@ core_opts = [ cfg.StrOpt('bindir', - default='$pybasedir/usr/libexec/kuryr', + default='/usr/libexec/kuryr', help=_('Directory for Kuryr vif binding executables.')), cfg.StrOpt('subnetpool_name_prefix', default='kuryrPool', diff --git a/kuryr/tests/unit/base.py b/kuryr/tests/unit/base.py index df6bb37c..8400c5e3 100644 --- a/kuryr/tests/unit/base.py +++ b/kuryr/tests/unit/base.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +from kuryr.lib import constants as const from oslotest import base @@ -18,3 +19,93 @@ class TestCase(base.BaseTestCase): def setUp(self): super(TestCase, self).setUp() + + @staticmethod + def _get_fake_networks(neutron_network_id): + fake_networks_response = { + "networks": [{ + "status": "ACTIVE", + "subnets": [], + "name": "fake_network", + "admin_state_up": True, + "tenant_id": "9bacb3c5d39d41a79512987f338cf177", + "router:external": False, + "segments": [], + "shared": False, + "id": neutron_network_id + }] + } + return fake_networks_response + + @staticmethod + def _get_fake_subnets(docker_endpoint_id, neutron_network_id, + fake_neutron_subnet_v4_id, + fake_neutron_subnet_v6_id): + # The following fake response is retrieved from the Neutron doc: + # http://developer.openstack.org/api-ref-networking-v2.html#createSubnet # noqa + fake_subnet_response = { + "subnets": [ + {"name": '-'.join([docker_endpoint_id, '192.168.1.0']), + "network_id": neutron_network_id, + "tenant_id": "c1210485b2424d48804aad5d39c61b8f", + "allocation_pools": [{"start": "192.168.1.2", + "end": "192.168.1.254"}], + "gateway_ip": "192.168.1.1", + "ip_version": 4, + "cidr": "192.168.1.0/24", + "id": fake_neutron_subnet_v4_id, + "enable_dhcp": True, + "subnetpool_id": ''}, + {"name": '-'.join([docker_endpoint_id, 'fe80::']), + "network_id": neutron_network_id, + "tenant_id": "c1210485b2424d48804aad5d39c61b8f", + "allocation_pools": [{"start": "fe80::f816:3eff:fe20:57c4", + "end": "fe80::ffff:ffff:ffff:ffff"}], + "gateway_ip": "fe80::f816:3eff:fe20:57c3", + "ip_version": 6, + "cidr": "fe80::/64", + "id": fake_neutron_subnet_v6_id, + "enable_dhcp": True, + "subnetpool_id": ''} + ] + } + return fake_subnet_response + + @staticmethod + def _get_fake_port(docker_endpoint_id, neutron_network_id, + neutron_port_id, + neutron_port_status=const.PORT_STATUS_DOWN, + neutron_subnet_v4_id=None, + neutron_subnet_v6_id=None, + neutron_subnet_v4_address="192.168.1.2", + neutron_subnet_v6_address="fe80::f816:3eff:fe20:57c4"): + # The following fake response is retrieved from the Neutron doc: + # http://developer.openstack.org/api-ref-networking-v2.html#createPort # noqa + fake_port = { + 'port': { + "status": neutron_port_status, + "name": docker_endpoint_id + '-port', + "allowed_address_pairs": [], + "admin_state_up": True, + "network_id": neutron_network_id, + "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa", + "device_owner": "", + "mac_address": "fa:16:3e:20:57:c3", + "fixed_ips": [], + "id": neutron_port_id, + "security_groups": [], + "device_id": "" + } + } + + if neutron_subnet_v4_id: + fake_port['port']['fixed_ips'].append({ + "subnet_id": neutron_subnet_v4_id, + "ip_address": neutron_subnet_v4_address + }) + if neutron_subnet_v6_id: + fake_port['port']['fixed_ips'].append({ + "subnet_id": neutron_subnet_v6_id, + "ip_address": neutron_subnet_v6_address + }) + return fake_port diff --git a/kuryr/tests/unit/test_binding.py b/kuryr/tests/unit/test_binding.py new file mode 100644 index 00000000..d3bcec8d --- /dev/null +++ b/kuryr/tests/unit/test_binding.py @@ -0,0 +1,89 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# 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 ddt +import mock +import uuid + +from kuryr.lib import binding +from kuryr.lib import constants +from kuryr.lib import utils +from kuryr.tests.unit import base +from mock import call + +mock_create = mock.MagicMock() +mock_interface = mock.MagicMock() + + +@ddt.ddt +class BindingTest(base.TestCase): + """Unit tests for binding.""" + + @ddt.data((False), (True)) + def test_is_up(self, interface_flag): + fake_interface = {'flags': 0x0} + if interface_flag: + fake_interface['flags'] = binding.IFF_UP + self.assertEqual(True, binding._is_up(fake_interface)) + else: + self.assertEqual(False, binding._is_up(fake_interface)) + + @mock.patch('os.path.exists', return_value=True) + @mock.patch('oslo_concurrency.processutils.execute', + return_value=('fake_stdout', 'fake_stderr')) + @mock.patch('pyroute2.ipdb.interface.InterfacesDict.__getattribute__', + return_value=mock_create) + @mock.patch('pyroute2.ipdb.interface.InterfacesDict.__getitem__', + return_value=mock_interface) + def test_port_bind(self, mock_getattribute, mock_getitem, + mock_execute, mock_path_exists): + fake_mtu = 1450 + fake_docker_network_id = utils.get_hash() + fake_docker_endpoint_id = utils.get_hash() + fake_port_id = str(uuid.uuid4()) + fake_neutron_v4_subnet_id = str(uuid.uuid4()) + fake_neutron_v6_subnet_id = str(uuid.uuid4()) + fake_port = self._get_fake_port( + fake_docker_endpoint_id, fake_docker_network_id, + fake_port_id, constants.PORT_STATUS_ACTIVE, + fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id) + fake_subnets = self._get_fake_subnets( + fake_docker_endpoint_id, fake_docker_network_id, + fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id) + fake_network = self._get_fake_networks(fake_docker_network_id) + fake_network['networks'][0]['mtu'] = fake_mtu + + binding.port_bind(fake_docker_endpoint_id, fake_port['port'], + fake_subnets['subnets'], fake_network['networks'][0]) + + expect_calls = [call.__enter__().set_mtu(fake_mtu), + call.__enter__().up()] + mock_interface.assert_has_calls(expect_calls, any_order=True) + mock_path_exists.assert_called_once() + mock_execute.assert_called_once() + + @mock.patch('kuryr.lib.binding.cleanup_veth') + @mock.patch('oslo_concurrency.processutils.execute', + return_value=('fake_stdout', 'fake_stderr')) + def test_port_unbind(self, mock_execute, mock_cleanup_veth): + fake_docker_network_id = utils.get_hash() + fake_docker_endpoint_id = utils.get_hash() + fake_port_id = str(uuid.uuid4()) + fake_neutron_v4_subnet_id = str(uuid.uuid4()) + fake_neutron_v6_subnet_id = str(uuid.uuid4()) + fake_port = self._get_fake_port( + fake_docker_endpoint_id, fake_docker_network_id, + fake_port_id, constants.PORT_STATUS_ACTIVE, + fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id) + binding.port_unbind(fake_docker_endpoint_id, fake_port['port']) + mock_execute.assert_called_once() + mock_cleanup_veth.assert_called_once()