neutron/neutron/tests/unit/plugins/ml2/drivers/cisco/apic/test_cisco_apic_topology_ag...

207 lines
9.0 KiB
Python

# 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.
import sys
import mock
sys.modules["apicapi"] = mock.Mock()
from neutron.plugins.ml2.drivers.cisco.apic import apic_topology
from neutron.tests import base
from neutron.tests.unit.plugins.ml2.drivers.cisco.apic import (
test_cisco_apic_common as mocked)
NOTIFIER = ('neutron.plugins.ml2.drivers.cisco.apic.'
'apic_topology.ApicTopologyServiceNotifierApi')
RPC_CONNECTION = 'neutron.common.rpc.Connection'
AGENTS_DB = 'neutron.db.agents_db'
PERIODIC_TASK = 'neutron.openstack.common.periodic_task'
DEV_EXISTS = 'neutron.agent.linux.ip_lib.device_exists'
IP_DEVICE = 'neutron.agent.linux.ip_lib.IPDevice'
EXECUTE = 'neutron.agent.linux.utils.execute'
LLDP_CMD = ['lldpctl', '-f', 'keyvalue']
ETH0 = mocked.SERVICE_HOST_IFACE
LLDPCTL_RES = (
'lldp.' + ETH0 + '.via=LLDP\n'
'lldp.' + ETH0 + '.rid=1\n'
'lldp.' + ETH0 + '.age=0 day, 20:55:54\n'
'lldp.' + ETH0 + '.chassis.mac=' + mocked.SERVICE_HOST_MAC + '\n'
'lldp.' + ETH0 + '.chassis.name=' + mocked.SERVICE_PEER_CHASSIS_NAME + '\n'
'lldp.' + ETH0 + '.chassis.descr=' + mocked.SERVICE_PEER_CHASSIS + '\n'
'lldp.' + ETH0 + '.chassis.Bridge.enabled=on\n'
'lldp.' + ETH0 + '.chassis.Router.enabled=on\n'
'lldp.' + ETH0 + '.port.local=' + mocked.SERVICE_PEER_PORT_LOCAL + '\n'
'lldp.' + ETH0 + '.port.descr=' + mocked.SERVICE_PEER_PORT_DESC)
class TestCiscoApicTopologyService(base.BaseTestCase,
mocked.ControllerMixin,
mocked.ConfigMixin):
def setUp(self):
super(TestCiscoApicTopologyService, self).setUp()
mocked.ControllerMixin.set_up_mocks(self)
mocked.ConfigMixin.set_up_mocks(self)
# Patch notifier
notifier_c = mock.patch(NOTIFIER).start()
self.notifier = mock.Mock()
notifier_c.return_value = self.notifier
# Patch Connection
connection_c = mock.patch(RPC_CONNECTION).start()
self.connection = mock.Mock()
connection_c.return_value = self.connection
# Patch agents db
self.agents_db = mock.patch(AGENTS_DB).start()
self.service = apic_topology.ApicTopologyService()
self.service.apic_manager = mock.Mock()
def test_init_host(self):
self.service.init_host()
self.connection.create_consumer.ensure_called_once()
self.connection.consume_in_threads.ensure_called_once()
def test_update_link_add_nopeers(self):
self.service.peers = {}
args = (mocked.SERVICE_HOST, mocked.SERVICE_HOST_IFACE,
mocked.SERVICE_HOST_MAC, mocked.APIC_EXT_SWITCH,
mocked.APIC_EXT_MODULE, mocked.APIC_EXT_PORT)
self.service.update_link(None, *args)
self.service.apic_manager.add_hostlink.assert_called_once_with(*args)
self.assertEqual(args,
self.service.peers[(mocked.SERVICE_HOST,
mocked.SERVICE_HOST_IFACE)])
def test_update_link_add_with_peers_diff(self):
args = (mocked.SERVICE_HOST, mocked.SERVICE_HOST_IFACE,
mocked.SERVICE_HOST_MAC, mocked.APIC_EXT_SWITCH,
mocked.APIC_EXT_MODULE, mocked.APIC_EXT_PORT)
args_prime = args[:2] + tuple(x + '1' for x in args[2:])
self.service.peers = {args_prime[:2]: args_prime}
self.service.update_link(None, *args)
self.service.apic_manager.remove_hostlink.assert_called_once_with(
*args_prime)
self.service.apic_manager.add_hostlink.assert_called_once_with(*args)
self.assertEqual(
args, self.service.peers[
(mocked.SERVICE_HOST, mocked.SERVICE_HOST_IFACE)])
def test_update_link_add_with_peers_eq(self):
args = (mocked.SERVICE_HOST, mocked.SERVICE_HOST_IFACE,
mocked.SERVICE_HOST_MAC,
mocked.APIC_EXT_SWITCH,
mocked.APIC_EXT_MODULE, mocked.APIC_EXT_PORT)
self.service.peers = {args[:2]: args}
self.service.update_link(None, *args)
def test_update_link_rem_with_peers(self):
args = (mocked.SERVICE_HOST, mocked.SERVICE_HOST_IFACE,
mocked.SERVICE_HOST_MAC, 0,
mocked.APIC_EXT_MODULE, mocked.APIC_EXT_PORT)
self.service.peers = {args[:2]: args}
self.service.update_link(None, *args)
self.service.apic_manager.remove_hostlink.assert_called_once_with(
*args)
self.assertFalse(bool(self.service.peers))
def test_update_link_rem_no_peers(self):
args = (mocked.SERVICE_HOST, mocked.SERVICE_HOST_IFACE,
mocked.SERVICE_HOST_MAC, 0,
mocked.APIC_EXT_MODULE, mocked.APIC_EXT_PORT)
self.service.update_link(None, *args)
class TestCiscoApicTopologyAgent(base.BaseTestCase,
mocked.ControllerMixin,
mocked.ConfigMixin):
def setUp(self):
super(TestCiscoApicTopologyAgent, self).setUp()
mocked.ControllerMixin.set_up_mocks(self)
mocked.ConfigMixin.set_up_mocks(self)
# Patch notifier
notifier_c = mock.patch(NOTIFIER).start()
self.notifier = mock.Mock()
notifier_c.return_value = self.notifier
# Patch device_exists
self.dev_exists = mock.patch(DEV_EXISTS).start()
# Patch IPDevice
ipdev_c = mock.patch(IP_DEVICE).start()
self.ipdev = mock.Mock()
ipdev_c.return_value = self.ipdev
self.ipdev.link.address = mocked.SERVICE_HOST_MAC
# Patch execute
self.execute = mock.patch(EXECUTE).start()
self.execute.return_value = LLDPCTL_RES
# Patch tasks
self.periodic_task = mock.patch(PERIODIC_TASK).start()
self.agent = apic_topology.ApicTopologyAgent()
self.agent.host = mocked.SERVICE_HOST
self.agent.service_agent = mock.Mock()
self.agent.lldpcmd = LLDP_CMD
def test_init_host_device_exists(self):
self.agent.lldpcmd = None
self.dev_exists.return_value = True
self.agent.init_host()
self.assertEqual(LLDP_CMD + mocked.APIC_UPLINK_PORTS,
self.agent.lldpcmd)
def test_init_host_device_not_exist(self):
self.agent.lldpcmd = None
self.dev_exists.return_value = False
self.agent.init_host()
self.assertEqual(LLDP_CMD, self.agent.lldpcmd)
def test_get_peers(self):
self.agent.peers = {}
peers = self.agent._get_peers()
expected = [(mocked.SERVICE_HOST, mocked.SERVICE_HOST_IFACE,
mocked.SERVICE_HOST_MAC, mocked.APIC_EXT_SWITCH,
mocked.APIC_EXT_MODULE, mocked.APIC_EXT_PORT)]
self.assertEqual(expected,
peers[mocked.SERVICE_HOST_IFACE])
def test_check_for_new_peers_no_peers(self):
self.agent.peers = {}
expected = (mocked.SERVICE_HOST, mocked.SERVICE_HOST_IFACE,
mocked.SERVICE_HOST_MAC, mocked.APIC_EXT_SWITCH,
mocked.APIC_EXT_MODULE, mocked.APIC_EXT_PORT)
peers = {mocked.SERVICE_HOST_IFACE: [expected]}
context = mock.Mock()
with mock.patch.object(self.agent, '_get_peers',
return_value=peers):
self.agent._check_for_new_peers(context)
self.assertEqual(expected,
self.agent.peers[mocked.SERVICE_HOST_IFACE])
self.agent.service_agent.update_link.assert_called_once_with(
context, *expected)
def test_check_for_new_peers_with_peers(self):
expected = (mocked.SERVICE_HOST, mocked.SERVICE_HOST_IFACE,
mocked.SERVICE_HOST_MAC, mocked.APIC_EXT_SWITCH,
mocked.APIC_EXT_MODULE, mocked.APIC_EXT_PORT)
peers = {mocked.SERVICE_HOST_IFACE: [expected]}
self.agent.peers = {mocked.SERVICE_HOST_IFACE:
[tuple(x + '1' for x in expected)]}
context = mock.Mock()
with mock.patch.object(self.agent, '_get_peers',
return_value=peers):
self.agent._check_for_new_peers(context)
self.agent.service_agent.update_link.assert_called_with(
context, *expected)