Index: third_party/grpc/test/cpp/end2end/hybrid_end2end_test.cc |
diff --git a/third_party/grpc/test/cpp/end2end/hybrid_end2end_test.cc b/third_party/grpc/test/cpp/end2end/hybrid_end2end_test.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c72e20628f992607e0d5023dcb6de0c796301de8 |
--- /dev/null |
+++ b/third_party/grpc/test/cpp/end2end/hybrid_end2end_test.cc |
@@ -0,0 +1,556 @@ |
+/* |
+ * |
+ * Copyright 2016, Google Inc. |
+ * All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions are |
+ * met: |
+ * |
+ * * Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * * Redistributions in binary form must reproduce the above |
+ * copyright notice, this list of conditions and the following disclaimer |
+ * in the documentation and/or other materials provided with the |
+ * distribution. |
+ * * Neither the name of Google Inc. nor the names of its |
+ * contributors may be used to endorse or promote products derived from |
+ * this software without specific prior written permission. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ * |
+ */ |
+ |
+#include <memory> |
+#include <thread> |
+ |
+#include <grpc++/channel.h> |
+#include <grpc++/client_context.h> |
+#include <grpc++/create_channel.h> |
+#include <grpc++/generic/async_generic_service.h> |
+#include <grpc++/server.h> |
+#include <grpc++/server_builder.h> |
+#include <grpc++/server_context.h> |
+#include <grpc/grpc.h> |
+#include <gtest/gtest.h> |
+ |
+#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" |
+#include "src/proto/grpc/testing/echo.grpc.pb.h" |
+#include "test/core/util/port.h" |
+#include "test/core/util/test_config.h" |
+#include "test/cpp/end2end/test_service_impl.h" |
+#include "test/cpp/util/byte_buffer_proto_helper.h" |
+ |
+namespace grpc { |
+namespace testing { |
+ |
+namespace { |
+ |
+void* tag(int i) { return (void*)(intptr_t)i; } |
+ |
+bool VerifyReturnSuccess(CompletionQueue* cq, int i) { |
+ void* got_tag; |
+ bool ok; |
+ EXPECT_TRUE(cq->Next(&got_tag, &ok)); |
+ EXPECT_EQ(tag(i), got_tag); |
+ return ok; |
+} |
+ |
+void Verify(CompletionQueue* cq, int i, bool expect_ok) { |
+ EXPECT_EQ(expect_ok, VerifyReturnSuccess(cq, i)); |
+} |
+ |
+// Handlers to handle async request at a server. To be run in a separate thread. |
+template <class Service> |
+void HandleEcho(Service* service, ServerCompletionQueue* cq, bool dup_service) { |
+ ServerContext srv_ctx; |
+ grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); |
+ EchoRequest recv_request; |
+ EchoResponse send_response; |
+ service->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq, cq, |
+ tag(1)); |
+ Verify(cq, 1, true); |
+ send_response.set_message(recv_request.message()); |
+ if (dup_service) { |
+ send_response.mutable_message()->append("_dup"); |
+ } |
+ response_writer.Finish(send_response, Status::OK, tag(2)); |
+ Verify(cq, 2, true); |
+} |
+ |
+template <class Service> |
+void HandleClientStreaming(Service* service, ServerCompletionQueue* cq) { |
+ ServerContext srv_ctx; |
+ EchoRequest recv_request; |
+ EchoResponse send_response; |
+ ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx); |
+ service->RequestRequestStream(&srv_ctx, &srv_stream, cq, cq, tag(1)); |
+ Verify(cq, 1, true); |
+ int i = 1; |
+ do { |
+ i++; |
+ send_response.mutable_message()->append(recv_request.message()); |
+ srv_stream.Read(&recv_request, tag(i)); |
+ } while (VerifyReturnSuccess(cq, i)); |
+ srv_stream.Finish(send_response, Status::OK, tag(100)); |
+ Verify(cq, 100, true); |
+} |
+ |
+template <class Service> |
+void HandleServerStreaming(Service* service, ServerCompletionQueue* cq) { |
+ ServerContext srv_ctx; |
+ EchoRequest recv_request; |
+ EchoResponse send_response; |
+ ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx); |
+ service->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, cq, cq, |
+ tag(1)); |
+ Verify(cq, 1, true); |
+ send_response.set_message(recv_request.message() + "0"); |
+ srv_stream.Write(send_response, tag(2)); |
+ Verify(cq, 2, true); |
+ send_response.set_message(recv_request.message() + "1"); |
+ srv_stream.Write(send_response, tag(3)); |
+ Verify(cq, 3, true); |
+ send_response.set_message(recv_request.message() + "2"); |
+ srv_stream.Write(send_response, tag(4)); |
+ Verify(cq, 4, true); |
+ srv_stream.Finish(Status::OK, tag(5)); |
+ Verify(cq, 5, true); |
+} |
+ |
+void HandleGenericEcho(GenericServerAsyncReaderWriter* stream, |
+ CompletionQueue* cq) { |
+ ByteBuffer recv_buffer; |
+ stream->Read(&recv_buffer, tag(2)); |
+ Verify(cq, 2, true); |
+ EchoRequest recv_request; |
+ EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); |
+ EchoResponse send_response; |
+ send_response.set_message(recv_request.message()); |
+ auto send_buffer = SerializeToByteBuffer(&send_response); |
+ stream->Write(*send_buffer, tag(3)); |
+ Verify(cq, 3, true); |
+ stream->Finish(Status::OK, tag(4)); |
+ Verify(cq, 4, true); |
+} |
+ |
+void HandleGenericRequestStream(GenericServerAsyncReaderWriter* stream, |
+ CompletionQueue* cq) { |
+ ByteBuffer recv_buffer; |
+ EchoRequest recv_request; |
+ EchoResponse send_response; |
+ int i = 1; |
+ while (true) { |
+ i++; |
+ stream->Read(&recv_buffer, tag(i)); |
+ if (!VerifyReturnSuccess(cq, i)) { |
+ break; |
+ } |
+ EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); |
+ send_response.mutable_message()->append(recv_request.message()); |
+ } |
+ auto send_buffer = SerializeToByteBuffer(&send_response); |
+ stream->Write(*send_buffer, tag(99)); |
+ Verify(cq, 99, true); |
+ stream->Finish(Status::OK, tag(100)); |
+ Verify(cq, 100, true); |
+} |
+ |
+// Request and handle one generic call. |
+void HandleGenericCall(AsyncGenericService* service, |
+ ServerCompletionQueue* cq) { |
+ GenericServerContext srv_ctx; |
+ GenericServerAsyncReaderWriter stream(&srv_ctx); |
+ service->RequestCall(&srv_ctx, &stream, cq, cq, tag(1)); |
+ Verify(cq, 1, true); |
+ if (srv_ctx.method() == "/grpc.testing.EchoTestService/Echo") { |
+ HandleGenericEcho(&stream, cq); |
+ } else if (srv_ctx.method() == |
+ "/grpc.testing.EchoTestService/RequestStream") { |
+ HandleGenericRequestStream(&stream, cq); |
+ } else { // other methods not handled yet. |
+ gpr_log(GPR_ERROR, "method: %s", srv_ctx.method().c_str()); |
+ GPR_ASSERT(0); |
+ } |
+} |
+ |
+class TestServiceImplDupPkg |
+ : public ::grpc::testing::duplicate::EchoTestService::Service { |
+ public: |
+ Status Echo(ServerContext* context, const EchoRequest* request, |
+ EchoResponse* response) GRPC_OVERRIDE { |
+ response->set_message(request->message() + "_dup"); |
+ return Status::OK; |
+ } |
+}; |
+ |
+class HybridEnd2endTest : public ::testing::Test { |
+ protected: |
+ HybridEnd2endTest() {} |
+ |
+ void SetUpServer(::grpc::Service* service1, ::grpc::Service* service2, |
+ AsyncGenericService* generic_service) { |
+ int port = grpc_pick_unused_port_or_die(); |
+ server_address_ << "localhost:" << port; |
+ |
+ // Setup server |
+ ServerBuilder builder; |
+ builder.AddListeningPort(server_address_.str(), |
+ grpc::InsecureServerCredentials()); |
+ builder.RegisterService(service1); |
+ if (service2) { |
+ builder.RegisterService(service2); |
+ } |
+ if (generic_service) { |
+ builder.RegisterAsyncGenericService(generic_service); |
+ } |
+ // Create a separate cq for each potential handler. |
+ for (int i = 0; i < 5; i++) { |
+ cqs_.push_back(builder.AddCompletionQueue()); |
+ } |
+ server_ = builder.BuildAndStart(); |
+ } |
+ |
+ void TearDown() GRPC_OVERRIDE { |
+ if (server_) { |
+ server_->Shutdown(); |
+ } |
+ void* ignored_tag; |
+ bool ignored_ok; |
+ for (auto it = cqs_.begin(); it != cqs_.end(); ++it) { |
+ (*it)->Shutdown(); |
+ while ((*it)->Next(&ignored_tag, &ignored_ok)) |
+ ; |
+ } |
+ } |
+ |
+ void ResetStub() { |
+ std::shared_ptr<Channel> channel = |
+ CreateChannel(server_address_.str(), InsecureChannelCredentials()); |
+ stub_ = grpc::testing::EchoTestService::NewStub(channel); |
+ } |
+ |
+ // Test all rpc methods. |
+ void TestAllMethods() { |
+ SendEcho(); |
+ SendSimpleClientStreaming(); |
+ SendSimpleServerStreaming(); |
+ SendBidiStreaming(); |
+ } |
+ |
+ void SendEcho() { |
+ EchoRequest send_request; |
+ EchoResponse recv_response; |
+ ClientContext cli_ctx; |
+ send_request.set_message("Hello"); |
+ Status recv_status = stub_->Echo(&cli_ctx, send_request, &recv_response); |
+ EXPECT_EQ(send_request.message(), recv_response.message()); |
+ EXPECT_TRUE(recv_status.ok()); |
+ } |
+ |
+ void SendEchoToDupService() { |
+ std::shared_ptr<Channel> channel = |
+ CreateChannel(server_address_.str(), InsecureChannelCredentials()); |
+ auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); |
+ EchoRequest send_request; |
+ EchoResponse recv_response; |
+ ClientContext cli_ctx; |
+ send_request.set_message("Hello"); |
+ Status recv_status = stub->Echo(&cli_ctx, send_request, &recv_response); |
+ EXPECT_EQ(send_request.message() + "_dup", recv_response.message()); |
+ EXPECT_TRUE(recv_status.ok()); |
+ } |
+ |
+ void SendSimpleClientStreaming() { |
+ EchoRequest send_request; |
+ EchoResponse recv_response; |
+ grpc::string expected_message; |
+ ClientContext cli_ctx; |
+ send_request.set_message("Hello"); |
+ auto stream = stub_->RequestStream(&cli_ctx, &recv_response); |
+ for (int i = 0; i < 5; i++) { |
+ EXPECT_TRUE(stream->Write(send_request)); |
+ expected_message.append(send_request.message()); |
+ } |
+ stream->WritesDone(); |
+ Status recv_status = stream->Finish(); |
+ EXPECT_EQ(expected_message, recv_response.message()); |
+ EXPECT_TRUE(recv_status.ok()); |
+ } |
+ |
+ void SendSimpleServerStreaming() { |
+ EchoRequest request; |
+ EchoResponse response; |
+ ClientContext context; |
+ request.set_message("hello"); |
+ |
+ auto stream = stub_->ResponseStream(&context, request); |
+ EXPECT_TRUE(stream->Read(&response)); |
+ EXPECT_EQ(response.message(), request.message() + "0"); |
+ EXPECT_TRUE(stream->Read(&response)); |
+ EXPECT_EQ(response.message(), request.message() + "1"); |
+ EXPECT_TRUE(stream->Read(&response)); |
+ EXPECT_EQ(response.message(), request.message() + "2"); |
+ EXPECT_FALSE(stream->Read(&response)); |
+ |
+ Status s = stream->Finish(); |
+ EXPECT_TRUE(s.ok()); |
+ } |
+ |
+ void SendBidiStreaming() { |
+ EchoRequest request; |
+ EchoResponse response; |
+ ClientContext context; |
+ grpc::string msg("hello"); |
+ |
+ auto stream = stub_->BidiStream(&context); |
+ |
+ request.set_message(msg + "0"); |
+ EXPECT_TRUE(stream->Write(request)); |
+ EXPECT_TRUE(stream->Read(&response)); |
+ EXPECT_EQ(response.message(), request.message()); |
+ |
+ request.set_message(msg + "1"); |
+ EXPECT_TRUE(stream->Write(request)); |
+ EXPECT_TRUE(stream->Read(&response)); |
+ EXPECT_EQ(response.message(), request.message()); |
+ |
+ request.set_message(msg + "2"); |
+ EXPECT_TRUE(stream->Write(request)); |
+ EXPECT_TRUE(stream->Read(&response)); |
+ EXPECT_EQ(response.message(), request.message()); |
+ |
+ stream->WritesDone(); |
+ EXPECT_FALSE(stream->Read(&response)); |
+ EXPECT_FALSE(stream->Read(&response)); |
+ |
+ Status s = stream->Finish(); |
+ EXPECT_TRUE(s.ok()); |
+ } |
+ |
+ std::vector<std::unique_ptr<ServerCompletionQueue> > cqs_; |
+ std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; |
+ std::unique_ptr<Server> server_; |
+ std::ostringstream server_address_; |
+}; |
+ |
+TEST_F(HybridEnd2endTest, AsyncEcho) { |
+ EchoTestService::WithAsyncMethod_Echo<TestServiceImpl> service; |
+ SetUpServer(&service, nullptr, nullptr); |
+ ResetStub(); |
+ std::thread echo_handler_thread( |
+ [this, &service] { HandleEcho(&service, cqs_[0].get(), false); }); |
+ TestAllMethods(); |
+ echo_handler_thread.join(); |
+} |
+ |
+TEST_F(HybridEnd2endTest, AsyncEchoRequestStream) { |
+ EchoTestService::WithAsyncMethod_RequestStream< |
+ EchoTestService::WithAsyncMethod_Echo<TestServiceImpl> > service; |
+ SetUpServer(&service, nullptr, nullptr); |
+ ResetStub(); |
+ std::thread echo_handler_thread( |
+ [this, &service] { HandleEcho(&service, cqs_[0].get(), false); }); |
+ std::thread request_stream_handler_thread( |
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); }); |
+ TestAllMethods(); |
+ echo_handler_thread.join(); |
+ request_stream_handler_thread.join(); |
+} |
+ |
+TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream) { |
+ EchoTestService::WithAsyncMethod_RequestStream< |
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> > |
+ service; |
+ SetUpServer(&service, nullptr, nullptr); |
+ ResetStub(); |
+ std::thread response_stream_handler_thread( |
+ [this, &service] { HandleServerStreaming(&service, cqs_[0].get()); }); |
+ std::thread request_stream_handler_thread( |
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); }); |
+ TestAllMethods(); |
+ response_stream_handler_thread.join(); |
+ request_stream_handler_thread.join(); |
+} |
+ |
+// Add a second service with one sync method. |
+TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_SyncDupService) { |
+ EchoTestService::WithAsyncMethod_RequestStream< |
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> > |
+ service; |
+ TestServiceImplDupPkg dup_service; |
+ SetUpServer(&service, &dup_service, nullptr); |
+ ResetStub(); |
+ std::thread response_stream_handler_thread( |
+ [this, &service] { HandleServerStreaming(&service, cqs_[0].get()); }); |
+ std::thread request_stream_handler_thread( |
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); }); |
+ TestAllMethods(); |
+ SendEchoToDupService(); |
+ response_stream_handler_thread.join(); |
+ request_stream_handler_thread.join(); |
+} |
+ |
+// Add a second service with one async method. |
+TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) { |
+ EchoTestService::WithAsyncMethod_RequestStream< |
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> > |
+ service; |
+ duplicate::EchoTestService::AsyncService dup_service; |
+ SetUpServer(&service, &dup_service, nullptr); |
+ ResetStub(); |
+ std::thread response_stream_handler_thread( |
+ [this, &service] { HandleServerStreaming(&service, cqs_[0].get()); }); |
+ std::thread request_stream_handler_thread( |
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); }); |
+ std::thread echo_handler_thread( |
+ [this, &dup_service] { HandleEcho(&dup_service, cqs_[2].get(), true); }); |
+ TestAllMethods(); |
+ SendEchoToDupService(); |
+ response_stream_handler_thread.join(); |
+ request_stream_handler_thread.join(); |
+ echo_handler_thread.join(); |
+} |
+ |
+TEST_F(HybridEnd2endTest, GenericEcho) { |
+ EchoTestService::WithGenericMethod_Echo<TestServiceImpl> service; |
+ AsyncGenericService generic_service; |
+ SetUpServer(&service, nullptr, &generic_service); |
+ ResetStub(); |
+ std::thread generic_handler_thread([this, &generic_service] { |
+ HandleGenericCall(&generic_service, cqs_[0].get()); |
+ }); |
+ TestAllMethods(); |
+ generic_handler_thread.join(); |
+} |
+ |
+TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream) { |
+ EchoTestService::WithAsyncMethod_RequestStream< |
+ EchoTestService::WithGenericMethod_Echo<TestServiceImpl> > service; |
+ AsyncGenericService generic_service; |
+ SetUpServer(&service, nullptr, &generic_service); |
+ ResetStub(); |
+ std::thread generic_handler_thread([this, &generic_service] { |
+ HandleGenericCall(&generic_service, cqs_[0].get()); |
+ }); |
+ std::thread request_stream_handler_thread( |
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); }); |
+ TestAllMethods(); |
+ generic_handler_thread.join(); |
+ request_stream_handler_thread.join(); |
+} |
+ |
+// Add a second service with one sync method. |
+TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_SyncDupService) { |
+ EchoTestService::WithAsyncMethod_RequestStream< |
+ EchoTestService::WithGenericMethod_Echo<TestServiceImpl> > service; |
+ AsyncGenericService generic_service; |
+ TestServiceImplDupPkg dup_service; |
+ SetUpServer(&service, &dup_service, &generic_service); |
+ ResetStub(); |
+ std::thread generic_handler_thread([this, &generic_service] { |
+ HandleGenericCall(&generic_service, cqs_[0].get()); |
+ }); |
+ std::thread request_stream_handler_thread( |
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); }); |
+ TestAllMethods(); |
+ SendEchoToDupService(); |
+ generic_handler_thread.join(); |
+ request_stream_handler_thread.join(); |
+} |
+ |
+// Add a second service with one async method. |
+TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_AsyncDupService) { |
+ EchoTestService::WithAsyncMethod_RequestStream< |
+ EchoTestService::WithGenericMethod_Echo<TestServiceImpl> > service; |
+ AsyncGenericService generic_service; |
+ duplicate::EchoTestService::AsyncService dup_service; |
+ SetUpServer(&service, &dup_service, &generic_service); |
+ ResetStub(); |
+ std::thread generic_handler_thread([this, &generic_service] { |
+ HandleGenericCall(&generic_service, cqs_[0].get()); |
+ }); |
+ std::thread request_stream_handler_thread( |
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); }); |
+ std::thread echo_handler_thread( |
+ [this, &dup_service] { HandleEcho(&dup_service, cqs_[2].get(), true); }); |
+ TestAllMethods(); |
+ SendEchoToDupService(); |
+ generic_handler_thread.join(); |
+ request_stream_handler_thread.join(); |
+ echo_handler_thread.join(); |
+} |
+ |
+TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStreamResponseStream) { |
+ EchoTestService::WithAsyncMethod_RequestStream< |
+ EchoTestService::WithGenericMethod_Echo< |
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> > > |
+ service; |
+ AsyncGenericService generic_service; |
+ SetUpServer(&service, nullptr, &generic_service); |
+ ResetStub(); |
+ std::thread generic_handler_thread([this, &generic_service] { |
+ HandleGenericCall(&generic_service, cqs_[0].get()); |
+ }); |
+ std::thread request_stream_handler_thread( |
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); }); |
+ std::thread response_stream_handler_thread( |
+ [this, &service] { HandleServerStreaming(&service, cqs_[2].get()); }); |
+ TestAllMethods(); |
+ generic_handler_thread.join(); |
+ request_stream_handler_thread.join(); |
+ response_stream_handler_thread.join(); |
+} |
+ |
+TEST_F(HybridEnd2endTest, GenericEchoRequestStreamAsyncResponseStream) { |
+ EchoTestService::WithGenericMethod_RequestStream< |
+ EchoTestService::WithGenericMethod_Echo< |
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> > > |
+ service; |
+ AsyncGenericService generic_service; |
+ SetUpServer(&service, nullptr, &generic_service); |
+ ResetStub(); |
+ std::thread generic_handler_thread([this, &generic_service] { |
+ HandleGenericCall(&generic_service, cqs_[0].get()); |
+ }); |
+ std::thread generic_handler_thread2([this, &generic_service] { |
+ HandleGenericCall(&generic_service, cqs_[1].get()); |
+ }); |
+ std::thread response_stream_handler_thread( |
+ [this, &service] { HandleServerStreaming(&service, cqs_[2].get()); }); |
+ TestAllMethods(); |
+ generic_handler_thread.join(); |
+ generic_handler_thread2.join(); |
+ response_stream_handler_thread.join(); |
+} |
+ |
+// If WithGenericMethod is called and no generic service is registered, the |
+// server will fail to build. |
+TEST_F(HybridEnd2endTest, GenericMethodWithoutGenericService) { |
+ EchoTestService::WithGenericMethod_RequestStream< |
+ EchoTestService::WithGenericMethod_Echo< |
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> > > |
+ service; |
+ SetUpServer(&service, nullptr, nullptr); |
+ EXPECT_EQ(nullptr, server_.get()); |
+} |
+ |
+} // namespace |
+} // namespace testing |
+} // namespace grpc |
+ |
+int main(int argc, char** argv) { |
+ grpc_test_init(argc, argv); |
+ ::testing::InitGoogleTest(&argc, argv); |
+ return RUN_ALL_TESTS(); |
+} |