123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- # -*- coding: utf-8 -*-
- '''
- :copyright: Copyright 2017 by the SaltStack Team, see AUTHORS for more details.
- :license: Apache 2.0, see LICENSE for more details.
- tests.support.processes
- ~~~~~~~~~~~~~~~~~~~~~~~
- Process handling utilities
- '''
- # Import python libs
- from __future__ import absolute_import
- import logging
- # Import pytest-salt libs
- from pytestsalt.utils import SaltRunEventListener as PytestSaltRunEventListener
- from pytestsalt.utils import collect_child_processes, terminate_process, terminate_process_list # pylint: disable=unused-import
- from pytestsalt.fixtures.daemons import Salt as PytestSalt
- from pytestsalt.fixtures.daemons import SaltKey as PytestSaltKey
- from pytestsalt.fixtures.daemons import SaltRun as PytestSaltRun
- from pytestsalt.fixtures.daemons import SaltCall as PytestSaltCall
- from pytestsalt.fixtures.daemons import SaltMaster as PytestSaltMaster
- from pytestsalt.fixtures.daemons import SaltMinion as PytestSaltMinion
- from pytestsalt.fixtures.daemons import SaltSyndic as PytestSaltSyndic
- from pytestsalt.fixtures.daemons import SaltProxy as PytestSaltProxy
- # Import tests support libs
- from tests.support.paths import ScriptPathMixin
- log = logging.getLogger(__name__)
- class SaltRunEventListener(ScriptPathMixin, PytestSaltRunEventListener):
- '''
- Override this class's __init__ because there's no request argument since we're still
- not running under pytest
- '''
- class GetSaltRunFixtureMixin(ScriptPathMixin):
- '''
- Override this classes `get_salt_run_fixture` because we're still not running under pytest
- '''
- def get_salt_run_fixture(self):
- pass
- def get_salt_run_event_listener(self):
- return SaltRunEventListener(None,
- self.config,
- self.config_dir,
- self.bin_dir_path,
- self.log_prefix,
- cli_script_name='run')
- class Salt(ScriptPathMixin, PytestSalt):
- '''
- Class which runs salt-call commands
- '''
- def __init__(self, *args, **kwargs):
- super(Salt, self).__init__(None, *args, **kwargs)
- class SaltCall(ScriptPathMixin, PytestSaltCall):
- '''
- Class which runs salt-call commands
- '''
- def __init__(self, *args, **kwargs):
- super(SaltCall, self).__init__(None, *args, **kwargs)
- class SaltKey(ScriptPathMixin, PytestSaltKey):
- '''
- Class which runs salt-key commands
- '''
- def __init__(self, *args, **kwargs):
- super(SaltKey, self).__init__(None, *args, **kwargs)
- class SaltRun(ScriptPathMixin, PytestSaltRun):
- '''
- Class which runs salt-run commands
- '''
- def __init__(self, *args, **kwargs):
- super(SaltRun, self).__init__(None, *args, **kwargs)
- class SaltProxy(GetSaltRunFixtureMixin, PytestSaltProxy):
- '''
- Class which runs the salt-proxy daemon
- '''
- class SaltMinion(GetSaltRunFixtureMixin, PytestSaltMinion):
- '''
- Class which runs the salt-minion daemon
- '''
- class SaltMaster(GetSaltRunFixtureMixin, PytestSaltMaster):
- '''
- Class which runs the salt-master daemon
- '''
- class SaltSyndic(GetSaltRunFixtureMixin, PytestSaltSyndic):
- '''
- Class which runs the salt-syndic daemon
- '''
- def start_daemon(daemon_name=None,
- daemon_id=None,
- daemon_log_prefix=None,
- daemon_cli_script_name=None,
- daemon_config=None,
- daemon_config_dir=None,
- daemon_class=None,
- bin_dir_path=None,
- fail_hard=False,
- start_timeout=10,
- slow_stop=False,
- environ=None,
- cwd=None):
- '''
- Returns a running salt daemon
- '''
- daemon_config['pytest_port'] = daemon_config['runtests_conn_check_port']
- request = None
- if fail_hard:
- fail_method = RuntimeError
- else:
- fail_method = RuntimeWarning
- log.info('[%s] Starting pytest %s(%s)', daemon_name, daemon_log_prefix, daemon_id)
- attempts = 0
- process = None
- while attempts <= 3: # pylint: disable=too-many-nested-blocks
- attempts += 1
- process = daemon_class(request,
- daemon_config,
- daemon_config_dir,
- bin_dir_path,
- daemon_log_prefix,
- cli_script_name=daemon_cli_script_name,
- slow_stop=slow_stop,
- environ=environ,
- cwd=cwd)
- process.start()
- if process.is_alive():
- try:
- connectable = process.wait_until_running(timeout=start_timeout)
- if connectable is False:
- connectable = process.wait_until_running(timeout=start_timeout/2)
- if connectable is False:
- process.terminate()
- if attempts >= 3:
- fail_method(
- 'The pytest {0}({1}) has failed to confirm running status '
- 'after {2} attempts'.format(daemon_name, daemon_id, attempts))
- continue
- except Exception as exc: # pylint: disable=broad-except
- log.exception('[%s] %s', daemon_log_prefix, exc, exc_info=True)
- terminate_process(process.pid, kill_children=True, slow_stop=slow_stop)
- if attempts >= 3:
- raise fail_method(str(exc))
- continue
- log.info(
- '[%s] The pytest %s(%s) is running and accepting commands '
- 'after %d attempts',
- daemon_log_prefix,
- daemon_name,
- daemon_id,
- attempts
- )
- def stop_daemon():
- log.info('[%s] Stopping pytest %s(%s)', daemon_log_prefix, daemon_name, daemon_id)
- terminate_process(process.pid, kill_children=True, slow_stop=slow_stop)
- log.info('[%s] pytest %s(%s) stopped', daemon_log_prefix, daemon_name, daemon_id)
- # request.addfinalizer(stop_daemon)
- return process
- else:
- terminate_process(process.pid, kill_children=True, slow_stop=slow_stop)
- continue
- else: # pylint: disable=useless-else-on-loop
- # Wrong, we have a return, its not useless
- if process is not None:
- terminate_process(process.pid, kill_children=True, slow_stop=slow_stop)
- raise fail_method(
- 'The pytest {0}({1}) has failed to start after {2} attempts'.format(
- daemon_name,
- daemon_id,
- attempts-1
- )
- )
|