1 """logtest, a unittest.TestCase helper for testing log output."""
2
3 import sys
4 import time
5
6
7 try:
8
9 import msvcrt
12 except ImportError:
13
14 import tty, termios
16 fd = sys.stdin.fileno()
17 old_settings = termios.tcgetattr(fd)
18 try:
19 tty.setraw(sys.stdin.fileno())
20 ch = sys.stdin.read(1)
21 finally:
22 termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
23 return ch
24
25
27 """unittest.TestCase mixin for testing log messages.
28
29 logfile: a filename for the desired log. Yes, I know modes are evil,
30 but it makes the test functions so much cleaner to set this once.
31
32 lastmarker: the last marker in the log. This can be used to search for
33 messages since the last marker.
34
35 markerPrefix: a string with which to prefix log markers. This should be
36 unique enough from normal log output to use for marker identification.
37 """
38
39 logfile = None
40 lastmarker = None
41 markerPrefix = "test suite marker: "
42
44 print
45 print " ERROR:", msg
46
47 if not self.interactive:
48 raise self.failureException(msg)
49
50 p = " Show: [L]og [M]arker [P]attern; [I]gnore, [R]aise, or sys.e[X]it >> "
51 print p,
52 while True:
53 i = getchar().upper()
54 if i not in "MPLIRX":
55 continue
56 print i.upper()
57 if i == "L":
58 for x, line in enumerate(data):
59 if (x + 1) % self.console_height == 0:
60
61 print "<-- More -->\r",
62 m = getchar().lower()
63
64 print " \r",
65 if m == "q":
66 break
67 print line.rstrip()
68 elif i == "M":
69 print repr(marker or self.lastmarker)
70 elif i == "P":
71 print repr(pattern)
72 elif i == "I":
73
74 return
75 elif i == "R":
76 raise self.failureException(msg)
77 elif i == "X":
78 self.exit()
79 print p,
80
83
85 """Overwrite self.logfile with 0 bytes."""
86 open(self.logfile, 'wb').write("")
87
95
97 """Return lines from self.logfile in the marked region.
98
99 If marker is None, self.lastmarker is used. If the log hasn't
100 been marked (using self.markLog), the entire log will be returned.
101 """
102
103
104
105 logfile = self.logfile
106 marker = marker or self.lastmarker
107 if marker is None:
108 return open(logfile, 'rb').readlines()
109
110 data = []
111 in_region = False
112 for line in open(logfile, 'rb'):
113 if in_region:
114 if (line.startswith(self.markerPrefix) and not marker in line):
115 break
116 else:
117 data.append(line)
118 elif marker in line:
119 in_region = True
120 return data
121
123 """Fail if the given (partial) line is not in the log.
124
125 The log will be searched from the given marker to the next marker.
126 If marker is None, self.lastmarker is used. If the log hasn't
127 been marked (using self.markLog), the entire log will be searched.
128 """
129 data = self._read_marked_region(marker)
130 for logline in data:
131 if line in logline:
132 return
133 msg = "%r not found in log" % line
134 self._handleLogError(msg, data, marker, line)
135
137 """Fail if the given (partial) line is in the log.
138
139 The log will be searched from the given marker to the next marker.
140 If marker is None, self.lastmarker is used. If the log hasn't
141 been marked (using self.markLog), the entire log will be searched.
142 """
143 data = self._read_marked_region(marker)
144 for logline in data:
145 if line in logline:
146 msg = "%r found in log" % line
147 self._handleLogError(msg, data, marker, line)
148
149 - def assertLog(self, sliceargs, lines, marker=None):
150 """Fail if log.readlines()[sliceargs] is not contained in 'lines'.
151
152 The log will be searched from the given marker to the next marker.
153 If marker is None, self.lastmarker is used. If the log hasn't
154 been marked (using self.markLog), the entire log will be searched.
155 """
156 data = self._read_marked_region(marker)
157 if isinstance(sliceargs, int):
158
159 if isinstance(lines, (tuple, list)):
160 lines = lines[0]
161 if lines not in data[sliceargs]:
162 msg = "%r not found on log line %r" % (lines, sliceargs)
163 self._handleLogError(msg, [data[sliceargs]], marker, lines)
164 else:
165
166 if isinstance(lines, tuple):
167 lines = list(lines)
168 elif isinstance(lines, basestring):
169 raise TypeError("The 'lines' arg must be a list when "
170 "'sliceargs' is a tuple.")
171
172 start, stop = sliceargs
173 for line, logline in zip(lines, data[start:stop]):
174 if line not in logline:
175 msg = "%r not found in log" % line
176 self._handleLogError(msg, data[start:stop], marker, line)
177