ulib/3party/rpc_core/test/test_rpc.cpp

319 lines
8.0 KiB
C++
Raw Normal View History

2024-01-21 16:05:01 +08:00
#include "assert_def.h"
#include "rpc_core.hpp"
#include "serialize/CustomType.h"
#include "test.h"
namespace rpc_core_test {
void test_rpc() {
using namespace rpc_core;
// 此示例使用回环连接 实际使用时需自定义连接
auto connection = std::make_shared<loopback_connection>();
// 创建rpc 收发消息
auto rpc = rpc::create(connection);
// 定时器实现 应配合当前应用的事件循环 以确保消息收发和超时回调在同一个线程
// 此示例使用回环连接 不做超时测试
rpc->set_timer([](uint32_t ms, const rpc::timeout_cb& cb) {
RPC_CORE_UNUSED(ms);
RPC_CORE_UNUSED(cb);
});
// 已连接时设置ready
rpc->set_ready(true);
/**
*
* `std::string`STL容器
*/
{
// The Receiver
rpc->subscribe("cmd", [](const std::string& msg) -> std::string {
assert(msg == "hello");
return "world";
});
// The Sender
rpc->cmd("cmd")
->msg(std::string("hello"))
->rsp([](const std::string& rsp) {
assert(rsp == "world");
})
->call();
}
/**
*
* 使
*/
{
RPC_CORE_LOG("1. 收发消息完整测试");
// 注册监听
rpc->subscribe("cmd1", [&](const std::string& msg) -> std::string {
RPC_CORE_LOGI("get cmd1: %s", msg.c_str());
ASSERT(msg == "test");
return "ok";
});
// 请求支持很多方法 可根据需求使用所需部分
bool pass = false;
auto request = rpc->cmd("cmd1")
->msg(std::string("test"))
->rsp([&](const std::string& rsp) {
RPC_CORE_LOGI("get rsp from cmd1: %s", rsp.c_str());
ASSERT(rsp == "ok");
pass = true;
})
->timeout([] {
RPC_CORE_LOGI("timeout");
})
->finally([](finally_t type) {
RPC_CORE_LOGI("finally: type:%s", rpc_core::request::finally_t_str(type));
});
RPC_CORE_LOGI("执行请求");
ASSERT(!pass);
request->call();
ASSERT(pass);
/// 其他功能测试
RPC_CORE_LOGI("多次调用");
pass = false;
request->call();
ASSERT(pass);
RPC_CORE_LOGI("测试取消");
pass = false;
request->cancel();
request->call();
ASSERT(!pass);
RPC_CORE_LOGI("恢复取消");
request->reset_cancel();
request->call();
ASSERT(pass);
RPC_CORE_LOGI("添加到dispose");
pass = false;
{ // RAII dispose
dispose dispose;
request->add_to(dispose);
}
request->call();
ASSERT(!pass);
RPC_CORE_LOGI("先创建request");
pass = false;
request::create()
->cmd("cmd1")
->msg(std::string("test"))
->rsp([&](const std::string& rsp) {
ASSERT(rsp == "ok");
pass = true;
})
->call(rpc);
ASSERT(pass);
RPC_CORE_LOGI("no_such_cmd");
pass = false;
request::create()
->cmd("cmd_xx")
->msg(std::string("test"))
->rsp([] {
ASSERT(false);
})
->finally([&](finally_t type) {
ASSERT(type == finally_t::no_such_cmd);
pass = true;
})
->call(rpc);
ASSERT(pass);
}
RPC_CORE_LOG("2. 复杂结构体类型测试包含STL容器");
{
bool pass = false;
CustomType customType;
customType.id = 1;
customType.ids = {1, 2, 3};
customType.name = "test";
rpc->subscribe("cmd2", [&](const CustomType& msg) -> CustomType {
RPC_CORE_LOGI("get cmd2");
ASSERT(msg == customType);
return customType;
});
rpc->cmd("cmd2")
->msg(customType)
->rsp([&](const CustomType& rsp) {
RPC_CORE_LOGI("get rsp from cmd2");
ASSERT(rsp == customType);
pass = true;
})
->call();
ASSERT(pass);
}
RPC_CORE_LOG("3. finally测试");
{
bool pass = false;
bool pass_finally = false;
rpc->subscribe("cmd3", [&](const std::string& msg) {
return msg;
});
rpc->cmd("cmd3")
->msg(std::string("test"))
->rsp([&](const std::string& rsp) {
ASSERT(rsp == "test");
pass = true;
})
->finally([&](finally_t type) {
ASSERT(type == finally_t::normal);
ASSERT(!pass_finally);
pass_finally = true;
})
->call();
ASSERT(pass);
ASSERT(pass_finally);
pass_finally = false;
rpc->cmd("cmd3")
->msg(std::string("test"))
->finally([&](finally_t type) {
ASSERT(type == finally_t::no_need_rsp);
ASSERT(!pass_finally);
pass_finally = true;
})
->call();
ASSERT(pass_finally);
}
RPC_CORE_LOG("4. 多种使用场景测试");
{
RPC_CORE_LOG("4.1 有参数 有返回");
{
bool pass_cmd = false;
bool pass_rsp = false;
rpc->subscribe("cmd4", [&](const std::string& msg) -> std::string {
ASSERT(msg == "test");
pass_cmd = true;
return "test";
});
rpc->cmd("cmd4")
->msg(std::string("test"))
->rsp([&](const std::string& msg) {
ASSERT(msg == "test");
pass_rsp = true;
})
->call();
ASSERT(pass_cmd);
ASSERT(pass_rsp);
}
RPC_CORE_LOG("4.2 有参数 无返回");
{
bool pass_cmd = false;
rpc->subscribe("cmd4", [&](const std::string& msg) {
ASSERT(msg == "test");
pass_cmd = true;
});
rpc->cmd("cmd4")->msg(std::string("test"))->call();
ASSERT(pass_cmd);
}
RPC_CORE_LOG("4.3 无参数 有返回");
{
bool pass_cmd = false;
bool pass_rsp = false;
rpc->subscribe("cmd4", [&]() -> std::string {
pass_cmd = true;
return "test";
});
rpc->cmd("cmd4")
->rsp([&](const std::string& msg) {
pass_rsp = true;
ASSERT(msg == "test");
})
->call();
ASSERT(pass_cmd);
ASSERT(pass_rsp);
}
RPC_CORE_LOG("4.4 无参数 无返回");
{
bool pass_cmd = false;
rpc->subscribe("cmd4", [&]() {
pass_cmd = true;
});
rpc->cmd("cmd4")->call();
ASSERT(pass_cmd);
}
}
RPC_CORE_LOG("5. ping pong测试");
{
bool pass = false;
rpc->ping("test")
->rsp([&](const std::string& payload) {
RPC_CORE_LOGI("get rsp from ping: %s", payload.c_str());
ASSERT(payload == "test");
pass = true;
})
->call();
ASSERT(pass);
}
RPC_CORE_LOG("6. dispose测试");
{
bool pass = false;
auto request = rpc->ping("test")
->rsp([&](const std::string& payload) {
RPC_CORE_UNUSED(payload);
ASSERT(false);
})
->finally([&](finally_t type) {
ASSERT(type == finally_t::canceled);
pass = true;
});
{
dispose dispose;
request->add_to(dispose);
}
request->call();
ASSERT(pass);
}
#ifndef RPC_CORE_FEATURE_DISABLE_FUTURE
RPC_CORE_LOG("7. future模式测试");
{
{
auto result = rpc->ping("test")->future<std::string>().get();
ASSERT(result.type == finally_t::normal);
ASSERT(result.data == "test");
}
{
auto result = rpc->ping()->future<void>().get();
ASSERT(result.type == finally_t::normal);
}
}
#endif
RPC_CORE_LOG("8. 未ready的rpc对象");
{
bool pass = false;
auto rpc_tmp = rpc::create(connection);
rpc_tmp->cmd("cmd")->call(); // should not crash
rpc_tmp->cmd("cmd")
->finally([&](finally_t type) {
RPC_CORE_LOG("finally: %d", (int)type);
ASSERT(type == finally_t::rpc_not_ready);
pass = true;
})
->call();
ASSERT(pass);
}
}
} // namespace rpc_core_test