summaryrefslogtreecommitdiff
path: root/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
commit88c643b6fec27eec436c8d138fee6346e92337d6 (patch)
tree82cd13b2f3cde1c9e5f79689ba4e6ba67694843f /unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
parent94994d372d014ce4c8758b9605d63fae651bd8aa (diff)
Notes
Diffstat (limited to 'unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp')
-rw-r--r--unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp362
1 files changed, 0 insertions, 362 deletions
diff --git a/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp b/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
deleted file mode 100644
index 187f1b2db9a37..0000000000000
--- a/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
+++ /dev/null
@@ -1,362 +0,0 @@
-//===-- GDBRemoteClientBaseTest.cpp -----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <future>
-
-#include "GDBRemoteTestUtils.h"
-
-#include "Plugins/Process/Utility/LinuxSignals.h"
-#include "Plugins/Process/gdb-remote/GDBRemoteClientBase.h"
-#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
-#include "lldb/Utility/StreamGDBRemote.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Testing/Support/Error.h"
-
-using namespace lldb_private::process_gdb_remote;
-using namespace lldb_private;
-using namespace lldb;
-typedef GDBRemoteCommunication::PacketResult PacketResult;
-
-namespace {
-
-struct MockDelegate : public GDBRemoteClientBase::ContinueDelegate {
- std::string output;
- std::string misc_data;
- unsigned stop_reply_called = 0;
- std::vector<std::string> structured_data_packets;
-
- void HandleAsyncStdout(llvm::StringRef out) { output += out; }
- void HandleAsyncMisc(llvm::StringRef data) { misc_data += data; }
- void HandleStopReply() { ++stop_reply_called; }
-
- void HandleAsyncStructuredDataPacket(llvm::StringRef data) {
- structured_data_packets.push_back(data);
- }
-};
-
-struct TestClient : public GDBRemoteClientBase {
- TestClient() : GDBRemoteClientBase("test.client", "test.client.listener") {
- m_send_acks = false;
- }
-};
-
-class GDBRemoteClientBaseTest : public GDBRemoteTest {
-public:
- void SetUp() override {
- ASSERT_THAT_ERROR(GDBRemoteCommunication::ConnectLocally(client, server),
- llvm::Succeeded());
- ASSERT_EQ(TestClient::eBroadcastBitRunPacketSent,
- listener_sp->StartListeningForEvents(
- &client, TestClient::eBroadcastBitRunPacketSent));
- }
-
-protected:
- TestClient client;
- MockServer server;
- MockDelegate delegate;
- ListenerSP listener_sp = Listener::MakeListener("listener");
-
- StateType SendCPacket(StringExtractorGDBRemote &response) {
- return client.SendContinuePacketAndWaitForResponse(delegate, LinuxSignals(),
- "c", response);
- }
-
- void WaitForRunEvent() {
- EventSP event_sp;
- listener_sp->GetEventForBroadcasterWithType(
- &client, TestClient::eBroadcastBitRunPacketSent, event_sp, llvm::None);
- }
-};
-
-} // end anonymous namespace
-
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndWait) {
- StringExtractorGDBRemote response;
-
- // Continue. The inferior will stop with a signal.
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
-
- // Continue. The inferior will exit.
- ASSERT_EQ(PacketResult::Success, server.SendPacket("W01"));
- ASSERT_EQ(eStateExited, SendCPacket(response));
- ASSERT_EQ("W01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
-
- // Continue. The inferior will get killed.
- ASSERT_EQ(PacketResult::Success, server.SendPacket("X01"));
- ASSERT_EQ(eStateExited, SendCPacket(response));
- ASSERT_EQ("X01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
-}
-
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncSignal) {
- StringExtractorGDBRemote continue_response, response;
-
- // SendAsyncSignal should do nothing when we are not running.
- ASSERT_FALSE(client.SendAsyncSignal(0x47));
-
- // Continue. After the run packet is sent, send an async signal.
- std::future<StateType> continue_state = std::async(
- std::launch::async, [&] { return SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- WaitForRunEvent();
-
- std::future<bool> async_result = std::async(
- std::launch::async, [&] { return client.SendAsyncSignal(0x47); });
-
- // First we'll get interrupted.
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T13"));
-
- // Then we get the signal packet.
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("C47", response.GetStringRef());
- ASSERT_TRUE(async_result.get());
-
- // And we report back a signal stop.
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T47"));
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T47", continue_response.GetStringRef());
-}
-
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncPacket) {
- StringExtractorGDBRemote continue_response, async_response, response;
- const bool send_async = true;
-
- // Continue. After the run packet is sent, send an async packet.
- std::future<StateType> continue_state = std::async(
- std::launch::async, [&] { return SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- WaitForRunEvent();
-
- // Sending without async enabled should fail.
- ASSERT_EQ(
- PacketResult::ErrorSendFailed,
- client.SendPacketAndWaitForResponse("qTest1", response, !send_async));
-
- std::future<PacketResult> async_result = std::async(std::launch::async, [&] {
- return client.SendPacketAndWaitForResponse("qTest2", async_response,
- send_async);
- });
-
- // First we'll get interrupted.
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T13"));
-
- // Then we get the async packet.
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("qTest2", response.GetStringRef());
-
- // Send the response and receive it.
- ASSERT_EQ(PacketResult::Success, server.SendPacket("QTest2"));
- ASSERT_EQ(PacketResult::Success, async_result.get());
- ASSERT_EQ("QTest2", async_response.GetStringRef());
-
- // And we get resumed again.
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T01", continue_response.GetStringRef());
-}
-
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt) {
- StringExtractorGDBRemote continue_response, response;
-
- // Interrupt should do nothing when we're not running.
- ASSERT_FALSE(client.Interrupt());
-
- // Continue. After the run packet is sent, send an interrupt.
- std::future<StateType> continue_state = std::async(
- std::launch::async, [&] { return SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- WaitForRunEvent();
-
- std::future<bool> async_result =
- std::async(std::launch::async, [&] { return client.Interrupt(); });
-
- // We get interrupted.
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T13"));
-
- // And that's it.
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T13", continue_response.GetStringRef());
- ASSERT_TRUE(async_result.get());
-}
-
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndLateInterrupt) {
- StringExtractorGDBRemote continue_response, response;
-
- // Continue. After the run packet is sent, send an interrupt.
- std::future<StateType> continue_state = std::async(
- std::launch::async, [&] { return SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- WaitForRunEvent();
-
- std::future<bool> async_result =
- std::async(std::launch::async, [&] { return client.Interrupt(); });
-
- // However, the target stops due to a different reason than the original
- // interrupt.
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T01", continue_response.GetStringRef());
- ASSERT_TRUE(async_result.get());
-
- // The subsequent continue packet should work normally.
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
-}
-
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt2PacketBug) {
- StringExtractorGDBRemote continue_response, async_response, response;
- const bool send_async = true;
-
- // Interrupt should do nothing when we're not running.
- ASSERT_FALSE(client.Interrupt());
-
- // Continue. After the run packet is sent, send an async signal.
- std::future<StateType> continue_state = std::async(
- std::launch::async, [&] { return SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- WaitForRunEvent();
-
- std::future<bool> interrupt_result =
- std::async(std::launch::async, [&] { return client.Interrupt(); });
-
- // We get interrupted. We'll send two packets to simulate a buggy stub.
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T13"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T13"));
-
- // We should stop.
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T13", continue_response.GetStringRef());
- ASSERT_TRUE(interrupt_result.get());
-
- // Packet stream should remain synchronized.
- std::future<PacketResult> send_result = std::async(std::launch::async, [&] {
- return client.SendPacketAndWaitForResponse("qTest", async_response,
- !send_async);
- });
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("qTest", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.SendPacket("QTest"));
- ASSERT_EQ(PacketResult::Success, send_result.get());
- ASSERT_EQ("QTest", async_response.GetStringRef());
-}
-
-TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateInterface) {
- StringExtractorGDBRemote response;
-
- // Continue. We'll have the server send a bunch of async packets before it
- // stops.
- ASSERT_EQ(PacketResult::Success, server.SendPacket("O4142"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("Apro"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("O4344"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("Afile"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
-
- EXPECT_EQ("ABCD", delegate.output);
- EXPECT_EQ("profile", delegate.misc_data);
- EXPECT_EQ(1u, delegate.stop_reply_called);
-}
-
-TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateStructuredDataReceipt) {
- // Build the plain-text version of the JSON data we will have the
- // server send.
- const std::string json_payload =
- "{ \"type\": \"MyFeatureType\", "
- " \"elements\": [ \"entry1\", \"entry2\" ] }";
- const std::string json_packet = "JSON-async:" + json_payload;
-
- // Escape it properly for transit.
- StreamGDBRemote stream;
- stream.PutEscapedBytes(json_packet.c_str(), json_packet.length());
- stream.Flush();
-
- StringExtractorGDBRemote response;
-
- // Send async structured data packet, then stop.
- ASSERT_EQ(PacketResult::Success, server.SendPacket(stream.GetData()));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
- ASSERT_EQ(1ul, delegate.structured_data_packets.size());
-
- // Verify the packet contents. It should have been unescaped upon packet
- // reception.
- ASSERT_EQ(json_packet, delegate.structured_data_packets[0]);
-}
-
-TEST_F(GDBRemoteClientBaseTest, InterruptNoResponse) {
- StringExtractorGDBRemote continue_response, response;
-
- // Continue. After the run packet is sent, send an interrupt.
- std::future<StateType> continue_state = std::async(
- std::launch::async, [&] { return SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- WaitForRunEvent();
-
- std::future<bool> async_result =
- std::async(std::launch::async, [&] { return client.Interrupt(); });
-
- // We get interrupted, but we don't send a stop packet.
- ASSERT_EQ(PacketResult::Success, server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
-
- // The functions should still terminate (after a timeout).
- ASSERT_TRUE(async_result.get());
- ASSERT_EQ(eStateInvalid, continue_state.get());
-}
-
-TEST_F(GDBRemoteClientBaseTest, SendPacketAndReceiveResponseWithOutputSupport) {
- StringExtractorGDBRemote response;
- StreamString command_output;
-
- ASSERT_EQ(PacketResult::Success, server.SendPacket("O"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("O48656c6c6f2c"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("O20"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("O"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("O776f726c64"));
- ASSERT_EQ(PacketResult::Success, server.SendPacket("OK"));
-
- PacketResult result = client.SendPacketAndReceiveResponseWithOutputSupport(
- "qRcmd,test", response, true,
- [&command_output](llvm::StringRef output) { command_output << output; });
-
- ASSERT_EQ(PacketResult::Success, result);
- ASSERT_EQ("OK", response.GetStringRef());
- ASSERT_EQ("Hello, world", command_output.GetString().str());
-}