Skip to content

Commit 09ff41a

Browse files
committed
[lldb/test] Add events listener helper class to lldbtest
This patch introduces a generic helper class that will listen for event in a background thread and match it against a source broadcaster. If the event received matches the source broadcaster, the event is queued up in a list that the user can access later on. The motivation behind this is to easily test new kinds of events (i.e. Swift type-system progress events). However, this patch also updates `TestProgressReporting.py` and `TestDiagnosticReporting.py` to make use of this new helper class. Differential Revision: https://reviews.llvm.org/D121977 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 2d8b6a4 commit 09ff41a

File tree

3 files changed

+88
-86
lines changed

3 files changed

+88
-86
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import threading
2+
3+
import lldb
4+
from lldbsuite.test.lldbtest import *
5+
6+
class EventListenerTestBase(TestBase):
7+
8+
"""
9+
Base class for lldb event listener tests.
10+
11+
This class will setup and start an event listener for the test to use.
12+
13+
If the event received matches the source broadcaster, the event is
14+
queued up in a list that the user can access later on.
15+
"""
16+
NO_DEBUG_INFO_TESTCASE = True
17+
18+
eBroadcastBitStopListenerThread = (1 << 0)
19+
events = []
20+
event_mask = None
21+
event_data_extractor = None
22+
23+
def setUp(self):
24+
TestBase.setUp(self)
25+
26+
self.src_broadcaster = self.dbg.GetBroadcaster()
27+
self.broadcaster = lldb.SBBroadcaster('lldb.test.broadcaster')
28+
self.listener = lldb.SBListener("lldb.test.listener")
29+
self.listener.StartListeningForEvents(self.broadcaster,
30+
self.eBroadcastBitStopListenerThread)
31+
32+
self.src_broadcaster.AddListener(self.listener, self.event_mask)
33+
34+
self.listener_thread = threading.Thread(target=self._fetch_events)
35+
self.listener_thread.start()
36+
37+
def tearDown(self):
38+
# Broadcast a eBroadcastBitStopListenerThread` event so the background
39+
# thread stops listening to events, then join the background thread.
40+
self.broadcaster.BroadcastEventByType(self.eBroadcastBitStopListenerThread)
41+
self.listener_thread.join()
42+
TestBase.tearDown(self)
43+
44+
def _fetch_events(self):
45+
event = lldb.SBEvent()
46+
47+
done = False
48+
while not done:
49+
if self.listener.GetNextEvent(event):
50+
event_mask = event.GetType();
51+
if event.BroadcasterMatchesRef(self.broadcaster):
52+
if event_mask & self.eBroadcastBitStopListenerThread:
53+
done = True;
54+
elif event.BroadcasterMatchesRef(self.src_broadcaster):
55+
# NOTE: https://wiki.python.org/moin/FromFunctionToMethod
56+
#
57+
# When assigning the `event_data_extractor` function pointer
58+
# to the `EventListenerTestBase` instance, it turns the
59+
# function object into an instance method which subsequently
60+
# passes `self` as an extra argument.
61+
62+
# However, because most of the event data extractor
63+
# functions are static, passing the `self` argument makes
64+
# the number of passed arguments exceeds the function definition
65+
66+
# This is why we unwrap the function from the instance
67+
# method object calling `__func__` instead.
68+
ret_args = self.event_data_extractor.__func__(event);
69+
if not ret_args:
70+
continue
71+
72+
self.events.append(ret_args)

lldb/test/API/functionalities/diagnostic_reporting/TestDiagnosticReporting.py

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,20 @@
22
Test that we are able to broadcast and receive diagnostic events from lldb
33
"""
44
import lldb
5-
from lldbsuite.test.lldbtest import *
6-
from lldbsuite.test.decorators import *
5+
76
import lldbsuite.test.lldbutil as lldbutil
8-
import threading
97

8+
from lldbsuite.test.lldbtest import *
9+
from lldbsuite.test.eventlistener import EventListenerTestBase
1010

11-
class TestDiagnosticReporting(TestBase):
11+
class TestDiagnosticReporting(EventListenerTestBase):
1212

1313
mydir = TestBase.compute_mydir(__file__)
14-
15-
eBroadcastBitStopDiagnosticThread = (1 << 0)
16-
17-
def setUp(self):
18-
TestBase.setUp(self)
19-
self.diagnostic_events = []
20-
21-
def fetch_events(self):
22-
event = lldb.SBEvent()
23-
24-
done = False
25-
while not done:
26-
if self.listener.WaitForEvent(1, event):
27-
event_mask = event.GetType()
28-
if event.BroadcasterMatchesRef(self.test_broadcaster):
29-
if event_mask & self.eBroadcastBitStopDiagnosticThread:
30-
done = True
31-
elif event.BroadcasterMatchesRef(self.diagnostic_broadcaster):
32-
self.diagnostic_events.append(
33-
lldb.SBDebugger.GetDiagnosticFromEvent(event))
14+
event_mask = lldb.SBDebugger.eBroadcastBitWarning | lldb.SBDebugger.eBroadcastBitError
15+
event_data_extractor = lldb.SBDebugger.GetDiagnosticFromEvent
3416

3517
def test_dwarf_symbol_loading_diagnostic_report(self):
3618
"""Test that we are able to fetch diagnostic events"""
37-
self.listener = lldb.SBListener("lldb.diagnostic.listener")
38-
self.test_broadcaster = lldb.SBBroadcaster('lldb.broadcaster.test')
39-
self.listener.StartListeningForEvents(
40-
self.test_broadcaster, self.eBroadcastBitStopDiagnosticThread)
41-
42-
self.diagnostic_broadcaster = self.dbg.GetBroadcaster()
43-
self.diagnostic_broadcaster.AddListener(
44-
self.listener, lldb.SBDebugger.eBroadcastBitWarning)
45-
self.diagnostic_broadcaster.AddListener(
46-
self.listener, lldb.SBDebugger.eBroadcastBitError)
47-
48-
listener_thread = threading.Thread(target=self.fetch_events)
49-
listener_thread.start()
5019

5120
self.yaml2obj("minidump.yaml", self.getBuildArtifact("minidump.core"))
5221

@@ -55,13 +24,9 @@ def test_dwarf_symbol_loading_diagnostic_report(self):
5524
self.process = self.target.LoadCore(
5625
self.getBuildArtifact("minidump.core"))
5726

58-
self.test_broadcaster.BroadcastEventByType(
59-
self.eBroadcastBitStopDiagnosticThread)
60-
listener_thread.join()
61-
62-
self.assertEquals(len(self.diagnostic_events), 1)
27+
self.assertEquals(len(self.events), 1)
6328

64-
diagnostic_event = self.diagnostic_events[0]
29+
diagnostic_event = self.events[0]
6530
self.assertEquals(
6631
diagnostic_event.GetValueForKey("type").GetStringValue(100),
6732
"warning")

lldb/test/API/functionalities/progress_reporting/TestProgressReporting.py

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,22 @@
22
Test that we are able to broadcast and receive progress events from lldb
33
"""
44
import lldb
5-
from lldbsuite.test.lldbtest import *
6-
from lldbsuite.test.decorators import *
7-
import lldbsuite.test.lldbutil as lldbutil
8-
import threading
95

10-
class TestProgressReporting(TestBase):
11-
12-
mydir = TestBase.compute_mydir(__file__)
13-
14-
eBroadcastBitStopProgressThread = (1 << 0)
6+
import lldbsuite.test.lldbutil as lldbutil
157

16-
def setUp(self):
17-
TestBase.setUp(self)
18-
self.progress_events = []
8+
from lldbsuite.test.lldbtest import *
9+
from lldbsuite.test.eventlistener import EventListenerTestBase
1910

20-
def fetch_events(self):
21-
event = lldb.SBEvent()
2211

23-
done = False
24-
while not done:
25-
if self.listener.WaitForEvent(1, event):
26-
event_mask = event.GetType();
27-
if event.BroadcasterMatchesRef(self.test_broadcaster):
28-
if event_mask & self.eBroadcastBitStopProgressThread:
29-
done = True;
30-
elif event.BroadcasterMatchesRef(self.progress_broadcaster):
31-
ret_args = lldb.SBDebugger().GetProgressFromEvent(event);
32-
self.assertGreater(len(ret_args), 1)
12+
class TestProgressReporting(EventListenerTestBase):
3313

34-
message = ret_args[0]
35-
if message:
36-
self.progress_events.append((message, event))
14+
mydir = TestBase.compute_mydir(__file__)
15+
event_mask = lldb.SBDebugger.eBroadcastBitProgress
16+
event_data_extractor = lldb.SBDebugger.GetProgressFromEvent
3717

3818
def test_dwarf_symbol_loading_progress_report(self):
3919
"""Test that we are able to fetch dwarf symbol loading progress events"""
4020
self.build()
4121

42-
self.listener = lldb.SBListener("lldb.progress.listener")
43-
self.test_broadcaster = lldb.SBBroadcaster('lldb.broadcaster.test')
44-
self.listener.StartListeningForEvents(self.test_broadcaster,
45-
self.eBroadcastBitStopProgressThread)
46-
47-
self.progress_broadcaster = self.dbg.GetBroadcaster()
48-
self.progress_broadcaster.AddListener(self.listener, lldb.SBDebugger.eBroadcastBitProgress)
49-
50-
listener_thread = threading.Thread(target=self.fetch_events)
51-
listener_thread.start()
52-
5322
lldbutil.run_to_source_breakpoint(self, 'break here', lldb.SBFileSpec('main.c'))
54-
55-
self.test_broadcaster.BroadcastEventByType(self.eBroadcastBitStopProgressThread)
56-
listener_thread.join()
57-
58-
self.assertGreater(len(self.progress_events), 0)
23+
self.assertGreater(len(self.events), 0)

0 commit comments

Comments
 (0)