|
20 | 20 | // Date: 2015/10/22 16:28:44 |
21 | 21 |
|
22 | 22 | #include <gtest/gtest.h> |
| 23 | +#include <errno.h> |
23 | 24 | #include "brpc/server.h" |
24 | 25 |
|
25 | 26 | #include "brpc/controller.h" |
26 | 27 | #include "brpc/channel.h" |
27 | 28 | #include "brpc/socket.h" |
| 29 | +#include "brpc/details/controller_private_accessor.h" |
28 | 30 | #include "brpc/stream_impl.h" |
29 | 31 | #include "brpc/policy/streaming_rpc_protocol.h" |
30 | 32 | #include "echo.pb.h" |
@@ -78,6 +80,52 @@ class StreamingRpcTest : public testing::Test { |
78 | 80 | test::EchoResponse response; |
79 | 81 | }; |
80 | 82 |
|
| 83 | +class MyServiceWithStreamAndFailedSocket : public test::EchoService { |
| 84 | +public: |
| 85 | + explicit MyServiceWithStreamAndFailedSocket(const brpc::StreamOptions& options) |
| 86 | + : _options(options) {} |
| 87 | + |
| 88 | + void Echo(::google::protobuf::RpcController* controller, |
| 89 | + const ::test::EchoRequest* request, |
| 90 | + ::test::EchoResponse* response, |
| 91 | + ::google::protobuf::Closure* done) override { |
| 92 | + brpc::ClosureGuard done_guard(done); |
| 93 | + response->set_message(request->message()); |
| 94 | + brpc::Controller* cntl = static_cast<brpc::Controller*>(controller); |
| 95 | + brpc::StreamId response_stream; |
| 96 | + ASSERT_EQ(0, StreamAccept(&response_stream, *cntl, &_options)); |
| 97 | + brpc::ControllerPrivateAccessor accessor(cntl); |
| 98 | + ASSERT_TRUE(accessor.get_sending_socket() != NULL); |
| 99 | + accessor.get_sending_socket()->SetFailed(); |
| 100 | + } |
| 101 | + |
| 102 | +private: |
| 103 | + brpc::StreamOptions _options; |
| 104 | +}; |
| 105 | + |
| 106 | +TEST_F(StreamingRpcTest, set_host_socket_returns_error_when_socket_is_failed) { |
| 107 | + brpc::SocketOptions socket_options; |
| 108 | + brpc::SocketId host_socket_id; |
| 109 | + ASSERT_EQ(0, brpc::Socket::Create(socket_options, &host_socket_id)); |
| 110 | + brpc::SocketUniquePtr host_socket; |
| 111 | + ASSERT_EQ(0, brpc::Socket::Address(host_socket_id, &host_socket)); |
| 112 | + ASSERT_EQ(0, host_socket->SetFailed()); |
| 113 | + |
| 114 | + brpc::StreamId stream_id; |
| 115 | + brpc::StreamOptions stream_options; |
| 116 | + ASSERT_EQ(0, brpc::Stream::Create(stream_options, NULL, &stream_id, false)); |
| 117 | + brpc::ScopedStream stream_guard(stream_id); |
| 118 | + |
| 119 | + brpc::SocketUniquePtr stream_socket; |
| 120 | + ASSERT_EQ(0, brpc::Socket::Address(stream_id, &stream_socket)); |
| 121 | + brpc::Stream* stream = static_cast<brpc::Stream*>(stream_socket->conn()); |
| 122 | + |
| 123 | + errno = 0; |
| 124 | + ASSERT_EQ(-1, stream->SetHostSocket(host_socket.get())); |
| 125 | + ASSERT_NE(0, errno); |
| 126 | + ASSERT_TRUE(stream->_host_socket == NULL); |
| 127 | +} |
| 128 | + |
81 | 129 | TEST_F(StreamingRpcTest, sanity) { |
82 | 130 | brpc::Server server; |
83 | 131 | MyServiceWithStream service; |
@@ -159,6 +207,39 @@ class OrderedInputHandler : public brpc::StreamInputHandler { |
159 | 207 | HandlerControl* _cntl; |
160 | 208 | }; |
161 | 209 |
|
| 210 | +TEST_F(StreamingRpcTest, server_failed_socket_before_response_closes_stream_without_abort) { |
| 211 | + OrderedInputHandler handler; |
| 212 | + brpc::StreamOptions response_stream_options; |
| 213 | + response_stream_options.handler = &handler; |
| 214 | + brpc::Server server; |
| 215 | + MyServiceWithStreamAndFailedSocket service(response_stream_options); |
| 216 | + ASSERT_EQ(0, server.AddService(&service, brpc::SERVER_DOESNT_OWN_SERVICE)); |
| 217 | + ASSERT_EQ(0, server.Start(9007, NULL)); |
| 218 | + |
| 219 | + brpc::Channel channel; |
| 220 | + ASSERT_EQ(0, channel.Init("127.0.0.1:9007", NULL)); |
| 221 | + brpc::Controller cntl; |
| 222 | + brpc::StreamId request_stream; |
| 223 | + ASSERT_EQ(0, StreamCreate(&request_stream, cntl, NULL)); |
| 224 | + brpc::ScopedStream stream_guard(request_stream); |
| 225 | + |
| 226 | + test::EchoService_Stub stub(&channel); |
| 227 | + stub.Echo(&cntl, &request, &response, NULL); |
| 228 | + ASSERT_TRUE(cntl.Failed()); |
| 229 | + |
| 230 | + for (int i = 0; i < 10000 && !handler.stopped(); ++i) { |
| 231 | + usleep(100); |
| 232 | + } |
| 233 | + |
| 234 | + server.Stop(0); |
| 235 | + server.Join(); |
| 236 | + |
| 237 | + ASSERT_TRUE(handler.stopped()); |
| 238 | + ASSERT_TRUE(handler.failed()); |
| 239 | + ASSERT_EQ(0, handler.idle_times()); |
| 240 | + ASSERT_EQ(0, handler._expected_next_value); |
| 241 | +} |
| 242 | + |
162 | 243 | TEST_F(StreamingRpcTest, received_in_order) { |
163 | 244 | OrderedInputHandler handler; |
164 | 245 | brpc::StreamOptions opt; |
|
0 commit comments