[lldb-dap] Migrate DAP launch tests (#207023)
Migrate all the tests in `lldb-dap/launch` base directory only. Fixes
any grammar if needed.
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_args.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_args.py
index 6774f05..98091e6 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_args.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_args.py
@@ -2,11 +2,11 @@
Test lldb-dap launch request.
"""
-from lldbsuite.test.decorators import expectedFailureWindows
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_args(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_args(DAPTestCaseBase):
"""
Tests launch of a simple program with arguments
"""
@@ -14,20 +14,21 @@
def test(self):
program = self.getBuildArtifact("a.out")
args = ["one", "with space", "'with single quotes'", '"with double quotes"']
- self.build_and_launch(program, args=args)
- self.continue_to_exit()
+ session = self.build_and_create_session()
+ session.launch(LaunchArgs(program=program, args=args))
+ session.verify_process_exited()
- # Now get the STDOUT and verify our arguments got passed correctly
- output = self.get_stdout()
+ output = session.get_stdout()
self.assertTrue(output and len(output) > 0, "expect program output")
lines = output.splitlines()
- # Skip the first argument that contains the program name
+ # Skip the first argument that contains the program name.
lines.pop(0)
- # Make sure arguments we specified are correct
- for i, arg in enumerate(args):
- quoted_arg = '"%s"' % (arg)
+ # Make sure arguments we specified are correct.
+ args_and_lines = zip(args, lines)
+ for i, (arg, line) in enumerate(args_and_lines, start=1):
+ quoted_arg = f'"{arg}"'
self.assertIn(
quoted_arg,
- lines[i],
- 'arg[%i] "%s" not in "%s"' % (i + 1, quoted_arg, lines[i]),
+ line,
+ f'arg[{i}] "{arg}" not in {line!r}',
)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_commands.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_commands.py
index 48398e5..21a3f61 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_commands.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_commands.py
@@ -4,10 +4,11 @@
from lldbsuite.test.decorators import skipIf
from lldbsuite.test.lldbtest import line_number
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_commands(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_commands(DAPTestCaseBase):
"""
Tests the "initCommands", "preRunCommands", "stopCommands",
"terminateCommands" and "exitCommands" that can be passed during
@@ -34,7 +35,9 @@
stopCommands = ["frame variable", "bt"]
exitCommands = ["expr 2+3", "expr 3+4"]
terminateCommands = ["expr 4+2"]
- self.build_and_launch(
+ session = self.build_and_create_session()
+
+ launch_args = LaunchArgs(
program,
initCommands=initCommands,
preRunCommands=preRunCommands,
@@ -43,49 +46,52 @@
exitCommands=exitCommands,
terminateCommands=terminateCommands,
)
- self.dap_server.wait_for_initialized()
+ with session.configure(launch_args) as ctx:
+ # Get output from the console. This should contain the
+ # "initCommands", "preRunCommands", and "postRunCommands".
+ coutput = session.collect_console(
+ after=ctx.init_response, until=postRunCommands[-1]
+ )
+ output = coutput.seen_texts
+ session.verify_commands("initCommands", output, initCommands)
+ session.verify_commands("preRunCommands", output, preRunCommands)
+ session.verify_commands("postRunCommands", output, postRunCommands)
- # Get output from the console. This should contain both the
- # "initCommands" and the "preRunCommands".
- output = self.collect_console(pattern=postRunCommands[-1])
- # Verify all "initCommands" were found in console output
- self.verify_commands("initCommands", output, initCommands)
- # Verify all "preRunCommands" were found in console output
- self.verify_commands("preRunCommands", output, preRunCommands)
- # Verify all "postRunCommands" were found in console output
- self.verify_commands("postRunCommands", output, postRunCommands)
+ source = "main.c"
+ first_line = line_number(source, "// breakpoint 1")
+ second_line = line_number(source, "// breakpoint 2")
+ lines = [first_line, second_line]
- source = "main.c"
- first_line = line_number(source, "// breakpoint 1")
- second_line = line_number(source, "// breakpoint 2")
- lines = [first_line, second_line]
+ # Set 2 breakpoints so we can verify that "stopCommands" get run as the
+ # breakpoints get hit.
+ [first_bp, second_bp] = session.resolve_source_breakpoints(source, lines)
- # Set 2 breakpoints so we can verify that "stopCommands" get run as the
- # breakpoints get hit
- breakpoint_ids = self.set_source_breakpoints(source, lines)
- self.assertEqual(
- len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
- )
+ launch_response = ctx.launch_or_attach_response
# Continue after launch and hit the first breakpoint.
- # Get output from the console. This should contain both the
- # "stopCommands" that were run after the first breakpoint was hit
- self.continue_to_breakpoints(breakpoint_ids)
- output = self.collect_console(pattern=stopCommands[-1])
- self.verify_commands("stopCommands", output, stopCommands)
+ # Get output from the console. This should contain the
+ # "stopCommands" that were run after the first breakpoint was hit.
+ session.verify_stopped_on_breakpoint(first_bp, after=ctx.process_event)
+ coutput = session.collect_console(after=launch_response, until=stopCommands[-1])
+ output = coutput.seen_texts
+ session.verify_commands("stopCommands", output, stopCommands)
# Continue again and hit the second breakpoint.
- # Get output from the console. This should contain both the
- # "stopCommands" that were run after the second breakpoint was hit
- self.continue_to_breakpoints(breakpoint_ids)
- output = self.collect_console(pattern=stopCommands[-1])
- self.verify_commands("stopCommands", output, stopCommands)
+ # Get output from the console. This should contain the
+ # "stopCommands" that were run after the second breakpoint was hit.
+ session.continue_to_breakpoint(second_bp)
+ coutput = session.collect_console(after=coutput.event, until=stopCommands[-1])
+ output = coutput.seen_texts
+ session.verify_commands("stopCommands", output, stopCommands)
- # Continue until the program exits
- self.continue_to_exit()
- # Get output from the console. This should contain both the
- # "exitCommands" that were run after the second breakpoint was hit
- # and the "terminateCommands" due to the debugging session ending
- output = self.collect_console(pattern=terminateCommands[0])
- self.verify_commands("exitCommands", output, exitCommands)
- self.verify_commands("terminateCommands", output, terminateCommands)
+ # Continue until the program exits.
+ # Get output from the console. This should contain the
+ # "exitCommands" run on process exit and the "terminateCommands"
+ # run when the debugging session ends.
+ session.continue_to_exit()
+ coutput = session.collect_console(
+ after=coutput.event, until=terminateCommands[0]
+ )
+ output = coutput.seen_texts
+ session.verify_commands("exitCommands", output, exitCommands)
+ session.verify_commands("terminateCommands", output, terminateCommands)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_cwd.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_cwd.py
index c2b2b986..a7e4ffa 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_cwd.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_cwd.py
@@ -2,35 +2,37 @@
Test lldb-dap launch request.
"""
-from lldbsuite.test.decorators import skipIfWindows
-import lldbdap_testcase
import os
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_cwd(lldbdap_testcase.DAPTestCaseBase):
+
+class TestDAP_launch_cwd(DAPTestCaseBase):
"""
Tests the default launch of a simple program with a current working
directory.
"""
- @skipIfWindows
def test(self):
program = self.getBuildArtifact("a.out")
program_parent_dir = os.path.realpath(os.path.dirname(os.path.dirname(program)))
- self.build_and_launch(program, cwd=program_parent_dir)
- self.continue_to_exit()
- # Now get the STDOUT and verify our program argument is correct
- output = self.get_stdout()
+ session = self.build_and_create_session()
+ session.launch(LaunchArgs(program=program, cwd=program_parent_dir))
+ session.verify_process_exited()
+
+ # Now get the STDOUT and verify our program's working directory is correct
+ output = session.get_stdout()
self.assertTrue(output and len(output) > 0, "expect program output")
+
lines = output.splitlines()
- found = False
- for line in lines:
- if line.startswith('cwd = "'):
- quote_path = '"%s"' % (program_parent_dir)
- found = True
- self.assertIn(
- quote_path,
- line,
- "working directory '%s' not in '%s'" % (program_parent_dir, line),
- )
- self.assertTrue(found, "verified program working directory")
+ cwd_lines = [line for line in lines if line.startswith('cwd = "')]
+ self.assertEqual(len(cwd_lines), 1, "verified program working directory")
+ cwd_line = cwd_lines[0]
+
+ quote_path = f'"{program_parent_dir}"'
+ self.assertIn(
+ quote_path,
+ cwd_line,
+ f"working directory '{program_parent_dir}' not in '{cwd_line}'",
+ )
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_debuggerRoot.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_debuggerRoot.py
index deeab23..6bf470e 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_debuggerRoot.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_debuggerRoot.py
@@ -2,13 +2,14 @@
Test lldb-dap launch request.
"""
-from lldbsuite.test.decorators import expectedFailureWindows
-from lldbsuite.test import lldbplatformutil
-import lldbdap_testcase
import os
+from lldbsuite.test import lldbplatformutil
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_debuggerRoot(lldbdap_testcase.DAPTestCaseBase):
+
+class TestDAP_launch_debuggerRoot(DAPTestCaseBase):
"""
Tests the "debuggerRoot" will change the working directory of
the lldb-dap debug adapter.
@@ -19,24 +20,29 @@
program_parent_dir = os.path.realpath(os.path.dirname(os.path.dirname(program)))
var = "%cd%" if lldbplatformutil.getHostPlatform() == "windows" else "$PWD"
- commands = [f"platform shell echo cwd = {var}"]
+ init_commands = [f"platform shell echo cwd = {var}"]
- self.build_and_launch(
- program, debuggerRoot=program_parent_dir, initCommands=commands
+ session = self.build_and_create_session()
+ process_event = session.launch(
+ LaunchArgs(
+ program=program,
+ debuggerRoot=program_parent_dir,
+ initCommands=init_commands,
+ )
)
- self.continue_to_exit()
- output = self.get_console()
+ session.verify_process_exited(after=process_event)
+
+ output = session.get_console()
self.assertTrue(output and len(output) > 0, "expect console output")
- lines = output.splitlines()
+
prefix = "cwd = "
- found = False
- for line in lines:
- if line.startswith(prefix):
- found = True
- self.assertEqual(
- program_parent_dir,
- line.strip()[len(prefix) :],
- "lldb-dap working dir '%s' == '%s'"
- % (program_parent_dir, line[len(prefix) :]),
- )
- self.assertTrue(found, "verified lldb-dap working directory")
+ cwd_lines = [line for line in output.splitlines() if line.startswith(prefix)]
+ self.assertEqual(
+ len(cwd_lines), 1, "expected exactly one cwd line in console output"
+ )
+ self.assertEqual(
+ cwd_lines[0].strip()[len(prefix) :],
+ program_parent_dir,
+ f"lldb-dap working dir mismatch: expected '{program_parent_dir}', "
+ f"got '{cwd_lines[0]}'",
+ )
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_disableSTDIO.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_disableSTDIO.py
index 0a780f5..39d350f 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_disableSTDIO.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_disableSTDIO.py
@@ -3,10 +3,11 @@
"""
from lldbsuite.test.decorators import skipIfWindows
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_disableSTDIO(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_disableSTDIO(DAPTestCaseBase):
"""
Tests the default launch of a simple program with STDIO disabled.
"""
@@ -14,8 +15,10 @@
@skipIfWindows
def test(self):
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program, disableSTDIO=True)
- self.continue_to_exit()
- # Now get the STDOUT and verify our program argument is correct
- output = self.get_stdout()
+ session = self.build_and_create_session()
+ session.launch(LaunchArgs(program=program, disableSTDIO=True))
+ session.verify_process_exited()
+
+ # Now get the STDOUT and verify our program argument is correct.
+ output = session.get_stdout()
self.assertEqual(output, "", "expect no program output")
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_environment_with_array.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_environment_with_array.py
index 1595f4a..2e96a11 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_environment_with_array.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_environment_with_array.py
@@ -3,10 +3,11 @@
"""
from lldbsuite.test.decorators import skipIfWindows
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_environment_with_array(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_environment_with_array(DAPTestCaseBase):
"""
Tests launch of a simple program with environment variables
"""
@@ -14,26 +15,28 @@
@skipIfWindows
def test(self):
program = self.getBuildArtifact("a.out")
- env = ["NO_VALUE", "WITH_VALUE=BAR", "EMPTY_VALUE=", "SPACE=Hello World"]
+ expected_env = [
+ "NO_VALUE",
+ "WITH_VALUE=BAR",
+ "EMPTY_VALUE=",
+ "SPACE=Hello World",
+ ]
- self.build_and_launch(program, env=env)
- self.continue_to_exit()
+ session = self.build_and_create_session()
+ process_event = session.launch(LaunchArgs(program=program, env=expected_env))
+ session.verify_process_exited(after=process_event)
- # Now get the STDOUT and verify our arguments got passed correctly
- output = self.get_stdout()
- self.assertTrue(output and len(output) > 0, "expect program output")
- lines = output.splitlines()
- # Skip the all arguments so we have only environment vars left
- while len(lines) and lines[0].startswith("arg["):
- lines.pop(0)
- # Make sure each environment variable in "env" is actually set in the
- # program environment that was printed to STDOUT
- for var in env:
- found = False
- for program_var in lines:
- if var in program_var:
- found = True
- break
- self.assertTrue(
- found, '"%s" must exist in program environment (%s)' % (var, lines)
+ # Now get the STDOUT and verify our arguments got passed correctly.
+ output = session.get_stdout()
+ self.assertTrue(output, "expect program output")
+
+ # Collect environment lines.
+ env_output = "\n".join(l for l in output.splitlines() if l.startswith("env["))
+ # Make sure each environment variable in "expected_env" is actually set in the
+ # program environment and contains the right value.
+ for expected_str in expected_env:
+ self.assertIn(
+ expected_str,
+ env_output,
+ f"\n{expected_str} must exist in program's environment \n{env_output}",
)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_environment_with_object.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_environment_with_object.py
index 8c7994e..a853bbc 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_environment_with_object.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_environment_with_object.py
@@ -2,41 +2,43 @@
Test lldb-dap launch request.
"""
-from lldbsuite.test.decorators import expectedFailureWindows
-import lldbdap_testcase
+from lldbsuite.test.decorators import skipIfWindows
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch(lldbdap_testcase.DAPTestCaseBase):
- def test_environment_with_object(self):
- """
- Tests launch of a simple program with environment variables
- """
+class TestDAP_launch_environment_with_object(DAPTestCaseBase):
+ """
+ Tests launch of a simple program with environment variables
+ """
+
+ @skipIfWindows
+ def test(self):
program = self.getBuildArtifact("a.out")
- env = {
- "NO_VALUE": "",
+ expected_env = {
+ "NO_VALUE": None,
"WITH_VALUE": "BAR",
"EMPTY_VALUE": "",
"SPACE": "Hello World",
}
- self.build_and_launch(program, env=env)
- self.continue_to_exit()
+ session = self.build_and_create_session()
+ process_event = session.launch(LaunchArgs(program=program, env=expected_env))
+ session.verify_process_exited(after=process_event)
- # Now get the STDOUT and verify our arguments got passed correctly
- output = self.get_stdout()
- self.assertTrue(output and len(output) > 0, "expect program output")
- lines = output.splitlines()
- # Skip the all arguments so we have only environment vars left
- while len(lines) and lines[0].startswith("arg["):
- lines.pop(0)
- # Make sure each environment variable in "env" is actually set in the
- # program environment that was printed to STDOUT
- for var in env:
- found = False
- for program_var in lines:
- if var in program_var:
- found = True
- break
- self.assertTrue(
- found, '"%s" must exist in program environment (%s)' % (var, lines)
+ # Now get the STDOUT and verify our arguments got passed correctly.
+ output = session.get_stdout()
+ self.assertTrue(output, "expect program output")
+
+ # Collect environment lines.
+ env_output = "\n".join(l for l in output.splitlines() if l.startswith("env["))
+ # Make sure each environment variable in "expected_env" is actually set in the
+ # program environment and contains the right value.
+ for variable, value in expected_env.items():
+ expected_value = value or ""
+ expected_str = f'"{variable}={expected_value}"'
+ self.assertIn(
+ expected_str,
+ env_output,
+ f"\n{expected_str} must exist in program's environment \n{env_output}",
)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_extra_launch_commands.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_extra_launch_commands.py
index ad48af6..92c481a 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_extra_launch_commands.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_extra_launch_commands.py
@@ -4,10 +4,11 @@
from lldbsuite.test.decorators import skipIf
from lldbsuite.test.lldbtest import line_number
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_extra_launch_commands(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_extra_launch_commands(DAPTestCaseBase):
"""
Tests the "launchCommands" with extra launching settings
"""
@@ -15,18 +16,17 @@
# Flakey on 32-bit Arm Linux.
@skipIf(oslist=["linux"], archs=["arm$"])
def test(self):
- self.build_and_create_debug_adapter()
program = self.getBuildArtifact("a.out")
-
- source = "main.c"
+ session = self.build_and_create_session()
+ source = self.getSourcePath("main.c")
first_line = line_number(source, "// breakpoint 1")
second_line = line_number(source, "// breakpoint 2")
- # Set target binary and 2 breakpoints
- # then we can verify the "launchCommands" get run
- # also we can verify that "stopCommands" get run as the
- # breakpoints get hit
+
+ # Set target binary and 2 breakpoints, so we can verify the
+ # "launchCommands" get run, and verify "stopCommands" get run
+ # as the breakpoints get hit.
launchCommands = [
- 'target create "%s"' % (program),
+ f'target create "{program}"',
"process launch --stop-at-entry",
]
initCommands = ["target list", "platform list"]
@@ -34,51 +34,48 @@
postRunCommands = ['script print("hello world")']
stopCommands = ["frame variable", "bt"]
exitCommands = ["expr 2+3", "expr 3+4"]
- self.launch(
- program,
- initCommands=initCommands,
- preRunCommands=preRunCommands,
- postRunCommands=postRunCommands,
- stopCommands=stopCommands,
- exitCommands=exitCommands,
- launchCommands=launchCommands,
- )
- self.set_source_breakpoints("main.c", [first_line, second_line])
- # Get output from the console. This should contain both the
- # "initCommands" and the "preRunCommands".
- output = self.get_console()
- # Verify all "initCommands" were found in console output
- self.verify_commands("initCommands", output, initCommands)
- # Verify all "preRunCommands" were found in console output
- self.verify_commands("preRunCommands", output, preRunCommands)
+ with session.configure(
+ LaunchArgs(
+ program=program,
+ launchCommands=launchCommands,
+ initCommands=initCommands,
+ preRunCommands=preRunCommands,
+ postRunCommands=postRunCommands,
+ stopCommands=stopCommands,
+ exitCommands=exitCommands,
+ )
+ ) as ctx:
+ session.resolve_source_breakpoints(source, [first_line, second_line])
+ process_event = ctx.process_event
+ # The launchCommands stop the process at entry, but lldb-dap auto-continues
+ # after configurationDone (since stopOnEntry isn't set), so the first
+ # observable stop is hitting the first breakpoint, not entry.
+ first_stop = session.verify_stopped_on_breakpoint(after=process_event)
- # Verify all "launchCommands" were found in console output
- # After execution, program should launch
- self.verify_commands("launchCommands", output, launchCommands)
- self.verify_commands("postRunCommands", output, postRunCommands)
+ # Get output from the console. This should contain the
+ # "initCommands", "preRunCommands", "launchCommands", and "postRunCommands".
+ output = session.get_console()
+ session.verify_commands("initCommands", output, initCommands)
+ session.verify_commands("preRunCommands", output, preRunCommands)
+ session.verify_commands("launchCommands", output, launchCommands)
+ session.verify_commands("postRunCommands", output, postRunCommands)
- # Finish configuration and continue target
- self.verify_configuration_done()
+ # Check that we got module events from target.
+ session.wait_for_module_event(after=ctx.init_response)
- # Check that we got module events from target
- modules = self.dap_server.wait_for_module_events()
- self.assertGreater(len(modules), 0)
+ # Verify the "stopCommands" ran on the first breakpoint hit.
+ # Wait until the last stopCommand's output arrives to avoid racing it.
+ output = session.collect_console(after=first_stop, until=stopCommands[-1])
+ session.verify_commands("stopCommands", output.seen_texts, stopCommands)
- # Verify the "stopCommands" here
- output = self.get_console()
- self.verify_commands("stopCommands", output, stopCommands)
+ # Continue and hit the second breakpoint, then verify "stopCommands"
+ # ran again.
+ session.continue_to_next_stop()
+ output = session.collect_console(after=output.event, until=stopCommands[-1])
+ session.verify_commands("stopCommands", output.seen_texts, stopCommands)
- # Continue and hit the second breakpoint.
- # Get output from the console. This should contain both the
- # "stopCommands" that were run after the first breakpoint was hit
- self.continue_to_next_stop()
- output = self.get_console()
- self.verify_commands("stopCommands", output, stopCommands)
-
- # Continue until the program exits
- self.continue_to_exit()
- # Get output from the console. This should contain both the
- # "exitCommands" that were run after the second breakpoint was hit
- output = self.get_console()
- self.verify_commands("exitCommands", output, exitCommands)
+ # Continue until the program exits, then verify "exitCommands" ran.
+ session.continue_to_exit()
+ output = session.collect_console(after=output.event, until=exitCommands[-1])
+ session.verify_commands("exitCommands", output.seen_texts, exitCommands)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_failing_console.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_failing_console.py
index c59a5fe..c4dc50a 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_failing_console.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_failing_console.py
@@ -2,22 +2,31 @@
Test lldb-dap launch request.
"""
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_failing_console(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_failing_console(DAPTestCaseBase):
"""
Tests launching in console with an invalid terminal type.
"""
def test(self):
program = self.getBuildArtifact("a.out")
- self.create_debug_adapter()
- launch_seq = self.launch(program, console="invalid")
- response = self.dap_server.receive_response(launch_seq)
- self.assertFalse(response["success"])
- self.assertTrue(self.get_dict_value(response, ["body", "error", "showUser"]))
+ # No build needed: the launch request should be rejected during arg
+ # validation, before lldb-dap touches the program path.
+ session = self.create_session()
+ session.initialize_sequence(session.initialize_args)
+
+ err_response = session.send_request(
+ LaunchArgs(program=program, console="invalid")
+ ).error()
+ error_msg = self.expect_not_none(
+ err_response.body and err_response.body.error,
+ "expected an error message in the launch response",
+ )
+ self.assertTrue(error_msg.showUser, "expected showUser=true")
self.assertRegex(
- response["body"]["error"]["format"],
- r"unexpected value, expected 'internalConsole\', 'integratedTerminal\' or 'externalTerminal\' at arguments.console",
+ error_msg.format,
+ r"unexpected value, expected 'internalConsole', 'integratedTerminal' or 'externalTerminal' at arguments.console",
)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_failing_launch_commands.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_failing_launch_commands.py
index ad48fb9..13730ed 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_failing_launch_commands.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_failing_launch_commands.py
@@ -2,50 +2,55 @@
Test lldb-dap launch request.
"""
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-import lldbdap_testcase
import os
import re
+from lldbsuite.test.tools.lldb_dap.dap_types import InitializedEvent, LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_failing_launch_commands(lldbdap_testcase.DAPTestCaseBase):
+
+class TestDAP_launch_failing_launch_commands(DAPTestCaseBase):
"""
Tests "launchCommands" failures prevents a launch.
"""
def test(self):
- self.build_and_create_debug_adapter()
+ session = self.build_and_create_session()
program = self.getBuildArtifact("a.out")
+ init_response = session.initialize_sequence(session.initialize_args)
# Run an invalid launch command, in this case a bad path.
bad_path = os.path.join("bad", "path")
- launchCommands = ['!target create "%s%s"' % (bad_path, program)]
-
+ launchCommands = [f'!target create "{bad_path}{program}"']
initCommands = ["target list", "platform list"]
preRunCommands = ["image list a.out", "image dump sections a.out"]
- response = self.launch_and_configurationDone(
- program,
- initCommands=initCommands,
- preRunCommands=preRunCommands,
- launchCommands=launchCommands,
- )
- self.assertFalse(response["success"])
+ launch_handle = session.send_request(
+ LaunchArgs(
+ program=program,
+ initCommands=initCommands,
+ preRunCommands=preRunCommands,
+ launchCommands=launchCommands,
+ )
+ )
+ session.wait_for_event(InitializedEvent, after=init_response)
+ session.configuration_done().result_or_error()
+ err_response = launch_handle.error()
+
+ error_msg = self.expect_not_none(
+ err_response.body and err_response.body.error,
+ "expected an error message in the launch response",
+ )
self.assertRegex(
- response["body"]["error"]["format"],
+ error_msg.format,
r"Failed to run launch commands\. See the Debug Console for more details",
)
- # Get output from the console. This should contain both the
- # "initCommands" and the "preRunCommands".
- output = self.get_console()
- # Verify all "initCommands" were found in console output
- self.verify_commands("initCommands", output, initCommands)
- # Verify all "preRunCommands" were found in console output
- self.verify_commands("preRunCommands", output, preRunCommands)
-
- # Verify all "launchCommands" were founc in console output
+ # Get output from the console. This should contain the
+ # "initCommands", "preRunCommands", and "launchCommands".
+ output = session.get_console()
+ session.verify_commands("initCommands", output, initCommands)
+ session.verify_commands("preRunCommands", output, preRunCommands)
+ session.verify_commands("launchCommands", output, launchCommands)
# The launch should fail due to the invalid command.
- self.verify_commands("launchCommands", output, launchCommands)
self.assertRegex(output, re.escape(bad_path) + r".*does not exist")
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_invalid_launch_commands_and_console.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_invalid_launch_commands_and_console.py
index 14d7dbe..dfd28e6 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_invalid_launch_commands_and_console.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_invalid_launch_commands_and_console.py
@@ -2,26 +2,35 @@
Test lldb-dap launch request.
"""
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import Console, LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_failing_launch_commands_and_console(
- lldbdap_testcase.DAPTestCaseBase
-):
+class TestDAP_launch_invalid_launch_commands_and_console(DAPTestCaseBase):
"""
Tests launching with launch commands in an integrated terminal.
"""
def test(self):
program = self.getBuildArtifact("a.out")
- self.create_debug_adapter()
- launch_seq = self.launch(
- program, launchCommands=["a b c"], console="integratedTerminal"
+ # No build needed: the launch request should be rejected during
+ # argument validation, before lldb-dap touches the program path.
+ session = self.create_session()
+ session.initialize_sequence(session.initialize_args)
+
+ err_response = session.send_request(
+ LaunchArgs(
+ program=program,
+ launchCommands=["a b c"],
+ console=Console.INTEGRATED_TERMINAL,
+ )
+ ).error()
+ error_msg = self.expect_not_none(
+ err_response.body and err_response.body.error,
+ "expected an error message in the launch response",
)
- response = self.dap_server.receive_response(launch_seq)
- self.assertFalse(response["success"])
- self.assertTrue(self.get_dict_value(response, ["body", "error", "showUser"]))
+ self.assertTrue(error_msg.showUser, "expected showUser=true")
self.assertIn(
"'launchCommands' and non-internal 'console' are mutually exclusive",
- self.get_dict_value(response, ["body", "error", "format"]),
+ error_msg.format,
)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_invalid_program.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_invalid_program.py
index d70426f..6074659 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_invalid_program.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_invalid_program.py
@@ -2,22 +2,26 @@
Test lldb-dap launch request.
"""
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_invalid_program(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_invalid_program(DAPTestCaseBase):
"""
Tests launching with an invalid program.
"""
def test(self):
program = self.getBuildArtifact("a.out")
- self.create_debug_adapter()
- launch_seq = self.launch(program)
- self.dap_server.wait_for_initialized()
- self.dap_server.request_configurationDone()
- response = self.dap_server.receive_response(launch_seq)
- self.assertFalse(response["success"])
- self.assertEqual(
- "'{0}' does not exist".format(program), response["body"]["error"]["format"]
+ session = self.create_session()
+ session.initialize_sequence(session.initialize_args)
+ launch_handle = session.send_request(LaunchArgs(program=program))
+ session.ensure_initialized()
+ session.verify_configuration_done(expected_success=False)
+
+ err_response = launch_handle.error()
+ error_msg = self.expect_not_none(
+ err_response.body and err_response.body.error,
+ "expected an error message in the launch response",
)
+ self.assertEqual(error_msg.format, f"'{program}' does not exist")
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_no_lldbinit_flag.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_no_lldbinit_flag.py
index 8a48075..22cfcf3 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_no_lldbinit_flag.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_no_lldbinit_flag.py
@@ -2,16 +2,21 @@
Test lldb-dap launch request.
"""
-import lldbdap_testcase
import os
import tempfile
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap.utils import DebugAdapterOptions
-class TestDAP_launch_no_lldbinit_flag(lldbdap_testcase.DAPTestCaseBase):
+
+class TestDAP_launch_no_lldbinit_flag(DAPTestCaseBase):
"""
Test that the --no-lldbinit flag prevents sourcing .lldbinit files.
"""
+ USE_DEFAULT_DEBUG_ADAPTER = False
+
def test(self):
# Create a temporary .lldbinit file in the home directory
with tempfile.TemporaryDirectory() as temp_home:
@@ -22,29 +27,35 @@
f.write("settings set stop-disassembly-display never\n")
f.write("settings set target.x86-disassembly-flavor intel\n")
- # Test with --no-lldbinit flag (should NOT source .lldbinit)
- self.build_and_create_debug_adapter(
- lldbDAPEnv={"HOME": temp_home}, additional_args=["--no-lldbinit"]
- )
+ # Build, then spin up a debug adapter with HOME pointing at the
+ # temp dir and the --no-lldbinit flag.
+ self.build()
program = self.getBuildArtifact("a.out")
+ adapter = self.create_stdio_debug_adapter(
+ DebugAdapterOptions(
+ env={"HOME": temp_home},
+ args=["--no-lldbinit"],
+ )
+ )
+ session = self.create_session(adapter=adapter)
- # Use initCommands to check if .lldbinit was sourced
+ # Use initCommands to check if .lldbinit was sourced.
initCommands = ["settings show stop-disassembly-display"]
+ process_event = session.launch(
+ LaunchArgs(program=program, initCommands=initCommands)
+ )
+ session.verify_process_exited(after=process_event)
- # Launch with initCommands to check the setting
- self.launch(program, initCommands=initCommands)
- self.continue_to_exit()
-
- # Get console output to verify the setting was NOT set from .lldbinit
- output = self.get_console()
+ # Get console output to verify the setting was NOT set from .lldbinit.
+ output = session.get_console()
self.assertTrue(output and len(output) > 0, "expect console output")
- # Verify the setting has default value, not "never" from .lldbinit
+ # Verify the setting has default value, not "never" from .lldbinit.
self.assertNotIn(
"never",
output,
"Setting should have default value when --no-lldbinit is used",
)
- # Verify the initCommands were executed
- self.verify_commands("initCommands", output, initCommands)
+ # Verify the initCommands were executed.
+ session.verify_commands("initCommands", output, initCommands)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_shellExpandArguments_disabled.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_shellExpandArguments_disabled.py
index d7b8579..3815784 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_shellExpandArguments_disabled.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_shellExpandArguments_disabled.py
@@ -2,12 +2,13 @@
Test lldb-dap launch request.
"""
-from lldbsuite.test.decorators import expectedFailureWindows
-import lldbdap_testcase
import os
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_shellExpandArguments_disabled(lldbdap_testcase.DAPTestCaseBase):
+
+class TestDAP_launch_shellExpandArguments_disabled(DAPTestCaseBase):
"""
Tests the default launch of a simple program with shell expansion
disabled.
@@ -17,15 +18,16 @@
program = self.getBuildArtifact("a.out")
program_dir = os.path.dirname(program)
glob = os.path.join(program_dir, "*.out")
- self.build_and_launch(program, args=[glob], shellExpandArguments=False)
- self.continue_to_exit()
+ session = self.build_and_create_session()
+ process_event = session.launch(
+ LaunchArgs(program=program, args=[glob], shellExpandArguments=False)
+ )
+ session.verify_process_exited(after=process_event)
+
# Now get the STDOUT and verify our program argument is correct
- output = self.get_stdout()
- self.assertTrue(output and len(output) > 0, "expect no program output")
- lines = output.splitlines()
- for line in lines:
- quote_path = '"%s"' % (glob)
+ output = session.get_stdout()
+ self.assertTrue(output and len(output) > 0, "expect program output")
+ for line in output.splitlines():
if line.startswith("arg[1] ="):
- self.assertIn(
- quote_path, line, 'verify "%s" stayed to "%s"' % (glob, glob)
- )
+ quote_path = f'"{glob}"'
+ self.assertIn(quote_path, line, f'verify "{glob}" stayed as "{glob}"')
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_shellExpandArguments_enabled.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_shellExpandArguments_enabled.py
index 7ddde21..e5ba6a4 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_shellExpandArguments_enabled.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_shellExpandArguments_enabled.py
@@ -2,16 +2,14 @@
Test lldb-dap launch request.
"""
-from lldbsuite.test.decorators import (
- skipIfLinux,
- expectedFailureWindows,
- expectedFailureAll,
-)
-import lldbdap_testcase
import os
+from lldbsuite.test.decorators import expectedFailureAll, skipIfLinux
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_shellExpandArguments_enabled(lldbdap_testcase.DAPTestCaseBase):
+
+class TestDAP_launch_shellExpandArguments_enabled(DAPTestCaseBase):
"""
Tests the default launch of a simple program with shell expansion
enabled.
@@ -25,15 +23,20 @@
program = self.getBuildArtifact("a.out")
program_dir = os.path.dirname(program)
glob = os.path.join(program_dir, "*.out")
- self.build_and_launch(program, args=[glob], shellExpandArguments=True)
- self.continue_to_exit()
+ session = self.build_and_create_session()
+ process_event = session.launch(
+ LaunchArgs(program=program, args=[glob], shellExpandArguments=True)
+ )
+ session.verify_process_exited(after=process_event)
+
# Now get the STDOUT and verify our program argument is correct
- output = self.get_stdout()
- self.assertTrue(output and len(output) > 0, "expect no program output")
- lines = output.splitlines()
- for line in lines:
- quote_path = '"%s"' % (program)
+ output = session.get_stdout()
+ self.assertTrue(output and len(output) > 0, "expect program output")
+ for line in output.splitlines():
if line.startswith("arg[1] ="):
+ quote_path = f'"{program}"'
self.assertIn(
- quote_path, line, 'verify "%s" expanded to "%s"' % (glob, program)
+ quote_path,
+ line,
+ f'verify "{glob}" expanded to "{program}"',
)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_sourcePath.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_sourcePath.py
index 4e09816..b62276c 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_sourcePath.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_sourcePath.py
@@ -2,11 +2,13 @@
Test lldb-dap launch request.
"""
-import lldbdap_testcase
import os
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_sourcePath(lldbdap_testcase.DAPTestCaseBase):
+
+class TestDAP_launch_sourcePath(DAPTestCaseBase):
"""
Tests the "sourcePath" will set the target.source-map.
"""
@@ -14,20 +16,23 @@
def test(self):
program = self.getBuildArtifact("a.out")
program_dir = os.path.dirname(program)
- self.build_and_launch(program, sourcePath=program_dir)
- self.continue_to_exit()
- output = self.get_console()
+ session = self.build_and_create_session()
+ process_event = session.launch(
+ LaunchArgs(program=program, sourcePath=program_dir)
+ )
+ session.verify_process_exited(after=process_event)
+
+ output = session.get_console()
self.assertTrue(output and len(output) > 0, "expect console output")
- lines = output.splitlines()
prefix = '(lldb) settings set target.source-map "." '
found = False
- for line in lines:
+ for line in output.splitlines():
if line.startswith(prefix):
found = True
- quoted_path = '"%s"' % (program_dir)
+ quoted_path = f'"{program_dir}"'
self.assertEqual(
quoted_path,
line[len(prefix) :],
- "lldb-dap working dir %s == %s" % (quoted_path, line[6:]),
+ f"lldb-dap working dir {quoted_path} == {line[6:]}",
)
self.assertTrue(found, 'found "sourcePath" in console output')
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stdio_redirection.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stdio_redirection.py
index 8150170..21d3110 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stdio_redirection.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stdio_redirection.py
@@ -2,22 +2,26 @@
Test lldb-dap launch request.
"""
-import lldbdap_testcase
import tempfile
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_stdio_redirection(lldbdap_testcase.DAPTestCaseBase):
+
+class TestDAP_launch_stdio_redirection(DAPTestCaseBase):
"""
Test stdio redirection.
"""
def test(self):
- self.build_and_create_debug_adapter()
program = self.getBuildArtifact("a.out")
+ session = self.build_and_create_session()
with tempfile.NamedTemporaryFile("rt") as f:
- self.launch_and_configurationDone(program, stdio=[None, f.name])
- self.verify_process_exited()
+ process_event = session.launch(
+ LaunchArgs(program=program, stdio=[None, f.name])
+ )
+ session.verify_process_exited(after=process_event)
lines = f.readlines()
self.assertIn(
program, lines[0], "make sure program path is in first argument"
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stdio_redirection_and_console.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stdio_redirection_and_console.py
index f4512a5..fa503c2 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stdio_redirection_and_console.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stdio_redirection_and_console.py
@@ -2,18 +2,20 @@
Test lldb-dap launch request.
"""
-from lldbsuite.test.decorators import (
- skipIfAsan,
- skipIf,
- skipIfBuildType,
- no_match,
- skipIfWindows,
-)
-import lldbdap_testcase
import tempfile
+from lldbsuite.test.decorators import (
+ no_match,
+ skipIf,
+ skipIfAsan,
+ skipIfBuildType,
+ skipIfWindows,
+)
+from lldbsuite.test.tools.lldb_dap.dap_types import Console, LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_stdio_redirection_and_console(lldbdap_testcase.DAPTestCaseBase):
+
+class TestDAP_launch_stdio_redirection_and_console(DAPTestCaseBase):
"""
Test stdio redirection and console.
"""
@@ -23,14 +25,18 @@
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
@skipIfBuildType(["debug"])
def test(self):
- self.build_and_create_debug_adapter()
program = self.getBuildArtifact("a.out")
+ session = self.build_and_create_session()
with tempfile.NamedTemporaryFile("rt") as f:
- self.launch_and_configurationDone(
- program, console="integratedTerminal", stdio=[None, f.name, None]
+ process_event = session.launch(
+ LaunchArgs(
+ program=program,
+ console=Console.INTEGRATED_TERMINAL,
+ stdio=[None, f.name, None],
+ )
)
- self.verify_process_exited()
+ session.verify_process_exited(after=process_event)
lines = f.readlines()
self.assertIn(
program, lines[0], "make sure program path is in first argument"
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stopOnEntry.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stopOnEntry.py
index 24ceaf3..bbeefc5 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stopOnEntry.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_stopOnEntry.py
@@ -2,10 +2,15 @@
Test lldb-dap launch request.
"""
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import (
+ ExitedEvent,
+ LaunchArgs,
+ StoppedEvent,
+)
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_stopOnEntry(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_stopOnEntry(DAPTestCaseBase):
"""
Tests the default launch of a simple program that stops at the
entry point instead of continuing.
@@ -13,16 +18,25 @@
def test(self):
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program, stopOnEntry=True)
- self.dap_server.request_configurationDone()
- self.dap_server.wait_for_stopped()
- self.assertTrue(
- len(self.dap_server.thread_stop_reasons) > 0,
- "expected stopped event during launch",
+ session = self.build_and_create_session()
+ process_event = session.launch(LaunchArgs(program, stopOnEntry=True))
+ stop_event = session.verify_stopped_on_entry(after=process_event)
+ exit_event = session.continue_to_exit()
+
+ seen_stop_events = []
+
+ def matches_exit_event(evt):
+ if isinstance(evt, StoppedEvent):
+ seen_stop_events.append(evt)
+ return evt.seq == exit_event.seq
+
+ # Collect stopped events until the ExitEvent.
+ session.wait_for_any_event(
+ (StoppedEvent, ExitedEvent), after=stop_event, until=matches_exit_event
)
- for _, body in self.dap_server.thread_stop_reasons.items():
- if "reason" in body:
- reason = body["reason"]
- self.assertNotEqual(
- reason, "breakpoint", 'verify stop isn\'t "main" breakpoint'
- )
+ # Verify we did not receive any other stop event.
+ self.assertEqual(
+ len(seen_stop_events),
+ 0,
+ f"expected no new stopped events. seen events: {seen_stop_events}",
+ )
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_terminate_commands.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_terminate_commands.py
index e2eed86..7e89a38 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_terminate_commands.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_terminate_commands.py
@@ -2,32 +2,35 @@
Test lldb-dap launch request.
"""
-from lldbsuite.test.decorators import skipIfNetBSD, skipIf
-import lldbdap_testcase
+from lldbsuite.test.decorators import skipIf, skipIfNetBSD
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_terminate_commands(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_terminate_commands(DAPTestCaseBase):
"""
- Tests that the "terminateCommands", that can be passed during
- launch, are run when the debugger is disconnected.
+ Tests that the "terminateCommands", that can be passed during launch,
+ are run when the debugger is disconnected.
"""
@skipIfNetBSD # Hangs on NetBSD as well
@skipIf(archs=["arm$", "aarch64"], oslist=["linux"])
def test(self):
- self.build_and_create_debug_adapter()
program = self.getBuildArtifact("a.out")
+ session = self.build_and_create_session(disconnect_automatically=False)
- terminateCommands = ["expr 4+2"]
- self.launch(
- program,
- stopOnEntry=True,
- terminateCommands=terminateCommands,
- disconnectAutomatically=False,
+ terminate_commands = ["history"]
+ process_event = session.launch(
+ LaunchArgs(
+ program=program,
+ stopOnEntry=True,
+ terminateCommands=terminate_commands,
+ )
)
- self.get_console()
- # Once it's disconnected the console should contain the
- # "terminateCommands"
- self.dap_server.request_disconnect(terminateDebuggee=True)
- output = self.collect_console(pattern=terminateCommands[0])
- self.verify_commands("terminateCommands", output, terminateCommands)
+ stop_event = session.verify_stopped_on_entry(after=process_event)
+ # Once it's disconnected the console should contain the "terminateCommands".
+ session.disconnect(terminateDebuggee=True)
+ output = session.collect_console(after=stop_event, until=terminate_commands[0])
+ session.verify_commands(
+ "terminateCommands", output.seen_texts, terminate_commands
+ )
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_termination.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_termination.py
index 71e5a45..35cad17 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_termination.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_termination.py
@@ -2,25 +2,41 @@
Test lldb-dap launch request.
"""
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap.utils import DebugAdapter
-class TestDAP_launch_termination(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_termination(DAPTestCaseBase):
"""
Tests the correct termination of lldb-dap upon a 'disconnect' request.
"""
- def test(self):
- self.create_debug_adapter()
- # The underlying lldb-dap process must be alive
- self.assertEqual(self.dap_server.process.poll(), None)
+ USE_DEFAULT_DEBUG_ADAPTER = False
+ def test_termination_socket(self):
+ adapter = self.create_server_debug_adapter(
+ connection="listen://localhost:0",
+ connection_timeout=1,
+ )
+ self.do_test_termination(adapter)
+
+ def test_termination_stdio(self):
+ adapter = self.create_stdio_debug_adapter()
+ self.do_test_termination(adapter)
+
+ def do_test_termination(self, adapter: DebugAdapter):
+ # The underlying lldb-dap process must be alive.
+ self.assertTrue(adapter.is_alive, f"adapter is dead: {adapter.process.args}")
+ session = self.create_session(adapter, disconnect_automatically=False)
+
+ session.initialize_sequence(session.initialize_args)
# The lldb-dap process should finish even though
- # we didn't close the communication socket explicitly
- self.dap_server.request_disconnect()
+ # we didn't close the communication socket explicitly.
+ session.disconnect()
# Wait until the underlying lldb-dap process dies.
- self.dap_server.process.wait(timeout=self.DEFAULT_TIMEOUT)
+ adapter.process.wait(timeout=self.DEFAULT_TIMEOUT)
+ self.assertFalse(session.is_running(), f"expected ended session.")
- # Check the return code
- self.assertEqual(self.dap_server.process.poll(), 0)
+ # Check the return code.
+ self.assertEqual(adapter.process.poll(), 0)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_version.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_version.py
index fca1530..0c3609f 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_version.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_version.py
@@ -1,13 +1,8 @@
-"""
-Test lldb-dap launch request.
-"""
-
-from lldbsuite.test.decorators import expectedFailureWindows
-from lldbsuite.test.lldbtest import line_number
-import lldbdap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-class TestDAP_launch_version(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_launch_version(DAPTestCaseBase):
"""
Tests that "initialize" response contains the "version" string the same
as the one returned by "version" command.
@@ -15,21 +10,14 @@
def test(self):
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
+ session = self.build_and_create_session()
- source = "main.c"
- breakpoint_line = line_number(source, "// breakpoint 1")
- lines = [breakpoint_line]
- # Set breakpoint in the thread function so we can step the threads
- breakpoint_ids = self.set_source_breakpoints(source, lines)
- self.continue_to_breakpoints(breakpoint_ids)
+ process_event = session.launch(LaunchArgs(program=program, stopOnEntry=True))
+ session.verify_stopped_on_entry(after=process_event)
- version_eval_response = self.dap_server.request_evaluate(
- "`version", context="repl"
- )
- version_eval_output = version_eval_response["body"]["result"]
+ version_eval_output = session.evaluate("`version", context="repl").result
+ version_string = self.expect_not_none(session.capabilities().lldb_version)
- version_string = self.dap_server.get_capability("$__lldb_version")
self.assertEqual(
version_eval_output.splitlines(),
version_string.splitlines(),
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index 75f3bc3..078f607 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Base64.h"
#include "llvm/Support/JSON.h"
+#include <optional>
#include <utility>
using namespace llvm;
@@ -35,13 +36,15 @@
return true;
if (const json::Object *env_obj = value->getAsObject()) {
- for (const auto &kv : *env_obj) {
- const std::optional<StringRef> value = kv.second.getAsString();
- if (!value) {
- P.field("env").field(kv.first).report("expected string value");
+ for (const auto &[key, val] : *env_obj) {
+ if (const std::optional<StringRef> val_str = val.getAsString()) {
+ env.insert({key.str(), val_str->str()});
+ } else if (val.getAsNull()) {
+ env.insert({key.str(), ""});
+ } else {
+ P.field("env").field(key).report("expected string value");
return false;
}
- env.insert({kv.first.str(), value->str()});
}
return true;
}