blob: bacf8ca36aa07a836a42929c9ab24e520e7fa5d8 [file] [log] [blame] [edit]
//===----------------------------------------------------------------------===//
//
// 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 <cstddef>
#include <memory>
#include <utility>
template <typename Proto>
class TestTransport final
: public lldb_private::transport::JSONTransport<Proto> {
public:
using MessageHandler =
typename lldb_private::transport::JSONTransport<Proto>::MessageHandler;
static std::pair<std::unique_ptr<TestTransport<Proto>>,
std::unique_ptr<TestTransport<Proto>>>
createPair() {
std::unique_ptr<TestTransport<Proto>> transports[2] = {
std::make_unique<TestTransport<Proto>>(),
std::make_unique<TestTransport<Proto>>()};
return std::make_pair(std::move(transports[0]), std::move(transports[1]));
}
explicit TestTransport() {
llvm::Expected<lldb::FileUP> 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<lldb_private::MainLoop::ReadHandleUP>
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 <typename Proto>
class MockMessageHandler final
: public lldb_private::transport::JSONTransport<Proto>::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