1 Description: Disable udev tests
2 udev is not always avaliable in Ubuntu buildds; skip tests that
3 want to use this feature.
4 Author: Chuck Short <zulcss@ubuntu.com>
6 diff -Naurp neutron-2014.1.b2.orig/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py neutron-2014.1.b2/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py
7 --- neutron-2014.1.b2.orig/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py 2014-01-23 10:13:25.000000000 -0500
8 +++ neutron-2014.1.b2/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py 2014-02-03 08:53:04.409255073 -0500
9 @@ -46,6 +46,7 @@ class FakeIpDevice(object):
10 class TestLinuxBridge(base.BaseTestCase):
13 + self.skipTest("udev not consistently available in Ubuntu buildds")
14 super(TestLinuxBridge, self).setUp()
15 self.addCleanup(cfg.CONF.reset)
16 interface_mappings = {'physnet1': 'eth1'}
17 @@ -109,6 +110,7 @@ class TestLinuxBridgeAgent(base.BaseTest
18 self.get_mac.return_value = '00:00:00:00:00:01'
20 def test_update_devices_failed(self):
21 + self.skipTest("udev not consistently available in Ubuntu buildds")
22 agent = linuxbridge_neutron_agent.LinuxBridgeNeutronAgentRPC({},
25 @@ -130,6 +132,7 @@ class TestLinuxBridgeAgent(base.BaseTest
26 self.assertEqual(3, log.call_count)
28 def test_process_network_devices_failed(self):
29 + self.skipTest("udev not consistently available in Ubuntu buildds")
30 device_info = {'current': [1, 2, 3]}
31 agent = linuxbridge_neutron_agent.LinuxBridgeNeutronAgentRPC({},
33 @@ -158,6 +161,7 @@ class TestLinuxBridgeAgent(base.BaseTest
35 class TestLinuxBridgeManager(base.BaseTestCase):
37 + self.skipTest("udev not consistently available in Ubuntu buildds")
38 super(TestLinuxBridgeManager, self).setUp()
39 self.interface_mappings = {'physnet1': 'eth1'}
40 self.root_helper = cfg.CONF.AGENT.root_helper
41 @@ -667,6 +671,7 @@ class TestLinuxBridgeManager(base.BaseTe
43 class TestLinuxBridgeRpcCallbacks(base.BaseTestCase):
45 + self.skipTest("udev not consistently available in Ubuntu buildds")
46 cfg.CONF.set_override('local_ip', LOCAL_IP, 'VXLAN')
47 self.addCleanup(cfg.CONF.reset)
48 super(TestLinuxBridgeRpcCallbacks, self).setUp()
49 diff -Naurp neutron-2014.1.b2.orig/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py.orig neutron-2014.1.b2/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py.orig
50 --- neutron-2014.1.b2.orig/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py.orig 1969-12-31 19:00:00.000000000 -0500
51 +++ neutron-2014.1.b2/neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py.orig 2014-01-23 10:13:25.000000000 -0500
53 +# vim: tabstop=4 shiftwidth=4 softtabstop=4
55 +# Copyright (c) 2012 OpenStack Foundation.
57 +# Licensed under the Apache License, Version 2.0 (the "License"); you may
58 +# not use this file except in compliance with the License. You may obtain
59 +# a copy of the License at
61 +# http://www.apache.org/licenses/LICENSE-2.0
63 +# Unless required by applicable law or agreed to in writing, software
64 +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
65 +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
66 +# License for the specific language governing permissions and limitations
73 +from oslo.config import cfg
76 +from neutron.agent.linux import ip_lib
77 +from neutron.agent.linux import utils
78 +from neutron.common import constants
79 +from neutron.openstack.common.rpc import common as rpc_common
80 +from neutron.plugins.common import constants as p_const
81 +from neutron.plugins.linuxbridge.agent import linuxbridge_neutron_agent
82 +from neutron.plugins.linuxbridge.common import constants as lconst
83 +from neutron.tests import base
85 +LOCAL_IP = '192.168.0.33'
88 +class FakeIpLinkCommand(object):
93 +class FakeIpDevice(object):
95 + self.link = FakeIpLinkCommand()
98 +class TestLinuxBridge(base.BaseTestCase):
101 + super(TestLinuxBridge, self).setUp()
102 + self.addCleanup(cfg.CONF.reset)
103 + interface_mappings = {'physnet1': 'eth1'}
104 + root_helper = cfg.CONF.AGENT.root_helper
106 + self.linux_bridge = linuxbridge_neutron_agent.LinuxBridgeManager(
107 + interface_mappings, root_helper)
109 + def test_ensure_physical_in_bridge_invalid(self):
110 + result = self.linux_bridge.ensure_physical_in_bridge('network_id',
114 + self.assertFalse(result)
116 + def test_ensure_physical_in_bridge_flat(self):
117 + with mock.patch.object(self.linux_bridge,
118 + 'ensure_flat_bridge') as flat_bridge_func:
119 + self.linux_bridge.ensure_physical_in_bridge(
120 + 'network_id', p_const.TYPE_FLAT, 'physnet1', None)
121 + self.assertTrue(flat_bridge_func.called)
123 + def test_ensure_physical_in_bridge_vlan(self):
124 + with mock.patch.object(self.linux_bridge,
125 + 'ensure_vlan_bridge') as vlan_bridge_func:
126 + self.linux_bridge.ensure_physical_in_bridge(
127 + 'network_id', p_const.TYPE_VLAN, 'physnet1', 7)
128 + self.assertTrue(vlan_bridge_func.called)
130 + def test_ensure_physical_in_bridge_vxlan(self):
131 + self.linux_bridge.vxlan_mode = lconst.VXLAN_UCAST
132 + with mock.patch.object(self.linux_bridge,
133 + 'ensure_vxlan_bridge') as vxlan_bridge_func:
134 + self.linux_bridge.ensure_physical_in_bridge(
135 + 'network_id', 'vxlan', 'physnet1', 7)
136 + self.assertTrue(vxlan_bridge_func.called)
139 +class TestLinuxBridgeAgent(base.BaseTestCase):
142 + '1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue \\'
144 + 'link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00',
145 + '2: eth77: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 \\'
146 + 'qdisc mq state UP qlen 1000\ link/ether \\'
147 + 'cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff']
150 + super(TestLinuxBridgeAgent, self).setUp()
151 + cfg.CONF.set_override('rpc_backend',
152 + 'neutron.openstack.common.rpc.impl_fake')
153 + self.execute_p = mock.patch.object(ip_lib.IPWrapper, '_execute')
154 + self.execute = self.execute_p.start()
155 + self.addCleanup(self.execute_p.stop)
156 + self.execute.return_value = '\n'.join(self.LINK_SAMPLE)
157 + self.get_mac_p = mock.patch('neutron.agent.linux.utils.'
158 + 'get_interface_mac')
159 + self.get_mac = self.get_mac_p.start()
160 + self.addCleanup(self.get_mac_p.stop)
161 + self.get_mac.return_value = '00:00:00:00:00:01'
163 + def test_update_devices_failed(self):
164 + agent = linuxbridge_neutron_agent.LinuxBridgeNeutronAgentRPC({},
167 + raise_exception = [0]
169 + def info_mock(msg):
170 + if raise_exception[0] < 2:
171 + raise_exception[0] += 1
173 + raise RuntimeError()
174 + with mock.patch.object(agent.br_mgr,
175 + "update_devices") as update_devices:
176 + update_devices.side_effect = RuntimeError
177 + with mock.patch.object(linuxbridge_neutron_agent.LOG,
179 + log.side_effect = info_mock
180 + with testtools.ExpectedException(RuntimeError):
181 + agent.daemon_loop()
182 + self.assertEqual(3, log.call_count)
184 + def test_process_network_devices_failed(self):
185 + device_info = {'current': [1, 2, 3]}
186 + agent = linuxbridge_neutron_agent.LinuxBridgeNeutronAgentRPC({},
189 + raise_exception = [0]
191 + def info_mock(msg):
192 + if raise_exception[0] < 2:
193 + raise_exception[0] += 1
195 + raise RuntimeError()
197 + with mock.patch.object(agent.br_mgr,
198 + "update_devices") as update_devices:
199 + update_devices.side_effect = device_info
200 + with contextlib.nested(
201 + mock.patch.object(linuxbridge_neutron_agent.LOG, 'info'),
202 + mock.patch.object(agent, 'process_network_devices')
203 + ) as (log, process_network_devices):
204 + log.side_effect = info_mock
205 + process_network_devices.side_effect = RuntimeError
206 + with testtools.ExpectedException(RuntimeError):
207 + agent.daemon_loop()
208 + self.assertEqual(3, log.call_count)
211 +class TestLinuxBridgeManager(base.BaseTestCase):
213 + super(TestLinuxBridgeManager, self).setUp()
214 + self.interface_mappings = {'physnet1': 'eth1'}
215 + self.root_helper = cfg.CONF.AGENT.root_helper
217 + self.lbm = linuxbridge_neutron_agent.LinuxBridgeManager(
218 + self.interface_mappings, self.root_helper)
220 + def test_device_exists(self):
221 + with mock.patch.object(utils, 'execute') as execute_fn:
222 + self.assertTrue(self.lbm.device_exists("eth0"))
223 + execute_fn.side_effect = RuntimeError()
224 + self.assertFalse(self.lbm.device_exists("eth0"))
226 + def test_interface_exists_on_bridge(self):
227 + with mock.patch.object(os, 'listdir') as listdir_fn:
228 + listdir_fn.return_value = ["abc"]
230 + self.lbm.interface_exists_on_bridge("br-int", "abc")
233 + self.lbm.interface_exists_on_bridge("br-int", "abd")
236 + def test_get_bridge_name(self):
237 + nw_id = "123456789101112"
238 + self.assertEqual(self.lbm.get_bridge_name(nw_id),
239 + "brq" + nw_id[0:11])
241 + self.assertEqual(self.lbm.get_bridge_name(nw_id),
244 + def test_get_subinterface_name(self):
245 + self.assertEqual(self.lbm.get_subinterface_name("eth0", "0"),
247 + self.assertEqual(self.lbm.get_subinterface_name("eth0", ""),
250 + def test_get_tap_device_name(self):
251 + if_id = "123456789101112"
252 + self.assertEqual(self.lbm.get_tap_device_name(if_id),
253 + "tap" + if_id[0:11])
255 + self.assertEqual(self.lbm.get_tap_device_name(if_id),
258 + def test_get_vxlan_device_name(self):
259 + vn_id = constants.MAX_VXLAN_VNI
260 + self.assertEqual(self.lbm.get_vxlan_device_name(vn_id),
261 + "vxlan-" + str(vn_id))
262 + self.assertIsNone(self.lbm.get_vxlan_device_name(vn_id + 1))
264 + def test_get_all_neutron_bridges(self):
265 + br_list = ["br-int", "brq1", "brq2", "br-ex"]
266 + with mock.patch.object(os, 'listdir') as listdir_fn:
267 + listdir_fn.return_value = br_list
268 + self.assertEqual(self.lbm.get_all_neutron_bridges(),
270 + self.assertTrue(listdir_fn.called)
272 + def test_get_interfaces_on_bridge(self):
273 + with contextlib.nested(
274 + mock.patch.object(utils, 'execute'),
275 + mock.patch.object(os, 'listdir')
276 + ) as (exec_fn, listdir_fn):
277 + listdir_fn.return_value = ["qbr1"]
278 + self.assertEqual(self.lbm.get_interfaces_on_bridge("br0"),
281 + def test_get_tap_devices_count(self):
282 + with mock.patch.object(os, 'listdir') as listdir_fn:
283 + listdir_fn.return_value = ['tap2101', 'eth0.100', 'vxlan-1000']
284 + self.assertEqual(self.lbm.get_tap_devices_count('br0'), 1)
285 + listdir_fn.side_effect = OSError()
286 + self.assertEqual(self.lbm.get_tap_devices_count('br0'), 0)
288 + def test_get_interface_by_ip(self):
289 + with contextlib.nested(
290 + mock.patch.object(ip_lib.IPWrapper, 'get_devices'),
291 + mock.patch.object(ip_lib.IpAddrCommand, 'list')
292 + ) as (get_dev_fn, ip_list_fn):
293 + device = mock.Mock()
294 + device.name = 'dev_name'
295 + get_dev_fn.return_value = [device]
296 + ip_list_fn.returnvalue = mock.Mock()
297 + self.assertEqual(self.lbm.get_interface_by_ip(LOCAL_IP),
300 + def test_get_bridge_for_tap_device(self):
301 + with contextlib.nested(
302 + mock.patch.object(self.lbm, "get_all_neutron_bridges"),
303 + mock.patch.object(self.lbm, "get_interfaces_on_bridge")
304 + ) as (get_all_qbr_fn, get_if_fn):
305 + get_all_qbr_fn.return_value = ["br-int", "br-ex"]
306 + get_if_fn.return_value = ["tap1", "tap2", "tap3"]
307 + self.assertEqual(self.lbm.get_bridge_for_tap_device("tap1"),
309 + self.assertIsNone(self.lbm.get_bridge_for_tap_device("tap4"))
311 + def test_is_device_on_bridge(self):
312 + self.assertTrue(not self.lbm.is_device_on_bridge(""))
313 + with mock.patch.object(os.path, 'exists') as exists_fn:
314 + exists_fn.return_value = True
315 + self.assertTrue(self.lbm.is_device_on_bridge("tap1"))
316 + exists_fn.assert_called_with(
317 + "/sys/devices/virtual/net/tap1/brport"
320 + def test_get_interface_details(self):
321 + with contextlib.nested(
322 + mock.patch.object(ip_lib.IpAddrCommand, 'list'),
323 + mock.patch.object(ip_lib.IpRouteCommand, 'get_gateway')
324 + ) as (list_fn, getgw_fn):
325 + gwdict = dict(gateway='1.1.1.1')
326 + getgw_fn.return_value = gwdict
327 + ipdict = dict(cidr='1.1.1.1/24',
328 + broadcast='1.1.1.255',
332 + list_fn.return_value = ipdict
333 + ret = self.lbm.get_interface_details("eth0")
335 + self.assertTrue(list_fn.called)
336 + self.assertTrue(getgw_fn.called)
337 + self.assertEqual(ret, (ipdict, gwdict))
339 + def test_ensure_flat_bridge(self):
340 + with contextlib.nested(
341 + mock.patch.object(ip_lib.IpAddrCommand, 'list'),
342 + mock.patch.object(ip_lib.IpRouteCommand, 'get_gateway')
343 + ) as (list_fn, getgw_fn):
344 + gwdict = dict(gateway='1.1.1.1')
345 + getgw_fn.return_value = gwdict
346 + ipdict = dict(cidr='1.1.1.1/24',
347 + broadcast='1.1.1.255',
351 + list_fn.return_value = ipdict
352 + with mock.patch.object(self.lbm, 'ensure_bridge') as ens:
354 + self.lbm.ensure_flat_bridge("123", "eth0"),
357 + self.assertTrue(list_fn.called)
358 + self.assertTrue(getgw_fn.called)
359 + ens.assert_called_once_with("brq123", "eth0",
362 + def test_ensure_vlan_bridge(self):
363 + with contextlib.nested(
364 + mock.patch.object(self.lbm, 'ensure_vlan'),
365 + mock.patch.object(self.lbm, 'ensure_bridge'),
366 + mock.patch.object(self.lbm, 'get_interface_details'),
367 + ) as (ens_vl_fn, ens, get_int_det_fn):
368 + ens_vl_fn.return_value = "eth0.1"
369 + get_int_det_fn.return_value = (None, None)
370 + self.assertEqual(self.lbm.ensure_vlan_bridge("123", "eth0", "1"),
372 + ens.assert_called_with("brq123", "eth0.1", None, None)
374 + get_int_det_fn.return_value = ("ips", "gateway")
375 + self.assertEqual(self.lbm.ensure_vlan_bridge("123", "eth0", "1"),
377 + ens.assert_called_with("brq123", "eth0.1", "ips", "gateway")
379 + def test_ensure_local_bridge(self):
380 + with mock.patch.object(self.lbm, 'ensure_bridge') as ens_fn:
381 + self.lbm.ensure_local_bridge("54321")
382 + ens_fn.assert_called_once_with("brq54321")
384 + def test_ensure_vlan(self):
385 + with mock.patch.object(self.lbm, 'device_exists') as de_fn:
386 + de_fn.return_value = True
387 + self.assertEqual(self.lbm.ensure_vlan("eth0", "1"), "eth0.1")
388 + de_fn.return_value = False
389 + with mock.patch.object(utils, 'execute') as exec_fn:
390 + exec_fn.return_value = False
391 + self.assertEqual(self.lbm.ensure_vlan("eth0", "1"), "eth0.1")
392 + exec_fn.assert_called_twice()
393 + exec_fn.return_value = True
394 + self.assertIsNone(self.lbm.ensure_vlan("eth0", "1"))
395 + exec_fn.assert_called_once()
397 + def test_ensure_vxlan(self):
398 + seg_id = "12345678"
399 + self.lbm.local_int = 'eth0'
400 + self.lbm.vxlan_mode = lconst.VXLAN_MCAST
401 + with mock.patch.object(self.lbm, 'device_exists') as de_fn:
402 + de_fn.return_value = True
403 + self.assertEqual(self.lbm.ensure_vxlan(seg_id), "vxlan-" + seg_id)
404 + de_fn.return_value = False
405 + with mock.patch.object(self.lbm.ip,
406 + 'add_vxlan') as add_vxlan_fn:
407 + add_vxlan_fn.return_value = FakeIpDevice()
408 + self.assertEqual(self.lbm.ensure_vxlan(seg_id),
410 + add_vxlan_fn.assert_called_with("vxlan-" + seg_id, seg_id,
412 + dev=self.lbm.local_int)
413 + cfg.CONF.set_override('l2_population', 'True', 'VXLAN')
414 + self.assertEqual(self.lbm.ensure_vxlan(seg_id),
416 + add_vxlan_fn.assert_called_with("vxlan-" + seg_id, seg_id,
418 + dev=self.lbm.local_int,
421 + def test_update_interface_ip_details(self):
422 + gwdict = dict(gateway='1.1.1.1',
424 + ipdict = dict(cidr='1.1.1.1/24',
425 + broadcast='1.1.1.255',
429 + with contextlib.nested(
430 + mock.patch.object(ip_lib.IpAddrCommand, 'add'),
431 + mock.patch.object(ip_lib.IpAddrCommand, 'delete')
432 + ) as (add_fn, del_fn):
433 + self.lbm.update_interface_ip_details("br0", "eth0",
435 + self.assertTrue(add_fn.called)
436 + self.assertTrue(del_fn.called)
438 + with contextlib.nested(
439 + mock.patch.object(ip_lib.IpRouteCommand, 'add_gateway'),
440 + mock.patch.object(ip_lib.IpRouteCommand, 'delete_gateway')
441 + ) as (addgw_fn, delgw_fn):
442 + self.lbm.update_interface_ip_details("br0", "eth0",
444 + self.assertTrue(addgw_fn.called)
445 + self.assertTrue(delgw_fn.called)
447 + def test_ensure_bridge(self):
448 + with contextlib.nested(
449 + mock.patch.object(self.lbm, 'device_exists'),
450 + mock.patch.object(utils, 'execute'),
451 + mock.patch.object(self.lbm, 'update_interface_ip_details'),
452 + mock.patch.object(self.lbm, 'interface_exists_on_bridge'),
453 + mock.patch.object(self.lbm, 'is_device_on_bridge'),
454 + mock.patch.object(self.lbm, 'get_bridge_for_tap_device'),
455 + ) as (de_fn, exec_fn, upd_fn, ie_fn, if_br_fn, get_if_br_fn):
456 + de_fn.return_value = False
457 + exec_fn.return_value = False
458 + self.assertEqual(self.lbm.ensure_bridge("br0", None), "br0")
459 + ie_fn.return_Value = False
460 + self.lbm.ensure_bridge("br0", "eth0")
461 + upd_fn.assert_called_with("br0", "eth0", None, None)
462 + ie_fn.assert_called_with("br0", "eth0")
464 + self.lbm.ensure_bridge("br0", "eth0", "ips", "gateway")
465 + upd_fn.assert_called_with("br0", "eth0", "ips", "gateway")
466 + ie_fn.assert_called_with("br0", "eth0")
468 + exec_fn.side_effect = Exception()
469 + de_fn.return_value = True
470 + self.lbm.ensure_bridge("br0", "eth0")
471 + ie_fn.assert_called_with("br0", "eth0")
473 + exec_fn.reset_mock()
474 + exec_fn.side_effect = None
475 + de_fn.return_value = True
476 + ie_fn.return_value = False
477 + get_if_br_fn.return_value = "br1"
478 + self.lbm.ensure_bridge("br0", "eth0")
480 + mock.call(['brctl', 'delif', 'br1', 'eth0'],
481 + root_helper=self.root_helper),
482 + mock.call(['brctl', 'addif', 'br0', 'eth0'],
483 + root_helper=self.root_helper),
485 + exec_fn.assert_has_calls(expected)
487 + def test_ensure_physical_in_bridge(self):
489 + self.lbm.ensure_physical_in_bridge("123", p_const.TYPE_VLAN,
492 + with mock.patch.object(self.lbm, "ensure_flat_bridge") as flbr_fn:
494 + self.lbm.ensure_physical_in_bridge("123", p_const.TYPE_FLAT,
497 + self.assertTrue(flbr_fn.called)
498 + with mock.patch.object(self.lbm, "ensure_vlan_bridge") as vlbr_fn:
500 + self.lbm.ensure_physical_in_bridge("123", p_const.TYPE_VLAN,
503 + self.assertTrue(vlbr_fn.called)
505 + with mock.patch.object(self.lbm, "ensure_vxlan_bridge") as vlbr_fn:
506 + self.lbm.vxlan_mode = lconst.VXLAN_MCAST
508 + self.lbm.ensure_physical_in_bridge("123", p_const.TYPE_VXLAN,
511 + self.assertTrue(vlbr_fn.called)
513 + def test_add_tap_interface(self):
514 + with mock.patch.object(self.lbm, "device_exists") as de_fn:
515 + de_fn.return_value = False
517 + self.lbm.add_tap_interface("123", p_const.TYPE_VLAN,
518 + "physnet1", "1", "tap1")
521 + de_fn.return_value = True
522 + with contextlib.nested(
523 + mock.patch.object(self.lbm, "ensure_local_bridge"),
524 + mock.patch.object(utils, "execute"),
525 + mock.patch.object(self.lbm, "get_bridge_for_tap_device")
526 + ) as (en_fn, exec_fn, get_br):
527 + exec_fn.return_value = False
528 + get_br.return_value = True
529 + self.assertTrue(self.lbm.add_tap_interface("123",
530 + p_const.TYPE_LOCAL,
533 + en_fn.assert_called_with("123")
535 + get_br.return_value = False
536 + exec_fn.return_value = True
537 + self.assertFalse(self.lbm.add_tap_interface("123",
538 + p_const.TYPE_LOCAL,
542 + with mock.patch.object(self.lbm,
543 + "ensure_physical_in_bridge") as ens_fn:
544 + ens_fn.return_value = False
545 + self.assertFalse(self.lbm.add_tap_interface("123",
550 + def test_add_interface(self):
551 + with mock.patch.object(self.lbm, "add_tap_interface") as add_tap:
552 + self.lbm.add_interface("123", p_const.TYPE_VLAN, "physnet-1",
554 + add_tap.assert_called_with("123", p_const.TYPE_VLAN, "physnet-1",
557 + def test_delete_vlan_bridge(self):
558 + with contextlib.nested(
559 + mock.patch.object(self.lbm, "device_exists"),
560 + mock.patch.object(self.lbm, "get_interfaces_on_bridge"),
561 + mock.patch.object(self.lbm, "remove_interface"),
562 + mock.patch.object(self.lbm, "get_interface_details"),
563 + mock.patch.object(self.lbm, "update_interface_ip_details"),
564 + mock.patch.object(self.lbm, "delete_vlan"),
565 + mock.patch.object(self.lbm, "delete_vxlan"),
566 + mock.patch.object(utils, "execute")
567 + ) as (de_fn, getif_fn, remif_fn, if_det_fn,
568 + updif_fn, del_vlan, del_vxlan, exec_fn):
569 + de_fn.return_value = False
570 + self.lbm.delete_vlan_bridge("br0")
571 + self.assertFalse(getif_fn.called)
573 + de_fn.return_value = True
574 + getif_fn.return_value = ["eth0", "eth1.1", "eth1", "vxlan-1002"]
575 + if_det_fn.return_value = ("ips", "gateway")
576 + exec_fn.return_value = False
577 + self.lbm.delete_vlan_bridge("br0")
578 + updif_fn.assert_called_with("eth1", "br0", "ips", "gateway")
579 + del_vlan.assert_called_with("eth1.1")
580 + del_vxlan.assert_called_with("vxlan-1002")
582 + def test_delete_vxlan_bridge_no_int_mappings(self):
583 + interface_mappings = {}
584 + lbm = linuxbridge_neutron_agent.LinuxBridgeManager(
585 + interface_mappings, self.root_helper)
587 + with contextlib.nested(
588 + mock.patch.object(lbm, "device_exists"),
589 + mock.patch.object(lbm, "get_interfaces_on_bridge"),
590 + mock.patch.object(lbm, "remove_interface"),
591 + mock.patch.object(lbm, "delete_vxlan"),
592 + mock.patch.object(utils, "execute")
593 + ) as (de_fn, getif_fn, remif_fn, del_vxlan, exec_fn):
594 + de_fn.return_value = False
595 + lbm.delete_vlan_bridge("br0")
596 + self.assertFalse(getif_fn.called)
598 + de_fn.return_value = True
599 + getif_fn.return_value = ["vxlan-1002"]
600 + exec_fn.return_value = False
601 + lbm.delete_vlan_bridge("br0")
602 + del_vxlan.assert_called_with("vxlan-1002")
604 + def test_remove_empty_bridges(self):
605 + self.lbm.network_map = {'net1': mock.Mock(), 'net2': mock.Mock()}
607 + def tap_count_side_effect(*args):
608 + return 0 if args[0] == 'brqnet1' else 1
610 + with contextlib.nested(
611 + mock.patch.object(self.lbm, "delete_vlan_bridge"),
612 + mock.patch.object(self.lbm, "get_tap_devices_count",
613 + side_effect=tap_count_side_effect),
614 + ) as (del_br_fn, count_tap_fn):
615 + self.lbm.remove_empty_bridges()
616 + del_br_fn.assert_called_once_with('brqnet1')
618 + def test_remove_interface(self):
619 + with contextlib.nested(
620 + mock.patch.object(self.lbm, "device_exists"),
621 + mock.patch.object(self.lbm, "is_device_on_bridge"),
622 + mock.patch.object(utils, "execute")
623 + ) as (de_fn, isdev_fn, exec_fn):
624 + de_fn.return_value = False
625 + self.assertFalse(self.lbm.remove_interface("br0", "eth0"))
626 + self.assertFalse(isdev_fn.called)
628 + de_fn.return_value = True
629 + isdev_fn.return_value = False
630 + self.assertTrue(self.lbm.remove_interface("br0", "eth0"))
632 + isdev_fn.return_value = True
633 + exec_fn.return_value = True
634 + self.assertFalse(self.lbm.remove_interface("br0", "eth0"))
636 + exec_fn.return_value = False
637 + self.assertTrue(self.lbm.remove_interface("br0", "eth0"))
639 + def test_delete_vlan(self):
640 + with contextlib.nested(
641 + mock.patch.object(self.lbm, "device_exists"),
642 + mock.patch.object(utils, "execute")
643 + ) as (de_fn, exec_fn):
644 + de_fn.return_value = False
645 + self.lbm.delete_vlan("eth1.1")
646 + self.assertFalse(exec_fn.called)
648 + de_fn.return_value = True
649 + exec_fn.return_value = False
650 + self.lbm.delete_vlan("eth1.1")
651 + self.assertTrue(exec_fn.called)
653 + def test_update_devices(self):
654 + with mock.patch.object(self.lbm, "udev_get_tap_devices") as gt_fn:
655 + gt_fn.return_value = set(["dev1"])
656 + self.assertIsNone(self.lbm.update_devices(set(["dev1"])))
658 + gt_fn.return_value = set(["dev1", "dev2"])
659 + self.assertEqual(self.lbm.update_devices(set(["dev2", "dev3"])),
660 + {"current": set(["dev1", "dev2"]),
661 + "added": set(["dev1"]),
662 + "removed": set(["dev3"])
665 + def _check_vxlan_support(self, kernel_version, vxlan_proxy_supported,
666 + fdb_append_supported, l2_population,
668 + def iproute_supported_side_effect(*args):
669 + if args[1] == 'proxy':
670 + return vxlan_proxy_supported
671 + elif args[1] == 'append':
672 + return fdb_append_supported
674 + with contextlib.nested(
675 + mock.patch("platform.release", return_value=kernel_version),
676 + mock.patch.object(ip_lib, 'iproute_arg_supported',
677 + side_effect=iproute_supported_side_effect),
678 + ) as (kver_fn, ip_arg_fn):
679 + self.lbm.check_vxlan_support()
680 + self.assertEqual(self.lbm.vxlan_mode, expected_mode)
682 + def test_vxlan_mode_ucast(self):
683 + self._check_vxlan_support(kernel_version='3.12',
684 + vxlan_proxy_supported=True,
685 + fdb_append_supported=True,
686 + l2_population=True,
687 + expected_mode=lconst.VXLAN_MCAST)
689 + def test_vxlan_mode_mcast(self):
690 + self._check_vxlan_support(kernel_version='3.12',
691 + vxlan_proxy_supported=True,
692 + fdb_append_supported=False,
693 + l2_population=True,
694 + expected_mode=lconst.VXLAN_MCAST)
695 + self._check_vxlan_support(kernel_version='3.10',
696 + vxlan_proxy_supported=True,
697 + fdb_append_supported=True,
698 + l2_population=True,
699 + expected_mode=lconst.VXLAN_MCAST)
701 + def test_vxlan_mode_unsupported(self):
702 + self._check_vxlan_support(kernel_version='3.7',
703 + vxlan_proxy_supported=True,
704 + fdb_append_supported=True,
705 + l2_population=False,
706 + expected_mode=lconst.VXLAN_NONE)
707 + self._check_vxlan_support(kernel_version='3.10',
708 + vxlan_proxy_supported=False,
709 + fdb_append_supported=False,
710 + l2_population=False,
711 + expected_mode=lconst.VXLAN_NONE)
712 + cfg.CONF.set_override('vxlan_group', '', 'VXLAN')
713 + self._check_vxlan_support(kernel_version='3.12',
714 + vxlan_proxy_supported=True,
715 + fdb_append_supported=True,
716 + l2_population=True,
717 + expected_mode=lconst.VXLAN_NONE)
720 +class TestLinuxBridgeRpcCallbacks(base.BaseTestCase):
722 + cfg.CONF.set_override('local_ip', LOCAL_IP, 'VXLAN')
723 + self.addCleanup(cfg.CONF.reset)
724 + super(TestLinuxBridgeRpcCallbacks, self).setUp()
726 + self.u_execute_p = mock.patch('neutron.agent.linux.utils.execute')
727 + self.u_execute = self.u_execute_p.start()
728 + self.addCleanup(self.u_execute_p.stop)
730 + class FakeLBAgent(object):
731 + def __init__(self):
733 + self.br_mgr = (linuxbridge_neutron_agent.
734 + LinuxBridgeManager({'physnet1': 'eth1'},
735 + cfg.CONF.AGENT.root_helper))
737 + self.br_mgr.vxlan_mode = lconst.VXLAN_UCAST
738 + segment = mock.Mock()
739 + segment.network_type = 'vxlan'
740 + segment.segmentation_id = 1
741 + self.br_mgr.network_map['net_id'] = segment
743 + self.lb_rpc = linuxbridge_neutron_agent.LinuxBridgeRpcCallbacks(
748 + self.root_helper = cfg.CONF.AGENT.root_helper
750 + def test_network_delete(self):
751 + with contextlib.nested(
752 + mock.patch.object(self.lb_rpc.agent.br_mgr, "get_bridge_name"),
753 + mock.patch.object(self.lb_rpc.agent.br_mgr, "delete_vlan_bridge")
754 + ) as (get_br_fn, del_fn):
755 + get_br_fn.return_value = "br0"
756 + self.lb_rpc.network_delete("anycontext", network_id="123")
757 + get_br_fn.assert_called_with("123")
758 + del_fn.assert_called_with("br0")
760 + def test_port_update(self):
761 + with contextlib.nested(
762 + mock.patch.object(self.lb_rpc.agent.br_mgr,
763 + "get_tap_device_name"),
764 + mock.patch.object(self.lb_rpc.agent.br_mgr,
765 + "udev_get_tap_devices"),
766 + mock.patch.object(self.lb_rpc.agent.br_mgr,
767 + "get_bridge_name"),
768 + mock.patch.object(self.lb_rpc.agent.br_mgr,
769 + "remove_interface"),
770 + mock.patch.object(self.lb_rpc.agent.br_mgr, "add_interface"),
771 + mock.patch.object(self.lb_rpc.agent,
772 + "plugin_rpc", create=True),
773 + mock.patch.object(self.lb_rpc.sg_agent,
774 + "refresh_firewall", create=True)
775 + ) as (get_tap_fn, udev_fn, getbr_fn, remif_fn,
776 + addif_fn, rpc_obj, reffw_fn):
777 + get_tap_fn.return_value = "tap123"
778 + udev_fn.return_value = ["tap123", "tap124"]
779 + port = {"admin_state_up": True,
781 + "network_id": "123-123"}
782 + self.lb_rpc.port_update("unused_context", port=port,
783 + vlan_id="1", physical_network="physnet1")
784 + self.assertFalse(reffw_fn.called)
785 + addif_fn.assert_called_with(port["network_id"], p_const.TYPE_VLAN,
786 + "physnet1", "1", port["id"])
788 + self.lb_rpc.port_update("unused_context", port=port,
789 + network_type=p_const.TYPE_VLAN,
790 + segmentation_id="2",
791 + physical_network="physnet1")
792 + self.assertFalse(reffw_fn.called)
793 + addif_fn.assert_called_with(port["network_id"], p_const.TYPE_VLAN,
794 + "physnet1", "2", port["id"])
796 + self.lb_rpc.port_update("unused_context", port=port,
797 + vlan_id=lconst.FLAT_VLAN_ID,
798 + physical_network="physnet1")
799 + self.assertFalse(reffw_fn.called)
800 + addif_fn.assert_called_with(port["network_id"], p_const.TYPE_FLAT,
801 + "physnet1", None, port["id"])
803 + self.lb_rpc.port_update("unused_context", port=port,
804 + network_type=p_const.TYPE_FLAT,
805 + segmentation_id=None,
806 + physical_network="physnet1")
807 + self.assertFalse(reffw_fn.called)
808 + addif_fn.assert_called_with(port["network_id"], p_const.TYPE_FLAT,
809 + "physnet1", None, port["id"])
811 + self.lb_rpc.port_update("unused_context", port=port,
812 + vlan_id=lconst.LOCAL_VLAN_ID,
813 + physical_network=None)
814 + self.assertFalse(reffw_fn.called)
815 + addif_fn.assert_called_with(port["network_id"], p_const.TYPE_LOCAL,
816 + None, None, port["id"])
818 + self.lb_rpc.port_update("unused_context", port=port,
819 + network_type=p_const.TYPE_LOCAL,
820 + segmentation_id=None,
821 + physical_network=None)
822 + self.assertFalse(reffw_fn.called)
823 + addif_fn.assert_called_with(port["network_id"], p_const.TYPE_LOCAL,
824 + None, None, port["id"])
826 + addif_fn.return_value = True
827 + self.lb_rpc.port_update("unused_context", port=port,
828 + network_type=p_const.TYPE_LOCAL,
829 + segmentation_id=None,
830 + physical_network=None)
831 + rpc_obj.update_device_up.assert_called_with(
832 + self.lb_rpc.context,
834 + self.lb_rpc.agent.agent_id,
838 + addif_fn.return_value = False
839 + self.lb_rpc.port_update("unused_context", port=port,
840 + network_type=p_const.TYPE_LOCAL,
841 + segmentation_id=None,
842 + physical_network=None)
843 + rpc_obj.update_device_down.assert_called_with(
844 + self.lb_rpc.context,
846 + self.lb_rpc.agent.agent_id,
850 + port["admin_state_up"] = False
851 + port["security_groups"] = True
852 + getbr_fn.return_value = "br0"
853 + self.lb_rpc.port_update("unused_context", port=port,
854 + vlan_id="1", physical_network="physnet1")
855 + self.assertTrue(reffw_fn.called)
856 + remif_fn.assert_called_with("br0", "tap123")
857 + rpc_obj.update_device_down.assert_called_with(
858 + self.lb_rpc.context,
860 + self.lb_rpc.agent.agent_id,
864 + def test_port_update_plugin_rpc_failed(self):
865 + with contextlib.nested(
866 + mock.patch.object(self.lb_rpc.agent.br_mgr,
867 + "get_tap_device_name"),
868 + mock.patch.object(self.lb_rpc.agent.br_mgr,
869 + "udev_get_tap_devices"),
870 + mock.patch.object(self.lb_rpc.agent.br_mgr,
871 + "get_bridge_name"),
872 + mock.patch.object(self.lb_rpc.agent.br_mgr,
873 + "remove_interface"),
874 + mock.patch.object(self.lb_rpc.agent.br_mgr, "add_interface"),
875 + mock.patch.object(self.lb_rpc.sg_agent,
876 + "refresh_firewall", create=True),
877 + mock.patch.object(self.lb_rpc.agent,
878 + "plugin_rpc", create=True),
879 + mock.patch.object(linuxbridge_neutron_agent.LOG, 'error'),
880 + ) as (get_tap_fn, udev_fn, _, _, _, _, plugin_rpc, log):
881 + get_tap_fn.return_value = "tap123"
882 + udev_fn.return_value = ["tap123", "tap124"]
883 + port = {"admin_state_up": True,
885 + "network_id": "123-123"}
886 + plugin_rpc.update_device_up.side_effect = rpc_common.Timeout
887 + self.lb_rpc.port_update(mock.Mock(), port=port)
888 + self.assertTrue(plugin_rpc.update_device_up.called)
889 + self.assertEqual(log.call_count, 1)
892 + port["admin_state_up"] = False
893 + plugin_rpc.update_device_down.side_effect = rpc_common.Timeout
894 + self.lb_rpc.port_update(mock.Mock(), port=port)
895 + self.assertTrue(plugin_rpc.update_device_down.called)
896 + self.assertEqual(log.call_count, 1)
898 + def test_fdb_add(self):
899 + fdb_entries = {'net_id':
901 + {'agent_ip': [constants.FLOODING_ENTRY,
902 + ['port_mac', 'port_ip']]},
903 + 'network_type': 'vxlan',
906 + with mock.patch.object(utils, 'execute',
907 + return_value='') as execute_fn:
908 + self.lb_rpc.fdb_add(None, fdb_entries)
911 + mock.call(['bridge', 'fdb', 'show', 'dev', 'vxlan-1'],
912 + root_helper=self.root_helper),
913 + mock.call(['bridge', 'fdb', 'add',
914 + constants.FLOODING_ENTRY[0],
915 + 'dev', 'vxlan-1', 'dst', 'agent_ip'],
916 + root_helper=self.root_helper,
917 + check_exit_code=False),
918 + mock.call(['ip', 'neigh', 'add', 'port_ip', 'lladdr',
919 + 'port_mac', 'dev', 'vxlan-1', 'nud', 'permanent'],
920 + root_helper=self.root_helper,
921 + check_exit_code=False),
922 + mock.call(['bridge', 'fdb', 'add', 'port_mac', 'dev',
923 + 'vxlan-1', 'dst', 'agent_ip'],
924 + root_helper=self.root_helper,
925 + check_exit_code=False),
927 + execute_fn.assert_has_calls(expected)
929 + def test_fdb_ignore(self):
930 + fdb_entries = {'net_id':
932 + {LOCAL_IP: [constants.FLOODING_ENTRY,
933 + ['port_mac', 'port_ip']]},
934 + 'network_type': 'vxlan',
937 + with mock.patch.object(utils, 'execute',
938 + return_value='') as execute_fn:
939 + self.lb_rpc.fdb_add(None, fdb_entries)
940 + self.lb_rpc.fdb_remove(None, fdb_entries)
942 + self.assertFalse(execute_fn.called)
944 + fdb_entries = {'other_net_id':
946 + {'192.168.0.67': [constants.FLOODING_ENTRY,
947 + ['port_mac', 'port_ip']]},
948 + 'network_type': 'vxlan',
951 + with mock.patch.object(utils, 'execute',
952 + return_value='') as execute_fn:
953 + self.lb_rpc.fdb_add(None, fdb_entries)
954 + self.lb_rpc.fdb_remove(None, fdb_entries)
956 + self.assertFalse(execute_fn.called)
958 + def test_fdb_remove(self):
959 + fdb_entries = {'net_id':
961 + {'agent_ip': [constants.FLOODING_ENTRY,
962 + ['port_mac', 'port_ip']]},
963 + 'network_type': 'vxlan',
966 + with mock.patch.object(utils, 'execute',
967 + return_value='') as execute_fn:
968 + self.lb_rpc.fdb_remove(None, fdb_entries)
971 + mock.call(['bridge', 'fdb', 'del',
972 + constants.FLOODING_ENTRY[0],
973 + 'dev', 'vxlan-1', 'dst', 'agent_ip'],
974 + root_helper=self.root_helper,
975 + check_exit_code=False),
976 + mock.call(['ip', 'neigh', 'del', 'port_ip', 'lladdr',
977 + 'port_mac', 'dev', 'vxlan-1'],
978 + root_helper=self.root_helper,
979 + check_exit_code=False),
980 + mock.call(['bridge', 'fdb', 'del', 'port_mac',
981 + 'dev', 'vxlan-1', 'dst', 'agent_ip'],
982 + root_helper=self.root_helper,
983 + check_exit_code=False),
985 + execute_fn.assert_has_calls(expected)
987 + def test_fdb_update_chg_ip(self):
988 + fdb_entries = {'chg_ip':
991 + {'before': [['port_mac', 'port_ip_1']],
992 + 'after': [['port_mac', 'port_ip_2']]}}}}
994 + with mock.patch.object(utils, 'execute',
995 + return_value='') as execute_fn:
996 + self.lb_rpc.fdb_update(None, fdb_entries)
999 + mock.call(['ip', 'neigh', 'add', 'port_ip_2', 'lladdr',
1000 + 'port_mac', 'dev', 'vxlan-1', 'nud', 'permanent'],
1001 + root_helper=self.root_helper,
1002 + check_exit_code=False),
1003 + mock.call(['ip', 'neigh', 'del', 'port_ip_1', 'lladdr',
1004 + 'port_mac', 'dev', 'vxlan-1'],
1005 + root_helper=self.root_helper,
1006 + check_exit_code=False)
1008 + execute_fn.assert_has_calls(expected)