]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - packages/Python/lldbsuite/test/macosx/queues/TestQueues.py
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / packages / Python / lldbsuite / test / macosx / queues / TestQueues.py
1 """Test queues inspection SB APIs."""
2
3 from __future__ import print_function
4
5
6 import unittest2
7 import os
8 import time
9 import lldb
10 from lldbsuite.test.decorators import *
11 from lldbsuite.test.lldbtest import *
12 from lldbsuite.test import lldbutil
13
14
15 class TestQueues(TestBase):
16
17     mydir = TestBase.compute_mydir(__file__)
18
19     @skipUnlessDarwin
20     @add_test_categories(['pyapi'])
21     @expectedFailureAll(bugnumber="rdar://28658529")
22     def test_with_python_api(self):
23         """Test queues inspection SB APIs."""
24         self.build()
25         self.queues()
26         self.queues_with_libBacktraceRecording()
27
28     def setUp(self):
29         # Call super's setUp().
30         TestBase.setUp(self)
31         # Find the line numbers that we will step to in main:
32         self.main_source = "main.c"
33
34     def check_queue_for_valid_queue_id(self, queue):
35         self.assertTrue(
36             queue.GetQueueID() != 0, "Check queue %s for valid QueueID (got 0x%x)" %
37             (queue.GetName(), queue.GetQueueID()))
38
39     def check_running_and_pending_items_on_queue(
40             self, queue, expected_running, expected_pending):
41         self.assertTrue(
42             queue.GetNumPendingItems() == expected_pending,
43             "queue %s should have %d pending items, instead has %d pending items" %
44             (queue.GetName(),
45              expected_pending,
46              (queue.GetNumPendingItems())))
47         self.assertTrue(
48             queue.GetNumRunningItems() == expected_running,
49             "queue %s should have %d running items, instead has %d running items" %
50             (queue.GetName(),
51              expected_running,
52              (queue.GetNumRunningItems())))
53
54     def check_number_of_threads_owned_by_queue(self, queue, number_threads):
55         self.assertTrue(
56             queue.GetNumThreads() == number_threads,
57             "queue %s should have %d thread executing, but has %d" %
58             (queue.GetName(),
59              number_threads,
60              queue.GetNumThreads()))
61
62     def check_queue_kind(self, queue, kind):
63         expected_kind_string = "Unknown"
64         if kind == lldb.eQueueKindSerial:
65             expected_kind_string = "Serial queue"
66         if kind == lldb.eQueueKindConcurrent:
67             expected_kind_string = "Concurrent queue"
68         actual_kind_string = "Unknown"
69         if queue.GetKind() == lldb.eQueueKindSerial:
70             actual_kind_string = "Serial queue"
71         if queue.GetKind() == lldb.eQueueKindConcurrent:
72             actual_kind_string = "Concurrent queue"
73         self.assertTrue(
74             queue.GetKind() == kind,
75             "queue %s is expected to be a %s but it is actually a %s" %
76             (queue.GetName(),
77              expected_kind_string,
78              actual_kind_string))
79
80     def check_queues_threads_match_queue(self, queue):
81         for idx in range(0, queue.GetNumThreads()):
82             t = queue.GetThreadAtIndex(idx)
83             self.assertTrue(
84                 t.IsValid(), "Queue %s's thread #%d must be valid" %
85                 (queue.GetName(), idx))
86             self.assertTrue(
87                 t.GetQueueID() == queue.GetQueueID(),
88                 "Queue %s has a QueueID of %d but its thread #%d has a QueueID of %d" %
89                 (queue.GetName(),
90                  queue.GetQueueID(),
91                  idx,
92                  t.GetQueueID()))
93             self.assertTrue(
94                 t.GetQueueName() == queue.GetName(),
95                 "Queue %s has a QueueName of %s but its thread #%d has a QueueName of %s" %
96                 (queue.GetName(),
97                  queue.GetName(),
98                  idx,
99                  t.GetQueueName()))
100             self.assertTrue(
101                 t.GetQueue().GetQueueID() == queue.GetQueueID(),
102                 "Thread #%d's Queue's QueueID of %d is not the same as the QueueID of its owning queue %d" %
103                 (idx,
104                  t.GetQueue().GetQueueID(),
105                     queue.GetQueueID()))
106
107     def queues(self):
108         """Test queues inspection SB APIs without libBacktraceRecording."""
109         exe = os.path.join(os.getcwd(), "a.out")
110
111         target = self.dbg.CreateTarget(exe)
112         self.assertTrue(target, VALID_TARGET)
113         self.main_source_spec = lldb.SBFileSpec(self.main_source)
114         break1 = target.BreakpointCreateByName("stopper", 'a.out')
115         self.assertTrue(break1, VALID_BREAKPOINT)
116         process = target.LaunchSimple(
117             None, None, self.get_process_working_directory())
118         self.assertTrue(process, PROCESS_IS_VALID)
119         threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1)
120         if len(threads) != 1:
121             self.fail("Failed to stop at breakpoint 1.")
122
123         queue_submittor_1 = lldb.SBQueue()
124         queue_performer_1 = lldb.SBQueue()
125         queue_performer_2 = lldb.SBQueue()
126         queue_performer_3 = lldb.SBQueue()
127         for idx in range(0, process.GetNumQueues()):
128             q = process.GetQueueAtIndex(idx)
129             if q.GetName() == "com.apple.work_submittor_1":
130                 queue_submittor_1 = q
131             if q.GetName() == "com.apple.work_performer_1":
132                 queue_performer_1 = q
133             if q.GetName() == "com.apple.work_performer_2":
134                 queue_performer_2 = q
135             if q.GetName() == "com.apple.work_performer_3":
136                 queue_performer_3 = q
137
138         self.assertTrue(
139             queue_submittor_1.IsValid() and queue_performer_1.IsValid() and queue_performer_2.IsValid() and queue_performer_3.IsValid(),
140             "Got all four expected queues: %s %s %s %s" %
141             (queue_submittor_1.IsValid(),
142              queue_performer_1.IsValid(),
143              queue_performer_2.IsValid(),
144              queue_performer_3.IsValid()))
145
146         self.check_queue_for_valid_queue_id(queue_submittor_1)
147         self.check_queue_for_valid_queue_id(queue_performer_1)
148         self.check_queue_for_valid_queue_id(queue_performer_2)
149         self.check_queue_for_valid_queue_id(queue_performer_3)
150
151         self.check_number_of_threads_owned_by_queue(queue_submittor_1, 1)
152         self.check_number_of_threads_owned_by_queue(queue_performer_1, 1)
153         self.check_number_of_threads_owned_by_queue(queue_performer_2, 1)
154         self.check_number_of_threads_owned_by_queue(queue_performer_3, 4)
155
156         self.check_queue_kind(queue_submittor_1, lldb.eQueueKindSerial)
157         self.check_queue_kind(queue_performer_1, lldb.eQueueKindSerial)
158         self.check_queue_kind(queue_performer_2, lldb.eQueueKindSerial)
159         self.check_queue_kind(queue_performer_3, lldb.eQueueKindConcurrent)
160
161         self.check_queues_threads_match_queue(queue_submittor_1)
162         self.check_queues_threads_match_queue(queue_performer_1)
163         self.check_queues_threads_match_queue(queue_performer_2)
164         self.check_queues_threads_match_queue(queue_performer_3)
165
166         # We have threads running with all the different dispatch QoS service
167         # levels - find those threads and check that we can get the correct
168         # QoS name for each of them.
169
170         user_initiated_thread = lldb.SBThread()
171         user_interactive_thread = lldb.SBThread()
172         utility_thread = lldb.SBThread()
173         unspecified_thread = lldb.SBThread()
174         background_thread = lldb.SBThread()
175         for th in process.threads:
176             if th.GetName() == "user initiated QoS":
177                 user_initiated_thread = th
178             if th.GetName() == "user interactive QoS":
179                 user_interactive_thread = th
180             if th.GetName() == "utility QoS":
181                 utility_thread = th
182             if th.GetName() == "unspecified QoS":
183                 unspecified_thread = th
184             if th.GetName() == "background QoS":
185                 background_thread = th
186
187         self.assertTrue(
188             user_initiated_thread.IsValid(),
189             "Found user initiated QoS thread")
190         self.assertTrue(
191             user_interactive_thread.IsValid(),
192             "Found user interactive QoS thread")
193         self.assertTrue(utility_thread.IsValid(), "Found utility QoS thread")
194         self.assertTrue(
195             unspecified_thread.IsValid(),
196             "Found unspecified QoS thread")
197         self.assertTrue(
198             background_thread.IsValid(),
199             "Found background QoS thread")
200
201         stream = lldb.SBStream()
202         self.assertTrue(
203             user_initiated_thread.GetInfoItemByPathAsString(
204                 "requested_qos.printable_name",
205                 stream),
206             "Get QoS printable string for user initiated QoS thread")
207         self.assertTrue(
208             stream.GetData() == "User Initiated",
209             "user initiated QoS thread name is valid")
210         stream.Clear()
211         self.assertTrue(
212             user_interactive_thread.GetInfoItemByPathAsString(
213                 "requested_qos.printable_name",
214                 stream),
215             "Get QoS printable string for user interactive QoS thread")
216         self.assertTrue(
217             stream.GetData() == "User Interactive",
218             "user interactive QoS thread name is valid")
219         stream.Clear()
220         self.assertTrue(
221             utility_thread.GetInfoItemByPathAsString(
222                 "requested_qos.printable_name",
223                 stream),
224             "Get QoS printable string for utility QoS thread")
225         self.assertTrue(
226             stream.GetData() == "Utility",
227             "utility QoS thread name is valid")
228         stream.Clear()
229         self.assertTrue(
230             unspecified_thread.GetInfoItemByPathAsString(
231                 "requested_qos.printable_name",
232                 stream),
233             "Get QoS printable string for unspecified QoS thread")
234         self.assertTrue(
235             stream.GetData() == "User Initiated",
236             "unspecified QoS thread name is valid")
237         stream.Clear()
238         self.assertTrue(
239             background_thread.GetInfoItemByPathAsString(
240                 "requested_qos.printable_name",
241                 stream),
242             "Get QoS printable string for background QoS thread")
243         self.assertTrue(
244             stream.GetData() == "Background",
245             "background QoS thread name is valid")
246
247     def queues_with_libBacktraceRecording(self):
248         """Test queues inspection SB APIs with libBacktraceRecording present."""
249         exe = os.path.join(os.getcwd(), "a.out")
250
251         if not os.path.isfile(
252                 '/Applications/Xcode.app/Contents/Developer/usr/lib/libBacktraceRecording.dylib'):
253             self.skipTest(
254                 "Skipped because libBacktraceRecording.dylib was present on the system.")
255
256         if not os.path.isfile(
257                 '/usr/lib/system/introspection/libdispatch.dylib'):
258             self.skipTest(
259                 "Skipped because introspection libdispatch dylib is not present.")
260
261         target = self.dbg.CreateTarget(exe)
262         self.assertTrue(target, VALID_TARGET)
263
264         self.main_source_spec = lldb.SBFileSpec(self.main_source)
265
266         break1 = target.BreakpointCreateByName("stopper", 'a.out')
267         self.assertTrue(break1, VALID_BREAKPOINT)
268
269         # Now launch the process, and do not stop at entry point.
270         process = target.LaunchSimple(
271             None,
272             [
273                 'DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/usr/lib/libBacktraceRecording.dylib',
274                 'DYLD_LIBRARY_PATH=/usr/lib/system/introspection'],
275             self.get_process_working_directory())
276
277         self.assertTrue(process, PROCESS_IS_VALID)
278
279         # The stop reason of the thread should be breakpoint.
280         threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1)
281         if len(threads) != 1:
282             self.fail("Failed to stop at breakpoint 1.")
283
284         libbtr_module_filespec = lldb.SBFileSpec("libBacktraceRecording.dylib")
285         libbtr_module = target.FindModule(libbtr_module_filespec)
286         if not libbtr_module.IsValid():
287             self.skipTest(
288                 "Skipped because libBacktraceRecording.dylib was not loaded into the process.")
289
290         self.assertTrue(
291             process.GetNumQueues() >= 4,
292             "Found the correct number of queues.")
293
294         queue_submittor_1 = lldb.SBQueue()
295         queue_performer_1 = lldb.SBQueue()
296         queue_performer_2 = lldb.SBQueue()
297         queue_performer_3 = lldb.SBQueue()
298         for idx in range(0, process.GetNumQueues()):
299             q = process.GetQueueAtIndex(idx)
300             if q.GetName() == "com.apple.work_submittor_1":
301                 queue_submittor_1 = q
302             if q.GetName() == "com.apple.work_performer_1":
303                 queue_performer_1 = q
304             if q.GetName() == "com.apple.work_performer_2":
305                 queue_performer_2 = q
306             if q.GetName() == "com.apple.work_performer_3":
307                 queue_performer_3 = q
308
309         self.assertTrue(
310             queue_submittor_1.IsValid() and queue_performer_1.IsValid() and queue_performer_2.IsValid() and queue_performer_3.IsValid(),
311             "Got all four expected queues: %s %s %s %s" %
312             (queue_submittor_1.IsValid(),
313              queue_performer_1.IsValid(),
314              queue_performer_2.IsValid(),
315              queue_performer_3.IsValid()))
316
317         self.check_queue_for_valid_queue_id(queue_submittor_1)
318         self.check_queue_for_valid_queue_id(queue_performer_1)
319         self.check_queue_for_valid_queue_id(queue_performer_2)
320         self.check_queue_for_valid_queue_id(queue_performer_3)
321
322         self.check_running_and_pending_items_on_queue(queue_submittor_1, 1, 0)
323         self.check_running_and_pending_items_on_queue(queue_performer_1, 1, 3)
324         self.check_running_and_pending_items_on_queue(
325             queue_performer_2, 1, 9999)
326         self.check_running_and_pending_items_on_queue(queue_performer_3, 4, 0)
327
328         self.check_number_of_threads_owned_by_queue(queue_submittor_1, 1)
329         self.check_number_of_threads_owned_by_queue(queue_performer_1, 1)
330         self.check_number_of_threads_owned_by_queue(queue_performer_2, 1)
331         self.check_number_of_threads_owned_by_queue(queue_performer_3, 4)
332
333         self.check_queue_kind(queue_submittor_1, lldb.eQueueKindSerial)
334         self.check_queue_kind(queue_performer_1, lldb.eQueueKindSerial)
335         self.check_queue_kind(queue_performer_2, lldb.eQueueKindSerial)
336         self.check_queue_kind(queue_performer_3, lldb.eQueueKindConcurrent)
337
338         self.check_queues_threads_match_queue(queue_submittor_1)
339         self.check_queues_threads_match_queue(queue_performer_1)
340         self.check_queues_threads_match_queue(queue_performer_2)
341         self.check_queues_threads_match_queue(queue_performer_3)
342
343         self.assertTrue(queue_performer_2.GetPendingItemAtIndex(
344             0).IsValid(), "queue 2's pending item #0 is valid")
345         self.assertTrue(queue_performer_2.GetPendingItemAtIndex(0).GetAddress().GetSymbol(
346         ).GetName() == "doing_the_work_2", "queue 2's pending item #0 should be doing_the_work_2")
347         self.assertTrue(
348             queue_performer_2.GetNumPendingItems() == 9999,
349             "verify that queue 2 still has 9999 pending items")
350         self.assertTrue(queue_performer_2.GetPendingItemAtIndex(
351             9998).IsValid(), "queue 2's pending item #9998 is valid")
352         self.assertTrue(queue_performer_2.GetPendingItemAtIndex(9998).GetAddress().GetSymbol(
353         ).GetName() == "doing_the_work_2", "queue 2's pending item #0 should be doing_the_work_2")
354         self.assertTrue(queue_performer_2.GetPendingItemAtIndex(
355             9999).IsValid() == False, "queue 2's pending item #9999 is invalid")