diff options
author | yang-g <yangg@google.com> | 2016-01-14 11:51:11 -0800 |
---|---|---|
committer | yang-g <yangg@google.com> | 2016-01-14 11:51:11 -0800 |
commit | 25f191d49bd12addce28e11386c242dfde74b4fe (patch) | |
tree | e4fc3e2b964530dd33a6e5ef6b969736c287c99f /test/cpp/end2end/hybrid_end2end_test.cc | |
parent | b9a1377fab3a25fd60e8b632dcf688d470ee9127 (diff) | |
parent | a2517a15734715c65be37a382c352ba17e89d816 (diff) |
merge with head
Diffstat (limited to 'test/cpp/end2end/hybrid_end2end_test.cc')
-rw-r--r-- | test/cpp/end2end/hybrid_end2end_test.cc | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc new file mode 100644 index 0000000000..24de363740 --- /dev/null +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -0,0 +1,178 @@ +/* + * + * Copyright 2015-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 <grpc++/channel.h> +#include <grpc++/client_context.h> +#include <grpc++/create_channel.h> +#include <grpc++/server.h> +#include <grpc++/server_builder.h> +#include <grpc++/server_context.h> +#include <grpc/grpc.h> +#include <grpc/support/thd.h> +#include <grpc/support/time.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/util/string_ref_helper.h" + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +namespace grpc { +namespace testing { + +namespace { + +void* tag(int i) { return (void*)(intptr_t)i; } + +// Handlers to handle async request at a server. To be run in a separate thread. +void HandleEcho(::grpc::Service* service, ServerCompletionQueue* cq) { + ServerContext srv_ctx; + grpc::ServerAsyncResponseWriter<EcoResponse> 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()); + response_writer.Finish(send_response, Status::OK, tag(2)); + Verify(cq, 2, true); +} + +void HandleClientStreaming(::grpc::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); + do { + srv_stream.Read(&recv_request, tag(2)); + } while (VerifyReturnSuccess(2)); + srv_stream.Finish(send_response, Status::OK, tag(3)); + Verify(cq, 3, true); +} + +class HybridEnd2endTest : public ::testing::Test { + protected: + HybridEnd2endTest() {} + + void SetUpServer(::grpc::Service* 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(&service_); + cq_ = builder.AddCompletionQueue(); + server_ = builder.BuildAndStart(); + } + + void TearDown() GRPC_OVERRIDE { + server_->Shutdown(); + void* ignored_tag; + bool ignored_ok; + cq_->Shutdown(); + while (cq_->Next(&ignored_tag, &ignored_ok)) + ; + } + + void ResetStub() { + std::shared_ptr<Channel> channel = + CreateChannel(server_address_.str(), InsecureChannelCredentials()); + stub_ = grpc::testing::EchoTestService::NewStub(channel); + } + + void TestAllMethods() { + SendEcho(); + SendSimpleClientStreaming(); + } + + 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 SendSimpleClientStreaming() { + EchoRequest send_request; + EchoResponse recv_response; + 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)); + } + Status recv_status = stream->Finish(); + EXPECT_EQ(send_request.message(), recv_response.message()); + EXPECT_TRUE(recv_status.ok()); + } + + std::unique_ptr<ServerCompletionQueue> cq_; + std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; + std::unique_ptr<Server> server_; + std::ostringstream server_address_; +}; + +TEST_F(HybridEnd2endTest, AsyncEchorequestStream) { + WithAsyncMethod_Echo<WithAsyncMethod_RequestStream<EchoTestService> > service; + SetUpServer(&service); + ResetStub(); + std::thread echo_handler_thread(HandleEcho, &service, cq_.get()); + std::thread request_stream_thread(HandleClientStreaming, &service, cq_.get()); + TestAllMethods(); + echo_handler_thread.join(); + request_stream_thread.join(); +} + + + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} |