From 9e2d329818b71050ad397cc3393517646e9311cc Mon Sep 17 00:00:00 2001 From: Todd Fiala Date: Wed, 9 Jul 2014 23:10:43 +0000 Subject: [PATCH] Skip tests that are intermittent on Linux, fix gdb-remote port-grabbing code. Marked skipped for Linux: TestCallStopAndContinue TestConvenienceVariables TestStopHookMultipleThreads Fixed up gdb-remote port-grabbing code to use a random port in a wide range, and to allow that to fail more gracefully. This appears to have solved some gdb-remote intermittent failing behavior. llvm-svn: 212662 --- .../call-function/TestCallStopAndContinue.py | 1 + .../timeout/TestCallWithTimeout.py | 1 + .../TestConvenienceVariables.py | 1 + .../TestStopHookMultipleThreads.py | 2 +- .../tools/lldb-gdbserver/gdbremote_testcase.py | 76 ++++++++++++---------- 5 files changed, 47 insertions(+), 34 deletions(-) diff --git a/lldb/test/expression_command/call-function/TestCallStopAndContinue.py b/lldb/test/expression_command/call-function/TestCallStopAndContinue.py index b00778e..d3bb94a 100644 --- a/lldb/test/expression_command/call-function/TestCallStopAndContinue.py +++ b/lldb/test/expression_command/call-function/TestCallStopAndContinue.py @@ -30,6 +30,7 @@ class ExprCommandCallStopContinueTestCase(TestBase): @dwarf_test @skipIfDarwin # see llvm.org/pr20274 - intermittent failure on MacOSX + @skipIfLinux # see llvm.org/pr20274 - intermittent failure on Linux def test_with_dwarf(self): """Test gathering result from interrupted function call.""" self.buildDwarf() diff --git a/lldb/test/expression_command/timeout/TestCallWithTimeout.py b/lldb/test/expression_command/timeout/TestCallWithTimeout.py index 96c8364..e3ed83d 100644 --- a/lldb/test/expression_command/timeout/TestCallWithTimeout.py +++ b/lldb/test/expression_command/timeout/TestCallWithTimeout.py @@ -27,6 +27,7 @@ class ExprCommandWithTimeoutsTestCase(TestBase): self.call_function() @expectedFailureFreeBSD("llvm.org/pr19605") # fails on buildbot + @skipIfLinux # llvm.org/pr20275 - fails intermittently on Linux @dwarf_test def test_with_dwarf(self): """Test calling std::String member function.""" diff --git a/lldb/test/functionalities/embedded_interpreter/TestConvenienceVariables.py b/lldb/test/functionalities/embedded_interpreter/TestConvenienceVariables.py index 71870e3..1325483 100644 --- a/lldb/test/functionalities/embedded_interpreter/TestConvenienceVariables.py +++ b/lldb/test/functionalities/embedded_interpreter/TestConvenienceVariables.py @@ -19,6 +19,7 @@ class ConvenienceVariablesCase(TestBase): @dwarf_test @skipIfFreeBSD # llvm.org/pr17228 + @skipIfLinux # llvm.org/pr20276 def test_with_dwarf_and_run_commands(self): """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame.""" self.buildDwarf() diff --git a/lldb/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py b/lldb/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py index 4ef7ccf..86410e4 100644 --- a/lldb/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py +++ b/lldb/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py @@ -20,8 +20,8 @@ class StopHookForMultipleThreadsTestCase(TestBase): self.setTearDownCleanup(dictionary=self.d) self.stop_hook_multiple_threads() - @expectedFailureLinux('llvm.org/pr15037') # -- stop hooks sometimes fail to fire on Linux @dwarf_test + @skipIfLinux # llvm.org/pr15037 stop hooks sometimes fail to fire on Linux (cannot mark XFAIL, sometimes it passes) def test_stop_hook_multiple_threads_with_dwarf(self): """Test that lldb stop-hook works for multiple threads.""" self.buildDwarf(dictionary=self.d) diff --git a/lldb/test/tools/lldb-gdbserver/gdbremote_testcase.py b/lldb/test/tools/lldb-gdbserver/gdbremote_testcase.py index ba9e8f5..96e941b 100644 --- a/lldb/test/tools/lldb-gdbserver/gdbremote_testcase.py +++ b/lldb/test/tools/lldb-gdbserver/gdbremote_testcase.py @@ -6,6 +6,7 @@ import errno import unittest2 import pexpect import platform +import random import re import sets import signal @@ -22,8 +23,6 @@ class GdbRemoteTestCaseBase(TestBase): mydir = TestBase.compute_mydir(__file__) - port = 12345 - _TIMEOUT_SECONDS = 5 _GDBREMOTE_KILL_PACKET = "$k#6b" @@ -50,10 +49,10 @@ class GdbRemoteTestCaseBase(TestBase): self.logger.setLevel(self._LOGGING_LEVEL) self.test_sequence = GdbRemoteTestSequence(self.logger) self.set_inferior_startup_launch() + self.port = self.get_next_port() - # Uncomment this code to force only a single test to run (by name). - #if not re.search(r"P_", self._testMethodName): - # self.skipTest("focusing on one test") + def get_next_port(self): + return 12000 + random.randint(0,3999) def reset_test_sequence(self): self.test_sequence = GdbRemoteTestSequence(self.logger) @@ -114,39 +113,50 @@ class GdbRemoteTestCaseBase(TestBase): return server def connect_to_debug_monitor(self, attach_pid=None): - server = self.launch_debug_monitor(attach_pid=attach_pid) - - # Wait until we receive the server ready message before continuing. - server.expect_exact('Listening to port {} for a connection from localhost'.format(self.port)) - - # Schedule debug monitor to be shut down during teardown. - logger = self.logger - def shutdown_debug_monitor(): - try: - server.close() - except: - logger.warning("failed to close pexpect server for debug monitor: {}; ignoring".format(sys.exc_info()[0])) - self.addTearDownHook(shutdown_debug_monitor) - attempts = 0 MAX_ATTEMPTS = 20 while attempts < MAX_ATTEMPTS: - # Create a socket to talk to the server + server = self.launch_debug_monitor(attach_pid=attach_pid) + + # Wait until we receive the server ready message before continuing. + port_good = True try: - self.sock = self.create_socket() - return server - except socket.error as serr: - # We're only trying to handle connection refused - if serr.errno != errno.ECONNREFUSED: - raise serr - - # Increment attempts. - print("connect to debug monitor on port %d failed, attempt #%d of %d" % (self.port, attempts + 1, MAX_ATTEMPTS)) - attempts += 1 - - # And wait a second before next attempt. - time.sleep(1) + server.expect_exact('Listening to port {} for a connection from localhost'.format(self.port)) + except: + port_good = False + server.close() + + if port_good: + # Schedule debug monitor to be shut down during teardown. + logger = self.logger + def shutdown_debug_monitor(): + try: + server.close() + except: + logger.warning("failed to close pexpect server for debug monitor: {}; ignoring".format(sys.exc_info()[0])) + self.addTearDownHook(shutdown_debug_monitor) + + # Create a socket to talk to the server + try: + self.sock = self.create_socket() + return server + except socket.error as serr: + # We're only trying to handle connection refused. + if serr.errno != errno.ECONNREFUSED: + raise serr + # We should close the server here to be safe. + server.close() + + # Increment attempts. + print("connect to debug monitor on port %d failed, attempt #%d of %d" % (self.port, attempts + 1, MAX_ATTEMPTS)) + attempts += 1 + + # And wait a random length of time before next attempt, to avoid collisions. + time.sleep(random.randint(1,5)) + + # Now grab a new port number. + self.port = self.get_next_port() raise Exception("failed to create a socket to the launched debug monitor after %d tries" % attempts) -- 2.7.4