AbstractBase.py revision 0bfa859ea49d27efd89d5f152b8371b39919d92d
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 generic_type_tester(self, atoms, quotedDisplay=False): 24 """Test that variables with basic types are displayed correctly.""" 25 26 # First, capture the golden output emitted by the oracle, i.e., the 27 # series of printf statements. 28 go = system("./a.out", sender=self)[0] 29 # This golden list contains a list of (variable, value) pairs extracted 30 # from the golden output. 31 gl = [] 32 33 # Scan the golden output line by line, looking for the pattern: 34 # 35 # variable = 'value' 36 # 37 for line in go.split(os.linesep): 38 match = self.pattern.search(line) 39 if match: 40 var, val = match.group(1), match.group(2) 41 gl.append((var, val)) 42 #print "golden list:", gl 43 44 # Bring the program to the point where we can issue a series of 45 # 'frame variable -t' command. 46 self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) 47 self.runCmd("breakpoint set --name Puts") 48 self.runCmd("run", RUN_SUCCEEDED) 49 self.runCmd("thread step-out", STEP_OUT_SUCCEEDED) 50 51 #self.runCmd("frame variable -t") 52 53 # Now iterate through the golden list, comparing against the output from 54 # 'frame variable -t var'. 55 for var, val in gl: 56 self.runCmd("frame variable -t %s" % var) 57 output = self.res.GetOutput() 58 59 # The input type is in a canonical form as a set of named atoms. 60 # The display type string must conatin each and every element. 61 # 62 # Example: 63 # runCmd: frame variable -t a_array_bounded[0] 64 # output: (char) a_array_bounded[0] = 'a' 65 # 66 try: 67 dt = re.match("^\((.*)\)", output).group(1) 68 except: 69 self.fail(self.DATA_TYPE_GROKKED) 70 71 # Expect the display type string to contain each and every atoms. 72 self.expect(dt, 73 "Display type: '%s' must contain the type atoms: '%s'" % 74 (dt, atoms), 75 exe=False, 76 substrs = list(atoms)) 77 78 # The (var, val) pair must match, too. 79 nv = ("%s = '%s'" if quotedDisplay else "%s = %s") % (var, val) 80 self.expect(output, Msg(var, val, True), exe=False, 81 substrs = [nv]) 82 83 def generic_type_expr_tester(self, atoms, quotedDisplay=False): 84 """Test that variable expressions with basic types are evaluated correctly.""" 85 86 # First, capture the golden output emitted by the oracle, i.e., the 87 # series of printf statements. 88 go = system("./a.out", sender=self)[0] 89 # This golden list contains a list of (variable, value) pairs extracted 90 # from the golden output. 91 gl = [] 92 93 # Scan the golden output line by line, looking for the pattern: 94 # 95 # variable = 'value' 96 # 97 for line in go.split(os.linesep): 98 match = self.pattern.search(line) 99 if match: 100 var, val = match.group(1), match.group(2) 101 gl.append((var, val)) 102 #print "golden list:", gl 103 104 # Bring the program to the point where we can issue a series of 105 # 'expr' command. 106 self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) 107 self.runCmd("breakpoint set --name Puts") 108 self.runCmd("run", RUN_SUCCEEDED) 109 self.runCmd("thread step-out", STEP_OUT_SUCCEEDED) 110 111 #self.runCmd("frame variable -t") 112 113 # Now iterate through the golden list, comparing against the output from 114 # 'expr var'. 115 for var, val in gl: 116 # Don't overwhelm the expression mechanism. 117 # This slows down the test suite quite a bit, to enable it, define 118 # the environment variable LLDB_TYPES_EXPR_TIME_WAIT. For example: 119 # 120 # export LLDB_TYPES_EXPR_TIME_WAIT=0.5 121 # 122 # causes a 0.5 second delay between 'expression' commands. 123 if "LLDB_TYPES_EXPR_TIME_WAIT" in os.environ: 124 time.sleep(float(os.environ["LLDB_TYPES_EXPR_TIME_WAIT"])) 125 126 self.runCmd("expression %s" % var) 127 output = self.res.GetOutput() 128 129 # The input type is in a canonical form as a set named atoms. 130 # The display type string must conatin each and every element. 131 # 132 # Example: 133 # runCmd: expr a 134 # output: (double) $0 = 1100.12 135 # 136 try: 137 dt = re.match("^\((.*)\) \$[0-9]+ = ", output).group(1) 138 except: 139 self.fail(self.DATA_TYPE_GROKKED) 140 141 # Expect the display type string to contain each and every atoms. 142 self.expect(dt, 143 "Display type: '%s' must contain the type atoms: '%s'" % 144 (dt, atoms), 145 exe=False, 146 substrs = list(atoms)) 147 148 # The val part must match, too. 149 valPart = ("'%s'" if quotedDisplay else "%s") % val 150 self.expect(output, Msg(var, val, False), exe=False, 151 substrs = [valPart]) 152