199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest lldb Python commands.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprechtimport sys
799451b44SJordan Rupprechtimport lldb
899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1099451b44SJordan Rupprecht
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprechtclass CmdPythonTestCase(TestBase):
1399451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht    def test(self):
1699451b44SJordan Rupprecht        self.build()
1799451b44SJordan Rupprecht        self.pycmd_tests()
1899451b44SJordan Rupprecht
1999451b44SJordan Rupprecht    def pycmd_tests(self):
2099451b44SJordan Rupprecht        self.runCmd("command source py_import")
2199451b44SJordan Rupprecht
2299451b44SJordan Rupprecht        # Test a bunch of different kinds of python callables with
2399451b44SJordan Rupprecht        # both 4 and 5 positional arguments.
2499451b44SJordan Rupprecht        self.expect("foobar", substrs=["All good"])
2599451b44SJordan Rupprecht        self.expect("foobar4", substrs=["All good"])
2699451b44SJordan Rupprecht        self.expect("vfoobar", substrs=["All good"])
2799451b44SJordan Rupprecht        self.expect("v5foobar", substrs=["All good"])
2899451b44SJordan Rupprecht        self.expect("sfoobar", substrs=["All good"])
2999451b44SJordan Rupprecht        self.expect("cfoobar", substrs=["All good"])
3099451b44SJordan Rupprecht        self.expect("ifoobar", substrs=["All good"])
3199451b44SJordan Rupprecht        self.expect("sfoobar4", substrs=["All good"])
3299451b44SJordan Rupprecht        self.expect("cfoobar4", substrs=["All good"])
3399451b44SJordan Rupprecht        self.expect("ifoobar4", substrs=["All good"])
3499451b44SJordan Rupprecht        self.expect("ofoobar", substrs=["All good"])
3599451b44SJordan Rupprecht        self.expect("ofoobar4", substrs=["All good"])
3699451b44SJordan Rupprecht
3799451b44SJordan Rupprecht        # Verify command that specifies eCommandRequiresTarget returns failure
3899451b44SJordan Rupprecht        # without a target.
3999451b44SJordan Rupprecht        self.expect('targetname',
4099451b44SJordan Rupprecht                    substrs=['a.out'], matching=False, error=True)
4199451b44SJordan Rupprecht
4299451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
4399451b44SJordan Rupprecht        self.expect("file " + exe,
4499451b44SJordan Rupprecht                    patterns=["Current executable set to .*a.out"])
4599451b44SJordan Rupprecht
4699451b44SJordan Rupprecht        self.expect('targetname',
4799451b44SJordan Rupprecht                    substrs=['a.out'], matching=True, error=False)
4899451b44SJordan Rupprecht
4999451b44SJordan Rupprecht        # This is the function to remove the custom commands in order to have a
5099451b44SJordan Rupprecht        # clean slate for the next test case.
5199451b44SJordan Rupprecht        def cleanup():
5299451b44SJordan Rupprecht            self.runCmd('command script delete welcome', check=False)
5399451b44SJordan Rupprecht            self.runCmd('command script delete targetname', check=False)
5499451b44SJordan Rupprecht            self.runCmd('command script delete longwait', check=False)
5599451b44SJordan Rupprecht            self.runCmd('command script delete mysto', check=False)
5699451b44SJordan Rupprecht            self.runCmd('command script delete tell_sync', check=False)
5799451b44SJordan Rupprecht            self.runCmd('command script delete tell_async', check=False)
5899451b44SJordan Rupprecht            self.runCmd('command script delete tell_curr', check=False)
5999451b44SJordan Rupprecht            self.runCmd('command script delete bug11569', check=False)
6099451b44SJordan Rupprecht            self.runCmd('command script delete takes_exe_ctx', check=False)
6199451b44SJordan Rupprecht            self.runCmd('command script delete decorated', check=False)
6299451b44SJordan Rupprecht
6399451b44SJordan Rupprecht        # Execute the cleanup function during test case tear down.
6499451b44SJordan Rupprecht        self.addTearDownHook(cleanup)
6599451b44SJordan Rupprecht
6699451b44SJordan Rupprecht        # Interact with debugger in synchronous mode
6799451b44SJordan Rupprecht        self.setAsync(False)
6899451b44SJordan Rupprecht
6999451b44SJordan Rupprecht        # We don't want to display the stdout if not in TraceOn() mode.
7099451b44SJordan Rupprecht        if not self.TraceOn():
7199451b44SJordan Rupprecht            self.HideStdout()
7299451b44SJordan Rupprecht
7399451b44SJordan Rupprecht        self.expect('welcome Enrico',
7499451b44SJordan Rupprecht                    substrs=['Hello Enrico, welcome to LLDB'])
7599451b44SJordan Rupprecht
7699451b44SJordan Rupprecht        self.expect("help welcome",
7799451b44SJordan Rupprecht                    substrs=['Just a docstring for welcome_impl',
7899451b44SJordan Rupprecht                             'A command that says hello to LLDB users'])
7999451b44SJordan Rupprecht
8099451b44SJordan Rupprecht        decorated_commands = ["decorated" + str(n) for n in range(1, 5)]
8199451b44SJordan Rupprecht        for name in decorated_commands:
8299451b44SJordan Rupprecht            self.expect(name, substrs=["hello from " + name])
8399451b44SJordan Rupprecht            self.expect("help " + name,
8499451b44SJordan Rupprecht                        substrs=["Python command defined by @lldb.command"])
8599451b44SJordan Rupprecht
8699451b44SJordan Rupprecht        self.expect("help",
8799451b44SJordan Rupprecht                    substrs=['For more information run']
8899451b44SJordan Rupprecht                             + decorated_commands + ['welcome'])
8999451b44SJordan Rupprecht
9099451b44SJordan Rupprecht        self.expect("help -a",
9199451b44SJordan Rupprecht                    substrs=['For more information run']
9299451b44SJordan Rupprecht                             + decorated_commands + ['welcome'])
9399451b44SJordan Rupprecht
9499451b44SJordan Rupprecht        self.expect("help -u", matching=False,
9599451b44SJordan Rupprecht                    substrs=['For more information run'])
9699451b44SJordan Rupprecht
9799451b44SJordan Rupprecht        self.runCmd("command script delete welcome")
9899451b44SJordan Rupprecht
9999451b44SJordan Rupprecht        self.expect('welcome Enrico', matching=False, error=True,
10099451b44SJordan Rupprecht                    substrs=['Hello Enrico, welcome to LLDB'])
10199451b44SJordan Rupprecht
10299451b44SJordan Rupprecht        self.expect('targetname fail', error=True,
10399451b44SJordan Rupprecht                    substrs=['a test for error in command'])
10499451b44SJordan Rupprecht
10599451b44SJordan Rupprecht        self.expect('command script list',
10699451b44SJordan Rupprecht                    substrs=['targetname',
10799451b44SJordan Rupprecht                             'For more information run'])
10899451b44SJordan Rupprecht
10999451b44SJordan Rupprecht        self.expect("help targetname",
11099451b44SJordan Rupprecht                    substrs=['Expects', '\'raw\'', 'input',
11199451b44SJordan Rupprecht                             'help', 'raw-input'])
11299451b44SJordan Rupprecht
11399451b44SJordan Rupprecht        self.expect("longwait",
11499451b44SJordan Rupprecht                    substrs=['Done; if you saw the delays I am doing OK'])
11599451b44SJordan Rupprecht
116*dd01d9aaSMuhammad Omair Javaid        self.runCmd("break set -f main.cpp -l 48")
11799451b44SJordan Rupprecht        self.runCmd("run")
11899451b44SJordan Rupprecht        self.runCmd("mysto 3")
11999451b44SJordan Rupprecht        self.expect("frame variable array",
12099451b44SJordan Rupprecht                    substrs=['[0] = 79630', '[1] = 388785018', '[2] = 0'])
12199451b44SJordan Rupprecht        self.runCmd("mysto 3")
12299451b44SJordan Rupprecht        self.expect("frame variable array",
12399451b44SJordan Rupprecht                    substrs=['[0] = 79630', '[4] = 388785018', '[5] = 0'])
12499451b44SJordan Rupprecht
12599451b44SJordan Rupprecht# we cannot use the stepover command to check for async execution mode since LLDB
12699451b44SJordan Rupprecht# seems to get confused when events start to queue up
12799451b44SJordan Rupprecht        self.expect("tell_sync",
12899451b44SJordan Rupprecht                    substrs=['running sync'])
12999451b44SJordan Rupprecht        self.expect("tell_async",
13099451b44SJordan Rupprecht                    substrs=['running async'])
13199451b44SJordan Rupprecht        self.expect("tell_curr",
13299451b44SJordan Rupprecht                    substrs=['I am running sync'])
13399451b44SJordan Rupprecht
13499451b44SJordan Rupprecht# check that the execution context is passed in to commands that ask for it
13599451b44SJordan Rupprecht        self.expect("takes_exe_ctx", substrs=["a.out"])
13699451b44SJordan Rupprecht
13799451b44SJordan Rupprecht        # Test that a python command can redefine itself
13899451b44SJordan Rupprecht        self.expect('command script add -f foobar welcome -h "just some help"')
13999451b44SJordan Rupprecht
14099451b44SJordan Rupprecht        self.runCmd("command script clear")
14199451b44SJordan Rupprecht
14299451b44SJordan Rupprecht        # Test that re-defining an existing command works
14399451b44SJordan Rupprecht        self.runCmd(
14499451b44SJordan Rupprecht            'command script add my_command --class welcome.WelcomeCommand')
14599451b44SJordan Rupprecht        self.expect('my_command Blah', substrs=['Hello Blah, welcome to LLDB'])
14699451b44SJordan Rupprecht
14799451b44SJordan Rupprecht        self.runCmd(
148c5011aedSJim Ingham            'command script add my_command -o --class welcome.TargetnameCommand')
14999451b44SJordan Rupprecht        self.expect('my_command', substrs=['a.out'])
15099451b44SJordan Rupprecht
15199451b44SJordan Rupprecht        self.runCmd("command script clear")
15299451b44SJordan Rupprecht
15399451b44SJordan Rupprecht        self.expect('command script list', matching=False,
15499451b44SJordan Rupprecht                    substrs=['targetname',
15599451b44SJordan Rupprecht                             'longwait'])
15699451b44SJordan Rupprecht
15799451b44SJordan Rupprecht        self.expect('command script add -f foobar frame', error=True,
15899451b44SJordan Rupprecht                    substrs=['cannot add command'])
15999451b44SJordan Rupprecht
16099451b44SJordan Rupprecht        # http://llvm.org/bugs/show_bug.cgi?id=11569
16199451b44SJordan Rupprecht        # LLDBSwigPythonCallCommand crashes when a command script returns an
16299451b44SJordan Rupprecht        # object
16399451b44SJordan Rupprecht        self.runCmd('command script add -f bug11569 bug11569')
16499451b44SJordan Rupprecht        # This should not crash.
16599451b44SJordan Rupprecht        self.runCmd('bug11569', check=False)
1667406d236SPavel Labath
1677406d236SPavel Labath    def test_persistence(self):
1680a07c966SPavel Labath        """
1690a07c966SPavel Labath        Ensure that function arguments meaningfully persist (and do not crash!)
1700a07c966SPavel Labath        even after the function terminates.
1710a07c966SPavel Labath        """
1727406d236SPavel Labath        self.runCmd("command script import persistence.py")
1737406d236SPavel Labath        self.runCmd("command script add -f persistence.save_debugger save_debugger")
1747406d236SPavel Labath        self.expect("save_debugger", substrs=[str(self.dbg)])
1750a07c966SPavel Labath
1760a07c966SPavel Labath        # After the command completes, the debugger object should still be
1770a07c966SPavel Labath        # valid.
1787406d236SPavel Labath        self.expect("script str(persistence.debugger_copy)", substrs=[str(self.dbg)])
1790a07c966SPavel Labath        # The result object will be replaced by an empty result object (in the
1800a07c966SPavel Labath        # "Started" state).
1810a07c966SPavel Labath        self.expect("script str(persistence.result_copy)", substrs=["Started"])
182