xref: /llvm-project/lldb/test/API/commands/command/script/TestCommandScript.py (revision 1e566f6b47fb77812d99c93e0a1b8613d288058c)
1"""
2Test lldb Python commands.
3"""
4
5
6import sys
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10
11
12class CmdPythonTestCase(TestBase):
13
14    mydir = TestBase.compute_mydir(__file__)
15    NO_DEBUG_INFO_TESTCASE = True
16
17    @skipIfReproducer # Unexpected packet during replay
18    def test(self):
19        self.build()
20        self.pycmd_tests()
21
22    def pycmd_tests(self):
23        self.runCmd("command source py_import")
24
25        # Test a bunch of different kinds of python callables with
26        # both 4 and 5 positional arguments.
27        self.expect("foobar", substrs=["All good"])
28        self.expect("foobar4", substrs=["All good"])
29        self.expect("vfoobar", substrs=["All good"])
30        self.expect("v5foobar", substrs=["All good"])
31        self.expect("sfoobar", substrs=["All good"])
32        self.expect("cfoobar", substrs=["All good"])
33        self.expect("ifoobar", substrs=["All good"])
34        self.expect("sfoobar4", substrs=["All good"])
35        self.expect("cfoobar4", substrs=["All good"])
36        self.expect("ifoobar4", substrs=["All good"])
37        self.expect("ofoobar", substrs=["All good"])
38        self.expect("ofoobar4", substrs=["All good"])
39
40        # Verify command that specifies eCommandRequiresTarget returns failure
41        # without a target.
42        self.expect('targetname',
43                    substrs=['a.out'], matching=False, error=True)
44
45        exe = self.getBuildArtifact("a.out")
46        self.expect("file " + exe,
47                    patterns=["Current executable set to .*a.out"])
48
49        self.expect('targetname',
50                    substrs=['a.out'], matching=True, error=False)
51
52        # This is the function to remove the custom commands in order to have a
53        # clean slate for the next test case.
54        def cleanup():
55            self.runCmd('command script delete welcome', check=False)
56            self.runCmd('command script delete targetname', check=False)
57            self.runCmd('command script delete longwait', check=False)
58            self.runCmd('command script delete mysto', check=False)
59            self.runCmd('command script delete tell_sync', check=False)
60            self.runCmd('command script delete tell_async', check=False)
61            self.runCmd('command script delete tell_curr', check=False)
62            self.runCmd('command script delete bug11569', check=False)
63            self.runCmd('command script delete takes_exe_ctx', check=False)
64            self.runCmd('command script delete decorated', check=False)
65
66        # Execute the cleanup function during test case tear down.
67        self.addTearDownHook(cleanup)
68
69        # Interact with debugger in synchronous mode
70        self.setAsync(False)
71
72        # We don't want to display the stdout if not in TraceOn() mode.
73        if not self.TraceOn():
74            self.HideStdout()
75
76        self.expect('welcome Enrico',
77                    substrs=['Hello Enrico, welcome to LLDB'])
78
79        self.expect("help welcome",
80                    substrs=['Just a docstring for welcome_impl',
81                             'A command that says hello to LLDB users'])
82
83        decorated_commands = ["decorated" + str(n) for n in range(1, 5)]
84        for name in decorated_commands:
85            self.expect(name, substrs=["hello from " + name])
86            self.expect("help " + name,
87                        substrs=["Python command defined by @lldb.command"])
88
89        self.expect("help",
90                    substrs=['For more information run']
91                             + decorated_commands + ['welcome'])
92
93        self.expect("help -a",
94                    substrs=['For more information run']
95                             + decorated_commands + ['welcome'])
96
97        self.expect("help -u", matching=False,
98                    substrs=['For more information run'])
99
100        self.runCmd("command script delete welcome")
101
102        self.expect('welcome Enrico', matching=False, error=True,
103                    substrs=['Hello Enrico, welcome to LLDB'])
104
105        self.expect('targetname fail', error=True,
106                    substrs=['a test for error in command'])
107
108        self.expect('command script list',
109                    substrs=['targetname',
110                             'For more information run'])
111
112        self.expect("help targetname",
113                    substrs=['Expects', '\'raw\'', 'input',
114                             'help', 'raw-input'])
115
116        self.expect("longwait",
117                    substrs=['Done; if you saw the delays I am doing OK'])
118
119        self.runCmd("b main")
120        self.runCmd("run")
121        self.runCmd("mysto 3")
122        self.expect("frame variable array",
123                    substrs=['[0] = 79630', '[1] = 388785018', '[2] = 0'])
124        self.runCmd("mysto 3")
125        self.expect("frame variable array",
126                    substrs=['[0] = 79630', '[4] = 388785018', '[5] = 0'])
127
128# we cannot use the stepover command to check for async execution mode since LLDB
129# seems to get confused when events start to queue up
130        self.expect("tell_sync",
131                    substrs=['running sync'])
132        self.expect("tell_async",
133                    substrs=['running async'])
134        self.expect("tell_curr",
135                    substrs=['I am running sync'])
136
137# check that the execution context is passed in to commands that ask for it
138        self.expect("takes_exe_ctx", substrs=["a.out"])
139
140        # Test that a python command can redefine itself
141        self.expect('command script add -f foobar welcome -h "just some help"')
142
143        self.runCmd("command script clear")
144
145        # Test that re-defining an existing command works
146        self.runCmd(
147            'command script add my_command --class welcome.WelcomeCommand')
148        self.expect('my_command Blah', substrs=['Hello Blah, welcome to LLDB'])
149
150        self.runCmd(
151            'command script add my_command --class welcome.TargetnameCommand')
152        self.expect('my_command', substrs=['a.out'])
153
154        self.runCmd("command script clear")
155
156        self.expect('command script list', matching=False,
157                    substrs=['targetname',
158                             'longwait'])
159
160        self.expect('command script add -f foobar frame', error=True,
161                    substrs=['cannot add command'])
162
163        # http://llvm.org/bugs/show_bug.cgi?id=11569
164        # LLDBSwigPythonCallCommand crashes when a command script returns an
165        # object
166        self.runCmd('command script add -f bug11569 bug11569')
167        # This should not crash.
168        self.runCmd('bug11569', check=False)
169