AbstractBase.py revision d062ee862396d29b8c06c60b9e2c38330cf42665
10b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen""" 27c52ff1d83ec262f35c9a825af107735913e7225Johnny ChenAbstract base class of basic types provides a generic type tester method. 30b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen""" 40b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen 50b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chenimport os, time 6091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chenimport re 70b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chenimport lldb 80b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chenfrom lldbtest import * 90b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen 1066a03531e5199f13482e46777f350312a2b950c1Johnny Chendef Msg(var, val, using_frame_variable): 1166a03531e5199f13482e46777f350312a2b950c1Johnny Chen return "'%s %s' matches the output (from compiled code): %s" % ( 1210de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham 'frame variable -T' if using_frame_variable else 'expression' ,var, val) 13091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen 1451a9e00e10d29ba01af7bc2d5efbcf31ec1f76a4Johnny Chenclass GenericTester(TestBase): 150b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen 16091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # This is the pattern by design to match the " var = 'value'" output from 17091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # printf() stmts (see basic_type.cpp). 18091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen pattern = re.compile(" (\*?a[^=]*) = '([^=]*)'$") 19091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen 20cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen # Assert message. 21cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen DATA_TYPE_GROKKED = "Data type from expr parser output is parsed correctly" 22cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen 23d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen def setUp(self): 24d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen # Call super's setUp(). 25d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen TestBase.setUp(self) 26d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen # We'll use the test method name as the exe_name. 27d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen # There are a bunch of test cases under test/types and we don't want the 28d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen # module cacheing subsystem to be confused with executable name "a.out" 29d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen # used for all the test cases. 30d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen self.exe_name = self._testMethodName 31d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen 322c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen def generic_type_tester(self, exe_name, atoms, quotedDisplay=False): 33091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen """Test that variables with basic types are displayed correctly.""" 34091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen 35091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # First, capture the golden output emitted by the oracle, i.e., the 36091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # series of printf statements. 372c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen go = system("./%s" % exe_name, sender=self)[0] 38091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # This golden list contains a list of (variable, value) pairs extracted 39091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # from the golden output. 40091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen gl = [] 410b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen 42091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # Scan the golden output line by line, looking for the pattern: 43091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # 44091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # variable = 'value' 45091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # 46091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen for line in go.split(os.linesep): 47091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen match = self.pattern.search(line) 48091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen if match: 49091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen var, val = match.group(1), match.group(2) 50091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen gl.append((var, val)) 51091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen #print "golden list:", gl 52091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen 53091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # Bring the program to the point where we can issue a series of 5410de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham # 'frame variable -T' command. 552c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET) 56c9aabf097245642531d74410ff1371a97991af64Johnny Chen puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on to check variables") 57e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line, 58e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham BREAKPOINT_CREATED, 59e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" % 60e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham puts_line) 61e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham 62c9aabf097245642531d74410ff1371a97991af64Johnny Chen self.runCmd("run", RUN_SUCCEEDED) 63c9aabf097245642531d74410ff1371a97991af64Johnny Chen self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, 64c9aabf097245642531d74410ff1371a97991af64Johnny Chen substrs = [" at basic_type.cpp:%d" % puts_line, 65c9aabf097245642531d74410ff1371a97991af64Johnny Chen "stop reason = breakpoint"]) 660b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen 6710de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham #self.runCmd("frame variable -T") 684ec97859ca68e299b5b2beb0313fffeea9d0119eJohnny Chen 69091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen # Now iterate through the golden list, comparing against the output from 7010de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham # 'frame variable -T var'. 71091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen for var, val in gl: 7210de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham self.runCmd("frame variable -T %s" % var) 73091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen output = self.res.GetOutput() 74757396a950315670e3400b97b51a081a8dcb4fc3Johnny Chen 7551287a1b5f1524f2e6b14254b41a80908b060668Johnny Chen # The input type is in a canonical form as a set of named atoms. 768ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen # The display type string must conatin each and every element. 775a3a3d968116e73a80b917a8d9c54ccdd92e2a8cJohnny Chen # 785a3a3d968116e73a80b917a8d9c54ccdd92e2a8cJohnny Chen # Example: 7910de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham # runCmd: frame variable -T a_array_bounded[0] 805a3a3d968116e73a80b917a8d9c54ccdd92e2a8cJohnny Chen # output: (char) a_array_bounded[0] = 'a' 815a3a3d968116e73a80b917a8d9c54ccdd92e2a8cJohnny Chen # 825fed90a7c7f5b496bc6e7453b7aaec2ff8e6399dJohnny Chen try: 835fed90a7c7f5b496bc6e7453b7aaec2ff8e6399dJohnny Chen dt = re.match("^\((.*)\)", output).group(1) 845fed90a7c7f5b496bc6e7453b7aaec2ff8e6399dJohnny Chen except: 85cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen self.fail(self.DATA_TYPE_GROKKED) 86757396a950315670e3400b97b51a081a8dcb4fc3Johnny Chen 878ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen # Expect the display type string to contain each and every atoms. 888ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen self.expect(dt, 898ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen "Display type: '%s' must contain the type atoms: '%s'" % 908ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen (dt, atoms), 918ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen exe=False, 928ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen substrs = list(atoms)) 93757396a950315670e3400b97b51a081a8dcb4fc3Johnny Chen 94757396a950315670e3400b97b51a081a8dcb4fc3Johnny Chen # The (var, val) pair must match, too. 9519edbc5223c7ace86c983c3cc6bd9e610cd329c8Johnny Chen nv = ("%s = '%s'" if quotedDisplay else "%s = %s") % (var, val) 9666a03531e5199f13482e46777f350312a2b950c1Johnny Chen self.expect(output, Msg(var, val, True), exe=False, 974ec97859ca68e299b5b2beb0313fffeea9d0119eJohnny Chen substrs = [nv]) 98b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen 992c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen def generic_type_expr_tester(self, exe_name, atoms, quotedDisplay=False): 100b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen """Test that variable expressions with basic types are evaluated correctly.""" 101b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen 102b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # First, capture the golden output emitted by the oracle, i.e., the 103b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # series of printf statements. 1042c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen go = system("./%s" % exe_name, sender=self)[0] 105b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # This golden list contains a list of (variable, value) pairs extracted 106b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # from the golden output. 107b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen gl = [] 108b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen 109b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # Scan the golden output line by line, looking for the pattern: 110b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # 111b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # variable = 'value' 112b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # 113b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen for line in go.split(os.linesep): 114b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen match = self.pattern.search(line) 115b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen if match: 116b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen var, val = match.group(1), match.group(2) 117b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen gl.append((var, val)) 118b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen #print "golden list:", gl 119b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen 120b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # Bring the program to the point where we can issue a series of 12134f99221dcb055d3a35b6174e0d818fdb73da878Johnny Chen # 'expr' command. 1222c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET) 123c9aabf097245642531d74410ff1371a97991af64Johnny Chen puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on to check variables.") 124e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line, 125e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham BREAKPOINT_CREATED, 126e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" % 127e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham puts_line) 128c9aabf097245642531d74410ff1371a97991af64Johnny Chen self.runCmd("run", RUN_SUCCEEDED) 129c9aabf097245642531d74410ff1371a97991af64Johnny Chen self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, 130c9aabf097245642531d74410ff1371a97991af64Johnny Chen substrs = [" at basic_type.cpp:%d" % puts_line, 131c9aabf097245642531d74410ff1371a97991af64Johnny Chen "stop reason = breakpoint"]) 132b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen 13310de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham #self.runCmd("frame variable -T") 134b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen 135b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # Now iterate through the golden list, comparing against the output from 136c401e37b99cca3482bacb7bc98cc09d69a1cd2acJohnny Chen # 'expr var'. 137b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen for var, val in gl: 138118d742036e0a8b04c5efb65a39fa6bbf461aa2fJohnny Chen # Don't overwhelm the expression mechanism. 13921c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen # This slows down the test suite quite a bit, to enable it, define 14021c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen # the environment variable LLDB_TYPES_EXPR_TIME_WAIT. For example: 14121c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen # 14221c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen # export LLDB_TYPES_EXPR_TIME_WAIT=0.5 14321c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen # 14421c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen # causes a 0.5 second delay between 'expression' commands. 14521c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen if "LLDB_TYPES_EXPR_TIME_WAIT" in os.environ: 14621c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen time.sleep(float(os.environ["LLDB_TYPES_EXPR_TIME_WAIT"])) 14721c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen 14866a03531e5199f13482e46777f350312a2b950c1Johnny Chen self.runCmd("expression %s" % var) 149b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen output = self.res.GetOutput() 150b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen 151b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # The input type is in a canonical form as a set named atoms. 152b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # The display type string must conatin each and every element. 153bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen # 154bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen # Example: 155bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen # runCmd: expr a 1566e81fa35eae0a3c6ca8aee19c4bb2f231b6ab912Johnny Chen # output: (double) $0 = 1100.12 157bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen # 158bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen try: 1596e81fa35eae0a3c6ca8aee19c4bb2f231b6ab912Johnny Chen dt = re.match("^\((.*)\) \$[0-9]+ = ", output).group(1) 160bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen except: 161cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen self.fail(self.DATA_TYPE_GROKKED) 162b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen 163b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen # Expect the display type string to contain each and every atoms. 164bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen self.expect(dt, 165bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen "Display type: '%s' must contain the type atoms: '%s'" % 166bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen (dt, atoms), 167bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen exe=False, 168bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen substrs = list(atoms)) 169b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen 170bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen # The val part must match, too. 171bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen valPart = ("'%s'" if quotedDisplay else "%s") % val 17266a03531e5199f13482e46777f350312a2b950c1Johnny Chen self.expect(output, Msg(var, val, False), exe=False, 173bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen substrs = [valPart]) 174