-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[LLDB-DAP] Send Progress update message over DAP #123837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
bc7bb24
faefdb6
56846b2
f6d8d81
e7bc902
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| CXX_SOURCES := main.cpp | ||
|
|
||
| include Makefile.rules |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| import inspect | ||
| import optparse | ||
| import shlex | ||
| import sys | ||
| import time | ||
|
|
||
| import lldb | ||
|
|
||
|
|
||
| class ProgressTesterCommand: | ||
| program = "test-progress" | ||
|
|
||
| @classmethod | ||
| def register_lldb_command(cls, debugger, module_name): | ||
| parser = cls.create_options() | ||
| cls.__doc__ = parser.format_help() | ||
| # Add any commands contained in this module to LLDB | ||
| command = "command script add -c %s.%s %s" % ( | ||
| module_name, | ||
| cls.__name__, | ||
| cls.program, | ||
| ) | ||
| debugger.HandleCommand(command) | ||
| print( | ||
| 'The "{0}" command has been installed, type "help {0}" or "{0} ' | ||
| '--help" for detailed help.'.format(cls.program) | ||
| ) | ||
|
|
||
| @classmethod | ||
| def create_options(cls): | ||
| usage = "usage: %prog [options]" | ||
| description = "Jacob Lalonde's sbprogress testing tool" | ||
| # Opt parse is deprecated, but leaving this the way it is because it allows help formating | ||
| # Additionally all our commands use optparse right now, ideally we migrate them all in one go. | ||
| parser = optparse.OptionParser( | ||
| description=description, prog=cls.program, usage=usage | ||
| ) | ||
|
|
||
| parser.add_option( | ||
| "--total", dest="total", help="Total to count up.", type="int" | ||
| ) | ||
|
|
||
| parser.add_option( | ||
| "--seconds", | ||
| dest="seconds", | ||
| help="Total number of seconds to wait between increments", | ||
| type="int", | ||
| ) | ||
|
|
||
| return parser | ||
|
|
||
| def get_short_help(self): | ||
| return "Progress Tester" | ||
|
|
||
| def get_long_help(self): | ||
| return self.help_string | ||
|
|
||
| def __init__(self, debugger, unused): | ||
| self.parser = self.create_options() | ||
| self.help_string = self.parser.format_help() | ||
|
|
||
| def __call__(self, debugger, command, exe_ctx, result): | ||
| command_args = shlex.split(command) | ||
| try: | ||
| (cmd_options, args) = self.parser.parse_args(command_args) | ||
| except: | ||
| result.SetError("option parsing failed") | ||
| return | ||
|
|
||
| total = cmd_options.total | ||
| progress = lldb.SBProgress("Progress tester", "Detail", total, debugger) | ||
|
|
||
| # This actually should start at 1 but it's 6:30 on a Friday... | ||
Jlalond marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| for i in range(1, total): | ||
| progress.Increment(1, f"Step {i}") | ||
| time.sleep(cmd_options.seconds) | ||
|
|
||
|
|
||
| def __lldb_init_module(debugger, dict): | ||
| # Register all classes that have a register_lldb_command method | ||
| for _name, cls in inspect.getmembers(sys.modules[__name__]): | ||
| if inspect.isclass(cls) and callable( | ||
| getattr(cls, "register_lldb_command", None) | ||
| ): | ||
| cls.register_lldb_command(debugger, __name__) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| """ | ||
| Test lldb-dap output events | ||
| """ | ||
|
|
||
| from lldbsuite.test.decorators import * | ||
| from lldbsuite.test.lldbtest import * | ||
| import os | ||
| import time | ||
|
|
||
| import lldbdap_testcase | ||
|
|
||
|
|
||
| class TestDAP_progress(lldbdap_testcase.DAPTestCaseBase): | ||
| @skipIfWindows | ||
| def test_output(self): | ||
| program = self.getBuildArtifact("a.out") | ||
| self.build_and_launch(program) | ||
| progress_emitter = os.path.join(os.getcwd(), "Progress_emitter.py") | ||
| print(f"Progress emitter path: {progress_emitter}") | ||
| source = "main.cpp" | ||
| # Set breakpoint in the thread function so we can step the threads | ||
| breakpoint_ids = self.set_source_breakpoints( | ||
| source, [line_number(source, "// break here")] | ||
| ) | ||
| self.continue_to_breakpoints(breakpoint_ids) | ||
| self.dap_server.request_evaluate( | ||
| f"`command script import {progress_emitter}", context="repl" | ||
| ) | ||
| self.dap_server.request_evaluate( | ||
| "`test-progress --total 3 --seconds 1", context="repl" | ||
| ) | ||
|
|
||
| self.dap_server.wait_for_event("progressEnd", 15) | ||
| # Expect at least a start, an update, and end event | ||
| # However because the progress is an RAII object and we can't guaruntee | ||
|
||
| # it's deterministic destruction in the python API, we verify just start and update | ||
| # otherwise this test could be flakey. | ||
| self.assertTrue(len(self.dap_server.progress_events) > 0) | ||
| start_found = False | ||
| update_found = False | ||
| for event in self.dap_server.progress_events: | ||
| event_type = event["event"] | ||
| if "progressStart" in event_type: | ||
| start_found = True | ||
| if "progressUpdate" in event_type: | ||
| update_found = True | ||
|
|
||
| self.assertTrue(start_found) | ||
| self.assertTrue(update_found) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| int main() { | ||
| char *ptr = "unused"; | ||
| // break here | ||
| return 0; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.