1""" 2Use lldb Python API to verify that expression evaluation for property references uses the correct getters and setters 3""" 4 5import os, time 6import re 7import unittest2 8import lldb, lldbutil 9from lldbtest import * 10 11class ObjCPropertyTestCase(TestBase): 12 13 mydir = os.path.join("lang", "objc", "objc-property") 14 15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 16 @python_api_test 17 @dsym_test 18 def test_objc_properties_with_dsym(self): 19 """Test that expr uses the correct property getters and setters""" 20 if self.getArchitecture() == 'i386': 21 self.skipTest("requires modern objc runtime") 22 self.buildDsym() 23 self.do_test_properties() 24 25 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 26 @python_api_test 27 @dwarf_test 28 def test_objc_properties_with_dwarf(self): 29 """Test that expr uses the correct property getters and setters""" 30 if self.getArchitecture() == 'i386': 31 self.skipTest("requires modern objc runtime") 32 self.buildDwarf() 33 self.do_test_properties() 34 35 def setUp(self): 36 # Call super's setUp(). 37 TestBase.setUp(self) 38 39 # Find the line number to break for main.c. 40 41 self.source_name = 'main.m' 42 43 def run_to_main (self): 44 """Test that expr uses the correct property getters and setters""" 45 exe = os.path.join(os.getcwd(), "a.out") 46 47 # Create a target from the debugger. 48 49 target = self.dbg.CreateTarget (exe) 50 self.assertTrue(target, VALID_TARGET) 51 52 # Set up our breakpoints: 53 54 main_bkpt = target.BreakpointCreateBySourceRegex ("Set a breakpoint here.", lldb.SBFileSpec (self.source_name)) 55 self.assertTrue(main_bkpt and 56 main_bkpt.GetNumLocations() == 1, 57 VALID_BREAKPOINT) 58 59 # Now launch the process, and do not stop at the entry point. 60 process = target.LaunchSimple (None, None, os.getcwd()) 61 62 self.assertTrue(process.GetState() == lldb.eStateStopped, 63 PROCESS_STOPPED) 64 65 threads = lldbutil.get_threads_stopped_at_breakpoint (process, main_bkpt) 66 self.assertTrue (len(threads) == 1) 67 thread = threads[0] 68 return thread 69 70 def do_test_properties (self): 71 72 thread = self.run_to_main() 73 74 frame = thread.GetFrameAtIndex(0) 75 76 mine = frame.FindVariable ("mine") 77 self.assertTrue (mine.IsValid()) 78 access_count = mine.GetChildMemberWithName ("_access_count") 79 self.assertTrue (access_count.IsValid()) 80 start_access_count = access_count.GetValueAsUnsigned (123456) 81 self.assertTrue (start_access_count != 123456) 82 83 # 84 # The first set of tests test calling the getter & setter of 85 # a property that actually only has a getter & setter and no 86 # @property. 87 # 88 nonexistant_value = frame.EvaluateExpression("mine.nonexistantInt", False) 89 nonexistant_error = nonexistant_value.GetError() 90 self.assertTrue (nonexistant_error.Success()) 91 nonexistant_int = nonexistant_value.GetValueAsUnsigned (123456) 92 self.assertTrue (nonexistant_int == 6) 93 94 # Calling the getter function would up the access count, so make sure that happened. 95 96 new_access_count = access_count.GetValueAsUnsigned (123456) 97 self.assertTrue (new_access_count - start_access_count == 1) 98 start_access_count = new_access_count 99 100 # 101 # Now call the setter, then make sure that 102 nonexistant_change = frame.EvaluateExpression("mine.nonexistantInt = 10", False) 103 nonexistant_error = nonexistant_change.GetError() 104 self.assertTrue (nonexistant_error.Success()) 105 106 # Calling the setter function would up the access count, so make sure that happened. 107 108 new_access_count = access_count.GetValueAsUnsigned (123456) 109 self.assertTrue (new_access_count - start_access_count == 1) 110 start_access_count = new_access_count 111 112 # 113 # Now we call the getter of a property that is backed by an ivar, 114 # make sure it works and that we actually update the backing ivar. 115 # 116 117 backed_value = frame.EvaluateExpression("mine.backedInt", False) 118 backed_error = backed_value.GetError() 119 self.assertTrue (backed_error.Success()) 120 backing_value = mine.GetChildMemberWithName ("_backedInt") 121 self.assertTrue (backing_value.IsValid()) 122 self.assertTrue (backed_value.GetValueAsUnsigned (12345) == backing_value.GetValueAsUnsigned(23456)) 123 124 unbacked_value = frame.EvaluateExpression("mine.unbackedInt", False) 125 unbacked_error = unbacked_value.GetError() 126 self.assertTrue (unbacked_error.Success()) 127 128 idWithProtocol_value = frame.EvaluateExpression("mine.idWithProtocol", False) 129 idWithProtocol_error = idWithProtocol_value.GetError() 130 self.assertTrue (idWithProtocol_error.Success()) 131 self.assertTrue (idWithProtocol_value.GetTypeName() == "id") 132 133if __name__ == '__main__': 134 import atexit 135 lldb.SBDebugger.Initialize() 136 atexit.register(lambda: lldb.SBDebugger.Terminate()) 137 unittest2.main() 138