1049ae930SJonas Devlieghere"""
2049ae930SJonas DevlieghereTest sending SIGINT to the embedded Python REPL.
3049ae930SJonas Devlieghere"""
4049ae930SJonas Devlieghere
5049ae930SJonas Devlieghereimport os
6049ae930SJonas Devlieghere
7049ae930SJonas Devlieghereimport lldb
8049ae930SJonas Devliegherefrom lldbsuite.test.decorators import *
9049ae930SJonas Devliegherefrom lldbsuite.test.lldbtest import *
10049ae930SJonas Devliegherefrom lldbsuite.test.lldbpexpect import PExpectTest
11049ae930SJonas Devlieghere
12049ae930SJonas Devlieghereclass TestCase(PExpectTest):
13049ae930SJonas Devlieghere
14049ae930SJonas Devlieghere    mydir = TestBase.compute_mydir(__file__)
15049ae930SJonas Devlieghere
16049ae930SJonas Devlieghere    def start_python_repl(self):
17049ae930SJonas Devlieghere        """ Starts up the embedded Python REPL."""
18049ae930SJonas Devlieghere        self.launch()
19049ae930SJonas Devlieghere        # Start the embedded Python REPL via the 'script' command.
20049ae930SJonas Devlieghere        self.child.send("script -l python --\n")
21049ae930SJonas Devlieghere        # Wait for the Python REPL prompt.
22049ae930SJonas Devlieghere        self.child.expect(">>>")
23049ae930SJonas Devlieghere
24049ae930SJonas Devlieghere    # PExpect uses many timeouts internally and doesn't play well
25049ae930SJonas Devlieghere    # under ASAN on a loaded machine..
26049ae930SJonas Devlieghere    @skipIfAsan
27049ae930SJonas Devlieghere    @skipIfWindows
28*df13239cSMuhammad Omair Javaid    @skipIf(oslist=["linux"], archs=["arm", "aarch64"])
29049ae930SJonas Devlieghere    def test_while_evaluating_code(self):
30049ae930SJonas Devlieghere        """ Tests SIGINT handling while Python code is being evaluated."""
31049ae930SJonas Devlieghere        self.start_python_repl()
32049ae930SJonas Devlieghere
33049ae930SJonas Devlieghere        # Start a long-running command that we try to abort with SIGINT.
34049ae930SJonas Devlieghere        # Note that we dont actually wait 10000s in this code as pexpect or
35049ae930SJonas Devlieghere        # lit will kill the test way before that.
36049ae930SJonas Devlieghere        self.child.send("import time; print('running' + 'now'); time.sleep(10000);\n")
37049ae930SJonas Devlieghere
38049ae930SJonas Devlieghere        # Make sure the command is actually being evaluated at the moment by
39049ae930SJonas Devlieghere        # looking at the string that the command is printing.
40049ae930SJonas Devlieghere        # Don't check for a needle that also occurs in the program itself to
41049ae930SJonas Devlieghere        # prevent that echoing will make this check pass unintentionally.
42049ae930SJonas Devlieghere        self.child.expect("runningnow")
43049ae930SJonas Devlieghere
44049ae930SJonas Devlieghere        # Send SIGINT to the LLDB process.
45049ae930SJonas Devlieghere        self.child.sendintr()
46049ae930SJonas Devlieghere
47049ae930SJonas Devlieghere        # This should get transformed to a KeyboardInterrupt which is the same
48049ae930SJonas Devlieghere        # behaviour as the standalone Python REPL. It should also interrupt
49049ae930SJonas Devlieghere        # the evaluation of our sleep statement.
50049ae930SJonas Devlieghere        self.child.expect("KeyboardInterrupt")
51049ae930SJonas Devlieghere        # Send EOF to quit the Python REPL.
52049ae930SJonas Devlieghere        self.child.sendeof()
53049ae930SJonas Devlieghere
54049ae930SJonas Devlieghere        self.quit()
55049ae930SJonas Devlieghere
56049ae930SJonas Devlieghere    # PExpect uses many timeouts internally and doesn't play well
57049ae930SJonas Devlieghere    # under ASAN on a loaded machine..
58049ae930SJonas Devlieghere    @skipIfAsan
59049ae930SJonas Devlieghere    # FIXME: On Linux the Python code that reads from stdin seems to block until
60049ae930SJonas Devlieghere    # it has finished reading a line before handling any queued signals.
61049ae930SJonas Devlieghere    @skipIfLinux
62049ae930SJonas Devlieghere    @skipIfWindows
63049ae930SJonas Devlieghere    def test_while_waiting_on_input(self):
64049ae930SJonas Devlieghere        """ Tests SIGINT handling while the REPL is waiting on input from
65049ae930SJonas Devlieghere        stdin."""
66049ae930SJonas Devlieghere        self.start_python_repl()
67049ae930SJonas Devlieghere
68049ae930SJonas Devlieghere        # Send SIGINT to the LLDB process.
69049ae930SJonas Devlieghere        self.child.sendintr()
70049ae930SJonas Devlieghere        # This should get transformed to a KeyboardInterrupt which is the same
71049ae930SJonas Devlieghere        # behaviour as the standalone Python REPL.
72049ae930SJonas Devlieghere        self.child.expect("KeyboardInterrupt")
73049ae930SJonas Devlieghere        # Send EOF to quit the Python REPL.
74049ae930SJonas Devlieghere        self.child.sendeof()
75049ae930SJonas Devlieghere
76049ae930SJonas Devlieghere        self.quit()
77