def recovery(): """Recover after a crash any incomplete procedure. It assumes that the executor is already running and that the recovery is sequential. In the future, we may consider optimizing this function. :return: False, if nothing bad happened while recovering. Otherwise, return True. """ Checkpoint.cleanup() error = False for checkpoint in Checkpoint.unfinished(): if checkpoint.undo_action: procedure = _executor.Executor().enqueue_procedure( False, checkpoint.undo_action, "Recovering %s." % (checkpoint.undo_action, ), checkpoint.lockable_objects, *checkpoint.param_args, **checkpoint.param_kwargs) procedure.wait() if procedure.status[-1]['success'] != _executor.Job.SUCCESS: _LOGGER.error("Error while recovering %s.", (checkpoint.do_action, )) error = True actions = [] procedure_uuid = None for checkpoint in Checkpoint.registered(): actions.append({ "job": checkpoint.job_uuid, "action": (checkpoint.do_action, "Recovering %s." % (checkpoint.do_action, ), checkpoint.param_args, checkpoint.param_kwargs) }) if procedure_uuid is not None and \ procedure_uuid != checkpoint.proc_uuid: _executor.Executor().reschedule_procedure( procedure_uuid, actions, checkpoint.lockable_objects) procedure_uuid = None actions = [] procedure_uuid = checkpoint.proc_uuid if procedure_uuid is not None: _executor.Executor().reschedule_procedure(procedure_uuid, actions, checkpoint.lockable_objects) return error
def __init__(self): """Constructor for Handler. """ super(Handler, self).__init__() self.__executor = _executor.Executor() self.__instance_for = {} self.__blocks_for = {}
def check_number_threads(increasing=0): """Check the number of threads that are running and whether the maximum number of connections in the state store is configured accordingly. :param increasing: Whether you want to increase the number of threads and how many threads. Default is zero. It raises a ConfigurationError exception if the number of connections is too small. """ from mysql.fabric import ( errors as _errors, executor as _executor, persistence as _persistence, services as _services, server as _server, ) n_sessions = _services.ServiceManager().get_number_sessions() n_executors = _executor.Executor().get_number_executors() n_failure_detectors = \ len(_server.Group.groups_by_status(_server.Group.ACTIVE)) n_controls = 1 persister = _persistence.current_persister() max_allowed_connections = persister.max_allowed_connections() if (n_sessions + n_executors + n_controls + n_failure_detectors +\ increasing) > (max_allowed_connections - 1): raise _errors.ConfigurationError( "Too many threads requested. Session threads (%s), Executor " "threads (%s), Control threads (%s) and Failure Detector threads " "(%s). The maximum number of threads allowed is (%s). Increase " "the maximum number of connections in the state store in order " "to increase this limit." % (n_sessions, n_executors, n_controls, n_failure_detectors, max_allowed_connections - 1))
def _configure_connections(config): """Configure information on database connection and remote servers. :param config: Configuration read from configuration file. """ # Configure the number of concurrent executors. executor = _executor.Executor() executor.set_number_executors(1) # Fetch options to configure the state store. address = config.get('storage', 'address') try: host, port = address.split(':') port = int(port) except ValueError: host = address port = 3306 user = config.get('storage', 'user') database = config.get('storage', 'database') try: password = config.get('storage', 'password') except _config.NoOptionError: password = _get_password("Storage password: "******"storage", "connection_timeout") connection_timeout = float(connection_timeout) except (_config.NoOptionError, _config.NoSectionError, ValueError): connection_timeout = None try: connection_attempts = config.get("storage", "connection_attempts") connection_attempts = int(connection_attempts) except (_config.NoOptionError, _config.NoSectionError, ValueError): connection_attempts = None try: connection_delay = config.get("storage", "connection_delay") connection_delay = int(connection_delay) except (_config.NoOptionError, _config.NoSectionError, ValueError): connection_delay = None try: auth_plugin = config.get("storage", "auth_plugin") except (_config.NoOptionError, _config.NoSectionError, ValueError): auth_plugin = None # Define state store configuration. _persistence.init(host=host, port=port, user=user, password=password, database=database, connection_timeout=connection_timeout, connection_attempts=connection_attempts, connection_delay=connection_delay, auth_plugin=auth_plugin)
def _report_failure(self, server): """Mark the server as faulty and report a failure. The thread is created to allow the built-in failure detector to continue monitoring the servers so that if the report failure hangs, it will kill all connections to faulty servers thus eventually freeing the thread. Not though that the report failure is not crash-safe so it might fail without promoting a new server to master. In the future, we will circumvent this limitation. """ try: _persistence.init_thread() server.status = MySQLServer.FAULTY self.__connection_manager.purge_connections(server) procedures = trigger( "REPORT_FAILURE", None, str(server.uuid), threading.current_thread().name, MySQLServer.FAULTY, False ) executor = _executor.Executor() for procedure in procedures: executor.wait_for_procedure(procedure) _persistence.deinit_thread() finally: self.__thread_report_failure = False
def execute(self, proc_uuids=None): """Wait until a set of procedures uniquely identified by their uuids finish their execution. However, before starting waiting, the function checks if the procedures exist. If one of the procedures is not found, the following exception is raised :class:`~mysql.fabric.errors.ProcedureError`. :param proc_uuids: Iterable with procedures' UUIDs. """ if proc_uuids is None: raise _errors.ProcedureError( "Please, specify which procedure(s) you will be waiting for.") procedures = [] for proc_uuid in proc_uuids: proc_uuid = _uuid.UUID(proc_uuid.strip()) procedure = _executor.Executor().get_procedure(proc_uuid) if not procedure: raise _errors.ProcedureError("Procedure (%s) was not found." % (proc_uuid, )) procedures.append(procedure) command_results = CommandResult(error=None) for procedure in procedures: command_result = ProcedureCommand.wait_for_procedures([ procedure, ], True) if command_result.error is None: for result in command_result.results: command_results.append_result(result) else: result = ResultSet(names=['uuid', 'error'], types=[str, str]) result.append_row( [str(procedure.uuid), str(command_result.error)]) command_results.append_result(result) return command_results
def execute(self, proc_uuids): """Wait until a set of procedures uniquely identified by their uuids finish their execution. However, before starting waiting, the function checks if the procedures exist. If one of the procedures is not found, the following exception is raised :class:`~mysql.fabric.errors.ProcedureError`. :param proc_uuids: Iterable with procedures' uuids. """ procs = [] it_proc_uuids = proc_uuids.split(",") for proc_uuid in it_proc_uuids: proc_uuid = _uuid.UUID(proc_uuid.strip()) procedure = _executor.Executor().get_procedure(proc_uuid) if not procedure: raise _errors.ProcedureError("Procedure (%s) was not found." % (proc_uuid, )) procs.append(procedure) for procedure in procs: procedure.wait() return CommandResult(None)
def wait_for_procedures(procedure_param, synchronous): """Wait until a procedure completes its execution and return detailed information on it. However, if the parameter synchronous is not set, only the procedure's uuid is returned because it is not safe to access the procedure's information while it may be executing. :param procedure_param: Iterable with procedures. :param synchronous: Whether should wait until the procedure finishes its execution or not. :return: A :class:`CommandResult` instance with the execution result. :rtype: CommandResult """ assert len(procedure_param) == 1 synchronous = str(synchronous).upper() not in ("FALSE", "0") if not synchronous: info = ResultSet(names=['uuid'], types=[str]) info.append_row([str(procedure_param[-1].uuid)]) return CommandResult(None, results=info) executor = _executor.Executor() for procedure in procedure_param: executor.wait_for_procedure(procedure) _LOGGER.debug("Result after wait: uuid='%s', status='%s', result='%s'", str(procedure_param[-1].uuid), procedure_param[-1].status, procedure_param[-1].result) # We look at the diagnosis of the last entry to decide the # status of the procedure execution. operation = procedure_param[-1].status[-1] complete = operation['state'] == _executor.Job.COMPLETE success = operation['success'] == _executor.Job.SUCCESS if success: result_field = procedure_param[-1].result info = ResultSet( names=('uuid', 'finished', 'success', 'result'), types=(str, bool, bool, type(result_field)), ) info.append_row([ str(procedure_param[-1].uuid), complete, success, result_field, ]) _LOGGER.debug("Success: uuid='%s', result='%s'", str(procedure_param[-1].uuid), str(procedure_param[-1].result)) rset = ResultSet( names=('state', 'success', 'when', 'description'), types=(int, int, float, str), ) for item in procedure_param[-1].status: rset.append_row([ item['state'], item['success'], item['when'], item['description'], ]) return CommandResult(None, results=[info, rset]) else: # The error message is the last line of the diagnosis, so # we get it from there. error = operation['diagnosis'].split("\n")[-2] _LOGGER.debug("Failure: error='%s'", error) return CommandResult(error)
def _run(self): """Function that verifies servers' availabilities. """ from mysql.fabric.server import ( Group, MySQLServer, ConnectionManager, ) ignored_status = [MySQLServer.FAULTY] quarantine = {} interval = FailureDetector._DETECTION_INTERVAL detections = FailureDetector._DETECTIONS detection_timeout = FailureDetector._DETECTION_TIMEOUT connection_manager = ConnectionManager() slave_deep_checks = FailureDetector._SLAVE_DEEP_CHECKS _persistence.init_thread() while self.__check: try: unreachable = set() group = Group.fetch(self.__group_id) if group is not None: for server in group.servers(): if server.status in ignored_status: ### Server is FAULTY connection_manager.kill_connections(server) continue else: ### Server is Not FAULTY if MySQLServer.is_alive(server, detection_timeout): ### Server is alive ### check depends on `slave_deep_checks` parameter if slave_deep_checks: ### When server is alive and status != FAULTY is_master= (group.master == server.uuid) if not is_master: ### Checking master is dead or alive. master_server = MySQLServer.fetch(group.master) if MySQLServer.is_alive(master_server, detection_timeout): ### Checking is replication valid or not if master is alive. server.connect() slave_issues, why_slave_issues = \ _replication.check_slave_issues(server) if slave_issues: if (why_slave_issues['io_error'] and \ why_slave_issues['io_errno'] == 2003): ### Nothing to do during reconnecting, just logging _LOGGER.info(why_slave_issues) else: ### If slave threads are not running, set status to SPARE server.status = MySQLServer.SPARE ### Done slave_issues. server.disconnect() ### Endif MySQLServer.is_alive(master_server, detection_timeout) ### Endif not is_master ### Endif slave_deep_checks continue ### Else MySQLServer.is_alive(server, detection_timeout) else: unreachable.add(server.uuid) _LOGGER.warning( "Server (%s) in group (%s) is unreachable.", server.uuid, self.__group_id ) unstable = False failed_attempts = 0 if server.uuid not in quarantine: quarantine[server.uuid] = failed_attempts = 1 else: failed_attempts = quarantine[server.uuid] + 1 quarantine[server.uuid] = failed_attempts if failed_attempts >= detections: unstable = True can_set_faulty = group.can_set_server_faulty( server, get_time() ) if unstable and can_set_faulty: # We have to make this transactional and make the # failover (i.e. report failure) robust to failures. # Otherwise, a master might be set to faulty and # a new one never promoted. server.status = MySQLServer.FAULTY connection_manager.kill_connections(server) procedures = trigger("REPORT_FAILURE", None, str(server.uuid), threading.current_thread().name, MySQLServer.FAULTY, False ) executor = _executor.Executor() for procedure in procedures: executor.wait_for_procedure(procedure) ### Endif MySQLServer.is_alive(server, detection_timeout) ### Endif server.status in ignored_status ### End for server in group.servers() ### Endif group is not None for uuid in quarantine.keys(): if uuid not in unreachable: del quarantine[uuid] except (_errors.ExecutorError, _errors.DatabaseError): pass except Exception as error: _LOGGER.exception(error) time.sleep(interval) _persistence.deinit_thread()
def _run(self): """Function that verifies servers' availabilities. """ from mysql.fabric.server import ( Group, MySQLServer, ConnectionManager, ) ignored_status = [MySQLServer.FAULTY] quarantine = {} interval = FailureDetector._DETECTION_INTERVAL detections = FailureDetector._DETECTIONS detection_timeout = FailureDetector._DETECTION_TIMEOUT connection_manager = ConnectionManager() _persistence.init_thread() while self.__check: try: unreachable = set() group = Group.fetch(self.__group_id) if group is not None: for server in group.servers(): if server.status in ignored_status or \ MySQLServer.is_alive(server, detection_timeout): if server.status == MySQLServer.FAULTY: connection_manager.kill_connections(server) continue unreachable.add(server.uuid) _LOGGER.warning( "Server (%s) in group (%s) is unreachable.", server.uuid, self.__group_id ) unstable = False failed_attempts = 0 if server.uuid not in quarantine: quarantine[server.uuid] = failed_attempts = 1 else: failed_attempts = quarantine[server.uuid] + 1 quarantine[server.uuid] = failed_attempts if failed_attempts >= detections: unstable = True can_set_faulty = group.can_set_server_faulty( server, get_time() ) if unstable and can_set_faulty: # We have to make this transactional and make the # failover (i.e. report failure) robust to failures. # Otherwise, a master might be set to faulty and # a new one never promoted. server.status = MySQLServer.FAULTY connection_manager.kill_connections(server) procedures = trigger("REPORT_FAILURE", None, str(server.uuid), threading.current_thread().name, MySQLServer.FAULTY, False ) executor = _executor.Executor() for procedure in procedures: executor.wait_for_procedure(procedure) for uuid in quarantine.keys(): if uuid not in unreachable: del quarantine[uuid] except (_errors.ExecutorError, _errors.DatabaseError): pass except Exception as error: _LOGGER.exception(error) time.sleep(interval / detections) _persistence.deinit_thread()
def test_recovery_chain_jobs(self): """Check checkpoint and recovery when a job triggers another job. """ global COUNT_1, COUNT_2 count_1 = 10 count_2 = 30 proc_uuid = _uuid.UUID("01da10ed-514e-43a4-8388-ab05c04d67e1") lockable_objects = set(["lock"]) job_uuid = _uuid.UUID("e4e1ba17-ff1d-45e6-a83c-5655ea5bb646") job_sequence = 0 job_uuid_registered_1 = \ _uuid.UUID("aaa1ba17-ff1d-45e6-a83c-5655ea5bb646") job_sequence_1 = 1 job_uuid_registered_2 = \ _uuid.UUID("bbb1ba17-ff1d-45e6-a83c-5655ea5bb646") job_sequence_2 = 2 do_action = check_do_action do_action_registered_1 = check_do_action_registered_1 do_action_registered_2 = check_do_action_registered_2 do_action_fqn = do_action.__module__ + "." + do_action.__name__ do_action_registered_1_fqn = \ do_action_registered_1.__module__ + "." + \ do_action_registered_1.__name__ do_action_registered_2_fqn = \ do_action_registered_2.__module__ + "." + \ do_action_registered_2.__name__ args = (count_1, count_2) kwargs = {} # BEGIN DO FINISH (FAILURE) COUNT_1 = 0 COUNT_2 = 0 checkpoint = _checkpoint.Checkpoint( proc_uuid, lockable_objects, job_uuid, job_sequence, do_action_fqn, args, kwargs ) registered_1 = _checkpoint.Checkpoint( proc_uuid, lockable_objects, job_uuid_registered_1, job_sequence_1, do_action_registered_1_fqn, args, kwargs ) registered_2 = _checkpoint.Checkpoint( proc_uuid, lockable_objects, job_uuid_registered_2, job_sequence_2, do_action_registered_2_fqn, args, kwargs ) checkpoint.register() checkpoint.begin() self.persister.begin() do_action(10, 30) checkpoint.finish() registered_1.register() registered_2.register() self.persister.commit() self.assertEqual(COUNT_1, 10) self.assertEqual(COUNT_2, 30) self.assertEqual(MyTransAction.count(), 1) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 2) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 0) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 3) _checkpoint.Checkpoint.cleanup() self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 3) _recovery.recovery() executor = _executor.Executor() procedure = executor.get_procedure(checkpoint.proc_uuid) if procedure is not None: procedure.wait() self.assertEqual(COUNT_1, 30) self.assertEqual(COUNT_2, 90) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 0) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 0) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 0) executor.remove_procedure(proc_uuid)
def test_recovery_single_job(self): """Check checkpoint and recovery with a single job. """ global COUNT_1, COUNT_2 count_1 = 10 count_2 = 30 proc_uuid = _uuid.UUID("9f994e3a-a732-43ba-8aab-f1051f553437") lockable_objects = set(["lock"]) job_uuid = _uuid.UUID("64835080-2114-46de-8fbf-8caba8e8cd90") job_sequence = 0 do_action = check_do_action do_action_fqn = do_action.__module__ + "." + do_action.__name__ args = (count_1, count_2) kwargs = {} # (FAILURE) BEGIN DO FINISH COUNT_1 = 0 COUNT_2 = 0 checkpoint = _checkpoint.Checkpoint( proc_uuid, lockable_objects, job_uuid, job_sequence, do_action_fqn, args, kwargs ) checkpoint.register() self.assertEqual(COUNT_1, 0) self.assertEqual(COUNT_2, 0) self.assertEqual(MyTransAction.count(), 0) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 1) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 0) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 1) _checkpoint.Checkpoint.cleanup() self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 1) _recovery.recovery() executor = _executor.Executor() procedure = executor.get_procedure(checkpoint.proc_uuid) if procedure is not None: procedure.wait() self.assertEqual(COUNT_1, 10) self.assertEqual(COUNT_2, 30) self.assertEqual(MyTransAction.count(), 1) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 0) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 0) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 0) executor.remove_procedure(proc_uuid) # BEGIN (FAILURE) DO FINISH COUNT_1 = 0 COUNT_2 = 0 checkpoint = _checkpoint.Checkpoint( proc_uuid, lockable_objects, job_uuid, job_sequence, do_action_fqn, args, kwargs ) checkpoint.register() checkpoint.begin() self.persister.begin() ####### empty ####### self.persister.rollback() self.assertEqual(COUNT_1, 0) self.assertEqual(COUNT_2, 0) self.assertEqual(MyTransAction.count(), 1) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 1) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 1) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 1) _checkpoint.Checkpoint.cleanup() self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 1) _recovery.recovery() executor = _executor.Executor() procedure = executor.get_procedure(checkpoint.proc_uuid) if procedure is not None: procedure.wait() self.assertEqual(COUNT_1, 10) self.assertEqual(COUNT_2, 30) self.assertEqual(MyTransAction.count(), 2) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 0) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 0) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 0) executor.remove_procedure(proc_uuid) # BEGIN DO (FAILURE) FINISH COUNT_1 = 0 COUNT_2 = 0 checkpoint = _checkpoint.Checkpoint( proc_uuid, lockable_objects, job_uuid, job_sequence, do_action_fqn, args, kwargs ) checkpoint.register() checkpoint.begin() self.persister.begin() do_action(10, 30) checkpoint.finish() self.persister.rollback() self.assertEqual(COUNT_1, 10) self.assertEqual(COUNT_2, 30) self.assertEqual(MyTransAction.count(), 2) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 1) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 1) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 1) _checkpoint.Checkpoint.cleanup() self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 1) _recovery.recovery() executor = _executor.Executor() procedure = executor.get_procedure(checkpoint.proc_uuid) if procedure is not None: procedure.wait() self.assertEqual(COUNT_1, 10) self.assertEqual(COUNT_2, 30) self.assertEqual(MyTransAction.count(), 3) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 0) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 0) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 0) executor.remove_procedure(proc_uuid) # BEGIN DO FINISH (FAILURE) COUNT_1 = 0 COUNT_2 = 0 checkpoint = _checkpoint.Checkpoint( proc_uuid, lockable_objects, job_uuid, job_sequence, do_action_fqn, args, kwargs, ) checkpoint.register() checkpoint.begin() self.persister.begin() do_action(10, 30) checkpoint.finish() self.persister.commit() self.assertEqual(COUNT_1, 10) self.assertEqual(COUNT_2, 30) self.assertEqual(MyTransAction.count(), 4) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 0) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 0) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 1) _recovery.recovery() executor = _executor.Executor() procedure = executor.get_procedure(checkpoint.proc_uuid) if procedure is not None: procedure.wait() self.assertEqual(COUNT_1, 10) self.assertEqual(COUNT_2, 30) self.assertEqual(MyTransAction.count(), 4) self.assertEqual(len(_checkpoint.Checkpoint.unfinished()), 0) self.assertEqual(len(_checkpoint.Checkpoint.registered()), 0) self.assertEqual(len(_checkpoint.Checkpoint.fetch(proc_uuid)), 0) executor.remove_procedure(proc_uuid)
def tearDown(self): """Clean up the existing environment """ _executor.Executor().shutdown() tests.utils.cleanup_environment() _executor.Executor().start()
def _configure_connections(config): """Configure information on database connection and remote servers. """ # Configure the number of concurrent executors. try: number_executors = config.get('executor', "executors") number_executors = int(number_executors) except (_config.NoOptionError, _config.NoSectionError, ValueError): number_executors = DEFAULT_N_EXECUTORS executor = _executor.Executor() executor.set_number_executors(number_executors) services = {} ssl_config = {} # XML-RPC service try: services['protocol.xmlrpc'] = config.get('protocol.xmlrpc', "address") try: number_threads = config.get('protocol.xmlrpc', "threads") number_threads = int(number_threads) except (_config.NoOptionError, ValueError): number_threads = DEFAULT_N_THREADS try: for option in ('ssl_ca', 'ssl_key', 'ssl_cert'): ssl_config[option] = config.get('protocol.xmlrpc', option) except _config.NoOptionError: ssl_config = {} except _config.NoSectionError: raise _errors.ConfigurationError( 'Configuration for protocol.xmlrpc is required') # MySQL-RPC service try: services['protocol.mysql'] = config.get('protocol.mysql', "address") except _config.NoSectionError: # No MySQL-RPC configured pass # Define service configuration _services.ServiceManager(services, number_threads, ssl_config) # Fetch options to configure the state store. address = config.get('storage', 'address') try: host, port = address.split(':') port = int(port) except ValueError: host = address port = _MYSQL_PORT user = config.get('storage', 'user') database = config.get('storage', 'database') try: password = config.get('storage', 'password') except _config.NoOptionError: password = getpass.getpass() try: connection_timeout = config.get("storage", "connection_timeout") connection_timeout = float(connection_timeout) except (_config.NoOptionError, _config.NoSectionError, ValueError): connection_timeout = None try: connection_attempts = config.get("storage", "connection_attempts") connection_attempts = int(connection_attempts) except (_config.NoOptionError, _config.NoSectionError, ValueError): connection_attempts = None try: connection_delay = config.get("storage", "connection_delay") connection_delay = int(connection_delay) except (_config.NoOptionError, _config.NoSectionError, ValueError): connection_delay = None try: auth_plugin = config.get("storage", "auth_plugin") except (_config.NoOptionError, _config.NoSectionError, ValueError): auth_plugin = None # Define state store configuration. _persistence.init(host=host, port=port, user=user, password=password, database=database, connection_timeout=connection_timeout, connection_attempts=connection_attempts, connection_delay=connection_delay, auth_plugin=auth_plugin)
def setUp(self): """Configure the existing environment """ tests.utils.cleanup_environment() self.executor = _executor.Executor()