xref: /llvm-project/lldb/test/API/python_api/interpreter/TestRunCommandInterpreterAPI.py (revision 435dd9746107e13c2ad019be3bd34815f7d2360d)
1"""Test the RunCommandInterpreter API."""
2
3import os
4import lldb
5from lldbsuite.test.decorators import *
6from lldbsuite.test.lldbtest import *
7
8
9class CommandRunInterpreterLegacyAPICase(TestBase):
10    NO_DEBUG_INFO_TESTCASE = True
11
12    def setUp(self):
13        TestBase.setUp(self)
14
15        self.stdin_path = self.getBuildArtifact("stdin.txt")
16
17        with open(self.stdin_path, "w") as input_handle:
18            input_handle.write("nonexistingcommand\nquit")
19
20        # Python will close the file descriptor if all references
21        # to the filehandle object lapse, so we need to keep one
22        # around.
23        self.filehandle = open(self.stdin_path, "r")
24        self.dbg.SetInputFileHandle(self.filehandle, False)
25
26        # No need to track the output
27        self.devnull = open(os.devnull, "w")
28        self.dbg.SetOutputFileHandle(self.devnull, False)
29        self.dbg.SetErrorFileHandle(self.devnull, False)
30
31    def test_run_session_with_error_and_quit_legacy(self):
32        """Run non-existing and quit command returns appropriate values"""
33
34        n_errors, quit_requested, has_crashed = self.dbg.RunCommandInterpreter(
35            True, False, lldb.SBCommandInterpreterRunOptions(), 0, False, False
36        )
37
38        self.assertGreater(n_errors, 0)
39        self.assertTrue(quit_requested)
40        self.assertFalse(has_crashed)
41
42
43class CommandRunInterpreterAPICase(TestBase):
44    NO_DEBUG_INFO_TESTCASE = True
45
46    def setUp(self):
47        TestBase.setUp(self)
48
49        self.stdin_path = self.getBuildArtifact("stdin.txt")
50        self.stdout_path = self.getBuildArtifact("stdout.txt")
51
52    def run_commands_string(
53        self, command_string, options=lldb.SBCommandInterpreterRunOptions()
54    ):
55        """Run the commands in command_string through RunCommandInterpreter.
56        Returns (n_errors, quit_requested, has_crashed, result_string)."""
57
58        with open(self.stdin_path, "w") as input_handle:
59            input_handle.write(command_string)
60
61        n_errors = 0
62        quit_requested = False
63        has_crashed = False
64
65        with open(self.stdin_path, "r") as in_fileH, open(
66            self.stdout_path, "w"
67        ) as out_fileH:
68            self.dbg.SetInputFile(in_fileH)
69
70            self.dbg.SetOutputFile(out_fileH)
71            self.dbg.SetErrorFile(out_fileH)
72
73            n_errors, quit_requested, has_crashed = self.dbg.RunCommandInterpreter(
74                True, False, options, 0, False, False
75            )
76
77        result_string = None
78        with open(self.stdout_path, "r") as out_fileH:
79            result_string = out_fileH.read()
80
81        return (n_errors, quit_requested, has_crashed, result_string)
82
83    def test_run_session_with_error_and_quit(self):
84        """Run non-existing and quit command returns appropriate values"""
85
86        n_errors, quit_requested, has_crashed, _ = self.run_commands_string(
87            "nonexistingcommand\nquit\n"
88        )
89        self.assertGreater(n_errors, 0)
90        self.assertTrue(quit_requested)
91        self.assertFalse(has_crashed)
92
93    def test_allow_repeat(self):
94        """Try auto-repeat of process launch - the command will fail and
95        the auto-repeat will fail because of no auto-repeat."""
96        options = lldb.SBCommandInterpreterRunOptions()
97        options.SetEchoCommands(False)
98        options.SetAllowRepeats(True)
99
100        n_errors, quit_requested, has_crashed, result_str = self.run_commands_string(
101            "process launch\n\n", options
102        )
103        self.assertEqual(n_errors, 2)
104        self.assertFalse(quit_requested)
105        self.assertFalse(has_crashed)
106
107        self.assertIn("invalid target", result_str)
108        self.assertIn("No auto repeat", result_str)
109
110
111class SBCommandInterpreterRunOptionsCase(TestBase):
112    NO_DEBUG_INFO_TESTCASE = True
113
114    def test_command_interpreter_run_options(self):
115        """Test SBCommandInterpreterRunOptions default values, getters & setters"""
116
117        opts = lldb.SBCommandInterpreterRunOptions()
118
119        # Check getters with default values
120        self.assertFalse(opts.GetStopOnContinue())
121        self.assertFalse(opts.GetStopOnError())
122        self.assertFalse(opts.GetStopOnCrash())
123        self.assertTrue(opts.GetEchoCommands())
124        self.assertTrue(opts.GetPrintResults())
125        self.assertTrue(opts.GetPrintErrors())
126        self.assertTrue(opts.GetAddToHistory())
127        self.assertFalse(opts.GetAllowRepeats())
128
129        # Invert values
130        opts.SetStopOnContinue(not opts.GetStopOnContinue())
131        opts.SetStopOnError(not opts.GetStopOnError())
132        opts.SetStopOnCrash(not opts.GetStopOnCrash())
133        opts.SetEchoCommands(not opts.GetEchoCommands())
134        opts.SetPrintResults(not opts.GetPrintResults())
135        opts.SetPrintErrors(not opts.GetPrintErrors())
136        opts.SetAddToHistory(not opts.GetAddToHistory())
137        opts.SetAllowRepeats(not opts.GetAllowRepeats())
138
139        # Check the value changed
140        self.assertTrue(opts.GetStopOnContinue())
141        self.assertTrue(opts.GetStopOnError())
142        self.assertTrue(opts.GetStopOnCrash())
143        self.assertFalse(opts.GetEchoCommands())
144        self.assertFalse(opts.GetPrintResults())
145        self.assertFalse(opts.GetPrintErrors())
146        self.assertFalse(opts.GetAddToHistory())
147        self.assertTrue(opts.GetAllowRepeats())
148