Neutron integration with OVN
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
6.4KB

  1. #
  2. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  3. # not use this file except in compliance with the License. You may obtain
  4. # a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software
  9. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  10. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  11. # License for the specific language governing permissions and limitations
  12. # under the License.
  13. #
  14. import uuid
  15. from ovsdbapp import event as ovsdb_event
  16. from ovsdbapp.tests.functional import base
  17. from ovsdbapp.tests.functional.schema.ovn_southbound import test_impl_idl as \
  18. test_sb
  19. from ovsdbapp.tests import utils
  20. from networking_ovn.ovsdb import impl_idl_ovn as impl
  21. class WaitForPortBindingEvent(test_sb.WaitForPortBindingEvent):
  22. def run(self, event, row, old):
  23. self.row = row
  24. super(WaitForPortBindingEvent, self).run(event, row, old)
  25. class TestSbApi(base.FunctionalTestCase):
  26. schemas = ['OVN_Southbound', 'OVN_Northbound']
  27. def setUp(self):
  28. super(TestSbApi, self).setUp()
  29. self.data = {
  30. 'chassis': [
  31. {'external_ids': {'ovn-bridge-mappings':
  32. 'public:br-ex,private:br-0'}},
  33. {'external_ids': {'ovn-bridge-mappings':
  34. 'public:br-ex,public2:br-ex'}},
  35. {'external_ids': {'ovn-bridge-mappings':
  36. 'public:br-ex'}},
  37. ]
  38. }
  39. self.api = impl.OvsdbSbOvnIdl(self.connection['OVN_Southbound'])
  40. self.nbapi = impl.OvsdbNbOvnIdl(self.connection['OVN_Northbound'])
  41. self.load_test_data()
  42. self.handler = ovsdb_event.RowEventHandler()
  43. self.api.idl.notify = self.handler.notify
  44. def load_test_data(self):
  45. with self.api.transaction(check_error=True) as txn:
  46. for chassis in self.data['chassis']:
  47. chassis['name'] = utils.get_rand_device_name('chassis')
  48. chassis['hostname'] = '%s.localdomain.com' % chassis['name']
  49. txn.add(self.api.chassis_add(
  50. chassis['name'], ['geneve'], chassis['hostname'],
  51. hostname=chassis['hostname'],
  52. external_ids=chassis['external_ids']))
  53. def test_get_chassis_hostname_and_physnets(self):
  54. mapping = self.api.get_chassis_hostname_and_physnets()
  55. self.assertLessEqual(len(self.data['chassis']), len(mapping))
  56. self.assertGreaterEqual(set(mapping.keys()),
  57. {c['hostname'] for c in self.data['chassis']})
  58. def test_get_all_chassis(self):
  59. chassis_list = set(self.api.get_all_chassis())
  60. our_chassis = {c['name'] for c in self.data['chassis']}
  61. self.assertLessEqual(our_chassis, chassis_list)
  62. def test_get_chassis_data_for_ml2_bind_port(self):
  63. host = self.data['chassis'][0]['hostname']
  64. dp, iface, phys = self.api.get_chassis_data_for_ml2_bind_port(host)
  65. self.assertEqual(dp, '')
  66. self.assertEqual(iface, '')
  67. self.assertItemsEqual(phys, ['private', 'public'])
  68. def test_chassis_exists(self):
  69. self.assertTrue(self.api.chassis_exists(
  70. self.data['chassis'][0]['hostname']))
  71. self.assertFalse(self.api.chassis_exists("nochassishere"))
  72. def test_get_chassis_and_physnets(self):
  73. mapping = self.api.get_chassis_and_physnets()
  74. self.assertLessEqual(len(self.data['chassis']), len(mapping))
  75. self.assertGreaterEqual(set(mapping.keys()),
  76. {c['name'] for c in self.data['chassis']})
  77. def _add_switch_port(self, chassis_name, type='localport'):
  78. sname, pname = (utils.get_rand_device_name(prefix=p)
  79. for p in ('switch', 'port'))
  80. chassis = self.api.lookup('Chassis', chassis_name)
  81. row_event = WaitForPortBindingEvent(pname)
  82. self.handler.watch_event(row_event)
  83. with self.nbapi.transaction(check_error=True) as txn:
  84. switch = txn.add(self.nbapi.ls_add(sname))
  85. port = txn.add(self.nbapi.lsp_add(sname, pname, type=type))
  86. row_event.wait()
  87. return chassis, switch.result, port.result, row_event.row
  88. def test_get_metadata_port_network(self):
  89. chassis, switch, port, binding = self._add_switch_port(
  90. self.data['chassis'][0]['name'])
  91. result = self.api.get_metadata_port_network(str(binding.datapath.uuid))
  92. self.assertEqual(binding, result)
  93. self.assertEqual(binding.datapath.external_ids['logical-switch'],
  94. str(switch.uuid))
  95. def test_get_metadata_port_network_missing(self):
  96. val = str(uuid.uuid4())
  97. self.assertIsNone(self.api.get_metadata_port_network(val))
  98. def test_set_get_chassis_metadata_networks(self):
  99. name = self.data['chassis'][0]['name']
  100. nets = [str(uuid.uuid4()) for _ in range(3)]
  101. self.api.set_chassis_metadata_networks(name, nets).execute(
  102. check_error=True)
  103. self.assertEqual(nets, self.api.get_chassis_metadata_networks(name))
  104. def test_get_network_port_bindings_by_ip(self):
  105. chassis, switch, port, binding = self._add_switch_port(
  106. self.data['chassis'][0]['name'])
  107. mac = 'de:ad:be:ef:4d:ad'
  108. ipaddr = '192.0.2.1'
  109. self.nbapi.lsp_set_addresses(
  110. port.name, ['%s %s' % (mac, ipaddr)]).execute(check_error=True)
  111. self.api.lsp_bind(port.name, chassis.name).execute(check_error=True)
  112. result = self.api.get_network_port_bindings_by_ip(
  113. str(binding.datapath.uuid), ipaddr)
  114. self.assertIn(binding, result)
  115. def test_get_ports_on_chassis(self):
  116. chassis, switch, port, binding = self._add_switch_port(
  117. self.data['chassis'][0]['name'])
  118. self.api.lsp_bind(port.name, chassis.name).execute(check_error=True)
  119. self.assertEqual([binding],
  120. self.api.get_ports_on_chassis(chassis.name))
  121. def test_get_logical_port_chassis_and_datapath(self):
  122. chassis, switch, port, binding = self._add_switch_port(
  123. self.data['chassis'][0]['name'])
  124. self.api.lsp_bind(port.name, chassis.name).execute(check_error=True)
  125. self.assertEqual(
  126. (chassis.name, str(binding.datapath.uuid)),
  127. self.api.get_logical_port_chassis_and_datapath(port.name))