mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-11 20:26:05 +00:00

By default these timeouts are extremely small (0.1s). This means that 100ms after sending an EOF, pexpect will start sending the process increasingly aggressive signals, but the small timeouts mean that (on a loaded machine) the kernel may not have enough time to process the signal even if the overall effect of the signal is to kill the application. It turns out we were already relying on this signals (instead of regular EOF quits) in our tests. In my experiments it was sufficient to block SIGINT and SIGHUP to cause some test to become flaky. This was most likely the reason of a couple of flakes on the lldb-x86_64-debian bot, and is probably the reason why the pexpect tests are flaky on several other (e.g. asan) bots. This patch increses the timeout to 6 seconds (60-fold increase), which is hopefully sufficient to avoid flakes even in the most extreme situations.
88 lines
2.7 KiB
Python
88 lines
2.7 KiB
Python
from __future__ import absolute_import
|
|
|
|
# System modules
|
|
import os
|
|
import sys
|
|
|
|
# Third-party modules
|
|
import six
|
|
|
|
# LLDB Modules
|
|
import lldb
|
|
from .lldbtest import *
|
|
from . import lldbutil
|
|
from lldbsuite.test.decorators import *
|
|
|
|
@skipIfRemote
|
|
@skipIfWindows # llvm.org/pr22274: need a pexpect replacement for windows
|
|
class PExpectTest(TestBase):
|
|
|
|
NO_DEBUG_INFO_TESTCASE = True
|
|
PROMPT = "(lldb) "
|
|
|
|
def expect_prompt(self):
|
|
self.child.expect_exact(self.PROMPT)
|
|
|
|
def launch(self, executable=None, extra_args=None, timeout=60,
|
|
dimensions=None, run_under=None, post_spawn=None):
|
|
logfile = getattr(sys.stdout, 'buffer',
|
|
sys.stdout) if self.TraceOn() else None
|
|
|
|
args = []
|
|
if run_under is not None:
|
|
args += run_under
|
|
args += [lldbtest_config.lldbExec, '--no-lldbinit', '--no-use-colors']
|
|
for cmd in self.setUpCommands():
|
|
args += ['-O', cmd]
|
|
if executable is not None:
|
|
args += ['--file', executable]
|
|
if extra_args is not None:
|
|
args.extend(extra_args)
|
|
|
|
env = dict(os.environ)
|
|
env["TERM"] = "vt100"
|
|
env["HOME"] = self.getBuildDir()
|
|
|
|
import pexpect
|
|
self.child = pexpect.spawn(
|
|
args[0], args=args[1:], logfile=logfile,
|
|
timeout=timeout, dimensions=dimensions, env=env)
|
|
self.child.ptyproc.delayafterclose = timeout/10
|
|
self.child.ptyproc.delayafterterminate = timeout/10
|
|
|
|
if post_spawn is not None:
|
|
post_spawn()
|
|
self.expect_prompt()
|
|
for cmd in self.setUpCommands():
|
|
self.child.expect_exact(cmd)
|
|
self.expect_prompt()
|
|
if executable is not None:
|
|
self.child.expect_exact("target create")
|
|
self.child.expect_exact("Current executable set to")
|
|
self.expect_prompt()
|
|
|
|
def expect(self, cmd, substrs=None):
|
|
self.assertNotIn('\n', cmd)
|
|
# If 'substrs' is a string then this code would just check that every
|
|
# character of the string is in the output.
|
|
assert not isinstance(substrs, six.string_types), \
|
|
"substrs must be a collection of strings"
|
|
|
|
self.child.sendline(cmd)
|
|
if substrs is not None:
|
|
for s in substrs:
|
|
self.child.expect_exact(s)
|
|
self.expect_prompt()
|
|
|
|
def quit(self, gracefully=True):
|
|
self.child.sendeof()
|
|
self.child.close(force=not gracefully)
|
|
self.child = None
|
|
|
|
def cursor_forward_escape_seq(self, chars_to_move):
|
|
"""
|
|
Returns the escape sequence to move the cursor forward/right
|
|
by a certain amount of characters.
|
|
"""
|
|
return b"\x1b\[" + str(chars_to_move).encode("utf-8") + b"C"
|