diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 18:01:57 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 18:01:57 +0000 |
commit | 88c643b6fec27eec436c8d138fee6346e92337d6 (patch) | |
tree | 82cd13b2f3cde1c9e5f79689ba4e6ba67694843f /unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp | |
parent | 94994d372d014ce4c8758b9605d63fae651bd8aa (diff) |
Notes
Diffstat (limited to 'unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp')
-rw-r--r-- | unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp | 362 |
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()); -} |