blob: b9e211e42376fbb83c593436fa51cf09b619392d [file] [log] [blame]
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001"""
2LLDB module which provides the abstract base class of lldb test case.
3
4The concrete subclass can override lldbtest.TesBase in order to inherit the
5common behavior for unitest.TestCase.setUp/tearDown implemented in this file.
6
7The subclass should override the attribute mydir in order for the python runtime
8to locate the individual test cases when running as part of a large test suite
9or when running each test case as a separate python invocation.
10
11./dotest.py provides a test driver which sets up the environment to run the
12entire test suite. Users who want to run a test case on its own can specify the
13LLDB_TEST and PYTHONPATH environment variables, for example:
14
15$ export LLDB_TEST=$PWD
16$ export PYTHONPATH=/Volumes/data/lldb/svn/trunk/build/Debug/LLDB.framework/Resources/Python:$LLDB_TEST
17$ echo $LLDB_TEST
18/Volumes/data/lldb/svn/trunk/test
19$ echo $PYTHONPATH
20/Volumes/data/lldb/svn/trunk/build/Debug/LLDB.framework/Resources/Python:/Volumes/data/lldb/svn/trunk/test
21$ python function_types/TestFunctionTypes.py
22.
23----------------------------------------------------------------------
24Ran 1 test in 0.363s
25
26OK
Johnny Chend0190a62010-08-23 17:10:44 +000027$ LLDB_COMMAND_TRACE=YES python array_types/TestArrayTypes.py
28LLDB_COMMAND_TRACE=YES python array_types/TestArrayTypes.py
29runCmd: file /Volumes/data/lldb/svn/trunk/test/array_types/a.out
30output: Current executable set to '/Volumes/data/lldb/svn/trunk/test/array_types/a.out' (x86_64).
31
32runCmd: breakpoint set -f main.c -l 42
33output: Breakpoint created: 1: file ='main.c', line = 42, locations = 1
34
35runCmd: run
36output: Launching '/Volumes/data/lldb/svn/trunk/test/array_types/a.out' (x86_64)
37
38runCmd: thread list
39output: Process 24987 state is Stopped
40 thread #1: tid = 0x2e03, pc = 0x0000000100000df4, where = a.out`main + 612 at /Volumes/data/lldb/svn/trunk/test/array_types/main.c:45, stop reason = breakpoint 1.1, queue = com.apple.main-thread
41
42runCmd: breakpoint list
43output: Current breakpoints:
441: file ='main.c', line = 42, locations = 1, resolved = 1
45 1.1: where = a.out`main + 612 at /Volumes/data/lldb/svn/trunk/test/array_types/main.c:45, address = 0x0000000100000df4, resolved, hit count = 1
46
47
48runCmd: variable list strings
49output: (char *[4]) strings = {
50 (char *) strings[0] = 0x0000000100000f0c "Hello",
51 (char *) strings[1] = 0x0000000100000f12 "Hola",
52 (char *) strings[2] = 0x0000000100000f17 "Bonjour",
53 (char *) strings[3] = 0x0000000100000f1f "Guten Tag"
54}
55
56runCmd: variable list char_16
57output: (char [16]) char_16 = {
58 (char) char_16[0] = 'H',
59 (char) char_16[1] = 'e',
60 (char) char_16[2] = 'l',
61 (char) char_16[3] = 'l',
62 (char) char_16[4] = 'o',
63 (char) char_16[5] = ' ',
64 (char) char_16[6] = 'W',
65 (char) char_16[7] = 'o',
66 (char) char_16[8] = 'r',
67 (char) char_16[9] = 'l',
68 (char) char_16[10] = 'd',
69 (char) char_16[11] = '\n',
70 (char) char_16[12] = '\0',
71 (char) char_16[13] = '\0',
72 (char) char_16[14] = '\0',
73 (char) char_16[15] = '\0'
74}
75
76runCmd: variable list ushort_matrix
77output: (unsigned short [2][3]) ushort_matrix = {
78 (unsigned short [3]) ushort_matrix[0] = {
79 (unsigned short) ushort_matrix[0][0] = 0x0001,
80 (unsigned short) ushort_matrix[0][1] = 0x0002,
81 (unsigned short) ushort_matrix[0][2] = 0x0003
82 },
83 (unsigned short [3]) ushort_matrix[1] = {
84 (unsigned short) ushort_matrix[1][0] = 0x000b,
85 (unsigned short) ushort_matrix[1][1] = 0x0016,
86 (unsigned short) ushort_matrix[1][2] = 0x0021
87 }
88}
89
90runCmd: variable list long_6
91output: (long [6]) long_6 = {
92 (long) long_6[0] = 1,
93 (long) long_6[1] = 2,
94 (long) long_6[2] = 3,
95 (long) long_6[3] = 4,
96 (long) long_6[4] = 5,
97 (long) long_6[5] = 6
98}
99
100.
101----------------------------------------------------------------------
102Ran 1 test in 0.349s
103
104OK
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000105$
106"""
107
108import os
Johnny Chenff3d01d2010-08-20 21:03:09 +0000109import sys
Johnny Chen73258832010-08-05 23:42:46 +0000110import unittest2
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000111import lldb
112
Johnny Chen00778092010-08-09 22:01:17 +0000113#
114# Some commonly used assert messages.
115#
116
117CURRENT_EXECUTABLE_SET = "Current executable set successfully"
118
Johnny Chenff3d01d2010-08-20 21:03:09 +0000119RUN_STOPPED = "Process is launched and then stopped successfully"
Johnny Chen00778092010-08-09 22:01:17 +0000120
Johnny Chen17941842010-08-09 23:44:24 +0000121RUN_COMPLETED = "Process exited successfully"
Johnny Chen00778092010-08-09 22:01:17 +0000122
Johnny Chen17941842010-08-09 23:44:24 +0000123BREAKPOINT_CREATED = "Breakpoint created successfully"
124
Johnny Chene76896c2010-08-17 21:33:31 +0000125BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
126
Johnny Chen17941842010-08-09 23:44:24 +0000127BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
Johnny Chen00778092010-08-09 22:01:17 +0000128
129STOPPED_DUE_TO_BREAKPOINT = "Process state is stopped due to breakpoint"
130
131STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
132
Johnny Chen3c884a02010-08-24 22:07:56 +0000133DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
134
Johnny Chen00778092010-08-09 22:01:17 +0000135VARIABLES_DISPLAYED_CORRECTLY = "Show specified variable(s) correctly"
136
Johnny Chen17941842010-08-09 23:44:24 +0000137#
138# And a generic "Command '%s' returns successfully" message generator.
139#
140def CMD_MSG(command):
141 return "Command '%s' returns successfully" % (command)
142
143
Johnny Chen73258832010-08-05 23:42:46 +0000144class TestBase(unittest2.TestCase):
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000145 """This LLDB abstract base class is meant to be subclassed."""
146
147 # The concrete subclass should override this attribute.
Johnny Chenf02ec122010-07-03 20:41:42 +0000148 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000149
Johnny Chen6ca006c2010-08-16 21:28:10 +0000150 # State pertaining to the inferior process, if any.
151 runStarted = False
152
Johnny Chend0190a62010-08-23 17:10:44 +0000153 # os.environ["LLDB_COMMAND_TRACE"], if set to "YES", will turn on this flag.
154 traceAlways = False;
155
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000156 def setUp(self):
Johnny Chen9289a652010-08-07 01:13:18 +0000157 #import traceback
Johnny Chena2124952010-08-05 21:23:45 +0000158 #traceback.print_stack()
159
Johnny Chenf02ec122010-07-03 20:41:42 +0000160 # Fail fast if 'mydir' attribute is not overridden.
161 if not self.mydir or len(self.mydir) == 0:
162 raise Exception("Subclasses must override the 'mydir' attribute.")
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000163 # Save old working directory.
164 self.oldcwd = os.getcwd()
165
166 # Change current working directory if ${LLDB_TEST} is defined.
167 # See also dotest.py which sets up ${LLDB_TEST}.
168 if ("LLDB_TEST" in os.environ):
169 os.chdir(os.path.join(os.environ["LLDB_TEST"], self.mydir));
170
Johnny Chend0190a62010-08-23 17:10:44 +0000171 if ("LLDB_COMMAND_TRACE" in os.environ and
172 os.environ["LLDB_COMMAND_TRACE"] == "YES"):
173 self.traceAlways = True
174
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000175 # Create the debugger instance if necessary.
176 try:
177 self.dbg = lldb.DBG
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000178 except AttributeError:
179 self.dbg = lldb.SBDebugger.Create()
Johnny Chenf02ec122010-07-03 20:41:42 +0000180
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000181 if not self.dbg.IsValid():
182 raise Exception('Invalid debugger instance')
183
184 # We want our debugger to be synchronous.
185 self.dbg.SetAsync(False)
186
187 # Retrieve the associated command interpreter instance.
188 self.ci = self.dbg.GetCommandInterpreter()
189 if not self.ci:
190 raise Exception('Could not get the command interpreter')
191
192 # And the result object.
193 self.res = lldb.SBCommandReturnObject()
194
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000195 def tearDown(self):
Johnny Chen6ca006c2010-08-16 21:28:10 +0000196 # Finish the inferior process, if it was "run" previously.
197 if self.runStarted:
198 self.ci.HandleCommand("continue", self.res)
199
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000200 del self.dbg
201
202 # Restore old working directory.
203 os.chdir(self.oldcwd)
Johnny Chen27f212d2010-08-19 23:26:59 +0000204
Johnny Chend0190a62010-08-23 17:10:44 +0000205 def runCmd(self, cmd, msg=None, check=True, trace=False):
Johnny Chen27f212d2010-08-19 23:26:59 +0000206 """
207 Ask the command interpreter to handle the command and then check its
208 return status.
209 """
210 # Fail fast if 'cmd' is not meaningful.
211 if not cmd or len(cmd) == 0:
212 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000213
Johnny Chend0190a62010-08-23 17:10:44 +0000214 trace = (True if self.traceAlways else trace)
215
216 if trace:
Johnny Chenff3d01d2010-08-20 21:03:09 +0000217 print >> sys.stderr, "runCmd:", cmd
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000218
Johnny Chen27f212d2010-08-19 23:26:59 +0000219 self.ci.HandleCommand(cmd, self.res)
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000220
Johnny Chena6480c12010-08-19 23:53:55 +0000221 if cmd.startswith("run"):
Johnny Chen27f212d2010-08-19 23:26:59 +0000222 self.runStarted = True
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000223
Johnny Chend0190a62010-08-23 17:10:44 +0000224 if trace:
Johnny Chenff3d01d2010-08-20 21:03:09 +0000225 if self.res.Succeeded():
226 print >> sys.stderr, "output:", self.res.GetOutput()
227 else:
228 print >> sys.stderr, self.res.GetError()
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000229
Johnny Chen27f212d2010-08-19 23:26:59 +0000230 if check:
231 self.assertTrue(self.res.Succeeded(),
232 msg if msg else CMD_MSG(cmd))
233
Johnny Chend0190a62010-08-23 17:10:44 +0000234 def expect(self, cmd, msg=None, startstr=None, substrs=None, trace=False):
Johnny Chen27f212d2010-08-19 23:26:59 +0000235 """
236 Similar to runCmd; with additional expect style output matching ability.
237
238 Ask the command interpreter to handle the command and then check its
239 return status. The 'msg' parameter specifies an informational assert
240 message. We expect the output from running the command to start with
241 'startstr' and matches the substrings contained in 'substrs'.
242 """
Johnny Chen74f26b82010-08-20 19:17:39 +0000243
Johnny Chend0190a62010-08-23 17:10:44 +0000244 trace = (True if self.traceAlways else trace)
245
Johnny Chen74f26b82010-08-20 19:17:39 +0000246 # First run the command.
Johnny Chend0190a62010-08-23 17:10:44 +0000247 self.runCmd(cmd, trace = (True if trace else False))
Johnny Chen27f212d2010-08-19 23:26:59 +0000248
Johnny Chen74f26b82010-08-20 19:17:39 +0000249 # Then compare the output against expected strings.
Johnny Chen27f212d2010-08-19 23:26:59 +0000250 output = self.res.GetOutput()
251 matched = output.startswith(startstr) if startstr else True
Johnny Chenb145bba2010-08-20 18:25:15 +0000252
Johnny Chenc7c9fcf2010-08-24 23:48:10 +0000253 if startstr and trace:
254 print >> sys.stderr, "Expecting start string:", startstr
255 print >> sys.stderr, "Matched" if matched else "Not matched"
256 print >> sys.stderr
Johnny Chenb145bba2010-08-20 18:25:15 +0000257
Johnny Chen27f212d2010-08-19 23:26:59 +0000258 if substrs:
259 for str in substrs:
260 matched = output.find(str) > 0
Johnny Chenc7c9fcf2010-08-24 23:48:10 +0000261 if trace:
262 print >> sys.stderr, "Expecting sub string:", str
263 print >> sys.stderr, "Matched" if matched else "Not matched"
Johnny Chen27f212d2010-08-19 23:26:59 +0000264 if not matched:
265 break
Johnny Chenc7c9fcf2010-08-24 23:48:10 +0000266 if trace:
267 print >> sys.stderr
Johnny Chen27f212d2010-08-19 23:26:59 +0000268
Johnny Chen74f26b82010-08-20 19:17:39 +0000269 self.assertTrue(matched, msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +0000270