Author: Ebuka Ezike Date: 2026-07-10T09:57:08+01:00 New Revision: 06e7dfcb3e64b2a4f13affeea5098860bedbd5bb
URL: https://github.com/llvm/llvm-project/commit/06e7dfcb3e64b2a4f13affeea5098860bedbd5bb DIFF: https://github.com/llvm/llvm-project/commit/06e7dfcb3e64b2a4f13affeea5098860bedbd5bb.diff LOG: [lldb-dap] Migrate all DAP module tests. (#207869) migrate tests module, moduleEvents and moduleSymbols Added: Modified: lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py lldb/test/API/tools/lldb-dap/module/TestDAP_module.py lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py Removed: ################################################################################ diff --git a/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py b/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py index bf64f7f822ea2..63eb0e70a2f50 100644 --- a/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py +++ b/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py @@ -1,57 +1,56 @@ -import dap_server -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil -import lldbdap_testcase -import re +from lldbsuite.test.decorators import ( + skipIfTargetDoesNotSupportSharedLibraries, + skipIfWindows, +) +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs, StoppedReason +from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase @skipIfTargetDoesNotSupportSharedLibraries() -class TestDAP_module_event(lldbdap_testcase.DAPTestCaseBase): +class TestDAP_module_event(DAPTestCaseBase): @skipIfWindows def test_module_event(self): + session = self.build_and_create_session() program = self.getBuildArtifact("a.out") - self.build_and_launch(program) source = "main.cpp" - breakpoint1_line = line_number(source, "// breakpoint 1") - breakpoint2_line = line_number(source, "// breakpoint 2") - breakpoint3_line = line_number(source, "// breakpoint 3") - - breakpoint_ids = self.set_source_breakpoints( - source, [breakpoint1_line, breakpoint2_line, breakpoint3_line] + bp1_line = line_number(source, "// breakpoint 1") + bp2_line = line_number(source, "// breakpoint 2") + bp3_line = line_number(source, "// breakpoint 3") + + with session.configure(LaunchArgs(program=program)) as ctx: + [bp1, bp2, bp3] = session.resolve_source_breakpoints( + source, [bp1_line, bp2_line, bp3_line] + ) + # Wait for the breakpoint before dlopen. + before_dlopen_event = session.verify_stopped_on_breakpoint( + bp1, after=ctx.process_event ) - self.continue_to_breakpoints(breakpoint_ids) - - # We're now stopped at breakpoint 1 before the dlopen. Flush all the module events. - self.dap_server.wait_for_module_events() # Continue to the second breakpoint, before the dlclose. - self.continue_to_breakpoints(breakpoint_ids) + session.continue_to_breakpoint(bp2) # Make sure we got a module event for libother. - event = self.dap_server.wait_for_event(["module"]) - self.assertIsNotNone(event, "didn't get a module event") - module_name = event["body"]["module"]["name"] - module_id = event["body"]["module"]["id"] - self.assertEqual(event["body"]["reason"], "new") - self.assertIn("libother", module_name) + new_module_event = session.verify_next_module_event(after=before_dlopen_event) + module_id = new_module_event.body.module.id + self.assertEqual(new_module_event.body.reason, "new") + self.assertIn("libother", new_module_event.body.module.name) # Continue to the third breakpoint, after the dlclose. - self.continue_to_breakpoints(breakpoint_ids) + session.continue_to_breakpoint(bp3) # Make sure we got a module event for libother. - event = self.dap_server.wait_for_event(["module"]) - self.assertIsNotNone(event, "didn't get a module event") - reason = event["body"]["reason"] + removed_module_event = session.verify_next_module_event(after=new_module_event) + reason = removed_module_event.body.reason self.assertEqual(reason, "removed") - self.assertEqual(event["body"]["module"]["id"], module_id) + self.assertEqual(removed_module_event.body.module.id, module_id) # The removed module event should omit everything but the module id and name # as they are required fields. - module_data = event["body"]["module"] - required_keys = ["id", "name"] - self.assertListEqual(list(module_data.keys()), required_keys) - self.assertEqual(module_data["name"], "", "expects empty name.") + removed_module = removed_module_event.body.module + self.assertIsNotNone(removed_module.id) + self.assertIsNotNone(removed_module.name) + self.assertEqual(removed_module.name, "", "expects empty name.") - self.continue_to_exit() + session.continue_to_exit() diff --git a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py index 629427a4e138d..ce7a2b8dc8b1f 100644 --- a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py +++ b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py @@ -2,88 +2,95 @@ Test lldb-dap module request """ -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -import lldbdap_testcase +import platform import re +from lldbsuite.test.decorators import skipIfWindows, skipUnlessDarwin +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap.dap_types import ( + CompileUnitsArgs, + LaunchArgs, + ModuleEvent, + ModuleReason, +) +from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase -@skipIfTargetDoesNotSupportSharedLibraries() -class TestDAP_module(lldbdap_testcase.DAPTestCaseBase): - def run_test(self, symbol_basename, expect_debug_info_size): + +class TestDAP_module(DAPTestCaseBase): + def run_test(self, symbol_basename: str, expect_debug_info_size: bool): + session = self.build_and_create_session() program_basename = "a.out.stripped" program = self.getBuildArtifact(program_basename) - self.build_and_launch(program) - functions = ["foo"] - # This breakpoint will be resolved only when the libfoo module is loaded - breakpoint_ids = self.set_function_breakpoints( - functions, wait_for_resolve=False - ) - self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint") - self.continue_to_breakpoints(breakpoint_ids) - active_modules = self.dap_server.get_modules() + with session.configure(LaunchArgs(program)) as ctx: + # This breakpoint will be resolved only when the libfoo module is loaded. + breakpoints = session.set_function_breakpoints(["foo"]).body.breakpoints + self.assertEqual(len(breakpoints), 1, "expect one breakpoint.") + foo_bp_id = self.expect_not_none(breakpoints[0].id) + self.assertFalse(breakpoints[0].verified) + + session.verify_stopped_on_breakpoint(foo_bp_id, after=ctx.process_event) + active_modules = session.get_modules() program_module = active_modules[program_basename] self.assertIn( program_basename, active_modules, - "%s module is in active modules" % (program_basename), + f"{program_basename} module is in active modules", ) - self.assertIn("name", program_module, "make sure name is in module") - self.assertEqual(program_basename, program_module["name"]) - self.assertIn("path", program_module, "make sure path is in module") - self.assertEqual(program, program_module["path"]) - self.assertNotIn( - "symbolFilePath", - program_module, - "Make sure a.out.stripped has no debug info", + self.assertEqual(program_basename, program_module.name) + self.assertIsNotNone(program_module.path, "make sure path is in module") + self.assertEqual(program, program_module.path) + self.assertIsNone( + program_module.symbolFilePath, "Make sure a.out.stripped has no debug info" ) symbols_path = self.getBuildArtifact(symbol_basename) - self.dap_server.request_evaluate( - "`%s" % ('target symbols add -s "%s" "%s"' % (program, symbols_path)), - context="repl", + event_before_mod_change = session.last_event() + session.evaluate( + f'''`target symbols add -s "{program}" "{symbols_path}"''', context="repl" ) - def check_symbols_loaded_with_size(): - active_modules = self.dap_server.get_modules() - program_module = active_modules[program_basename] - self.assertIn("symbolFilePath", program_module) - self.assertIn(symbols_path, program_module["symbolFilePath"]) - size_regex = re.compile(r"[0-9]+(\.[0-9]*)?[KMG]?B") - return size_regex.match(program_module["debugInfoSize"]) + # Make sure we got an update event for the program module when the + # symbols got added. + changed_event = session.verify_next_module_event( + ModuleReason.CHANGED, after=event_before_mod_change + ) + changed_module = changed_event.body.module + self.assertEqual(program_module.name, changed_module.name) + self.assertIsNotNone(changed_module.symbolFilePath) + changed_symbols_path = self.expect_not_none(changed_module.symbolFilePath) + self.assertIn(symbols_path, changed_symbols_path) if expect_debug_info_size: - self.assertTrue( - self.wait_until(check_symbols_loaded_with_size), - "expect has debug info size", + changed_debug_size = self.expect_not_none(changed_module.debugInfoSize) + size_regex = re.compile(r"[0-9]+(\.[0-9]*)?[KMG]?B") + self.assertRegex( + changed_debug_size, size_regex, "expect has debug info size" ) - active_modules = self.dap_server.get_modules() + active_modules = session.get_modules() program_module = active_modules[program_basename] - self.assertEqual(program_basename, program_module["name"]) - self.assertEqual(program, program_module["path"]) - self.assertIn("addressRange", program_module) - - # Collect all the module names we saw as events. - module_new_names = [] - module_changed_names = [] - for module_event in self.dap_server.wait_for_module_events(): - reason = module_event["body"]["reason"] - if reason == "new": - module_new_names.append(module_event["body"]["module"]["name"]) - elif reason == "changed": - module_changed_names.append(module_event["body"]["module"]["name"]) + self.assertEqual(program_basename, program_module.name) + self.assertEqual(program, program_module.path) + self.assertIsNotNone(program_module.addressRange) + + # Collect all the modules added before we changed the program module. + new_module_names = [] + + def seen_module_changed_event(event: ModuleEvent): + if event.body.reason == ModuleReason.NEW: + new_module_names.append(event.body.module.name) + + return event.seq == changed_event.seq + + init_resp = ctx.init_response + session.wait_for_module_event(after=init_resp, until=seen_module_changed_event) # Make sure we got an event for every active module. - self.assertNotEqual(len(module_new_names), 0) + self.assertNotEqual(len(new_module_names), 0) for module in active_modules: - self.assertIn(module, module_new_names) + self.assertIn(module, new_module_names) - # Make sure we got an update event for the program module when the - # symbols got added. - self.assertNotEqual(len(module_changed_names), 0) - self.assertIn(program_module["name"], module_changed_names) - self.continue_to_exit() + session.continue_to_exit() @skipIfWindows def test_modules(self): @@ -112,18 +119,20 @@ def test_modules_dsym(self): @skipIfWindows def test_compile_units(self): + session = self.build_and_create_session() program = self.getBuildArtifact("a.out") - self.build_and_launch(program) source = "main.cpp" main_source_path = self.getSourcePath(source) - breakpoint1_line = line_number(source, "// breakpoint 1") - lines = [breakpoint1_line] - breakpoint_ids = self.set_source_breakpoints(source, lines) - self.continue_to_breakpoints(breakpoint_ids) - moduleId = self.dap_server.get_modules()["a.out"]["id"] - response = self.dap_server.request_compileUnits(moduleId) - self.assertTrue(response["body"]) - cu_paths = [cu["compileUnitPath"] for cu in response["body"]["compileUnits"]] + with session.configure(LaunchArgs(program)) as ctx: + breakpoint1_line = line_number(source, "// breakpoint 1") + bp_ids = session.resolve_source_breakpoints(source, [breakpoint1_line]) + process_event = ctx.process_event + + session.verify_stopped_on_breakpoint(bp_ids, after=process_event) + + module_id = session.get_modules()["a.out"].id + response = session.send_request(CompileUnitsArgs(module_id)).result() + cu_paths = [cu.compileUnitPath for cu in response.body.compileUnits] self.assertIn(main_source_path, cu_paths, "Real path to main.cpp matches") - self.continue_to_exit() + session.continue_to_exit() diff --git a/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py b/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py index 2336b9f2a5a1a..5a1edeb679bc5 100644 --- a/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py +++ b/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py @@ -2,11 +2,12 @@ Test lldb-dap moduleSymbols request """ -import lldbdap_testcase -from lldbsuite.test.decorators import * +from lldbsuite.test.decorators import skipIfWindows +from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs, ModuleSymbolsArgs +from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase -class TestDAP_moduleSymbols(lldbdap_testcase.DAPTestCaseBase): +class TestDAP_moduleSymbols(DAPTestCaseBase): # On windows LLDB doesn't recognize symbols in a.out. @skipIfWindows def test_moduleSymbols(self): @@ -14,27 +15,24 @@ def test_moduleSymbols(self): Test that the moduleSymbols request returns correct symbols from the module. """ program = self.getBuildArtifact("a.out") - self.build_and_launch(program) + session = self.build_and_create_session() + session.launch(LaunchArgs(program=program)) - symbol_names = [] - i = 0 + symbol_names = set() + start = 0 + page_size = 100 while True: - next_symbol = self.dap_server.request_moduleSymbols( - moduleName="a.out", startIndex=i, count=1 + module_sym_args = ModuleSymbolsArgs( + moduleName="a.out", startIndex=start, count=page_size ) - self.assertIn("symbols", next_symbol["body"]) - result_symbols = next_symbol["body"]["symbols"] - self.assertLessEqual(len(result_symbols), 1) - if len(result_symbols) == 0: - break + response = session.send_request(module_sym_args).result() + symbols = response.body.symbols + symbol_names.update(sym.name for sym in symbols) - self.assertIn("name", result_symbols[0]) - symbol_names.append(result_symbols[0]["name"]) - i += 1 - if i >= 1000: + if len(symbols) < page_size: break + start += page_size - self.assertGreater(len(symbol_names), 0) self.assertIn("main", symbol_names) self.assertIn("func1", symbol_names) self.assertIn("func2", symbol_names) _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
