Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-paramiko-expect for
openSUSE:Factory checked in at 2022-04-08 00:28:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-paramiko-expect (Old)
and /work/SRC/openSUSE:Factory/.python-paramiko-expect.new.1900 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-paramiko-expect"
Fri Apr 8 00:28:25 2022 rev:3 rq:967527 version:0.3.2
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-paramiko-expect/python-paramiko-expect.changes
2020-04-21 13:10:26.216784721 +0200
+++
/work/SRC/openSUSE:Factory/.python-paramiko-expect.new.1900/python-paramiko-expect.changes
2022-04-08 00:29:03.893413972 +0200
@@ -1,0 +2,6 @@
+Thu Apr 7 11:55:05 UTC 2022 - [email protected]
+
+- version update to 0.3.2
+ * no upstream changelog file found
+
+-------------------------------------------------------------------
Old:
----
paramiko-expect-0.2.8.tar.gz
New:
----
paramiko-expect-0.3.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-paramiko-expect.spec ++++++
--- /var/tmp/diff_new_pack.4S0XTe/_old 2022-04-08 00:29:04.481407343 +0200
+++ /var/tmp/diff_new_pack.4S0XTe/_new 2022-04-08 00:29:04.489407252 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-paramiko-expect
#
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%bcond_without python2
Name: python-paramiko-expect
-Version: 0.2.8
+Version: 0.3.2
Release: 0
Summary: An expect-like extension for the Paramiko SSH library
License: MIT
++++++ paramiko-expect-0.2.8.tar.gz -> paramiko-expect-0.3.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/paramiko-expect-0.2.8/PKG-INFO
new/paramiko-expect-0.3.2/PKG-INFO
--- old/paramiko-expect-0.2.8/PKG-INFO 2017-05-15 23:02:20.000000000 +0200
+++ new/paramiko-expect-0.3.2/PKG-INFO 2022-01-13 13:07:35.973393200 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: paramiko-expect
-Version: 0.2.8
+Version: 0.3.2
Summary: An expect-like extension for the Paramiko SSH library
Home-page: https://github.com/fgimian/paramiko-expect
Author: Fotis Gimian
@@ -12,16 +12,16 @@
.. image:: https://img.shields.io/pypi/l/paramiko-expect.svg
:target:
https://github.com/fgimian/paramiko-expect/blob/master/LICENSE
- .. image::
https://coveralls.io/repos/github/fgimian/paramiko-expect/badge.svg?branch=master
- :target:
https://coveralls.io/github/fgimian/paramiko-expect?branch=master
+ .. image::
https://codecov.io/gh/fgimian/paramiko-expect/branch/master/graph/badge.svg
+ :target: https://codecov.io/gh/fgimian/paramiko-expect
- .. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg
+ .. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg
:target: https://travis-ci.org/fruch/paramiko-expect/
- .. image:: https://img.shields.io/pypi/v/paramiko-expect.svg
+ .. image:: https://img.shields.io/pypi/v/paramiko-expect.svg
:target: https://pypi.python.org/pypi/paramiko-expect/
- .. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg
+ .. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg
:target: https://pypi.python.org/pypi/paramiko-expect/
@@ -49,7 +49,7 @@
.. code:: bash
# from pypi
- pip insall paramiko-expect
+ pip install paramiko-expect
# from source
pip install git+https://github.com/fgimian/paramiko-expect.git
@@ -183,7 +183,7 @@
.. code:: bash
pip install -r requirements-test.txt
- docker run -d -p 2222:22 -v `pwd`/examples:/examples -v
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys macropin/sshd
+ docker run -d -p 2222:22 -v `pwd`/examples:/examples -v
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys docker.io/panubo/sshd
pytest -s --cov paramiko_expect --cov-report term-missing
@@ -204,11 +204,10 @@
Platform: Posix
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Intended Audience :: Developers
+Description-Content-Type: text/x-rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/paramiko-expect-0.2.8/README.rst
new/paramiko-expect-0.3.2/README.rst
--- old/paramiko-expect-0.2.8/README.rst 2017-05-15 23:01:24.000000000
+0200
+++ new/paramiko-expect-0.3.2/README.rst 2021-01-24 21:23:29.000000000
+0100
@@ -4,16 +4,16 @@
.. image:: https://img.shields.io/pypi/l/paramiko-expect.svg
:target: https://github.com/fgimian/paramiko-expect/blob/master/LICENSE
-.. image::
https://coveralls.io/repos/github/fgimian/paramiko-expect/badge.svg?branch=master
- :target: https://coveralls.io/github/fgimian/paramiko-expect?branch=master
+.. image::
https://codecov.io/gh/fgimian/paramiko-expect/branch/master/graph/badge.svg
+ :target: https://codecov.io/gh/fgimian/paramiko-expect
-.. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg
+.. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg
:target: https://travis-ci.org/fruch/paramiko-expect/
-.. image:: https://img.shields.io/pypi/v/paramiko-expect.svg
+.. image:: https://img.shields.io/pypi/v/paramiko-expect.svg
:target: https://pypi.python.org/pypi/paramiko-expect/
-.. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg
+.. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg
:target: https://pypi.python.org/pypi/paramiko-expect/
@@ -41,7 +41,7 @@
.. code:: bash
# from pypi
- pip insall paramiko-expect
+ pip install paramiko-expect
# from source
pip install git+https://github.com/fgimian/paramiko-expect.git
@@ -175,7 +175,7 @@
.. code:: bash
pip install -r requirements-test.txt
- docker run -d -p 2222:22 -v `pwd`/examples:/examples -v
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys macropin/sshd
+ docker run -d -p 2222:22 -v `pwd`/examples:/examples -v
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys docker.io/panubo/sshd
pytest -s --cov paramiko_expect --cov-report term-missing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/paramiko-expect-0.2.8/paramiko_expect.egg-info/PKG-INFO
new/paramiko-expect-0.3.2/paramiko_expect.egg-info/PKG-INFO
--- old/paramiko-expect-0.2.8/paramiko_expect.egg-info/PKG-INFO 2017-05-15
23:02:20.000000000 +0200
+++ new/paramiko-expect-0.3.2/paramiko_expect.egg-info/PKG-INFO 2022-01-13
13:07:35.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: paramiko-expect
-Version: 0.2.8
+Version: 0.3.2
Summary: An expect-like extension for the Paramiko SSH library
Home-page: https://github.com/fgimian/paramiko-expect
Author: Fotis Gimian
@@ -12,16 +12,16 @@
.. image:: https://img.shields.io/pypi/l/paramiko-expect.svg
:target:
https://github.com/fgimian/paramiko-expect/blob/master/LICENSE
- .. image::
https://coveralls.io/repos/github/fgimian/paramiko-expect/badge.svg?branch=master
- :target:
https://coveralls.io/github/fgimian/paramiko-expect?branch=master
+ .. image::
https://codecov.io/gh/fgimian/paramiko-expect/branch/master/graph/badge.svg
+ :target: https://codecov.io/gh/fgimian/paramiko-expect
- .. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg
+ .. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg
:target: https://travis-ci.org/fruch/paramiko-expect/
- .. image:: https://img.shields.io/pypi/v/paramiko-expect.svg
+ .. image:: https://img.shields.io/pypi/v/paramiko-expect.svg
:target: https://pypi.python.org/pypi/paramiko-expect/
- .. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg
+ .. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg
:target: https://pypi.python.org/pypi/paramiko-expect/
@@ -49,7 +49,7 @@
.. code:: bash
# from pypi
- pip insall paramiko-expect
+ pip install paramiko-expect
# from source
pip install git+https://github.com/fgimian/paramiko-expect.git
@@ -183,7 +183,7 @@
.. code:: bash
pip install -r requirements-test.txt
- docker run -d -p 2222:22 -v `pwd`/examples:/examples -v
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys macropin/sshd
+ docker run -d -p 2222:22 -v `pwd`/examples:/examples -v
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys docker.io/panubo/sshd
pytest -s --cov paramiko_expect --cov-report term-missing
@@ -204,11 +204,10 @@
Platform: Posix
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Intended Audience :: Developers
+Description-Content-Type: text/x-rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/paramiko-expect-0.2.8/paramiko_expect.py
new/paramiko-expect-0.3.2/paramiko_expect.py
--- old/paramiko-expect-0.2.8/paramiko_expect.py 2017-05-15
23:01:24.000000000 +0200
+++ new/paramiko-expect-0.3.2/paramiko_expect.py 2021-12-14
15:03:04.000000000 +0100
@@ -13,25 +13,31 @@
#
from __future__ import unicode_literals
+import codecs
import sys
import re
import socket
import struct
+import time
# Windows does not have termios
try:
import termios
import tty
has_termios = True
-except ImportError: # pragma: no cover
+ MAX_TIMEOUT = 2 ** (struct.Struct(str('i')).size * 8 - 1) - 1
+except ImportError: # pragma: no cover
import threading
has_termios = False
+ MAX_TIMEOUT = threading.TIMEOUT_MAX
import select
+
def strip_ansi_codes(s):
return re.sub(r'\x1b\[([0-9,A-Z]{1,2}(;[0-9]{1,2})?(;[0-9]{3})?)?[m|K]?',
'', s)
+
def default_output_func(msg):
sys.stdout.write(msg)
sys.stdout.flush()
@@ -52,12 +58,14 @@
real-time as it is being performed (especially useful
when debugging)
:param encoding: The character encoding to use.
+ :param lines_to_check: The number of last few lines of the output to
+ look at, while matching regular expression(s)
"""
def __init__(
self, client, timeout=60, newline='\r', buffer_size=1024,
display=False, encoding='utf-8', output_callback=default_output_func,
- tty_width=80, tty_height=24
+ tty_width=80, tty_height=24, lines_to_check=1
):
self.channel = client.invoke_shell(width=tty_width, height=tty_height)
self.timeout = timeout
@@ -66,12 +74,17 @@
self.display = display
self.encoding = encoding
self.output_callback = output_callback
+ self.lines_to_check = lines_to_check
self.current_output = ''
self.current_output_clean = ''
self.current_send_string = ''
self.last_match = ''
+ # If the output is long, multi-byte encoded characters may be split
+ # across calls to recv, so decode incrementally.
+ self.decoder = codecs.getincrementaldecoder(self.encoding)()
+
def __del__(self):
self.close()
@@ -85,10 +98,13 @@
"""Attempts to close the channel for clean completion."""
try:
self.channel.close()
- except:
+ except Exception:
pass
- def expect(self, re_strings='', timeout=None, output_callback=None,
default_match_prefix='.*\n', strip_ansi=True):
+ def expect(
+ self, re_strings='', timeout=None, output_callback=None,
default_match_prefix='.*\n',
+ strip_ansi=True, ignore_decode_error=True, lines_to_check=None
+ ):
"""
This function takes in a regular expression (or regular expressions)
that represent the last line of output from the server. The function
@@ -111,6 +127,10 @@
or the command has no output.
:param strip_ansi: If True, will strip ansi control chars befores
regex matching
default to True.
+ :param ignore_decode_error: If True, will ignore decode errors if any.
+ default to True.
+ :param lines_to_check: The number of last few lines of the output to
+ look at, while matching regular expression(s)
:return: An EOF returns -1, a regex metch returns 0 and a match in a
list of regexes returns the index of the matched string in
the list.
@@ -122,15 +142,21 @@
timeout = timeout if timeout else self.timeout
self.channel.settimeout(timeout)
+ lines_to_check = lines_to_check if lines_to_check else
self.lines_to_check
+
+ if ignore_decode_error:
+ self.decoder =
codecs.getincrementaldecoder(self.encoding)('ignore')
# Create an empty output buffer
self.current_output = ''
-
+ # saves the current buffer to check for re_strings pattern
+ current_buffer_output_decoded = ''
# This function needs all regular expressions to be in the form of a
# list, so if the user provided a string, let's convert it to a 1
# item list.
if isinstance(re_strings, str) and len(re_strings) != 0:
re_strings = [re_strings]
-
+ # to avoid looping in recv_ready()
+ base_time = time.time()
# Loop until one of the expressions is matched or loop forever if
# nothing is expected (usually used for exit)
while (
@@ -138,8 +164,15 @@
not [re_string
for re_string in re_strings
if re.match(default_match_prefix + re_string + '$',
- self.current_output, re.DOTALL)]
+ current_buffer_output_decoded, re.DOTALL)]
):
+ current_buffer_output_decoded = ''
+ # avoids paramiko hang when recv is not ready yet
+ while not self.channel.recv_ready():
+ time.sleep(.009)
+ if time.time() >= (base_time + timeout):
+ print('EXCESS TIME RECV_READY TIMEOUT, did you expect()
before a send()')
+ return -1
# Read some of the output
current_buffer = self.channel.recv(self.buffer_size)
@@ -148,7 +181,7 @@
break
# Convert the buffer to our chosen encoding
- current_buffer_decoded = current_buffer.decode(self.encoding)
+ current_buffer_decoded = self.decoder.decode(current_buffer)
# Strip all ugly \r (Ctrl-M making) characters from the current
# read
@@ -156,14 +189,18 @@
# Display the current buffer in realtime if requested to do so
# (good for debugging purposes)
- if self.display:
- output_callback(current_buffer_decoded)
-
if strip_ansi:
current_buffer_decoded =
strip_ansi_codes(current_buffer_decoded)
+ if not current_buffer_decoded:
+ continue
+
+ if self.display:
+ output_callback(current_buffer_decoded)
+
# Add the currently read buffer to the output
self.current_output += current_buffer_decoded
+ current_buffer_output_decoded = '\n' +
'\n'.join(self.current_output.splitlines()[-lines_to_check:])
# Grab the first pattern that was matched
if len(re_strings) != 0:
@@ -177,7 +214,7 @@
if len(self.current_send_string) != 0:
self.current_output_clean = (
self.current_output_clean.replace(
- self.current_send_string + '\n', ''
+ self.current_send_string + self.newline, ''
)
)
@@ -200,12 +237,21 @@
# measure, let's send back a -1
return -1
- def send(self, send_string):
+ def send(self, send_string, newline=None):
"""Saves and sends the send string provided."""
self.current_send_string = send_string
- self.channel.send(send_string + self.newline)
-
- def tail(self, line_prefix=None, callback=None, output_callback=None,
stop_callback=lambda x: False, timeout=None):
+ # send_string, _ = codecs.getdecoder(self.encoding)(send_string)
+ newline = newline if newline is not None else self.newline
+ # don't send till send_ready
+ while not self.channel.send_ready():
+ time.sleep(.009)
+ self.channel.send(send_string)
+ self.channel.send(newline)
+
+ def tail(
+ self, line_prefix=None, callback=None, output_callback=None,
stop_callback=lambda x: False,
+ timeout=None
+ ):
"""
This function takes control of an SSH channel and displays line
by line of output as \n is recieved. This function is specifically
@@ -225,18 +271,18 @@
:param output_callback: A function used to print ssh output. Printed
to stdout
by default. A user-defined logger may be passed like
output_callback=lambda m: mylog.debug(m)
- :param stop_callback: A function usesd to stop the tail, when function
retruns
+ :param stop_callback: A function usesd to stop the tail, when function
retruns
True tail will stop, by default stop_callback=lambda
x: False
- :param timeout: how much time to wait for data, default to None which
+ :param timeout: how much time to wait for data, default to None which
mean almost forever.
"""
output_callback = output_callback if output_callback else
self.output_callback
- # Set the channel timeout to the maximum integer the server allows,
+ # Set the channel timeout to the maximum allowed value,
# setting this to None breaks the KeyboardInterrupt exception and
- # won't allow us to Ctrl+C out of teh script
- timeout = timeout if timeout else 2 ** (struct.Struct(str('i')).size
* 8 - 1) - 1
+ # won't allow us to Ctrl+C out of the script
+ timeout = timeout if timeout else MAX_TIMEOUT
self.channel.settimeout(timeout)
# Create an empty line buffer and a line counter
@@ -260,7 +306,7 @@
# Display the last read line in realtime when we reach a \n
# character
if buffer == line_feed_byte:
- current_line_decoded = current_line.decode(self.encoding)
+ current_line_decoded = self.decoder.decode(current_line)
if line_counter:
if callback:
output_callback(callback(line_prefix,
current_line_decoded))
@@ -307,7 +353,7 @@
buffer = self.channel.recv(self.buffer_size)
if len(buffer) == 0:
break
- sys.stdout.write(buffer.decode(self.encoding))
+ sys.stdout.write(self.decoder.decode(buffer))
sys.stdout.flush()
except socket.timeout:
pass
@@ -327,7 +373,7 @@
buffer = sock.recv(self.buffer_size)
if len(buffer) == 0:
break
- sys.stdout.write(buffer.decode(self.encoding))
+ sys.stdout.write(self.decoder.decode(buffer))
sys.stdout.flush()
writer = threading.Thread(target=writeall, args=(self.channel,))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/paramiko-expect-0.2.8/setup.cfg
new/paramiko-expect-0.3.2/setup.cfg
--- old/paramiko-expect-0.2.8/setup.cfg 2017-05-15 23:02:20.000000000 +0200
+++ new/paramiko-expect-0.3.2/setup.cfg 2022-01-13 13:07:35.973393200 +0100
@@ -4,5 +4,4 @@
[egg_info]
tag_build =
tag_date = 0
-tag_svn_revision = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/paramiko-expect-0.2.8/setup.py
new/paramiko-expect-0.3.2/setup.py
--- old/paramiko-expect-0.2.8/setup.py 2017-05-15 23:01:24.000000000 +0200
+++ new/paramiko-expect-0.3.2/setup.py 2022-01-13 13:07:25.000000000 +0100
@@ -8,13 +8,14 @@
setup(
name='paramiko-expect',
- version='0.2.8',
+ version='0.3.2',
url='https://github.com/fgimian/paramiko-expect',
license='MIT',
author='Fotis Gimian',
author_email='[email protected]',
description='An expect-like extension for the Paramiko SSH library',
long_description=long_description,
+ long_description_content_type='text/x-rst',
platforms='Posix',
py_modules=['paramiko_expect'],
install_requires=[
@@ -23,9 +24,7 @@
classifiers=[
'Development Status :: 4 - Beta',
'License :: OSI Approved :: MIT License',
- 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/paramiko-expect-0.2.8/test/test_paramiko_expect.py
new/paramiko-expect-0.3.2/test/test_paramiko_expect.py
--- old/paramiko-expect-0.2.8/test/test_paramiko_expect.py 2017-05-15
23:01:24.000000000 +0200
+++ new/paramiko-expect-0.3.2/test/test_paramiko_expect.py 2022-01-13
13:07:25.000000000 +0100
@@ -1,5 +1,5 @@
-import io
-import sys
+# -*- coding: utf-8 -*-
+
import socket
import pytest
@@ -13,15 +13,15 @@
from paramiko_expect import SSHClientInteraction
try:
- from contextlib import ExitStack, contextmanager
+ from contextlib import ExitStack
except ImportError:
- from contextlib2 import ExitStack, contextmanager
+ from contextlib2 import ExitStack
+
+prompt = ".*:~#.*"
-prompt=".*:~#.*"
@pytest.fixture(scope="module")
def interact(request):
-
# Create a new SSH client object
client = paramiko.SSHClient()
# Set SSH key parameters to auto accept unknown hosts
@@ -30,11 +30,11 @@
client.connect(hostname="localhost", username="root", port=2222,
key_filename='./test/id_rsa')
# Create a client interaction class which will interact with the host
interact = SSHClientInteraction(client, timeout=10, display=True)
-
+
def fin():
interact.send('exit')
interact.expect()
-
+
interact.close()
request.addfinalizer(fin)
@@ -42,23 +42,24 @@
def test_01_install_python(interact):
-
interact.send('apk update')
interact.expect(prompt, timeout=120)
- interact.send('apk add python')
+ interact.send('apk add python3')
interact.expect(prompt, timeout=120)
interact.send('apk add curl')
interact.expect(prompt, timeout=120)
+
def test_02_test_other_commnads(interact):
interact.send('ls -l /')
interact.expect(prompt, timeout=5)
+
def test_03_test_demo_helper(interact):
interact.expect(prompt)
- interact.send('python /examples/paramiko_expect-demo-helper.py')
+ interact.send('python3 /examples/paramiko_expect-demo-helper.py')
found_index = interact.expect([prompt, '.*Please enter your name:.*'])
assert interact.last_match == '.*Please enter your name:.*'
assert found_index == 1
@@ -68,38 +69,41 @@
def test_04_tail(interact):
-
interact.send('sleep 1; curl -v https://httpbin.org/stream/100')
+
def stop_callback(msg):
- return "Connection #0 to host httpbin.org left intact" in msg
+ return "Connection #0 to host httpbin.org left intact" in msg
interact.tail(stop_callback=stop_callback)
-def test_04_tail_line_prefix(interact):
+def test_04_tail_line_prefix(interact):
interact.send('sleep 1; curl -v https://httpbin.org/stream/100')
+
def stop_callback(msg):
- return "Connection #0 to host httpbin.org left intact" in msg
+ return "Connection #0 to host httpbin.org left intact" in msg
interact.tail(line_prefix="test:", stop_callback=stop_callback)
-def test_04_tail_callback(interact):
+def test_04_tail_callback(interact):
interact.send('sleep 1; curl -v https://httpbin.org/stream/100')
+
def stop_callback(msg):
- return "Connection #0 to host httpbin.org left intact" in msg
- interact.tail(line_prefix="test:", callback=lambda p, m: ""
,stop_callback=stop_callback)
+ return "Connection #0 to host httpbin.org left intact" in msg
+ interact.tail(line_prefix="test:", callback=lambda p, m: "",
stop_callback=stop_callback)
-def test_04_tail_empty_response(interact):
+def test_04_tail_empty_response(interact):
interact.send('sleep 1; curl -v https://httpbin.org/stream/100')
+
def stop_callback(msg):
- return "Connection #0 to host httpbin.org left intact" in msg
+ return "Connection #0 to host httpbin.org left intact" in msg
with mock.patch.object(interact, 'channel') as channel_mock:
- channel_mock.recv.side_effect = [ b"" ]
- interact.tail(line_prefix="test:", callback=lambda p, m: ""
,stop_callback=stop_callback)
+ channel_mock.recv.side_effect = [b""]
+ interact.tail(line_prefix="test:", callback=lambda p, m: "",
stop_callback=stop_callback)
-def test_05_context():
+def test_05_context():
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname="localhost", username="root", port=2222,
key_filename='./test/id_rsa')
@@ -107,58 +111,71 @@
interact.send('ls -all /')
interact.expect(prompt, timeout=120)
-def test_06_take_control_01(interact):
+def test_06_take_control_01(interact):
with ExitStack() as stack:
- mocks = [ mock.patch('termios.tcsetattr'),
mock.patch('termios.tcgetattr'),
- mock.patch('tty.setraw'), mock.patch('tty.setcbreak') ]
- [ stack.enter_context(m) for m in mocks ]
+ mocks = [
+ mock.patch('termios.tcsetattr'), mock.patch('termios.tcgetattr'),
+ mock.patch('tty.setraw'), mock.patch('tty.setcbreak')
+ ]
+ [stack.enter_context(m) for m in mocks]
select_mock = stack.enter_context(mock.patch('select.select'))
channel_mock = stack.enter_context(mock.patch.object(interact,
'channel'))
stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
- channel_mock.recv.side_effect = [ b"test", b"test" ]
+ channel_mock.recv.side_effect = [b"test", b"test"]
stdin_mock.read.side_effect = [b"ls -all\n", b""]
- select_mock.side_effect = [ [[stdin_mock,], [], []], [[stdin_mock,
channel_mock], [], []] ]
+ select_mock.side_effect = [
+ [[stdin_mock], [], []],
+ [[stdin_mock, channel_mock], [], []]
+ ]
interact.take_control()
def test_06_take_control_02(interact):
-
with ExitStack() as stack:
- mocks = [ mock.patch('termios.tcsetattr'),
mock.patch('termios.tcgetattr'),
- mock.patch('tty.setraw'), mock.patch('tty.setcbreak') ]
- [ stack.enter_context(m) for m in mocks ]
+ mocks = [
+ mock.patch('termios.tcsetattr'), mock.patch('termios.tcgetattr'),
+ mock.patch('tty.setraw'), mock.patch('tty.setcbreak')
+ ]
+ [stack.enter_context(m) for m in mocks]
select_mock = stack.enter_context(mock.patch('select.select'))
channel_mock = stack.enter_context(mock.patch.object(interact,
'channel'))
stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
- channel_mock.recv.side_effect = [ socket.timeout() ]
+ channel_mock.recv.side_effect = [socket.timeout()]
stdin_mock.read.side_effect = [b"ls -all\n", b""]
- select_mock.side_effect = [ [[stdin_mock,], [], []], [[stdin_mock,
channel_mock], [], []] ]
+ select_mock.side_effect = [
+ [[stdin_mock], [], []],
+ [[stdin_mock, channel_mock], [], []]
+ ]
interact.take_control()
def test_06_take_control_03(interact):
-
with ExitStack() as stack:
- mocks = [ mock.patch('termios.tcsetattr'),
mock.patch('termios.tcgetattr'),
- mock.patch('tty.setraw'), mock.patch('tty.setcbreak') ]
- [ stack.enter_context(m) for m in mocks ]
+ mocks = [
+ mock.patch('termios.tcsetattr'), mock.patch('termios.tcgetattr'),
+ mock.patch('tty.setraw'), mock.patch('tty.setcbreak')
+ ]
+ [stack.enter_context(m) for m in mocks]
select_mock = stack.enter_context(mock.patch('select.select'))
channel_mock = stack.enter_context(mock.patch.object(interact,
'channel'))
stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
- channel_mock.recv.side_effect = [ "" ]
+ channel_mock.recv.side_effect = [""]
stdin_mock.read.side_effect = [b"ls -all\n", b""]
- select_mock.side_effect = [ [[stdin_mock,], [], []], [[stdin_mock,
channel_mock], [], []] ]
+ select_mock.side_effect = [
+ [[stdin_mock], [], []],
+ [[stdin_mock, channel_mock], [], []]
+ ]
interact.take_control()
-def test_06_take_control_no_termios_01(interact):
+def test_06_take_control_no_termios_01(interact):
paramiko_expect.has_termios = False
import threading
paramiko_expect.threading = threading
@@ -167,7 +184,7 @@
channel_mock = stack.enter_context(mock.patch.object(interact,
'channel'))
stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
- channel_mock.recv.side_effect = [ b"test" ]
+ channel_mock.recv.side_effect = [b"test"]
stdin_mock.read.side_effect = [b"ls -all\n", b""]
interact.take_control()
@@ -182,12 +199,12 @@
channel_mock = stack.enter_context(mock.patch.object(interact,
'channel'))
stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
- channel_mock.recv.side_effect = [ b"" ]
+ channel_mock.recv.side_effect = [b""]
stdin_mock.read.side_effect = [b"ls -all\n", b""]
interact.take_control()
-def test_06_take_control_no_termios_03(interact):
+def test_06_take_control_no_termios_03(interact):
paramiko_expect.has_termios = False
import threading
paramiko_expect.threading = threading
@@ -196,14 +213,33 @@
channel_mock = stack.enter_context(mock.patch.object(interact,
'channel'))
stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
- channel_mock().recv.side_effect = [ b"test", b"test"]
+ channel_mock().recv.side_effect = [b"test", b"test"]
stdin_mock.read.side_effect = [b"ls -all\n", EOFError()]
interact.take_control()
def test_07_close(interact):
-
with mock.patch.object(interact, 'channel') as channel_mock:
- channel_mock.close.side_effect = [ socket.timeout ]
+ channel_mock.close.side_effect = [socket.timeout]
interact.close()
+
+def test_08_issue_25_skip_newline():
+ client = paramiko.SSHClient()
+ client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+ client.connect(hostname="localhost", username="root", port=2222,
key_filename='./test/id_rsa')
+ with SSHClientInteraction(client, timeout=10, display=True) as interact:
+ interact.send('ls -all')
+ interact.expect(prompt, timeout=5)
+
+ # Do not actually sleep, send a ctrl-c at the end
+ interact.send('sleep 1', newline=chr(3))
+ interact.expect(prompt, timeout=5)
+ interact.send('sleep 1' + chr(3), newline='')
+ interact.expect(prompt, timeout=5)
+
+ interact.send('ls -all')
+ interact.expect(prompt, timeout=5)
+
+def test_09_utf8(interact):
+ interact.send(u'Andr??')