Skip to content

Commit 56846b2

Browse files
committed
Add new test for progress
1 parent faefdb6 commit 56846b2

File tree

4 files changed

+143
-0
lines changed

4 files changed

+143
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CXX_SOURCES := main.cpp
2+
3+
include Makefile.rules
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import inspect
2+
import optparse
3+
import shlex
4+
import sys
5+
import time
6+
7+
import lldb
8+
9+
10+
class ProgressTesterCommand:
11+
program = "test-progress"
12+
13+
@classmethod
14+
def register_lldb_command(cls, debugger, module_name):
15+
parser = cls.create_options()
16+
cls.__doc__ = parser.format_help()
17+
# Add any commands contained in this module to LLDB
18+
command = "command script add -c %s.%s %s" % (
19+
module_name,
20+
cls.__name__,
21+
cls.program,
22+
)
23+
debugger.HandleCommand(command)
24+
print(
25+
'The "{0}" command has been installed, type "help {0}" or "{0} '
26+
'--help" for detailed help.'.format(cls.program)
27+
)
28+
29+
@classmethod
30+
def create_options(cls):
31+
usage = "usage: %prog [options]"
32+
description = "Jacob Lalonde's sbprogress testing tool"
33+
# Opt parse is deprecated, but leaving this the way it is because it allows help formating
34+
# Additionally all our commands use optparse right now, ideally we migrate them all in one go.
35+
parser = optparse.OptionParser(
36+
description=description, prog=cls.program, usage=usage
37+
)
38+
39+
parser.add_option(
40+
"--total", dest="total", help="Total to count up.", type="int"
41+
)
42+
43+
parser.add_option(
44+
"--seconds",
45+
dest="seconds",
46+
help="Total number of seconds to wait between increments",
47+
type="int",
48+
)
49+
50+
return parser
51+
52+
def get_short_help(self):
53+
return "Progress Tester"
54+
55+
def get_long_help(self):
56+
return self.help_string
57+
58+
def __init__(self, debugger, unused):
59+
self.parser = self.create_options()
60+
self.help_string = self.parser.format_help()
61+
62+
def __call__(self, debugger, command, exe_ctx, result):
63+
64+
command_args = shlex.split(command)
65+
try:
66+
(cmd_options, args) = self.parser.parse_args(command_args)
67+
except:
68+
result.SetError("option parsing failed")
69+
return
70+
71+
total = cmd_options.total
72+
progress = lldb.SBProgress("Progress tester", "Detail", total, debugger)
73+
74+
# This actually should start at 1 but it's 6:30 on a Friday...
75+
for i in range(1, total):
76+
progress.Increment(1, f"Step {i}")
77+
time.sleep(cmd_options.seconds)
78+
79+
80+
def __lldb_init_module(debugger, dict):
81+
# Register all classes that have a register_lldb_command method
82+
for _name, cls in inspect.getmembers(sys.modules[__name__]):
83+
if inspect.isclass(cls) and callable(
84+
getattr(cls, "register_lldb_command", None)
85+
):
86+
cls.register_lldb_command(debugger, __name__)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""
2+
Test lldb-dap output events
3+
"""
4+
5+
from lldbsuite.test.decorators import *
6+
from lldbsuite.test.lldbtest import *
7+
import os
8+
import time
9+
10+
import lldbdap_testcase
11+
12+
13+
class TestDAP_progress(lldbdap_testcase.DAPTestCaseBase):
14+
@skipIfWindows
15+
def test_output(self):
16+
program = self.getBuildArtifact("a.out")
17+
self.build_and_launch(program)
18+
progress_emitter = os.path.join(os.getcwd(), "Progress_emitter.py")
19+
print(f"Progress emitter path: {progress_emitter}")
20+
source = "main.cpp"
21+
# Set breakpoint in the thread function so we can step the threads
22+
breakpoint_ids = self.set_source_breakpoints(
23+
source, [line_number(source, "// break here")]
24+
)
25+
self.continue_to_breakpoints(breakpoint_ids)
26+
self.dap_server.request_evaluate(
27+
f"`command script import {progress_emitter}", context="repl"
28+
)
29+
self.dap_server.request_evaluate(
30+
"`test-progress --total 3 --seconds 1", context="repl"
31+
)
32+
33+
self.dap_server.wait_for_event("progressEnd", 15)
34+
# Expect at least a start, an update, and end event
35+
# However because the progress is an RAII object and we can't guaruntee
36+
# it's deterministic destruction in the python API, we verify just start and update
37+
# otherwise this test could be flakey.
38+
self.assertTrue(len(self.dap_server.progress_events) > 0)
39+
start_found = False
40+
update_found = False
41+
for event in self.dap_server.progress_events:
42+
event_type = event["event"]
43+
if "progressStart" in event_type:
44+
start_found = True
45+
if "progressUpdate" in event_type:
46+
update_found = True
47+
48+
self.assertTrue(start_found)
49+
self.assertTrue(update_found)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
int main() {
2+
char *ptr = "unused";
3+
// break here
4+
return 0;
5+
}

0 commit comments

Comments
 (0)