lokinet/test/jsonrpc_unittest.cpp

194 lines
3.9 KiB
C++
Raw Normal View History

2018-11-02 17:08:01 +00:00
#include <gtest/gtest.h>
#include <libabyss.hpp>
#include <llarp/ev.h>
#include <llarp/threading.hpp>
#include <llarp/net.hpp>
struct AbyssTestBase : public ::testing::Test
{
2018-11-02 17:49:01 +00:00
llarp_crypto crypto;
2018-11-02 17:08:01 +00:00
llarp_threadpool* threadpool = nullptr;
llarp_ev_loop* loop = nullptr;
llarp_logic* logic = nullptr;
abyss::httpd::BaseReqHandler* server = nullptr;
abyss::http::JSONRPC* client = nullptr;
const std::string method = "test.method";
bool called = false;
2018-11-02 17:08:01 +00:00
void
AssertMethod(const std::string& meth) const
{
ASSERT_TRUE(meth == method);
}
2018-11-02 17:49:01 +00:00
void
SetUp()
{
// for llarp_randint
llarp_crypto_init(&crypto);
}
2018-11-02 17:56:48 +00:00
static void
CancelIt(void* u, __attribute__((unused)) uint64_t orig, uint64_t left)
2018-11-02 17:56:48 +00:00
{
if(left)
return;
static_cast< AbyssTestBase* >(u)->Stop();
2018-11-02 17:56:48 +00:00
}
2018-11-02 17:08:01 +00:00
void
Start()
{
threadpool = llarp_init_same_process_threadpool();
llarp_ev_loop_alloc(&loop);
logic = llarp_init_single_process_logic(threadpool);
sockaddr_in addr;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons((llarp_randint() % 2000) + 2000);
addr.sin_family = AF_INET;
llarp::Addr a(addr);
while(true)
{
if(server->ServeAsync(loop, logic, a))
{
client->RunAsync(loop, a.ToString());
2018-11-02 17:56:48 +00:00
llarp_logic_call_later(logic, {1000, this, &CancelIt});
2018-11-02 17:08:01 +00:00
return;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void
Stop()
{
if(server)
server->Close();
llarp_logic_stop(logic);
llarp_ev_loop_stop(loop);
llarp_threadpool_stop(threadpool);
}
void
TearDown()
{
if(loop && threadpool && logic)
{
llarp_free_logic(&logic);
llarp_ev_loop_free(&loop);
llarp_free_threadpool(&threadpool);
}
}
};
struct ClientHandler : public abyss::http::IRPCClientHandler
{
AbyssTestBase* test;
ClientHandler(abyss::http::ConnImpl* impl, AbyssTestBase* parent)
: abyss::http::IRPCClientHandler(impl), test(parent)
{
}
void
HandleError()
{
ASSERT_TRUE(false);
}
void
PopulateReqHeaders(__attribute__((unused)) abyss::http::Headers_t& hdr)
2018-11-02 17:08:01 +00:00
{
}
bool
HandleResponse(__attribute__((unused))
const abyss::http::RPC_Response& response)
2018-11-02 17:08:01 +00:00
{
test->Stop();
return true;
}
};
struct ServerHandler : public abyss::httpd::IRPCHandler
{
AbyssTestBase* test;
ServerHandler(abyss::httpd::ConnImpl* impl, AbyssTestBase* parent)
2018-11-02 17:08:01 +00:00
: abyss::httpd::IRPCHandler(impl), test(parent)
{
}
bool
HandleJSONRPC(Method_t method, __attribute__((unused)) const Params& params,
__attribute__((unused)) Response& response)
2018-11-02 17:08:01 +00:00
{
test->AssertMethod(method);
test->called = true;
2018-11-02 17:08:01 +00:00
return true;
}
};
struct AbyssTest : public AbyssTestBase,
public abyss::http::JSONRPC,
public abyss::httpd::BaseReqHandler
{
AbyssTest()
: AbyssTestBase()
, abyss::http::JSONRPC()
, abyss::httpd::BaseReqHandler(1000)
{
}
abyss::http::IRPCClientHandler*
NewConn(abyss::http::ConnImpl* impl)
{
return new ClientHandler(impl, this);
}
abyss::httpd::IRPCHandler*
CreateHandler(abyss::httpd::ConnImpl* impl)
2018-11-02 17:08:01 +00:00
{
return new ServerHandler(impl, this);
}
void
SetUp()
{
2018-11-02 17:49:01 +00:00
AbyssTestBase::SetUp();
2018-11-02 17:08:01 +00:00
client = this;
server = this;
}
static void
FlushIt(void* u)
{
static_cast< AbyssTest* >(u)->Flush();
}
void
AsyncFlush()
{
llarp_logic_queue_job(logic, {this, &FlushIt});
}
void
RunLoop()
{
llarp_ev_loop_run_single_process(loop, threadpool, logic);
}
};
TEST_F(AbyssTest, TestClientAndServer)
{
Start();
abyss::json::Value params;
params.SetObject();
QueueRPC(method, std::move(params),
std::bind(&AbyssTest::NewConn, this, std::placeholders::_1));
2018-11-02 17:08:01 +00:00
AsyncFlush();
RunLoop();
ASSERT_TRUE(called);
};