Add end2end test for codegen_generic

pull/15805/head
ncteisen 7 years ago
parent 93a90e6132
commit bacd625d37
  1. 40
      CMakeLists.txt
  2. 48
      Makefile
  3. 13
      build.yaml
  4. 454
      test/cpp/end2end/codegen_generic_end2end_test.cc
  5. 13
      test/cpp/util/byte_buffer_proto_helper.cc
  6. 3
      test/cpp/util/byte_buffer_proto_helper.h
  7. 19
      tools/run_tests/generated/sources_and_headers.json
  8. 24
      tools/run_tests/generated/tests.json

@ -554,6 +554,7 @@ add_dependencies(buildtests_cxx client_crash_test)
endif()
add_dependencies(buildtests_cxx client_crash_test_server)
add_dependencies(buildtests_cxx client_lb_end2end_test)
add_dependencies(buildtests_cxx codegen_generic_end2end_test)
add_dependencies(buildtests_cxx codegen_test_full)
add_dependencies(buildtests_cxx codegen_test_minimal)
add_dependencies(buildtests_cxx credentials_test)
@ -11137,6 +11138,45 @@ target_link_libraries(client_lb_end2end_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(codegen_generic_end2end_test
test/cpp/end2end/codegen_generic_end2end_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(codegen_generic_end2end_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(codegen_generic_end2end_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_util
grpc_test_util
grpc++
grpc
gpr_test_util
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(codegen_test_full
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.cc

@ -1130,6 +1130,7 @@ client_channel_stress_test: $(BINDIR)/$(CONFIG)/client_channel_stress_test
client_crash_test: $(BINDIR)/$(CONFIG)/client_crash_test
client_crash_test_server: $(BINDIR)/$(CONFIG)/client_crash_test_server
client_lb_end2end_test: $(BINDIR)/$(CONFIG)/client_lb_end2end_test
codegen_generic_end2end_test: $(BINDIR)/$(CONFIG)/codegen_generic_end2end_test
codegen_test_full: $(BINDIR)/$(CONFIG)/codegen_test_full
codegen_test_minimal: $(BINDIR)/$(CONFIG)/codegen_test_minimal
credentials_test: $(BINDIR)/$(CONFIG)/credentials_test
@ -1627,6 +1628,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/client_crash_test \
$(BINDIR)/$(CONFIG)/client_crash_test_server \
$(BINDIR)/$(CONFIG)/client_lb_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_generic_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_test_full \
$(BINDIR)/$(CONFIG)/codegen_test_minimal \
$(BINDIR)/$(CONFIG)/credentials_test \
@ -1803,6 +1805,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/client_crash_test \
$(BINDIR)/$(CONFIG)/client_crash_test_server \
$(BINDIR)/$(CONFIG)/client_lb_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_generic_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_test_full \
$(BINDIR)/$(CONFIG)/codegen_test_minimal \
$(BINDIR)/$(CONFIG)/credentials_test \
@ -2247,6 +2250,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/client_crash_test || ( echo test client_crash_test failed ; exit 1 )
$(E) "[RUN] Testing client_lb_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/client_lb_end2end_test || ( echo test client_lb_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing codegen_generic_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/codegen_generic_end2end_test || ( echo test codegen_generic_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing codegen_test_full"
$(Q) $(BINDIR)/$(CONFIG)/codegen_test_full || ( echo test codegen_test_full failed ; exit 1 )
$(E) "[RUN] Testing codegen_test_minimal"
@ -16788,6 +16793,49 @@ endif
endif
CODEGEN_GENERIC_END2END_TEST_SRC = \
test/cpp/end2end/codegen_generic_end2end_test.cc \
CODEGEN_GENERIC_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CODEGEN_GENERIC_END2END_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/codegen_generic_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.5.0+.
$(BINDIR)/$(CONFIG)/codegen_generic_end2end_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/codegen_generic_end2end_test: $(PROTOBUF_DEP) $(CODEGEN_GENERIC_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) $(CODEGEN_GENERIC_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)/codegen_generic_end2end_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/codegen_generic_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_codegen_generic_end2end_test: $(CODEGEN_GENERIC_END2END_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(CODEGEN_GENERIC_END2END_TEST_OBJS:.o=.dep)
endif
endif
CODEGEN_TEST_FULL_SRC = \
$(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \

@ -4354,6 +4354,19 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: codegen_generic_end2end_test
gtest: true
build: test
language: c++
src:
- test/cpp/end2end/codegen_generic_end2end_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
- name: codegen_test_full
gtest: true
build: test

@ -0,0 +1,454 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <cinttypes>
#include <memory>
#include <thread>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
#include <grpcpp/server_context.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/iomgr/port.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/byte_buffer_proto_helper.h"
#include "test/cpp/util/string_ref_helper.h"
#include <gtest/gtest.h>
using grpc::testing::EchoRequest;
using grpc::testing::EchoResponse;
namespace grpc {
namespace testing {
namespace {
void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
int detag(void* p) { return static_cast<int>(reinterpret_cast<intptr_t>(p)); }
class Verifier {
public:
Verifier() : lambda_run_(false) {}
// Expect sets the expected ok value for a specific tag
Verifier& Expect(int i, bool expect_ok) {
return ExpectUnless(i, expect_ok, false);
}
// ExpectUnless sets the expected ok value for a specific tag
// unless the tag was already marked seen (as a result of ExpectMaybe)
Verifier& ExpectUnless(int i, bool expect_ok, bool seen) {
if (!seen) {
expectations_[tag(i)] = expect_ok;
}
return *this;
}
// ExpectMaybe sets the expected ok value for a specific tag, but does not
// require it to appear
// If it does, sets *seen to true
Verifier& ExpectMaybe(int i, bool expect_ok, bool* seen) {
if (!*seen) {
maybe_expectations_[tag(i)] = MaybeExpect{expect_ok, seen};
}
return *this;
}
// Next waits for 1 async tag to complete, checks its
// expectations, and returns the tag
int Next(CompletionQueue* cq, bool ignore_ok) {
bool ok;
void* got_tag;
EXPECT_TRUE(cq->Next(&got_tag, &ok));
GotTag(got_tag, ok, ignore_ok);
return detag(got_tag);
}
template <typename T>
CompletionQueue::NextStatus DoOnceThenAsyncNext(
CompletionQueue* cq, void** got_tag, bool* ok, T deadline,
std::function<void(void)> lambda) {
if (lambda_run_) {
return cq->AsyncNext(got_tag, ok, deadline);
} else {
lambda_run_ = true;
return cq->DoThenAsyncNext(lambda, got_tag, ok, deadline);
}
}
// Verify keeps calling Next until all currently set
// expected tags are complete
void Verify(CompletionQueue* cq) { Verify(cq, false); }
// This version of Verify allows optionally ignoring the
// outcome of the expectation
void Verify(CompletionQueue* cq, bool ignore_ok) {
GPR_ASSERT(!expectations_.empty() || !maybe_expectations_.empty());
while (!expectations_.empty()) {
Next(cq, ignore_ok);
}
}
// This version of Verify stops after a certain deadline
void Verify(CompletionQueue* cq,
std::chrono::system_clock::time_point deadline) {
if (expectations_.empty()) {
bool ok;
void* got_tag;
EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline),
CompletionQueue::TIMEOUT);
} else {
while (!expectations_.empty()) {
bool ok;
void* got_tag;
EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline),
CompletionQueue::GOT_EVENT);
GotTag(got_tag, ok, false);
}
}
}
// This version of Verify stops after a certain deadline, and uses the
// DoThenAsyncNext API
// to call the lambda
void Verify(CompletionQueue* cq,
std::chrono::system_clock::time_point deadline,
std::function<void(void)> lambda) {
if (expectations_.empty()) {
bool ok;
void* got_tag;
EXPECT_EQ(DoOnceThenAsyncNext(cq, &got_tag, &ok, deadline, lambda),
CompletionQueue::TIMEOUT);
} else {
while (!expectations_.empty()) {
bool ok;
void* got_tag;
EXPECT_EQ(DoOnceThenAsyncNext(cq, &got_tag, &ok, deadline, lambda),
CompletionQueue::GOT_EVENT);
GotTag(got_tag, ok, false);
}
}
}
private:
void GotTag(void* got_tag, bool ok, bool ignore_ok) {
auto it = expectations_.find(got_tag);
if (it != expectations_.end()) {
if (!ignore_ok) {
EXPECT_EQ(it->second, ok);
}
expectations_.erase(it);
} else {
auto it2 = maybe_expectations_.find(got_tag);
if (it2 != maybe_expectations_.end()) {
if (it2->second.seen != nullptr) {
EXPECT_FALSE(*it2->second.seen);
*it2->second.seen = true;
}
if (!ignore_ok) {
EXPECT_EQ(it2->second.ok, ok);
}
} else {
gpr_log(GPR_ERROR, "Unexpected tag: %p", tag);
abort();
}
}
}
struct MaybeExpect {
bool ok;
bool* seen;
};
std::map<void*, bool> expectations_;
std::map<void*, MaybeExpect> maybe_expectations_;
bool lambda_run_;
};
class CodegenGenericEnd2EndTest : public ::testing::Test {
protected:
CodegenGenericEnd2EndTest() {}
void SetUp() override {
port_ = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port_;
}
void TearDown() override {
server_->Shutdown();
void* ignored_tag;
bool ignored_ok;
cq_->Shutdown();
while (cq_->Next(&ignored_tag, &ignored_ok))
;
stub_.reset();
grpc_recycle_unused_port(port_);
}
template <typename ServerType>
std::unique_ptr<ServerType> BuildAndStartServer() {
ServerBuilder builder;
builder.AddListeningPort(server_address_.str(),
grpc::InsecureServerCredentials());
std::unique_ptr<ServerType> service(new ServerType());
builder.RegisterService(service.get());
cq_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart();
return service;
}
void ResetStub() {
ChannelArguments args;
std::shared_ptr<Channel> channel = CreateChannel(
server_address_.str(), grpc::InsecureChannelCredentials());
stub_ = grpc::testing::EchoTestService::NewStub(channel);
}
std::unique_ptr<ServerCompletionQueue> cq_;
std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
std::unique_ptr<Server> server_;
std::ostringstream server_address_;
int port_;
// For the client application to populate and send to server.
EchoRequest send_request_;
::grpc::ByteBuffer send_request_buffer_;
// For the server to give to gRPC to be populated by incoming request
// from client.
EchoRequest recv_request_;
::grpc::ByteBuffer recv_request_buffer_;
// For the server application to populate and send back to client.
EchoResponse send_response_;
::grpc::ByteBuffer send_response_buffer_;
// For the client to give to gRPC to be populated by incoming response
// from server.
EchoResponse recv_response_;
::grpc::ByteBuffer recv_response_buffer_;
Status recv_status_;
// Both sides need contexts
ClientContext cli_ctx_;
ServerContext srv_ctx_;
};
// Regular Async, both peers use proto
TEST_F(CodegenGenericEnd2EndTest, PureAsyncService) {
typedef grpc::testing::EchoTestService::AsyncService SType;
ResetStub();
auto service = BuildAndStartServer<SType>();
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));
response_reader->Finish(&recv_response_, &recv_status_, tag(4));
Verifier().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().Expect(3, true).Expect(4, true).Verify(cq_.get());
EXPECT_EQ(send_response_.message(), recv_response_.message());
EXPECT_TRUE(recv_status_.ok());
}
// Client uses proto, server uses generic codegen, unary
TEST_F(CodegenGenericEnd2EndTest, CodegenGenericServerUnary) {
typedef grpc::testing::EchoTestService::WithCodegenGenericMethod_Echo<
grpc::testing::EchoTestService::Service>
SType;
ResetStub();
auto service = BuildAndStartServer<SType>();
grpc::GenericServerAsyncResponseWriter response_writer(&srv_ctx_);
send_request_.set_message("hello unary");
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx_, send_request_, cq_.get()));
service->RequestEcho(&srv_ctx_, &recv_request_buffer_, &response_writer,
cq_.get(), cq_.get(), tag(2));
response_reader->Finish(&recv_response_, &recv_status_, tag(4));
Verifier().Expect(2, true).Verify(cq_.get());
EXPECT_TRUE(ParseFromByteBuffer(&recv_request_buffer_, &recv_request_));
EXPECT_EQ(send_request_.message(), recv_request_.message());
send_response_.set_message(recv_request_.message());
EXPECT_TRUE(
SerializeToByteBufferInPlace(&send_response_, &send_response_buffer_));
response_writer.Finish(send_response_buffer_, Status::OK, tag(3));
Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get());
EXPECT_EQ(send_response_.message(), recv_response_.message());
EXPECT_TRUE(recv_status_.ok());
}
// Client uses proto, server uses generic codegen, client streaming
TEST_F(CodegenGenericEnd2EndTest, CodegenGenericServerClientStreaming) {
typedef grpc::testing::EchoTestService::WithCodegenGenericMethod_RequestStream<
grpc::testing::EchoTestService::Service>
SType;
ResetStub();
auto service = BuildAndStartServer<SType>();
grpc::GenericServerAsyncReader srv_stream(&srv_ctx_);
send_request_.set_message("hello client streaming");
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().Expect(2, true).Expect(1, true).Verify(cq_.get());
cli_stream->Write(send_request_, tag(3));
srv_stream.Read(&recv_request_buffer_, tag(4));
Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get());
ParseFromByteBuffer(&recv_request_buffer_, &recv_request_);
EXPECT_EQ(send_request_.message(), recv_request_.message());
cli_stream->Write(send_request_, tag(5));
srv_stream.Read(&recv_request_buffer_, tag(6));
Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get());
ParseFromByteBuffer(&recv_request_buffer_, &recv_request_);
EXPECT_EQ(send_request_.message(), recv_request_.message());
cli_stream->WritesDone(tag(7));
srv_stream.Read(&recv_request_buffer_, tag(8));
Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get());
ParseFromByteBuffer(&recv_request_buffer_, &recv_request_);
send_response_.set_message(recv_request_.message());
SerializeToByteBufferInPlace(&send_response_, &send_response_buffer_);
srv_stream.Finish(send_response_buffer_, Status::OK, tag(9));
cli_stream->Finish(&recv_status_, tag(10));
Verifier().Expect(9, true).Expect(10, true).Verify(cq_.get());
EXPECT_EQ(send_response_.message(), recv_response_.message());
EXPECT_TRUE(recv_status_.ok());
}
// Client uses proto, server uses generic codegen, server streaming
TEST_F(CodegenGenericEnd2EndTest, CodegenGenericServerServerStreaming) {
typedef grpc::testing::EchoTestService::WithCodegenGenericMethod_ResponseStream<
grpc::testing::EchoTestService::Service>
SType;
ResetStub();
auto service = BuildAndStartServer<SType>();
grpc::GenericServerAsyncWriter srv_stream(&srv_ctx_);
send_request_.set_message("hello server streaming");
std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
stub_->AsyncResponseStream(&cli_ctx_, send_request_, cq_.get(), tag(1)));
service->RequestResponseStream(&srv_ctx_, &recv_request_buffer_, &srv_stream,
cq_.get(), cq_.get(), tag(2));
Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get());
ParseFromByteBuffer(&recv_request_buffer_, &recv_request_);
EXPECT_EQ(send_request_.message(), recv_request_.message());
send_response_.set_message(recv_request_.message());
SerializeToByteBufferInPlace(&send_response_, &send_response_buffer_);
srv_stream.Write(send_response_buffer_, tag(3));
cli_stream->Read(&recv_response_, tag(4));
Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get());
EXPECT_EQ(send_response_.message(), recv_response_.message());
srv_stream.Write(send_response_buffer_, tag(5));
cli_stream->Read(&recv_response_, tag(6));
Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get());
EXPECT_EQ(send_response_.message(), recv_response_.message());
srv_stream.Finish(Status::OK, tag(7));
cli_stream->Read(&recv_response_, tag(8));
Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get());
cli_stream->Finish(&recv_status_, tag(9));
Verifier().Expect(9, true).Verify(cq_.get());
EXPECT_TRUE(recv_status_.ok());
}
// Client uses proto, server uses generic codegen, bidi streaming
TEST_F(CodegenGenericEnd2EndTest, CodegenGenericServerBidiStreaming) {
typedef grpc::testing::EchoTestService::WithCodegenGenericMethod_BidiStream<
grpc::testing::EchoTestService::Service>
SType;
ResetStub();
auto service = BuildAndStartServer<SType>();
grpc::GenericServerAsyncReaderWriter srv_stream(&srv_ctx_);
send_request_.set_message("hello bidi streaming");
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().Expect(1, true).Expect(2, true).Verify(cq_.get());
cli_stream->Write(send_request_, tag(3));
srv_stream.Read(&recv_request_buffer_, tag(4));
Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get());
ParseFromByteBuffer(&recv_request_buffer_, &recv_request_);
EXPECT_EQ(send_request_.message(), recv_request_.message());
send_response_.set_message(recv_request_.message());
SerializeToByteBufferInPlace(&send_response_, &send_response_buffer_);
srv_stream.Write(send_response_buffer_, tag(5));
cli_stream->Read(&recv_response_, tag(6));
Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get());
EXPECT_EQ(send_response_.message(), recv_response_.message());
cli_stream->WritesDone(tag(7));
srv_stream.Read(&recv_request_buffer_, tag(8));
Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get());
srv_stream.Finish(Status::OK, tag(9));
cli_stream->Finish(&recv_status_, tag(10));
Verifier().Expect(9, true).Expect(10, true).Verify(cq_.get());
EXPECT_TRUE(recv_status_.ok());
}
} // namespace
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
// Change the backup poll interval from 5s to 100ms to speed up the
// ReconnectChannel test
grpc_test_init(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
}

@ -40,5 +40,18 @@ std::unique_ptr<ByteBuffer> SerializeToByteBuffer(
return std::unique_ptr<ByteBuffer>(new ByteBuffer(&slice, 1));
}
bool SerializeToByteBufferInPlace(grpc::protobuf::Message* message,
ByteBuffer* buffer) {
grpc::string buf;
if (!message->SerializeToString(&buf)) {
return false;
}
buffer->Clear();
Slice slice(buf);
ByteBuffer tmp(&slice, 1);
buffer->Swap(&tmp);
return true;
}
} // namespace testing
} // namespace grpc

@ -32,6 +32,9 @@ bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message);
std::unique_ptr<ByteBuffer> SerializeToByteBuffer(
grpc::protobuf::Message* message);
bool SerializeToByteBufferInPlace(grpc::protobuf::Message* message,
ByteBuffer* buffer);
} // namespace testing
} // namespace grpc

@ -3248,6 +3248,25 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc++",
"grpc++_test_util",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c++",
"name": "codegen_generic_end2end_test",
"src": [
"test/cpp/end2end/codegen_generic_end2end_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",

@ -3855,6 +3855,30 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "codegen_generic_end2end_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save