https://github.com/da-viper created https://github.com/llvm/llvm-project/pull/211597
None >From f4acc1c4ec09d5c638c937e091720cf4c4400efd Mon Sep 17 00:00:00 2001 From: Ebuka Ezike <[email protected]> Date: Thu, 23 Jul 2026 16:57:55 +0100 Subject: [PATCH] [lldb-dap] Migrate optimized, output and repl_mode_detection tests --- .../lldb-dap/optimized/TestDAP_optimized.py | 59 ++++++------- .../tools/lldb-dap/output/TestDAP_output.py | 44 +++++----- .../repl-mode/TestDAP_repl_mode_detection.py | 83 +++++++++++-------- 3 files changed, 103 insertions(+), 83 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/optimized/TestDAP_optimized.py b/lldb/test/API/tools/lldb-dap/optimized/TestDAP_optimized.py index 3b769d2dd89ce..d76cc14e64c10 100644 --- a/lldb/test/API/tools/lldb-dap/optimized/TestDAP_optimized.py +++ b/lldb/test/API/tools/lldb-dap/optimized/TestDAP_optimized.py @@ -2,56 +2,57 @@ Test lldb-dap variables/stackTrace request for optimized code """ -import dap_server -import lldbdap_testcase -from lldbsuite.test import lldbutil -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import skipIfAsan, skipIfWindows +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap.types import LaunchArgs +from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase -class TestDAP_optimized(lldbdap_testcase.DAPTestCaseBase): +class TestDAP_optimized(DAPTestCaseBase): @skipIfWindows def test_stack_frame_name(self): """Test optimized frame has special name suffix.""" program = self.getBuildArtifact("a.out") - self.build_and_launch(program) + session = self.build_and_create_session() + source = "main.cpp" breakpoint_line = line_number(source, "// breakpoint 1") - lines = [breakpoint_line] - breakpoint_ids = self.set_source_breakpoints(source, lines) - self.assertEqual( - len(breakpoint_ids), len(lines), "expect correct number of breakpoints" + with session.configure(LaunchArgs(program)) as ctx: + bp_ids = session.resolve_source_breakpoints(source, [breakpoint_line]) + + stop_event = session.verify_stopped_on_breakpoint( + bp_ids, after=ctx.process_event ) - self.continue_to_breakpoints(breakpoint_ids) - leaf_frame = self.dap_server.get_stackFrame(frameIndex=0) - self.assertTrue(leaf_frame["name"].endswith(" [opt]")) - parent_frame = self.dap_server.get_stackFrame(frameIndex=1) - self.assertTrue(parent_frame["name"].endswith(" [opt]")) + frames = session.thread_context_from(stop_event).frames() + + leaf_frame = frames[0].frame + self.assertTrue(leaf_frame.name.endswith(" [opt]")) + parent_frame = frames[1].frame + self.assertTrue(parent_frame.name.endswith(" [opt]")) @skipIfAsan # On ASAN builds this test intermittently fails https://github.com/llvm/llvm-project/issues/111061 @skipIfWindows def test_optimized_variable(self): """Test optimized variable value contains error.""" program = self.getBuildArtifact("a.out") - self.build_and_launch(program) + session = self.build_and_create_session() source = "main.cpp" breakpoint_line = line_number(source, "// breakpoint 2") - lines = [breakpoint_line] - # Set breakpoint in the thread function so we can step the threads - breakpoint_ids = self.set_source_breakpoints(source, lines) - self.assertEqual( - len(breakpoint_ids), len(lines), "expect correct number of breakpoints" + with session.configure(LaunchArgs(program)) as ctx: + bp_ids = session.resolve_source_breakpoints(source, [breakpoint_line]) + + stop_event = session.verify_stopped_on_breakpoint( + bp_ids, after=ctx.process_event ) - self.continue_to_breakpoints(breakpoint_ids) - optimized_variable = self.dap_server.get_local_variable("argc") + optimized_variable = session.top_frame_from(stop_event).locals["argc"] + value = optimized_variable.value - value: str = optimized_variable["value"] self.assertTrue( - value.startswith("<error:"), - f"expect error for value: '{value}'", + value.startswith("<error:"), f"expect error for value: '{value}'" ) self.assertTrue( ("could not evaluate DW_OP_entry_value: no parent function" in value) - or ("variable not available" in value) + or ("variable not available" in value), + f"{value=}", ) - self.continue_to_exit() + session.continue_to_exit() diff --git a/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py b/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py index 0065258920ecb..a58de060263ce 100644 --- a/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py +++ b/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py @@ -2,21 +2,22 @@ Test lldb-dap output events """ -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -import lldbdap_testcase +from lldbsuite.test.decorators import skipIfWindows +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap.types import LaunchArgs +from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase -class TestDAP_output(lldbdap_testcase.DAPTestCaseBase): +class TestDAP_output(DAPTestCaseBase): @skipIfWindows def test_output(self): """ Test output handling for the running process. """ program = self.getBuildArtifact("a.out") - self.build_and_launch( + session = self.build_and_create_session(disconnect_automatically=False) + launch_args = LaunchArgs( program, - disconnectAutomatically=False, exitCommands=[ # Ensure that output produced by lldb itself is not consumed by the OutputRedirector. "?script print('out\\0\\0', end='\\r\\n', file=sys.stdout)", @@ -24,28 +25,31 @@ def test_output(self): ], ) source = "main.c" - lines = [line_number(source, "// breakpoint 1")] - breakpoint_ids = self.set_source_breakpoints(source, lines) - self.continue_to_breakpoints(breakpoint_ids) + breakpoint_line = line_number(source, "// breakpoint 1") + with session.configure(launch_args) as ctx: + bp_ids = session.resolve_source_breakpoints(source, [breakpoint_line]) + + process_event = ctx.process_event + session.verify_stopped_on_breakpoint(bp_ids, after=process_event) # Ensure partial messages are still sent. - output = self.collect_stdout(pattern="abcdef") - self.assertTrue(output and len(output) > 0, "expect program stdout") + partial_output = session.collect_stdout(after=process_event, until="abcdef") + self.assertGreater(len(partial_output.seen_texts), 0, "expect program stdout") - self.continue_to_exit() + session.continue_to_exit() # Disconnecting from the server to ensure any pending IO is flushed. - self.dap_server.request_disconnect() + session.disconnect() - output += self.get_stdout() - self.assertTrue(output and len(output) > 0, "expect program stdout") + stdout = session.get_stdout() + self.assertTrue(stdout, "expect program stdout") self.assertIn( "abcdefghi\r\nhello world\r\nfinally\0\0", - output, - "full stdout not found in: " + repr(output), + stdout, + "full stdout not found in: " + repr(stdout), ) - console = self.get_console() - self.assertTrue(console and len(console) > 0, "expect dap messages") + console = session.get_console() + self.assertTrue(console, "expect dap messages") self.assertIn( - "out\0\0\r\nerr\0\0\r\n", console, f"full console message not found" + "out\0\0\r\nerr\0\0\r\n", console, "full console message not found" ) diff --git a/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py b/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py index c6f59949d668e..c27a5c5237b6e 100644 --- a/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py +++ b/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py @@ -2,51 +2,66 @@ Test lldb-dap repl mode detection """ -import lldbdap_testcase -import dap_server -from lldbsuite.test import lldbutil -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * - - -class TestDAP_repl_mode_detection(lldbdap_testcase.DAPTestCaseBase): - def assertEvaluate(self, expression, regex): - self.assertRegex( - self.dap_server.request_evaluate(expression, context="repl")["body"][ - "result" - ], - regex, - ) +from typing import Optional + +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap.types import LaunchArgs +from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase + + +class TestDAP_repl_mode_detection(DAPTestCaseBase): + def assertEvaluate( + self, expression: str, regex: str, frame_id: Optional[int] = None + ): + result = self._session.evaluate( + expression, context="repl", frameId=frame_id + ).result + self.assertRegex(result, regex) def test_completions(self): program = self.getBuildArtifact("a.out") - self.build_and_launch(program) + session = self.build_and_create_session() + self._session = session source = "main.cpp" breakpoint1_line = line_number(source, "// breakpoint 1") breakpoint2_line = line_number(source, "// breakpoint 2") - self.set_source_breakpoints(source, [breakpoint1_line, breakpoint2_line]) + with session.configure(LaunchArgs(program)) as ctx: + session.resolve_source_breakpoints( + source, [breakpoint1_line, breakpoint2_line] + ) - # The result of the commands should return the empty string. - self.assertEvaluate("`command regex user_command s/^$/platform/", r"^$") - self.assertEvaluate("`command alias alias_command platform", r"^$") - self.assertEvaluate( - "`command alias alias_command_with_arg platform select --sysroot %1 remote-linux", - r"^$", - ) + self.assertEvaluate("lldb-dap repl-mode", "auto") + # The result of the commands should return the empty string. + self.assertEvaluate("`command regex user_command s/^$/platform/", r"^$") + self.assertEvaluate("`command alias alias_command platform", r"^$") + self.assertEvaluate( + "`command alias alias_command_with_arg platform select --sysroot %1 remote-linux", + r"^$", + ) - self.continue_to_next_stop() - self.assertEvaluate("user_command", "474747") - self.assertEvaluate("alias_command", "474747") - self.assertEvaluate("alias_command_with_arg", "474747") - self.assertEvaluate("platform", "474747") + # Stop in `fun`. Locals shadow the command names, so evaluating + # the identifiers should return the local integer values. + stop_event = session.verify_stopped_on_breakpoint(after=ctx.process_event) + top_frame_id = session.top_frame_from(stop_event).id - self.continue_to_next_stop() + self.assertEvaluate("user_command", "474747", top_frame_id) + self.assertEvaluate("alias_command", "474747", top_frame_id) + self.assertEvaluate("alias_command_with_arg", "474747", top_frame_id) + self.assertEvaluate("platform", "474747", top_frame_id) + + # Stop back in `main`. With no shadowing locals, the same names + # should resolve to their lldb command counterparts. + stop_event = session.continue_to_next_stop() + top_frame_id = session.top_frame_from(stop_event).id platform_help_needle = "Commands to manage and create platforms" - self.assertEvaluate("user_command", platform_help_needle) - self.assertEvaluate("alias_command", platform_help_needle) + + self.assertEvaluate("user_command", platform_help_needle, top_frame_id) + self.assertEvaluate("alias_command", platform_help_needle, top_frame_id) self.assertEvaluate( - "alias_command_with_arg " + self.getBuildDir(), "Platform: remote-linux" + "alias_command_with_arg " + self.getBuildDir(), + "Platform: remote-linux", + top_frame_id, ) - self.assertEvaluate("platform", platform_help_needle) + self.assertEvaluate("platform", platform_help_needle, top_frame_id) _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
