Revision: 156
Author: janne.t.harkonen
Date: Fri Aug 24 04:22:04 2012
Log: move read*** methods from Library to Client
http://code.google.com/p/robotframework-sshlibrary/source/detail?r=156
Modified:
/trunk/atest/interactive_session.txt
/trunk/src/SSHLibrary/__init__.py
/trunk/src/SSHLibrary/core.py
/trunk/src/SSHLibrary/javaclient.py
/trunk/src/SSHLibrary/pythonclient.py
=======================================
--- /trunk/atest/interactive_session.txt Fri Aug 24 04:21:51 2012
+++ /trunk/atest/interactive_session.txt Fri Aug 24 04:22:04 2012
@@ -47,7 +47,7 @@
[Teardown] Remove Counter and Read All Data
Write Until Expected Output In Case Of Time Out
- Run Keyword And Expect Error No match found for '11' in 5 seconds
Write Until Expected Output ./${REPEAT TEST SCRIPT NAME}\n 11 5s 0.5s
+ Run Keyword And Expect Error No match found for '11' in 2 seconds.
Write Until Expected Output ./${REPEAT TEST SCRIPT NAME}\n 11 2s 0.5s
[Teardown] Remove Counter and Read All Data
Write Bare And Read
=======================================
--- /trunk/src/SSHLibrary/__init__.py Fri Aug 24 04:21:30 2012
+++ /trunk/src/SSHLibrary/__init__.py Fri Aug 24 04:22:04 2012
@@ -353,7 +353,7 @@
used.
"""
self._write(text, add_newline=True)
- return self.read_until(self._config.newline, loglevel)
+ return self._read_and_log(self.ssh_client.read_until_newline,
loglevel)
def write_bare(self, text):
"""Writes given text over the connection without appending newline.
@@ -380,9 +380,7 @@
This keyword is most useful for reading everything from the output
buffer, thus clearing it.
"""
- ret = self.ssh_client.read()
- self._log(ret, loglevel)
- return ret
+ return self._read_and_log(self.ssh_client.read, loglevel)
def read_until(self, expected, loglevel=None):
"""Reads output until expected is encountered or timeout expires.
@@ -395,27 +393,13 @@
See `Read` for more information on `loglevel`.
"""
- return self._read_until(expected, loglevel)
-
- def _read_until(self, expected, loglevel):
- ret = ''
- start_time = time.time()
- while time.time() < float(self._config.timeout) + start_time:
- ret += self.ssh_client.read_char()
- if (isinstance(expected, basestring) and expected in ret) or \
- (not isinstance(expected, basestring) and
expected.search(ret)):
- self._log(ret, loglevel)
- return ret
- self._log(ret, loglevel)
- if not isinstance(expected, basestring):
- expected = expected.pattern
- raise AssertionError("No match found for '%s' in %s"
- % (expected, utils.secs_to_timestr(self._config.timeout)))
+ reader = lambda: self.ssh_client.read_until(expected)
+ return self._read_and_log(reader, loglevel)
def read_until_regexp(self, regexp, loglevel=None):
"""Reads output until a match to `regexp` is found or timeout
expires.
- `regexp` can be a pattern or a compiled re-object.
+ `regexp` can be a pattern or a compiled regexp-object.
Returns text up until and including the regexp.
@@ -429,7 +413,8 @@
"""
if isinstance(regexp, basestring):
regexp = re.compile(regexp)
- return self._read_until(regexp, loglevel)
+ reader = lambda: self.ssh_client.read_until_regexp(regexp)
+ return self._read_and_log(reader, loglevel)
def read_until_prompt(self, loglevel=None):
"""Reads and returns text from the output until prompt is found.
@@ -443,7 +428,7 @@
output of previous command has been read and the command does not
produce prompt characters in its output.
"""
- return self.read_until(self.ssh_client.config.prompt, loglevel)
+ return self._read_and_log(self.ssh_client.read_until_prompt,
loglevel)
def write_until_expected_output(self, text, expected, timeout,
retry_interval, loglevel=None):
@@ -469,19 +454,17 @@
"""
timeout = utils.timestr_to_secs(timeout)
retry_interval = utils.timestr_to_secs(retry_interval)
- old_timeout = self.set_timeout(retry_interval)
- starttime = time.time()
- while time.time() - starttime < timeout:
- self.write_bare(text)
- try:
- ret = self._read_until(expected, loglevel)
- self.set_timeout(old_timeout)
- return ret
- except AssertionError:
- pass
- self.set_timeout(old_timeout)
- raise AssertionError("No match found for '%s' in %s"
- % (expected, utils.secs_to_timestr(timeout)))
+ reader = lambda: self.ssh_client.write_until_expected(
+ text, expected, timeout, retry_interval)
+ self._read_and_log(reader, loglevel)
+
+ def _read_and_log(self, reader, loglevel):
+ try:
+ output = reader()
+ except SSHClientException, e:
+ raise RuntimeError(e)
+ self._log(output, loglevel)
+ return output
def put_file(self, source, destination='.', mode='0744',
newlines='default'):
"""Copies file(s) from local host to remote host.
@@ -643,21 +626,17 @@
self._log(msg, 'DEBUG')
def _log(self, msg, level=None):
- self._is_valid_log_level(level, raise_if_invalid=True)
+ level = self._active_log_level(level)
msg = msg.strip()
- if level is None:
- level = self._config.log_level
if msg != '':
- print '*%s* %s' % (level.upper(), msg)
+ print '*%s* %s' % (level, msg)
- def _is_valid_log_level(self, level, raise_if_invalid=False):
+ def _active_log_level(self, level):
if level is None:
- return True
+ return self._config.log_level
if isinstance(level, basestring) and \
level.upper() in
['TRACE', 'DEBUG', 'INFO', 'WARN', 'HTML']:
- return True
- if not raise_if_invalid:
- return False
+ return level.upper()
raise AssertionError("Invalid log level '%s'" % level)
=======================================
--- /trunk/src/SSHLibrary/core.py Fri Aug 24 04:21:13 2012
+++ /trunk/src/SSHLibrary/core.py Fri Aug 24 04:22:04 2012
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import time
+
from config import Configuration, StringEntry, TimeEntry, IntegerEntry
@@ -110,6 +112,89 @@
text += self.config.newline
self._write(text)
+ def read(self):
+ """Read and return currently available output."""
+ return self._read()
+
+ def read_char(self):
+ """Read and return a single character from current session."""
+ return self._read_char()
+
+ def read_until(self, expected):
+ """Read and return from the output until expected.
+
+ :param str expected: text to look for in the output
+ :raises SSHClientException: if expected is not found in output when
+ timeout expires.
+
+ timeout is defined with :py:methc:`open_connection()`
+ """
+ return self._read_until(lambda s: expected in s, expected)
+
+ def read_until_newline(self):
+ """Read and return from the output up to the first newline
character.
+
+ :raises SSHClientException: if newline is not found in output when
+ timeout expires.
+
+ timeout is defined with :py:methc:`open_connection()`
+ """
+ return self.read_until(self.config.newline)
+
+ def read_until_prompt(self):
+ """Read and return from the output until prompt.
+
+ :raises SSHClientException: if prompt is not set or it is not found
+ in output when timeout expires.
+
+ prompt and timeout are defined with :py:methc:`open_connection()`
+ """
+ self._ensure_prompt_is_set()
+ return self.read_until(self.config.prompt)
+
+ def read_until_regexp(self, regexp):
+ """Read and return from the output until regexp matches.
+
+ :param regexp: a compiled regexp obect used for matching
+ :raises SSHClientException: if match is not found in output when
+ timeout expires.
+
+ timeout is defined with :py:methc:`open_connection()`
+ """
+ return self._read_until(lambda s: regexp.search(s), regexp.pattern)
+
+ def write_until_expected(self, text, expected, timeout, interval):
+ """Write text until expected output appears or timeout expires.
+
+ :param str text: Text to be written using #write_bare().
+ :param str expected: Text to look for in the output.
+ :param int timeout: The timeout during which `expected` must appear
+ in the output, in seconds.
+ :param int interval: Time to wait between repeated writings'
+ """
+ timeout = TimeEntry(timeout)
+ starttime = time.time()
+ while time.time() - starttime < timeout.value:
+ self.write(text)
+ try:
+ return self._read_until(lambda s: expected in s,
+ expected, timeout=interval)
+ except SSHClientException:
+ pass
+ raise SSHClientException("No match found for '%s' in %s."
+ % (expected, timeout))
+
+ def _read_until(self, matcher, expected, timeout=None):
+ ret = ''
+ timeout = TimeEntry(timeout) if timeout else
self.config.get('timeout')
+ start_time = time.time()
+ while time.time() < float(timeout.value) + start_time:
+ ret += self._read_char()
+ if matcher(ret):
+ return ret
+ raise SSHClientException("No match found for '%s'
in %s\nOutput:\n%s"
+ % (expected, timeout, ret))
+
def _ensure_prompt_is_set(self):
if not self.config.prompt:
raise SSHClientException('Prompt is not set.')
=======================================
--- /trunk/src/SSHLibrary/javaclient.py Fri Aug 24 04:21:13 2012
+++ /trunk/src/SSHLibrary/javaclient.py Fri Aug 24 04:22:04 2012
@@ -71,7 +71,7 @@
self._writer.write(text)
self._writer.flush()
- def read(self):
+ def _read(self):
data = ''
if self._stdout.available():
buf = jarray.zeros(self._stdout.available(), 'b')
@@ -79,7 +79,7 @@
data += ''.join([chr(b) for b in buf])
return data
- def read_char(self):
+ def _read_char(self):
if self._stdout.available():
buf = jarray.zeros(1, 'b')
self._stdout.read(buf)
=======================================
--- /trunk/src/SSHLibrary/pythonclient.py Fri Aug 24 04:21:13 2012
+++ /trunk/src/SSHLibrary/pythonclient.py Fri Aug 24 04:22:04 2012
@@ -73,13 +73,13 @@
def _write(self, text):
self.shell.sendall(text)
- def read(self):
+ def _read(self):
data = ''
while self.shell.recv_ready():
data += self.shell.recv(100000)
return data
- def read_char(self):
+ def _read_char(self):
if self.shell.recv_ready():
return self.shell.recv(1)
return ''