def test_get_inconsistent_resources(self): # Set the intial revision to -1 to force it to be incosistent self._create_initial_revision( self.net['id'], ovn_rn_db.TYPE_NETWORKS, revision_number=-1) res = ovn_rn_db.get_inconsistent_resources(self.ctx) self.assertEqual(1, len(res)) self.assertEqual(self.net['id'], res[0].resource_uuid)
def test_get_inconsistent_resources_consistent(self): # Set the initial revision to 0 which is the initial revision_number # for recently created resources self._create_initial_revision( self.net['id'], ovn_rn_db.TYPE_NETWORKS, revision_number=0) res = ovn_rn_db.get_inconsistent_resources(self.ctx) # Assert nothing is inconsistent self.assertEqual([], res)
def test_get_inconsistent_resources_older_than(self): # Stop the mock so the INCONSISTENCIES_OLDER_THAN will have # it's default value self.older_than_mock.stop() self._create_initial_revision( self.net['id'], ovn_rn_db.TYPE_NETWORKS, revision_number=-1) res = ovn_rn_db.get_inconsistent_resources(self.ctx) # Assert that nothing is returned because the entry is not old # enough to be picked as an inconsistency self.assertEqual(0, len(res)) # Start the mock again and make sure it nows shows up as an # inconsistency self.older_than_mock.start() res = ovn_rn_db.get_inconsistent_resources(self.ctx) self.assertEqual(1, len(res)) self.assertEqual(self.net['id'], res[0].resource_uuid)
def check_for_inconsistencies(self): # Only the worker holding a valid lock within OVSDB will run # this periodic if not self.has_lock: return admin_context = n_context.get_admin_context() create_update_inconsistencies = ( revision_numbers_db.get_inconsistent_resources(admin_context)) delete_inconsistencies = ( revision_numbers_db.get_deleted_resources(admin_context)) if not any([create_update_inconsistencies, delete_inconsistencies]): LOG.debug('Maintenance task: No inconsistencies found. Skipping') return LOG.debug('Maintenance task: Synchronizing Neutron ' 'and OVN databases') self._log_maintenance_inconsistencies(create_update_inconsistencies, delete_inconsistencies) self._sync_timer.restart() dbg_log_msg = ('Maintenance task: Fixing resource %(res_uuid)s ' '(type: %(res_type)s) at %(type_)s') # Fix the create/update resources inconsistencies for row in create_update_inconsistencies: LOG.debug(dbg_log_msg, {'res_uuid': row.resource_uuid, 'res_type': row.resource_type, 'type_': INCONSISTENCY_TYPE_CREATE_UPDATE}) try: # NOTE(lucasagomes): The way to fix subnets is bit # different than other resources. A subnet in OVN language # is just a DHCP rule but, this rule only exist if the # subnet in Neutron has the "enable_dhcp" attribute set # to True. So, it's possible to have a consistent subnet # resource even when it does not exist in the OVN database. if row.resource_type == ovn_const.TYPE_SUBNETS: self._fix_create_update_subnet(admin_context, row) else: self._fix_create_update(admin_context, row) except Exception: LOG.exception('Maintenance task: Failed to fix resource ' '%(res_uuid)s (type: %(res_type)s)', {'res_uuid': row.resource_uuid, 'res_type': row.resource_type}) # Fix the deleted resources inconsistencies for row in delete_inconsistencies: LOG.debug(dbg_log_msg, {'res_uuid': row.resource_uuid, 'res_type': row.resource_type, 'type_': INCONSISTENCY_TYPE_DELETE}) try: if row.resource_type == ovn_const.TYPE_SUBNETS: self._ovn_client.delete_subnet(admin_context, row.resource_uuid) elif row.resource_type == ovn_const.TYPE_PORTS: self._ovn_client.delete_port(admin_context, row.resource_uuid) else: self._fix_delete(admin_context, row) except Exception: LOG.exception('Maintenance task: Failed to fix deleted ' 'resource %(res_uuid)s (type: %(res_type)s)', {'res_uuid': row.resource_uuid, 'res_type': row.resource_type}) self._sync_timer.stop() LOG.info('Maintenance task: Synchronization finished ' '(took %.2f seconds)', self._sync_timer.elapsed())
def test_get_inconsistent_resources_order(self): self._prepare_resources_for_ordering_test() res = ovn_rn_db.get_inconsistent_resources(self.ctx) actual_order = tuple(r.resource_type for r in res) self.assertEqual(ovn_rn_db._TYPES_PRIORITY_ORDER, actual_order)