xref: /llvm-project/lldb/unittests/Core/ProgressReportTest.cpp (revision 774c22686330f3ca43e48a1b8076eb30ae03dbd8)
1 //===-- ProgressReportTest.cpp --------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
10 #include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h"
11 #include "TestingSupport/SubsystemRAII.h"
12 #include "TestingSupport/TestUtilities.h"
13 #include "lldb/Core/Debugger.h"
14 #include "lldb/Core/Progress.h"
15 #include "lldb/Host/FileSystem.h"
16 #include "lldb/Host/HostInfo.h"
17 #include "lldb/Utility/Listener.h"
18 #include "gtest/gtest.h"
19 #include <memory>
20 #include <mutex>
21 #include <thread>
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 static std::chrono::milliseconds TIMEOUT(500);
27 
28 class ProgressReportTest : public ::testing::Test {
29 public:
30   ListenerSP CreateListenerFor(uint32_t bit) {
31     // Set up the debugger, make sure that was done properly.
32     ArchSpec arch("x86_64-apple-macosx-");
33     Platform::SetHostPlatform(
34         PlatformRemoteMacOSX::CreateInstance(true, &arch));
35 
36     m_debugger_sp = Debugger::CreateInstance();
37 
38     // Get the debugger's broadcaster.
39     Broadcaster &broadcaster = m_debugger_sp->GetBroadcaster();
40 
41     // Create a listener, make sure it can receive events and that it's
42     // listening to the correct broadcast bit.
43     m_listener_sp = Listener::MakeListener("progress-listener");
44     m_listener_sp->StartListeningForEvents(&broadcaster, bit);
45     return m_listener_sp;
46   }
47 
48 protected:
49   // The debugger's initialization function can't be called with no arguments
50   // so calling it using SubsystemRAII will cause the test build to fail as
51   // SubsystemRAII will call Initialize with no arguments. As such we set it up
52   // here the usual way.
53   void SetUp() override {
54     std::call_once(TestUtilities::g_debugger_initialize_flag,
55                    []() { Debugger::Initialize(nullptr); });
56   };
57 
58   DebuggerSP m_debugger_sp;
59   ListenerSP m_listener_sp;
60   SubsystemRAII<FileSystem, HostInfo, PlatformMacOSX, ProgressManager>
61       subsystems;
62 };
63 
64 TEST_F(ProgressReportTest, TestReportCreation) {
65   ListenerSP listener_sp = CreateListenerFor(lldb::eBroadcastBitProgress);
66   EventSP event_sp;
67   const ProgressEventData *data;
68 
69   // Scope this for RAII on the progress objects.
70   // Create progress reports and check that their respective events for having
71   // started and ended are broadcasted.
72   {
73     Progress progress1("Progress report 1", "Starting report 1");
74     Progress progress2("Progress report 2", "Starting report 2");
75     Progress progress3("Progress report 3", "Starting report 3");
76   }
77 
78   // Start popping events from the queue, they should have been recevied
79   // in this order:
80   // Starting progress: 1, 2, 3
81   // Ending progress: 3, 2, 1
82   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
83   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
84 
85   EXPECT_EQ(data->GetDetails(), "Starting report 1");
86   EXPECT_FALSE(data->IsFinite());
87   EXPECT_FALSE(data->GetCompleted());
88   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
89   EXPECT_EQ(data->GetMessage(), "Progress report 1: Starting report 1");
90 
91   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
92   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
93 
94   EXPECT_EQ(data->GetDetails(), "Starting report 2");
95   EXPECT_FALSE(data->IsFinite());
96   EXPECT_FALSE(data->GetCompleted());
97   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
98   EXPECT_EQ(data->GetMessage(), "Progress report 2: Starting report 2");
99 
100   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
101   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
102 
103   EXPECT_EQ(data->GetDetails(), "Starting report 3");
104   EXPECT_FALSE(data->IsFinite());
105   EXPECT_FALSE(data->GetCompleted());
106   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
107   EXPECT_EQ(data->GetMessage(), "Progress report 3: Starting report 3");
108 
109   // Progress report objects should be destroyed at this point so
110   // get each report from the queue and check that they've been
111   // destroyed in reverse order.
112   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
113   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
114 
115   EXPECT_EQ(data->GetTitle(), "Progress report 3");
116   EXPECT_TRUE(data->GetCompleted());
117   EXPECT_FALSE(data->IsFinite());
118   EXPECT_EQ(data->GetMessage(), "Progress report 3: Starting report 3");
119 
120   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
121   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
122 
123   EXPECT_EQ(data->GetTitle(), "Progress report 2");
124   EXPECT_TRUE(data->GetCompleted());
125   EXPECT_FALSE(data->IsFinite());
126   EXPECT_EQ(data->GetMessage(), "Progress report 2: Starting report 2");
127 
128   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
129   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
130 
131   EXPECT_EQ(data->GetTitle(), "Progress report 1");
132   EXPECT_TRUE(data->GetCompleted());
133   EXPECT_FALSE(data->IsFinite());
134   EXPECT_EQ(data->GetMessage(), "Progress report 1: Starting report 1");
135 }
136 
137 TEST_F(ProgressReportTest, TestReportDestructionWithPartialProgress) {
138   ListenerSP listener_sp = CreateListenerFor(lldb::eBroadcastBitProgress);
139   EventSP event_sp;
140   const ProgressEventData *data;
141 
142   // Create a finite progress report and only increment to a non-completed
143   // state before destruction.
144   {
145     Progress progress("Finite progress", "Report 1", 100);
146     progress.Increment(3);
147   }
148 
149   // Verify that the progress in the events are:
150   // 1. At construction: 0 out of 100
151   // 2. At increment: 3 out of 100
152   // 3. At destruction: 100 out of 100
153   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
154   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
155   EXPECT_EQ(data->GetDetails(), "Report 1");
156   EXPECT_TRUE(data->IsFinite());
157   EXPECT_EQ(data->GetCompleted(), (uint64_t)0);
158   EXPECT_EQ(data->GetTotal(), (uint64_t)100);
159   EXPECT_EQ(data->GetMessage(), "Finite progress: Report 1");
160 
161   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
162   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
163   EXPECT_EQ(data->GetDetails(), "Report 1");
164   EXPECT_TRUE(data->IsFinite());
165   EXPECT_EQ(data->GetCompleted(), (uint64_t)3);
166   EXPECT_EQ(data->GetTotal(), (uint64_t)100);
167   EXPECT_EQ(data->GetMessage(), "Finite progress: Report 1");
168 
169   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
170   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
171   EXPECT_EQ(data->GetDetails(), "Report 1");
172   EXPECT_TRUE(data->IsFinite());
173   EXPECT_EQ(data->GetCompleted(), (uint64_t)100);
174   EXPECT_EQ(data->GetTotal(), (uint64_t)100);
175   EXPECT_EQ(data->GetMessage(), "Finite progress: Report 1");
176 
177   // Create an infinite progress report and increment by some amount.
178   {
179     Progress progress("Infinite progress", "Report 2");
180     progress.Increment(3);
181   }
182 
183   // Verify that the progress in the events are:
184   // 1. At construction: 0
185   // 2. At increment: 3
186   // 3. At destruction: Progress::kNonDeterministicTotal
187   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
188   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
189   EXPECT_EQ(data->GetDetails(), "Report 2");
190   EXPECT_FALSE(data->IsFinite());
191   EXPECT_EQ(data->GetCompleted(), (uint64_t)0);
192   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
193   EXPECT_EQ(data->GetMessage(), "Infinite progress: Report 2");
194 
195   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
196   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
197   EXPECT_EQ(data->GetDetails(), "Report 2");
198   EXPECT_FALSE(data->IsFinite());
199   EXPECT_EQ(data->GetCompleted(), (uint64_t)3);
200   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
201   EXPECT_EQ(data->GetMessage(), "Infinite progress: Report 2");
202 
203   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
204   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
205   EXPECT_EQ(data->GetDetails(), "Report 2");
206   EXPECT_FALSE(data->IsFinite());
207   EXPECT_EQ(data->GetCompleted(), Progress::kNonDeterministicTotal);
208   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
209   EXPECT_EQ(data->GetMessage(), "Infinite progress: Report 2");
210 }
211 
212 TEST_F(ProgressReportTest, TestFiniteOverflow) {
213   ListenerSP listener_sp = CreateListenerFor(lldb::eBroadcastBitProgress);
214   EventSP event_sp;
215   const ProgressEventData *data;
216 
217   // Increment the report beyond its limit and make sure we only get one
218   // completed event.
219   {
220     Progress progress("Finite progress", "Report 1", 10);
221     progress.Increment(11);
222     progress.Increment(47);
223   }
224 
225   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
226   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
227   EXPECT_TRUE(data->IsFinite());
228   EXPECT_EQ(data->GetCompleted(), 0U);
229   EXPECT_EQ(data->GetTotal(), 10U);
230 
231   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
232   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
233   EXPECT_TRUE(data->IsFinite());
234   EXPECT_EQ(data->GetCompleted(), 10U);
235   EXPECT_EQ(data->GetTotal(), 10U);
236 
237   ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT));
238 }
239 
240 TEST_F(ProgressReportTest, TestNonDeterministicOverflow) {
241   ListenerSP listener_sp = CreateListenerFor(lldb::eBroadcastBitProgress);
242   EventSP event_sp;
243   const ProgressEventData *data;
244   constexpr uint64_t max_minus_1 = std::numeric_limits<uint64_t>::max() - 1;
245 
246   // Increment the report beyond its limit and make sure we only get one
247   // completed event. The event which overflows the counter should be ignored.
248   {
249     Progress progress("Non deterministic progress", "Report 1");
250     progress.Increment(max_minus_1);
251     progress.Increment(max_minus_1);
252   }
253 
254   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
255   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
256   EXPECT_FALSE(data->IsFinite());
257   EXPECT_EQ(data->GetCompleted(), 0U);
258   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
259 
260   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
261   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
262   EXPECT_FALSE(data->IsFinite());
263   EXPECT_EQ(data->GetCompleted(), max_minus_1);
264   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
265 
266   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
267   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
268   EXPECT_FALSE(data->IsFinite());
269   EXPECT_EQ(data->GetCompleted(), Progress::kNonDeterministicTotal);
270   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
271 
272   ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT));
273 }
274 
275 TEST_F(ProgressReportTest, TestMinimumReportTime) {
276   ListenerSP listener_sp = CreateListenerFor(lldb::eBroadcastBitProgress);
277   EventSP event_sp;
278   const ProgressEventData *data;
279 
280   {
281     Progress progress("Finite progress", "Report 1", /*total=*/20,
282                       m_debugger_sp.get(),
283                       /*minimum_report_time=*/std::chrono::seconds(1));
284     // Send 10 events in quick succession. These should not generate any events.
285     for (int i = 0; i < 10; ++i)
286       progress.Increment();
287 
288     // Sleep, then send 10 more. This should generate one event for the first
289     // increment, and then another for completion.
290     std::this_thread::sleep_for(std::chrono::seconds(1));
291     for (int i = 0; i < 10; ++i)
292       progress.Increment();
293   }
294 
295   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
296   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
297   EXPECT_TRUE(data->IsFinite());
298   EXPECT_EQ(data->GetCompleted(), 0U);
299   EXPECT_EQ(data->GetTotal(), 20U);
300 
301   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
302   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
303   EXPECT_TRUE(data->IsFinite());
304   EXPECT_EQ(data->GetCompleted(), 11U);
305   EXPECT_EQ(data->GetTotal(), 20U);
306 
307   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
308   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
309   EXPECT_TRUE(data->IsFinite());
310   EXPECT_EQ(data->GetCompleted(), 20U);
311   EXPECT_EQ(data->GetTotal(), 20U);
312 
313   ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT));
314 }
315 
316 TEST_F(ProgressReportTest, TestProgressManager) {
317   ListenerSP listener_sp =
318       CreateListenerFor(lldb::eBroadcastBitProgressCategory);
319   EventSP event_sp;
320   const ProgressEventData *data;
321 
322   // Create three progress events with the same category then try to pop 2
323   // events from the queue in a row before the progress reports are destroyed.
324   // Since only 1 event should've been broadcast for this category, the second
325   // GetEvent() call should return false.
326   {
327     Progress progress1("Progress report 1", "Starting report 1");
328     Progress progress2("Progress report 1", "Starting report 2");
329     Progress progress3("Progress report 1", "Starting report 3");
330     ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
331     ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT));
332   }
333 
334   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
335 
336   EXPECT_EQ(data->GetDetails(), "");
337   EXPECT_FALSE(data->IsFinite());
338   EXPECT_FALSE(data->GetCompleted());
339   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
340   EXPECT_EQ(data->GetMessage(), "Progress report 1");
341 
342   // Pop another event from the queue, this should be the event for the final
343   // report for this category.
344   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
345   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
346 
347   EXPECT_EQ(data->GetDetails(), "");
348   EXPECT_FALSE(data->IsFinite());
349   EXPECT_TRUE(data->GetCompleted());
350   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
351   EXPECT_EQ(data->GetMessage(), "Progress report 1");
352 }
353 
354 TEST_F(ProgressReportTest, TestOverlappingEvents) {
355   ListenerSP listener_sp =
356       CreateListenerFor(lldb::eBroadcastBitProgressCategory);
357   EventSP event_sp;
358   const ProgressEventData *data;
359 
360   // Create two progress reports of the same category that overlap with each
361   // other. Here we want to ensure that the ID broadcasted for the initial and
362   // final reports for this category are the same.
363   std::unique_ptr<Progress> overlap_progress1 =
364       std::make_unique<Progress>("Overlapping report 1", "Starting report 1");
365   std::unique_ptr<Progress> overlap_progress2 =
366       std::make_unique<Progress>("Overlapping report 1", "Starting report 2");
367   overlap_progress1.reset();
368 
369   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
370   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
371   // Get the ID used in the first report for this category.
372   uint64_t expected_progress_id = data->GetID();
373 
374   EXPECT_EQ(data->GetDetails(), "");
375   EXPECT_FALSE(data->IsFinite());
376   EXPECT_FALSE(data->GetCompleted());
377   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
378   EXPECT_EQ(data->GetMessage(), "Overlapping report 1");
379 
380   overlap_progress2.reset();
381 
382   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
383   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
384 
385   EXPECT_EQ(data->GetDetails(), "");
386   EXPECT_FALSE(data->IsFinite());
387   EXPECT_TRUE(data->GetCompleted());
388   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
389   EXPECT_EQ(data->GetMessage(), "Overlapping report 1");
390   // The progress ID for the final report should be the same as that for the
391   // initial report.
392   EXPECT_EQ(data->GetID(), expected_progress_id);
393 }
394 
395 TEST_F(ProgressReportTest, TestProgressManagerDisjointReports) {
396   ListenerSP listener_sp =
397       CreateListenerFor(lldb::eBroadcastBitProgressCategory);
398   EventSP event_sp;
399   const ProgressEventData *data;
400   uint64_t expected_progress_id;
401 
402   { Progress progress("Coalesced report 1", "Starting report 1"); }
403   { Progress progress("Coalesced report 1", "Starting report 2"); }
404   { Progress progress("Coalesced report 1", "Starting report 3"); }
405 
406   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
407   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
408   expected_progress_id = data->GetID();
409 
410   EXPECT_EQ(data->GetDetails(), "");
411   EXPECT_FALSE(data->IsFinite());
412   EXPECT_FALSE(data->GetCompleted());
413   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
414   EXPECT_EQ(data->GetMessage(), "Coalesced report 1");
415 
416   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
417   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
418 
419   EXPECT_EQ(data->GetID(), expected_progress_id);
420   EXPECT_EQ(data->GetDetails(), "");
421   EXPECT_FALSE(data->IsFinite());
422   EXPECT_TRUE(data->GetCompleted());
423   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
424   EXPECT_EQ(data->GetMessage(), "Coalesced report 1");
425 
426   ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT));
427 }
428 
429 TEST_F(ProgressReportTest, TestExternalReportCreation) {
430   ListenerSP listener_sp =
431       CreateListenerFor(lldb::eBroadcastBitExternalProgress);
432   EventSP event_sp;
433   const ProgressEventData *data;
434 
435   // Scope this for RAII on the progress objects.
436   // Create progress reports and check that their respective events for having
437   // started and ended are broadcasted.
438   {
439     Progress progress1("Progress report 1", "Starting report 1",
440                        /*total=*/std::nullopt, /*debugger=*/nullptr,
441                        /*minimum_report_time=*/std::chrono::seconds(0),
442                        Progress::Origin::eExternal);
443     Progress progress2("Progress report 2", "Starting report 2",
444                        /*total=*/std::nullopt, /*debugger=*/nullptr,
445                        /*minimum_report_time=*/std::chrono::seconds(0),
446                        Progress::Origin::eExternal);
447     Progress progress3("Progress report 3", "Starting report 3",
448                        /*total=*/std::nullopt, /*debugger=*/nullptr,
449                        /*minimum_report_time=*/std::chrono::seconds(0),
450                        Progress::Origin::eExternal);
451   }
452 
453   // Start popping events from the queue, they should have been recevied
454   // in this order:
455   // Starting progress: 1, 2, 3
456   // Ending progress: 3, 2, 1
457   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
458   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
459 
460   EXPECT_EQ(data->GetDetails(), "Starting report 1");
461   EXPECT_FALSE(data->IsFinite());
462   EXPECT_FALSE(data->GetCompleted());
463   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
464   EXPECT_EQ(data->GetMessage(), "Progress report 1: Starting report 1");
465 
466   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
467   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
468 
469   EXPECT_EQ(data->GetDetails(), "Starting report 2");
470   EXPECT_FALSE(data->IsFinite());
471   EXPECT_FALSE(data->GetCompleted());
472   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
473   EXPECT_EQ(data->GetMessage(), "Progress report 2: Starting report 2");
474 
475   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
476   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
477 
478   EXPECT_EQ(data->GetDetails(), "Starting report 3");
479   EXPECT_FALSE(data->IsFinite());
480   EXPECT_FALSE(data->GetCompleted());
481   EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
482   EXPECT_EQ(data->GetMessage(), "Progress report 3: Starting report 3");
483 
484   // Progress report objects should be destroyed at this point so
485   // get each report from the queue and check that they've been
486   // destroyed in reverse order.
487   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
488   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
489 
490   EXPECT_EQ(data->GetTitle(), "Progress report 3");
491   EXPECT_TRUE(data->GetCompleted());
492   EXPECT_FALSE(data->IsFinite());
493   EXPECT_EQ(data->GetMessage(), "Progress report 3: Starting report 3");
494 
495   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
496   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
497 
498   EXPECT_EQ(data->GetTitle(), "Progress report 2");
499   EXPECT_TRUE(data->GetCompleted());
500   EXPECT_FALSE(data->IsFinite());
501   EXPECT_EQ(data->GetMessage(), "Progress report 2: Starting report 2");
502 
503   ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
504   data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
505 
506   EXPECT_EQ(data->GetTitle(), "Progress report 1");
507   EXPECT_TRUE(data->GetCompleted());
508   EXPECT_FALSE(data->IsFinite());
509   EXPECT_EQ(data->GetMessage(), "Progress report 1: Starting report 1");
510 }
511 
512 TEST_F(ProgressReportTest, TestExternalReportNotReceived) {
513   ListenerSP listener_sp = CreateListenerFor(lldb::eBroadcastBitProgress);
514   EventSP event_sp;
515 
516   // Scope this for RAII on the progress objects.
517   // Create progress reports and check that their respective events for having
518   // started and ended are broadcasted.
519   {
520     Progress progress1("External Progress report 1",
521                        "Starting external report 1",
522                        /*total=*/std::nullopt, /*debugger=*/nullptr,
523                        /*minimum_report_time=*/std::chrono::seconds(0),
524                        Progress::Origin::eExternal);
525   }
526 
527   ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT));
528 }
529