2 Use lldb Python API to verify that expression evaluation for property references uses the correct getters and setters
7 from lldbsuite
.test
.decorators
import *
8 from lldbsuite
.test
.lldbtest
import *
9 from lldbsuite
.test
import lldbutil
12 class ObjCPropertyTestCase(TestBase
):
14 # Call super's setUp().
17 # Find the line number to break for main.c.
18 self
.source_name
= "main.m"
20 @add_test_categories(["pyapi"])
21 def test_objc_properties(self
):
22 """Test that expr uses the correct property getters and setters"""
23 if self
.getArchitecture() == "i386":
24 self
.skipTest("requires modern objc runtime")
27 exe
= self
.getBuildArtifact("a.out")
29 # Create a target from the debugger.
31 target
= self
.dbg
.CreateTarget(exe
)
32 self
.assertTrue(target
, VALID_TARGET
)
34 # Set up our breakpoints:
36 main_bkpt
= target
.BreakpointCreateBySourceRegex(
37 "Set a breakpoint here.", lldb
.SBFileSpec(self
.source_name
)
40 main_bkpt
and main_bkpt
.GetNumLocations() == 1, VALID_BREAKPOINT
43 # Now launch the process, and do not stop at the entry point.
44 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
46 self
.assertState(process
.GetState(), lldb
.eStateStopped
, PROCESS_STOPPED
)
48 threads
= lldbutil
.get_threads_stopped_at_breakpoint(process
, main_bkpt
)
49 self
.assertEquals(len(threads
), 1)
51 frame
= thread
.GetFrameAtIndex(0)
53 mine
= frame
.FindVariable("mine")
54 self
.assertTrue(mine
.IsValid())
55 access_count
= mine
.GetChildMemberWithName("_access_count")
56 self
.assertTrue(access_count
.IsValid())
57 start_access_count
= access_count
.GetValueAsUnsigned(123456)
58 self
.assertNotEqual(start_access_count
, 123456)
61 # The first set of tests test calling the getter & setter of
62 # a property that actually only has a getter & setter and no
65 nonexistant_value
= frame
.EvaluateExpression("mine.nonexistantInt", False)
66 nonexistant_error
= nonexistant_value
.GetError()
67 self
.assertSuccess(nonexistant_error
)
68 nonexistant_int
= nonexistant_value
.GetValueAsUnsigned(123456)
69 self
.assertEquals(nonexistant_int
, 6)
71 # Calling the getter function would up the access count, so make sure
74 new_access_count
= access_count
.GetValueAsUnsigned(123456)
75 self
.assertEquals(new_access_count
- start_access_count
, 1)
76 start_access_count
= new_access_count
79 # Now call the setter, then make sure that
80 nonexistant_change
= frame
.EvaluateExpression("mine.nonexistantInt = 10", False)
81 nonexistant_error
= nonexistant_change
.GetError()
82 self
.assertSuccess(nonexistant_error
)
84 # Calling the setter function would up the access count, so make sure
87 new_access_count
= access_count
.GetValueAsUnsigned(123456)
88 self
.assertEquals(new_access_count
- start_access_count
, 1)
89 start_access_count
= new_access_count
92 # Now we call the getter of a property that is backed by an ivar,
93 # make sure it works and that we actually update the backing ivar.
96 backed_value
= frame
.EvaluateExpression("mine.backedInt", False)
97 backed_error
= backed_value
.GetError()
98 self
.assertSuccess(backed_error
)
99 backing_value
= mine
.GetChildMemberWithName("_backedInt")
100 self
.assertTrue(backing_value
.IsValid())
102 backed_value
.GetValueAsUnsigned(12345),
103 backing_value
.GetValueAsUnsigned(23456),
106 value_from_typedef
= frame
.EvaluateExpression("typedefd.backedInt", False)
107 self
.assertSuccess(value_from_typedef
.GetError())
109 value_from_typedef
.GetValueAsUnsigned(12345),
110 backing_value
.GetValueAsUnsigned(23456),
113 unbacked_value
= frame
.EvaluateExpression("mine.unbackedInt", False)
114 unbacked_error
= unbacked_value
.GetError()
115 self
.assertSuccess(unbacked_error
)
117 idWithProtocol_value
= frame
.EvaluateExpression("mine.idWithProtocol", False)
118 idWithProtocol_error
= idWithProtocol_value
.GetError()
119 self
.assertSuccess(idWithProtocol_error
)
120 self
.assertEquals(idWithProtocol_value
.GetTypeName(), "id")
122 # Make sure that class property getter works as expected
123 value
= frame
.EvaluateExpression("BaseClass.classInt", False)
124 self
.assertSuccess(value
.GetError())
125 self
.assertEquals(value
.GetValueAsUnsigned(11111), 123)
127 # Make sure that class property setter works as expected
128 value
= frame
.EvaluateExpression("BaseClass.classInt = 234", False)
129 self
.assertSuccess(value
.GetError())
131 # Verify that setter above actually worked
132 value
= frame
.EvaluateExpression("BaseClass.classInt", False)
133 self
.assertSuccess(value
.GetError())
134 self
.assertEquals(value
.GetValueAsUnsigned(11111), 234)
136 # Test that accessing two distinct class and instance properties that
137 # share the same name works.
138 self
.expect_expr("mine.propConflict", result_value
="4")
139 self
.expect_expr("BaseClass.propConflict", result_value
="6")