def test_gateway_chassis_rebalance(self): def _get_result_dict(): sched_info = {} for row in self.nb_api.tables[ 'Logical_Router_Port'].rows.values(): for gwc in row.gateway_chassis: chassis = sched_info.setdefault(gwc.chassis_name, {}) chassis[gwc.priority] = chassis.get(gwc.priority, 0) + 1 return sched_info if not self._l3_ha_supported(): self.skipTest('L3 HA not supported') ovn_client = self.l3_plugin._ovn_client chassis4 = self.add_fake_chassis( 'ovs-host4', physical_nets=['physnet4'], external_ids={ 'ovn-cms-options': 'enable-chassis-as-gw'}) ovn_client._ovn_scheduler = l3_sched.OVNGatewayLeastLoadedScheduler() ext1 = self._create_ext_network( 'ext1', 'flat', 'physnet4', None, "30.0.0.1", "30.0.0.0/24") gw_info = {'network_id': ext1['network']['id']} # Create 20 routers with a gateway. Since we're using physnet4, the # chassis candidates will be chassis4 initially. for i in range(20): router = self._create_router('router%d' % i, gw_info=gw_info) gw_port_id = router.get('gw_port_id') logical_port = 'cr-lrp-%s' % gw_port_id self.assertTrue(self.cr_lrp_pb_event.wait(logical_port)) self.sb_api.lsp_bind(logical_port, chassis4, may_exist=True).execute(check_error=True) self.l3_plugin.schedule_unhosted_gateways() expected = {chassis4: {1: 20}} self.assertEqual(expected, _get_result_dict()) # Add another chassis as a gateway chassis chassis5 = self.add_fake_chassis( 'ovs-host5', physical_nets=['physnet4'], external_ids={ 'ovn-cms-options': 'enable-chassis-as-gw'}) # Add a node as compute node. Compute node wont be # used to schedule the router gateway ports therefore # priority values wont be changed. Therefore chassis4 would # still have priority 2 self.add_fake_chassis('ovs-host6', physical_nets=['physnet4']) # Chassis4 should have all ports at Priority 2 self.l3_plugin.schedule_unhosted_gateways() self.assertEqual({2: 20}, _get_result_dict()[chassis4]) # Chassis5 should have all ports at Priority 1 self.assertEqual({1: 20}, _get_result_dict()[chassis5]) # delete chassis that hosts all the gateways self.del_fake_chassis(chassis4) self.l3_plugin.schedule_unhosted_gateways() # As Chassis4 has been removed so all gateways that were # hosted there are now masters on chassis5 and have # priority 1. self.assertEqual({1: 20}, _get_result_dict()[chassis5])
def test_gateway_chassis_least_loaded_scheduler(self): # This test will create 4 routers each with its own gateway. # Using the least loaded policy for scheduling gateway ports, we # expect that they are equally distributed across the two available # chassis. ovn_client = self.l3_plugin._ovn_client ovn_client._ovn_scheduler = l3_sched.OVNGatewayLeastLoadedScheduler() ext1 = self._create_ext_network('ext1', 'flat', 'physnet3', None, "20.0.0.1", "20.0.0.0/24") gw_info = {'network_id': ext1['network']['id']} # Create 4 routers with a gateway. Since we're using physnet3, the # chassis candidates will be chassis1 and chassis2. for i in range(1, 5): self._create_router('router%d' % i, gw_info=gw_info) # At this point we expect two gateways to be present in chassis1 # and two in chassis2. If schema supports L3 HA, we expect each # chassis to host 2 priority 2 gateways and 2 priority 1 ones. if self._l3_ha_supported(): # Each chassis contains a dict of (priority, # of ports hosted). # {1: 2, 2: 2} means that this chassis hosts 2 ports of prio 1 # and two ports of prio 2. expected = { self.chassis1: { 1: 2, 2: 2 }, self.chassis2: { 1: 2, 2: 2 } } else: # For non L3 HA, each chassis should contain two gateway ports. expected = {self.chassis1: 2, self.chassis2: 2} sched_info = {} for row in self.nb_api.tables['Logical_Router_Port'].rows.values(): if self._l3_ha_supported(): for gwc in row.gateway_chassis: chassis = sched_info.setdefault(gwc.chassis_name, {}) chassis[gwc.priority] = chassis.get(gwc.priority, 0) + 1 else: rc = row.options.get(ovn_const.OVN_GATEWAY_CHASSIS_KEY) sched_info[rc] = sched_info.get(rc, 0) + 1 self.assertEqual(expected, sched_info)
def setUp(self): super(OVNGatewayLeastLoadedScheduler, self).setUp() self.l3_scheduler = l3_ovn_scheduler.OVNGatewayLeastLoadedScheduler()