diff options
-rw-r--r-- | Makefile | 47 | ||||
-rw-r--r-- | build.yaml | 12 | ||||
-rw-r--r-- | test/cpp/end2end/hybrid_end2end_test.cc | 174 | ||||
-rw-r--r-- | test/cpp/end2end/mixed_handlers_end2end_test.cc | 747 | ||||
-rw-r--r-- | tools/run_tests/sources_and_headers.json | 16 | ||||
-rw-r--r-- | tools/run_tests/tests.json | 19 |
6 files changed, 250 insertions, 765 deletions
@@ -911,6 +911,7 @@ grpc_csharp_plugin: $(BINDIR)/$(CONFIG)/grpc_csharp_plugin grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin +hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test interop_client: $(BINDIR)/$(CONFIG)/interop_client interop_server: $(BINDIR)/$(CONFIG)/interop_server interop_test: $(BINDIR)/$(CONFIG)/interop_test @@ -1260,6 +1261,7 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \ $(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ + $(BINDIR)/$(CONFIG)/hybrid_end2end_test \ $(BINDIR)/$(CONFIG)/interop_client \ $(BINDIR)/$(CONFIG)/interop_server \ $(BINDIR)/$(CONFIG)/interop_test \ @@ -1561,6 +1563,8 @@ test_cxx: test_zookeeper buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test || ( echo test generic_async_streaming_ping_pong_test failed ; exit 1 ) $(E) "[RUN] Testing generic_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing hybrid_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/hybrid_end2end_test || ( echo test hybrid_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing interop_test" $(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 ) $(E) "[RUN] Testing mock_test" @@ -9613,6 +9617,49 @@ ifneq ($(NO_DEPS),true) endif +HYBRID_END2END_TEST_SRC = \ + test/cpp/end2end/hybrid_end2end_test.cc \ + +HYBRID_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HYBRID_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/hybrid_end2end_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/hybrid_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/hybrid_end2end_test: $(PROTOBUF_DEP) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/hybrid_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/hybrid_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_hybrid_end2end_test: $(HYBRID_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(HYBRID_END2END_TEST_OBJS:.o=.dep) +endif +endif + + ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. diff --git a/build.yaml b/build.yaml index a23197c12c..d2695176ca 100644 --- a/build.yaml +++ b/build.yaml @@ -2043,6 +2043,18 @@ targets: secure: false vs_config_type: Application vs_project_guid: '{069E9D05-B78B-4751-9252-D21EBAE7DE8E}' +- name: hybrid_end2end_test + build: test + language: c++ + src: + - test/cpp/end2end/hybrid_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr - name: interop_client build: test run: false diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index 24de363740..36e8b28ee2 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +32,7 @@ */ #include <memory> +#include <thread> #include <grpc++/channel.h> #include <grpc++/client_context.h> @@ -50,20 +51,145 @@ #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 { +class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { + public: + TestServiceImpl() : signal_client_(false), host_() {} + explicit TestServiceImpl(const grpc::string& host) + : signal_client_(false), host_(new grpc::string(host)) {} + + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) GRPC_OVERRIDE { + response->set_message(request->message()); + if (host_) { + response->mutable_param()->set_host(*host_); + } + if (request->has_param() && request->param().client_cancel_after_us()) { + { + std::unique_lock<std::mutex> lock(mu_); + signal_client_ = true; + } + while (!context->IsCancelled()) { + gpr_sleep_until(gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_micros(request->param().client_cancel_after_us(), + GPR_TIMESPAN))); + } + return Status::CANCELLED; + } else if (request->has_param() && + request->param().server_cancel_after_us()) { + gpr_sleep_until(gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_micros(request->param().server_cancel_after_us(), + GPR_TIMESPAN))); + return Status::CANCELLED; + } else { + EXPECT_FALSE(context->IsCancelled()); + } + + if (request->has_param() && request->param().echo_metadata()) { + const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata = + context->client_metadata(); + for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator + iter = client_metadata.begin(); + iter != client_metadata.end(); ++iter) { + context->AddTrailingMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + if (request->has_param() && + request->param().response_message_length() > 0) { + response->set_message( + grpc::string(request->param().response_message_length(), '\0')); + } + if (request->has_param() && request->param().echo_peer()) { + response->mutable_param()->set_peer(context->peer()); + } + return Status::OK; + } + + // Unimplemented is left unimplemented to test the returned error. + + Status RequestStream(ServerContext* context, + ServerReader<EchoRequest>* reader, + EchoResponse* response) GRPC_OVERRIDE { + EchoRequest request; + response->set_message(""); + int cancel_after_reads = 0; + while (reader->Read(&request)) { + if (cancel_after_reads == 1) { + gpr_log(GPR_INFO, "return cancel status"); + return Status::CANCELLED; + } else if (cancel_after_reads > 0) { + cancel_after_reads--; + } + response->mutable_message()->append(request.message()); + } + return Status::OK; + } + + // Return 3 messages. + // TODO(yangg) make it generic by adding a parameter into EchoRequest + Status ResponseStream(ServerContext* context, const EchoRequest* request, + ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE { + EchoResponse response; + response.set_message(request->message() + "0"); + writer->Write(response); + response.set_message(request->message() + "1"); + writer->Write(response); + response.set_message(request->message() + "2"); + writer->Write(response); + + return Status::OK; + } + + Status BidiStream(ServerContext* context, + ServerReaderWriter<EchoResponse, EchoRequest>* stream) + GRPC_OVERRIDE { + EchoRequest request; + EchoResponse response; + while (stream->Read(&request)) { + gpr_log(GPR_INFO, "recv msg %s", request.message().c_str()); + response.set_message(request.message()); + stream->Write(response); + } + return Status::OK; + } + + bool signal_client() { + std::unique_lock<std::mutex> lock(mu_); + return signal_client_; + } + + private: + bool signal_client_; + std::mutex mu_; + std::unique_ptr<grpc::string> host_; +}; + 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. -void HandleEcho(::grpc::Service* service, ServerCompletionQueue* cq) { +template <class Service> +void HandleEcho(Service* service, ServerCompletionQueue* cq) { ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EcoResponse> response_writer(&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)); @@ -73,16 +199,18 @@ void HandleEcho(::grpc::Service* service, ServerCompletionQueue* cq) { Verify(cq, 2, true); } -void HandleClientStreaming(::grpc::Service* service, ServerCompletionQueue* cq) { +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)); + service->RequestRequestStream(&srv_ctx, &srv_stream, cq, cq, tag(1)); Verify(cq, 1, true); do { + send_response.mutable_message()->append(recv_request.message()); srv_stream.Read(&recv_request, tag(2)); - } while (VerifyReturnSuccess(2)); + } while (VerifyReturnSuccess(cq, 2)); srv_stream.Finish(send_response, Status::OK, tag(3)); Verify(cq, 3, true); } @@ -99,7 +227,7 @@ class HybridEnd2endTest : public ::testing::Test { ServerBuilder builder; builder.AddListeningPort(server_address_.str(), grpc::InsecureServerCredentials()); - builder.RegisterService(&service_); + builder.RegisterService(service); cq_ = builder.AddCompletionQueue(); server_ = builder.BuildAndStart(); } @@ -137,14 +265,17 @@ class HybridEnd2endTest : public ::testing::Test { 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)); + EXPECT_TRUE(stream->Write(send_request)); + expected_message.append(send_request.message()); } + stream->WritesDone(); Status recv_status = stream->Finish(); - EXPECT_EQ(send_request.message(), recv_response.message()); + EXPECT_EQ(expected_message, recv_response.message()); EXPECT_TRUE(recv_status.ok()); } @@ -154,18 +285,25 @@ class HybridEnd2endTest : public ::testing::Test { std::ostringstream server_address_; }; -TEST_F(HybridEnd2endTest, AsyncEchorequestStream) { - WithAsyncMethod_Echo<WithAsyncMethod_RequestStream<EchoTestService> > service; +TEST_F(HybridEnd2endTest, AsyncEcho) { + EchoTestService::WithAsyncMethod_Echo<TestServiceImpl> service; SetUpServer(&service); ResetStub(); - std::thread echo_handler_thread(HandleEcho, &service, cq_.get()); - std::thread request_stream_thread(HandleClientStreaming, &service, cq_.get()); + std::thread echo_handler_thread([this, &service] { HandleEcho(&service, cq_.get()); }); TestAllMethods(); echo_handler_thread.join(); - request_stream_thread.join(); } - +TEST_F(HybridEnd2endTest, AsyncEchoRequestStream) { + EchoTestService::WithAsyncMethod_RequestStream<EchoTestService::WithAsyncMethod_Echo<TestServiceImpl> > service; + SetUpServer(&service); + ResetStub(); + std::thread echo_handler_thread([this, &service] { HandleEcho(&service, cq_.get()); }); + std::thread request_stream_handler_thread([this, &service] { HandleClientStreaming(&service, cq_.get()); }); + TestAllMethods(); + echo_handler_thread.join(); + request_stream_handler_thread.join(); +} } // namespace } // namespace testing diff --git a/test/cpp/end2end/mixed_handlers_end2end_test.cc b/test/cpp/end2end/mixed_handlers_end2end_test.cc deleted file mode 100644 index a896ad2d73..0000000000 --- a/test/cpp/end2end/mixed_handlers_end2end_test.cc +++ /dev/null @@ -1,747 +0,0 @@ -/* - * - * 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/grpc.h> -#include <grpc/support/thd.h> -#include <grpc/support/time.h> -#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 <gtest/gtest.h> - -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/cpp/util/string_ref_helper.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; -using std::chrono::system_clock; - -namespace grpc { -namespace testing { - -namespace { - -void* tag(int i) { return (void*)(intptr_t)i; } - -class Verifier { - public: - explicit Verifier(bool spin) : spin_(spin) {} - Verifier& Expect(int i, bool expect_ok) { - expectations_[tag(i)] = expect_ok; - return *this; - } - void Verify(CompletionQueue* cq) { - GPR_ASSERT(!expectations_.empty()); - while (!expectations_.empty()) { - bool ok; - void* got_tag; - if (spin_) { - for (;;) { - auto r = cq->AsyncNext(&got_tag, &ok, gpr_time_0(GPR_CLOCK_REALTIME)); - if (r == CompletionQueue::TIMEOUT) continue; - if (r == CompletionQueue::GOT_EVENT) break; - gpr_log(GPR_ERROR, "unexpected result from AsyncNext"); - abort(); - } - } else { - EXPECT_TRUE(cq->Next(&got_tag, &ok)); - } - auto it = expectations_.find(got_tag); - EXPECT_TRUE(it != expectations_.end()); - EXPECT_EQ(it->second, ok); - expectations_.erase(it); - } - } - void Verify(CompletionQueue* cq, - std::chrono::system_clock::time_point deadline) { - if (expectations_.empty()) { - bool ok; - void* got_tag; - if (spin_) { - while (std::chrono::system_clock::now() < deadline) { - EXPECT_EQ( - cq->AsyncNext(&got_tag, &ok, gpr_time_0(GPR_CLOCK_REALTIME)), - CompletionQueue::TIMEOUT); - } - } else { - EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline), - CompletionQueue::TIMEOUT); - } - } else { - while (!expectations_.empty()) { - bool ok; - void* got_tag; - if (spin_) { - for (;;) { - GPR_ASSERT(std::chrono::system_clock::now() < deadline); - auto r = - cq->AsyncNext(&got_tag, &ok, gpr_time_0(GPR_CLOCK_REALTIME)); - if (r == CompletionQueue::TIMEOUT) continue; - if (r == CompletionQueue::GOT_EVENT) break; - gpr_log(GPR_ERROR, "unexpected result from AsyncNext"); - abort(); - } - } else { - EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline), - CompletionQueue::GOT_EVENT); - } - auto it = expectations_.find(got_tag); - EXPECT_TRUE(it != expectations_.end()); - EXPECT_EQ(it->second, ok); - expectations_.erase(it); - } - } - } - - private: - std::map<void*, bool> expectations_; - bool spin_; -}; - -class AsyncEnd2endTest : public ::testing::TestWithParam<bool> { - protected: - AsyncEnd2endTest() {} - - void SetUp() GRPC_OVERRIDE { - 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::TestService::NewStub(channel); - } - - void SendRpc(int num_rpcs) { - for (int i = 0; i < num_rpcs; i++) { - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - - Verifier(GetParam()).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(3)); - Verifier(GetParam()).Expect(3, true).Verify(cq_.get()); - - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam()).Expect(4, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - } - } - - std::unique_ptr<ServerCompletionQueue> cq_; - std::unique_ptr<grpc::testing::TestService::Stub> stub_; - std::unique_ptr<Server> server_; - grpc::testing::TestService::AsyncService service_; - std::ostringstream server_address_; -}; - -TEST_P(AsyncEnd2endTest, SimpleRpc) { - ResetStub(); - SendRpc(1); -} - -TEST_P(AsyncEnd2endTest, SequentialRpcs) { - ResetStub(); - SendRpc(10); -} - -// Test a simple RPC using the async version of Next -TEST_P(AsyncEnd2endTest, AsyncNextRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - std::chrono::system_clock::time_point time_now( - std::chrono::system_clock::now()); - std::chrono::system_clock::time_point time_limit( - std::chrono::system_clock::now() + std::chrono::seconds(10)); - Verifier(GetParam()).Verify(cq_.get(), time_now); - Verifier(GetParam()).Verify(cq_.get(), time_now); - - service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - - Verifier(GetParam()).Expect(2, true).Verify(cq_.get(), time_limit); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(3)); - Verifier(GetParam()) - .Expect(3, true) - .Verify(cq_.get(), std::chrono::system_clock::time_point::max()); - - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam()) - .Expect(4, true) - .Verify(cq_.get(), std::chrono::system_clock::time_point::max()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -// Two pings and a final pong. -TEST_P(AsyncEnd2endTest, SimpleClientStreaming) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - - send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncWriter<EchoRequest> > cli_stream( - stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1))); - - service_.RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - - Verifier(GetParam()).Expect(2, true).Expect(1, true).Verify(cq_.get()); - - cli_stream->Write(send_request, tag(3)); - Verifier(GetParam()).Expect(3, true).Verify(cq_.get()); - - srv_stream.Read(&recv_request, tag(4)); - Verifier(GetParam()).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - cli_stream->Write(send_request, tag(5)); - Verifier(GetParam()).Expect(5, true).Verify(cq_.get()); - - srv_stream.Read(&recv_request, tag(6)); - Verifier(GetParam()).Expect(6, true).Verify(cq_.get()); - - EXPECT_EQ(send_request.message(), recv_request.message()); - cli_stream->WritesDone(tag(7)); - Verifier(GetParam()).Expect(7, true).Verify(cq_.get()); - - srv_stream.Read(&recv_request, tag(8)); - Verifier(GetParam()).Expect(8, false).Verify(cq_.get()); - - send_response.set_message(recv_request.message()); - srv_stream.Finish(send_response, Status::OK, tag(9)); - Verifier(GetParam()).Expect(9, true).Verify(cq_.get()); - - cli_stream->Finish(&recv_status, tag(10)); - Verifier(GetParam()).Expect(10, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -// One ping, two pongs. -TEST_P(AsyncEnd2endTest, SimpleServerStreaming) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx); - - send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncReader<EchoResponse> > cli_stream( - stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1))); - - service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, - cq_.get(), cq_.get(), tag(2)); - - Verifier(GetParam()).Expect(1, true).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - srv_stream.Write(send_response, tag(3)); - Verifier(GetParam()).Expect(3, true).Verify(cq_.get()); - - cli_stream->Read(&recv_response, tag(4)); - Verifier(GetParam()).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - srv_stream.Write(send_response, tag(5)); - Verifier(GetParam()).Expect(5, true).Verify(cq_.get()); - - cli_stream->Read(&recv_response, tag(6)); - Verifier(GetParam()).Expect(6, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - srv_stream.Finish(Status::OK, tag(7)); - Verifier(GetParam()).Expect(7, true).Verify(cq_.get()); - - cli_stream->Read(&recv_response, tag(8)); - Verifier(GetParam()).Expect(8, false).Verify(cq_.get()); - - cli_stream->Finish(&recv_status, tag(9)); - Verifier(GetParam()).Expect(9, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -// One ping, one pong. -TEST_P(AsyncEnd2endTest, SimpleBidiStreaming) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - - send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse> > - cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1))); - - service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - - Verifier(GetParam()).Expect(1, true).Expect(2, true).Verify(cq_.get()); - - cli_stream->Write(send_request, tag(3)); - Verifier(GetParam()).Expect(3, true).Verify(cq_.get()); - - srv_stream.Read(&recv_request, tag(4)); - Verifier(GetParam()).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - srv_stream.Write(send_response, tag(5)); - Verifier(GetParam()).Expect(5, true).Verify(cq_.get()); - - cli_stream->Read(&recv_response, tag(6)); - Verifier(GetParam()).Expect(6, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - cli_stream->WritesDone(tag(7)); - Verifier(GetParam()).Expect(7, true).Verify(cq_.get()); - - srv_stream.Read(&recv_request, tag(8)); - Verifier(GetParam()).Expect(8, false).Verify(cq_.get()); - - srv_stream.Finish(Status::OK, tag(9)); - Verifier(GetParam()).Expect(9, true).Verify(cq_.get()); - - cli_stream->Finish(&recv_status, tag(10)); - Verifier(GetParam()).Expect(10, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -// Metadata tests -TEST_P(AsyncEnd2endTest, ClientInitialMetadataRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message("Hello"); - std::pair<grpc::string, grpc::string> meta1("key1", "val1"); - std::pair<grpc::string, grpc::string> meta2("key2", "val2"); - cli_ctx.AddMetadata(meta1.first, meta1.second); - cli_ctx.AddMetadata(meta2.first, meta2.second); - - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - Verifier(GetParam()).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - auto client_initial_metadata = srv_ctx.client_metadata(); - EXPECT_EQ(meta1.second, - ToString(client_initial_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(client_initial_metadata.find(meta2.first)->second)); - EXPECT_GE(client_initial_metadata.size(), static_cast<size_t>(2)); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(3)); - - Verifier(GetParam()).Expect(3, true).Verify(cq_.get()); - - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam()).Expect(4, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -TEST_P(AsyncEnd2endTest, ServerInitialMetadataRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message("Hello"); - std::pair<grpc::string, grpc::string> meta1("key1", "val1"); - std::pair<grpc::string, grpc::string> meta2("key2", "val2"); - - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - Verifier(GetParam()).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - srv_ctx.AddInitialMetadata(meta1.first, meta1.second); - srv_ctx.AddInitialMetadata(meta2.first, meta2.second); - response_writer.SendInitialMetadata(tag(3)); - Verifier(GetParam()).Expect(3, true).Verify(cq_.get()); - - response_reader->ReadInitialMetadata(tag(4)); - Verifier(GetParam()).Expect(4, true).Verify(cq_.get()); - auto server_initial_metadata = cli_ctx.GetServerInitialMetadata(); - EXPECT_EQ(meta1.second, - ToString(server_initial_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(server_initial_metadata.find(meta2.first)->second)); - EXPECT_EQ(static_cast<size_t>(2), server_initial_metadata.size()); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(5)); - Verifier(GetParam()).Expect(5, true).Verify(cq_.get()); - - response_reader->Finish(&recv_response, &recv_status, tag(6)); - Verifier(GetParam()).Expect(6, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -TEST_P(AsyncEnd2endTest, ServerTrailingMetadataRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message("Hello"); - std::pair<grpc::string, grpc::string> meta1("key1", "val1"); - std::pair<grpc::string, grpc::string> meta2("key2", "val2"); - - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - Verifier(GetParam()).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - response_writer.SendInitialMetadata(tag(3)); - Verifier(GetParam()).Expect(3, true).Verify(cq_.get()); - - send_response.set_message(recv_request.message()); - srv_ctx.AddTrailingMetadata(meta1.first, meta1.second); - srv_ctx.AddTrailingMetadata(meta2.first, meta2.second); - response_writer.Finish(send_response, Status::OK, tag(4)); - - Verifier(GetParam()).Expect(4, true).Verify(cq_.get()); - - response_reader->Finish(&recv_response, &recv_status, tag(5)); - Verifier(GetParam()).Expect(5, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - auto server_trailing_metadata = cli_ctx.GetServerTrailingMetadata(); - EXPECT_EQ(meta1.second, - ToString(server_trailing_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(server_trailing_metadata.find(meta2.first)->second)); - EXPECT_EQ(static_cast<size_t>(2), server_trailing_metadata.size()); -} - -TEST_P(AsyncEnd2endTest, MetadataRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message("Hello"); - std::pair<grpc::string, grpc::string> meta1("key1", "val1"); - std::pair<grpc::string, grpc::string> meta2( - "key2-bin", - grpc::string("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", 13)); - std::pair<grpc::string, grpc::string> meta3("key3", "val3"); - std::pair<grpc::string, grpc::string> meta6( - "key4-bin", - grpc::string("\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", - 14)); - std::pair<grpc::string, grpc::string> meta5("key5", "val5"); - std::pair<grpc::string, grpc::string> meta4( - "key6-bin", - grpc::string( - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", 15)); - - cli_ctx.AddMetadata(meta1.first, meta1.second); - cli_ctx.AddMetadata(meta2.first, meta2.second); - - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - Verifier(GetParam()).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - auto client_initial_metadata = srv_ctx.client_metadata(); - EXPECT_EQ(meta1.second, - ToString(client_initial_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(client_initial_metadata.find(meta2.first)->second)); - EXPECT_GE(client_initial_metadata.size(), static_cast<size_t>(2)); - - srv_ctx.AddInitialMetadata(meta3.first, meta3.second); - srv_ctx.AddInitialMetadata(meta4.first, meta4.second); - response_writer.SendInitialMetadata(tag(3)); - Verifier(GetParam()).Expect(3, true).Verify(cq_.get()); - response_reader->ReadInitialMetadata(tag(4)); - Verifier(GetParam()).Expect(4, true).Verify(cq_.get()); - auto server_initial_metadata = cli_ctx.GetServerInitialMetadata(); - EXPECT_EQ(meta3.second, - ToString(server_initial_metadata.find(meta3.first)->second)); - EXPECT_EQ(meta4.second, - ToString(server_initial_metadata.find(meta4.first)->second)); - EXPECT_GE(server_initial_metadata.size(), static_cast<size_t>(2)); - - send_response.set_message(recv_request.message()); - srv_ctx.AddTrailingMetadata(meta5.first, meta5.second); - srv_ctx.AddTrailingMetadata(meta6.first, meta6.second); - response_writer.Finish(send_response, Status::OK, tag(5)); - - Verifier(GetParam()).Expect(5, true).Verify(cq_.get()); - - response_reader->Finish(&recv_response, &recv_status, tag(6)); - Verifier(GetParam()).Expect(6, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - auto server_trailing_metadata = cli_ctx.GetServerTrailingMetadata(); - EXPECT_EQ(meta5.second, - ToString(server_trailing_metadata.find(meta5.first)->second)); - EXPECT_EQ(meta6.second, - ToString(server_trailing_metadata.find(meta6.first)->second)); - EXPECT_GE(server_trailing_metadata.size(), static_cast<size_t>(2)); -} - -// Server uses AsyncNotifyWhenDone API to check for cancellation -TEST_P(AsyncEnd2endTest, ServerCheckCancellation) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - srv_ctx.AsyncNotifyWhenDone(tag(5)); - service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - - Verifier(GetParam()).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - cli_ctx.TryCancel(); - Verifier(GetParam()).Expect(5, true).Verify(cq_.get()); - EXPECT_TRUE(srv_ctx.IsCancelled()); - - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam()).Expect(4, false).Verify(cq_.get()); - - EXPECT_EQ(StatusCode::CANCELLED, recv_status.error_code()); -} - -// Server uses AsyncNotifyWhenDone API to check for normal finish -TEST_P(AsyncEnd2endTest, ServerCheckDone) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - srv_ctx.AsyncNotifyWhenDone(tag(5)); - service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - - Verifier(GetParam()).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(3)); - Verifier(GetParam()).Expect(3, true).Verify(cq_.get()); - Verifier(GetParam()).Expect(5, true).Verify(cq_.get()); - EXPECT_FALSE(srv_ctx.IsCancelled()); - - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam()).Expect(4, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -TEST_P(AsyncEnd2endTest, UnimplementedRpc) { - std::shared_ptr<Channel> channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); - std::unique_ptr<grpc::testing::UnimplementedService::Stub> stub; - stub = grpc::testing::UnimplementedService::NewStub(channel); - EchoRequest send_request; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub->AsyncUnimplemented(&cli_ctx, send_request, cq_.get())); - - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam()).Expect(4, false).Verify(cq_.get()); - - EXPECT_EQ(StatusCode::UNIMPLEMENTED, recv_status.error_code()); - EXPECT_EQ("", recv_status.error_message()); -} - -INSTANTIATE_TEST_CASE_P(AsyncEnd2end, AsyncEnd2endTest, - ::testing::Values(false, true)); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 612b830e80..4e336ee84d 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -1608,6 +1608,22 @@ "gpr_test_util", "grpc", "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "language": "c++", + "name": "hybrid_end2end_test", + "src": [ + "test/cpp/end2end/hybrid_end2end_test.cc" + ] + }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", "grpc++_test_config", "grpc++_test_util", "grpc_test_util", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 2757ce445d..509ba5bfe2 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -1864,6 +1864,25 @@ "ci_platforms": [ "linux", "mac", + "posix", + "windows" + ], + "exclude_configs": [], + "flaky": false, + "language": "c++", + "name": "hybrid_end2end_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", "posix" ], "exclude_configs": [], |