Pavel Labath 56fb745695 [lldb/test] Increase pexpect termination timeouts
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.
2022-03-22 15:14:21 +01:00

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"