def test_no_update_network_mtu(self): mtu_value = self.n1['network']['mtu'] base_revision = db_rev.get_revision_row(self.context, self.sub['subnet']['id']) data = {'network': {'mtu': mtu_value}} req = self.new_update_request('networks', data, self.n1['network']['id'], self.fmt) req.get_response(self.api) second_revision = db_rev.get_revision_row(self.context, self.sub['subnet']['id']) self.assertEqual(base_revision.updated_at, second_revision.updated_at)
def _test_fix_security_group_create(self, mock_bump, revision_number): with db_api.CONTEXT_WRITER.using(self.ctx): sg_name = utils.ovn_addrset_name('fake_id', 'ip4') sg = self._make_security_group(self.fmt, sg_name, '')['security_group'] ovn_revision_numbers_db.create_initial_revision( self.ctx, sg['id'], constants.TYPE_SECURITY_GROUPS, revision_number=revision_number) row = ovn_revision_numbers_db.get_revision_row(self.ctx, sg['id']) self.assertEqual(revision_number, row.revision_number) if revision_number < 0: self.fake_ovn_client._nb_idl.get_address_set.return_value = None self.fake_ovn_client._nb_idl.get_port_group.return_value = None else: self.fake_ovn_client._nb_idl.get_address_set.return_value = ( mock.sentinel.AddressSet) self.fake_ovn_client._plugin.get_security_group.return_value = sg self.periodic._fix_create_update(self.ctx, row) if revision_number < 0: self.fake_ovn_client.create_security_group.assert_called_once_with( self.ctx, sg) else: # If the object already exist let's make sure we just bump # the revision number in the ovn_revision_numbers table self.assertFalse(self.fake_ovn_client.create_security_group.called) mock_bump.assert_called_once_with(self.ctx, sg, constants.TYPE_SECURITY_GROUPS)
def _test_fix_create_update_port(self, ovn_rev, neutron_rev): self.port['revision_number'] = neutron_rev # Create an entry to the revision_numbers table and assert the # initial revision_number for our test object is the expected ovn_revision_numbers_db.create_initial_revision( self.ctx, self.port['id'], constants.TYPE_PORTS, revision_number=ovn_rev) row = ovn_revision_numbers_db.get_revision_row(self.ctx, self.port['id']) self.assertEqual(ovn_rev, row.revision_number) if ovn_rev < 0: self.fake_ovn_client._nb_idl.get_lswitch_port.return_value = None else: fake_lsp = mock.Mock(external_ids={ constants.OVN_REV_NUM_EXT_ID_KEY: ovn_rev}) self.fake_ovn_client._nb_idl.get_lswitch_port.return_value = ( fake_lsp) self.fake_ovn_client._plugin.get_port.return_value = self.port self.periodic._fix_create_update(self.ctx, row) # Since the revision number was < 0, make sure create_port() # is invoked with the latest version of the object in the neutron # database if ovn_rev < 0: self.fake_ovn_client.create_port.assert_called_once_with( self.port) # If the revision number is > 0 it means that the object already # exist and we just need to update to match the latest in the # neutron database so, update_port() should be called. else: self.fake_ovn_client.update_port.assert_called_once_with( self.port)
def test_network(self): net_name = 'networktest' with mock.patch.object(self._ovn_client, 'create_network'): neutron_obj = self._create_network(net_name) # Assert the network doesn't exist in OVN self.assertIsNone(self._find_network_row_by_name(net_name)) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the network was now created ovn_obj = self._find_network_row_by_name(net_name) self.assertIsNotNone(ovn_obj) self.assertEqual( neutron_obj['revision_number'], int(ovn_obj.external_ids[ovn_const.OVN_REV_NUM_EXT_ID_KEY])) # > Update new_obj_name = 'networktest_updated' with mock.patch.object(self._ovn_client, 'update_network'): new_neutron_obj = self._update_network_name( neutron_obj['id'], new_obj_name) # Assert the revision numbers are out-of-sync ovn_obj = self._find_network_row_by_name(net_name) self.assertNotEqual( new_neutron_obj['revision_number'], int(ovn_obj.external_ids[ovn_const.OVN_REV_NUM_EXT_ID_KEY])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the old name doesn't exist anymore in the OVNDB self.assertIsNone(self._find_network_row_by_name(net_name)) # Assert the network is now in sync ovn_obj = self._find_network_row_by_name(new_obj_name) self.assertEqual( new_neutron_obj['revision_number'], int(ovn_obj.external_ids[ovn_const.OVN_REV_NUM_EXT_ID_KEY])) # > Delete with mock.patch.object(self._ovn_client, 'delete_network'): self._delete('networks', new_neutron_obj['id']) # Assert the network still exists in OVNDB self.assertIsNotNone(self._find_network_row_by_name(new_obj_name)) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the network is now deleted from OVNDB self.assertIsNone(self._find_network_row_by_name(new_obj_name)) # Assert the revision number no longer exists self.assertIsNone( db_rev.get_revision_row(self.context, new_neutron_obj['id']))
def test_bump_revision_row_not_found(self, mock_log): self.net['revision_number'] = 123 ovn_rn_db.bump_revision(self.ctx, self.net, ovn_rn_db.TYPE_NETWORKS) # Assert the revision number wasn't bumped row = ovn_rn_db.get_revision_row(self.ctx, self.net['id']) self.assertEqual(123, row.revision_number) self.assertIn('No revision row found for', mock_log.call_args[0][0])
def test_bump_revision(self): self._create_initial_revision(self.net['id'], ovn_rn_db.TYPE_NETWORKS) self.net['revision_number'] = 123 ovn_rn_db.bump_revision(self.ctx, self.net, ovn_rn_db.TYPE_NETWORKS) row = ovn_rn_db.get_revision_row(self.ctx, self.net['id']) self.assertEqual(123, row.revision_number)
def test_router_port(self): neutron_net = self._create_network('networktest', external=True) neutron_subnet = self._create_subnet('subnettest', neutron_net['id']) neutron_router = self._create_router('routertest') with mock.patch.object(self._l3_ovn_client, 'create_router_port'): with mock.patch('neutron.db.ovn_revision_numbers_db.' 'bump_revision'): neutron_obj = self._add_router_interface(neutron_router['id'], neutron_subnet['id']) # Assert the router port doesn't exist in OVN self.assertIsNone( self._find_router_port_row_by_port_id(neutron_obj['port_id'])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the router port was now created self.assertIsNotNone( self._find_router_port_row_by_port_id(neutron_obj['port_id'])) # > Delete with mock.patch.object(self._l3_ovn_client, 'delete_router_port'): self._remove_router_interface(neutron_router['id'], neutron_subnet['id']) # Assert the router port still exists in OVNDB self.assertIsNotNone( self._find_router_port_row_by_port_id(neutron_obj['port_id'])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the router port is now deleted from OVNDB self.assertIsNone( self._find_router_port_row_by_port_id(neutron_obj['port_id'])) # Assert the revision number no longer exists self.assertIsNone(db_rev.get_revision_row( self.context, neutron_obj['port_id']))
def test_security_group(self): with mock.patch.object(self._ovn_client, 'create_security_group'): neutron_obj = self._create_security_group() # Assert the sg doesn't exist in OVN self.assertIsNone( self._find_security_group_row_by_id(neutron_obj['id'])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the sg was now created. We don't save the revision number # in the Security Group because OVN doesn't support updating it, # all we care about is whether it exists or not. self.assertIsNotNone( self._find_security_group_row_by_id(neutron_obj['id'])) # > Delete with mock.patch.object(self._ovn_client, 'delete_security_group'): self._delete('security-groups', neutron_obj['id']) # Assert the sg still exists in OVNDB self.assertIsNotNone( self._find_security_group_row_by_id(neutron_obj['id'])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the sg is now deleted from OVNDB self.assertIsNone( self._find_security_group_row_by_id(neutron_obj['id'])) # Assert the revision number no longer exists self.assertIsNone(db_rev.get_revision_row( self.context, neutron_obj['id']))
def test_subnet(self): obj_name = 'subnettest' neutron_net = self._create_network('network1') with mock.patch.object(self._ovn_client, 'create_subnet'): neutron_obj = self._create_subnet(obj_name, neutron_net['id']) # Assert the subnet doesn't exist in OVN self.assertIsNone(self._find_subnet_row_by_id(neutron_obj['id'])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the subnet was now created ovn_obj = self._find_subnet_row_by_id(neutron_obj['id']) self.assertIsNotNone(ovn_obj) self.assertEqual( neutron_obj['revision_number'], int(ovn_obj.external_ids[ovn_const.OVN_REV_NUM_EXT_ID_KEY])) # > Update with mock.patch.object(self._ovn_client, 'update_subnet'): neutron_obj = self._update_subnet_enable_dhcp( neutron_obj['id'], False) # Assert the revision numbers are out-of-sync ovn_obj = self._find_subnet_row_by_id(neutron_obj['id']) self.assertNotEqual( neutron_obj['revision_number'], int(ovn_obj.external_ids[ovn_const.OVN_REV_NUM_EXT_ID_KEY])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the old name doesn't exist anymore in the OVNDB. When # the subnet's enable_dhcp's is set to False, OVN will remove the # DHCP_Options entry related to that subnet. self.assertIsNone(self._find_subnet_row_by_id(neutron_obj['id'])) # Re-enable the DHCP for the subnet and check if the maintenance # thread will re-create it in OVN with mock.patch.object(self._ovn_client, 'update_subnet'): neutron_obj = self._update_subnet_enable_dhcp( neutron_obj['id'], True) # Assert the DHCP_Options still doesn't exist in OVNDB self.assertIsNone(self._find_subnet_row_by_id(neutron_obj['id'])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the subnet is now in sync ovn_obj = self._find_subnet_row_by_id(neutron_obj['id']) self.assertEqual( neutron_obj['revision_number'], int(ovn_obj.external_ids[ovn_const.OVN_REV_NUM_EXT_ID_KEY])) # > Delete with mock.patch.object(self._ovn_client, 'delete_subnet'): self._delete('subnets', neutron_obj['id']) # Assert the subnet still exists in OVNDB self.assertIsNotNone(self._find_subnet_row_by_id(neutron_obj['id'])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the subnet is now deleted from OVNDB self.assertIsNone(self._find_subnet_row_by_id(neutron_obj['id'])) # Assert the revision number no longer exists self.assertIsNone( db_rev.get_revision_row(self.context, neutron_obj['id']))
def test_port(self): obj_name = 'porttest' neutron_net = self._create_network('network1') with mock.patch.object(self._ovn_client, 'create_port'): neutron_obj = self._create_port(obj_name, neutron_net['id']) # Assert the port doesn't exist in OVN self.assertIsNone(self._find_port_row_by_name(obj_name)) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the port was now created ovn_obj = self._find_port_row_by_name(obj_name) self.assertIsNotNone(ovn_obj) self.assertEqual( neutron_obj['revision_number'], int(ovn_obj.external_ids[ovn_const.OVN_REV_NUM_EXT_ID_KEY])) # > Update new_obj_name = 'porttest_updated' with mock.patch.object(self._ovn_client, 'update_port'): new_neutron_obj = self._update_port_name(neutron_obj['id'], new_obj_name) # Assert the revision numbers are out-of-sync ovn_obj = self._find_port_row_by_name(obj_name) self.assertNotEqual( new_neutron_obj['revision_number'], int(ovn_obj.external_ids[ovn_const.OVN_REV_NUM_EXT_ID_KEY])) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the old name doesn't exist anymore in the OVNDB self.assertIsNone(self._find_port_row_by_name(obj_name)) # Assert the port is now in sync. Note that for ports we are # fetching it again from the Neutron database prior to comparison # because of the monitor code that can update the ports again upon # changes to it. ovn_obj = self._find_port_row_by_name(new_obj_name) new_neutron_obj = self._ovn_client._plugin.get_port( self.context, neutron_obj['id']) self.assertEqual( new_neutron_obj['revision_number'], int(ovn_obj.external_ids[ovn_const.OVN_REV_NUM_EXT_ID_KEY])) # > Delete with mock.patch.object(self._ovn_client, 'delete_port'): self._delete('ports', new_neutron_obj['id']) # Assert the port still exists in OVNDB self.assertIsNotNone(self._find_port_row_by_name(new_obj_name)) # Call the maintenance thread to fix the problem self.maint.check_for_inconsistencies() # Assert the port is now deleted from OVNDB self.assertIsNone(self._find_port_row_by_name(new_obj_name)) # Assert the revision number no longer exists self.assertIsNone( db_rev.get_revision_row(self.context, neutron_obj['id']))
def test_delete_revision(self): self._create_initial_revision(self.net['id'], ovn_rn_db.TYPE_NETWORKS) ovn_rn_db.delete_revision(self.ctx, self.net['id'], ovn_rn_db.TYPE_NETWORKS) row = ovn_rn_db.get_revision_row(self.ctx, self.net['id']) self.assertIsNone(row)