c3b5a29da2
All checks were successful
rpcrypto-build / build (Debug, hisiv510.toolchain.cmake) (push) Successful in 1m6s
rpcrypto-build / build (Debug, himix200.toolchain.cmake) (push) Successful in 1m9s
rpcrypto-build / build (Release, himix200.toolchain.cmake) (push) Successful in 1m17s
rpcrypto-build / build (Release, hisiv510.toolchain.cmake) (push) Successful in 1m22s
linux-hisiv500-gcc / linux-gcc-hisiv500 (push) Successful in 1m39s
linux-mips64-gcc / linux-gcc-mips64el (push) Successful in 1m48s
linux-x64-gcc / linux-gcc (push) Successful in 2m3s
319 lines
8.0 KiB
C++
319 lines
8.0 KiB
C++
#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
|