[Lldb-commits] [lldb] r207395 - Added two new test types: @debugserver_test and @llgs_test.
Todd Fiala
todd.fiala at gmail.com
Sun Apr 27 21:49:41 PDT 2014
Author: tfiala
Date: Sun Apr 27 23:49:40 2014
New Revision: 207395
URL: http://llvm.org/viewvc/llvm-project?rev=207395&view=rev
Log:
Added two new test types: @debugserver_test and @llgs_test.
TestLldbGdbServer now supports both lldb-gdbserver (llgs) and
debugserver tests. Similar to the dsym/dwarf tests, they allow
running the same underlying gdb remote protocol tests against
lldb-gdbserver and debugserver. This will help make sure the
protocol-level tests for lldb-gdbserver faithfully represent
what debugserver does on OS X.
Switched back gdb remote protocol test logging to warning
and above (accidentally submitted it at debug level in a
recent commit).
Modified:
lldb/trunk/test/dotest.py
lldb/trunk/test/lldbtest.py
lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py
lldb/trunk/test/tools/lldb-gdbserver/lldbgdbserverutils.py
Modified: lldb/trunk/test/dotest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=207395&r1=207394&r2=207395&view=diff
==============================================================================
--- lldb/trunk/test/dotest.py (original)
+++ lldb/trunk/test/dotest.py Sun Apr 27 23:49:40 2014
@@ -126,6 +126,13 @@ just_do_benchmarks_test = False
dont_do_dsym_test = "linux" in sys.platform or "freebsd" in sys.platform
dont_do_dwarf_test = False
+# Don't do debugserver tests on everything except OS X.
+# Something for Windows here?
+dont_do_debugserver_test = "linux" in sys.platform or "freebsd" in sys.platform
+
+# Don't do lldb-gdbserver (llgs) tests on anything except Linux.
+dont_do_llgs_test = not ("linux" in sys.platform)
+
# The blacklist is optional (-b blacklistFile) and allows a central place to skip
# testclass's and/or testclass.testmethod's.
blacklist = None
@@ -1300,6 +1307,8 @@ lldb.just_do_python_api_test = just_do_p
lldb.just_do_benchmarks_test = just_do_benchmarks_test
lldb.dont_do_dsym_test = dont_do_dsym_test
lldb.dont_do_dwarf_test = dont_do_dwarf_test
+lldb.dont_do_debugserver_test = dont_do_debugserver_test
+lldb.dont_do_llgs_test = dont_do_llgs_test
# Do we need to skip build and cleanup?
lldb.skip_build_and_cleanup = skip_build_and_cleanup
Modified: lldb/trunk/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=207395&r1=207394&r2=207395&view=diff
==============================================================================
--- lldb/trunk/test/lldbtest.py (original)
+++ lldb/trunk/test/lldbtest.py Sun Apr 27 23:49:40 2014
@@ -373,6 +373,40 @@ def dwarf_test(func):
wrapper.__dwarf_test__ = True
return wrapper
+def debugserver_test(func):
+ """Decorate the item as a debugserver test."""
+ if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+ raise Exception("@debugserver_test can only be used to decorate a test method")
+ @wraps(func)
+ def wrapper(self, *args, **kwargs):
+ try:
+ if lldb.dont_do_debugserver_test:
+ self.skipTest("debugserver tests")
+ except AttributeError:
+ pass
+ return func(self, *args, **kwargs)
+
+ # Mark this function as such to separate them from the regular tests.
+ wrapper.__debugserver_test__ = True
+ return wrapper
+
+def llgs_test(func):
+ """Decorate the item as a lldb-gdbserver test."""
+ if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+ raise Exception("@llgs_test can only be used to decorate a test method")
+ @wraps(func)
+ def wrapper(self, *args, **kwargs):
+ try:
+ if lldb.dont_do_llgs_test:
+ self.skipTest("llgs tests")
+ except AttributeError:
+ pass
+ return func(self, *args, **kwargs)
+
+ # Mark this function as such to separate them from the regular tests.
+ wrapper.__llgs_test__ = True
+ return wrapper
+
def not_remote_testsuite_ready(func):
"""Decorate the item as a test which is not ready yet for remote testsuite."""
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Modified: lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py?rev=207395&r1=207394&r2=207395&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py (original)
+++ lldb/trunk/test/tools/lldb-gdbserver/TestLldbGdbServer.py Sun Apr 27 23:49:40 2014
@@ -21,20 +21,27 @@ class LldbGdbServerTestCase(TestBase):
_GDBREMOTE_KILL_PACKET = "$k#6b"
- # _LOGGING_LEVEL = logging.WARNING
- _LOGGING_LEVEL = logging.DEBUG
+ _LOGGING_LEVEL = logging.WARNING
+ # _LOGGING_LEVEL = logging.DEBUG
def setUp(self):
TestBase.setUp(self)
- self.lldb_gdbserver_exe = get_lldb_gdbserver_exe()
- if not self.lldb_gdbserver_exe:
- self.skipTest("lldb_gdbserver exe not specified")
FORMAT = '%(asctime)-15s %(levelname)-8s %(message)s'
logging.basicConfig(format=FORMAT)
self.logger = logging.getLogger(__name__)
self.logger.setLevel(self._LOGGING_LEVEL)
+ def init_llgs_test(self):
+ self.debug_monitor_exe = get_lldb_gdbserver_exe()
+ if not self.debug_monitor_exe:
+ self.skipTest("lldb_gdbserver exe not found")
+
+ def init_debugserver_test(self):
+ self.debug_monitor_exe = get_debugserver_exe()
+ if not self.debug_monitor_exe:
+ self.skipTest("debugserver exe not found")
+
def create_socket(self):
sock = socket.socket()
logger = self.logger
@@ -59,24 +66,24 @@ class LldbGdbServerTestCase(TestBase):
def start_server(self):
# start the server
- server = pexpect.spawn("{} localhost:{}".format(self.lldb_gdbserver_exe, self.port))
+ server = pexpect.spawn("{} localhost:{}".format(self.debug_monitor_exe, self.port))
# Turn on logging for what the child sends back.
if self.TraceOn():
server.logfile_read = sys.stdout
- # Schedule lldb-gdbserver to be shutting down during teardown.
+ # Schedule debug monitor to be shut down during teardown.
logger = self.logger
- def shutdown_lldb_gdbserver():
+ 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_lldb_gdbserver)
+ self.addTearDownHook(shutdown_debug_monitor)
# Wait until we receive the server ready message before continuing.
- server.expect_exact('Listening for a connection on localhost:{}'.format(self.port))
+ server.expect_exact('Listening to port {} for a connection from localhost'.format(self.port))
# Create a socket to talk to the server
self.sock = self.create_socket()
@@ -91,11 +98,17 @@ class LldbGdbServerTestCase(TestBase):
"lldb-gdbserver < 6> send packet: $OK#9a",
"lldb-gdbserver < 1> read packet: +"]
+ @debugserver_test
+ def test_exe_starts_debugserver(self):
+ self.init_debugserver_test()
+ server = self.start_server()
- def test_exe_starts(self):
+ @llgs_test
+ def test_exe_starts_llgs(self):
+ self.init_llgs_test()
server = self.start_server()
- def test_start_no_ack_mode(self):
+ def start_no_ack_mode(self):
server = self.start_server()
self.assertIsNotNone(server)
@@ -104,8 +117,17 @@ class LldbGdbServerTestCase(TestBase):
expect_lldb_gdbserver_replay(self, self.sock, log_lines, True,
self._TIMEOUT_SECONDS, self.logger)
- @unittest2.expectedFailure()
- def test_thread_suffix_supported(self):
+ @debugserver_test
+ def test_start_no_ack_mode_debugserver(self):
+ self.init_debugserver_test()
+ self.start_no_ack_mode()
+
+ @llgs_test
+ def test_start_no_ack_mode_llgs(self):
+ self.init_llgs_test()
+ self.start_no_ack_mode()
+
+ def thread_suffix_supported(self):
server = self.start_server()
self.assertIsNotNone(server)
@@ -117,8 +139,18 @@ class LldbGdbServerTestCase(TestBase):
expect_lldb_gdbserver_replay(self, self.sock, log_lines, True,
self._TIMEOUT_SECONDS, self.logger)
+ @debugserver_test
+ def test_thread_suffix_supported_debugserver(self):
+ self.init_debugserver_test()
+ self.thread_suffix_supported()
+
+ @llgs_test
@unittest2.expectedFailure()
- def test_list_threads_in_stop_reply_supported(self):
+ def test_thread_suffix_supported_llgs(self):
+ self.init_llgs_test()
+ self.thread_suffix_supported()
+
+ def list_threads_in_stop_reply_supported(self):
server = self.start_server()
self.assertIsNotNone(server)
@@ -130,6 +162,17 @@ class LldbGdbServerTestCase(TestBase):
expect_lldb_gdbserver_replay(self, self.sock, log_lines, True,
self._TIMEOUT_SECONDS, self.logger)
+ @debugserver_test
+ def test_list_threads_in_stop_reply_supported_debugserver(self):
+ self.init_debugserver_test()
+ self.list_threads_in_stop_reply_supported()
+
+ @llgs_test
+ @unittest2.expectedFailure()
+ def test_list_threads_in_stop_reply_supported_llgs(self):
+ self.init_llgs_test()
+ self.list_threads_in_stop_reply_supported()
+
def start_inferior(self):
server = self.start_server()
self.assertIsNotNone(server)
@@ -148,13 +191,17 @@ class LldbGdbServerTestCase(TestBase):
expect_lldb_gdbserver_replay(self, self.sock, log_lines, True,
self._TIMEOUT_SECONDS, self.logger)
+ @debugserver_test
@dsym_test
- def test_start_inferior(self):
+ def test_start_inferior_debugserver_dsym(self):
+ self.init_debugserver_test()
self.buildDsym()
self.start_inferior()
+ @llgs_test
@dwarf_test
- def test_start_inferior(self):
+ def test_start_inferior_llgs_dwarf(self):
+ self.init_llgs_test()
self.buildDwarf()
self.start_inferior()
Modified: lldb/trunk/test/tools/lldb-gdbserver/lldbgdbserverutils.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-gdbserver/lldbgdbserverutils.py?rev=207395&r1=207394&r2=207395&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-gdbserver/lldbgdbserverutils.py (original)
+++ lldb/trunk/test/tools/lldb-gdbserver/lldbgdbserverutils.py Sun Apr 27 23:49:40 2014
@@ -7,36 +7,42 @@ import re
import select
import time
-def _get_lldb_gdbserver_from_lldb(lldb_exe):
- """Return the lldb-gdbserver exe path given the lldb exe path.
- This method attempts to construct a valid lldb-gdbserver exe name
+def _get_debug_monitor_from_lldb(lldb_exe, debug_monitor_basename):
+ """Return the debug monitor exe path given the lldb exe path.
+
+ This method attempts to construct a valid debug monitor exe name
from a given lldb exe name. It will return None if the synthesized
- lldb-gdbserver name is not found to exist.
+ debug monitor name is not found to exist.
- The lldb-gdbserver exe path is synthesized by taking the directory
+ The debug monitor exe path is synthesized by taking the directory
of the lldb exe, and replacing the portion of the base name that
- matches "lldb" (case insensitive) and replacing with "lldb-gdbserver".
+ matches "lldb" (case insensitive) and replacing with the value of
+ debug_monitor_basename.
Args:
lldb_exe: the path to an lldb executable.
+ debug_monitor_basename: the base name portion of the debug monitor
+ that will replace 'lldb'.
+
Returns:
- A path to the lldb-gdbserver exe if it is found to exist; otherwise,
+ A path to the debug monitor exe if it is found to exist; otherwise,
returns None.
+
"""
exe_dir = os.path.dirname(lldb_exe)
exe_base = os.path.basename(lldb_exe)
# we'll rebuild the filename by replacing lldb with
- # lldb-gdbserver, keeping any prefix or suffix in place.
+ # the debug monitor basename, keeping any prefix or suffix in place.
regex = re.compile(r"lldb", re.IGNORECASE)
- new_base = regex.sub("lldb-gdbserver", exe_base)
+ new_base = regex.sub(debug_monitor_basename, exe_base)
- lldb_gdbserver_exe = os.path.join(exe_dir, new_base)
- if os.path.exists(lldb_gdbserver_exe):
- return lldb_gdbserver_exe
+ debug_monitor_exe = os.path.join(exe_dir, new_base)
+ if os.path.exists(debug_monitor_exe):
+ return debug_monitor_exe
else:
return None
@@ -52,7 +58,20 @@ def get_lldb_gdbserver_exe():
if not lldb_exe:
return None
else:
- return _get_lldb_gdbserver_from_lldb(lldb_exe)
+ return _get_debug_monitor_from_lldb(lldb_exe, "lldb-gedbserver")
+
+def get_debugserver_exe():
+ """Return the debugserver exe path.
+
+ Returns:
+ A path to the debugserver exe if it is found to exist; otherwise,
+ returns None.
+ """
+ lldb_exe = os.environ["LLDB_EXEC"]
+ if not lldb_exe:
+ return None
+ else:
+ return _get_debug_monitor_from_lldb(lldb_exe, "debugserver")
_LOG_LINE_REGEX = re.compile(r'^(lldb-gdbserver|debugserver)\s+<\s*(\d+)>' +
@@ -87,8 +106,18 @@ def _is_packet_lldb_gdbserver_input(pack
raise "Unknown packet type: {}".format(packet_type)
-_GDB_REMOTE_PACKET_REGEX = re.compile(r'^\$[^\#]*\#[0-9a-fA-F]{2}')
+_STRIP_CHECKSUM_REGEX = re.compile(r'#[0-9a-fA-F]{2}$')
+
+def assert_packets_equal(asserter, actual_packet, expected_packet):
+ # strip off the checksum digits of the packet. When we're in
+ # no-ack mode, the # checksum is ignored, and should not be cause
+ # for a mismatched packet.
+ actual_stripped = _STRIP_CHECKSUM_REGEX.sub('', actual_packet)
+ expected_stripped = _STRIP_CHECKSUM_REGEX.sub('', expected_packet)
+ asserter.assertEqual(actual_stripped, expected_stripped)
+
+_GDB_REMOTE_PACKET_REGEX = re.compile(r'^\$([^\#]*)#[0-9a-fA-F]{2}')
def expect_lldb_gdbserver_replay(
asserter,
@@ -134,19 +163,20 @@ def expect_lldb_gdbserver_replay(
logger.debug("processing log line: {}".format(packet))
match = _LOG_LINE_REGEX.match(packet)
if match:
+ playback_packet = match.group(4)
if _is_packet_lldb_gdbserver_input(
match.group(3),
read_is_llgs_input):
# handle as something to send to lldb-gdbserver on
# socket.
if logger:
- logger.info("sending packet to llgs: {}".format(match.group(4)))
- sock.sendall(match.group(4))
+ logger.info("sending packet to llgs: {}".format(playback_packet))
+ sock.sendall(playback_packet)
else:
# expect it as output from lldb-gdbserver received
# from socket.
if logger:
- logger.info("receiving packet from llgs, should match: {}".format(match.group(4)))
+ logger.info("receiving packet from llgs, should match: {}".format(playback_packet))
start_time = time.time()
timeout_time = start_time + timeout_seconds
@@ -157,7 +187,7 @@ def expect_lldb_gdbserver_replay(
if time.time() > timeout_time:
raise Exception(
'timed out after {} seconds while waiting for llgs to respond with: {}, currently received: {}'.format(
- timeout_seconds, match.group(4), receive_buffer))
+ timeout_seconds, playback_packet, receive_buffer))
can_read, _, _ = select.select(
[sock], [], [], 0)
if can_read and sock in can_read:
@@ -191,9 +221,8 @@ def expect_lldb_gdbserver_replay(
# got a line - now try to match it against expected line
if len(received_lines) > 0:
- actual_receive = received_lines.pop(0)
- expected_receive = match.group(4)
- asserter.assertEqual(actual_receive, expected_receive)
+ received_packet = received_lines.pop(0)
+ assert_packets_equal(asserter, received_packet, playback_packet)
return None
More information about the lldb-commits
mailing list