Skip to content

Commit e70d4db

Browse files
committed
Expand RPC response socket test coverage
Verify rejection and subsequent completion on the sending socket for baidu_std, sofa_pbrpc, and public_pbrpc response handlers. Exercise real channel/server calls across all four affected protocols and their supported connection types using an ephemeral server port.
1 parent 1c05f20 commit e70d4db

3 files changed

Lines changed: 144 additions & 0 deletions

File tree

‎test/brpc_channel_unittest.cpp‎

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "brpc/policy/baidu_rpc_protocol.h"
3535
#include "brpc/policy/baidu_rpc_meta.pb.h"
3636
#include "brpc/policy/most_common_message.h"
37+
#include "brpc/policy/public_pbrpc_protocol.h"
3738
#include "brpc/channel.h"
3839
#include "brpc/details/load_balancer_with_naming.h"
3940
#include "brpc/parallel_channel.h"
@@ -2282,6 +2283,97 @@ class MyShared : public brpc::SharedObject {
22822283
int MyShared::nctor = 0;
22832284
int MyShared::ndtor = 0;
22842285

2286+
TEST(ResponseSocketTest, baidu_response_requires_sending_socket) {
2287+
brpc::Controller cntl;
2288+
test::EchoResponse res;
2289+
cntl._response = &res;
2290+
ASSERT_EQ(0, bthread_id_lock_and_reset_range(
2291+
cntl.call_id(), nullptr, 2));
2292+
ASSERT_EQ(0, bthread_id_unlock(cntl.current_id()));
2293+
brpc::SocketId sending_id;
2294+
brpc::SocketId foreign_id;
2295+
ASSERT_EQ(0, brpc::Socket::Create(brpc::SocketOptions(), &sending_id));
2296+
ASSERT_EQ(0, brpc::Socket::Create(brpc::SocketOptions(), &foreign_id));
2297+
ASSERT_EQ(0, brpc::Socket::Address(
2298+
sending_id, &cntl._current_call.sending_sock));
2299+
brpc::SocketUniquePtr foreign_socket;
2300+
ASSERT_EQ(0, brpc::Socket::Address(foreign_id, &foreign_socket));
2301+
2302+
brpc::policy::RpcMeta meta;
2303+
meta.set_correlation_id(cntl.current_id().value);
2304+
meta.mutable_response()->set_error_code(0);
2305+
auto make_response = [&meta](brpc::Socket* socket) {
2306+
auto* msg = brpc::policy::MostCommonMessage::Get();
2307+
butil::IOBufAsZeroCopyOutputStream meta_stream(&msg->meta);
2308+
EXPECT_TRUE(meta.SerializeToZeroCopyStream(&meta_stream));
2309+
test::EchoResponse response;
2310+
response.set_message("matched");
2311+
butil::IOBufAsZeroCopyOutputStream payload_stream(&msg->payload);
2312+
EXPECT_TRUE(response.SerializeToZeroCopyStream(&payload_stream));
2313+
socket->ReAddress(&msg->_socket);
2314+
socket->PostponeEOF();
2315+
return msg;
2316+
};
2317+
brpc::policy::ProcessRpcResponse(make_response(foreign_socket.get()));
2318+
EXPECT_TRUE(res.message().empty());
2319+
EXPECT_EQ(0, cntl.ErrorCode());
2320+
brpc::policy::ProcessRpcResponse(
2321+
make_response(cntl._current_call.sending_sock.get()));
2322+
EXPECT_EQ("matched", res.message());
2323+
EXPECT_EQ(0, cntl.ErrorCode());
2324+
}
2325+
2326+
TEST(ResponseSocketTest, real_rpc_responses_match_sending_socket) {
2327+
class EchoService : public test::EchoService {
2328+
void Echo(google::protobuf::RpcController*,
2329+
const test::EchoRequest* request,
2330+
test::EchoResponse* response,
2331+
google::protobuf::Closure* done) override {
2332+
brpc::ClosureGuard done_guard(done);
2333+
response->set_message("received " + request->message());
2334+
}
2335+
} service;
2336+
brpc::Server server;
2337+
ASSERT_EQ(0, server.AddService(&service, brpc::SERVER_DOESNT_OWN_SERVICE));
2338+
brpc::ServerOptions server_options;
2339+
server_options.nshead_service = new brpc::policy::PublicPbrpcServiceAdaptor;
2340+
ASSERT_EQ(0, server.Start(0, &server_options));
2341+
2342+
const char* protocols[] = {
2343+
"baidu_std", "hulu_pbrpc", "sofa_pbrpc", "public_pbrpc"};
2344+
const char* connections[] = {"single", "pooled", "short"};
2345+
for (const char* protocol : protocols) {
2346+
for (const char* connection : connections) {
2347+
// Public pbrpc uses the half-duplex nshead server adaptor.
2348+
if (strcmp(protocol, "public_pbrpc") == 0 &&
2349+
strcmp(connection, "single") == 0) {
2350+
continue;
2351+
}
2352+
SCOPED_TRACE(protocol);
2353+
SCOPED_TRACE(connection);
2354+
brpc::ChannelOptions options;
2355+
options.protocol = protocol;
2356+
options.connection_type = connection;
2357+
options.timeout_ms = 5000;
2358+
options.max_retry = 0;
2359+
brpc::Channel channel;
2360+
ASSERT_EQ(0, channel.Init(server.listen_address(), &options));
2361+
test::EchoService_Stub stub(&channel);
2362+
for (int i = 0; i < 2; ++i) {
2363+
brpc::Controller cntl;
2364+
test::EchoRequest request;
2365+
test::EchoResponse response;
2366+
request.set_message("socket binding");
2367+
stub.Echo(&cntl, &request, &response, nullptr);
2368+
ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
2369+
EXPECT_EQ("received socket binding", response.message());
2370+
}
2371+
}
2372+
}
2373+
server.Stop(0);
2374+
server.Join();
2375+
}
2376+
22852377
TEST_F(ChannelTest, intrusive_ptr_sanity) {
22862378
MyShared::nctor = 0;
22872379
MyShared::ndtor = 0;

‎test/brpc_public_pbrpc_protocol_unittest.cpp‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,32 @@ TEST_F(PublicPbrpcTest, process_response_after_eof) {
250250
ASSERT_TRUE(_socket->Failed());
251251
}
252252

253+
TEST_F(PublicPbrpcTest, process_response_requires_sending_socket) {
254+
brpc::Controller cntl;
255+
test::EchoResponse res;
256+
cntl._response = &res;
257+
ASSERT_EQ(0, bthread_id_lock_and_reset_range(
258+
cntl.call_id(), nullptr, 2));
259+
ASSERT_EQ(0, bthread_id_unlock(cntl.current_id()));
260+
brpc::SocketId sending_id;
261+
ASSERT_EQ(0, brpc::Socket::Create(brpc::SocketOptions(), &sending_id));
262+
ASSERT_EQ(0, brpc::Socket::Address(
263+
sending_id, &cntl._current_call.sending_sock));
264+
265+
brpc::policy::PublicPbrpcResponse meta;
266+
meta.add_responsebody()->set_id(cntl.current_id().value);
267+
meta.mutable_responsehead()->set_code(0);
268+
ProcessMessage(brpc::policy::ProcessPublicPbrpcResponse, MakeResponseMessage(&meta), false);
269+
EXPECT_TRUE(res.message().empty());
270+
EXPECT_EQ(0, cntl.ErrorCode());
271+
272+
brpc::policy::MostCommonMessage* msg = MakeResponseMessage(&meta);
273+
cntl._current_call.sending_sock->ReAddress(&msg->_socket);
274+
ProcessMessage(brpc::policy::ProcessPublicPbrpcResponse, msg, false);
275+
EXPECT_EQ(EXP_RESPONSE, res.message());
276+
EXPECT_EQ(0, cntl.ErrorCode());
277+
}
278+
253279
TEST_F(PublicPbrpcTest, process_response_error_code) {
254280
const int ERROR_CODE = 12345;
255281
brpc::policy::PublicPbrpcResponse meta;

‎test/brpc_sofa_pbrpc_protocol_unittest.cpp‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,32 @@ TEST_F(SofaTest, reject_huge_meta_size) {
296296
ASSERT_EQ(brpc::PARSE_ERROR_TOO_BIG_DATA, pr.error());
297297
}
298298

299+
TEST_F(SofaTest, process_response_requires_sending_socket) {
300+
brpc::Controller cntl;
301+
test::EchoResponse res;
302+
cntl._response = &res;
303+
ASSERT_EQ(0, bthread_id_lock_and_reset_range(
304+
cntl.call_id(), nullptr, 2));
305+
ASSERT_EQ(0, bthread_id_unlock(cntl.current_id()));
306+
brpc::SocketId sending_id;
307+
ASSERT_EQ(0, brpc::Socket::Create(brpc::SocketOptions(), &sending_id));
308+
ASSERT_EQ(0, brpc::Socket::Address(
309+
sending_id, &cntl._current_call.sending_sock));
310+
311+
brpc::policy::SofaRpcMeta meta;
312+
meta.set_type(brpc::policy::SofaRpcMeta::RESPONSE);
313+
meta.set_sequence_id(cntl.current_id().value);
314+
ProcessMessage(brpc::policy::ProcessSofaResponse, MakeResponseMessage(meta), false);
315+
EXPECT_TRUE(res.message().empty());
316+
EXPECT_EQ(0, cntl.ErrorCode());
317+
318+
brpc::policy::MostCommonMessage* msg = MakeResponseMessage(meta);
319+
cntl._current_call.sending_sock->ReAddress(&msg->_socket);
320+
ProcessMessage(brpc::policy::ProcessSofaResponse, msg, false);
321+
EXPECT_EQ(EXP_RESPONSE, res.message());
322+
EXPECT_EQ(0, cntl.ErrorCode());
323+
}
324+
299325
TEST_F(SofaTest, process_response_error_code) {
300326
const int ERROR_CODE = 12345;
301327
brpc::policy::SofaRpcMeta meta;

0 commit comments

Comments
 (0)