|
18 | 18 | from neutron_lib.callbacks import events
|
19 | 19 | from neutron_lib.callbacks import registry
|
20 | 20 | from neutron_lib.callbacks import resources
|
| 21 | +from neutron_lib import constants as nlib_consts |
21 | 22 | from neutron_lib import exceptions as n_exc
|
22 | 23 | from neutron_lib.services.trunk import constants as trunk_consts
|
23 | 24 | from oslo_config import cfg
|
24 | 25 |
|
25 | 26 | from neutron.common.ovn.constants import OVN_ML2_MECH_DRIVER_NAME
|
26 | 27 | from neutron.objects.ports import Port
|
27 | 28 | from neutron.objects.ports import PortBinding
|
| 29 | +from neutron.objects import trunk as trunk_objects |
| 30 | +from neutron.services.trunk import drivers |
28 | 31 | from neutron.services.trunk.drivers.ovn import trunk_driver
|
| 32 | +from neutron.services.trunk import plugin as trunk_plugin |
29 | 33 | from neutron.tests import base
|
30 | 34 | from neutron.tests.unit import fake_resources
|
| 35 | +from neutron.tests.unit.plugins.ml2 import test_plugin |
31 | 36 |
|
32 | 37 |
|
33 | 38 | class FakePayload:
|
@@ -430,6 +435,70 @@ def test_subports_deleted_no_parent(self, m__unset_sub_ports):
|
430 | 435 | m__unset_sub_ports.assert_not_called()
|
431 | 436 |
|
432 | 437 |
|
| 438 | +class TestTrunkHandlerWithPlugin(test_plugin.Ml2PluginV2TestCase): |
| 439 | + def setUp(self): |
| 440 | + super().setUp() |
| 441 | + self.drivers_patch = mock.patch.object(drivers, 'register').start() |
| 442 | + self.compat_patch = mock.patch.object( |
| 443 | + trunk_plugin.TrunkPlugin, 'check_compatibility').start() |
| 444 | + self.trunk_plugin = trunk_plugin.TrunkPlugin() |
| 445 | + self.trunk_plugin.add_segmentation_type('vlan', lambda x: True) |
| 446 | + self.plugin_driver = mock.Mock() |
| 447 | + self.trunk_handler = trunk_driver.OVNTrunkHandler(self.plugin_driver) |
| 448 | + |
| 449 | + def _create_test_trunk(self, port, subports=None): |
| 450 | + subports = subports if subports else [] |
| 451 | + trunk = {'port_id': port['port']['id'], |
| 452 | + 'project_id': 'test_tenant', |
| 453 | + 'sub_ports': subports} |
| 454 | + response = ( |
| 455 | + self.trunk_plugin.create_trunk(self.context, {'trunk': trunk})) |
| 456 | + return response |
| 457 | + |
| 458 | + def _get_trunk_obj(self, trunk_id): |
| 459 | + return trunk_objects.Trunk.get_object(self.context, id=trunk_id) |
| 460 | + |
| 461 | + def test_parent_active_triggers_trunk_active(self): |
| 462 | + with self.port() as new_parent: |
| 463 | + new_parent['status'] = nlib_consts.PORT_STATUS_ACTIVE |
| 464 | + old_parent = {'status': nlib_consts.PORT_STATUS_DOWN} |
| 465 | + old_trunk = self._create_test_trunk(new_parent) |
| 466 | + old_trunk = self._get_trunk_obj(old_trunk['id']) |
| 467 | + old_trunk.update(status=trunk_consts.TRUNK_DOWN_STATUS) |
| 468 | + trunk_details = {'trunk_id': old_trunk.id} |
| 469 | + new_parent['trunk_details'] = trunk_details |
| 470 | + old_parent['trunk_details'] = trunk_details |
| 471 | + self.trunk_handler.port_updated( |
| 472 | + resources.PORT, |
| 473 | + events.AFTER_UPDATE, |
| 474 | + None, |
| 475 | + payload=events.DBEventPayload( |
| 476 | + self.context, states=(old_parent, new_parent))) |
| 477 | + new_trunk = self._get_trunk_obj(old_trunk.id) |
| 478 | + self.assertEqual( |
| 479 | + trunk_consts.TRUNK_ACTIVE_STATUS, new_trunk.status) |
| 480 | + |
| 481 | + def test_parent_build_does_not_trigger_trunk_active(self): |
| 482 | + with self.port() as new_parent: |
| 483 | + new_parent['status'] = nlib_consts.PORT_STATUS_BUILD |
| 484 | + old_parent = {'status': nlib_consts.PORT_STATUS_DOWN} |
| 485 | + old_trunk = self._create_test_trunk(new_parent) |
| 486 | + old_trunk = self._get_trunk_obj(old_trunk['id']) |
| 487 | + old_trunk.update(status=trunk_consts.TRUNK_DOWN_STATUS) |
| 488 | + trunk_details = {'trunk_id': old_trunk.id} |
| 489 | + new_parent['trunk_details'] = trunk_details |
| 490 | + old_parent['trunk_details'] = trunk_details |
| 491 | + self.trunk_handler.port_updated( |
| 492 | + resources.PORT, |
| 493 | + events.AFTER_UPDATE, |
| 494 | + None, |
| 495 | + payload=events.DBEventPayload( |
| 496 | + self.context, states=(old_parent, new_parent))) |
| 497 | + new_trunk = self._get_trunk_obj(old_trunk.id) |
| 498 | + self.assertNotEqual( |
| 499 | + trunk_consts.TRUNK_ACTIVE_STATUS, new_trunk.status) |
| 500 | + |
| 501 | + |
433 | 502 | class TestTrunkDriver(base.BaseTestCase):
|
434 | 503 | def test_is_loaded(self):
|
435 | 504 | driver = trunk_driver.OVNTrunkDriver.create(mock.Mock())
|
|
0 commit comments