def _initialize(self, shelldicts):
     self.terminal = AutoRunnerTerminal()
     self.proxies = _RemoteRunnerProxies(self.terminal)
     self.terminal.initialize_with_shelldicts(
         shelldicts=deepcopy(shelldicts),
         prepare=self._prepare)
     self._initialize_terminal()
def test_error_handling(mock_session, mock_get_response_or_raise):
    terminal = AutoRunnerTerminal()
    terminal.initialize(session=mock_session)
    assert terminal.run_python('cmd') == (
        mock_get_response_or_raise.return_value.obj)

    mock_session.auto_close.assert_called_once_with()
def test_initialize_with_finalize(mock_session):
    mock_finalize = mock.Mock()
    terminal = AutoRunnerTerminal()
    terminal.initialize(session=mock_session, finalize=mock_finalize)

    _, set_finalize_args, _ = mock_session.set_finalize.mock_calls[0]
    mock_session_finalize = set_finalize_args[0]
    mock_session_finalize()

    mock_finalize.assert_called_once_with()
def test_initialize(mock_session):
    terminal = AutoRunnerTerminal()
    terminal.initialize(session=mock_session)
    # pylint: disable=protected-access
    mock_session.set_prepare.assert_called_once_with(terminal.setup_session)
    mock_session.set_finalize.assert_called_once_with(
        terminal._close_in_auto_close)
    mock_session.set_broken_exceptions.assert_called_once_with(
        RunnerTerminalSessionBroken)
    mock_session.set_verify.assert_called_once_with(terminal._verify)
def test_autorecovery_as_local(mock_interactivesession, is_finalize):

    terminal = AutoRunnerTerminal()
    p = SimpleProxyContainer(terminal)
    fkwargs = {'finalize': p.finalize} if is_finalize else {}
    terminal.initialize_with_shells(shells=mock.Mock(),
                                    prepare=p.prepare,
                                    **fkwargs)

    assert p.proxy.as_local_value() == '0'
    break_session(mock_interactivesession)
    assert p.proxy.as_local_value() == '0'
def test_error_handling_closed_session(mock_session):
    terminal = AutoRunnerTerminal()
    terminal.initialize(session=mock_session)
    terminal.close()
    with pytest.raises(RunnerTerminalSessionClosed) as excinfo:
        terminal.run_python('cmd')

    assert "Trying to run command" in excinfo.value.args[0]
class _Terminal(object):

    def __init__(self, key, shelldicts, properties):
        self.key = key
        self.shelldicts = shelldicts
        self.properties = properties
        self.terminal = None
        self.proxies = None
        self._initialize(shelldicts)
        self.terminal_cleanup = lambda: None
        self.is_persistent = lambda: True

    def set_terminal_cleanup(self, terminal_cleanup):
        self.terminal_cleanup = terminal_cleanup

    def set_is_persistent(self, is_persistent):
        self.is_persistent = is_persistent

    def shall_be_stored(self):
        return self.is_persistent() and self.terminal is not None

    def _initialize(self, shelldicts):
        self.terminal = AutoRunnerTerminal()
        self.proxies = _RemoteRunnerProxies(self.terminal)
        self.terminal.initialize_with_shelldicts(
            shelldicts=deepcopy(shelldicts),
            prepare=self._prepare)
        self._initialize_terminal()

    def _prepare(self):
        self.proxies.prepare()

    def initialize_with_properties(self, properties):
        self.properties = properties
        self._initialize_terminal()

    def _initialize_terminal(self):
        self.terminal.prompt_timeout = self.properties.prompt_timeout

    def close(self):
        if self.terminal is not None:
            try:
                self.terminal_cleanup()
                self.terminal.close()
            finally:
                self.terminal = None
class FileCopier(object):
    def __init__(self, shells=None):
        self.terminal = None
        self.buffersize = 32768
        self._initialize(BashShell() if shells is None else shells)
        self._buf = None

    def set_buffersize(self, buffersize):
        self.buffersize = buffersize

    def _initialize(self, shells):
        self.terminal = AutoRunnerTerminal()
        self.terminal.initialize_with_shells(shells=shells)

    def copy_file_to_remote(self, source, dest):
        self._copy_file_from_ropen_to_wopen(
            lambda: open(source, 'rb'),
            lambda: _RemoteFile(self.terminal, dest, 'wb'))

    def copy_file_from_remote(self, source, dest):
        self._copy_file_from_ropen_to_wopen(
            lambda: _RemoteFile(self.terminal, source, 'rb'),
            lambda: open(dest, 'wb'))

    def _copy_file_from_ropen_to_wopen(self, ropen, wopen):
        with ropen() as readf:
            with wopen() as writef:
                self._copy_file_from_readf_to_writef(readf, writef)

    def _copy_file_from_readf_to_writef(self, readf, writef):
        while self._read(readf):
            writef.write(self._buf)

    def _read(self, readf):
        self._buf = readf.read(self.buffersize)
        return self._buf
def test_error_handling_session_broken(mock_session,
                                       mock_get_response_or_raise):
    terminal = AutoRunnerTerminal()
    terminal.initialize(session=mock_session)
    mock_get_response_or_raise.side_effect = RunnerTerminalSessionBroken

    with pytest.raises(RunnerTerminalSessionBroken):
        terminal.run_python('cmd')

    mock_session.auto_close.assert_called_once_with()
def autorunnerterminal():
    a = AutoRunnerTerminal()
    try:
        yield a
    finally:
        a.close()
 def _initialize(self, shells):
     self.terminal = AutoRunnerTerminal()
     self.terminal.initialize_with_shells(shells=shells)
Example #12
0
 def _initialize(self, shells):
     self.terminal = AutoRunnerTerminal()
     self.terminal.initialize_with_shells(shells=shells,
                                          prepare=self._prepare)
     self._setup_with_empty_proxies()
Example #13
0
class BackgroundRunner(object):
    def __init__(self, shells=None):
        self.terminal = None
        self.popen = None
        self.pipe = None
        self.os = None
        self._initialize(BashShell() if shells is None else shells)

    def _initialize(self, shells):
        self.terminal = AutoRunnerTerminal()
        self.terminal.initialize_with_shells(shells=shells,
                                             prepare=self._prepare)
        self._setup_with_empty_proxies()

    def _setup_with_empty_proxies(self):
        self.os = _OsProxies(self.terminal)
        self.popen = self.terminal.create_empty_recursive_proxy()
        self.pipe = self.terminal.create_empty_remote_proxy()

    def _prepare(self):
        self._import_libraries()
        self._setup_proxies()

    def _import_libraries(self):
        self.terminal.import_libraries('os', 'subprocess')

    def _setup_proxies(self):
        self._setup_subprocess_proxies()
        self._setup_os_proxies()

    def _setup_subprocess_proxies(self):
        self.popen.set_from_remote_proxy(
            self.terminal.get_recursive_proxy('subprocess.Popen'))
        self.pipe.set_from_remote_proxy(
            self.terminal.get_proxy_object('subprocess.PIPE', None))

    def _setup_os_proxies(self):
        self.os.killpg.set_from_remote_proxy(
            self.terminal.get_proxy_object('os.killpg', None))
        self.os.getpgid.set_from_remote_proxy(
            self.terminal.get_proxy_object('os.getpgid', None))
        self.os.setsid.set_from_remote_proxy(
            self.terminal.get_proxy_object('os.setsid', None))

    def run_in_background(self, cmd):
        pro = self.popen(cmd,
                         stdout=self.pipe,
                         stderr=self.pipe,
                         shell=True,
                         preexec_fn=self.os.setsid)
        return self._communicate(pro)

    @staticmethod
    def _communicate(pro):
        communicate = pro.communicate
        communicate.remote_proxy_use_asynchronous_response()
        return ResponseHandle(pro=pro, handle=communicate())

    def terminate_and_get_response(self, handle):
        self._terminate_if_needed(handle.pro)
        out, err = handle.pro.get_remote_proxy_response(handle.handle,
                                                        timeout=10)
        return RunResponse(ret=handle.pro.returncode, out=out, err=err)

    def _terminate_if_needed(self, pro):
        try:
            self.os.killpg(self.os.getpgid(pro.pid), signal.SIGTERM)
        except OSError as e:
            if e.errno == errno.ESRCH:
                logger.debug('Not terminating: process already terminated')
            else:
                raise