//===----------------------------------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #ifndef LLDB_UNITTESTS_TESTINGSUPPORT_HOST_JSONTRANSPORTTESTUTILITIES_H #define LLDB_UNITTESTS_TESTINGSUPPORT_HOST_JSONTRANSPORTTESTUTILITIES_H #include "lldb/Host/FileSystem.h" #include "lldb/Host/JSONTransport.h" #include "lldb/Host/MainLoop.h" #include "lldb/Utility/FileSpec.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Testing/Support/Error.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include #include #include template class TestTransport final : public lldb_private::transport::JSONTransport { public: using MessageHandler = typename lldb_private::transport::JSONTransport::MessageHandler; static std::pair>, std::unique_ptr>> createPair() { std::unique_ptr> transports[2] = { std::make_unique>(), std::make_unique>()}; return std::make_pair(std::move(transports[0]), std::move(transports[1])); } explicit TestTransport() { llvm::Expected dummy_file = lldb_private::FileSystem::Instance().Open( lldb_private::FileSpec(lldb_private::FileSystem::DEV_NULL), lldb_private::File::eOpenOptionReadWrite); EXPECT_THAT_EXPECTED(dummy_file, llvm::Succeeded()); m_dummy_file = std::move(*dummy_file); } llvm::Error Send(const typename Proto::Evt &evt) override { EXPECT_TRUE(m_loop && m_handler) << "Send called before RegisterMessageHandler"; m_loop->AddPendingCallback([this, evt](lldb_private::MainLoopBase &) { m_handler->Received(evt); }); return llvm::Error::success(); } llvm::Error Send(const typename Proto::Req &req) override { EXPECT_TRUE(m_loop && m_handler) << "Send called before RegisterMessageHandler"; m_loop->AddPendingCallback([this, req](lldb_private::MainLoopBase &) { m_handler->Received(req); }); return llvm::Error::success(); } llvm::Error Send(const typename Proto::Resp &resp) override { EXPECT_TRUE(m_loop && m_handler) << "Send called before RegisterMessageHandler"; m_loop->AddPendingCallback([this, resp](lldb_private::MainLoopBase &) { m_handler->Received(resp); }); return llvm::Error::success(); } llvm::Expected RegisterMessageHandler(lldb_private::MainLoop &loop, MessageHandler &handler) override { if (!m_loop) m_loop = &loop; if (!m_handler) m_handler = &handler; lldb_private::Status status; auto handle = loop.RegisterReadObject( m_dummy_file, [](lldb_private::MainLoopBase &) {}, status); if (status.Fail()) return status.takeError(); return handle; } protected: void Log(llvm::StringRef message) override {}; private: lldb_private::MainLoop *m_loop = nullptr; MessageHandler *m_handler = nullptr; // Dummy file for registering with the MainLoop. lldb::FileSP m_dummy_file = nullptr; }; template class MockMessageHandler final : public lldb_private::transport::JSONTransport::MessageHandler { public: MOCK_METHOD(void, Received, (const typename Proto::Req &), (override)); MOCK_METHOD(void, Received, (const typename Proto::Resp &), (override)); MOCK_METHOD(void, Received, (const typename Proto::Evt &), (override)); MOCK_METHOD(void, OnError, (llvm::Error), (override)); MOCK_METHOD(void, OnClosed, (), (override)); }; #endif