Robot Framework Integrated Development Environment (RIDE)
Telnet.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from contextlib import contextmanager
17 import inspect
18 import re
19 import socket
20 import struct
21 import telnetlib
22 import time
23 
24 try:
25  import pyte
26 except ImportError:
27  pyte = None
28 
29 from robotide.lib.robot.api import logger
30 from robotide.lib.robot.api.deco import keyword
31 from robotide.lib.robot.utils import (ConnectionCache, is_bytes, is_string, is_truthy,
32  is_unicode, secs_to_timestr, seq2str, timestr_to_secs)
33 from robotide.lib.robot.version import get_version
34 
35 
36 
288 class Telnet():
289  ROBOT_LIBRARY_SCOPE = 'TEST_SUITE'
290  ROBOT_LIBRARY_VERSION = get_version()
291 
292 
315  def __init__(self, timeout='3 seconds', newline='CRLF',
316  prompt=None, prompt_is_regexp=False,
317  encoding='UTF-8', encoding_errors='ignore',
318  default_log_level='INFO', window_size=None,
319  environ_user=None, terminal_emulation=False,
320  terminal_type=None, telnetlib_log_level='TRACE',
321  connection_timeout=None):
322  self._timeout_timeout = timeout or 3.0
323  self._set_connection_timeout_set_connection_timeout(connection_timeout)
324  self._newline_newline = newline or 'CRLF'
325  self._prompt_prompt = (prompt, prompt_is_regexp)
326  self._encoding_encoding = encoding
327  self._encoding_errors_encoding_errors = encoding_errors
328  self._default_log_level_default_log_level = default_log_level
329  self._window_size_window_size = window_size
330  self._environ_user_environ_user = environ_user
331  self._terminal_emulation_terminal_emulation = terminal_emulation
332  self._terminal_type_terminal_type = terminal_type
333  self._telnetlib_log_level_telnetlib_log_level = telnetlib_log_level
334  self._cache_cache = ConnectionCache()
335  self._conn_conn = None
336  self._conn_kws_conn_kws = self._lib_kws_lib_kws = None
337 
338  def get_keyword_names(self):
339  return self._get_library_keywords_get_library_keywords() + self._get_connection_keywords_get_connection_keywords()
340 
342  if self._lib_kws_lib_kws is None:
343  self._lib_kws_lib_kws = self._get_keywords_get_keywords(self, ['get_keyword_names'])
344  return self._lib_kws_lib_kws
345 
346  def _get_keywords(self, source, excluded):
347  return [name for name in dir(source)
348  if self._is_keyword_is_keyword(name, source, excluded)]
349 
350  def _is_keyword(self, name, source, excluded):
351  return (name not in excluded and
352  not name.startswith('_') and
353  name != 'get_keyword_names' and
354  inspect.ismethod(getattr(source, name)))
355 
357  if self._conn_kws_conn_kws is None:
358  conn = self._get_connection_get_connection()
359  excluded = [name for name in dir(telnetlib.Telnet())
360  if name not in ['write', 'read', 'read_until']]
361  self._conn_kws_conn_kws = self._get_keywords_get_keywords(conn, excluded)
362  return self._conn_kws_conn_kws
363 
364  def __getattr__(self, name):
365  if name not in self._get_connection_keywords_get_connection_keywords():
366  raise AttributeError(name)
367  # If no connection is initialized, get attributes from a non-active
368  # connection. This makes it possible for Robot to create keyword
369  # handlers when it imports the library.
370  return getattr(self._conn_conn or self._get_connection_get_connection(), name)
371 
372  @keyword(types=None)
373 
389  def open_connection(self, host, alias=None, port=23, timeout=None,
390  newline=None, prompt=None, prompt_is_regexp=False,
391  encoding=None, encoding_errors=None,
392  default_log_level=None, window_size=None,
393  environ_user=None, terminal_emulation=None,
394  terminal_type=None, telnetlib_log_level=None,
395  connection_timeout=None):
396  timeout = timeout or self._timeout_timeout
397  connection_timeout = (timestr_to_secs(connection_timeout)
398  if connection_timeout
399  else self._connection_timeout_connection_timeout)
400  newline = newline or self._newline_newline
401  encoding = encoding or self._encoding_encoding
402  encoding_errors = encoding_errors or self._encoding_errors_encoding_errors
403  default_log_level = default_log_level or self._default_log_level_default_log_level
404  window_size = self._parse_window_size_parse_window_size(window_size or self._window_size_window_size)
405  environ_user = environ_user or self._environ_user_environ_user
406  if terminal_emulation is None:
407  terminal_emulation = self._terminal_emulation_terminal_emulation
408  terminal_type = terminal_type or self._terminal_type_terminal_type
409  telnetlib_log_level = telnetlib_log_level or self._telnetlib_log_level_telnetlib_log_level
410  if not prompt:
411  prompt, prompt_is_regexp = self._prompt_prompt
412  logger.info('Opening connection to %s:%s with prompt: %s%s'
413  % (host, port, prompt, ' (regexp)' if prompt_is_regexp else ''))
414  self._conn_conn = self._get_connection_get_connection(host, port, timeout, newline,
415  prompt, is_truthy(prompt_is_regexp),
416  encoding, encoding_errors,
417  default_log_level,
418  window_size,
419  environ_user,
420  is_truthy(terminal_emulation),
421  terminal_type,
422  telnetlib_log_level,
423  connection_timeout)
424  return self._cache_cache.register(self._conn_conn, alias)
425 
426  def _parse_window_size(self, window_size):
427  if not window_size:
428  return None
429  try:
430  cols, rows = window_size.split('x', 1)
431  return int(cols), int(rows)
432  except ValueError:
433  raise ValueError("Invalid window size '%s'. Should be "
434  "<rows>x<columns>." % window_size)
435 
436 
439  def _get_connection(self, *args):
440  return TelnetConnection(*args)
441 
442  def _set_connection_timeout(self, connection_timeout):
443  self._connection_timeout_connection_timeout = connection_timeout
444  if self._connection_timeout_connection_timeout:
445  self._connection_timeout_connection_timeout = timestr_to_secs(connection_timeout)
446 
447 
478  def switch_connection(self, index_or_alias):
479  old_index = self._cache_cache.current_index
480  self._conn_conn = self._cache_cache.switch(index_or_alias)
481  return old_index
482 
483 
494  self._conn_conn = self._cache_cache.close_all()
495 
496 
497 class TelnetConnection(telnetlib.Telnet):
498  NEW_ENVIRON_IS = b'\x00'
499  NEW_ENVIRON_VAR = b'\x00'
500  NEW_ENVIRON_VALUE = b'\x01'
501  INTERNAL_UPDATE_FREQUENCY = 0.03
502 
503  def __init__(self, host=None, port=23, timeout=3.0, newline='CRLF',
504  prompt=None, prompt_is_regexp=False,
505  encoding='UTF-8', encoding_errors='ignore',
506  default_log_level='INFO', window_size=None, environ_user=None,
507  terminal_emulation=False, terminal_type=None,
508  telnetlib_log_level='TRACE', connection_timeout=None):
509  if connection_timeout is None:
510  telnetlib.Telnet.__init__(self, host, int(port) if port else 23)
511  else:
512  telnetlib.Telnet.__init__(self, host, int(port) if port else 23,
513  connection_timeout)
514  self._set_timeout_set_timeout(timeout)
515  self._set_newline_set_newline(newline)
516  self._set_prompt_set_prompt(prompt, prompt_is_regexp)
517  self._set_encoding_set_encoding(encoding, encoding_errors)
518  self._set_default_log_level_set_default_log_level(default_log_level)
519  self._window_size_window_size = window_size
520  self._environ_user_environ_user = self._encode_encode(environ_user) if environ_user else None
521  self._terminal_emulator_terminal_emulator = self._check_terminal_emulation_check_terminal_emulation(terminal_emulation)
522  self._terminal_type_terminal_type = self._encode_encode(terminal_type) if terminal_type else None
523  self.set_option_negotiation_callback(self._negotiate_options_negotiate_options)
524  self._set_telnetlib_log_level_set_telnetlib_log_level(telnetlib_log_level)
525  self._opt_responses_opt_responses = list()
526 
527 
544  def set_timeout(self, timeout):
545  self._verify_connection_verify_connection()
546  old = self._timeout_timeout
547  self._set_timeout_set_timeout(timeout)
548  return secs_to_timestr(old)
549 
550  def _set_timeout(self, timeout):
551  self._timeout_timeout = timestr_to_secs(timeout)
552 
553 
564  def set_newline(self, newline):
565  self._verify_connection_verify_connection()
566  if self._terminal_emulator_terminal_emulator:
567  raise AssertionError("Newline can not be changed when terminal emulation is used.")
568  old = self._newline_newline
569  self._set_newline_set_newline(newline)
570  return old
571 
572  def _set_newline(self, newline):
573  newline = str(newline).upper()
574  self._newline_newline = newline.replace('LF', '\n').replace('CR', '\r')
575 
576 
597  def set_prompt(self, prompt, prompt_is_regexp=False):
598  self._verify_connection_verify_connection()
599  old = self._prompt_prompt
600  self._set_prompt_set_prompt(prompt, prompt_is_regexp)
601  if old[1]:
602  return old[0].pattern, True
603  return old
604 
605  def _set_prompt(self, prompt, prompt_is_regexp):
606  if is_truthy(prompt_is_regexp):
607  self._prompt_prompt = (re.compile(prompt), True)
608  else:
609  self._prompt_prompt = (prompt, False)
610 
611  def _prompt_is_set(self):
612  return self._prompt_prompt[0] is not None
613 
614  @keyword(types=None)
615 
633  def set_encoding(self, encoding=None, errors=None):
634  self._verify_connection_verify_connection()
635  if self._terminal_emulator_terminal_emulator:
636  raise AssertionError("Encoding can not be changed when terminal emulation is used.")
637  old = self._encoding_encoding
638  self._set_encoding_set_encoding(encoding or old[0], errors or old[1])
639  return old
640 
641  def _set_encoding(self, encoding, errors):
642  self._encoding_encoding = (encoding.upper(), errors)
643 
644  def _encode(self, text):
645  if is_bytes(text):
646  return text
647  if self._encoding_encoding[0] == 'NONE':
648  return text.encode('ASCII')
649  return text.encode(*self._encoding_encoding)
650 
651  def _decode(self, bytes):
652  if self._encoding_encoding[0] == 'NONE':
653  return bytes
654  return bytes.decode(*self._encoding_encoding)
655 
656 
661  def set_telnetlib_log_level(self, level):
662  self._verify_connection_verify_connection()
663  old = self._telnetlib_log_level_telnetlib_log_level
664  self._set_telnetlib_log_level_set_telnetlib_log_level(level)
665  return old
666 
667  def _set_telnetlib_log_level(self, level):
668  if level.upper() == 'NONE':
669  self._telnetlib_log_level_telnetlib_log_level = 'NONE'
670  elif self._is_valid_log_level_is_valid_log_level(level) is False:
671  raise AssertionError("Invalid log level '%s'" % level)
672  self._telnetlib_log_level_telnetlib_log_level = level.upper()
673 
674 
682  def set_default_log_level(self, level):
683  self._verify_connection_verify_connection()
684  old = self._default_log_level_default_log_level
685  self._set_default_log_level_set_default_log_level(level)
686  return old
687 
688  def _set_default_log_level(self, level):
689  if level is None or not self._is_valid_log_level_is_valid_log_level(level):
690  raise AssertionError("Invalid log level '%s'" % level)
691  self._default_log_level_default_log_level = level.upper()
692 
693  def _is_valid_log_level(self, level):
694  if level is None:
695  return True
696  if not is_string(level):
697  return False
698  return level.upper() in ('TRACE', 'DEBUG', 'INFO', 'WARN')
699 
700 
710  def close_connection(self, loglevel=None):
711  if self.sock:
712  self.sock.shutdown(socket.SHUT_RDWR)
713  self.close()
714  output = self._decode_decode(self.read_all())
715  self._log_log(output, loglevel)
716  return output
717 
718 
742  def login(self, username, password, login_prompt='login: ',
743  password_prompt='Password: ', login_timeout='1 second',
744  login_incorrect='Login incorrect'):
745  output = self._submit_credentials_submit_credentials(username, password, login_prompt,
746  password_prompt)
747  if self._prompt_is_set_prompt_is_set():
748  success, output2 = self._read_until_prompt_read_until_prompt()
749  else:
750  success, output2 = self._verify_login_without_prompt_verify_login_without_prompt(
751  login_timeout, login_incorrect)
752  output += output2
753  self._log_log(output)
754  if not success:
755  raise AssertionError('Login incorrect')
756  return output
757 
758  def _submit_credentials(self, username, password, login_prompt, password_prompt):
759  # Using write_bare here instead of write because don't want to wait for
760  # newline: https://github.com/robotframework/robotframework/issues/1371
761  output = self.read_untilread_until(login_prompt, 'TRACE')
762  self.write_barewrite_bare(username + self._newline_newline)
763  output += self.read_untilread_until(password_prompt, 'TRACE')
764  self.write_barewrite_bare(password + self._newline_newline)
765  return output
766 
767  def _verify_login_without_prompt(self, delay, incorrect):
768  time.sleep(timestr_to_secs(delay))
769  output = self.readread('TRACE')
770  success = incorrect not in output
771  return success, output
772 
773 
789  def write(self, text, loglevel=None):
790  newline = self._get_newline_for_get_newline_for(text)
791  if newline in text:
792  raise RuntimeError("'Write' keyword cannot be used with strings "
793  "containing newlines. Use 'Write Bare' instead.")
794  self.write_barewrite_bare(text + newline)
795  # Can't read until 'text' because long lines are cut strangely in the output
796  return self.read_untilread_until(self._newline_newline, loglevel)
797 
798  def _get_newline_for(self, text):
799  if is_bytes(text):
800  return self._encode_encode(self._newline_newline)
801  return self._newline_newline
802 
803 
808  def write_bare(self, text):
809  self._verify_connection_verify_connection()
810  telnetlib.Telnet.write(self, self._encode_encode(text))
811 
812 
834  def write_until_expected_output(self, text, expected, timeout,
835  retry_interval, loglevel=None):
836  timeout = timestr_to_secs(timeout)
837  retry_interval = timestr_to_secs(retry_interval)
838  maxtime = time.time() + timeout
839  while time.time() < maxtime:
840  self.write_barewrite_bare(text)
841  self.read_untilread_until(text, loglevel)
842  try:
843  with self._custom_timeout_custom_timeout(retry_interval):
844  return self.read_untilread_until(expected, loglevel)
845  except AssertionError:
846  pass
847  raise NoMatchError(expected, timeout)
848 
849 
862  def write_control_character(self, character):
863  self._verify_connection_verify_connection()
864  self.sock.sendall(telnetlib.IAC + self._get_control_character_get_control_character(character))
865 
866  def _get_control_character(self, int_or_name):
867  try:
868  ordinal = int(int_or_name)
869  return bytes(bytearray([ordinal]))
870  except ValueError:
871  return self._convert_control_code_name_to_character_convert_control_code_name_to_character(int_or_name)
872 
874  code_names = {
875  'BRK' : telnetlib.BRK,
876  'IP' : telnetlib.IP,
877  'AO' : telnetlib.AO,
878  'AYT' : telnetlib.AYT,
879  'EC' : telnetlib.EC,
880  'EL' : telnetlib.EL,
881  'NOP' : telnetlib.NOP
882  }
883  try:
884  return code_names[name]
885  except KeyError:
886  raise RuntimeError("Unsupported control character '%s'." % name)
887 
888 
893  def read(self, loglevel=None):
894  self._verify_connection_verify_connection()
895  output = self._decode_decode(self.read_very_eager())
896  if self._terminal_emulator_terminal_emulator:
897  self._terminal_emulator_terminal_emulator.feed(output)
898  output = self._terminal_emulator_terminal_emulator.read()
899  self._log_log(output, loglevel)
900  return output
901 
902 
911  def read_until(self, expected, loglevel=None):
912  success, output = self._read_until_read_until(expected)
913  self._log_log(output, loglevel)
914  if not success:
915  raise NoMatchError(expected, self._timeout_timeout, output)
916  return output
917 
918  def _read_until(self, expected):
919  self._verify_connection_verify_connection()
920  if self._terminal_emulator_terminal_emulator:
921  return self._terminal_read_until_terminal_read_until(expected)
922  expected = self._encode_encode(expected)
923  output = telnetlib.Telnet.read_until(self, expected, self._timeout_timeout)
924  return output.endswith(expected), self._decode_decode(output)
925 
926  @property
927  _terminal_frequency = property
928 
930  return min(self.INTERNAL_UPDATE_FREQUENCYINTERNAL_UPDATE_FREQUENCY, self._timeout_timeout)
931 
932  def _terminal_read_until(self, expected):
933  max_time = time.time() + self._timeout_timeout
934  output = self._terminal_emulator_terminal_emulator.read_until(expected)
935  if output:
936  return True, output
937  while time.time() < max_time:
938  output = telnetlib.Telnet.read_until(self, self._encode_encode(expected),
939  self._terminal_frequency_terminal_frequency_terminal_frequency)
940  self._terminal_emulator_terminal_emulator.feed(self._decode_decode(output))
941  output = self._terminal_emulator_terminal_emulator.read_until(expected)
942  if output:
943  return True, output
944  return False, self._terminal_emulator_terminal_emulator.read()
945 
946  def _read_until_regexp(self, *expected):
947  self._verify_connection_verify_connection()
948  if self._terminal_emulator_terminal_emulator:
949  return self._terminal_read_until_regexp_terminal_read_until_regexp(expected)
950  expected = [self._encode_encode(exp) if is_unicode(exp) else exp
951  for exp in expected]
952  return self._telnet_read_until_regexp_telnet_read_until_regexp(expected)
953 
954  def _terminal_read_until_regexp(self, expected_list):
955  max_time = time.time() + self._timeout_timeout
956  regexps_bytes = [self._to_byte_regexp_to_byte_regexp(rgx) for rgx in expected_list]
957  regexps_unicode = [re.compile(self._decode_decode(rgx.pattern))
958  for rgx in regexps_bytes]
959  out = self._terminal_emulator_terminal_emulator.read_until_regexp(regexps_unicode)
960  if out:
961  return True, out
962  while time.time() < max_time:
963  output = self.expect(regexps_bytes, self._terminal_frequency_terminal_frequency_terminal_frequency)[-1]
964  self._terminal_emulator_terminal_emulator.feed(self._decode_decode(output))
965  out = self._terminal_emulator_terminal_emulator.read_until_regexp(regexps_unicode)
966  if out:
967  return True, out
968  return False, self._terminal_emulator_terminal_emulator.read()
969 
970  def _telnet_read_until_regexp(self, expected_list):
971  expected = [self._to_byte_regexp_to_byte_regexp(exp) for exp in expected_list]
972  try:
973  index, _, output = self.expect(expected, self._timeout_timeout)
974  except TypeError:
975  index, output = -1, b''
976  return index != -1, self._decode_decode(output)
977 
978  def _to_byte_regexp(self, exp):
979  if is_bytes(exp):
980  return re.compile(exp)
981  if is_string(exp):
982  return re.compile(self._encode_encode(exp))
983  pattern = exp.pattern
984  if is_bytes(pattern):
985  return exp
986  return re.compile(self._encode_encode(pattern))
987 
988 
1010  def read_until_regexp(self, *expected):
1011  if not expected:
1012  raise RuntimeError('At least one pattern required')
1013  if self._is_valid_log_level_is_valid_log_level(expected[-1]):
1014  loglevel = expected[-1]
1015  expected = expected[:-1]
1016  else:
1017  loglevel = None
1018  success, output = self._read_until_regexp_read_until_regexp(*expected)
1019  self._log_log(output, loglevel)
1020  if not success:
1021  expected = [exp if is_string(exp) else exp.pattern
1022  for exp in expected]
1023  raise NoMatchError(expected, self._timeout_timeout, output)
1024  return output
1025 
1026 
1043  def read_until_prompt(self, loglevel=None, strip_prompt=False):
1044  if not self._prompt_is_set_prompt_is_set():
1045  raise RuntimeError('Prompt is not set.')
1046  success, output = self._read_until_prompt_read_until_prompt()
1047  self._log_log(output, loglevel)
1048  if not success:
1049  prompt, regexp = self._prompt_prompt
1050  raise AssertionError("Prompt '%s' not found in %s."
1051  % (prompt if not regexp else prompt.pattern,
1052  secs_to_timestr(self._timeout_timeout)))
1053  if is_truthy(strip_prompt):
1054  output = self._strip_prompt_strip_prompt(output)
1055  return output
1056 
1058  prompt, regexp = self._prompt_prompt
1059  read_until = self._read_until_regexp_read_until_regexp if regexp else self._read_until_read_until
1060  return read_until(prompt)
1061 
1062  def _strip_prompt(self, output):
1063  prompt, regexp = self._prompt_prompt
1064  if not regexp:
1065  length = len(prompt)
1066  else:
1067  match = prompt.search(output)
1068  length = match.end() - match.start()
1069  return output[:-length]
1070 
1071 
1087  def execute_command(self, command, loglevel=None, strip_prompt=False):
1088  self.writewrite(command, loglevel)
1089  return self.read_until_promptread_until_prompt(loglevel, strip_prompt)
1090 
1091  @contextmanager
1092  def _custom_timeout(self, timeout):
1093  old = self.set_timeoutset_timeout(timeout)
1094  try:
1095  yield
1096  finally:
1097  self.set_timeoutset_timeout(old)
1098 
1100  if not self.sock:
1101  raise RuntimeError('No connection open')
1102 
1103  def _log(self, msg, level=None):
1104  msg = msg.strip()
1105  if msg:
1106  logger.write(msg, level or self._default_log_level_default_log_level)
1107 
1108  def _negotiate_options(self, sock, cmd, opt):
1109  # We don't have state changes in our accepted telnet options.
1110  # Therefore, we just track if we've already responded to an option. If
1111  # this is the case, we must not send any response.
1112  if cmd in (telnetlib.DO, telnetlib.DONT, telnetlib.WILL, telnetlib.WONT):
1113  if (cmd, opt) in self._opt_responses_opt_responses:
1114  return
1115  else:
1116  self._opt_responses_opt_responses.append((cmd, opt))
1117 
1118  # This is supposed to turn server side echoing on and turn other options off.
1119  if opt == telnetlib.ECHO and cmd in (telnetlib.WILL, telnetlib.WONT):
1120  self._opt_echo_on_opt_echo_on(opt)
1121  elif cmd == telnetlib.DO and opt == telnetlib.TTYPE and self._terminal_type_terminal_type:
1122  self._opt_terminal_type_opt_terminal_type(opt, self._terminal_type_terminal_type)
1123  elif cmd == telnetlib.DO and opt == telnetlib.NEW_ENVIRON and self._environ_user_environ_user:
1124  self._opt_environ_user_opt_environ_user(opt, self._environ_user_environ_user)
1125  elif cmd == telnetlib.DO and opt == telnetlib.NAWS and self._window_size_window_size:
1126  self._opt_window_size_opt_window_size(opt, *self._window_size_window_size)
1127  elif opt != telnetlib.NOOPT:
1128  self._opt_dont_and_wont_opt_dont_and_wont(cmd, opt)
1129 
1130  def _opt_echo_on(self, opt):
1131  return self.sock.sendall(telnetlib.IAC + telnetlib.DO + opt)
1132 
1133  def _opt_terminal_type(self, opt, terminal_type):
1134  self.sock.sendall(telnetlib.IAC + telnetlib.WILL + opt)
1135  self.sock.sendall(telnetlib.IAC + telnetlib.SB + telnetlib.TTYPE
1136  + self.NEW_ENVIRON_ISNEW_ENVIRON_IS + terminal_type
1137  + telnetlib.IAC + telnetlib.SE)
1138 
1139  def _opt_environ_user(self, opt, environ_user):
1140  self.sock.sendall(telnetlib.IAC + telnetlib.WILL + opt)
1141  self.sock.sendall(telnetlib.IAC + telnetlib.SB + telnetlib.NEW_ENVIRON
1142  + self.NEW_ENVIRON_ISNEW_ENVIRON_IS + self.NEW_ENVIRON_VARNEW_ENVIRON_VAR
1143  + b"USER" + self.NEW_ENVIRON_VALUENEW_ENVIRON_VALUE + environ_user
1144  + telnetlib.IAC + telnetlib.SE)
1145 
1146  def _opt_window_size(self, opt, window_x, window_y):
1147  self.sock.sendall(telnetlib.IAC + telnetlib.WILL + opt)
1148  self.sock.sendall(telnetlib.IAC + telnetlib.SB + telnetlib.NAWS
1149  + struct.pack('!HH', window_x, window_y)
1150  + telnetlib.IAC + telnetlib.SE)
1151 
1152  def _opt_dont_and_wont(self, cmd, opt):
1153  if cmd in (telnetlib.DO, telnetlib.DONT):
1154  self.sock.sendall(telnetlib.IAC + telnetlib.WONT + opt)
1155  elif cmd in (telnetlib.WILL, telnetlib.WONT):
1156  self.sock.sendall(telnetlib.IAC + telnetlib.DONT + opt)
1157 
1158  def msg(self, msg, *args):
1159  # Forward telnetlib's debug messages to log
1160  if self._telnetlib_log_level_telnetlib_log_level != 'NONE':
1161  logger.write(msg % args, self._telnetlib_log_level_telnetlib_log_level)
1162 
1163  def _check_terminal_emulation(self, terminal_emulation):
1164  if not terminal_emulation:
1165  return False
1166  if not pyte:
1167  raise RuntimeError("Terminal emulation requires pyte module!\n"
1168  "http://pypi.python.org/pypi/pyte/")
1169  return TerminalEmulator(window_size=self._window_size_window_size,
1170  newline=self._newline_newline)
1171 
1172 
1174 
1175  def __init__(self, window_size=None, newline="\r\n"):
1176  self._rows, self._columns_columns = window_size or (200, 200)
1177  self._newline_newline = newline
1178  self._stream_stream = pyte.Stream()
1179  self._screen_screen = pyte.HistoryScreen(self._rows,
1180  self._columns_columns,
1181  history=100000)
1182  self._stream_stream.attach(self._screen_screen)
1183  self._buffer_buffer = ''
1184  self._whitespace_after_last_feed_whitespace_after_last_feed = ''
1185 
1186  @property
1187  current_output = property
1188 
1189  def current_output(self):
1190  return self._buffer_buffer + self._dump_screen_dump_screen()
1191 
1192  def _dump_screen(self):
1193  return self._get_history_get_history(self._screen_screen) + \
1194  self._get_screen_get_screen(self._screen_screen) + \
1195  self._whitespace_after_last_feed_whitespace_after_last_feed
1196 
1197  def _get_history(self, screen):
1198  if not screen.history.top:
1199  return ''
1200  rows = []
1201  for row in screen.history.top:
1202  # Newer pyte versions store row data in mappings
1203  data = (char.data for _, char in sorted(row.items()))
1204  rows.append(''.join(data).rstrip())
1205  return self._newline_newline.join(rows).rstrip(self._newline_newline) + self._newline_newline
1206 
1207  def _get_screen(self, screen):
1208  rows = (row.rstrip() for row in screen.display)
1209  return self._newline_newline.join(rows).rstrip(self._newline_newline)
1210 
1211  def feed(self, text):
1212  self._stream_stream.feed(text)
1213  self._whitespace_after_last_feed_whitespace_after_last_feed = text[len(text.rstrip()):]
1214 
1215  def read(self):
1216  current_out = self.current_outputcurrent_outputcurrent_output
1217  self._update_buffer_update_buffer('')
1218  return current_out
1219 
1220  def read_until(self, expected):
1221  current_out = self.current_outputcurrent_outputcurrent_output
1222  exp_index = current_out.find(expected)
1223  if exp_index != -1:
1224  self._update_buffer_update_buffer(current_out[exp_index+len(expected):])
1225  return current_out[:exp_index+len(expected)]
1226  return None
1227 
1228  def read_until_regexp(self, regexp_list):
1229  current_out = self.current_outputcurrent_outputcurrent_output
1230  for rgx in regexp_list:
1231  match = rgx.search(current_out)
1232  if match:
1233  self._update_buffer_update_buffer(current_out[match.end():])
1234  return current_out[:match.end()]
1235  return None
1236 
1237  def _update_buffer(self, terminal_buffer):
1238  self._buffer_buffer = terminal_buffer
1239  self._whitespace_after_last_feed_whitespace_after_last_feed = ''
1240  self._screen_screen.reset()
1241 
1242 
1244  ROBOT_SUPPRESS_NAME = True
1245 
1246  def __init__(self, expected, timeout, output=None):
1247  self.expectedexpected = expected
1248  self.timeouttimeout = secs_to_timestr(timeout)
1249  self.outputoutput = output
1250  AssertionError.__init__(self, self._get_message_get_message())
1251 
1252  def _get_message(self):
1253  expected = "'%s'" % self.expectedexpected \
1254  if is_string(self.expectedexpected) \
1255  else seq2str(self.expectedexpected, lastsep=' or ')
1256  msg = "No match found for %s in %s." % (expected, self.timeouttimeout)
1257  if self.outputoutput is not None:
1258  msg += ' Output:\n%s' % self.outputoutput
1259  return msg
def __init__(self, expected, timeout, output=None)
Definition: Telnet.py:1246
def _opt_window_size(self, opt, window_x, window_y)
Definition: Telnet.py:1146
def _submit_credentials(self, username, password, login_prompt, password_prompt)
Definition: Telnet.py:758
def execute_command(self, command, loglevel=None, strip_prompt=False)
Executes the given command and reads, logs, and returns everything until the prompt.
Definition: Telnet.py:1087
def read_until(self, expected, loglevel=None)
Reads output until expected text is encountered.
Definition: Telnet.py:911
def _opt_environ_user(self, opt, environ_user)
Definition: Telnet.py:1139
def set_telnetlib_log_level(self, level)
Sets the log level used for logging in the underlying telnetlib.
Definition: Telnet.py:661
def set_encoding(self, encoding=None, errors=None)
Sets the encoding to use for writing and reading in the current connection.
Definition: Telnet.py:633
def _set_encoding(self, encoding, errors)
Definition: Telnet.py:641
def read_until_regexp(self, *expected)
Reads output until any of the expected regular expressions match.
Definition: Telnet.py:1010
def set_timeout(self, timeout)
Sets the timeout used for waiting output in the current connection.
Definition: Telnet.py:544
def set_prompt(self, prompt, prompt_is_regexp=False)
Sets the prompt used by Read Until Prompt and Login in the current connection.
Definition: Telnet.py:597
def set_newline(self, newline)
Sets the newline used by Write keyword in the current connection.
Definition: Telnet.py:564
def _set_prompt(self, prompt, prompt_is_regexp)
Definition: Telnet.py:605
def set_default_log_level(self, level)
Sets the default log level used for logging in the current connection.
Definition: Telnet.py:682
def read(self, loglevel=None)
Reads everything that is currently available in the output.
Definition: Telnet.py:893
def _check_terminal_emulation(self, terminal_emulation)
Definition: Telnet.py:1163
def _terminal_read_until_regexp(self, expected_list)
Definition: Telnet.py:954
def _opt_terminal_type(self, opt, terminal_type)
Definition: Telnet.py:1133
def __init__(self, host=None, port=23, timeout=3.0, newline='CRLF', prompt=None, prompt_is_regexp=False, encoding='UTF-8', encoding_errors='ignore', default_log_level='INFO', window_size=None, environ_user=None, terminal_emulation=False, terminal_type=None, telnetlib_log_level='TRACE', connection_timeout=None)
Definition: Telnet.py:508
def login(self, username, password, login_prompt='login:', password_prompt='Password:', login_timeout='1 second', login_incorrect='Login incorrect')
Logs in to the Telnet server with the given user information.
Definition: Telnet.py:744
def write(self, text, loglevel=None)
Writes the given text plus a newline into the connection.
Definition: Telnet.py:789
def _telnet_read_until_regexp(self, expected_list)
Definition: Telnet.py:970
def write_until_expected_output(self, text, expected, timeout, retry_interval, loglevel=None)
Writes the given text repeatedly, until expected appears in the output.
Definition: Telnet.py:835
def _verify_login_without_prompt(self, delay, incorrect)
Definition: Telnet.py:767
def close_connection(self, loglevel=None)
Closes the current Telnet connection.
Definition: Telnet.py:710
def read_until_prompt(self, loglevel=None, strip_prompt=False)
Reads output until the prompt is encountered.
Definition: Telnet.py:1043
def write_bare(self, text)
Writes the given text, and nothing else, into the connection.
Definition: Telnet.py:808
def write_control_character(self, character)
Writes the given control character into the connection.
Definition: Telnet.py:862
A test library providing communication over Telnet connections.
Definition: Telnet.py:288
def _parse_window_size(self, window_size)
Definition: Telnet.py:426
def __init__(self, timeout='3 seconds', newline='CRLF', prompt=None, prompt_is_regexp=False, encoding='UTF-8', encoding_errors='ignore', default_log_level='INFO', window_size=None, environ_user=None, terminal_emulation=False, terminal_type=None, telnetlib_log_level='TRACE', connection_timeout=None)
Telnet library can be imported with optional configuration parameters.
Definition: Telnet.py:321
def _get_keywords(self, source, excluded)
Definition: Telnet.py:346
def close_all_connections(self)
Closes all open connections and empties the connection cache.
Definition: Telnet.py:493
def _get_connection(self, *args)
Can be overridden to use a custom connection.
Definition: Telnet.py:439
def switch_connection(self, index_or_alias)
Switches between active connections using an index or an alias.
Definition: Telnet.py:478
def _is_keyword(self, name, source, excluded)
Definition: Telnet.py:350
def _set_connection_timeout(self, connection_timeout)
Definition: Telnet.py:442
def open_connection(self, host, alias=None, port=23, timeout=None, newline=None, prompt=None, prompt_is_regexp=False, encoding=None, encoding_errors=None, default_log_level=None, window_size=None, environ_user=None, terminal_emulation=None, terminal_type=None, telnetlib_log_level=None, connection_timeout=None)
Opens a new Telnet connection to the given host and port.
Definition: Telnet.py:395
def __init__(self, window_size=None, newline="\r\n")
Definition: Telnet.py:1175
def seq2str(sequence, quote="'", sep=', ', lastsep=' and ')
Returns sequence in format ‘'item 1’, 'item 2' and 'item 3'`.
Definition: misc.py:115
def secs_to_timestr(secs, compact=False)
Converts time in seconds to a string representation.
Definition: robottime.py:126
def timestr_to_secs(timestr, round_to=3)
Parses time like '1h 10s', '01:00:10' or '42' and returns seconds.
Definition: robottime.py:45
def is_truthy(item)
Returns True or False depending is the item considered true or not.
Definition: robottypes.py:49
def get_version(naked=False)
Definition: version.py:24