xref: /llvm-project/lldb/packages/Python/lldbsuite/test/lldbpexpect.py (revision 8bed754c2f965c8cbbb050be6f650b78f7fd78a6)
1# System modules
2import os
3import sys
4
5# LLDB Modules
6import lldb
7from .lldbtest import *
8from . import lldbutil
9from lldbsuite.test.decorators import *
10
11
12@skipIfRemote
13@add_test_categories(["pexpect"])
14class PExpectTest(TestBase):
15    NO_DEBUG_INFO_TESTCASE = True
16    PROMPT = "(lldb) "
17
18    def expect_prompt(self):
19        self.child.expect_exact(self.PROMPT)
20
21    def launch(
22        self,
23        executable=None,
24        extra_args=None,
25        timeout=60,
26        dimensions=None,
27        run_under=None,
28        post_spawn=None,
29        encoding=None,
30        use_colors=False,
31    ):
32        # Using a log file is incompatible with using utf-8 as the encoding.
33        logfile = (
34            getattr(sys.stdout, "buffer", sys.stdout)
35            if (self.TraceOn() and not encoding)
36            else None
37        )
38
39        args = []
40        if run_under is not None:
41            args += run_under
42        args += [lldbtest_config.lldbExec, "--no-lldbinit"]
43        if not use_colors:
44            args.append("--no-use-colors")
45        for cmd in self.setUpCommands():
46            if "use-color false" in cmd and use_colors:
47                continue
48            args += ["-O", cmd]
49        if executable is not None:
50            args += ["--file", executable]
51        if extra_args is not None:
52            args.extend(extra_args)
53
54        env = dict(os.environ)
55        env["TERM"] = "vt100"
56        env["HOME"] = self.getBuildDir()
57
58        import pexpect
59
60        self.child = pexpect.spawn(
61            args[0],
62            args=args[1:],
63            logfile=logfile,
64            timeout=timeout,
65            dimensions=dimensions,
66            env=env,
67            encoding=encoding,
68        )
69        self.child.ptyproc.delayafterclose = timeout / 10
70        self.child.ptyproc.delayafterterminate = timeout / 10
71
72        if post_spawn is not None:
73            post_spawn()
74        self.expect_prompt()
75        for cmd in self.setUpCommands():
76            if "use-color false" in cmd and use_colors:
77                continue
78            self.child.expect_exact(cmd)
79            self.expect_prompt()
80        if executable is not None:
81            self.child.expect_exact("target create")
82            self.child.expect_exact("Current executable set to")
83            self.expect_prompt()
84
85    def expect(self, cmd, substrs=None):
86        self.assertNotIn("\n", cmd)
87        # If 'substrs' is a string then this code would just check that every
88        # character of the string is in the output.
89        assert not isinstance(substrs, str), "substrs must be a collection of strings"
90
91        self.child.sendline(cmd)
92        if substrs is not None:
93            for s in substrs:
94                self.child.expect_exact(s)
95        self.expect_prompt()
96
97    def quit(self, gracefully=True):
98        self.child.sendeof()
99        self.child.close(force=not gracefully)
100        self.child = None
101
102    def cursor_forward_escape_seq(self, chars_to_move):
103        """
104        Returns the escape sequence to move the cursor forward/right
105        by a certain amount of characters.
106        """
107        return b"\x1b\[" + str(chars_to_move).encode("utf-8") + b"C"
108