def __init__(self, args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=None, env=None, timeout=None, subprocess_factory=None): """Constructs the Popen instance. Unlike subprocess.Popen, this class supports only the following arguments. - |args|: Command line arguments. Must be a list of str. Note that subprocess.Popen supports str args, but it is not supported here. - |stdout|, |stderr|: Must be None or subprocess.PIPE. - |cwd|, |env|: passed through to the subprocess.Popen. - |timeout|: Process timeout duration in seconds. |timeout| secs after the process is created, terminate() is invoked. Also, handle_timeout() will be invoked, via handle_output(). |timeout| can be None to not apply a timeout. - subprocess_factory: factory to launch a real subprocess. It should take |args|, |stdout|, |stderr|, |cwd| and |env| as its arguments. By default (= None), the default subprocess factory is used. """ assert isinstance(args, list), '|args| must be a list, %r' % (args,) assert stdout in (None, subprocess.PIPE), ( 'stdout for concurrent_subprocess.Popen must be None or PIPE.') assert stderr in (None, subprocess.PIPE, subprocess.STDOUT), ( 'stderr for concurrent_subprocess.Popen must be None, PIPE or STDOUT.') self._lock = threading.Lock() # Set True when timed out. self._timedout = False self._handle_output_invoked = False # Set when kill() is called. self._kill_event = threading.Event() # threading.Timer instances for timeout or terminate_later. # When the subprocess is poll()ed, all timers will be cancelled and # _timers will be set to None. See _poll_locked() for more details. self._timers = [] if subprocess_factory is None: subprocess_factory = ( _XvfbPopen if args[0] == 'xvfb-run' else subprocess.Popen) formatted_commandline = ( logging_util.format_commandline(args, cwd=cwd, env=env)) logging.info('Popen: %s', formatted_commandline) try: self._process = subprocess_factory( args, stdout=stdout, stderr=stderr, cwd=cwd, env=env) except Exception: logging.exception('Popen failed: %s', formatted_commandline) raise logging.info('Created pid %d', self._process.pid) # Set timeout timer, when specified. if timeout: with self._lock: self._start_timer_locked(timeout, self._timeout)
def _remove_iteration_lock_file(self): """Removes the iteration lock file, possibly on remote machine.""" if self._remote: args = [ 'ssh', '-o', 'StrictHostKeyChecking=no', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'PasswordAuthentication=no', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=%s' % _SSH_CONTROL_PATH, '-i', _TEST_SSH_KEY, 'root@%s' % self._remote ] os.chmod(os.path.join(self._arc_root, _TEST_SSH_KEY), 0600) else: args = ['bash', '-c'] args.append('rm -f "%s"' % self._iteration_lock_file) logging.info('$ %s', logging_util.format_commandline(args, cwd=self._arc_root)) subprocess.check_call(args, cwd=self._arc_root)
def _remove_iteration_lock_file(self): """Removes the iteration lock file, possibly on remote machine.""" if self._remote: args = [ 'ssh', '-o', 'StrictHostKeyChecking=no', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'PasswordAuthentication=no', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=%s' % _SSH_CONTROL_PATH, '-i', _TEST_SSH_KEY, 'root@%s' % self._remote] os.chmod(os.path.join(self._arc_root, _TEST_SSH_KEY), 0600) else: args = ['bash', '-c'] args.append('rm -f "%s"' % self._iteration_lock_file) logging.info('$ %s', logging_util.format_commandline(args, cwd=self._arc_root)) subprocess.check_call(args, cwd=self._arc_root)
def _run_command(func, *args, **kwargs): logging.info( '%s', logging_util.format_commandline(_get_command(*args, **kwargs))) return func(*args, **kwargs)
def __init__(self, args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=None, env=None, timeout=None, subprocess_factory=None): """Constructs the Popen instance. Unlike subprocess.Popen, this class supports only the following arguments. - |args|: Command line arguments. Must be a list of str. Note that subprocess.Popen supports str args, but it is not supported here. - |stdout|, |stderr|: Must be None or subprocess.PIPE. - |cwd|, |env|: passed through to the subprocess.Popen. - |timeout|: Process timeout duration in seconds. |timeout| secs after the process is created, terminate() is invoked. Also, handle_timeout() will be invoked, via handle_output(). |timeout| can be None to not apply a timeout. - subprocess_factory: factory to launch a real subprocess. It should take |args|, |stdout|, |stderr|, |cwd| and |env| as its arguments. By default (= None), the default subprocess factory is used. """ assert isinstance(args, list), '|args| must be a list, %r' % (args, ) assert stdout in (None, subprocess.PIPE), ( 'stdout for concurrent_subprocess.Popen must be None or PIPE.') assert stderr in (None, subprocess.PIPE, subprocess.STDOUT), ( 'stderr for concurrent_subprocess.Popen must be None, PIPE or STDOUT.' ) self._lock = threading.Lock() # Set True when timed out. self._timedout = False self._handle_output_invoked = False # Set when kill() is called. self._kill_event = threading.Event() # threading.Timer instances for timeout or terminate_later. # When the subprocess is poll()ed, all timers will be cancelled and # _timers will be set to None. See _poll_locked() for more details. self._timers = [] if subprocess_factory is None: subprocess_factory = (_XvfbPopen if args[0] == 'xvfb-run' else subprocess.Popen) formatted_commandline = (logging_util.format_commandline(args, cwd=cwd, env=env)) logging.info('Popen: %s', formatted_commandline) try: self._process = subprocess_factory(args, stdout=stdout, stderr=stderr, cwd=cwd, env=env) except Exception: logging.exception('Popen failed: %s', formatted_commandline) raise logging.info('Created pid %d', self._process.pid) # Set timeout timer, when specified. if timeout: with self._lock: self._start_timer_locked(timeout, self._timeout)