AbstractBase.py revision 99323d8797f5a75dcbf64937422fbc685cf132b6
1""" 2Abstract base class of basic types provides a generic type tester method. 3""" 4 5import os, time 6import re 7import lldb 8from lldbtest import * 9 10def Msg(var, val, using_frame_variable): 11 return "'%s %s' matches the output (from compiled code): %s" % ( 12 'frame variable -T' if using_frame_variable else 'expression' ,var, val) 13 14class GenericTester(TestBase): 15 16 # This is the pattern by design to match the " var = 'value'" output from 17 # printf() stmts (see basic_type.cpp). 18 pattern = re.compile(" (\*?a[^=]*) = '([^=]*)'$") 19 20 # Assert message. 21 DATA_TYPE_GROKKED = "Data type from expr parser output is parsed correctly" 22 23 def setUp(self): 24 # Call super's setUp(). 25 TestBase.setUp(self) 26 # We'll use the test method name as the exe_name. 27 # There are a bunch of test cases under test/types and we don't want the 28 # module cacheing subsystem to be confused with executable name "a.out" 29 # used for all the test cases. 30 self.exe_name = self.testMethodName 31 32 def generic_type_tester(self, exe_name, atoms, quotedDisplay=False): 33 """Test that variables with basic types are displayed correctly.""" 34 35 # First, capture the golden output emitted by the oracle, i.e., the 36 # series of printf statements. 37 go = system("./%s" % exe_name, sender=self)[0] 38 # This golden list contains a list of (variable, value) pairs extracted 39 # from the golden output. 40 gl = [] 41 42 # Scan the golden output line by line, looking for the pattern: 43 # 44 # variable = 'value' 45 # 46 for line in go.split(os.linesep): 47 match = self.pattern.search(line) 48 if match: 49 var, val = match.group(1), match.group(2) 50 gl.append((var, val)) 51 #print "golden list:", gl 52 53 # Bring the program to the point where we can issue a series of 54 # 'frame variable -T' command. 55 self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET) 56 puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on to check variables") 57 self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line, 58 BREAKPOINT_CREATED, 59 startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" % 60 puts_line) 61 62 self.runCmd("run", RUN_SUCCEEDED) 63 self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, 64 substrs = [" at basic_type.cpp:%d" % puts_line, 65 "stop reason = breakpoint"]) 66 67 #self.runCmd("frame variable -T") 68 69 # Now iterate through the golden list, comparing against the output from 70 # 'frame variable -T var'. 71 for var, val in gl: 72 self.runCmd("frame variable -T %s" % var) 73 output = self.res.GetOutput() 74 75 # The input type is in a canonical form as a set of named atoms. 76 # The display type string must conatin each and every element. 77 # 78 # Example: 79 # runCmd: frame variable -T a_array_bounded[0] 80 # output: (char) a_array_bounded[0] = 'a' 81 # 82 try: 83 dt = re.match("^\((.*)\)", output).group(1) 84 except: 85 self.fail(self.DATA_TYPE_GROKKED) 86 87 # Expect the display type string to contain each and every atoms. 88 self.expect(dt, 89 "Display type: '%s' must contain the type atoms: '%s'" % 90 (dt, atoms), 91 exe=False, 92 substrs = list(atoms)) 93 94 # The (var, val) pair must match, too. 95 nv = ("%s = '%s'" if quotedDisplay else "%s = %s") % (var, val) 96 self.expect(output, Msg(var, val, True), exe=False, 97 substrs = [nv]) 98 99 def generic_type_expr_tester(self, exe_name, atoms, quotedDisplay=False): 100 """Test that variable expressions with basic types are evaluated correctly.""" 101 102 # First, capture the golden output emitted by the oracle, i.e., the 103 # series of printf statements. 104 go = system("./%s" % exe_name, sender=self)[0] 105 # This golden list contains a list of (variable, value) pairs extracted 106 # from the golden output. 107 gl = [] 108 109 # Scan the golden output line by line, looking for the pattern: 110 # 111 # variable = 'value' 112 # 113 for line in go.split(os.linesep): 114 match = self.pattern.search(line) 115 if match: 116 var, val = match.group(1), match.group(2) 117 gl.append((var, val)) 118 #print "golden list:", gl 119 120 # Bring the program to the point where we can issue a series of 121 # 'expr' command. 122 self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET) 123 puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on to check variables.") 124 self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line, 125 BREAKPOINT_CREATED, 126 startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" % 127 puts_line) 128 self.runCmd("run", RUN_SUCCEEDED) 129 self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, 130 substrs = [" at basic_type.cpp:%d" % puts_line, 131 "stop reason = breakpoint"]) 132 133 #self.runCmd("frame variable -T") 134 135 # Now iterate through the golden list, comparing against the output from 136 # 'expr var'. 137 for var, val in gl: 138 # Don't overwhelm the expression mechanism. 139 # This slows down the test suite quite a bit, to enable it, define 140 # the environment variable LLDB_TYPES_EXPR_TIME_WAIT. For example: 141 # 142 # export LLDB_TYPES_EXPR_TIME_WAIT=0.5 143 # 144 # causes a 0.5 second delay between 'expression' commands. 145 if "LLDB_TYPES_EXPR_TIME_WAIT" in os.environ: 146 time.sleep(float(os.environ["LLDB_TYPES_EXPR_TIME_WAIT"])) 147 148 self.runCmd("expression %s" % var) 149 output = self.res.GetOutput() 150 151 # The input type is in a canonical form as a set of named atoms. 152 # The display type string must conatin each and every element. 153 # 154 # Example: 155 # runCmd: expr a 156 # output: (double) $0 = 1100.12 157 # 158 try: 159 dt = re.match("^\((.*)\) \$[0-9]+ = ", output).group(1) 160 except: 161 self.fail(self.DATA_TYPE_GROKKED) 162 163 # Expect the display type string to contain each and every atoms. 164 self.expect(dt, 165 "Display type: '%s' must contain the type atoms: '%s'" % 166 (dt, atoms), 167 exe=False, 168 substrs = list(atoms)) 169 170 # The val part must match, too. 171 valPart = ("'%s'" if quotedDisplay else "%s") % val 172 self.expect(output, Msg(var, val, False), exe=False, 173 substrs = [valPart]) 174