xref: /llvm-project/lldb/unittests/Core/DiagnosticEventTest.cpp (revision b9e3fa84d3fdfe718a4a3085f7adeda3d81f2568)
1 //===-- DiagnosticEventTest.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 "gtest/gtest.h"
10 
11 #include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
12 #include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h"
13 #include "TestingSupport/SubsystemRAII.h"
14 #include "TestingSupport/TestUtilities.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/DebuggerEvents.h"
17 #include "lldb/Host/FileSystem.h"
18 #include "lldb/Host/HostInfo.h"
19 #include "lldb/Utility/Broadcaster.h"
20 #include "lldb/Utility/Event.h"
21 #include "lldb/Utility/Listener.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 using namespace lldb_private::repro;
26 
27 static const constexpr std::chrono::seconds TIMEOUT(0);
28 static const constexpr size_t DEBUGGERS = 3;
29 
30 namespace {
31 class DiagnosticEventTest : public ::testing::Test {
32 public:
SetUp()33   void SetUp() override {
34     FileSystem::Initialize();
35     HostInfo::Initialize();
36     PlatformMacOSX::Initialize();
37     std::call_once(TestUtilities::g_debugger_initialize_flag,
38                    []() { Debugger::Initialize(nullptr); });
39     ArchSpec arch("x86_64-apple-macosx-");
40     Platform::SetHostPlatform(
41         PlatformRemoteMacOSX::CreateInstance(true, &arch));
42   }
TearDown()43   void TearDown() override {
44     PlatformMacOSX::Terminate();
45     HostInfo::Terminate();
46     FileSystem::Terminate();
47   }
48 };
49 } // namespace
50 
TEST_F(DiagnosticEventTest,Warning)51 TEST_F(DiagnosticEventTest, Warning) {
52   DebuggerSP debugger_sp = Debugger::CreateInstance();
53 
54   Broadcaster &broadcaster = debugger_sp->GetBroadcaster();
55   ListenerSP listener_sp = Listener::MakeListener("test-listener");
56 
57   listener_sp->StartListeningForEvents(&broadcaster,
58                                        lldb::eBroadcastBitWarning);
59   EXPECT_TRUE(broadcaster.EventTypeHasListeners(lldb::eBroadcastBitWarning));
60 
61   Debugger::ReportWarning("foo", debugger_sp->GetID());
62 
63   EventSP event_sp;
64   EXPECT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
65   ASSERT_TRUE(event_sp);
66 
67   const DiagnosticEventData *data =
68       DiagnosticEventData::GetEventDataFromEvent(event_sp.get());
69   ASSERT_NE(data, nullptr);
70   EXPECT_EQ(data->GetPrefix(), "warning");
71   EXPECT_EQ(data->GetMessage(), "foo");
72 
73   Debugger::Destroy(debugger_sp);
74 }
75 
TEST_F(DiagnosticEventTest,Error)76 TEST_F(DiagnosticEventTest, Error) {
77   DebuggerSP debugger_sp = Debugger::CreateInstance();
78 
79   Broadcaster &broadcaster = debugger_sp->GetBroadcaster();
80   ListenerSP listener_sp = Listener::MakeListener("test-listener");
81 
82   listener_sp->StartListeningForEvents(&broadcaster, lldb::eBroadcastBitError);
83   EXPECT_TRUE(broadcaster.EventTypeHasListeners(lldb::eBroadcastBitError));
84 
85   Debugger::ReportError("bar", debugger_sp->GetID());
86 
87   EventSP event_sp;
88   EXPECT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
89   ASSERT_TRUE(event_sp);
90 
91   const DiagnosticEventData *data =
92       DiagnosticEventData::GetEventDataFromEvent(event_sp.get());
93   ASSERT_NE(data, nullptr);
94   EXPECT_EQ(data->GetPrefix(), "error");
95   EXPECT_EQ(data->GetMessage(), "bar");
96 
97   Debugger::Destroy(debugger_sp);
98 }
99 
TEST_F(DiagnosticEventTest,MultipleDebuggers)100 TEST_F(DiagnosticEventTest, MultipleDebuggers) {
101   std::vector<DebuggerSP> debuggers;
102   std::vector<ListenerSP> listeners;
103 
104   for (size_t i = 0; i < DEBUGGERS; ++i) {
105     DebuggerSP debugger = Debugger::CreateInstance();
106     ListenerSP listener = Listener::MakeListener("listener");
107 
108     debuggers.push_back(debugger);
109     listeners.push_back(listener);
110 
111     listener->StartListeningForEvents(&debugger->GetBroadcaster(),
112                                       lldb::eBroadcastBitError);
113   }
114 
115   Debugger::ReportError("baz");
116 
117   for (size_t i = 0; i < DEBUGGERS; ++i) {
118     EventSP event_sp;
119     EXPECT_TRUE(listeners[i]->GetEvent(event_sp, TIMEOUT));
120     ASSERT_TRUE(event_sp);
121 
122     const DiagnosticEventData *data =
123         DiagnosticEventData::GetEventDataFromEvent(event_sp.get());
124     ASSERT_NE(data, nullptr);
125     EXPECT_EQ(data->GetPrefix(), "error");
126     EXPECT_EQ(data->GetMessage(), "baz");
127   }
128 
129   for (size_t i = 0; i < DEBUGGERS; ++i) {
130     Debugger::Destroy(debuggers[i]);
131   }
132 }
133 
TEST_F(DiagnosticEventTest,WarningOnce)134 TEST_F(DiagnosticEventTest, WarningOnce) {
135   DebuggerSP debugger_sp = Debugger::CreateInstance();
136 
137   Broadcaster &broadcaster = debugger_sp->GetBroadcaster();
138   ListenerSP listener_sp = Listener::MakeListener("test-listener");
139 
140   listener_sp->StartListeningForEvents(&broadcaster,
141                                        lldb::eBroadcastBitWarning);
142   EXPECT_TRUE(broadcaster.EventTypeHasListeners(lldb::eBroadcastBitWarning));
143 
144   std::once_flag once;
145   Debugger::ReportWarning("foo", debugger_sp->GetID(), &once);
146 
147   {
148     EventSP event_sp;
149     EXPECT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
150     ASSERT_TRUE(event_sp);
151 
152     const DiagnosticEventData *data =
153         DiagnosticEventData::GetEventDataFromEvent(event_sp.get());
154     ASSERT_NE(data, nullptr);
155     EXPECT_EQ(data->GetPrefix(), "warning");
156     EXPECT_EQ(data->GetMessage(), "foo");
157   }
158 
159   EventSP second_event_sp;
160   EXPECT_FALSE(listener_sp->GetEvent(second_event_sp, TIMEOUT));
161 
162   Debugger::ReportWarning("foo", debugger_sp->GetID(), &once);
163   EXPECT_FALSE(listener_sp->GetEvent(second_event_sp, TIMEOUT));
164 
165   Debugger::ReportWarning("foo", debugger_sp->GetID());
166   EXPECT_TRUE(listener_sp->GetEvent(second_event_sp, TIMEOUT));
167 
168   Debugger::Destroy(debugger_sp);
169 }
170