blob: 0ebefc10e802ed8ecc76d9272c3c826ea01ab650 [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
133VARIABLES_DISPLAYED_CORRECTLY = "Show specified variable(s) correctly"
134
Johnny Chen17941842010-08-09 23:44:24 +0000135#
136# And a generic "Command '%s' returns successfully" message generator.
137#
138def CMD_MSG(command):
139 return "Command '%s' returns successfully" % (command)
140
141
Johnny Chen73258832010-08-05 23:42:46 +0000142class TestBase(unittest2.TestCase):
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000143 """This LLDB abstract base class is meant to be subclassed."""
144
145 # The concrete subclass should override this attribute.
Johnny Chenf02ec122010-07-03 20:41:42 +0000146 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000147
Johnny Chen6ca006c2010-08-16 21:28:10 +0000148 # State pertaining to the inferior process, if any.
149 runStarted = False
150
Johnny Chend0190a62010-08-23 17:10:44 +0000151 # os.environ["LLDB_COMMAND_TRACE"], if set to "YES", will turn on this flag.
152 traceAlways = False;
153
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000154 def setUp(self):
Johnny Chen9289a652010-08-07 01:13:18 +0000155 #import traceback
Johnny Chena2124952010-08-05 21:23:45 +0000156 #traceback.print_stack()
157
Johnny Chenf02ec122010-07-03 20:41:42 +0000158 # Fail fast if 'mydir' attribute is not overridden.
159 if not self.mydir or len(self.mydir) == 0:
160 raise Exception("Subclasses must override the 'mydir' attribute.")
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000161 # Save old working directory.
162 self.oldcwd = os.getcwd()
163
164 # Change current working directory if ${LLDB_TEST} is defined.
165 # See also dotest.py which sets up ${LLDB_TEST}.
166 if ("LLDB_TEST" in os.environ):
167 os.chdir(os.path.join(os.environ["LLDB_TEST"], self.mydir));
168
Johnny Chend0190a62010-08-23 17:10:44 +0000169 if ("LLDB_COMMAND_TRACE" in os.environ and
170 os.environ["LLDB_COMMAND_TRACE"] == "YES"):
171 self.traceAlways = True
172
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000173 # Create the debugger instance if necessary.
174 try:
175 self.dbg = lldb.DBG
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000176 except AttributeError:
177 self.dbg = lldb.SBDebugger.Create()
Johnny Chenf02ec122010-07-03 20:41:42 +0000178
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000179 if not self.dbg.IsValid():
180 raise Exception('Invalid debugger instance')
181
182 # We want our debugger to be synchronous.
183 self.dbg.SetAsync(False)
184
185 # Retrieve the associated command interpreter instance.
186 self.ci = self.dbg.GetCommandInterpreter()
187 if not self.ci:
188 raise Exception('Could not get the command interpreter')
189
190 # And the result object.
191 self.res = lldb.SBCommandReturnObject()
192
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000193 def tearDown(self):
Johnny Chen6ca006c2010-08-16 21:28:10 +0000194 # Finish the inferior process, if it was "run" previously.
195 if self.runStarted:
196 self.ci.HandleCommand("continue", self.res)
197
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000198 del self.dbg
199
200 # Restore old working directory.
201 os.chdir(self.oldcwd)
Johnny Chen27f212d2010-08-19 23:26:59 +0000202
Johnny Chend0190a62010-08-23 17:10:44 +0000203 def runCmd(self, cmd, msg=None, check=True, trace=False):
Johnny Chen27f212d2010-08-19 23:26:59 +0000204 """
205 Ask the command interpreter to handle the command and then check its
206 return status.
207 """
208 # Fail fast if 'cmd' is not meaningful.
209 if not cmd or len(cmd) == 0:
210 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000211
Johnny Chend0190a62010-08-23 17:10:44 +0000212 trace = (True if self.traceAlways else trace)
213
214 if trace:
Johnny Chenff3d01d2010-08-20 21:03:09 +0000215 print >> sys.stderr, "runCmd:", cmd
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000216
Johnny Chen27f212d2010-08-19 23:26:59 +0000217 self.ci.HandleCommand(cmd, self.res)
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000218
Johnny Chena6480c12010-08-19 23:53:55 +0000219 if cmd.startswith("run"):
Johnny Chen27f212d2010-08-19 23:26:59 +0000220 self.runStarted = True
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000221
Johnny Chend0190a62010-08-23 17:10:44 +0000222 if trace:
Johnny Chenff3d01d2010-08-20 21:03:09 +0000223 if self.res.Succeeded():
224 print >> sys.stderr, "output:", self.res.GetOutput()
225 else:
226 print >> sys.stderr, self.res.GetError()
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000227
Johnny Chen27f212d2010-08-19 23:26:59 +0000228 if check:
229 self.assertTrue(self.res.Succeeded(),
230 msg if msg else CMD_MSG(cmd))
231
Johnny Chend0190a62010-08-23 17:10:44 +0000232 def expect(self, cmd, msg=None, startstr=None, substrs=None, trace=False):
Johnny Chen27f212d2010-08-19 23:26:59 +0000233 """
234 Similar to runCmd; with additional expect style output matching ability.
235
236 Ask the command interpreter to handle the command and then check its
237 return status. The 'msg' parameter specifies an informational assert
238 message. We expect the output from running the command to start with
239 'startstr' and matches the substrings contained in 'substrs'.
240 """
Johnny Chen74f26b82010-08-20 19:17:39 +0000241
Johnny Chend0190a62010-08-23 17:10:44 +0000242 trace = (True if self.traceAlways else trace)
243
Johnny Chen74f26b82010-08-20 19:17:39 +0000244 # First run the command.
Johnny Chend0190a62010-08-23 17:10:44 +0000245 self.runCmd(cmd, trace = (True if trace else False))
Johnny Chen27f212d2010-08-19 23:26:59 +0000246
Johnny Chen74f26b82010-08-20 19:17:39 +0000247 # Then compare the output against expected strings.
Johnny Chen27f212d2010-08-19 23:26:59 +0000248 output = self.res.GetOutput()
249 matched = output.startswith(startstr) if startstr else True
Johnny Chenb145bba2010-08-20 18:25:15 +0000250
Johnny Chend0190a62010-08-23 17:10:44 +0000251 if not matched and startstr and trace:
Johnny Chenff3d01d2010-08-20 21:03:09 +0000252 print >> sys.stderr, "Startstr not matched:", startstr
Johnny Chenb145bba2010-08-20 18:25:15 +0000253
Johnny Chen27f212d2010-08-19 23:26:59 +0000254 if substrs:
255 for str in substrs:
256 matched = output.find(str) > 0
257 if not matched:
Johnny Chend0190a62010-08-23 17:10:44 +0000258 if trace:
Johnny Chenff3d01d2010-08-20 21:03:09 +0000259 print >> sys.stderr, "Substring not matched:", str
Johnny Chen27f212d2010-08-19 23:26:59 +0000260 break
261
Johnny Chen74f26b82010-08-20 19:17:39 +0000262 self.assertTrue(matched, msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +0000263