Skip to content

Commit

Permalink
Reland "[lldb][progress][NFC] Add unit test for progress reports (llv…
Browse files Browse the repository at this point in the history
…m#79533)"

This reverts commit 209fe1f.

The original commit failed to due an assertion failure in the unit test
`ProgressReportTest` that the commit added. The Debugger::Initialize()
function was called more than once which triggered the assertion, so
this commit calls that function under a `std::call_once`.
  • Loading branch information
chelcassanova committed Jan 31, 2024
1 parent 7c2e32d commit a5a8cbb
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
1 change: 1 addition & 0 deletions lldb/unittests/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_lldb_unittest(LLDBCoreTests
FormatEntityTest.cpp
MangledTest.cpp
ModuleSpecTest.cpp
ProgressReportTest.cpp
RichManglingContextTest.cpp
SourceLocationSpecTest.cpp
SourceManagerTest.cpp
Expand Down
127 changes: 127 additions & 0 deletions lldb/unittests/Core/ProgressReportTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//===-- ProgressReportTest.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Progress.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/Listener.h"
#include "gtest/gtest.h"
#include <mutex>

using namespace lldb;
using namespace lldb_private;

static std::once_flag debugger_initialize_flag;
class ProgressReportTest : public ::testing::Test {
SubsystemRAII<FileSystem, HostInfo, PlatformMacOSX> subsystems;

// The debugger's initialization function can't be called with no arguments
// so calling it using SubsystemRAII will cause the test build to fail as
// SubsystemRAII will call Initialize with no arguments. As such we set it up
// here the usual way.
void SetUp() override {
std::call_once(debugger_initialize_flag,
[]() { Debugger::Initialize(nullptr); });
};
};

TEST_F(ProgressReportTest, TestReportCreation) {
std::chrono::milliseconds timeout(100);

// Set up the debugger, make sure that was done properly.
ArchSpec arch("x86_64-apple-macosx-");
Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch));

DebuggerSP debugger_sp = Debugger::CreateInstance();
ASSERT_TRUE(debugger_sp);

// Get the debugger's broadcaster.
Broadcaster &broadcaster = debugger_sp->GetBroadcaster();

// Create a listener, make sure it can receive events and that it's
// listening to the correct broadcast bit.
ListenerSP listener_sp = Listener::MakeListener("progress-listener");

listener_sp->StartListeningForEvents(&broadcaster,
Debugger::eBroadcastBitProgress);
EXPECT_TRUE(
broadcaster.EventTypeHasListeners(Debugger::eBroadcastBitProgress));

EventSP event_sp;
const ProgressEventData *data;

// Scope this for RAII on the progress objects.
// Create progress reports and check that their respective events for having
// started and ended are broadcasted.
{
Progress progress1("Progress report 1", "Starting report 1");
Progress progress2("Progress report 2", "Starting report 2");
Progress progress3("Progress report 3", "Starting report 3");
}

// Start popping events from the queue, they should have been recevied
// in this order:
// Starting progress: 1, 2, 3
// Ending progress: 3, 2, 1
EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
data = ProgressEventData::GetEventDataFromEvent(event_sp.get());

ASSERT_EQ(data->GetDetails(), "Starting report 1");
ASSERT_FALSE(data->IsFinite());
ASSERT_FALSE(data->GetCompleted());
ASSERT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
ASSERT_EQ(data->GetMessage(), "Progress report 1: Starting report 1");

EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
data = ProgressEventData::GetEventDataFromEvent(event_sp.get());

ASSERT_EQ(data->GetDetails(), "Starting report 2");
ASSERT_FALSE(data->IsFinite());
ASSERT_FALSE(data->GetCompleted());
ASSERT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
ASSERT_EQ(data->GetMessage(), "Progress report 2: Starting report 2");

EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
ASSERT_EQ(data->GetDetails(), "Starting report 3");
ASSERT_FALSE(data->IsFinite());
ASSERT_FALSE(data->GetCompleted());
ASSERT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
ASSERT_EQ(data->GetMessage(), "Progress report 3: Starting report 3");

// Progress report objects should be destroyed at this point so
// get each report from the queue and check that they've been
// destroyed in reverse order.
EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
data = ProgressEventData::GetEventDataFromEvent(event_sp.get());

ASSERT_EQ(data->GetTitle(), "Progress report 3");
ASSERT_TRUE(data->GetCompleted());
ASSERT_FALSE(data->IsFinite());
ASSERT_EQ(data->GetMessage(), "Progress report 3: Starting report 3");

EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
data = ProgressEventData::GetEventDataFromEvent(event_sp.get());

ASSERT_EQ(data->GetTitle(), "Progress report 2");
ASSERT_TRUE(data->GetCompleted());
ASSERT_FALSE(data->IsFinite());
ASSERT_EQ(data->GetMessage(), "Progress report 2: Starting report 2");

EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
data = ProgressEventData::GetEventDataFromEvent(event_sp.get());

ASSERT_EQ(data->GetTitle(), "Progress report 1");
ASSERT_TRUE(data->GetCompleted());
ASSERT_FALSE(data->IsFinite());
ASSERT_EQ(data->GetMessage(), "Progress report 1: Starting report 1");
}

0 comments on commit a5a8cbb

Please sign in to comment.