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