annotate pexpecter.py @ 126:d0e071e19c26

1.4.7
author catherine@localhost
date Wed, 30 Jul 2008 12:41:26 -0400
parents 9c87fa772ec1
children
rev   line source
0
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
1 """
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
2 pexpecter
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
3
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
4 Uses pexpect to handle interactive sessions
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
5 Create subclass of Session for each type of program to be used
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
6 """
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
7 import re, os
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
8
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
9 try:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
10 import pexpect
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
11
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
12 class Session(object):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
13 available = True
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
14 call = 'theprogram %s'
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
15 errPattern = re.compile('.')
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
16 validPattern = re.compile('Connected to:')
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
17 promptstub = '>'
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
18 def __init__(self, argstring):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
19 self.argstring = argstring
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
20 self.sess = pexpect.spawn("%s %s" % (self.call, self.argstring))
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
21 try:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
22 self.sess.expect(self.promptstub)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
23 self.valid = self.validPattern.search(self.sess.before)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
24 self.prompt = '[\r\n]%s%s' % (self.sess.before.splitlines()[-1], self.promptstub)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
25 except:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
26 self.valid = False
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
27 def success(self, result):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
28 return not self.errPattern.search(result)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
29 def attempt(self, command, timeout=30):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
30 self.sess.sendline(self._pre_attempt(command))
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
31 try:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
32 self.sess.expect(self.prompt, timeout=timeout)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
33 except pexpect.TIMEOUT:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
34 return (False, """Errror: Waited %d seconds with no response from %s.
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
35 To wait longer, set timeout.""" % (timeout, str(self.__class__)))
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
36 result = self.sess.before
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
37 success = self.success(result)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
38 if success:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
39 print 'Executed through %s' % (str(self.__class__))
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
40 return (success, result)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
41 def _pre_attempt(self, command):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
42 return command
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
43
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
44 class YASQLSession(Session):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
45 errPattern = re.compile('\n[A-Z2]{3,4}-\d{4}:\s')
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
46 terminatorPattern = re.compile('(;|\\g|\\i|\/|\\G|\\s|\\S)\s*\d*\s*$')
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
47 call = os.popen('locate -r /yasql$').readline().strip()
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
48 if not call:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
49 print 'yasql not found; commands cannot failover to YASQL'
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
50 available = False
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
51 def _pre_attempt(self, command):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
52 if not self.terminatorPattern.search(command):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
53 return '%s;' % (command)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
54 return command
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
55
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
56 class SQLSession(Session):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
57 def _pre_attempt(self, command):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
58 if command.strip()[-1] != ';':
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
59 return '%s;' % (command)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
60 return command
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
61
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
62 class SqlPlusSession(SQLSession):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
63 call = r'sqlplus'
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
64 errPattern = re.compile('\n[A-Z2]{3,4}-\d{4}:\s')
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
65 """ def _pre_attempt(self, command):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
66 if command.strip()[-1] != ';':
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
67 return '%s;' % (command)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
68 return command"""
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
69 # can still trip on: apparent error messages listed as data
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
70
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
71 class SenoraSession(SQLSession):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
72 errPattern = re.compile('(\n[A-Z2]{3,4}-\d{4}:\s)|(\nwhat ? )')
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
73 call = os.popen('locate -r Senora\.pm$').readline().strip()
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
74 if call:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
75 call = 'perl %s' % (call)
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
76 else:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
77 print 'Senora.pm not found; commands cannot failover to Senora'
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
78 available = False
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
79
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
80 except ImportError:
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
81 print '''Python's pexpect module is not installed; cannot pass
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
82 commands through to sqlplus, etc.'''
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
83 class Session(object):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
84 valid = False
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
85 available = False
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
86 class YASQLSession(Session):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
87 pass
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
88 class SqlPlusSession(Session):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
89 pass
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
90 class SenoraSession(Session):
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
91 pass
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
92
9c87fa772ec1 before big refactor
catherine@serenity.wpafb.af.mil
parents:
diff changeset
93 available = [s for s in [SenoraSession, YASQLSession, SqlPlusSession] if s.available]