|
34 | 34 | #include "brpc/policy/baidu_rpc_protocol.h" |
35 | 35 | #include "brpc/policy/baidu_rpc_meta.pb.h" |
36 | 36 | #include "brpc/policy/most_common_message.h" |
| 37 | +#include "brpc/policy/public_pbrpc_protocol.h" |
37 | 38 | #include "brpc/channel.h" |
38 | 39 | #include "brpc/details/load_balancer_with_naming.h" |
39 | 40 | #include "brpc/parallel_channel.h" |
@@ -2282,6 +2283,97 @@ class MyShared : public brpc::SharedObject { |
2282 | 2283 | int MyShared::nctor = 0; |
2283 | 2284 | int MyShared::ndtor = 0; |
2284 | 2285 |
|
| 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 | + |
2285 | 2377 | TEST_F(ChannelTest, intrusive_ptr_sanity) { |
2286 | 2378 | MyShared::nctor = 0; |
2287 | 2379 | MyShared::ndtor = 0; |
|
0 commit comments